diff --git a/projects/RPi/linux/linux.arm.conf b/projects/RPi/linux/linux.arm.conf index de549daf9a..8b0b08ecfc 100644 --- a/projects/RPi/linux/linux.arm.conf +++ b/projects/RPi/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.0.5 Kernel Configuration +# Linux/arm 4.1.0-rc8 Kernel Configuration # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -21,6 +21,7 @@ CONFIG_NEED_MACH_IO_H=y CONFIG_NEED_MACH_MEMORY_H=y CONFIG_PHYS_OFFSET=0x0 CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y @@ -61,13 +62,13 @@ CONFIG_HAVE_ARCH_AUDITSYSCALL=y # CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_IRQ_DOMAIN=y CONFIG_HANDLE_DOMAIN_IRQ=y # CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y # # Timers subsystem @@ -97,6 +98,7 @@ CONFIG_SRCU=y # CONFIG_RCU_STALL_COMMON is not set # CONFIG_TREE_RCU_TRACE is not set CONFIG_RCU_KTHREAD_PRIO=0 +# CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m CONFIG_IKCONFIG_PROC=y @@ -133,6 +135,7 @@ CONFIG_HAVE_UID16=y CONFIG_BPF=y CONFIG_EXPERT=y # CONFIG_UID16 is not set +CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set # CONFIG_SYSFS_SYSCALL is not set CONFIG_SYSCTL_SYSCALL=y @@ -199,6 +202,7 @@ CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y @@ -274,11 +278,11 @@ CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y # System Type # CONFIG_MMU=y +CONFIG_ARCH_BCM2708=y +# CONFIG_ARCH_BCM2709 is not set # CONFIG_ARCH_MULTIPLATFORM is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -CONFIG_ARCH_BCM2708=y # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set @@ -297,7 +301,6 @@ CONFIG_ARCH_BCM2708=y # CONFIG_ARCH_W90X900 is not set # CONFIG_ARCH_LPC32XX is not set # CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set # CONFIG_ARCH_SHMOBILE_LEGACY is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -305,7 +308,6 @@ CONFIG_ARCH_BCM2708=y # CONFIG_ARCH_S3C64XX is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP1 is not set -# CONFIG_ARCH_BCM2709 is not set # # Broadcom BCM2708 Implementations @@ -401,6 +403,7 @@ CONFIG_CLEANCACHE=y CONFIG_FRONTSWAP=y CONFIG_CMA=y # CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=7 # CONFIG_ZSWAP is not set # CONFIG_ZPOOL is not set @@ -458,6 +461,7 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y # CONFIG_CPUFREQ_DT is not set # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set CONFIG_ARM_BCM2835_CPUFREQ=y +# CONFIG_QORIQ_CPUFREQ is not set # # CPU Idle @@ -469,6 +473,7 @@ CONFIG_CPU_IDLE_GOV_MENU=y # # ARM CPU Idle Drivers # +# CONFIG_ARM_CPUIDLE is not set # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set # @@ -484,7 +489,6 @@ CONFIG_VFP=y # Userspace binary formats # CONFIG_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -772,7 +776,7 @@ CONFIG_DNS_RESOLVER=y # CONFIG_VSOCKETS is not set # CONFIG_NETLINK_MMAP is not set # CONFIG_NETLINK_DIAG is not set -# CONFIG_NET_MPLS_GSO is not set +# CONFIG_MPLS is not set # CONFIG_HSR is not set # CONFIG_NET_SWITCHDEV is not set # CONFIG_CGROUP_NET_PRIO is not set @@ -796,11 +800,15 @@ CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_HIDP=m CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set # # Bluetooth device drivers # +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_BCM=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set CONFIG_BT_HCIBCM203X=m @@ -922,6 +930,7 @@ CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MG_DISK is not set @@ -1058,13 +1067,7 @@ CONFIG_TUN=y # Distributed Switch Architecture drivers # # CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6060 is not set # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -# CONFIG_NET_DSA_MV88E6171 is not set -# CONFIG_NET_DSA_MV88E6352 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set # CONFIG_ETHERNET is not set CONFIG_PHYLIB=y @@ -1073,7 +1076,6 @@ CONFIG_PHYLIB=y # # CONFIG_AT803X_PHY is not set # CONFIG_AMD_PHY is not set -# CONFIG_AMD_XGBE_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_DAVICOM_PHY is not set # CONFIG_QSEMI_PHY is not set @@ -1378,8 +1380,8 @@ CONFIG_HW_RANDOM_BCM2708=m # CONFIG_TCG_TPM is not set CONFIG_BRCM_CHAR_DRIVERS=y CONFIG_BCM_VC_CMA=y -# CONFIG_BCM_VC_SM is not set CONFIG_BCM2708_VCMEM=y +# CONFIG_BCM_VC_SM is not set # CONFIG_XILLYBUS is not set # @@ -1496,8 +1498,9 @@ CONFIG_PINCTRL=y CONFIG_PINMUX=y CONFIG_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_BCM2835=y +# CONFIG_PINCTRL_AMD is not set # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_BCM2835=y CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y @@ -1507,55 +1510,44 @@ CONFIG_OF_GPIO=y CONFIG_GPIO_SYSFS=y # -# Memory mapped GPIO drivers: +# Memory mapped GPIO drivers # # CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_ALTERA is not set # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_EM is not set -# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GRGPIO is not set # CONFIG_GPIO_PL061 is not set # CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_ZEVIO is not set # -# I2C GPIO expanders: +# I2C GPIO expanders # -CONFIG_GPIO_ARIZONA=m +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_ADNP is not set # -# PCI GPIO expanders: +# MFD GPIO expanders # +CONFIG_GPIO_ARIZONA=m # -# SPI GPIO expanders: +# SPI GPIO expanders # +# CONFIG_GPIO_74X164 is not set # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set # -# AC97 GPIO expanders: -# - -# -# LPC GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# - -# -# USB GPIO expanders: +# USB GPIO expanders # CONFIG_W1=m @@ -1684,6 +1676,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set # CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT15 is not set @@ -1819,10 +1812,12 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77686 is not set # CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_EZX_PCAP is not set # CONFIG_MFD_VIPERBOARD is not set @@ -1838,6 +1833,7 @@ CONFIG_MFD_RTSX_USB=y # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SMSC is not set # CONFIG_ABX500_CORE is not set # CONFIG_MFD_STMPE is not set @@ -2139,7 +2135,6 @@ CONFIG_MEDIA_TUNER_FC0013=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_MEDIA_TUNER_E4000=m CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88TS2022=m CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_SI2157=m CONFIG_MEDIA_TUNER_IT913X=m @@ -2396,6 +2391,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_QCOM is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set CONFIG_SND_SOC_I2C_AND_SPI=m @@ -2459,6 +2455,8 @@ CONFIG_SND_SOC_WM8731=m # CONFIG_SND_SOC_WM8770 is not set # CONFIG_SND_SOC_WM8776 is not set CONFIG_SND_SOC_WM8804=m +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set # CONFIG_SND_SOC_WM8903 is not set # CONFIG_SND_SOC_WM8962 is not set # CONFIG_SND_SOC_WM8978 is not set @@ -2499,7 +2497,6 @@ CONFIG_DRAGONRISE_FF=y CONFIG_HID_EZKEY=y # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set -# CONFIG_HID_HUION is not set # CONFIG_HID_KEYTOUCH is not set CONFIG_HID_KYE=y # CONFIG_HID_UCLOGIC is not set @@ -2728,6 +2725,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_EZUSB_FX2 is not set # CONFIG_USB_HSIC_USB3503 is not set # CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set # # USB Physical Layer drivers @@ -2802,6 +2800,7 @@ CONFIG_LEDS_GPIO=y # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -2843,6 +2842,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set @@ -2923,7 +2923,6 @@ CONFIG_DMADEVICES=y # DMA Devices # # CONFIG_AMBA_PL08X is not set -# CONFIG_DW_DMAC_CORE is not set # CONFIG_DW_DMAC is not set # CONFIG_PL330_DMA is not set CONFIG_DMA_BCM2708=y @@ -2988,6 +2987,7 @@ CONFIG_LIRC_XBOX=m # CONFIG_GS_FPGABOOT is not set # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set # CONFIG_FB_TFT is not set +# CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y @@ -3000,7 +3000,6 @@ CONFIG_COMMON_CLK=y # CONFIG_CLK_QORIQ is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set -# CONFIG_COMMON_CLK_QCOM is not set # # Hardware Spinlock drivers @@ -3014,9 +3013,9 @@ CONFIG_COMMON_CLK=y # CONFIG_SH_TIMER_MTU2 is not set # CONFIG_SH_TIMER_TMU is not set # CONFIG_EM_TIMER_STI is not set -# CONFIG_CLKSRC_VERSATILE is not set CONFIG_MAILBOX=y CONFIG_BCM2708_MBOX=y +# CONFIG_ARM_MHU is not set # CONFIG_PL320_MBOX is not set # CONFIG_ALTERA_MBOX is not set # CONFIG_IOMMU_SUPPORT is not set @@ -3045,6 +3044,7 @@ CONFIG_EXTCON_ARIZONA=m # CONFIG_EXTCON_GPIO is not set # CONFIG_EXTCON_RT8973A is not set # CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set # CONFIG_MEMORY is not set # CONFIG_IIO is not set # CONFIG_PWM is not set @@ -3066,6 +3066,11 @@ CONFIG_IRQCHIP=y # # CONFIG_ANDROID is not set +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set + # # File systems # @@ -3076,6 +3081,7 @@ CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -3103,6 +3109,10 @@ CONFIG_BTRFS_FS=m # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y @@ -3190,10 +3200,6 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_PSTORE is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_F2FS_FS=y -CONFIG_F2FS_STAT_FS=y -# CONFIG_F2FS_FS_XATTR is not set -CONFIG_F2FS_CHECK_FS=y CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V2=y @@ -3346,6 +3352,7 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set # CONFIG_TIMER_STATS is not set # @@ -3373,6 +3380,7 @@ CONFIG_PANIC_TIMEOUT=0 # # RCU Debugging # +# CONFIG_PROVE_RCU is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -3410,6 +3418,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -3508,7 +3517,6 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA1_ARM=m CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set @@ -3518,7 +3526,6 @@ CONFIG_CRYPTO_SHA256=y # Ciphers # CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_ARM=m # CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_BLOWFISH is not set @@ -3553,6 +3560,10 @@ CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_USER_API_RNG is not set # CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_AES_ARM=m # CONFIG_BINARY_PRINTF is not set # diff --git a/projects/RPi/options b/projects/RPi/options index ff8d9084ee..ce23603dc8 100644 --- a/projects/RPi/options +++ b/projects/RPi/options @@ -57,7 +57,7 @@ # Kernel to use. values can be: # default: default mainline kernel - LINUX="4.0" + LINUX="default" # NOOBS supported hex versions NOOBS_HEX="2,3,4,5,6,7,8,9,d,e,f,10,11,12,14,19" diff --git a/projects/RPi/patches/linux/linux-01-RPi_support.patch b/projects/RPi/patches/linux/linux-01-RPi_support.patch index c1f57bb01c..0008aa8b30 100644 --- a/projects/RPi/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi/patches/linux/linux-01-RPi_support.patch @@ -1,52 +1,77 @@ -From 0e7aaf92061593060fc62957aeec745534add9a4 Mon Sep 17 00:00:00 2001 +From 8e2bdce040b3459de0954cb2f212dea47549131c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 001/216] Main bcm2708 linux port +Subject: [PATCH 01/77] Main bcm2708/bcm2709 linux port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix +Signed-off-by: Noralf Trønnes --- - arch/arm/Kconfig | 17 + + arch/arm/Kconfig | 39 ++ arch/arm/Kconfig.debug | 8 + - arch/arm/Makefile | 1 + + arch/arm/Makefile | 2 + + arch/arm/kernel/head.S | 8 + arch/arm/kernel/process.c | 10 + - arch/arm/mach-bcm2708/Kconfig | 26 + - arch/arm/mach-bcm2708/Makefile | 6 + + arch/arm/mach-bcm2708/Kconfig | 30 + + arch/arm/mach-bcm2708/Makefile | 5 + arch/arm/mach-bcm2708/Makefile.boot | 3 + - arch/arm/mach-bcm2708/armctrl.c | 208 +++++++ + arch/arm/mach-bcm2708/armctrl.c | 304 +++++++++ arch/arm/mach-bcm2708/armctrl.h | 27 + - arch/arm/mach-bcm2708/bcm2708.c | 662 +++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 622 ++++++++++++++++++ arch/arm/mach-bcm2708/bcm2708.h | 49 ++ - arch/arm/mach-bcm2708/clock.c | 61 +++ - arch/arm/mach-bcm2708/clock.h | 24 + - arch/arm/mach-bcm2708/dma.c | 399 ++++++++++++++ - arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++++ - arch/arm/mach-bcm2708/include/mach/arm_power.h | 62 +++ + arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++ arch/arm/mach-bcm2708/include/mach/clkdev.h | 7 + arch/arm/mach-bcm2708/include/mach/debug-macro.S | 22 + - arch/arm/mach-bcm2708/include/mach/dma.h | 88 +++ - arch/arm/mach-bcm2708/include/mach/entry-macro.S | 69 +++ + arch/arm/mach-bcm2708/include/mach/entry-macro.S | 69 ++ arch/arm/mach-bcm2708/include/mach/frc.h | 38 ++ arch/arm/mach-bcm2708/include/mach/hardware.h | 28 + arch/arm/mach-bcm2708/include/mach/io.h | 27 + - arch/arm/mach-bcm2708/include/mach/irqs.h | 196 +++++++ + arch/arm/mach-bcm2708/include/mach/irqs.h | 196 ++++++ arch/arm/mach-bcm2708/include/mach/memory.h | 57 ++ - arch/arm/mach-bcm2708/include/mach/platform.h | 228 ++++++++ - arch/arm/mach-bcm2708/include/mach/power.h | 26 + + arch/arm/mach-bcm2708/include/mach/platform.h | 228 +++++++ arch/arm/mach-bcm2708/include/mach/system.h | 38 ++ arch/arm/mach-bcm2708/include/mach/timex.h | 23 + arch/arm/mach-bcm2708/include/mach/uncompress.h | 84 +++ - arch/arm/mach-bcm2708/include/mach/vc_mem.h | 35 ++ - arch/arm/mach-bcm2708/include/mach/vcio.h | 165 ++++++ arch/arm/mach-bcm2708/include/mach/vmalloc.h | 20 + - arch/arm/mach-bcm2708/power.c | 197 +++++++ - arch/arm/mach-bcm2708/vc_mem.c | 431 +++++++++++++++ - arch/arm/mach-bcm2708/vcio.c | 474 ++++++++++++++++ + arch/arm/mach-bcm2709/Kconfig | 42 ++ + arch/arm/mach-bcm2709/Makefile | 6 + + arch/arm/mach-bcm2709/Makefile.boot | 3 + + arch/arm/mach-bcm2709/armctrl.c | 361 ++++++++++ + arch/arm/mach-bcm2709/armctrl.h | 27 + + arch/arm/mach-bcm2709/bcm2708_gpio.c | 426 ++++++++++++ + arch/arm/mach-bcm2709/bcm2709.c | 801 +++++++++++++++++++++++ + arch/arm/mach-bcm2709/bcm2709.h | 49 ++ + arch/arm/mach-bcm2709/delay.S | 21 + + arch/arm/mach-bcm2709/include/mach/arm_control.h | 493 ++++++++++++++ + arch/arm/mach-bcm2709/include/mach/barriers.h | 3 + + arch/arm/mach-bcm2709/include/mach/clkdev.h | 7 + + arch/arm/mach-bcm2709/include/mach/debug-macro.S | 22 + + arch/arm/mach-bcm2709/include/mach/entry-macro.S | 123 ++++ + arch/arm/mach-bcm2709/include/mach/frc.h | 38 ++ + arch/arm/mach-bcm2709/include/mach/gpio.h | 17 + + arch/arm/mach-bcm2709/include/mach/hardware.h | 28 + + arch/arm/mach-bcm2709/include/mach/io.h | 27 + + arch/arm/mach-bcm2709/include/mach/irqs.h | 225 +++++++ + arch/arm/mach-bcm2709/include/mach/memory.h | 57 ++ + arch/arm/mach-bcm2709/include/mach/platform.h | 225 +++++++ + arch/arm/mach-bcm2709/include/mach/system.h | 38 ++ + arch/arm/mach-bcm2709/include/mach/timex.h | 23 + + arch/arm/mach-bcm2709/include/mach/uncompress.h | 84 +++ + arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 + + arch/arm/mach-bcm2709/include/mach/vc_support.h | 69 ++ + arch/arm/mach-bcm2709/include/mach/vmalloc.h | 20 + + arch/arm/mach-bcm2709/vc_mem.c | 431 ++++++++++++ + arch/arm/mach-bcm2709/vc_support.c | 318 +++++++++ arch/arm/mm/Kconfig | 2 +- arch/arm/mm/proc-v6.S | 15 +- - arch/arm/tools/mach-types | 1 + + arch/arm/mm/proc-v7.S | 1 + + arch/arm/tools/mach-types | 2 + + drivers/clocksource/arm_arch_timer.c | 36 + drivers/tty/serial/amba-pl011.c | 2 +- include/linux/mmc/host.h | 1 + - 41 files changed, 4251 insertions(+), 5 deletions(-) + 62 files changed, 6436 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile create mode 100644 arch/arm/mach-bcm2708/Makefile.boot @@ -54,14 +79,9 @@ Signed-off-by: popcornmix create mode 100644 arch/arm/mach-bcm2708/armctrl.h create mode 100644 arch/arm/mach-bcm2708/bcm2708.c create mode 100644 arch/arm/mach-bcm2708/bcm2708.h - create mode 100644 arch/arm/mach-bcm2708/clock.c - create mode 100644 arch/arm/mach-bcm2708/clock.h - create mode 100644 arch/arm/mach-bcm2708/dma.c create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_control.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_power.h create mode 100644 arch/arm/mach-bcm2708/include/mach/clkdev.h create mode 100644 arch/arm/mach-bcm2708/include/mach/debug-macro.S - create mode 100644 arch/arm/mach-bcm2708/include/mach/dma.h create mode 100644 arch/arm/mach-bcm2708/include/mach/entry-macro.S create mode 100644 arch/arm/mach-bcm2708/include/mach/frc.h create mode 100644 arch/arm/mach-bcm2708/include/mach/hardware.h @@ -69,57 +89,102 @@ Signed-off-by: popcornmix create mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h create mode 100644 arch/arm/mach-bcm2708/include/mach/memory.h create mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/power.h create mode 100644 arch/arm/mach-bcm2708/include/mach/system.h create mode 100644 arch/arm/mach-bcm2708/include/mach/timex.h create mode 100644 arch/arm/mach-bcm2708/include/mach/uncompress.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_mem.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/vcio.h create mode 100644 arch/arm/mach-bcm2708/include/mach/vmalloc.h - create mode 100644 arch/arm/mach-bcm2708/power.c - create mode 100644 arch/arm/mach-bcm2708/vc_mem.c - create mode 100644 arch/arm/mach-bcm2708/vcio.c + create mode 100644 arch/arm/mach-bcm2709/Kconfig + create mode 100644 arch/arm/mach-bcm2709/Makefile + create mode 100644 arch/arm/mach-bcm2709/Makefile.boot + create mode 100644 arch/arm/mach-bcm2709/armctrl.c + create mode 100644 arch/arm/mach-bcm2709/armctrl.h + create mode 100644 arch/arm/mach-bcm2709/bcm2708_gpio.c + create mode 100644 arch/arm/mach-bcm2709/bcm2709.c + create mode 100644 arch/arm/mach-bcm2709/bcm2709.h + create mode 100644 arch/arm/mach-bcm2709/delay.S + create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_control.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/clkdev.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/debug-macro.S + create mode 100644 arch/arm/mach-bcm2709/include/mach/entry-macro.S + create mode 100644 arch/arm/mach-bcm2709/include/mach/frc.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/gpio.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/hardware.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/io.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/irqs.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/memory.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/platform.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/system.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/timex.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/uncompress.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h + create mode 100755 arch/arm/mach-bcm2709/include/mach/vc_support.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/vmalloc.h + create mode 100644 arch/arm/mach-bcm2709/vc_mem.c + create mode 100644 arch/arm/mach-bcm2709/vc_support.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index cf4c0c9..6876ae8 100644 +index 45df48b..bd9b2f3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -369,6 +369,22 @@ config ARCH_AT91 - This enables support for systems based on Atmel - AT91RM9200, AT91SAM9 and SAMA5 processors. +@@ -314,6 +314,42 @@ choice + default ARCH_VERSATILE if !MMU + default ARCH_MULTIPLATFORM if MMU +config ARCH_BCM2708 + bool "Broadcom BCM2708 family" + select CPU_V6 + select ARM_AMBA -+ select HAVE_CLK + select HAVE_SCHED_CLOCK + select NEED_MACH_GPIO_H + select NEED_MACH_MEMORY_H -+ select CLKDEV_LOOKUP ++ select COMMON_CLK ++ select ARCH_HAS_CPUFREQ + select GENERIC_CLOCKEVENTS + select ARM_ERRATA_411920 + select MACH_BCM2708 + select VC4 ++ select FIQ + help + This enables support for Broadcom BCM2708 boards. + - config ARCH_CLPS711X - bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" - select ARCH_REQUIRE_GPIOLIB -@@ -967,6 +983,7 @@ source "arch/arm/plat-versatile/Kconfig" - source "arch/arm/mach-vt8500/Kconfig" - - source "arch/arm/mach-w90x900/Kconfig" ++config ARCH_BCM2709 ++ bool "Broadcom BCM2709 family" ++ select ARCH_HAS_BARRIERS if SMP ++ select CPU_V7 ++ select HAVE_SMP ++ select ARM_AMBA ++ select MIGHT_HAVE_CACHE_L2X0 ++ select HAVE_SCHED_CLOCK ++ select NEED_MACH_MEMORY_H ++ select NEED_MACH_IO_H ++ select COMMON_CLK ++ select ARCH_HAS_CPUFREQ ++ select GENERIC_CLOCKEVENTS ++ select MACH_BCM2709 ++ select VC4 ++ select FIQ ++ help ++ This enables support for Broadcom BCM2709 boards. ++ + config ARCH_MULTIPLATFORM + bool "Allow multiple platforms to be selected" + depends on MMU +@@ -823,6 +859,9 @@ config ARCH_VIRT + # Kconfigs may be included either alphabetically (according to the + # plat- suffix) or along side the corresponding mach-* source. + # +source "arch/arm/mach-bcm2708/Kconfig" ++source "arch/arm/mach-bcm2709/Kconfig" ++ + source "arch/arm/mach-mvebu/Kconfig" - source "arch/arm/mach-zynq/Kconfig" - + source "arch/arm/mach-alpine/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index 970de75..eaadbe8 100644 +index 0c12ffb..18db6c4 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug -@@ -1209,6 +1209,14 @@ choice +@@ -1197,6 +1197,14 @@ choice options; the platform specific options are deprecated and will be soon removed. @@ -135,22 +200,42 @@ index 970de75..eaadbe8 100644 config DEBUG_AT91_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index eb7bb51..27c0f92 100644 +index 985227c..e5df9a5 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -146,6 +146,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +@@ -142,6 +142,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 + + # Machine directory name. This list is sorted alphanumerically + # by CONFIG_* macro name. ++machine-$(CONFIG_ARCH_BCM2708) += bcm2708 ++machine-$(CONFIG_ARCH_BCM2709) += bcm2709 + machine-$(CONFIG_ARCH_ALPINE) += alpine machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AXXIA) += axxia - machine-$(CONFIG_ARCH_BCM) += bcm -+machine-$(CONFIG_ARCH_BCM2708) += bcm2708 - machine-$(CONFIG_ARCH_BERLIN) += berlin - machine-$(CONFIG_ARCH_CLPS711X) += clps711x - machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx +diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S +index 3637973..380430a 100644 +--- a/arch/arm/kernel/head.S ++++ b/arch/arm/kernel/head.S +@@ -680,6 +680,14 @@ ARM_BE8(rev16 ip, ip) + ldrcc r7, [r4], #4 @ use branch for delay slot + bcc 1b + ret lr ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop + #endif + ENDPROC(__fixup_a_pv_table) + diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index 2bf1a16..2915516 100644 +index f192a2a..f638dae 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c -@@ -172,6 +172,16 @@ void arch_cpu_idle_dead(void) +@@ -98,6 +98,16 @@ void arch_cpu_idle_dead(void) } #endif @@ -164,15 +249,15 @@ index 2bf1a16..2915516 100644 + +__setup("reboot=", reboot_setup); + - /* - * Called by kexec, immediately prior to machine_kexec(). - * + void __show_regs(struct pt_regs *regs) + { + unsigned long flags; diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig new file mode 100644 -index 0000000..1f11478 +index 0000000..4955422 --- /dev/null +++ b/arch/arm/mach-bcm2708/Kconfig -@@ -0,0 +1,26 @@ +@@ -0,0 +1,30 @@ +menu "Broadcom BCM2708 Implementations" + depends on ARCH_BCM2708 + @@ -184,12 +269,16 @@ index 0000000..1f11478 + help + Include support for the Broadcom(R) BCM2708 platform. + -+config BCM2708_VCMEM -+ bool "Videocore Memory" ++config BCM2708_DT ++ bool "BCM2708 Device Tree support" + depends on MACH_BCM2708 -+ default y -+ help -+ Helper for videocore memory access and total size allocation. ++ default n ++ select USE_OF ++ select ARCH_REQUIRE_GPIOLIB ++ select PINCTRL ++ select PINCTRL_BCM2835 ++ help ++ Enable Device Tree support for BCM2708 + +config BCM2708_NOL2CACHE + bool "Videocore L2 cache disable" @@ -201,16 +290,15 @@ index 0000000..1f11478 +endmenu diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile new file mode 100644 -index 0000000..c76f39bc +index 0000000..e7d5a29 --- /dev/null +++ b/arch/arm/mach-bcm2708/Makefile -@@ -0,0 +1,6 @@ +@@ -0,0 +1,5 @@ +# +# Makefile for the linux kernel. +# + -+obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o ++obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o diff --git a/arch/arm/mach-bcm2708/Makefile.boot b/arch/arm/mach-bcm2708/Makefile.boot new file mode 100644 index 0000000..67039c3 @@ -222,10 +310,10 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c new file mode 100644 -index 0000000..ef1c8d5 +index 0000000..cd252fa --- /dev/null +++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -0,0 +1,208 @@ +@@ -0,0 +1,304 @@ +/* + * linux/arch/arm/mach-bcm2708/armctrl.c + * @@ -251,6 +339,8 @@ index 0000000..ef1c8d5 +#include +#include +#include ++#include ++#include + +#include +#include @@ -297,6 +387,99 @@ index 0000000..ef1c8d5 + writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); +} + ++#ifdef CONFIG_OF ++ ++#define NR_IRQS_BANK0 21 ++#define NR_BANKS 3 ++#define IRQS_PER_BANK 32 ++ ++/* from drivers/irqchip/irq-bcm2835.c */ ++static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, ++ const u32 *intspec, unsigned int intsize, ++ unsigned long *out_hwirq, unsigned int *out_type) ++{ ++ if (WARN_ON(intsize != 2)) ++ return -EINVAL; ++ ++ if (WARN_ON(intspec[0] >= NR_BANKS)) ++ return -EINVAL; ++ ++ if (WARN_ON(intspec[1] >= IRQS_PER_BANK)) ++ return -EINVAL; ++ ++ if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0)) ++ return -EINVAL; ++ ++ if (intspec[0] == 0) ++ *out_hwirq = ARM_IRQ0_BASE + intspec[1]; ++ else if (intspec[0] == 1) ++ *out_hwirq = ARM_IRQ1_BASE + intspec[1]; ++ else ++ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; ++ ++ /* reverse remap_irqs[] */ ++ switch (*out_hwirq) { ++ case INTERRUPT_VC_JPEG: ++ *out_hwirq = INTERRUPT_JPEG; ++ break; ++ case INTERRUPT_VC_USB: ++ *out_hwirq = INTERRUPT_USB; ++ break; ++ case INTERRUPT_VC_3D: ++ *out_hwirq = INTERRUPT_3D; ++ break; ++ case INTERRUPT_VC_DMA2: ++ *out_hwirq = INTERRUPT_DMA2; ++ break; ++ case INTERRUPT_VC_DMA3: ++ *out_hwirq = INTERRUPT_DMA3; ++ break; ++ case INTERRUPT_VC_I2C: ++ *out_hwirq = INTERRUPT_I2C; ++ break; ++ case INTERRUPT_VC_SPI: ++ *out_hwirq = INTERRUPT_SPI; ++ break; ++ case INTERRUPT_VC_I2SPCM: ++ *out_hwirq = INTERRUPT_I2SPCM; ++ break; ++ case INTERRUPT_VC_SDIO: ++ *out_hwirq = INTERRUPT_SDIO; ++ break; ++ case INTERRUPT_VC_UART: ++ *out_hwirq = INTERRUPT_UART; ++ break; ++ case INTERRUPT_VC_ARASANSDIO: ++ *out_hwirq = INTERRUPT_ARASANSDIO; ++ break; ++ } ++ ++ *out_type = IRQ_TYPE_NONE; ++ return 0; ++} ++ ++static struct irq_domain_ops armctrl_ops = { ++ .xlate = armctrl_xlate ++}; ++ ++void __init armctrl_dt_init(void) ++{ ++ struct device_node *np; ++ struct irq_domain *domain; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic"); ++ if (!np) ++ return; ++ ++ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS, ++ IRQ_ARMCTRL_START, 0, ++ &armctrl_ops, NULL); ++ WARN_ON(!domain); ++} ++#else ++void __init armctrl_dt_init(void) { } ++#endif /* CONFIG_OF */ ++ +#if defined(CONFIG_PM) + +/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ @@ -432,6 +615,7 @@ index 0000000..ef1c8d5 + } + + armctrl_pm_register(base, irq_start, resume_sources); ++ armctrl_dt_init(); + return 0; +} diff --git a/arch/arm/mach-bcm2708/armctrl.h b/arch/arm/mach-bcm2708/armctrl.h @@ -469,10 +653,10 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c new file mode 100644 -index 0000000..9b4e709 +index 0000000..d6659b0 --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -0,0 +1,662 @@ +@@ -0,0 +1,622 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708.c + * @@ -502,10 +686,14 @@ index 0000000..9b4e709 +#include +#include +#include ++#include ++#include +#include +#include +#include +#include ++#include ++#include + +#include +#include @@ -523,15 +711,12 @@ index 0000000..9b4e709 +#include + +#include -+#include -+#include +#include + +#include + +#include "bcm2708.h" +#include "armctrl.h" -+#include "clock.h" + +#ifdef CONFIG_BCM_VC_CMA +#include @@ -552,11 +737,13 @@ index 0000000..9b4e709 + +/* command line parameters */ +static unsigned boardrev, serial; -+static unsigned uart_clock; ++static unsigned uart_clock = UART0_CLOCK; +static unsigned disk_led_gpio = 16; +static unsigned disk_led_active_low = 1; +static unsigned reboot_part = 0; + ++static unsigned use_dt = 0; ++ +static void __init bcm2708_init_led(void); + +void __init bcm2708_init_irq(void) @@ -662,44 +849,40 @@ index 0000000..9b4e709 + } +} + ++struct clk __init *bcm2708_clk_register(const char *name, unsigned long fixed_rate) ++{ ++ struct clk *clk; + -+/* -+ * These are fixed clocks. -+ */ -+static struct clk ref24_clk = { -+ .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */ -+}; ++ clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, ++ fixed_rate); ++ if (IS_ERR(clk)) ++ pr_err("%s not registered\n", name); + -+static struct clk osc_clk = { -+#ifdef CONFIG_ARCH_BCM2708_CHIPIT -+ .rate = 27000000, -+#else -+ .rate = 500000000, /* ARM clock is set from the VideoCore booter */ -+#endif -+}; ++ return clk; ++} + -+/* warning - the USB needs a clock > 34MHz */ ++void __init bcm2708_register_clkdev(struct clk *clk, const char *name) ++{ ++ int ret; + -+#ifdef CONFIG_MMC_BCM2708 -+static struct clk sdhost_clk = { -+#ifdef CONFIG_ARCH_BCM2708_CHIPIT -+ .rate = 4000000, /* 4MHz */ -+#else -+ .rate = 250000000, /* 250MHz */ -+#endif -+}; -+#endif ++ ret = clk_register_clkdev(clk, NULL, name); ++ if (ret) ++ pr_err("%s alias not registered\n", name); ++} + -+static struct clk_lookup lookups[] = { -+ { /* UART0 */ -+ .dev_id = "dev:f1", -+ .clk = &ref24_clk, -+ }, -+ { /* USB */ -+ .dev_id = "bcm2708_usb", -+ .clk = &osc_clk, -+ } -+}; ++void __init bcm2708_init_clocks(void) ++{ ++ struct clk *clk; ++ ++ clk = bcm2708_clk_register("uart0_clk", uart_clock); ++ bcm2708_register_clkdev(clk, "dev:f1"); ++ ++ clk = bcm2708_clk_register("sdhost_clk", 250000000); ++ bcm2708_register_clkdev(clk, "mmc-bcm2835.0"); ++ bcm2708_register_clkdev(clk, "bcm2708_spi.0"); ++ bcm2708_register_clkdev(clk, "bcm2708_i2c.0"); ++ bcm2708_register_clkdev(clk, "bcm2708_i2c.1"); ++} + +#define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ } +#define UART0_DMA { 15, 14 } @@ -710,21 +893,6 @@ index 0000000..9b4e709 + &uart0_device, +}; + -+static struct resource bcm2708_dmaman_resources[] = { -+ { -+ .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), -+}; -+ +static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_fb_device = { @@ -738,38 +906,17 @@ index 0000000..9b4e709 + }, +}; + -+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, -+ }, -+ {}, -+}; -+ -+static struct platform_device bcm2708_uart1_device = { -+ .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, -+ }, ++ .start = USB_BASE, ++ .end = USB_BASE + SZ_128K - 1, ++ .flags = IORESOURCE_MEM, ++ }, + [1] = { -+ .start = IRQ_USB, -+ .end = IRQ_USB, -+ .flags = IORESOURCE_IRQ, -+ }, ++ .start = IRQ_USB, ++ .end = IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, +}; + +static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); @@ -786,17 +933,21 @@ index 0000000..9b4e709 +}; + +static struct resource bcm2708_vcio_resources[] = { -+ [0] = { /* mailbox/semaphore/doorbell access */ -+ .start = MCORE_BASE, -+ .end = MCORE_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, ++ { ++ .start = ARMCTRL_0_MAIL0_BASE, ++ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_MAILBOX, ++ .end = IRQ_ARM_MAILBOX, ++ .flags = IORESOURCE_IRQ, ++ }, +}; + +static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_vcio_device = { -+ .name = BCM_VCIO_DRIVER_NAME, ++ .name = "bcm2708_vcio", + .id = -1, /* only one VideoCore I/O area */ + .resource = bcm2708_vcio_resources, + .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), @@ -806,53 +957,6 @@ index 0000000..9b4e709 + }, +}; + -+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, -+ } -+ -+}; -+ -+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), -+ }, -+}; -+ -+static struct resource bcm2708_powerman_resources[] = { -+ [0] = { -+ .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}, -+}; -+ +int __init bcm_register_device(struct platform_device *pdev) +{ + int ret; @@ -865,6 +969,16 @@ index 0000000..9b4e709 + return ret; +} + ++/* ++ * Use these macros for platform and i2c devices that are present in the ++ * Device Tree. This way the devices are only added on non-DT systems. ++ */ ++#define bcm_register_device_dt(pdev) \ ++ if (!use_dt) bcm_register_device(pdev) ++ ++#define i2c_register_board_info_dt(busnum, info, n) \ ++ if (!use_dt) i2c_register_board_info(busnum, info, n) ++ +int calc_rsts(int partition) +{ + return PM_PASSWORD | @@ -930,6 +1044,35 @@ index 0000000..9b4e709 + } +} + ++static void __init bcm2708_init_uart1(void) ++{ ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); ++ if (of_device_is_available(np)) { ++ pr_info("bcm2708: Mini UART enabled\n"); ++ writel(1, __io_address(UART1_BASE + 0x4)); ++ } ++} ++ ++#ifdef CONFIG_OF ++static void __init bcm2708_dt_init(void) ++{ ++ int ret; ++ ++ of_clk_init(NULL); ++ ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++ if (ret) { ++ pr_err("of_platform_populate failed: %d\n", ret); ++ /* Proceed as if CONFIG_OF was not defined */ ++ } else { ++ use_dt = 1; ++ } ++} ++#else ++static void __init bcm2708_dt_init(void) { } ++#endif /* CONFIG_OF */ ++ +void __init bcm2708_init(void) +{ + int i; @@ -940,25 +1083,24 @@ index 0000000..9b4e709 + printk("bcm2708.uart_clock = %d\n", uart_clock); + pm_power_off = bcm2708_power_off; + -+ if (uart_clock) -+ lookups[0].clk->rate = uart_clock; ++ bcm2708_init_clocks(); ++ bcm2708_dt_init(); + -+ for (i = 0; i < ARRAY_SIZE(lookups); i++) -+ clkdev_add(&lookups[i]); -+ -+ bcm_register_device(&bcm2708_dmaman_device); + bcm_register_device(&bcm2708_vcio_device); -+ bcm_register_device(&bcm2708_systemtimer_device); -+ bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device(&bcm2708_uart1_device); -+ bcm_register_device(&bcm2708_powerman_device); ++#ifdef CONFIG_BCM2708_GPIO ++ bcm_register_device_dt(&bcm2708_gpio_device); ++#endif ++ bcm_register_device_dt(&bcm2708_fb_device); ++ bcm_register_device_dt(&bcm2708_usb_device); + + bcm2708_init_led(); ++ bcm2708_init_uart1(); + -+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -+ struct amba_device *d = amba_devs[i]; -+ amba_device_register(d, &iomem_resource); ++ if (!use_dt) { ++ 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; @@ -1041,10 +1183,6 @@ index 0000000..9b4e709 + bcm2708_clocksource_init(); + + /* -+ * Initialise to a known state (all timers off) -+ */ -+ writel(0, __io_address(ARM_T_CONTROL)); -+ /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMER3, &bcm2708_timer_irq); @@ -1091,9 +1229,9 @@ index 0000000..9b4e709 + +static void __init bcm2708_init_led(void) +{ -+ bcm2708_leds[0].gpio = disk_led_gpio; -+ bcm2708_leds[0].active_low = disk_led_active_low; -+ platform_device_register(&bcm2708_led_device); ++ bcm2708_leds[0].gpio = disk_led_gpio; ++ bcm2708_leds[0].active_low = disk_led_active_low; ++ bcm_register_device_dt(&bcm2708_led_device); +} +#else +static inline void bcm2708_init_led(void) @@ -1118,6 +1256,11 @@ index 0000000..9b4e709 +#endif +} + ++static const char * const bcm2708_compat[] = { ++ "brcm,bcm2708", ++ NULL ++}; ++ +MACHINE_START(BCM2708, "BCM2708") + /* Maintainer: Broadcom Europe Ltd. */ + .map_io = bcm2708_map_io, @@ -1127,6 +1270,7 @@ index 0000000..9b4e709 + .init_early = bcm2708_init_early, + .reserve = board_reserve, + .restart = bcm2708_restart, ++ .dt_compat = bcm2708_compat, +MACHINE_END + +module_param(boardrev, uint, 0644); @@ -1190,508 +1334,6 @@ index 0000000..e339a93 +} + +#endif -diff --git a/arch/arm/mach-bcm2708/clock.c b/arch/arm/mach-bcm2708/clock.c -new file mode 100644 -index 0000000..4fc556e ---- /dev/null -+++ b/arch/arm/mach-bcm2708/clock.c -@@ -0,0 +1,61 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "clock.h" -+ -+int clk_enable(struct clk *clk) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(clk_enable); -+ -+void clk_disable(struct clk *clk) -+{ -+} -+EXPORT_SYMBOL(clk_disable); -+ -+unsigned long clk_get_rate(struct clk *clk) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_get_rate); -+ -+long clk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_round_rate); -+ -+int clk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ return -EIO; -+} -+EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2708/clock.h b/arch/arm/mach-bcm2708/clock.h -new file mode 100644 -index 0000000..5f9d725 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/clock.h -@@ -0,0 +1,24 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 -+ */ -+struct module; -+ -+struct clk { -+ unsigned long rate; -+}; -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -new file mode 100644 -index 0000000..51d147a ---- /dev/null -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -0,0 +1,399 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/dma.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/*****************************************************************************\ -+ * * -+ * Configuration * -+ * * -+\*****************************************************************************/ -+ -+#define CACHE_LINE_MASK 31 -+#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME -+#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -+ -+/* valid only for channels 0 - 14, 15 has its own base address */ -+#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ -+#define BCM2708_DMA_CHANIO(dma_base, n) \ -+ ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -+ -+ -+/*****************************************************************************\ -+ * * -+ * DMA Auxilliary Functions * -+ * * -+\*****************************************************************************/ -+ -+/* A DMA buffer on an arbitrary boundary may separate a cache line into a -+ section inside the DMA buffer and another section outside it. -+ Even if we flush DMA buffers from the cache there is always the chance that -+ during a DMA someone will access the part of a cache line that is outside -+ the DMA buffer - which will then bring in unwelcome data. -+ Without being able to dictate our own buffer pools we must insist that -+ DMA buffers consist of a whole number of cache lines. -+*/ -+ -+extern int -+bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) -+{ -+ int i; -+ -+ for (i = 0; i < sg_len; i++) { -+ if (sg_ptr[i].offset & CACHE_LINE_MASK || -+ sg_ptr[i].length & CACHE_LINE_MASK) -+ return 0; -+ } -+ -+ return 1; -+} -+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -+ -+extern void -+bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) -+{ -+ dsb(); /* ARM data synchronization (push) operation */ -+ -+ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -+ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); -+} -+ -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ /* ugly busy wait only option for now */ -+ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -+ cpu_relax(); -+} -+ -+EXPORT_SYMBOL_GPL(bcm_dma_start); -+ -+/* Complete an ongoing DMA (assuming its results are to be ignored) -+ Does nothing if there is no DMA in progress. -+ This routine waits for the current AXI transfer to complete before -+ terminating the current DMA. If the current transfer is hung on a DREQ used -+ by an uncooperative peripheral the AXI transfer may never complete. In this -+ case the routine times out and return a non-zero error code. -+ Use of this routine doesn't guarantee that the ongoing or aborted DMA -+ does not produce an interrupt. -+*/ -+extern int -+bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ unsigned long int cs; -+ int rc = 0; -+ -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (BCM2708_DMA_ACTIVE & cs) { -+ long int timeout = 10000; -+ -+ /* write 0 to the active bit - pause the DMA */ -+ writel(0, dma_chan_base + BCM2708_DMA_CS); -+ -+ /* wait for any current AXI transfer to complete */ -+ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -+ /* we'll un-pause when we set of our next DMA */ -+ rc = -ETIMEDOUT; -+ -+ } else if (BCM2708_DMA_ACTIVE & cs) { -+ /* terminate the control block chain */ -+ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -+ -+ /* abort the whole DMA */ -+ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -+ dma_chan_base + BCM2708_DMA_CS); -+ } -+ } -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_abort); -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Device Methods * -+ * * -+\*****************************************************************************/ -+ -+struct vc_dmaman { -+ void __iomem *dma_base; -+ u32 chan_available; /* bitmap of available channels */ -+ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ -+}; -+ -+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -+ u32 chans_available) -+{ -+ dmaman->dma_base = dma_base; -+ dmaman->chan_available = chans_available; -+ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -+} -+ -+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) -+{ -+ u32 chans; -+ int feature; -+ -+ chans = dmaman->chan_available; -+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -+ /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) -+ chans &= dmaman->has_feature[feature]; -+ -+ if (chans) { -+ int chan = 0; -+ /* return the ordinal of the first channel in the bitmap */ -+ while (chans != 0 && (chans & 1) == 0) { -+ chans >>= 1; -+ chan++; -+ } -+ /* claim the channel */ -+ dmaman->chan_available &= ~(1 << chan); -+ return chan; -+ } else -+ return -ENOMEM; -+} -+ -+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) -+{ -+ if (chan < 0) -+ return -EINVAL; -+ else if ((1 << chan) & dmaman->chan_available) -+ return -EIDRM; -+ else { -+ dmaman->chan_available |= (1 << chan); -+ return 0; -+ } -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA IRQs * -+ * * -+\*****************************************************************************/ -+ -+static unsigned char bcm_dma_irqs[] = { -+ IRQ_DMA0, -+ IRQ_DMA1, -+ IRQ_DMA2, -+ IRQ_DMA3, -+ IRQ_DMA4, -+ IRQ_DMA5, -+ IRQ_DMA6, -+ IRQ_DMA7, -+ IRQ_DMA8, -+ IRQ_DMA9, -+ IRQ_DMA10, -+ IRQ_DMA11, -+ IRQ_DMA12 -+}; -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Monitor * -+ * * -+\*****************************************************************************/ -+ -+static struct device *dmaman_dev; /* we assume there's only one! */ -+ -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq) -+{ -+ if (!dmaman_dev) -+ return -ENODEV; -+ else { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ if (rc >= 0) { -+ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -+ rc); -+ *out_dma_irq = bcm_dma_irqs[rc]; -+ } -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -+ -+extern int bcm_dma_chan_free(int channel) -+{ -+ if (dmaman_dev) { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_free(dmaman, channel); -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -+ -+static int dev_dmaman_register(const char *dev_name, struct device *dev) -+{ -+ int rc = dmaman_dev ? -EINVAL : 0; -+ dmaman_dev = dev; -+ return rc; -+} -+ -+static void dev_dmaman_deregister(const char *dev_name, struct device *dev) -+{ -+ dmaman_dev = NULL; -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA Device * -+ * * -+\*****************************************************************************/ -+ -+static int dmachans = -1; /* module parameter */ -+ -+static int bcm_dmaman_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_dmaman *dmaman; -+ struct resource *dma_res = NULL; -+ void __iomem *dma_base = NULL; -+ int have_dma_region = 0; -+ -+ dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -+ if (NULL == dmaman) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "DMA management memory\n"); -+ ret = -ENOMEM; -+ } else { -+ -+ dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (dma_res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ } else if (!request_mem_region(dma_res->start, -+ resource_size(dma_res), -+ DRIVER_NAME)) { -+ dev_err(&pdev->dev, "cannot obtain DMA region\n"); -+ ret = -EBUSY; -+ } else { -+ have_dma_region = 1; -+ dma_base = ioremap(dma_res->start, -+ resource_size(dma_res)); -+ if (!dma_base) { -+ dev_err(&pdev->dev, "cannot map DMA region\n"); -+ ret = -ENOMEM; -+ } else { -+ /* use module parameter if one was provided */ -+ if (dmachans > 0) -+ vc_dmaman_init(dmaman, dma_base, -+ dmachans); -+ else -+ vc_dmaman_init(dmaman, dma_base, -+ DEFAULT_DMACHAN_BITMAP); -+ -+ platform_set_drvdata(pdev, dmaman); -+ dev_dmaman_register(DRIVER_NAME, &pdev->dev); -+ -+ printk(KERN_INFO DRIVER_NAME ": DMA manager " -+ "at %p\n", dma_base); -+ } -+ } -+ } -+ if (ret != 0) { -+ if (dma_base) -+ iounmap(dma_base); -+ if (dma_res && have_dma_region) -+ release_mem_region(dma_res->start, -+ resource_size(dma_res)); -+ if (dmaman) -+ kfree(dmaman); -+ } -+ return ret; -+} -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -+ kfree(dmaman); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_dmaman_driver = { -+ .probe = bcm_dmaman_probe, -+ .remove = bcm_dmaman_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+/*****************************************************************************\ -+ * * -+ * Driver init/exit * -+ * * -+\*****************************************************************************/ -+ -+static int __init bcm_dmaman_drv_init(void) -+{ -+ int ret; -+ -+ ret = platform_driver_register(&bcm_dmaman_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_dmaman_drv_exit(void) -+{ -+ platform_driver_unregister(&bcm_dmaman_driver); -+} -+ -+module_init(bcm_dmaman_drv_init); -+module_exit(bcm_dmaman_drv_exit); -+ -+module_param(dmachans, int, 0644); -+ -+MODULE_AUTHOR("Gray Girling "); -+MODULE_DESCRIPTION("DMA channel manager driver"); -+MODULE_LICENSE("GPL"); -+ -+MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); diff --git a/arch/arm/mach-bcm2708/include/mach/arm_control.h b/arch/arm/mach-bcm2708/include/mach/arm_control.h new file mode 100644 index 0000000..a82bb92b @@ -2117,74 +1759,6 @@ index 0000000..a82bb92b +#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c) + +#endif -diff --git a/arch/arm/mach-bcm2708/include/mach/arm_power.h b/arch/arm/mach-bcm2708/include/mach/arm_power.h -new file mode 100644 -index 0000000..d3bf245 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/arm_power.h -@@ -0,0 +1,62 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _ARM_POWER_H -+#define _ARM_POWER_H -+ -+/* Use meaningful names on each side */ -+#ifdef __VIDEOCORE__ -+#define PREFIX(x) ARM_##x -+#else -+#define PREFIX(x) BCM_##x -+#endif -+ -+enum { -+ PREFIX(POWER_SDCARD_BIT), -+ PREFIX(POWER_UART_BIT), -+ PREFIX(POWER_MINIUART_BIT), -+ PREFIX(POWER_USB_BIT), -+ PREFIX(POWER_I2C0_BIT), -+ PREFIX(POWER_I2C1_BIT), -+ PREFIX(POWER_I2C2_BIT), -+ PREFIX(POWER_SPI_BIT), -+ PREFIX(POWER_CCP2TX_BIT), -+ PREFIX(POWER_DSI_BIT), -+ -+ PREFIX(POWER_MAX) -+}; -+ -+enum { -+ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -+ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -+ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -+ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -+ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -+ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -+ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -+ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -+ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -+ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -+ -+ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -+ PREFIX(POWER_NONE) = 0 -+}; -+ -+#endif diff --git a/arch/arm/mach-bcm2708/include/mach/clkdev.h b/arch/arm/mach-bcm2708/include/mach/clkdev.h new file mode 100644 index 0000000..04b37a8 @@ -2226,100 +1800,6 @@ index 0000000..b24304a + .endm + +#include -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -new file mode 100644 -index 0000000..f2568d4 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -0,0 +1,88 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/dma.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+ -+#ifndef _MACH_BCM2708_DMA_H -+#define _MACH_BCM2708_DMA_H -+ -+#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -+ -+/* DMA CS Control and Status bits */ -+#define BCM2708_DMA_ACTIVE (1 << 0) -+#define BCM2708_DMA_INT (1 << 2) -+#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ -+#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ -+#define BCM2708_DMA_ERR (1 << 8) -+#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ -+#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -+ -+/* DMA control block "info" field bits */ -+#define BCM2708_DMA_INT_EN (1 << 0) -+#define BCM2708_DMA_TDMODE (1 << 1) -+#define BCM2708_DMA_WAIT_RESP (1 << 3) -+#define BCM2708_DMA_D_INC (1 << 4) -+#define BCM2708_DMA_D_WIDTH (1 << 5) -+#define BCM2708_DMA_D_DREQ (1 << 6) -+#define BCM2708_DMA_S_INC (1 << 8) -+#define BCM2708_DMA_S_WIDTH (1 << 9) -+#define BCM2708_DMA_S_DREQ (1 << 10) -+ -+#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) -+#define BCM2708_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -+ -+#define BCM2708_DMA_DREQ_EMMC 11 -+#define BCM2708_DMA_DREQ_SDHOST 13 -+ -+#define BCM2708_DMA_CS 0x00 /* Control and Status */ -+#define BCM2708_DMA_ADDR 0x04 -+/* the current control block appears in the following registers - read only */ -+#define BCM2708_DMA_INFO 0x08 -+#define BCM2708_DMA_SOURCE_AD 0x0c -+#define BCM2708_DMA_DEST_AD 0x10 -+#define BCM2708_DMA_NEXTCB 0x1C -+#define BCM2708_DMA_DEBUG 0x20 -+ -+#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) -+#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -+ -+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -+ -+struct bcm2708_dma_cb { -+ unsigned long info; -+ unsigned long src; -+ unsigned long dst; -+ unsigned long length; -+ unsigned long stride; -+ unsigned long next; -+ unsigned long pad[2]; -+}; -+ -+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); -+extern void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block); -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -+ -+/* When listing features we can ask for when allocating DMA channels give -+ those with higher priority smaller ordinal numbers */ -+#define BCM_DMA_FEATURE_FAST_ORD 0 -+#define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_FAST (1< -+#include -+ -+typedef unsigned int BCM_POWER_HANDLE_T; -+ -+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); -+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); -+extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -+ -+#endif diff --git a/arch/arm/mach-bcm2708/include/mach/system.h b/arch/arm/mach-bcm2708/include/mach/system.h new file mode 100644 index 0000000..2d0b821 @@ -3200,218 +2648,6 @@ index 0000000..d634813 + * nothing to do + */ +#define arch_decomp_wdog() -diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h -new file mode 100644 -index 0000000..4a4a338 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/vc_mem.h -@@ -0,0 +1,35 @@ -+/***************************************************************************** -+* Copyright 2010 - 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. -+*****************************************************************************/ -+ -+#if !defined( VC_MEM_H ) -+#define VC_MEM_H -+ -+#include -+ -+#define VC_MEM_IOC_MAGIC 'v' -+ -+#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 ) -+#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -+ -+#if defined( __KERNEL__ ) -+#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -+ -+extern unsigned long mm_vc_mem_phys_addr; -+extern unsigned int mm_vc_mem_size; -+extern int vc_mem_get_current_size( void ); -+#endif -+ -+#endif /* VC_MEM_H */ -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -new file mode 100644 -index 0000000..8e11d67e ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h -@@ -0,0 +1,165 @@ -+/* -+ * arch/arm/mach-bcm2708/include/mach/vcio.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _MACH_BCM2708_VCIO_H -+#define _MACH_BCM2708_VCIO_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); -+extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); -+extern int /*rc*/ bcm_mailbox_property(void *data, int size); -+ -+#include -+ -+/* -+ * The major device number. We can't rely on dynamic -+ * registration any more, because ioctls need to know -+ * it. -+ */ -+#define MAJOR_NUM 100 -+ -+/* -+ * Set the message of the device driver -+ */ -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+/* -+ * _IOWR means that we're creating an ioctl command -+ * number for passing information from a user process -+ * to the kernel module and from the kernel module to user process -+ * -+ * The first arguments, MAJOR_NUM, is the major device -+ * number we're using. -+ * -+ * The second argument is the number of the command -+ * (there could be several with different meanings). -+ * -+ * The third argument is the type we want to get from -+ * the process to the kernel. -+ */ -+ -+/* -+ * The name of the device file -+ */ -+#define DEVICE_FILE_NAME "vcio" -+ -+#endif diff --git a/arch/arm/mach-bcm2708/include/mach/vmalloc.h b/arch/arm/mach-bcm2708/include/mach/vmalloc.h new file mode 100644 index 0000000..502c617 @@ -3438,1370 +2674,12 @@ index 0000000..502c617 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define VMALLOC_END (0xe8000000) -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -new file mode 100644 -index 0000000..2696be9 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/power.c -@@ -0,0 +1,197 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/power.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_power" -+ -+#define BCM_POWER_MAXCLIENTS 4 -+#define BCM_POWER_NOCLIENT (1<<31) -+ -+/* Some drivers expect there devices to be permanently powered */ -+ -+#ifdef CONFIG_USB -+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) -+#endif -+ -+#if 1 -+#define DPRINTK printk -+#else -+#define DPRINTK if (0) printk -+#endif -+ -+struct state_struct { -+ uint32_t global_request; -+ uint32_t client_request[BCM_POWER_MAXCLIENTS]; -+ struct semaphore client_mutex; -+ struct semaphore mutex; -+} g_state; -+ -+int bcm_power_open(BCM_POWER_HANDLE_T *handle) -+{ -+ BCM_POWER_HANDLE_T i; -+ int ret = -EBUSY; -+ -+ down(&g_state.client_mutex); -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -+ g_state.client_request[i] = BCM_POWER_NONE; -+ *handle = i; -+ ret = 0; -+ break; -+ } -+ } -+ -+ up(&g_state.client_mutex); -+ -+ DPRINTK("bcm_power_open() -> %d\n", *handle); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(bcm_power_open); -+ -+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) -+{ -+ int rc = 0; -+ -+ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -+ -+ if ((handle < BCM_POWER_MAXCLIENTS) && -+ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -+ if (down_interruptible(&g_state.mutex) != 0) { -+ DPRINTK("bcm_power_request -> interrupted\n"); -+ return -EINTR; -+ } -+ -+ if (request != g_state.client_request[handle]) { -+ uint32_t others_request = 0; -+ uint32_t global_request; -+ BCM_POWER_HANDLE_T i; -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (i != handle) -+ others_request |= -+ g_state.client_request[i]; -+ } -+ others_request &= ~BCM_POWER_NOCLIENT; -+ -+ global_request = request | others_request; -+ if (global_request != g_state.global_request) { -+ uint32_t actual; -+ -+ /* Send a request to VideoCore */ -+ 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); -+ DPRINTK -+ ("bcm_mailbox_read -> %08x, %d\n", -+ actual, rc); -+ actual >>= 4; -+ } else { -+ rc = 0; -+ actual = global_request; -+ } -+ -+ 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", -+ __func__, -+ g_state.global_request, -+ global_request, actual, request, others_request); -+ /* A failure */ -+ BUG_ON((others_request & actual) -+ != others_request); -+ request &= actual; -+ rc = -EIO; -+ } -+ -+ g_state.global_request = actual; -+ g_state.client_request[handle] = -+ request; -+ } -+ } -+ } -+ up(&g_state.mutex); -+ } else { -+ rc = -EINVAL; -+ } -+ DPRINTK("bcm_power_request -> %d\n", rc); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_request); -+ -+int bcm_power_close(BCM_POWER_HANDLE_T handle) -+{ -+ int rc; -+ -+ DPRINTK("bcm_power_close(%d)\n", handle); -+ -+ rc = bcm_power_request(handle, BCM_POWER_NONE); -+ if (rc == 0) -+ g_state.client_request[handle] = BCM_POWER_NOCLIENT; -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_close); -+ -+static int __init bcm_power_init(void) -+{ -+#if defined(BCM_POWER_ALWAYS_ON) -+ BCM_POWER_HANDLE_T always_on_handle; -+#endif -+ int rc = 0; -+ 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; -+ -+ sema_init(&g_state.client_mutex, 1); -+ sema_init(&g_state.mutex, 1); -+ -+ g_state.global_request = 0; -+ -+#if defined(BCM_POWER_ALWAYS_ON) -+ if (BCM_POWER_ALWAYS_ON) { -+ bcm_power_open(&always_on_handle); -+ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -+ } -+#endif -+ -+ return rc; -+} -+ -+static void __exit bcm_power_exit(void) -+{ -+ bcm_mailbox_write(MBOX_CHAN_POWER, 0); -+} -+ -+arch_initcall(bcm_power_init); /* Initialize early */ -+module_exit(bcm_power_exit); -+ -+MODULE_AUTHOR("Phil Elwell"); -+MODULE_DESCRIPTION("Interface to BCM2708 power management"); -+MODULE_LICENSE("GPL"); -diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c -new file mode 100644 -index 0000000..2982af7 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/vc_mem.c -@@ -0,0 +1,431 @@ -+/***************************************************************************** -+* Copyright 2010 - 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 -+ -+#ifdef CONFIG_ARCH_KONA -+#include -+#elif CONFIG_ARCH_BCM2708 -+#else -+#include -+#endif -+ -+#include "mach/vc_mem.h" -+#include -+ -+#define DRIVER_NAME "vc-mem" -+ -+// Device (/dev) related variables -+static dev_t vc_mem_devnum = 0; -+static struct class *vc_mem_class = NULL; -+static struct cdev vc_mem_cdev; -+static int vc_mem_inited = 0; -+ -+#ifdef CONFIG_DEBUG_FS -+static struct dentry *vc_mem_debugfs_entry; -+#endif -+ -+/* -+ * Videocore memory addresses and size -+ * -+ * Drivers that wish to know the videocore memory addresses and sizes should -+ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -+ * headers. This allows the other drivers to not be tied down to a a certain -+ * address/size at compile time. -+ * -+ * In the future, the goal is to have the videocore memory virtual address and -+ * size be calculated at boot time rather than at compile time. The decision of -+ * where the videocore memory resides and its size would be in the hands of the -+ * bootloader (and/or kernel). When that happens, the values of these variables -+ * would be calculated and assigned in the init function. -+ */ -+// in the 2835 VC in mapped above ARM, but ARM has full access to VC space -+unsigned long mm_vc_mem_phys_addr = 0x00000000; -+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); -+ -+static uint phys_addr = 0; -+static uint mem_size = 0; -+static uint mem_base = 0; -+ -+ -+/**************************************************************************** -+* -+* vc_mem_open -+* -+***************************************************************************/ -+ -+static int -+vc_mem_open(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_release -+* -+***************************************************************************/ -+ -+static int -+vc_mem_release(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_size -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_size(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_base -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_base(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_current_size -+* -+***************************************************************************/ -+ -+int -+vc_mem_get_current_size(void) -+{ -+ return mm_vc_mem_size; -+} -+ -+EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -+ -+/**************************************************************************** -+* -+* vc_mem_ioctl -+* -+***************************************************************************/ -+ -+static long -+vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int rc = 0; -+ -+ (void) cmd; -+ (void) arg; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ switch (cmd) { -+ case VC_MEM_IOC_MEM_PHYS_ADDR: -+ { -+ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -+ __func__, (void *) mm_vc_mem_phys_addr); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -+ sizeof (mm_vc_mem_phys_addr)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_SIZE: -+ { -+ // Get the videocore memory size first -+ vc_mem_get_size(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -+ mm_vc_mem_size); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_size, -+ sizeof (mm_vc_mem_size)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_BASE: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -+ mm_vc_mem_base); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_base, -+ sizeof (mm_vc_mem_base)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_LOAD: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -+ { -+ return -ENOTTY; -+ } -+ } -+ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_mmap -+* -+***************************************************************************/ -+ -+static int -+vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ int rc = 0; -+ unsigned long length = vma->vm_end - vma->vm_start; -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ -+ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -+ __func__, (long) vma->vm_start, (long) vma->vm_end, -+ (long) vma->vm_pgoff); -+ -+ if (offset + length > mm_vc_mem_size) { -+ pr_err("%s: length %ld is too big\n", __func__, length); -+ return -EINVAL; -+ } -+ // Do not cache the memory map -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ -+ rc = remap_pfn_range(vma, vma->vm_start, -+ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -+ vma->vm_pgoff, length, vma->vm_page_prot); -+ if (rc != 0) { -+ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -+ } -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* File Operations for the driver. -+* -+***************************************************************************/ -+ -+static const struct file_operations vc_mem_fops = { -+ .owner = THIS_MODULE, -+ .open = vc_mem_open, -+ .release = vc_mem_release, -+ .unlocked_ioctl = vc_mem_ioctl, -+ .mmap = vc_mem_mmap, -+}; -+ -+#ifdef CONFIG_DEBUG_FS -+static void vc_mem_debugfs_deinit(void) -+{ -+ debugfs_remove_recursive(vc_mem_debugfs_entry); -+ vc_mem_debugfs_entry = NULL; -+} -+ -+ -+static int vc_mem_debugfs_init( -+ struct device *dev) -+{ -+ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -+ if (!vc_mem_debugfs_entry) { -+ dev_warn(dev, "could not create debugfs entry\n"); -+ return -EFAULT; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_phys_addr", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_phys_addr)) { -+ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_size", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_size)) { -+ dev_warn(dev, "%s:could not create vc_mem_size entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_base", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_base)) { -+ dev_warn(dev, "%s:could not create vc_mem_base entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ vc_mem_debugfs_deinit(); -+ return -EFAULT; -+} -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -+ -+/**************************************************************************** -+* -+* vc_mem_init -+* -+***************************************************************************/ -+ -+static int __init -+vc_mem_init(void) -+{ -+ int rc = -EFAULT; -+ struct device *dev; -+ -+ pr_debug("%s: called\n", __func__); -+ -+ mm_vc_mem_phys_addr = phys_addr; -+ mm_vc_mem_size = mem_size; -+ mm_vc_mem_base = mem_base; -+ -+ vc_mem_get_size(); -+ -+ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -+ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -+ -+ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -+ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -+ __func__, rc); -+ goto out_err; -+ } -+ -+ cdev_init(&vc_mem_cdev, &vc_mem_fops); -+ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -+ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -+ goto out_unregister; -+ } -+ -+ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vc_mem_class)) { -+ rc = PTR_ERR(vc_mem_class); -+ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -+ goto out_cdev_del; -+ } -+ -+ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -+ DRIVER_NAME); -+ if (IS_ERR(dev)) { -+ rc = PTR_ERR(dev); -+ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -+ goto out_class_destroy; -+ } -+ -+#ifdef CONFIG_DEBUG_FS -+ /* don't fail if the debug entries cannot be created */ -+ vc_mem_debugfs_init(dev); -+#endif -+ -+ vc_mem_inited = 1; -+ return 0; -+ -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ -+ out_class_destroy: -+ class_destroy(vc_mem_class); -+ vc_mem_class = NULL; -+ -+ out_cdev_del: -+ cdev_del(&vc_mem_cdev); -+ -+ out_unregister: -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ -+ out_err: -+ return -1; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_exit -+* -+***************************************************************************/ -+ -+static void __exit -+vc_mem_exit(void) -+{ -+ pr_debug("%s: called\n", __func__); -+ -+ if (vc_mem_inited) { -+#if CONFIG_DEBUG_FS -+ vc_mem_debugfs_deinit(); -+#endif -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ class_destroy(vc_mem_class); -+ cdev_del(&vc_mem_cdev); -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ } -+} -+ -+module_init(vc_mem_init); -+module_exit(vc_mem_exit); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Broadcom Corporation"); -+ -+module_param(phys_addr, uint, 0644); -+module_param(mem_size, uint, 0644); -+module_param(mem_base, uint, 0644); -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -new file mode 100644 -index 0000000..5e43e85 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -0,0 +1,474 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -+#define SUPPORT_SYSRQ -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+ -+ -+#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* offsets from a mail box base address */ -+#define MAIL_WRT 0x00 /* write - and next 4 words */ -+#define MAIL_RD 0x00 /* read - and next 4 words */ -+#define MAIL_POL 0x10 /* read without popping the fifo */ -+#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL_STA 0x18 /* status */ -+#define MAIL_CNF 0x1C /* configuration */ -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+struct vc_mailbox { -+ struct device *dev; /* parent device */ -+ void __iomem *status; -+ void __iomem *config; -+ void __iomem *read; -+ void __iomem *write; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -+ uint32_t addr_mbox) -+{ -+ int i; -+ -+ mbox_out->dev = dev; -+ mbox_out->status = __io_address(addr_mbox + MAIL_STA); -+ mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -+ mbox_out->read = __io_address(addr_mbox + MAIL_RD); -+ /* Write to the other mailbox */ -+ mbox_out->write = -+ __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -+ MAIL_WRT); -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->write); -+ rc = 0; -+ } -+ return rc; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ rc = 0; -+ } -+ return rc; -+} -+ -+static irqreturn_t mbox_irq(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -+ int status = readl(mbox->status); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->read); -+ int chan = MBOX_CHAN(msg); -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ /* Overflow */ -+ printk(KERN_ERR DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ printk(KERN_ERR DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->status); -+ } -+ return ret; -+} -+ -+static struct irqaction mbox_irqaction = { -+ .name = "ARM Mailbox IRQ", -+ .flags = IRQF_DISABLED | IRQF_IRQPOLL, -+ .handler = mbox_irq, -+}; -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox Methods -+ * -------------------------------------------------------------------- */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_write(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_read(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static void dev_mbox_register(const char *dev_name, struct device *dev) -+{ -+ mbox_dev = dev; -+} -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)src < TASK_SIZE) -+ { -+ return copy_from_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)dst < TASK_SIZE) -+ { -+ return copy_to_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) { -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ } -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* ---------------------------------------------------------------------- -+ * Platform Device for Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static int Device_Open = 0; -+ -+/* -+ * This is called whenever a process attempts to open the device file -+ */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* -+ * We don't want to talk to two processes at the same time -+ */ -+ if (Device_Open) -+ return -EBUSY; -+ -+ Device_Open++; -+ /* -+ * Initialize the message -+ */ -+ try_module_get(THIS_MODULE); -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* -+ * We're now ready for our next caller -+ */ -+ Device_Open--; -+ -+ module_put(THIS_MODULE); -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -+ unsigned int ioctl_num, /* number and param for ioctl */ -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ /* -+ * Switch according to the ioctl called -+ */ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ break; -+ default: -+ printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_mailbox *mailbox; -+ -+ mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -+ if (NULL == mailbox) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "mailbox memory\n"); -+ ret = -ENOMEM; -+ } else { -+ struct resource *res; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ kfree(mailbox); -+ } else { -+ /* should be based on the registers from res really */ -+ mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -+ -+ platform_set_drvdata(pdev, mailbox); -+ dev_mbox_register(DRIVER_NAME, &pdev->dev); -+ -+ mbox_irqaction.dev_id = mailbox; -+ setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -+ printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -+ __io_address(ARM_0_MAIL0_RD)); -+ } -+ } -+ -+ if (ret == 0) { -+ /* -+ * Register the character device -+ */ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ -+ /* -+ * Negative values signify an error -+ */ -+ if (ret < 0) { -+ printk(KERN_ERR DRIVER_NAME -+ "Failed registering the character device %d\n", ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(mailbox); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ int ret; -+ -+ printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -+ -+ ret = platform_driver_register(&bcm_mbox_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bcm-mbox"); -diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index 9b4f29e5..0c5d4ac 100644 ---- a/arch/arm/mm/Kconfig -+++ b/arch/arm/mm/Kconfig -@@ -358,7 +358,7 @@ config CPU_PJ4B - - # ARMv6 - config CPU_V6 -- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) -+ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708) - select CPU_32v6 - select CPU_ABRT_EV6 - select CPU_CACHE_V6 -diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S -index d0390f4..a042de8 100644 ---- a/arch/arm/mm/proc-v6.S -+++ b/arch/arm/mm/proc-v6.S -@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset) - * - * IRQs are already disabled. - */ -+ -+/* See jira SW-5991 for details of this workaround */ - ENTRY(cpu_v6_do_idle) -- mov r1, #0 -- mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode -- mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt -+ .align 5 -+ mov r1, #2 -+1: subs r1, #1 -+ nop -+ mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode -+ mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt -+ nop -+ nop -+ nop -+ bne 1b - ret lr - - ENTRY(cpu_v6_dcache_clean_area) -diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types -index a10297d..c9ddd87 100644 ---- a/arch/arm/tools/mach-types -+++ b/arch/arm/tools/mach-types -@@ -522,6 +522,7 @@ torbreck MACH_TORBRECK TORBRECK 3090 - prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 - paz00 MACH_PAZ00 PAZ00 3128 - acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 -+bcm2708 MACH_BCM2708 BCM2708 3138 - ag5evm MACH_AG5EVM AG5EVM 3189 - ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 - wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 8d94c19..16ca535 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -84,7 +84,7 @@ struct vendor_data { - - static unsigned int get_fifosize_arm(struct amba_device *dev) - { -- return amba_rev(dev) < 3 ? 16 : 32; -+ return 16; //TODO: fix: amba_rev(dev) < 3 ? 16 : 32; - } - - static struct vendor_data vendor_arm = { -diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index 0c8cbe5..c3b84a2 100644 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -291,6 +291,7 @@ struct mmc_host { - MMC_CAP2_HS400_1_2V) - #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) - #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) -+#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ - - mmc_pm_flag_t pm_caps; /* supported pm features */ - - -From 6763b931593e5ce8e1b5e45de482527d61390f56 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 7 May 2013 14:32:27 +0100 -Subject: [PATCH 002/216] Add 2709 platform for Raspberry Pi 2 - ---- - arch/arm/Kconfig | 21 + - arch/arm/Makefile | 1 + - arch/arm/kernel/head.S | 8 + - arch/arm/mach-bcm2709/Kconfig | 49 + - arch/arm/mach-bcm2709/Makefile | 7 + - arch/arm/mach-bcm2709/Makefile.boot | 3 + - arch/arm/mach-bcm2709/armctrl.c | 361 +++++++ - arch/arm/mach-bcm2709/armctrl.h | 27 + - arch/arm/mach-bcm2709/bcm2708_gpio.c | 426 ++++++++ - arch/arm/mach-bcm2709/bcm2709.c | 1263 ++++++++++++++++++++++ - arch/arm/mach-bcm2709/bcm2709.h | 49 + - arch/arm/mach-bcm2709/clock.c | 61 ++ - arch/arm/mach-bcm2709/clock.h | 24 + - arch/arm/mach-bcm2709/delay.S | 21 + - arch/arm/mach-bcm2709/dma.c | 409 +++++++ - arch/arm/mach-bcm2709/include/mach/arm_control.h | 493 +++++++++ - arch/arm/mach-bcm2709/include/mach/arm_power.h | 62 ++ - arch/arm/mach-bcm2709/include/mach/barriers.h | 3 + - arch/arm/mach-bcm2709/include/mach/clkdev.h | 7 + - arch/arm/mach-bcm2709/include/mach/debug-macro.S | 22 + - arch/arm/mach-bcm2709/include/mach/dma.h | 94 ++ - arch/arm/mach-bcm2709/include/mach/entry-macro.S | 123 +++ - arch/arm/mach-bcm2709/include/mach/frc.h | 38 + - arch/arm/mach-bcm2709/include/mach/gpio.h | 17 + - arch/arm/mach-bcm2709/include/mach/hardware.h | 28 + - arch/arm/mach-bcm2709/include/mach/io.h | 27 + - arch/arm/mach-bcm2709/include/mach/irqs.h | 225 ++++ - arch/arm/mach-bcm2709/include/mach/memory.h | 57 + - arch/arm/mach-bcm2709/include/mach/platform.h | 225 ++++ - arch/arm/mach-bcm2709/include/mach/power.h | 26 + - arch/arm/mach-bcm2709/include/mach/system.h | 38 + - arch/arm/mach-bcm2709/include/mach/timex.h | 23 + - arch/arm/mach-bcm2709/include/mach/uncompress.h | 84 ++ - arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 + - arch/arm/mach-bcm2709/include/mach/vc_support.h | 69 ++ - arch/arm/mach-bcm2709/include/mach/vcio.h | 165 +++ - arch/arm/mach-bcm2709/include/mach/vmalloc.h | 20 + - arch/arm/mach-bcm2709/power.c | 195 ++++ - arch/arm/mach-bcm2709/vc_mem.c | 431 ++++++++ - arch/arm/mach-bcm2709/vc_support.c | 318 ++++++ - arch/arm/mach-bcm2709/vcio.c | 474 ++++++++ - arch/arm/mm/proc-v7.S | 1 + - arch/arm/tools/mach-types | 1 + - drivers/clocksource/arm_arch_timer.c | 36 + - 44 files changed, 6067 insertions(+) - create mode 100644 arch/arm/mach-bcm2709/Kconfig - create mode 100644 arch/arm/mach-bcm2709/Makefile - create mode 100644 arch/arm/mach-bcm2709/Makefile.boot - create mode 100644 arch/arm/mach-bcm2709/armctrl.c - create mode 100644 arch/arm/mach-bcm2709/armctrl.h - create mode 100644 arch/arm/mach-bcm2709/bcm2708_gpio.c - create mode 100644 arch/arm/mach-bcm2709/bcm2709.c - create mode 100644 arch/arm/mach-bcm2709/bcm2709.h - create mode 100644 arch/arm/mach-bcm2709/clock.c - create mode 100644 arch/arm/mach-bcm2709/clock.h - create mode 100644 arch/arm/mach-bcm2709/delay.S - create mode 100644 arch/arm/mach-bcm2709/dma.c - create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_control.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_power.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/clkdev.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/debug-macro.S - create mode 100644 arch/arm/mach-bcm2709/include/mach/dma.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/entry-macro.S - create mode 100644 arch/arm/mach-bcm2709/include/mach/frc.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/gpio.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/hardware.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/io.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/irqs.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/memory.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/platform.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/power.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/system.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/timex.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/uncompress.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h - create mode 100755 arch/arm/mach-bcm2709/include/mach/vc_support.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/vcio.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/vmalloc.h - create mode 100644 arch/arm/mach-bcm2709/power.c - create mode 100644 arch/arm/mach-bcm2709/vc_mem.c - create mode 100755 arch/arm/mach-bcm2709/vc_support.c - create mode 100644 arch/arm/mach-bcm2709/vcio.c - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 6876ae8..4018fea 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -793,6 +793,26 @@ config ARCH_OMAP1 - help - Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx) - -+config ARCH_BCM2709 -+ bool "Broadcom BCM2709 family" -+ select ARCH_HAS_BARRIERS if SMP -+ select CPU_V7 -+ select HAVE_SMP -+ select ARM_AMBA -+ select MIGHT_HAVE_CACHE_L2X0 -+ select HAVE_SCHED_CLOCK -+ select NEED_MACH_MEMORY_H -+ select NEED_MACH_IO_H -+ select COMMON_CLK -+ select ARCH_HAS_CPUFREQ -+ select GENERIC_CLOCKEVENTS -+ select MACH_BCM2709 -+ select VC4 -+ select FIQ -+# select ZONE_DMA -+ help -+ This enables support for Broadcom BCM2709 boards. -+ - endchoice - - menu "Multiple platform selection" -@@ -984,6 +1004,7 @@ source "arch/arm/mach-vt8500/Kconfig" - - source "arch/arm/mach-w90x900/Kconfig" - source "arch/arm/mach-bcm2708/Kconfig" -+source "arch/arm/mach-bcm2709/Kconfig" - - source "arch/arm/mach-zynq/Kconfig" - -diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 27c0f92..21ba7f3 100644 ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -147,6 +147,7 @@ machine-$(CONFIG_ARCH_AT91) += at91 - machine-$(CONFIG_ARCH_AXXIA) += axxia - machine-$(CONFIG_ARCH_BCM) += bcm - machine-$(CONFIG_ARCH_BCM2708) += bcm2708 -+machine-$(CONFIG_ARCH_BCM2709) += bcm2709 - machine-$(CONFIG_ARCH_BERLIN) += berlin - machine-$(CONFIG_ARCH_CLPS711X) += clps711x - machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx -diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S -index 0196327..e4d6030 100644 ---- a/arch/arm/kernel/head.S -+++ b/arch/arm/kernel/head.S -@@ -680,6 +680,14 @@ ARM_BE8(rev16 ip, ip) - ldrcc r7, [r4], #4 @ use branch for delay slot - bcc 1b - ret lr -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop - #endif - ENDPROC(__fixup_a_pv_table) - diff --git a/arch/arm/mach-bcm2709/Kconfig b/arch/arm/mach-bcm2709/Kconfig new file mode 100644 -index 0000000..4fb6e1b +index 0000000..d61ade0 --- /dev/null +++ b/arch/arm/mach-bcm2709/Kconfig -@@ -0,0 +1,49 @@ +@@ -0,0 +1,42 @@ +menu "Broadcom BCM2709 Implementations" + depends on ARCH_BCM2709 + @@ -4829,13 +2707,6 @@ index 0000000..4fb6e1b + help + Include support for the Broadcom(R) BCM2709 gpio. + -+config BCM2708_VCMEM -+ bool "Videocore Memory" -+ depends on MACH_BCM2709 -+ default y -+ help -+ Helper for videocore memory access and total size allocation. -+ +config BCM2708_NOL2CACHE + bool "Videocore L2 cache disable" + depends on MACH_BCM2709 @@ -4853,17 +2724,16 @@ index 0000000..4fb6e1b +endmenu diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile new file mode 100644 -index 0000000..2a803bb +index 0000000..1ae8b80 --- /dev/null +++ b/arch/arm/mach-bcm2709/Makefile -@@ -0,0 +1,7 @@ +@@ -0,0 +1,6 @@ +# +# Makefile for the linux kernel. +# + -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o dma.o ++obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o +obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o -+obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o diff --git a/arch/arm/mach-bcm2709/Makefile.boot b/arch/arm/mach-bcm2709/Makefile.boot new file mode 100644 index 0000000..67039c3 @@ -4875,7 +2745,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c new file mode 100644 -index 0000000..2815b64 +index 0000000..2fcfab9 --- /dev/null +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -0,0 +1,361 @@ @@ -5230,7 +3100,7 @@ index 0000000..2815b64 + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); + } else { + irq_set_chip_and_handler(irq, &armctrl_chip, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + irq_set_chip_data(irq, (void *)data); + } @@ -5275,7 +3145,7 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2709/bcm2708_gpio.c b/arch/arm/mach-bcm2709/bcm2708_gpio.c new file mode 100644 -index 0000000..c1e9254 +index 0000000..e33265d --- /dev/null +++ b/arch/arm/mach-bcm2709/bcm2708_gpio.c @@ -0,0 +1,426 @@ @@ -5587,7 +3457,7 @@ index 0000000..c1e9254 + +static struct irqaction bcm2708_gpio_irq = { + .name = "BCM2708 GPIO catchall handler", -+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2708_gpio_interrupt, +}; + @@ -5707,10 +3577,10 @@ index 0000000..c1e9254 +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c new file mode 100644 -index 0000000..f8679bb +index 0000000..19d0601 --- /dev/null +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -0,0 +1,1263 @@ +@@ -0,0 +1,801 @@ +/* + * linux/arch/arm/mach-bcm2709/bcm2709.c + * @@ -5747,9 +3617,7 @@ index 0000000..f8679bb +#include +#include +#include -+#include +#include -+#include + +#include +#include @@ -5768,8 +3636,6 @@ index 0000000..f8679bb +#include + +#include -+#include -+#include +#include + +#include @@ -5795,19 +3661,12 @@ index 0000000..f8679bb + */ +#define DMA_MASK_BITS_COMMON 32 + -+// use GPIO 4 for the one-wire GPIO pin, if enabled -+#define W1_GPIO 4 -+// ensure one-wire GPIO pullup is disabled by default -+#define W1_PULLUP -1 -+ +/* command line parameters */ +static unsigned boardrev, serial; +static unsigned uart_clock = UART0_CLOCK; +static unsigned disk_led_gpio = 16; +static unsigned disk_led_active_low = 1; +static unsigned reboot_part = 0; -+static unsigned w1_gpio_pin = W1_GPIO; -+static unsigned w1_gpio_pullup = W1_PULLUP; + +static unsigned use_dt = 0; + @@ -5953,6 +3812,7 @@ index 0000000..f8679bb + bcm2709_register_clkdev(clk, "dev:f1"); + + clk = bcm2709_clk_register("sdhost_clk", 250000000); ++ bcm2709_register_clkdev(clk, "mmc-bcm2835.0"); + bcm2709_register_clkdev(clk, "bcm2708_spi.0"); + bcm2709_register_clkdev(clk, "bcm2708_i2c.0"); + bcm2709_register_clkdev(clk, "bcm2708_i2c.1"); @@ -5967,35 +3827,6 @@ index 0000000..f8679bb + &uart0_device, +}; + -+static struct resource bcm2708_dmaman_resources[] = { -+ { -+ .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), -+}; -+ -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+static struct w1_gpio_platform_data w1_gpio_pdata = { -+ .pin = W1_GPIO, -+ .ext_pullup_enable_pin = W1_PULLUP, -+ .is_open_drain = 0, -+}; -+ -+static struct platform_device w1_device = { -+ .name = "w1-gpio", -+ .id = -1, -+ .dev.platform_data = &w1_gpio_pdata, -+}; -+#endif -+ +static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_fb_device = { @@ -6009,27 +3840,6 @@ index 0000000..f8679bb + }, +}; + -+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, -+ }, -+ {}, -+}; -+ -+static struct platform_device bcm2708_uart1_device = { -+ .name = "serial8250", -+ .id = PLAT8250_DEV_PLATFORM, -+ .dev = { -+ .platform_data = bcm2708_uart1_platform_data, -+ }, -+}; -+ +static struct resource bcm2708_usb_resources[] = { + [0] = { + .start = USB_BASE, @@ -6078,17 +3888,21 @@ index 0000000..f8679bb +}; + +static struct resource bcm2708_vcio_resources[] = { -+ [0] = { /* mailbox/semaphore/doorbell access */ -+ .start = MCORE_BASE, -+ .end = MCORE_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, ++ { ++ .start = ARMCTRL_0_MAIL0_BASE, ++ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_MAILBOX, ++ .end = IRQ_ARM_MAILBOX, ++ .flags = IORESOURCE_IRQ, ++ }, +}; + +static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_vcio_device = { -+ .name = BCM_VCIO_DRIVER_NAME, ++ .name = "bcm2708_vcio", + .id = -1, /* only one VideoCore I/O area */ + .resource = bcm2708_vcio_resources, + .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), @@ -6098,360 +3912,6 @@ index 0000000..f8679bb + }, +}; + -+#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, -+ }, -+}; -+ -+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 SYSTEM_TIMER -+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, -+ } -+ -+}; -+ -+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), -+ }, -+}; -+#endif -+ -+#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ -+static struct resource bcm2835_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, -+ }, -+ [1] = { -+ .start = IRQ_ARASANSDIO, -+ .end = IRQ_ARASANSDIO, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 bcm2835_emmc_dmamask = 0xffffffffUL; -+ -+struct platform_device bcm2835_emmc_device = { -+ .name = "mmc-bcm2835", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2835_emmc_resources), -+ .resource = bcm2835_emmc_resources, -+ .dev = { -+ .dma_mask = &bcm2835_emmc_dmamask, -+ .coherent_dma_mask = 0xffffffffUL}, -+}; -+#endif /* CONFIG_MMC_BCM2835 */ -+ -+static struct resource bcm2708_powerman_resources[] = { -+ [0] = { -+ .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}, -+}; -+ -+ -+static struct platform_device bcm2708_alsa_devices[] = { -+ [0] = { -+ .name = "bcm2835_AUD0", -+ .id = 0, /* first audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [1] = { -+ .name = "bcm2835_AUD1", -+ .id = 1, /* second audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [2] = { -+ .name = "bcm2835_AUD2", -+ .id = 2, /* third audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [3] = { -+ .name = "bcm2835_AUD3", -+ .id = 3, /* forth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [4] = { -+ .name = "bcm2835_AUD4", -+ .id = 4, /* fifth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [5] = { -+ .name = "bcm2835_AUD5", -+ .id = 5, /* sixth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [6] = { -+ .name = "bcm2835_AUD6", -+ .id = 6, /* seventh audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [7] = { -+ .name = "bcm2835_AUD7", -+ .id = 7, /* eighth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+}; -+ -+static struct resource bcm2708_spi_resources[] = { -+ { -+ .start = SPI0_BASE, -+ .end = SPI0_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_SPI, -+ .end = IRQ_SPI, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+ -+static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+static struct platform_device bcm2708_spi_device = { -+ .name = "bcm2708_spi", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_spi_resources), -+ .resource = bcm2708_spi_resources, -+ .dev = { -+ .dma_mask = &bcm2708_spi_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)}, -+}; -+ -+#ifdef CONFIG_BCM2708_SPIDEV -+static struct spi_board_info bcm2708_spi_devices[] = { -+#ifdef CONFIG_SPI_SPIDEV -+ { -+ .modalias = "spidev", -+ .max_speed_hz = 500000, -+ .bus_num = 0, -+ .chip_select = 0, -+ .mode = SPI_MODE_0, -+ }, { -+ .modalias = "spidev", -+ .max_speed_hz = 500000, -+ .bus_num = 0, -+ .chip_select = 1, -+ .mode = SPI_MODE_0, -+ } -+#endif -+}; -+#endif -+ -+static struct resource bcm2708_bsc0_resources[] = { -+ { -+ .start = BSC0_BASE, -+ .end = BSC0_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc0_device = { -+ .name = "bcm2708_i2c", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), -+ .resource = bcm2708_bsc0_resources, -+}; -+ -+ -+static struct resource bcm2708_bsc1_resources[] = { -+ { -+ .start = BSC1_BASE, -+ .end = BSC1_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc1_device = { -+ .name = "bcm2708_i2c", -+ .id = 1, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), -+ .resource = bcm2708_bsc1_resources, -+}; -+ -+static struct platform_device bcm2835_hwmon_device = { -+ .name = "bcm2835_hwmon", -+}; -+ -+static struct platform_device bcm2835_thermal_device = { -+ .name = "bcm2835_thermal", -+}; -+ -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+static struct resource bcm2708_i2s_resources[] = { -+ { -+ .start = I2S_BASE, -+ .end = I2S_BASE + 0x20, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = PCM_CLOCK_BASE, -+ .end = PCM_CLOCK_BASE + 0x02, -+ .flags = IORESOURCE_MEM, -+ } -+}; -+ -+static struct platform_device bcm2708_i2s_device = { -+ .name = "bcm2708-i2s", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), -+ .resource = bcm2708_i2s_resources, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+static struct platform_device snd_hifiberry_dac_device = { -+ .name = "snd-hifiberry-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm5102a_codec_device = { -+ .name = "pcm5102a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+static struct platform_device snd_rpi_hifiberry_dacplus_device = { -+ .name = "snd-rpi-hifiberry-dacplus", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4d) -+ }, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+static struct platform_device snd_hifiberry_digi_device = { -+ .name = "snd-hifiberry-digi", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("wm8804", 0x3b) -+ }, -+}; -+ -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+static struct platform_device snd_hifiberry_amp_device = { -+ .name = "snd-hifiberry-amp", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("tas5713", 0x1b) -+ }, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+static struct platform_device snd_rpi_dac_device = { -+ .name = "snd-rpi-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm1794a_codec_device = { -+ .name = "pcm1794a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ -+ -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+static struct platform_device snd_rpi_iqaudio_dac_device = { -+ .name = "snd-rpi-iqaudio-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+// Use the actual device name rather than generic driver name -+static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4c) -+ }, -+}; -+#endif -+ +int __init bcm_register_device(struct platform_device *pdev) +{ + int ret; @@ -6539,6 +3999,17 @@ index 0000000..f8679bb + } +} + ++static void __init bcm2709_init_uart1(void) ++{ ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); ++ if (of_device_is_available(np)) { ++ pr_info("bcm2709: Mini UART enabled\n"); ++ writel(1, __io_address(UART1_BASE + 0x4)); ++ } ++} ++ +#ifdef CONFIG_OF +static void __init bcm2709_dt_init(void) +{ @@ -6570,85 +4041,24 @@ index 0000000..f8679bb + bcm2709_init_clocks(); + bcm2709_dt_init(); + -+ bcm_register_device(&bcm2708_dmaman_device); + bcm_register_device(&bcm2708_vcio_device); +#ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); +#endif -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+ w1_gpio_pdata.pin = w1_gpio_pin; -+ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -+ bcm_register_device_dt(&w1_device); -+#endif -+#ifdef SYSTEM_TIMER -+ bcm_register_device(&bcm2708_systemtimer_device); -+#endif -+ bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device(&bcm2708_uart1_device); -+ bcm_register_device(&bcm2708_powerman_device); ++ bcm_register_device_dt(&bcm2708_fb_device); ++ bcm_register_device_dt(&bcm2708_usb_device); + -+#ifdef CONFIG_MMC_BCM2835 -+ bcm_register_device(&bcm2835_emmc_device); -+#endif -+ bcm2709_init_led(); -+ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); ++ bcm2708_init_led(); ++ bcm2708_init_uart1(); + -+ bcm_register_device_dt(&bcm2708_spi_device); -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ -+ bcm_register_device(&bcm2835_hwmon_device); -+ bcm_register_device(&bcm2835_thermal_device); -+ -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+ bcm_register_device_dt(&bcm2708_i2s_device); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_dac_device); -+ bcm_register_device_dt(&snd_pcm5102a_codec_device); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_digi_device); -+ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_amp_device); -+ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_dac_device); -+ bcm_register_device_dt(&snd_pcm1794a_codec_device); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); -+#endif -+ -+ -+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -+ struct amba_device *d = amba_devs[i]; -+ amba_device_register(d, &iomem_resource); ++ if (!use_dt) { ++ 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; -+ -+#ifdef CONFIG_BCM2708_SPIDEV -+ if (!use_dt) -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); -+#endif +} + +#ifdef SYSTEM_TIMER @@ -6972,8 +4382,6 @@ index 0000000..f8679bb +module_param(disk_led_gpio, uint, 0644); +module_param(disk_led_active_low, uint, 0644); +module_param(reboot_part, uint, 0644); -+module_param(w1_gpio_pin, uint, 0644); -+module_param(w1_gpio_pullup, uint, 0644); diff --git a/arch/arm/mach-bcm2709/bcm2709.h b/arch/arm/mach-bcm2709/bcm2709.h new file mode 100644 index 0000000..e339a93 @@ -7029,103 +4437,6 @@ index 0000000..e339a93 +} + +#endif -diff --git a/arch/arm/mach-bcm2709/clock.c b/arch/arm/mach-bcm2709/clock.c -new file mode 100644 -index 0000000..4fc556e ---- /dev/null -+++ b/arch/arm/mach-bcm2709/clock.c -@@ -0,0 +1,61 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "clock.h" -+ -+int clk_enable(struct clk *clk) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(clk_enable); -+ -+void clk_disable(struct clk *clk) -+{ -+} -+EXPORT_SYMBOL(clk_disable); -+ -+unsigned long clk_get_rate(struct clk *clk) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_get_rate); -+ -+long clk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_round_rate); -+ -+int clk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ return -EIO; -+} -+EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2709/clock.h b/arch/arm/mach-bcm2709/clock.h -new file mode 100644 -index 0000000..5f9d725 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/clock.h -@@ -0,0 +1,24 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 -+ */ -+struct module; -+ -+struct clk { -+ unsigned long rate; -+}; diff --git a/arch/arm/mach-bcm2709/delay.S b/arch/arm/mach-bcm2709/delay.S new file mode 100644 index 0000000..06f4780 @@ -7153,421 +4464,6 @@ index 0000000..06f4780 + bhi bcm2708_delay + mov pc, lr +ENDPROC(bcm2708_delay) -diff --git a/arch/arm/mach-bcm2709/dma.c b/arch/arm/mach-bcm2709/dma.c -new file mode 100644 -index 0000000..a5e58d1 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/dma.c -@@ -0,0 +1,409 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/dma.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/*****************************************************************************\ -+ * * -+ * Configuration * -+ * * -+\*****************************************************************************/ -+ -+#define CACHE_LINE_MASK 31 -+#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME -+#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -+ -+/* valid only for channels 0 - 14, 15 has its own base address */ -+#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ -+#define BCM2708_DMA_CHANIO(dma_base, n) \ -+ ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -+ -+ -+/*****************************************************************************\ -+ * * -+ * DMA Auxilliary Functions * -+ * * -+\*****************************************************************************/ -+ -+/* A DMA buffer on an arbitrary boundary may separate a cache line into a -+ section inside the DMA buffer and another section outside it. -+ Even if we flush DMA buffers from the cache there is always the chance that -+ during a DMA someone will access the part of a cache line that is outside -+ the DMA buffer - which will then bring in unwelcome data. -+ Without being able to dictate our own buffer pools we must insist that -+ DMA buffers consist of a whole number of cache lines. -+*/ -+ -+extern int -+bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) -+{ -+ int i; -+ -+ for (i = 0; i < sg_len; i++) { -+ if (sg_ptr[i].offset & CACHE_LINE_MASK || -+ sg_ptr[i].length & CACHE_LINE_MASK) -+ return 0; -+ } -+ -+ return 1; -+} -+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -+ -+extern void -+bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) -+{ -+ dsb(); /* ARM data synchronization (push) operation */ -+ -+ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -+ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); -+} -+ -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ /* ugly busy wait only option for now */ -+ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -+ cpu_relax(); -+} -+ -+EXPORT_SYMBOL_GPL(bcm_dma_start); -+ -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ -+/* Complete an ongoing DMA (assuming its results are to be ignored) -+ Does nothing if there is no DMA in progress. -+ This routine waits for the current AXI transfer to complete before -+ terminating the current DMA. If the current transfer is hung on a DREQ used -+ by an uncooperative peripheral the AXI transfer may never complete. In this -+ case the routine times out and return a non-zero error code. -+ Use of this routine doesn't guarantee that the ongoing or aborted DMA -+ does not produce an interrupt. -+*/ -+extern int -+bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ unsigned long int cs; -+ int rc = 0; -+ -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (BCM2708_DMA_ACTIVE & cs) { -+ long int timeout = 10000; -+ -+ /* write 0 to the active bit - pause the DMA */ -+ writel(0, dma_chan_base + BCM2708_DMA_CS); -+ -+ /* wait for any current AXI transfer to complete */ -+ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -+ /* we'll un-pause when we set of our next DMA */ -+ rc = -ETIMEDOUT; -+ -+ } else if (BCM2708_DMA_ACTIVE & cs) { -+ /* terminate the control block chain */ -+ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -+ -+ /* abort the whole DMA */ -+ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -+ dma_chan_base + BCM2708_DMA_CS); -+ } -+ } -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_abort); -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Device Methods * -+ * * -+\*****************************************************************************/ -+ -+struct vc_dmaman { -+ void __iomem *dma_base; -+ u32 chan_available; /* bitmap of available channels */ -+ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ -+}; -+ -+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -+ u32 chans_available) -+{ -+ dmaman->dma_base = dma_base; -+ dmaman->chan_available = chans_available; -+ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ -+} -+ -+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) -+{ -+ u32 chans; -+ int feature; -+ -+ chans = dmaman->chan_available; -+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -+ /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) -+ chans &= dmaman->has_feature[feature]; -+ -+ if (chans) { -+ int chan = 0; -+ /* return the ordinal of the first channel in the bitmap */ -+ while (chans != 0 && (chans & 1) == 0) { -+ chans >>= 1; -+ chan++; -+ } -+ /* claim the channel */ -+ dmaman->chan_available &= ~(1 << chan); -+ return chan; -+ } else -+ return -ENOMEM; -+} -+ -+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) -+{ -+ if (chan < 0) -+ return -EINVAL; -+ else if ((1 << chan) & dmaman->chan_available) -+ return -EIDRM; -+ else { -+ dmaman->chan_available |= (1 << chan); -+ return 0; -+ } -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA IRQs * -+ * * -+\*****************************************************************************/ -+ -+static unsigned char bcm_dma_irqs[] = { -+ IRQ_DMA0, -+ IRQ_DMA1, -+ IRQ_DMA2, -+ IRQ_DMA3, -+ IRQ_DMA4, -+ IRQ_DMA5, -+ IRQ_DMA6, -+ IRQ_DMA7, -+ IRQ_DMA8, -+ IRQ_DMA9, -+ IRQ_DMA10, -+ IRQ_DMA11, -+ IRQ_DMA12 -+}; -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Monitor * -+ * * -+\*****************************************************************************/ -+ -+static struct device *dmaman_dev; /* we assume there's only one! */ -+ -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq) -+{ -+ if (!dmaman_dev) -+ return -ENODEV; -+ else { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ if (rc >= 0) { -+ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -+ rc); -+ *out_dma_irq = bcm_dma_irqs[rc]; -+ } -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -+ -+extern int bcm_dma_chan_free(int channel) -+{ -+ if (dmaman_dev) { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_free(dmaman, channel); -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -+ -+static int dev_dmaman_register(const char *dev_name, struct device *dev) -+{ -+ int rc = dmaman_dev ? -EINVAL : 0; -+ dmaman_dev = dev; -+ return rc; -+} -+ -+static void dev_dmaman_deregister(const char *dev_name, struct device *dev) -+{ -+ dmaman_dev = NULL; -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA Device * -+ * * -+\*****************************************************************************/ -+ -+static int dmachans = -1; /* module parameter */ -+ -+static int bcm_dmaman_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_dmaman *dmaman; -+ struct resource *dma_res = NULL; -+ void __iomem *dma_base = NULL; -+ int have_dma_region = 0; -+ -+ dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -+ if (NULL == dmaman) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "DMA management memory\n"); -+ ret = -ENOMEM; -+ } else { -+ -+ dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (dma_res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ } else if (!request_mem_region(dma_res->start, -+ resource_size(dma_res), -+ DRIVER_NAME)) { -+ dev_err(&pdev->dev, "cannot obtain DMA region\n"); -+ ret = -EBUSY; -+ } else { -+ have_dma_region = 1; -+ dma_base = ioremap(dma_res->start, -+ resource_size(dma_res)); -+ if (!dma_base) { -+ dev_err(&pdev->dev, "cannot map DMA region\n"); -+ ret = -ENOMEM; -+ } else { -+ /* use module parameter if one was provided */ -+ if (dmachans > 0) -+ vc_dmaman_init(dmaman, dma_base, -+ dmachans); -+ else -+ vc_dmaman_init(dmaman, dma_base, -+ DEFAULT_DMACHAN_BITMAP); -+ -+ platform_set_drvdata(pdev, dmaman); -+ dev_dmaman_register(DRIVER_NAME, &pdev->dev); -+ -+ printk(KERN_INFO DRIVER_NAME ": DMA manager " -+ "at %p\n", dma_base); -+ } -+ } -+ } -+ if (ret != 0) { -+ if (dma_base) -+ iounmap(dma_base); -+ if (dma_res && have_dma_region) -+ release_mem_region(dma_res->start, -+ resource_size(dma_res)); -+ if (dmaman) -+ kfree(dmaman); -+ } -+ return ret; -+} -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -+ kfree(dmaman); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_dmaman_driver = { -+ .probe = bcm_dmaman_probe, -+ .remove = bcm_dmaman_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+/*****************************************************************************\ -+ * * -+ * Driver init/exit * -+ * * -+\*****************************************************************************/ -+ -+static int __init bcm_dmaman_drv_init(void) -+{ -+ int ret; -+ -+ ret = platform_driver_register(&bcm_dmaman_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_dmaman_drv_exit(void) -+{ -+ platform_driver_unregister(&bcm_dmaman_driver); -+} -+ -+module_init(bcm_dmaman_drv_init); -+module_exit(bcm_dmaman_drv_exit); -+ -+module_param(dmachans, int, 0644); -+ -+MODULE_AUTHOR("Gray Girling "); -+MODULE_DESCRIPTION("DMA channel manager driver"); -+MODULE_LICENSE("GPL"); -+ -+MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); diff --git a/arch/arm/mach-bcm2709/include/mach/arm_control.h b/arch/arm/mach-bcm2709/include/mach/arm_control.h new file mode 100644 index 0000000..e346caf @@ -8067,74 +4963,6 @@ index 0000000..e346caf +#define ARM_LOCAL_MAILBOX3_CLR3 HW_REGISTER_RW(ARM_LOCAL_BASE+0x0FC) + +#endif -diff --git a/arch/arm/mach-bcm2709/include/mach/arm_power.h b/arch/arm/mach-bcm2709/include/mach/arm_power.h -new file mode 100644 -index 0000000..d3bf245 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/include/mach/arm_power.h -@@ -0,0 +1,62 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _ARM_POWER_H -+#define _ARM_POWER_H -+ -+/* Use meaningful names on each side */ -+#ifdef __VIDEOCORE__ -+#define PREFIX(x) ARM_##x -+#else -+#define PREFIX(x) BCM_##x -+#endif -+ -+enum { -+ PREFIX(POWER_SDCARD_BIT), -+ PREFIX(POWER_UART_BIT), -+ PREFIX(POWER_MINIUART_BIT), -+ PREFIX(POWER_USB_BIT), -+ PREFIX(POWER_I2C0_BIT), -+ PREFIX(POWER_I2C1_BIT), -+ PREFIX(POWER_I2C2_BIT), -+ PREFIX(POWER_SPI_BIT), -+ PREFIX(POWER_CCP2TX_BIT), -+ PREFIX(POWER_DSI_BIT), -+ -+ PREFIX(POWER_MAX) -+}; -+ -+enum { -+ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -+ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -+ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -+ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -+ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -+ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -+ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -+ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -+ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -+ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -+ -+ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -+ PREFIX(POWER_NONE) = 0 -+}; -+ -+#endif diff --git a/arch/arm/mach-bcm2709/include/mach/barriers.h b/arch/arm/mach-bcm2709/include/mach/barriers.h new file mode 100644 index 0000000..723cdad @@ -8185,106 +5013,6 @@ index 0000000..b24304a + .endm + +#include -diff --git a/arch/arm/mach-bcm2709/include/mach/dma.h b/arch/arm/mach-bcm2709/include/mach/dma.h -new file mode 100644 -index 0000000..d03e7b5 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/include/mach/dma.h -@@ -0,0 +1,94 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/dma.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+ -+#ifndef _MACH_BCM2708_DMA_H -+#define _MACH_BCM2708_DMA_H -+ -+#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -+ -+/* DMA CS Control and Status bits */ -+#define BCM2708_DMA_ACTIVE (1 << 0) -+#define BCM2708_DMA_INT (1 << 2) -+#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ -+#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ -+#define BCM2708_DMA_ERR (1 << 8) -+#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ -+#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -+ -+/* DMA control block "info" field bits */ -+#define BCM2708_DMA_INT_EN (1 << 0) -+#define BCM2708_DMA_TDMODE (1 << 1) -+#define BCM2708_DMA_WAIT_RESP (1 << 3) -+#define BCM2708_DMA_D_INC (1 << 4) -+#define BCM2708_DMA_D_WIDTH (1 << 5) -+#define BCM2708_DMA_D_DREQ (1 << 6) -+#define BCM2708_DMA_S_INC (1 << 8) -+#define BCM2708_DMA_S_WIDTH (1 << 9) -+#define BCM2708_DMA_S_DREQ (1 << 10) -+ -+#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) -+#define BCM2708_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -+ -+#define BCM2708_DMA_DREQ_EMMC 11 -+#define BCM2708_DMA_DREQ_SDHOST 13 -+ -+#define BCM2708_DMA_CS 0x00 /* Control and Status */ -+#define BCM2708_DMA_ADDR 0x04 -+/* the current control block appears in the following registers - read only */ -+#define BCM2708_DMA_INFO 0x08 -+#define BCM2708_DMA_SOURCE_AD 0x0c -+#define BCM2708_DMA_DEST_AD 0x10 -+#define BCM2708_DMA_NEXTCB 0x1C -+#define BCM2708_DMA_DEBUG 0x20 -+ -+#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) -+#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -+ -+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -+ -+struct bcm2708_dma_cb { -+ unsigned long info; -+ unsigned long src; -+ unsigned long dst; -+ unsigned long length; -+ unsigned long stride; -+ unsigned long next; -+ unsigned long pad[2]; -+}; -+struct scatterlist; -+ -+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); -+extern void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block); -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); -+extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -+ -+/* When listing features we can ask for when allocating DMA channels give -+ those with higher priority smaller ordinal numbers */ -+#define BCM_DMA_FEATURE_FAST_ORD 0 -+#define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_NORMAL_ORD 2 -+#define BCM_DMA_FEATURE_LITE_ORD 3 -+#define BCM_DMA_FEATURE_FAST (1< -+#include -+ -+typedef unsigned int BCM_POWER_HANDLE_T; -+ -+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); -+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); -+extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -+ -+#endif diff --git a/arch/arm/mach-bcm2709/include/mach/system.h b/arch/arm/mach-bcm2709/include/mach/system.h new file mode 100644 index 0000000..2d0b821 @@ -9384,177 +6080,6 @@ index 0000000..70e809f + unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5); + +#endif -diff --git a/arch/arm/mach-bcm2709/include/mach/vcio.h b/arch/arm/mach-bcm2709/include/mach/vcio.h -new file mode 100644 -index 0000000..8e11d67e ---- /dev/null -+++ b/arch/arm/mach-bcm2709/include/mach/vcio.h -@@ -0,0 +1,165 @@ -+/* -+ * arch/arm/mach-bcm2708/include/mach/vcio.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _MACH_BCM2708_VCIO_H -+#define _MACH_BCM2708_VCIO_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); -+extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); -+extern int /*rc*/ bcm_mailbox_property(void *data, int size); -+ -+#include -+ -+/* -+ * The major device number. We can't rely on dynamic -+ * registration any more, because ioctls need to know -+ * it. -+ */ -+#define MAJOR_NUM 100 -+ -+/* -+ * Set the message of the device driver -+ */ -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+/* -+ * _IOWR means that we're creating an ioctl command -+ * number for passing information from a user process -+ * to the kernel module and from the kernel module to user process -+ * -+ * The first arguments, MAJOR_NUM, is the major device -+ * number we're using. -+ * -+ * The second argument is the number of the command -+ * (there could be several with different meanings). -+ * -+ * The third argument is the type we want to get from -+ * the process to the kernel. -+ */ -+ -+/* -+ * The name of the device file -+ */ -+#define DEVICE_FILE_NAME "vcio" -+ -+#endif diff --git a/arch/arm/mach-bcm2709/include/mach/vmalloc.h b/arch/arm/mach-bcm2709/include/mach/vmalloc.h new file mode 100644 index 0000000..6aa6826 @@ -9581,210 +6106,9 @@ index 0000000..6aa6826 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define VMALLOC_END (0xff000000) -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -new file mode 100644 -index 0000000..3421057 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/power.c -@@ -0,0 +1,195 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/power.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_power" -+ -+#define BCM_POWER_MAXCLIENTS 4 -+#define BCM_POWER_NOCLIENT (1<<31) -+ -+/* Some drivers expect there devices to be permanently powered */ -+#ifdef CONFIG_USB -+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) -+#endif -+ -+#if 1 -+#define DPRINTK printk -+#else -+#define DPRINTK if (0) printk -+#endif -+ -+struct state_struct { -+ uint32_t global_request; -+ uint32_t client_request[BCM_POWER_MAXCLIENTS]; -+ struct semaphore client_mutex; -+ struct semaphore mutex; -+} g_state; -+ -+int bcm_power_open(BCM_POWER_HANDLE_T *handle) -+{ -+ BCM_POWER_HANDLE_T i; -+ int ret = -EBUSY; -+ -+ down(&g_state.client_mutex); -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -+ g_state.client_request[i] = BCM_POWER_NONE; -+ *handle = i; -+ ret = 0; -+ break; -+ } -+ } -+ -+ up(&g_state.client_mutex); -+ -+ DPRINTK("bcm_power_open() -> %d\n", *handle); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(bcm_power_open); -+ -+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) -+{ -+ int rc = 0; -+ -+ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -+ -+ if ((handle < BCM_POWER_MAXCLIENTS) && -+ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -+ if (down_interruptible(&g_state.mutex) != 0) { -+ DPRINTK("bcm_power_request -> interrupted\n"); -+ return -EINTR; -+ } -+ -+ if (request != g_state.client_request[handle]) { -+ uint32_t others_request = 0; -+ uint32_t global_request; -+ BCM_POWER_HANDLE_T i; -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (i != handle) -+ others_request |= -+ g_state.client_request[i]; -+ } -+ others_request &= ~BCM_POWER_NOCLIENT; -+ -+ global_request = request | others_request; -+ if (global_request != g_state.global_request) { -+ uint32_t actual; -+ -+ /* Send a request to VideoCore */ -+ 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); -+ DPRINTK -+ ("bcm_mailbox_read -> %08x, %d\n", -+ actual, rc); -+ actual >>= 4; -+ } else { -+ rc = 0; -+ actual = global_request; -+ } -+ -+ 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", -+ __func__, -+ g_state.global_request, -+ global_request, actual, request, others_request); -+ /* A failure */ -+ BUG_ON((others_request & actual) -+ != others_request); -+ request &= actual; -+ rc = -EIO; -+ } -+ -+ g_state.global_request = actual; -+ g_state.client_request[handle] = -+ request; -+ } -+ } -+ } -+ up(&g_state.mutex); -+ } else { -+ rc = -EINVAL; -+ } -+ DPRINTK("bcm_power_request -> %d\n", rc); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_request); -+ -+int bcm_power_close(BCM_POWER_HANDLE_T handle) -+{ -+ int rc; -+ -+ DPRINTK("bcm_power_close(%d)\n", handle); -+ -+ rc = bcm_power_request(handle, BCM_POWER_NONE); -+ if (rc == 0) -+ g_state.client_request[handle] = BCM_POWER_NOCLIENT; -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_close); -+ -+static int __init bcm_power_init(void) -+{ -+#if defined(BCM_POWER_ALWAYS_ON) -+ BCM_POWER_HANDLE_T always_on_handle; -+#endif -+ int rc = 0; -+ 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; -+ -+ sema_init(&g_state.client_mutex, 1); -+ sema_init(&g_state.mutex, 1); -+ -+ g_state.global_request = 0; -+#if defined(BCM_POWER_ALWAYS_ON) -+ if (BCM_POWER_ALWAYS_ON) { -+ bcm_power_open(&always_on_handle); -+ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -+ } -+#endif -+ -+ return rc; -+} -+ -+static void __exit bcm_power_exit(void) -+{ -+ bcm_mailbox_write(MBOX_CHAN_POWER, 0); -+} -+ -+arch_initcall(bcm_power_init); /* Initialize early */ -+module_exit(bcm_power_exit); -+ -+MODULE_AUTHOR("Phil Elwell"); -+MODULE_DESCRIPTION("Interface to BCM2708 power management"); -+MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c new file mode 100644 -index 0000000..ac578db +index 0000000..d2adfd1 --- /dev/null +++ b/arch/arm/mach-bcm2709/vc_mem.c @@ -0,0 +1,431 @@ @@ -9812,6 +6136,7 @@ index 0000000..ac578db +#include +#include +#include ++#include + +#ifdef CONFIG_ARCH_KONA +#include @@ -9821,7 +6146,6 @@ index 0000000..ac578db +#endif + +#include "mach/vc_mem.h" -+#include + +#define DRIVER_NAME "vc-mem" + @@ -10220,8 +6544,8 @@ index 0000000..ac578db +module_param(mem_size, uint, 0644); +module_param(mem_base, uint, 0644); diff --git a/arch/arm/mach-bcm2709/vc_support.c b/arch/arm/mach-bcm2709/vc_support.c -new file mode 100755 -index 0000000..0bc41c4 +new file mode 100644 +index 0000000..c4dc7d6 --- /dev/null +++ b/arch/arm/mach-bcm2709/vc_support.c @@ -0,0 +1,318 @@ @@ -10233,7 +6557,7 @@ index 0000000..0bc41c4 + */ + +#include -+#include ++#include + +#ifdef ECLIPSE_IGNORE + @@ -10543,491 +6867,51 @@ index 0000000..0bc41c4 + return 1; + } +} -diff --git a/arch/arm/mach-bcm2709/vcio.c b/arch/arm/mach-bcm2709/vcio.c -new file mode 100644 -index 0000000..5e43e85 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/vcio.c -@@ -0,0 +1,474 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -+#define SUPPORT_SYSRQ -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+ -+ -+#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* offsets from a mail box base address */ -+#define MAIL_WRT 0x00 /* write - and next 4 words */ -+#define MAIL_RD 0x00 /* read - and next 4 words */ -+#define MAIL_POL 0x10 /* read without popping the fifo */ -+#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL_STA 0x18 /* status */ -+#define MAIL_CNF 0x1C /* configuration */ -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+struct vc_mailbox { -+ struct device *dev; /* parent device */ -+ void __iomem *status; -+ void __iomem *config; -+ void __iomem *read; -+ void __iomem *write; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -+ uint32_t addr_mbox) -+{ -+ int i; -+ -+ mbox_out->dev = dev; -+ mbox_out->status = __io_address(addr_mbox + MAIL_STA); -+ mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -+ mbox_out->read = __io_address(addr_mbox + MAIL_RD); -+ /* Write to the other mailbox */ -+ mbox_out->write = -+ __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -+ MAIL_WRT); -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->write); -+ rc = 0; -+ } -+ return rc; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ rc = 0; -+ } -+ return rc; -+} -+ -+static irqreturn_t mbox_irq(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -+ int status = readl(mbox->status); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->read); -+ int chan = MBOX_CHAN(msg); -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ /* Overflow */ -+ printk(KERN_ERR DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ printk(KERN_ERR DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->status); -+ } -+ return ret; -+} -+ -+static struct irqaction mbox_irqaction = { -+ .name = "ARM Mailbox IRQ", -+ .flags = IRQF_DISABLED | IRQF_IRQPOLL, -+ .handler = mbox_irq, -+}; -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox Methods -+ * -------------------------------------------------------------------- */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_write(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_read(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static void dev_mbox_register(const char *dev_name, struct device *dev) -+{ -+ mbox_dev = dev; -+} -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)src < TASK_SIZE) -+ { -+ return copy_from_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)dst < TASK_SIZE) -+ { -+ return copy_to_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) { -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ } -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* ---------------------------------------------------------------------- -+ * Platform Device for Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static int Device_Open = 0; -+ -+/* -+ * This is called whenever a process attempts to open the device file -+ */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* -+ * We don't want to talk to two processes at the same time -+ */ -+ if (Device_Open) -+ return -EBUSY; -+ -+ Device_Open++; -+ /* -+ * Initialize the message -+ */ -+ try_module_get(THIS_MODULE); -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* -+ * We're now ready for our next caller -+ */ -+ Device_Open--; -+ -+ module_put(THIS_MODULE); -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -+ unsigned int ioctl_num, /* number and param for ioctl */ -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ /* -+ * Switch according to the ioctl called -+ */ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ break; -+ default: -+ printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_mailbox *mailbox; -+ -+ mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -+ if (NULL == mailbox) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "mailbox memory\n"); -+ ret = -ENOMEM; -+ } else { -+ struct resource *res; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ kfree(mailbox); -+ } else { -+ /* should be based on the registers from res really */ -+ mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -+ -+ platform_set_drvdata(pdev, mailbox); -+ dev_mbox_register(DRIVER_NAME, &pdev->dev); -+ -+ mbox_irqaction.dev_id = mailbox; -+ setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -+ printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -+ __io_address(ARM_0_MAIL0_RD)); -+ } -+ } -+ -+ if (ret == 0) { -+ /* -+ * Register the character device -+ */ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ -+ /* -+ * Negative values signify an error -+ */ -+ if (ret < 0) { -+ printk(KERN_ERR DRIVER_NAME -+ "Failed registering the character device %d\n", ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(mailbox); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ int ret; -+ -+ printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -+ -+ ret = platform_driver_register(&bcm_mbox_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bcm-mbox"); +diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig +index b4f92b9..bb263d8 100644 +--- a/arch/arm/mm/Kconfig ++++ b/arch/arm/mm/Kconfig +@@ -358,7 +358,7 @@ config CPU_PJ4B + + # ARMv6 + config CPU_V6 +- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) ++ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708) + select CPU_32v6 + select CPU_ABRT_EV6 + select CPU_CACHE_V6 +diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S +index 06d890a..30d96e8 100644 +--- a/arch/arm/mm/proc-v6.S ++++ b/arch/arm/mm/proc-v6.S +@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset) + * + * IRQs are already disabled. + */ ++ ++/* See jira SW-5991 for details of this workaround */ + ENTRY(cpu_v6_do_idle) +- mov r1, #0 +- mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode +- mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ .align 5 ++ mov r1, #2 ++1: subs r1, #1 ++ nop ++ mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode ++ mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ nop ++ nop ++ nop ++ bne 1b + ret lr + + ENTRY(cpu_v6_dcache_clean_area) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S -index 8b4ee5e..80fa74b 100644 +index 3d1054f..7615bbf 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S -@@ -441,6 +441,7 @@ __v7_setup: +@@ -456,6 +456,7 @@ __v7_setup: orr r0, r0, r6 @ set them THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions ret lr @ return to head.S:__ret @@ -11036,25 +6920,26 @@ index 8b4ee5e..80fa74b 100644 .align 2 diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types -index c9ddd87..bfc397c 100644 +index 2ed1b8a..b52d949 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types -@@ -523,6 +523,7 @@ prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 +@@ -522,6 +522,8 @@ torbreck MACH_TORBRECK TORBRECK 3090 + prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 paz00 MACH_PAZ00 PAZ00 3128 acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 - bcm2708 MACH_BCM2708 BCM2708 3138 ++bcm2708 MACH_BCM2708 BCM2708 3138 +bcm2709 MACH_BCM2709 BCM2709 3139 ag5evm MACH_AG5EVM AG5EVM 3189 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index a3025e7..4a2a601 100644 +index 0aa135d..89dbcb9 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c -@@ -804,3 +804,39 @@ static void __init arch_timer_mem_init(struct device_node *np) +@@ -882,3 +882,39 @@ void __init acpi_generic_timer_init(void) + acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init); } - CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", - arch_timer_mem_init); + #endif + +int __init dc4_arch_timer_init(void) +{ @@ -11091,11 +6976,396 @@ index a3025e7..4a2a601 100644 + arch_timer_common_init(); + return 0; +} +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 763eb20..ad45801 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -85,7 +85,7 @@ struct vendor_data { + + static unsigned int get_fifosize_arm(struct amba_device *dev) + { +- return amba_rev(dev) < 3 ? 16 : 32; ++ return 16; //TODO: fix: amba_rev(dev) < 3 ? 16 : 32; + } + + static struct vendor_data vendor_arm = { +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +index b5bedae..b0258e8 100644 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -285,6 +285,7 @@ struct mmc_host { + MMC_CAP2_HS400_1_2V) + #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) + #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) ++#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ + + mmc_pm_flag_t pm_caps; /* supported pm features */ + -From ade70caa2a108d3a2257a32ce6873758ae968f97 Mon Sep 17 00:00:00 2001 +From aa090a771afa15310eb10d3209c190441f3ecefd Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 16 Jun 2015 23:48:09 +0100 +Subject: [PATCH 02/77] power: Add power driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: popcornmix + +BCM270x: power: Change initcall level to subsys + +Load ordering of modules are determined by the initcall used. +If it's the same initcall level, makefile ordering decides. +Now that the mailbox driver is being moved, it's no longer +placed before the power driver by the linker. +So use a later initcall level to let the mailbox driver +load first. + +Signed-off-by: Noralf Trønnes + +BCM270x: Move power module + +Make the power module available on ARCH_BCM2835 by moving it. +The module turns on USB power making it possible to boot +ARCH_BCM2835 directly with the VC bootloader. + +Signed-off-by: Noralf Trønnes +--- + drivers/soc/Kconfig | 1 + + drivers/soc/Makefile | 1 + + drivers/soc/bcm2835/Kconfig | 9 ++ + drivers/soc/bcm2835/Makefile | 1 + + drivers/soc/bcm2835/bcm2708-power.c | 200 ++++++++++++++++++++++++++++++++++++ + include/soc/bcm2835/power.h | 61 +++++++++++ + 6 files changed, 273 insertions(+) + create mode 100644 drivers/soc/bcm2835/Kconfig + create mode 100644 drivers/soc/bcm2835/Makefile + create mode 100644 drivers/soc/bcm2835/bcm2708-power.c + create mode 100644 include/soc/bcm2835/power.h + +diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig +index d8bde82..595c9cd 100644 +--- a/drivers/soc/Kconfig ++++ b/drivers/soc/Kconfig +@@ -1,5 +1,6 @@ + menu "SOC (System On Chip) specific Drivers" + ++source "drivers/soc/bcm2835/Kconfig" + source "drivers/soc/mediatek/Kconfig" + source "drivers/soc/qcom/Kconfig" + source "drivers/soc/ti/Kconfig" +diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile +index 70042b2..9ad449c 100644 +--- a/drivers/soc/Makefile ++++ b/drivers/soc/Makefile +@@ -2,6 +2,7 @@ + # Makefile for the Linux Kernel SOC specific device drivers. + # + ++obj-y += bcm2835/ + obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ + obj-$(CONFIG_ARCH_QCOM) += qcom/ + obj-$(CONFIG_ARCH_TEGRA) += tegra/ +diff --git a/drivers/soc/bcm2835/Kconfig b/drivers/soc/bcm2835/Kconfig +new file mode 100644 +index 0000000..c2980f3 +--- /dev/null ++++ b/drivers/soc/bcm2835/Kconfig +@@ -0,0 +1,9 @@ ++# ++# BCM2835 Soc drivers ++# ++config BCM2708_POWER ++ tristate "BCM2708 legacy power driver" ++ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX ++ default y ++ help ++ Turns on USB power and provides an API for controlling power. +diff --git a/drivers/soc/bcm2835/Makefile b/drivers/soc/bcm2835/Makefile +new file mode 100644 +index 0000000..3614ad9 +--- /dev/null ++++ b/drivers/soc/bcm2835/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_BCM2708_POWER) += bcm2708-power.o +diff --git a/drivers/soc/bcm2835/bcm2708-power.c b/drivers/soc/bcm2835/bcm2708-power.c +new file mode 100644 +index 0000000..e7931a9 +--- /dev/null ++++ b/drivers/soc/bcm2835/bcm2708-power.c +@@ -0,0 +1,200 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/power.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "bcm2708_power" ++ ++#define BCM_POWER_MAXCLIENTS 4 ++#define BCM_POWER_NOCLIENT (1<<31) ++ ++/* Some drivers expect there devices to be permanently powered */ ++ ++#ifdef CONFIG_USB ++#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) ++#endif ++ ++#if 1 ++#define DPRINTK printk ++#else ++#define DPRINTK if (0) printk ++#endif ++ ++struct state_struct { ++ uint32_t global_request; ++ uint32_t client_request[BCM_POWER_MAXCLIENTS]; ++ struct semaphore client_mutex; ++ struct semaphore mutex; ++} g_state; ++ ++int bcm_power_open(BCM_POWER_HANDLE_T *handle) ++{ ++ BCM_POWER_HANDLE_T i; ++ int ret = -EBUSY; ++ ++ down(&g_state.client_mutex); ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { ++ g_state.client_request[i] = BCM_POWER_NONE; ++ *handle = i; ++ ret = 0; ++ break; ++ } ++ } ++ ++ up(&g_state.client_mutex); ++ ++ DPRINTK("bcm_power_open() -> %d\n", *handle); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(bcm_power_open); ++ ++int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) ++{ ++ int rc = 0; ++ ++ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); ++ ++ if ((handle < BCM_POWER_MAXCLIENTS) && ++ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { ++ if (down_interruptible(&g_state.mutex) != 0) { ++ DPRINTK("bcm_power_request -> interrupted\n"); ++ return -EINTR; ++ } ++ ++ if (request != g_state.client_request[handle]) { ++ uint32_t others_request = 0; ++ uint32_t global_request; ++ BCM_POWER_HANDLE_T i; ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (i != handle) ++ others_request |= ++ g_state.client_request[i]; ++ } ++ others_request &= ~BCM_POWER_NOCLIENT; ++ ++ global_request = request | others_request; ++ if (global_request != g_state.global_request) { ++ uint32_t actual; ++ ++ /* Send a request to VideoCore */ ++ 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); ++ DPRINTK ++ ("bcm_mailbox_read -> %08x, %d\n", ++ actual, rc); ++ actual >>= 4; ++ } else { ++ rc = 0; ++ actual = global_request; ++ } ++ ++ 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", ++ __func__, ++ g_state.global_request, ++ global_request, actual, request, others_request); ++ /* A failure */ ++ BUG_ON((others_request & actual) ++ != others_request); ++ request &= actual; ++ rc = -EIO; ++ } ++ ++ g_state.global_request = actual; ++ g_state.client_request[handle] = ++ request; ++ } ++ } ++ } ++ up(&g_state.mutex); ++ } else { ++ rc = -EINVAL; ++ } ++ DPRINTK("bcm_power_request -> %d\n", rc); ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_request); ++ ++int bcm_power_close(BCM_POWER_HANDLE_T handle) ++{ ++ int rc; ++ ++ DPRINTK("bcm_power_close(%d)\n", handle); ++ ++ rc = bcm_power_request(handle, BCM_POWER_NONE); ++ if (rc == 0) ++ g_state.client_request[handle] = BCM_POWER_NOCLIENT; ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_close); ++ ++static int __init bcm_power_init(void) ++{ ++#if defined(BCM_POWER_ALWAYS_ON) ++ BCM_POWER_HANDLE_T always_on_handle; ++#endif ++ int rc = 0; ++ 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; ++ ++ sema_init(&g_state.client_mutex, 1); ++ sema_init(&g_state.mutex, 1); ++ ++ g_state.global_request = 0; ++ ++#if defined(BCM_POWER_ALWAYS_ON) ++ if (BCM_POWER_ALWAYS_ON) { ++ bcm_power_open(&always_on_handle); ++ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); ++ } ++#endif ++ ++ return rc; ++} ++ ++static void __exit bcm_power_exit(void) ++{ ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); ++} ++ ++/* ++ * Load after the mailbox driver is initialized (arch_initcall), ++ * but before depending drivers (module_init). ++ */ ++subsys_initcall(bcm_power_init); ++module_exit(bcm_power_exit); ++ ++MODULE_AUTHOR("Phil Elwell"); ++MODULE_DESCRIPTION("Interface to BCM2708 power management"); ++MODULE_LICENSE("GPL"); +diff --git a/include/soc/bcm2835/power.h b/include/soc/bcm2835/power.h +new file mode 100644 +index 0000000..bf22b26 +--- /dev/null ++++ b/include/soc/bcm2835/power.h +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#ifndef _BCM2708_POWER_H ++#define _BCM2708_POWER_H ++ ++#include ++ ++/* Use meaningful names on each side */ ++#ifdef __VIDEOCORE__ ++#define PREFIX(x) ARM_##x ++#else ++#define PREFIX(x) BCM_##x ++#endif ++ ++enum { ++ PREFIX(POWER_SDCARD_BIT), ++ PREFIX(POWER_UART_BIT), ++ PREFIX(POWER_MINIUART_BIT), ++ PREFIX(POWER_USB_BIT), ++ PREFIX(POWER_I2C0_BIT), ++ PREFIX(POWER_I2C1_BIT), ++ PREFIX(POWER_I2C2_BIT), ++ PREFIX(POWER_SPI_BIT), ++ PREFIX(POWER_CCP2TX_BIT), ++ PREFIX(POWER_DSI_BIT), ++ ++ PREFIX(POWER_MAX) ++}; ++ ++enum { ++ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), ++ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), ++ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), ++ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), ++ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), ++ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), ++ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), ++ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), ++ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), ++ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), ++ ++ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, ++ PREFIX(POWER_NONE) = 0 ++}; ++ ++typedef unsigned int BCM_POWER_HANDLE_T; ++ ++extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); ++extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); ++extern int bcm_power_close(BCM_POWER_HANDLE_T handle); ++ ++#endif + +From 9409d45ef7d82d4f0677ea1a16bb6e87d41ed8de Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 Oct 2014 18:50:05 +0100 -Subject: [PATCH 003/216] Add bcm2708_gpio driver +Subject: [PATCH 03/77] Add bcm2708_gpio driver Signed-off-by: popcornmix @@ -11130,22 +7400,23 @@ Issue: linux #760 --- arch/arm/mach-bcm2708/Kconfig | 8 + arch/arm/mach-bcm2708/Makefile | 1 + - arch/arm/mach-bcm2708/bcm2708.c | 28 ++ + arch/arm/mach-bcm2708/bcm2708.c | 25 ++ arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++ arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++ + arch/arm/mach-bcm2709/bcm2709.c | 25 ++ include/linux/platform_data/bcm2708.h | 23 ++ - 6 files changed, 503 insertions(+) + 7 files changed, 525 insertions(+) create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h create mode 100644 include/linux/platform_data/bcm2708.h diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 1f11478..9355841 100644 +index 4955422..4cbda0c 100644 --- a/arch/arm/mach-bcm2708/Kconfig +++ b/arch/arm/mach-bcm2708/Kconfig -@@ -9,6 +9,14 @@ config MACH_BCM2708 +@@ -20,6 +20,14 @@ config BCM2708_DT help - Include support for the Broadcom(R) BCM2708 platform. + Enable Device Tree support for BCM2708 +config BCM2708_GPIO + bool "BCM2708 gpio support" @@ -11155,24 +7426,23 @@ index 1f11478..9355841 100644 + help + Include support for the Broadcom(R) BCM2708 gpio. + - config BCM2708_VCMEM - bool "Videocore Memory" + config BCM2708_NOL2CACHE + bool "Videocore L2 cache disable" depends on MACH_BCM2708 diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index c76f39bc..a722f3f 100644 +index e7d5a29..5120994 100644 --- a/arch/arm/mach-bcm2708/Makefile +++ b/arch/arm/mach-bcm2708/Makefile -@@ -3,4 +3,5 @@ +@@ -3,3 +3,4 @@ # - obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o + obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o +obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 9b4e709..7503649 100644 +index d6659b0..c606853 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -331,6 +331,31 @@ static struct platform_device bcm2708_vcio_device = { +@@ -298,6 +298,31 @@ static struct platform_device bcm2708_vcio_device = { }, }; @@ -11201,19 +7471,9 @@ index 9b4e709..7503649 100644 +}; +#endif + - static struct resource bcm2708_systemtimer_resources[] = { - [0] = { /* system timer access */ - .start = ST_BASE, -@@ -473,6 +498,9 @@ void __init bcm2708_init(void) - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_vcio_device); -+#ifdef CONFIG_BCM2708_GPIO -+ bcm_register_device(&bcm2708_gpio_device); -+#endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c new file mode 100644 index 0000000..c1e9254 @@ -11669,6 +7929,42 @@ index 0000000..7965a97 +#define irq_to_gpio(x) ((x) - GPIO_IRQ_START) + +#endif +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 19d0601..6060a0d 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -329,6 +329,31 @@ static struct platform_device bcm2708_vcio_device = { + }, + }; + ++#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, ++ }, ++}; ++ ++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 ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; diff --git a/include/linux/platform_data/bcm2708.h b/include/linux/platform_data/bcm2708.h new file mode 100644 index 0000000..fb69624 @@ -11699,10 +7995,647 @@ index 0000000..fb69624 + +#endif -From 2ca472651d3e308f62709f5e2536eaba99944b11 Mon Sep 17 00:00:00 2001 +From 4b9ec02bb6738a9c29f6308c55cbcab58c2c88a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 1 May 2015 19:11:03 +0200 +Subject: [PATCH 04/77] mailbox: bcm2708: Add bcm2708-vcio +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: popcornmix + +Copy the arch vcio.c driver to drivers/mailbox. +This is done to make it available on ARCH_BCM2835. + +Signed-off-by: Noralf Trønnes + +mailbox: bcm2708-vcio: Allocation does not need to be atomic + +No need to do atomic allocation in a context that can sleep. + +Signed-off-by: Noralf Trønnes + +mailbox: bcm2708-vcio: Check the correct status register before writing + +With the VC reader blocked and the ARM writing, MAIL0_STA reads +empty permanently while MAIL1_STA goes from empty (0x40000000) +to non-empty (0x00000001-0x00000007) to full (0x80000008). + +Suggested-by: Phil Elwell +Signed-off-by: Noralf Trønnes +--- + drivers/mailbox/Kconfig | 6 + + drivers/mailbox/Makefile | 2 + + drivers/mailbox/bcm2708-vcio.c | 427 ++++++++++++++++++++++++++ + include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++ + 4 files changed, 561 insertions(+) + create mode 100644 drivers/mailbox/bcm2708-vcio.c + create mode 100644 include/linux/platform_data/mailbox-bcm2708.h + +diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig +index 84b0a2d..7f19cb4 100644 +--- a/drivers/mailbox/Kconfig ++++ b/drivers/mailbox/Kconfig +@@ -7,6 +7,12 @@ menuconfig MAILBOX + + if MAILBOX + ++config BCM2708_MBOX ++ bool "Broadcom BCM2708 Mailbox (vcio)" ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 ++ help ++ Broadcom BCM2708 Mailbox (vcio) ++ + config ARM_MHU + tristate "ARM MHU Mailbox" + depends on ARM_AMBA +diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile +index b18201e..cecfad3 100644 +--- a/drivers/mailbox/Makefile ++++ b/drivers/mailbox/Makefile +@@ -2,6 +2,8 @@ + + obj-$(CONFIG_MAILBOX) += mailbox.o + ++obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o ++ + obj-$(CONFIG_ARM_MHU) += arm_mhu.o + + obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o +diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c +new file mode 100644 +index 0000000..d91672b +--- /dev/null ++++ b/drivers/mailbox/bcm2708-vcio.c +@@ -0,0 +1,427 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/vcio.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for writing to the mailboxes, ++ * semaphores, doorbells etc. that are shared between the ARM and the ++ * VideoCore processor ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "bcm2708_vcio" ++#define DEVICE_FILE_NAME "vcio" ++ ++/* offsets from a mail box base address */ ++#define MAIL0_RD 0x00 /* read - and next 4 words */ ++#define MAIL0_POL 0x10 /* read without popping the fifo */ ++#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ ++#define MAIL0_STA 0x18 /* status */ ++#define MAIL0_CNF 0x1C /* configuration */ ++#define MAIL1_WRT 0x20 /* write - and next 4 words */ ++#define MAIL1_STA 0x38 /* status */ ++ ++/* On MACH_BCM270x these come through (arm_control.h ) */ ++#ifndef ARM_MS_EMPTY ++#define ARM_MS_EMPTY BIT(30) ++#define ARM_MS_FULL BIT(31) ++ ++#define ARM_MC_IHAVEDATAIRQEN BIT(0) ++#endif ++ ++#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) ++#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) ++#define MBOX_CHAN(msg) ((msg) & 0xf) ++#define MBOX_DATA28(msg) ((msg) & ~0xf) ++#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) ++ ++#define MBOX_MAGIC 0xd0d0c0de ++ ++#define MAJOR_NUM 100 ++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) ++ ++static struct class *vcio_class; ++ ++struct vc_mailbox { ++ void __iomem *regs; ++ uint32_t msg[MBOX_CHAN_COUNT]; ++ struct semaphore sema[MBOX_CHAN_COUNT]; ++ uint32_t magic; ++}; ++ ++static void mbox_init(struct vc_mailbox *mbox_out) ++{ ++ int i; ++ ++ for (i = 0; i < MBOX_CHAN_COUNT; i++) { ++ mbox_out->msg[i] = 0; ++ sema_init(&mbox_out->sema[i], 0); ++ } ++ ++ /* Enable the interrupt on data reception */ ++ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); ++ ++ mbox_out->magic = MBOX_MAGIC; ++} ++ ++static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) ++{ ++ if (mbox->magic != MBOX_MAGIC) ++ return -EINVAL; ++ ++ /* wait for the mailbox FIFO to have some space in it */ ++ while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) ++ cpu_relax(); ++ ++ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); ++ ++ return 0; ++} ++ ++static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) ++{ ++ if (mbox->magic != MBOX_MAGIC) ++ return -EINVAL; ++ ++ down(&mbox->sema[chan]); ++ *data28 = MBOX_DATA28(mbox->msg[chan]); ++ mbox->msg[chan] = 0; ++ ++ return 0; ++} ++ ++static irqreturn_t mbox_irq_handler(int irq, void *dev_id) ++{ ++ /* wait for the mailbox FIFO to have some data in it */ ++ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; ++ int status = readl(mbox->regs + MAIL0_STA); ++ int ret = IRQ_NONE; ++ ++ while (!(status & ARM_MS_EMPTY)) { ++ uint32_t msg = readl(mbox->regs + MAIL0_RD); ++ int chan = MBOX_CHAN(msg); ++ ++ if (chan < MBOX_CHAN_COUNT) { ++ if (mbox->msg[chan]) { ++ pr_err(DRIVER_NAME ++ ": mbox chan %d overflow - drop %08x\n", ++ chan, msg); ++ } else { ++ mbox->msg[chan] = (msg | 0xf); ++ up(&mbox->sema[chan]); ++ } ++ } else { ++ pr_err(DRIVER_NAME ++ ": invalid channel selector (msg %08x)\n", msg); ++ } ++ ret = IRQ_HANDLED; ++ status = readl(mbox->regs + MAIL0_STA); ++ } ++ return ret; ++} ++ ++/* Mailbox Methods */ ++ ++static struct device *mbox_dev; /* we assume there's only one! */ ++ ++static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) ++{ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ int rc; ++ ++ device_lock(dev); ++ rc = mbox_write(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) ++{ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ int rc; ++ ++ device_lock(dev); ++ rc = mbox_read(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++extern int bcm_mailbox_write(unsigned chan, uint32_t data28) ++{ ++ if (!mbox_dev) ++ return -ENODEV; ++ ++ return dev_mbox_write(mbox_dev, chan, data28); ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_write); ++ ++extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) ++{ ++ if (!mbox_dev) ++ return -ENODEV; ++ ++ return dev_mbox_read(mbox_dev, chan, data28); ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_read); ++ ++static int mbox_copy_from_user(void *dst, const void *src, int size) ++{ ++ if ((uint32_t)src < TASK_SIZE) ++ return copy_from_user(dst, src, size); ++ ++ memcpy(dst, src, size); ++ ++ return 0; ++} ++ ++static int mbox_copy_to_user(void *dst, const void *src, int size) ++{ ++ if ((uint32_t)dst < TASK_SIZE) ++ return copy_to_user(dst, src, size); ++ ++ memcpy(dst, src, size); ++ ++ return 0; ++} ++ ++static DEFINE_MUTEX(mailbox_lock); ++extern int bcm_mailbox_property(void *data, int size) ++{ ++ uint32_t success; ++ dma_addr_t mem_bus; /* the memory address accessed from videocore */ ++ void *mem_kern; /* the memory address accessed from driver */ ++ int s = 0; ++ ++ mutex_lock(&mailbox_lock); ++ /* allocate some memory for the messages communicating with GPU */ ++ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, ++ GFP_KERNEL); ++ if (mem_kern) { ++ /* create the message */ ++ mbox_copy_from_user(mem_kern, data, size); ++ ++ /* send the message */ ++ wmb(); ++ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); ++ if (s == 0) ++ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); ++ if (s == 0) { ++ /* copy the response */ ++ rmb(); ++ mbox_copy_to_user(data, mem_kern, size); ++ } ++ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); ++ } else { ++ s = -ENOMEM; ++ } ++ if (s != 0) ++ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); ++ ++ mutex_unlock(&mailbox_lock); ++ return s; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_property); ++ ++/* Platform Device for Mailbox */ ++ ++/* ++ * Is the device open right now? Used to prevent ++ * concurent access into the same device ++ */ ++static bool device_is_open; ++ ++/* This is called whenever a process attempts to open the device file */ ++static int device_open(struct inode *inode, struct file *file) ++{ ++ /* We don't want to talk to two processes at the same time */ ++ if (device_is_open) ++ return -EBUSY; ++ ++ device_is_open = true; ++ try_module_get(THIS_MODULE); ++ ++ return 0; ++} ++ ++static int device_release(struct inode *inode, struct file *file) ++{ ++ /* We're now ready for our next caller */ ++ device_is_open = false; ++ ++ module_put(THIS_MODULE); ++ ++ return 0; ++} ++ ++/* ++ * This function is called whenever a process tries to do an ioctl on our ++ * device file. We get two extra parameters (additional to the inode and file ++ * structures, which all device functions get): the number of the ioctl called ++ * and the parameter given to the ioctl function. ++ * ++ * If the ioctl is write or read/write (meaning output is returned to the ++ * calling process), the ioctl call returns the output of this function. ++ * ++ */ ++static long device_ioctl(struct file *file, unsigned int ioctl_num, ++ unsigned long ioctl_param) ++{ ++ unsigned size; ++ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY: ++ /* ++ * Receive a pointer to a message (in user space) and set that ++ * to be the device's message. Get the parameter given to ++ * ioctl by the process. ++ */ ++ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); ++ return bcm_mailbox_property((void *)ioctl_param, size); ++ default: ++ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Module Declarations */ ++ ++/* ++ * This structure will hold the functions to be called ++ * when a process does something to the device we ++ * created. Since a pointer to this structure is kept in ++ * the devices table, it can't be local to ++ * init_module. NULL is for unimplemented functios. ++ */ ++const struct file_operations fops = { ++ .unlocked_ioctl = device_ioctl, ++ .open = device_open, ++ .release = device_release, /* a.k.a. close */ ++}; ++ ++static int bcm_vcio_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device *vdev; ++ struct vc_mailbox *mailbox; ++ struct resource *res; ++ int irq, ret; ++ ++ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); ++ if (!mailbox) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ mailbox->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(mailbox->regs)) ++ return PTR_ERR(mailbox->regs); ++ ++ irq = platform_get_irq(pdev, 0); ++ ret = devm_request_irq(dev, irq, mbox_irq_handler, ++ IRQF_IRQPOLL, ++ dev_name(dev), mailbox); ++ if (ret) { ++ dev_err(dev, "Interrupt request failed %d\n", ret); ++ return ret; ++ } ++ ++ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); ++ if (ret < 0) { ++ pr_err("Character device registration failed %d\n", ret); ++ return ret; ++ } ++ ++ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); ++ if (IS_ERR(vcio_class)) { ++ ret = PTR_ERR(vcio_class); ++ pr_err("Class creation failed %d\n", ret); ++ goto err_class; ++ } ++ ++ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, ++ "vcio"); ++ if (IS_ERR(vdev)) { ++ ret = PTR_ERR(vdev); ++ pr_err("Device creation failed %d\n", ret); ++ goto err_dev; ++ } ++ ++ mbox_init(mailbox); ++ platform_set_drvdata(pdev, mailbox); ++ mbox_dev = dev; ++ ++ dev_info(dev, "mailbox at %p\n", mailbox->regs); ++ ++ return 0; ++ ++err_dev: ++ class_destroy(vcio_class); ++err_class: ++ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); ++ ++ return ret; ++} ++ ++static int bcm_vcio_remove(struct platform_device *pdev) ++{ ++ mbox_dev = NULL; ++ platform_set_drvdata(pdev, NULL); ++ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); ++ class_destroy(vcio_class); ++ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_vcio_of_match_table[] = { ++ { .compatible = "brcm,bcm2708-vcio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); ++ ++static struct platform_driver bcm_mbox_driver = { ++ .probe = bcm_vcio_probe, ++ .remove = bcm_vcio_remove, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_vcio_of_match_table, ++ }, ++}; ++ ++static int __init bcm_mbox_init(void) ++{ ++ return platform_driver_register(&bcm_mbox_driver); ++} ++ ++static void __exit bcm_mbox_exit(void) ++{ ++ platform_driver_unregister(&bcm_mbox_driver); ++} ++ ++arch_initcall(bcm_mbox_init); /* Initialize early */ ++module_exit(bcm_mbox_exit); ++ ++MODULE_AUTHOR("Gray Girling"); ++MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); ++MODULE_LICENSE("GPL"); +diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h +new file mode 100644 +index 0000000..cc284ed +--- /dev/null ++++ b/include/linux/platform_data/mailbox-bcm2708.h +@@ -0,0 +1,126 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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. ++ */ ++#ifndef _PLAT_MAILBOX_BCM2708_H ++#define _PLAT_MAILBOX_BCM2708_H ++ ++/* Routines to handle I/O via the VideoCore "ARM control" registers ++ * (semaphores, doorbells, mailboxes) ++ */ ++ ++/* Constants shared with the ARM identifying separate mailbox channels */ ++#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ ++#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ ++#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ ++#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ ++#define MBOX_CHAN_COUNT 9 ++ ++enum { ++ VCMSG_PROCESS_REQUEST = 0x00000000 ++}; ++ ++enum { ++ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, ++ VCMSG_REQUEST_FAILED = 0x80000001 ++}; ++ ++/* Mailbox property tags */ ++enum { ++ VCMSG_PROPERTY_END = 0x00000000, ++ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, ++ VCMSG_GET_BOARD_MODEL = 0x00010001, ++ VCMSG_GET_BOARD_REVISION = 0x00010002, ++ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, ++ VCMSG_GET_BOARD_SERIAL = 0x00010004, ++ VCMSG_GET_ARM_MEMORY = 0x00010005, ++ VCMSG_GET_VC_MEMORY = 0x00010006, ++ VCMSG_GET_CLOCKS = 0x00010007, ++ VCMSG_GET_COMMAND_LINE = 0x00050001, ++ VCMSG_GET_DMA_CHANNELS = 0x00060001, ++ VCMSG_GET_POWER_STATE = 0x00020001, ++ VCMSG_GET_TIMING = 0x00020002, ++ VCMSG_SET_POWER_STATE = 0x00028001, ++ VCMSG_GET_CLOCK_STATE = 0x00030001, ++ VCMSG_SET_CLOCK_STATE = 0x00038001, ++ VCMSG_GET_CLOCK_RATE = 0x00030002, ++ VCMSG_SET_CLOCK_RATE = 0x00038002, ++ VCMSG_GET_VOLTAGE = 0x00030003, ++ VCMSG_SET_VOLTAGE = 0x00038003, ++ VCMSG_GET_MAX_CLOCK = 0x00030004, ++ VCMSG_GET_MAX_VOLTAGE = 0x00030005, ++ VCMSG_GET_TEMPERATURE = 0x00030006, ++ VCMSG_GET_MIN_CLOCK = 0x00030007, ++ VCMSG_GET_MIN_VOLTAGE = 0x00030008, ++ VCMSG_GET_TURBO = 0x00030009, ++ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, ++ VCMSG_GET_STC = 0x0003000b, ++ VCMSG_SET_TURBO = 0x00038009, ++ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, ++ VCMSG_SET_LOCK_MEM = 0x0003000d, ++ VCMSG_SET_UNLOCK_MEM = 0x0003000e, ++ VCMSG_SET_RELEASE_MEM = 0x0003000f, ++ VCMSG_SET_EXECUTE_CODE = 0x00030010, ++ VCMSG_SET_EXECUTE_QPU = 0x00030011, ++ VCMSG_SET_ENABLE_QPU = 0x00030012, ++ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, ++ VCMSG_GET_EDID_BLOCK = 0x00030020, ++ VCMSG_GET_CUSTOMER_OTP = 0x00030021, ++ VCMSG_SET_CUSTOMER_OTP = 0x00038021, ++ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, ++ VCMSG_SET_RELEASE_BUFFER = 0x00048001, ++ VCMSG_SET_BLANK_SCREEN = 0x00040002, ++ VCMSG_TST_BLANK_SCREEN = 0x00044002, ++ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, ++ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, ++ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, ++ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, ++ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, ++ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, ++ VCMSG_GET_DEPTH = 0x00040005, ++ VCMSG_TST_DEPTH = 0x00044005, ++ VCMSG_SET_DEPTH = 0x00048005, ++ VCMSG_GET_PIXEL_ORDER = 0x00040006, ++ VCMSG_TST_PIXEL_ORDER = 0x00044006, ++ VCMSG_SET_PIXEL_ORDER = 0x00048006, ++ VCMSG_GET_ALPHA_MODE = 0x00040007, ++ VCMSG_TST_ALPHA_MODE = 0x00044007, ++ VCMSG_SET_ALPHA_MODE = 0x00048007, ++ VCMSG_GET_PITCH = 0x00040008, ++ VCMSG_TST_PITCH = 0x00044008, ++ VCMSG_SET_PITCH = 0x00048008, ++ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, ++ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, ++ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, ++ VCMSG_GET_OVERSCAN = 0x0004000a, ++ VCMSG_TST_OVERSCAN = 0x0004400a, ++ VCMSG_SET_OVERSCAN = 0x0004800a, ++ VCMSG_GET_PALETTE = 0x0004000b, ++ VCMSG_TST_PALETTE = 0x0004400b, ++ VCMSG_SET_PALETTE = 0x0004800b, ++ VCMSG_GET_LAYER = 0x0004000c, ++ VCMSG_TST_LAYER = 0x0004400c, ++ VCMSG_SET_LAYER = 0x0004800c, ++ VCMSG_GET_TRANSFORM = 0x0004000d, ++ VCMSG_TST_TRANSFORM = 0x0004400d, ++ VCMSG_SET_TRANSFORM = 0x0004800d, ++ VCMSG_TST_VSYNC = 0x0004400e, ++ VCMSG_SET_VSYNC = 0x0004800e, ++ VCMSG_SET_CURSOR_INFO = 0x00008010, ++ VCMSG_SET_CURSOR_STATE = 0x00008011, ++}; ++ ++int bcm_mailbox_read(unsigned chan, uint32_t *data28); ++int bcm_mailbox_write(unsigned chan, uint32_t data28); ++int bcm_mailbox_property(void *data, int size); ++ ++#endif + +From c921ec1cd21e8a8eb4e453834a205e9da5dff30a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 004/216] Add dwc_otg driver +Subject: [PATCH 05/77] Add dwc_otg driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix @@ -12117,16 +9050,38 @@ in the middle of a transaction. Make the effects less severe. Also get rid of the useless return value. squash: dwc_otg: Allow to build without SMP + +usb: core: make overcurrent messages more prominent + +Hub overcurrent messages are more serious than "debug". Increase loglevel. + +usb: dwc_otg: Don't use dma_to_virt() + +Commit 6ce0d20 changes dma_to_virt() which breaks this driver. +Open code the old dma_to_virt() implementation to work around this. + +Limit the use of __bus_to_virt() to cases where transfer_buffer_length +is set and transfer_buffer is not set. This is done to increase the +chance that this driver will also work on ARCH_BCM2835. + +transfer_buffer should not be NULL if the length is set, but the +comment in the code indicates that there are situations where this +might happen. drivers/usb/isp1760/isp1760-hcd.c also has a similar +comment pointing to a possible: 'usb storage / SCSI bug'. + +Signed-off-by: Noralf Trønnes + +dwc_otg: Fix crash when fiq_enable=0 --- - arch/arm/Kconfig | 1 + arch/arm/include/asm/irqflags.h | 16 +- arch/arm/kernel/fiqasm.S | 4 + arch/arm/mach-bcm2708/armctrl.c | 19 +- - arch/arm/mach-bcm2708/bcm2708.c | 15 +- + arch/arm/mach-bcm2708/bcm2708.c | 11 + arch/arm/mach-bcm2708/include/mach/irqs.h | 153 +- arch/arm/mach-bcm2709/armctrl.c | 10 +- drivers/usb/Makefile | 1 + drivers/usb/core/generic.c | 1 + + drivers/usb/core/hub.c | 2 +- drivers/usb/core/message.c | 79 + drivers/usb/core/otg_whitelist.h | 114 +- drivers/usb/gadget/file_storage.c | 3676 ++++++++++ @@ -12169,7 +9124,7 @@ squash: dwc_otg: Allow to build without SMP drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 1594 +++++ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 705 ++ drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 117 + - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1749 +++++ + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1756 +++++ drivers/usb/host/dwc_otg/dwc_otg_driver.h | 86 + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 1346 ++++ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 367 + @@ -12179,7 +9134,7 @@ squash: dwc_otg: Allow to build without SMP drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 1132 ++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 417 ++ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2713 ++++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 994 +++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 995 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 957 +++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 188 + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2712 ++++++++ @@ -12192,7 +9147,7 @@ squash: dwc_otg: Allow to build without SMP drivers/usb/host/dwc_otg/test/dwc_otg_test.pm | 337 + drivers/usb/host/dwc_otg/test/test_mod_param.pl | 133 + drivers/usb/host/dwc_otg/test/test_sysfs.pl | 193 + - 74 files changed, 60026 insertions(+), 97 deletions(-) + 74 files changed, 60032 insertions(+), 96 deletions(-) create mode 100644 drivers/usb/gadget/file_storage.c create mode 100644 drivers/usb/host/dwc_common_port/Makefile create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd @@ -12255,18 +9210,6 @@ squash: dwc_otg: Allow to build without SMP create mode 100644 drivers/usb/host/dwc_otg/test/test_mod_param.pl create mode 100644 drivers/usb/host/dwc_otg/test/test_sysfs.pl -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 4018fea..ee1bb5e 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -382,6 +382,7 @@ config ARCH_BCM2708 - select ARM_ERRATA_411920 - select MACH_BCM2708 - select VC4 -+ select FIQ - help - This enables support for Broadcom BCM2708 boards. - diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h index 3b763d6..5770408 100644 --- a/arch/arm/include/asm/irqflags.h @@ -12310,10 +9253,10 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index ef1c8d5..96fa9b9 100644 +index cd252fa..74bacb3 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -52,8 +52,12 @@ static void armctrl_mask_irq(struct irq_data *d) +@@ -54,8 +54,12 @@ static void armctrl_mask_irq(struct irq_data *d) 0 }; @@ -12328,7 +9271,7 @@ index ef1c8d5..96fa9b9 100644 } static void armctrl_unmask_irq(struct irq_data *d) -@@ -65,8 +69,14 @@ static void armctrl_unmask_irq(struct irq_data *d) +@@ -67,8 +71,14 @@ static void armctrl_unmask_irq(struct irq_data *d) 0 }; @@ -12344,38 +9287,37 @@ index ef1c8d5..96fa9b9 100644 + } } - #if defined(CONFIG_PM) -@@ -204,5 +214,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + #ifdef CONFIG_OF +@@ -299,6 +309,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, } armctrl_pm_register(base, irq_start, resume_sources); + init_FIQ(FIQ_START); + armctrl_dt_init(); return 0; } diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 7503649..d9db081 100644 +index c606853..4455f34 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -291,12 +291,23 @@ static struct resource bcm2708_usb_resources[] = { - .flags = IORESOURCE_MEM, - }, +@@ -254,12 +254,23 @@ static struct resource bcm2708_usb_resources[] = { + .flags = IORESOURCE_MEM, + }, [1] = { -- .start = IRQ_USB, -- .end = IRQ_USB, + .start = MPHI_BASE, + .end = MPHI_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, -+ }, ++ }, + [2] = { -+ .start = IRQ_HOSTPORT, -+ .end = IRQ_HOSTPORT, - .flags = IORESOURCE_IRQ, - }, ++ .start = IRQ_HOSTPORT, ++ .end = IRQ_HOSTPORT, ++ .flags = IORESOURCE_IRQ, ++ }, + [3] = { -+ .start = IRQ_USB, -+ .end = IRQ_USB, -+ .flags = IORESOURCE_IRQ, -+ }, + .start = IRQ_USB, + .end = IRQ_USB, + .flags = IORESOURCE_IRQ, + }, }; + @@ -12553,7 +9495,7 @@ index 3a88a1a..45152ed 100644 #define SPARE_ALLOC_IRQS 64 #define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c -index 2815b64..fc6cb8b 100644 +index 2fcfab9..a366275 100644 --- a/arch/arm/mach-bcm2709/armctrl.c +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -91,7 +91,15 @@ static void armctrl_unmask_irq(struct irq_data *d) @@ -12574,12 +9516,12 @@ index 2815b64..fc6cb8b 100644 } else if (d->irq >= IRQ_ARM_LOCAL_CNTPSIRQ && d->irq < IRQ_ARM_LOCAL_CNTPSIRQ + 4) { #if 1 diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile -index 2f1e2aa..887ca56 100644 +index d8926c6..0607af9 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile -@@ -6,6 +6,7 @@ - +@@ -7,6 +7,7 @@ obj-$(CONFIG_USB) += core/ + obj-$(CONFIG_USB_SUPPORT) += phy/ +obj-$(CONFIG_USB_DWCOTG) += host/ obj-$(CONFIG_USB_DWC3) += dwc3/ @@ -12597,6 +9539,19 @@ index 358ca8d..abaac7c 100644 } return i; } +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 3b71516..8324c14 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4922,7 +4922,7 @@ static void port_event(struct usb_hub *hub, int port1) + if (portchange & USB_PORT_STAT_C_OVERCURRENT) { + u16 status = 0, unused; + +- dev_dbg(&port_dev->dev, "over-current change\n"); ++ dev_notice(&port_dev->dev, "over-current change\n"); + usb_clear_port_feature(hdev, port1, + USB_PORT_FEAT_C_OVER_CURRENT); + msleep(100); /* Cool down */ diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..2f6e3fe 100644 --- a/drivers/usb/core/message.c @@ -16527,7 +13482,7 @@ index 0000000..a896d73 +} +module_exit(fsg_cleanup); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 5ad60e4..fb5b986 100644 +index 197a6a3..5496cd0 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -738,6 +738,19 @@ config USB_HWA_HCD @@ -44589,10 +41544,10 @@ index 0000000..ccc24e0 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c new file mode 100644 -index 0000000..dc7cd32 +index 0000000..53307f0 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -0,0 +1,1749 @@ +@@ -0,0 +1,1756 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $ + * $Revision: #92 $ @@ -45638,9 +42593,16 @@ index 0000000..dc7cd32 +}; +MODULE_DEVICE_TABLE(platform, platform_ids); + ++static const struct of_device_id dwc_otg_of_match_table[] = { ++ { .compatible = "brcm,bcm2708-usb", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dwc_otg_of_match_table); ++ +static struct platform_driver dwc_otg_driver = { + .driver = { + .name = (char *)dwc_driver_name, ++ .of_match_table = dwc_otg_of_match_table, + }, + .id_table = platform_ids, + @@ -48247,7 +45209,7 @@ index 0000000..ffa8d21 +END(_dwc_otg_fiq_stub) diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c new file mode 100644 -index 0000000..6c53d2c +index 0000000..4d7c7bb --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c @@ -0,0 +1,4252 @@ @@ -50273,7 +47235,7 @@ index 0000000..6c53d2c + * we hold off on bulk retransmissions to reduce NAK interrupt overhead for full-speed + * cheeky devices that just hold off using NAKs + */ -+ if (nak_holdoff && qh->do_split) { ++ if (fiq_enable && nak_holdoff && qh->do_split) { + if (qh->nak_frame != 0xffff) { + uint16_t next_frame = dwc_frame_num_inc(qh->nak_frame, (qh->ep_type == UE_BULK) ? nak_holdoff : 8); + uint16_t frame = dwc_otg_hcd_get_frame_number(hcd); @@ -57653,10 +54615,10 @@ index 0000000..8a31562 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c new file mode 100644 -index 0000000..1d28459 +index 0000000..0f4ebcd --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -0,0 +1,994 @@ +@@ -0,0 +1,995 @@ + +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $ @@ -58195,9 +55157,9 @@ index 0000000..1d28459 + * IRQ line, and calls hcd_start method. + */ +#ifdef PLATFORM_INTERFACE -+ retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED | IRQF_DISABLED); ++ retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED); +#else -+ retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED | IRQF_DISABLED); ++ retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED); +#endif + if (retval < 0) { + goto error2; @@ -58425,16 +55387,17 @@ index 0000000..1d28459 + !(usb_pipein(urb->pipe)))); + + buf = urb->transfer_buffer; -+ if (hcd->self.uses_dma) { ++ if (hcd->self.uses_dma && !buf && urb->transfer_buffer_length) { + /* + * Calculate virtual address from physical address, + * because some class driver may not fill transfer_buffer. + * In Buffer DMA mode virual address is used, + * when handling non DWORD aligned buffers. + */ -+ //buf = phys_to_virt(urb->transfer_dma); -+ // DMA addresses are bus addresses not physical addresses! -+ buf = dma_to_virt(&urb->dev->dev, urb->transfer_dma); ++ buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma); ++ dev_warn_once(&urb->dev->dev, ++ "USB transfer_buffer was NULL, will use __bus_to_virt(%pad)=%p\n", ++ &urb->transfer_dma, buf); + } + + if (!(urb->transfer_flags & URB_NO_INTERRUPT)) @@ -72943,24 +69906,24 @@ index 0000000..cdc9963 +test_main(); +0; -From 0876a9278a3227e3f8924b6e04c1af6c18d4e1e7 Mon Sep 17 00:00:00 2001 +From 560486db654a651cebb107628426d1705ef4cc20 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:54:32 +0100 -Subject: [PATCH 005/216] bcm2708 watchdog driver +Subject: [PATCH 06/77] bcm2708 watchdog driver Signed-off-by: popcornmix --- - drivers/watchdog/Kconfig | 6 + + drivers/watchdog/Kconfig | 8 +- drivers/watchdog/Makefile | 1 + drivers/watchdog/bcm2708_wdog.c | 382 ++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 389 insertions(+) + 3 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 drivers/watchdog/bcm2708_wdog.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index 16f2023..ca7d6463 100644 +index e5e7c55..b9c1ed5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -452,6 +452,12 @@ config RETU_WATCHDOG +@@ -451,6 +451,12 @@ config RETU_WATCHDOG To compile this driver as a module, choose M here: the module will be called retu_wdt. @@ -72973,6 +69936,15 @@ index 16f2023..ca7d6463 100644 config MOXART_WDT tristate "MOXART watchdog" depends on ARCH_MOXART +@@ -1216,7 +1222,7 @@ config BCM63XX_WDT + + config BCM2835_WDT + tristate "Broadcom BCM2835 hardware watchdog" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + select WATCHDOG_CORE + help + Watchdog driver for the built in watchdog hardware in Broadcom diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 5c19294..aac60bd 100644 --- a/drivers/watchdog/Makefile @@ -73374,10 +70346,13 @@ index 0000000..8a27d68 +MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_LICENSE("GPL"); -From e32648d3db67d9954ee0a8bc13ab3f81345c50af Mon Sep 17 00:00:00 2001 +From 7014dbd386a6ce510bd6b9fa3a3fcfc2bd89d237 Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Wed, 1 May 2013 19:55:09 +0100 -Subject: [PATCH 006/216] bcm2708 framebuffer driver +Date: Wed, 17 Jun 2015 17:06:34 +0100 +Subject: [PATCH 07/77] bcm2708 framebuffer driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix @@ -73423,55 +70398,40 @@ transfers, busy-waiting is still likely to be faster. Signed-off-by: Luke Diamand bcm2708: Make ioctl logging quieter + +video: fbdev: bcm2708_fb: Don't panic on error + +No need to panic the kernel if the video driver fails. +Just print a message and return an error. + +Signed-off-by: Noralf Trønnes + +fbdev: bcm2708_fb: Add ARCH_BCM2835 support + +Add Device Tree support. +Pass the device to dma_alloc_coherent() in order to get the +correct bus address on ARCH_BCM2835. +Use the new DMA legacy API header file. +Including is not necessary. + +Signed-off-by: Noralf Trønnes + +BCM270x_DT: Add bcm2708-fb device + +Add bcm2708-fb to Device Tree and don't add the +platform device when booting in DT mode. + +Signed-off-by: Noralf Trønnes --- - arch/arm/mach-bcm2708/dma.c | 8 + - arch/arm/mach-bcm2708/include/mach/dma.h | 2 + drivers/video/fbdev/Kconfig | 14 + drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/bcm2708_fb.c | 818 ++++++++++ + drivers/video/fbdev/bcm2708_fb.c | 824 ++++++++++ drivers/video/logo/logo_linux_clut224.ppm | 2483 ++++++++++------------------- - 6 files changed, 1724 insertions(+), 1602 deletions(-) + 4 files changed, 1720 insertions(+), 1602 deletions(-) create mode 100644 drivers/video/fbdev/bcm2708_fb.c -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -index 51d147a..1da2413 100644 ---- a/arch/arm/mach-bcm2708/dma.c -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -83,6 +83,14 @@ extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) - - EXPORT_SYMBOL_GPL(bcm_dma_start); - -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ - /* Complete an ongoing DMA (assuming its results are to be ignored) - Does nothing if there is no DMA in progress. - This routine waits for the current AXI transfer to complete before -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index f2568d4..a4aac4c 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -64,11 +64,13 @@ struct bcm2708_dma_cb { - unsigned long next; - unsigned long pad[2]; - }; -+struct scatterlist; - - extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); - extern void bcm_dma_start(void __iomem *dma_chan_base, - dma_addr_t control_block); - extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); - extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); - - /* When listing features we can ask for when allocating DMA channels give diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index b3dd417..b3768b4 100644 +index 1094623..42e6c3b 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -224,6 +224,20 @@ config FB_TILEBLITTING @@ -73480,7 +70440,7 @@ index b3dd417..b3768b4 100644 +config FB_BCM2708 + tristate "BCM2708 framebuffer support" -+ depends on FB && ARM ++ depends on FB && ARM && BCM2708_MBOX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT @@ -73509,10 +70469,10 @@ index 1979aff..57181ad 100644 obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c new file mode 100644 -index 0000000..9179291 +index 0000000..f6ac7da --- /dev/null +++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -0,0 +1,818 @@ +@@ -0,0 +1,824 @@ +/* + * linux/drivers/video/bcm2708_fb.c + * @@ -73539,16 +70499,13 @@ index 0000000..9179291 +#include +#include +#include ++#include ++#include +#include +#include +#include +#include +#include -+ -+#include -+#include -+#include -+ +#include +#include +#include @@ -73840,8 +70797,8 @@ index 0000000..9179291 + /* the console may currently be locked */ + console_trylock(); + console_unlock(); -+ -+ BUG(); /* what can we do here */ ++ pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); ++ return -EIO; + } + } + print_debug @@ -74143,7 +71100,7 @@ index 0000000..9179291 + void *mem; + + mem = -+ dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, ++ dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, + GFP_KERNEL); + + if (NULL == mem) { @@ -74192,7 +71149,9 @@ index 0000000..9179291 + */ + + fb_set_var(&fb->fb, &fb->fb.var); -+ bcm2708_fb_set_par(&fb->fb); ++ ret = bcm2708_fb_set_par(&fb->fb); ++ if (ret) ++ return ret; + + print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", fbwidth, + fbheight, fbdepth, fbswap); @@ -74296,12 +71255,19 @@ index 0000000..9179291 + return 0; +} + ++static const struct of_device_id bcm2708_fb_of_match_table[] = { ++ { .compatible = "brcm,bcm2708-fb", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_fb_of_match_table); ++ +static struct platform_driver bcm2708_fb_driver = { + .probe = bcm2708_fb_probe, + .remove = bcm2708_fb_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_fb_of_match_table, + }, +}; + @@ -76822,10 +73788,10 @@ index 3c14e43..7626beb6a 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From 31a44367b5b2a156b2a45d34a1e6b65c55fe8c96 Mon Sep 17 00:00:00 2001 +From 5efe288a95d60bd10a162be79442d04b6f1d4079 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 007/216] dmaengine: Add support for BCM2708 +Subject: [PATCH 08/77] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -76874,116 +73840,277 @@ Add Device Tree support to the non ARCH_BCM2835 case. Use the same driver name regardless of architecture. Signed-off-by: Noralf Trønnes + +BCM270x_DT: add bcm2835-dma entry + +Add Device Tree entry for bcm2835-dma. +The entry doesn't contain any resources since they are handled +by the arch/arm/mach-bcm270x/dma.c driver. +In non-DT mode, don't add the device in the board file. + +Signed-off-by: Noralf Trønnes + +bcm2708-dmaengine: Add debug options + +BCM270x: Add memory and irq resources to dmaengine device and DT + +Prepare for merging of the legacy DMA API arch driver dma.c +with bcm2708-dmaengine by adding memory and irq resources both +to platform file device and Device Tree node. +Don't use BCM_DMAMAN_DRIVER_NAME so we don't have to include mach/dma.h + +Signed-off-by: Noralf Trønnes + +dmaengine: bcm2708: Merge with arch dma.c driver and disable dma.c + +Merge the legacy DMA API driver with bcm2708-dmaengine. +This is done so we can use bcm2708_fb on ARCH_BCM2835 (mailbox +driver is also needed). + +Changes to the dma.c code: +- Use BIT() macro. +- Cutdown some comments to one line. +- Add mutex to vc_dmaman and use this, since the dev lock is locked + during probing of the engine part. +- Add global g_dmaman variable since drvdata is used by the engine part. +- Restructure for readability: + vc_dmaman_chan_alloc() + vc_dmaman_chan_free() + bcm_dma_chan_free() +- Restructure bcm_dma_chan_alloc() to simplify error handling. +- Use device irq resources instead of hardcoded bcm_dma_irqs table. +- Remove dev_dmaman_register() and code it directly. +- Remove dev_dmaman_deregister() and code it directly. +- Simplify bcm_dmaman_probe() using devm_* functions. +- Get dmachans from DT if available. +- Keep 'dma.dmachans' module argument name for backwards compatibility. + +Make it available on ARCH_BCM2835 as well. + +Signed-off-by: Noralf Trønnes + +dmaengine: bcm2708: set residue_granularity field + +bcm2708-dmaengine supports residue reporting at burst level +but didn't report this via the residue_granularity field. + +Without this field set properly we get playback issues with I2S cards. --- - arch/arm/mach-bcm2708/bcm2708.c | 6 + - arch/arm/mach-bcm2708/dma.c | 2 + - arch/arm/mach-bcm2708/include/mach/dma.h | 6 +- - arch/arm/mach-bcm2709/bcm2709.c | 6 + - drivers/dma/Kconfig | 6 + - drivers/dma/Makefile | 1 + - drivers/dma/bcm2708-dmaengine.c | 989 +++++++++++++++++++++++++++++++ - 7 files changed, 1015 insertions(+), 1 deletion(-) + arch/arm/mach-bcm2708/bcm2708.c | 68 ++ + arch/arm/mach-bcm2709/bcm2709.c | 68 ++ + drivers/dma/Kconfig | 13 +- + drivers/dma/Makefile | 1 + + drivers/dma/bcm2708-dmaengine.c | 1298 +++++++++++++++++++++++++++++ + include/linux/platform_data/dma-bcm2708.h | 127 +++ + 6 files changed, 1574 insertions(+), 1 deletion(-) create mode 100644 drivers/dma/bcm2708-dmaengine.c + create mode 100644 include/linux/platform_data/dma-bcm2708.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index d9db081..5d8657b 100644 +index 4455f34..6b0b6c4 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -250,6 +250,11 @@ static struct platform_device bcm2708_dmaman_device = { - .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), +@@ -234,6 +234,73 @@ static struct amba_device *amba_devs[] __initdata = { + &uart0_device, }; ++static struct resource bcm2708_dmaengine_resources[] = { ++ { ++ .start = DMA_BASE, ++ .end = DMA_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_DMA0, ++ .end = IRQ_DMA0, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA1, ++ .end = IRQ_DMA1, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA2, ++ .end = IRQ_DMA2, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA3, ++ .end = IRQ_DMA3, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA4, ++ .end = IRQ_DMA4, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA5, ++ .end = IRQ_DMA5, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA6, ++ .end = IRQ_DMA6, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA7, ++ .end = IRQ_DMA7, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA8, ++ .end = IRQ_DMA8, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA9, ++ .end = IRQ_DMA9, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA10, ++ .end = IRQ_DMA10, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA11, ++ .end = IRQ_DMA11, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA12, ++ .end = IRQ_DMA12, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ +static struct platform_device bcm2708_dmaengine_device = { + .name = "bcm2708-dmaengine", + .id = -1, ++ .resource = bcm2708_dmaengine_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), +}; + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -508,6 +513,7 @@ void __init bcm2708_init(void) - clkdev_add(&lookups[i]); +@@ -463,6 +530,7 @@ void __init bcm2708_init(void) + bcm2708_init_clocks(); + bcm2708_dt_init(); - bcm_register_device(&bcm2708_dmaman_device); -+ bcm_register_device(&bcm2708_dmaengine_device); ++ bcm_register_device_dt(&bcm2708_dmaengine_device); bcm_register_device(&bcm2708_vcio_device); #ifdef CONFIG_BCM2708_GPIO - bcm_register_device(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -index 1da2413..a5e58d1 100644 ---- a/arch/arm/mach-bcm2708/dma.c -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -156,6 +156,8 @@ static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, - dmaman->chan_available = chans_available; - dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ - dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ - } - - static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index a4aac4c..d03e7b5 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -77,9 +77,13 @@ extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); - those with higher priority smaller ordinal numbers */ - #define BCM_DMA_FEATURE_FAST_ORD 0 - #define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_NORMAL_ORD 2 -+#define BCM_DMA_FEATURE_LITE_ORD 3 - #define BCM_DMA_FEATURE_FAST (1< +#include +#include ++#include +#include +#include +#include +#include -+ -+#ifndef CONFIG_ARCH_BCM2835 -+ -+/* dma manager */ -+#include -+ -+//#define DMA_COMPLETE DMA_SUCCESS -+ -+#endif -+ +#include +#include + +#include "virt-dma.h" + ++static unsigned dma_debug; ++ ++/* ++ * Legacy DMA API ++ */ ++ ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++ ++#define CACHE_LINE_MASK 31 ++#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ ++ ++/* valid only for channels 0 - 14, 15 has its own base address */ ++#define BCM2708_DMA_CHAN(n) ((n) << 8) /* base address */ ++#define BCM2708_DMA_CHANIO(dma_base, n) \ ++ ((void __iomem *)((char *)(dma_base) + BCM2708_DMA_CHAN(n))) ++ ++struct vc_dmaman { ++ void __iomem *dma_base; ++ u32 chan_available; /* bitmap of available channels */ ++ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ ++ struct mutex lock; ++}; ++ ++static struct device *dmaman_dev; /* we assume there's only one! */ ++static struct vc_dmaman *g_dmaman; /* DMA manager */ ++static int dmachans = -1; /* module parameter */ ++ ++/* DMA Auxiliary Functions */ ++ ++/* A DMA buffer on an arbitrary boundary may separate a cache line into a ++ section inside the DMA buffer and another section outside it. ++ Even if we flush DMA buffers from the cache there is always the chance that ++ during a DMA someone will access the part of a cache line that is outside ++ the DMA buffer - which will then bring in unwelcome data. ++ Without being able to dictate our own buffer pools we must insist that ++ DMA buffers consist of a whole number of cache lines. ++*/ ++extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) ++{ ++ int i; ++ ++ for (i = 0; i < sg_len; i++) { ++ if (sg_ptr[i].offset & CACHE_LINE_MASK || ++ sg_ptr[i].length & CACHE_LINE_MASK) ++ return 0; ++ } ++ ++ return 1; ++} ++EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); ++ ++extern void bcm_dma_start(void __iomem *dma_chan_base, ++ dma_addr_t control_block) ++{ ++ dsb(); /* ARM data synchronization (push) operation */ ++ ++ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); ++ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); ++} ++EXPORT_SYMBOL_GPL(bcm_dma_start); ++ ++extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ /* ugly busy wait only option for now */ ++ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) ++ cpu_relax(); ++} ++EXPORT_SYMBOL_GPL(bcm_dma_wait_idle); ++ ++extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_is_busy); ++ ++/* Complete an ongoing DMA (assuming its results are to be ignored) ++ Does nothing if there is no DMA in progress. ++ This routine waits for the current AXI transfer to complete before ++ terminating the current DMA. If the current transfer is hung on a DREQ used ++ by an uncooperative peripheral the AXI transfer may never complete. In this ++ case the routine times out and return a non-zero error code. ++ Use of this routine doesn't guarantee that the ongoing or aborted DMA ++ does not produce an interrupt. ++*/ ++extern int bcm_dma_abort(void __iomem *dma_chan_base) ++{ ++ unsigned long int cs; ++ int rc = 0; ++ ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (BCM2708_DMA_ACTIVE & cs) { ++ long int timeout = 10000; ++ ++ /* write 0 to the active bit - pause the DMA */ ++ writel(0, dma_chan_base + BCM2708_DMA_CS); ++ ++ /* wait for any current AXI transfer to complete */ ++ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { ++ /* we'll un-pause when we set of our next DMA */ ++ rc = -ETIMEDOUT; ++ ++ } else if (BCM2708_DMA_ACTIVE & cs) { ++ /* terminate the control block chain */ ++ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); ++ ++ /* abort the whole DMA */ ++ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, ++ dma_chan_base + BCM2708_DMA_CS); ++ } ++ } ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_abort); ++ ++ /* DMA Manager Device Methods */ ++ ++static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, ++ u32 chans_available) ++{ ++ dmaman->dma_base = dma_base; ++ dmaman->chan_available = chans_available; ++ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* 2 & 3 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* 0 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* 1 to 7 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* 8 to 14 */ ++} ++ ++static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, ++ unsigned preferred_feature_set) ++{ ++ u32 chans; ++ int chan = 0; ++ int feature; ++ ++ chans = dmaman->chan_available; ++ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) ++ /* select the subset of available channels with the desired ++ feature so long as some of the candidate channels have that ++ feature */ ++ if ((preferred_feature_set & (1 << feature)) && ++ (chans & dmaman->has_feature[feature])) ++ chans &= dmaman->has_feature[feature]; ++ ++ if (!chans) ++ return -ENOENT; ++ ++ /* return the ordinal of the first channel in the bitmap */ ++ while (chans != 0 && (chans & 1) == 0) { ++ chans >>= 1; ++ chan++; ++ } ++ /* claim the channel */ ++ dmaman->chan_available &= ~(1 << chan); ++ ++ return chan; ++} ++ ++static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) ++{ ++ if (chan < 0) ++ return -EINVAL; ++ ++ if ((1 << chan) & dmaman->chan_available) ++ return -EIDRM; ++ ++ dmaman->chan_available |= (1 << chan); ++ ++ return 0; ++} ++ ++/* DMA Manager Monitor */ ++ ++extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, int *out_dma_irq) ++{ ++ struct vc_dmaman *dmaman = g_dmaman; ++ struct platform_device *pdev = to_platform_device(dmaman_dev); ++ struct resource *r; ++ int chan; ++ ++ if (!dmaman_dev) ++ return -ENODEV; ++ ++ mutex_lock(&dmaman->lock); ++ chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); ++ if (chan < 0) ++ goto out; ++ ++ r = platform_get_resource(pdev, IORESOURCE_IRQ, (unsigned int)chan); ++ if (!r) { ++ dev_err(dmaman_dev, "failed to get irq for DMA channel %d\n", ++ chan); ++ vc_dmaman_chan_free(dmaman, chan); ++ chan = -ENOENT; ++ goto out; ++ } ++ ++ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, chan); ++ *out_dma_irq = r->start; ++ dev_dbg(dmaman_dev, ++ "Legacy API allocated channel=%d, base=%p, irq=%i\n", ++ chan, *out_dma_base, *out_dma_irq); ++ ++out: ++ mutex_unlock(&dmaman->lock); ++ ++ return chan; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); ++ ++extern int bcm_dma_chan_free(int channel) ++{ ++ struct vc_dmaman *dmaman = g_dmaman; ++ int rc; ++ ++ if (!dmaman_dev) ++ return -ENODEV; ++ ++ mutex_lock(&dmaman->lock); ++ rc = vc_dmaman_chan_free(dmaman, channel); ++ mutex_unlock(&dmaman->lock); ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_free); ++ ++static int bcm_dmaman_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct vc_dmaman *dmaman; ++ struct resource *r; ++ void __iomem *dma_base; ++ uint32_t val; ++ ++ if (!of_property_read_u32(dev->of_node, ++ "brcm,dma-channel-mask", &val)) ++ dmachans = val; ++ else if (dmachans == -1) ++ dmachans = DEFAULT_DMACHAN_BITMAP; ++ ++ dmaman = devm_kzalloc(dev, sizeof(*dmaman), GFP_KERNEL); ++ if (!dmaman) ++ return -ENOMEM; ++ ++ mutex_init(&dmaman->lock); ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ dma_base = devm_ioremap_resource(dev, r); ++ if (IS_ERR(dma_base)) ++ return PTR_ERR(dma_base); ++ ++ vc_dmaman_init(dmaman, dma_base, dmachans); ++ g_dmaman = dmaman; ++ dmaman_dev = dev; ++ ++ dev_info(dev, "DMA legacy API manager at %p, dmachans=0x%x\n", ++ dma_base, dmachans); ++ ++ return 0; ++} ++ ++static int bcm_dmaman_remove(struct platform_device *pdev) ++{ ++ dmaman_dev = NULL; ++ ++ return 0; ++} ++ ++#else /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++static int bcm_dmaman_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++#endif /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++/* ++ * DMA engine ++ */ + +struct bcm2835_dmadev { + struct dma_device ddev; @@ -77602,7 +75008,10 @@ index 0000000..6150b8f + } + + /* Common part */ -+ control_block->info |= BCM2835_DMA_WAITS(SDHCI_BCM_DMA_WAITS); ++ u32 waits = SDHCI_BCM_DMA_WAITS; ++ if ((dma_debug >> 0) & 0x1f) ++ waits = (dma_debug >> 0) & 0x1f; ++ control_block->info |= BCM2835_DMA_WAITS(waits); + control_block->info |= BCM2835_DMA_WAIT_RESP; + + /* Enable */ @@ -77707,7 +75116,7 @@ index 0000000..6150b8f + return 0; +} + -+#ifdef CONFIG_ARCH_BCM2835 ++#ifndef CONFIG_DMA_BCM2708_LEGACY +static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) +{ + struct bcm2835_chan *c; @@ -77785,7 +75194,7 @@ index 0000000..6150b8f +static int bcm2835_dma_probe(struct platform_device *pdev) +{ + struct bcm2835_dmadev *od; -+#ifdef CONFIG_ARCH_BCM2835 ++#ifndef CONFIG_DMA_BCM2708_LEGACY + struct resource *res; + void __iomem *base; + uint32_t chans_available; @@ -77798,10 +75207,7 @@ index 0000000..6150b8f + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + -+ /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */ -+ /* hence the difference between probing */ -+ -+#ifndef CONFIG_ARCH_BCM2835 ++#ifdef CONFIG_DMA_BCM2708_LEGACY + + rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) @@ -77813,6 +75219,10 @@ index 0000000..6150b8f + if (!od) + return -ENOMEM; + ++ rc = bcm_dmaman_probe(pdev); ++ if (rc) ++ return rc; ++ + pdev->dev.dma_parms = &od->dma_parms; + dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); + @@ -77831,6 +75241,7 @@ index 0000000..6150b8f + od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); ++ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + od->ddev.dev = &pdev->dev; + INIT_LIST_HEAD(&od->ddev.channels); + spin_lock_init(&od->lock); @@ -77899,6 +75310,7 @@ index 0000000..6150b8f + od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); ++ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + od->ddev.dev = &pdev->dev; + INIT_LIST_HEAD(&od->ddev.channels); + spin_lock_init(&od->lock); @@ -77954,6 +75366,7 @@ index 0000000..6150b8f + } + + dev_info(&pdev->dev, "Load BCM2835 DMA engine driver\n"); ++ dev_info(&pdev->dev, "dma_debug:%x\n", dma_debug); + + return 0; + @@ -77968,6 +75381,7 @@ index 0000000..6150b8f + + dma_async_device_unregister(&od->ddev); + bcm2835_dma_free(od); ++ bcm_dmaman_remove(pdev); + + return 0; +} @@ -77982,18 +75396,173 @@ index 0000000..6150b8f + }, +}; + -+module_platform_driver(bcm2835_dma_driver); ++static int bcm2835_init(void) ++{ ++ return platform_driver_register(&bcm2835_dma_driver); ++} + ++static void bcm2835_exit(void) ++{ ++ platform_driver_unregister(&bcm2835_dma_driver); ++} ++ ++/* ++ * Load after serial driver (arch_initcall) so we see the messages if it fails, ++ * but before drivers (module_init) that need a DMA channel. ++ */ ++subsys_initcall(bcm2835_init); ++module_exit(bcm2835_exit); ++ ++module_param(dma_debug, uint, 0644); ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++/* Keep backward compatibility: dma.dmachans= */ ++#undef MODULE_PARAM_PREFIX ++#define MODULE_PARAM_PREFIX "dma." ++module_param(dmachans, int, 0644); ++#endif +MODULE_ALIAS("platform:bcm2835-dma"); +MODULE_DESCRIPTION("BCM2835 DMA engine driver"); +MODULE_AUTHOR("Florian Meier "); +MODULE_AUTHOR("Gellert Weisz "); +MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/platform_data/dma-bcm2708.h b/include/linux/platform_data/dma-bcm2708.h +new file mode 100644 +index 0000000..2310e34 +--- /dev/null ++++ b/include/linux/platform_data/dma-bcm2708.h +@@ -0,0 +1,127 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef _PLAT_BCM2708_DMA_H ++#define _PLAT_BCM2708_DMA_H ++ ++/* DMA CS Control and Status bits */ ++#define BCM2708_DMA_ACTIVE BIT(0) ++#define BCM2708_DMA_INT BIT(2) ++#define BCM2708_DMA_ISPAUSED BIT(4) /* Pause requested or not active */ ++#define BCM2708_DMA_ISHELD BIT(5) /* Is held by DREQ flow control */ ++#define BCM2708_DMA_ERR BIT(8) ++#define BCM2708_DMA_ABORT BIT(30) /* stop current CB, go to next, WO */ ++#define BCM2708_DMA_RESET BIT(31) /* WO, self clearing */ ++ ++/* DMA control block "info" field bits */ ++#define BCM2708_DMA_INT_EN BIT(0) ++#define BCM2708_DMA_TDMODE BIT(1) ++#define BCM2708_DMA_WAIT_RESP BIT(3) ++#define BCM2708_DMA_D_INC BIT(4) ++#define BCM2708_DMA_D_WIDTH BIT(5) ++#define BCM2708_DMA_D_DREQ BIT(6) ++#define BCM2708_DMA_S_INC BIT(8) ++#define BCM2708_DMA_S_WIDTH BIT(9) ++#define BCM2708_DMA_S_DREQ BIT(10) ++ ++#define BCM2708_DMA_BURST(x) (((x) & 0xf) << 12) ++#define BCM2708_DMA_PER_MAP(x) ((x) << 16) ++#define BCM2708_DMA_WAITS(x) (((x) & 0x1f) << 21) ++ ++#define BCM2708_DMA_DREQ_EMMC 11 ++#define BCM2708_DMA_DREQ_SDHOST 13 ++ ++#define BCM2708_DMA_CS 0x00 /* Control and Status */ ++#define BCM2708_DMA_ADDR 0x04 ++/* the current control block appears in the following registers - read only */ ++#define BCM2708_DMA_INFO 0x08 ++#define BCM2708_DMA_SOURCE_AD 0x0c ++#define BCM2708_DMA_DEST_AD 0x10 ++#define BCM2708_DMA_NEXTCB 0x1C ++#define BCM2708_DMA_DEBUG 0x20 ++ ++#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4) + BCM2708_DMA_CS) ++#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4) + BCM2708_DMA_ADDR) ++ ++#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) ++ ++/* When listing features we can ask for when allocating DMA channels give ++ those with higher priority smaller ordinal numbers */ ++#define BCM_DMA_FEATURE_FAST_ORD 0 ++#define BCM_DMA_FEATURE_BULK_ORD 1 ++#define BCM_DMA_FEATURE_NORMAL_ORD 2 ++#define BCM_DMA_FEATURE_LITE_ORD 3 ++#define BCM_DMA_FEATURE_FAST BIT(BCM_DMA_FEATURE_FAST_ORD) ++#define BCM_DMA_FEATURE_BULK BIT(BCM_DMA_FEATURE_BULK_ORD) ++#define BCM_DMA_FEATURE_NORMAL BIT(BCM_DMA_FEATURE_NORMAL_ORD) ++#define BCM_DMA_FEATURE_LITE BIT(BCM_DMA_FEATURE_LITE_ORD) ++#define BCM_DMA_FEATURE_COUNT 4 ++ ++struct bcm2708_dma_cb { ++ unsigned long info; ++ unsigned long src; ++ unsigned long dst; ++ unsigned long length; ++ unsigned long stride; ++ unsigned long next; ++ unsigned long pad[2]; ++}; ++ ++struct scatterlist; ++ ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++ ++int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); ++void bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block); ++void bcm_dma_wait_idle(void __iomem *dma_chan_base); ++bool bcm_dma_is_busy(void __iomem *dma_chan_base); ++int bcm_dma_abort(void __iomem *dma_chan_base); ++ ++/* return channel no or -ve error */ ++int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, int *out_dma_irq); ++int bcm_dma_chan_free(int channel); ++ ++#else /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++static inline int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, ++ int sg_len) ++{ ++ return 0; ++} ++ ++static inline void bcm_dma_start(void __iomem *dma_chan_base, ++ dma_addr_t control_block) { } ++ ++static inline void bcm_dma_wait_idle(void __iomem *dma_chan_base) { } ++ ++static inline bool bcm_dma_is_busy(void __iomem *dma_chan_base) ++{ ++ return false; ++} ++ ++static inline int bcm_dma_abort(void __iomem *dma_chan_base) ++{ ++ return -EINVAL; ++} ++ ++static inline int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, ++ int *out_dma_irq) ++{ ++ return -EINVAL; ++} ++ ++static inline int bcm_dma_chan_free(int channel) ++{ ++ return -EINVAL; ++} ++ ++#endif /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++#endif /* _PLAT_BCM2708_DMA_H */ -From 7ec18e818133424bf20d58993fa6822dd241e096 Mon Sep 17 00:00:00 2001 +From be30ad8849aa9fd6ffbe6f8198a5af4bb62c465f Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 008/216] MMC: added alternative MMC driver +Subject: [PATCH 09/77] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -78019,23 +75588,61 @@ Probe error handling is broken in several places. Simplify error handling by using device managed functions. Replace pr_{err,info} with dev_{err,info}. +Signed-off-by: Noralf Trønnes + +bcm2835-mmc: Add locks when accessing sdhost registers + +bcm2835-mmc: Add range of debug options for slowing things down + +bcm2835-mmc: Add option to disable some delays + +bcm2835-mmc: Add option to disable MMC_QUIRK_BLK_NO_CMD23 + +bcm2835-mmc: Default to disabling MMC_QUIRK_BLK_NO_CMD23 + +bcm2835-mmc: Adding overclocking option + +Allow a different clock speed to be substitued for a requested 50MHz. +This option is exposed using the "overclock_50" DT parameter. +Note that the mmc interface is restricted to EVEN integer divisions of +250MHz, and the highest sensible option is 63 (250/4 = 62.5), the +next being 125 (250/2) which is much too high. + +Use at your own risk. + +bcm2835-mmc: Round up the overclock, so 62 works for 62.5Mhz + +Also only warn once for each overclock setting. + +mmc: bcm2835-mmc: Make available on ARCH_BCM2835 + +Make the bcm2835-mmc driver available for use on ARCH_BCM2835. + +Signed-off-by: Noralf Trønnes + +BCM270x_DT: add bcm2835-mmc entry + +Add Device Tree entry for bcm2835-mmc. +In non-DT mode, don't add the device in the board file. + Signed-off-by: Noralf Trønnes --- arch/arm/mach-bcm2708/bcm2708.c | 31 + - drivers/mmc/core/quirks.c | 4 + + arch/arm/mach-bcm2709/bcm2709.c | 35 +- + drivers/mmc/core/quirks.c | 6 + drivers/mmc/host/Kconfig | 29 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1506 +++++++++++++++++++++++++++++++++++++++ - 5 files changed, 1571 insertions(+) + drivers/mmc/host/bcm2835-mmc.c | 1558 +++++++++++++++++++++++++++++++++++++++ + 6 files changed, 1658 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5d8657b..d1308ed 100644 +index 6b0b6c4..5b10802 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -399,6 +399,34 @@ static struct platform_device bcm2708_systemtimer_device = { - }, +@@ -401,6 +401,34 @@ static struct platform_device bcm2708_gpio_device = { }; + #endif +#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ +static struct resource bcm2835_emmc_resources[] = { @@ -78065,35 +75672,97 @@ index 5d8657b..d1308ed 100644 +}; +#endif /* CONFIG_MMC_BCM2835 */ + - static struct resource bcm2708_powerman_resources[] = { - [0] = { - .start = PM_BASE, -@@ -524,6 +552,9 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -538,6 +566,9 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); +#ifdef CONFIG_MMC_BCM2835 -+ bcm_register_device(&bcm2835_emmc_device); ++ bcm_register_device_dt(&bcm2835_emmc_device); +#endif bcm2708_init_led(); + bcm2708_init_uart1(); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 86ebfbe..54c5444 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -421,6 +421,34 @@ static struct platform_device bcm2708_gpio_device = { + }; + #endif + ++#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ ++static struct resource bcm2835_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, ++ }, ++ [1] = { ++ .start = IRQ_ARASANSDIO, ++ .end = IRQ_ARASANSDIO, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 bcm2835_emmc_dmamask = 0xffffffffUL; ++ ++struct platform_device bcm2835_emmc_device = { ++ .name = "mmc-bcm2835", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2835_emmc_resources), ++ .resource = bcm2835_emmc_resources, ++ .dev = { ++ .dma_mask = &bcm2835_emmc_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++#endif /* CONFIG_MMC_BCM2835 */ ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -558,8 +586,11 @@ void __init bcm2709_init(void) + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); + +- bcm2708_init_led(); +- bcm2708_init_uart1(); ++#ifdef CONFIG_MMC_BCM2835 ++ bcm_register_device_dt(&bcm2835_emmc_device); ++#endif ++ bcm2709_init_led(); ++ bcm2709_init_uart1(); + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index dd1d1e0..f472082 100644 +index dd1d1e0..bc3bbad 100644 --- a/drivers/mmc/core/quirks.c +++ b/drivers/mmc/core/quirks.c -@@ -95,5 +95,9 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) +@@ -71,6 +71,7 @@ static const struct mmc_fixup mmc_fixup_methods[] = { + + void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) + { ++ extern unsigned mmc_debug; + const struct mmc_fixup *f; + u64 rev = cid_rev_card(card); + +@@ -95,5 +96,10 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) f->vendor_fixup(card, f->data); } } + /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. + * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). + */ ++ if (mmc_debug & (1<<13)) + card->quirks |= MMC_QUIRK_BLK_NO_CMD23; } EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 61ac63a..7c093a6 100644 +index b1f837e..0ef7417 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -4,6 +4,35 @@ @@ -78102,7 +75771,7 @@ index 61ac63a..7c093a6 100644 +config MMC_BCM2835 + tristate "MMC support on BCM2835" -+ depends on (MACH_BCM2708 || MACH_BCM2709) ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 + help + This selects the MMC Interface on BCM2835. + @@ -78133,7 +75802,7 @@ index 61ac63a..7c093a6 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 6a7cfe0..9d41de9 100644 +index e3ab5b9..f1ee1f7 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -78146,10 +75815,10 @@ index 6a7cfe0..9d41de9 100644 obj-$(CONFIG_MMC_OMAP) += omap.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..eef0d351 +index 0000000..b7c4883 --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1506 @@ +@@ -0,0 +1,1558 @@ +/* + * BCM2835 MMC host driver. + * @@ -78223,6 +75892,9 @@ index 0000000..eef0d351 +#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) + + ++unsigned mmc_debug; ++unsigned mmc_debug2; ++ +struct bcm2835_host { + spinlock_t lock; + @@ -78280,22 +75952,38 @@ index 0000000..eef0d351 +#define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ +#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ +#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ ++ ++ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ ++ u32 max_overclock; /* Highest reported */ +}; + + -+static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) ++static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg, int from) +{ ++ unsigned delay; ++ lockdep_assert_held_once(&host->lock); + writel(val, host->ioaddr + reg); + udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); ++ ++ delay = ((mmc_debug >> 16) & 0xf) << ((mmc_debug >> 20) & 0xf); ++ if (delay && !((1<lock); + writel(val, host->ioaddr + reg); ++ ++ delay = ((mmc_debug >> 24) & 0xf) << ((mmc_debug >> 28) & 0xf); ++ if (delay) ++ udelay(delay); +} + +static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) +{ ++ lockdep_assert_held_once(&host->lock); + return readl(host->ioaddr + reg); +} + @@ -78311,7 +75999,7 @@ index 0000000..eef0d351 + if (reg == SDHCI_TRANSFER_MODE) + host->shadow = newval; + else -+ bcm2835_mmc_writel(host, newval, reg & ~3); ++ bcm2835_mmc_writel(host, newval, reg & ~3, 0); + +} + @@ -78323,7 +76011,7 @@ index 0000000..eef0d351 + u32 mask = 0xff << byte_shift; + u32 newval = (oldval & ~mask) | (val << byte_shift); + -+ bcm2835_mmc_writel(host, newval, reg & ~3); ++ bcm2835_mmc_writel(host, newval, reg & ~3, 1); +} + + @@ -78355,7 +76043,7 @@ index 0000000..eef0d351 + ier &= ~clear; + /* change which requests generate IRQs - makes no difference to + the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ -+ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE, 2); +} + + @@ -78407,7 +76095,9 @@ index 0000000..eef0d351 +static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) +{ + unsigned long timeout; ++ unsigned long flags; + ++ spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + if (mask & SDHCI_RESET_ALL) @@ -78425,19 +76115,23 @@ index 0000000..eef0d351 + return; + } + timeout--; ++ spin_unlock_irqrestore(&host->lock, flags); + mdelay(1); ++ spin_lock_irqsave(&host->lock, flags); + } + + if (100-timeout > 10 && 100-timeout > host->max_delay) { + host->max_delay = 100-timeout; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } ++ spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + +static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) +{ ++ unsigned long flags; + if (soft) + bcm2835_mmc_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); + else @@ -78449,8 +76143,10 @@ index 0000000..eef0d351 + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | + SDHCI_INT_RESPONSE; + -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ spin_lock_irqsave(&host->lock, flags); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 3); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 3); ++ spin_unlock_irqrestore(&host->lock, flags); + + if (soft) { + /* force clock reconfiguration */ @@ -78649,11 +76345,14 @@ index 0000000..eef0d351 + dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); + } + if (desc) { ++ unsigned long flags; ++ spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | + SDHCI_INT_SPACE_AVAIL); + host->tx_desc = desc; + desc->callback = bcm2835_mmc_dma_complete; + desc->callback_param = host; ++ spin_unlock_irqrestore(&host->lock, flags); + dmaengine_submit(desc); + dma_async_issue_pending(dma_chan); + } @@ -78672,8 +76371,8 @@ index 0000000..eef0d351 + else + host->ier = (host->ier & ~dma_irqs) | pio_irqs; + -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 4); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 4); +} + + @@ -78755,7 +76454,7 @@ index 0000000..eef0d351 + mode |= SDHCI_TRNS_AUTO_CMD12; + else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { + mode |= SDHCI_TRNS_AUTO_CMD23; -+ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); ++ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2, 5); + } + } + @@ -78818,7 +76517,7 @@ index 0000000..eef0d351 + + bcm2835_mmc_prepare_data(host, cmd); + -+ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT); ++ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT, 6); + + bcm2835_mmc_set_transfer_mode(host, cmd); + @@ -78975,8 +76674,8 @@ index 0000000..eef0d351 + else + host->ier &= ~SDHCI_INT_CARD_INT; + -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 7); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 7); + mmiowb(); + } +} @@ -79123,7 +76822,7 @@ index 0000000..eef0d351 + /* Clear selected interrupts. */ + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | + SDHCI_INT_BUS_POWER); -+ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS); ++ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS, 8); + + + if (intmask & SDHCI_INT_CMD_MASK) @@ -79153,7 +76852,7 @@ index 0000000..eef0d351 + + if (intmask) { + unexpected |= intmask; -+ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS); ++ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS, 9); + } + + if (result == IRQ_NONE) @@ -79211,7 +76910,10 @@ index 0000000..eef0d351 + int real_div = div, clk_mul = 1; + u16 clk = 0; + unsigned long timeout; ++ unsigned int input_clock = clock; + ++ if (host->overclock_50 && (clock == 50000000)) ++ clock = host->overclock_50 * 1000000 + 999999; + + host->mmc->actual_clock = 0; + @@ -79235,7 +76937,14 @@ index 0000000..eef0d351 + div >>= 1; + + if (real_div) -+ host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; ++ clock = (host->max_clk * clk_mul) / real_div; ++ host->mmc->actual_clock = clock; ++ ++ if ((clock > input_clock) && (clock > host->max_overclock)) { ++ pr_warn("%s: Overclocking to %dHz\n", ++ mmc_hostname(host->mmc), clock); ++ host->max_overclock = clock; ++ } + + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; + clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) @@ -79302,6 +77011,9 @@ index 0000000..eef0d351 + u8 ctrl; + u16 clk, ctrl_2; + ++ pr_debug("bcm2835_mmc_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", ++ ios->clock, ios->power_mode, ios->bus_width, ++ ios->timing, ios->signal_voltage, ios->drv_type); + + spin_lock_irqsave(&host->lock, flags); + @@ -79395,8 +77107,10 @@ index 0000000..eef0d351 + (mrq->data && (mrq->data->error || + (mrq->data->stop && mrq->data->stop->error))))) { + ++ spin_unlock_irqrestore(&host->lock, flags); + bcm2835_mmc_reset(host, SDHCI_RESET_CMD); + bcm2835_mmc_reset(host, SDHCI_RESET_DATA); ++ spin_lock_irqsave(&host->lock, flags); + } + + host->mrq = NULL; @@ -79411,7 +77125,7 @@ index 0000000..eef0d351 + + + -+int bcm2835_mmc_add_host(struct bcm2835_host *host) ++static int bcm2835_mmc_add_host(struct bcm2835_host *host) +{ + struct mmc_host *mmc = host->mmc; + struct device *dev = mmc->parent; @@ -79439,8 +77153,7 @@ index 0000000..eef0d351 + + host->flags = SDHCI_AUTO_CMD23; + -+ spin_lock_init(&host->lock); -+ ++ dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); +#ifdef FORCE_PIO + dev_info(dev, "Forcing PIO mode\n"); + host->have_dma = false; @@ -79568,10 +77281,16 @@ index 0000000..eef0d351 + goto err; + } + -+ if (node) ++ if (node) { + mmc_of_parse(mmc); -+ else ++ ++ /* Read any custom properties */ ++ of_property_read_u32(node, ++ "brcm,overclock-50", ++ &host->overclock_50); ++ } else { + mmc->caps |= MMC_CAP_4_BIT_DATA; ++ } + + ret = bcm2835_mmc_add_host(host); + if (ret) @@ -79652,15 +77371,1790 @@ index 0000000..eef0d351 +}; +module_platform_driver(bcm2835_mmc_driver); + ++module_param(mmc_debug, uint, 0644); ++module_param(mmc_debug2, uint, 0644); +MODULE_ALIAS("platform:mmc-bcm2835"); +MODULE_DESCRIPTION("BCM2835 SDHCI driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From 97f9d94720b108ba3e793621d4a500cc593fc775 Mon Sep 17 00:00:00 2001 +From 81cff325dce6ba8765e23e542a219d3c9103a70b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 25 Mar 2015 17:49:47 +0000 +Subject: [PATCH 10/77] Adding bcm2835-sdhost driver, and an overlay to enable + it + +BCM2835 has two SD card interfaces. This driver uses the other one. + +bcm2835-sdhost: Error handling fix, and code clarification + +bcm2835-sdhost: Adding overclocking option + +Allow a different clock speed to be substitued for a requested 50MHz. +This option is exposed using the "overclock_50" DT parameter. +Note that the sdhost interface is restricted to integer divisions of +core_freq, and the highest sensible option for a core_freq of 250MHz +is 84 (250/3 = 83.3MHz), the next being 125 (250/2) which is much too +high. + +Use at your own risk. + +bcm2835-sdhost: Round up the overclock, so 62 works for 62.5Mhz + +Also only warn once for each overclock setting. +--- + drivers/mmc/host/Kconfig | 10 + + drivers/mmc/host/Makefile | 1 + + drivers/mmc/host/bcm2835-sdhost.c | 1702 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 1713 insertions(+) + create mode 100644 drivers/mmc/host/bcm2835-sdhost.c + +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 0ef7417..1af139a 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER + + If unsure, say 2 here. + ++config MMC_BCM2835_SDHOST ++ tristate "Support for the SDHost controller on BCM2708/9" ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 ++ help ++ This selects the SDHost controller on BCM2835/6. ++ ++ If you have a controller with this interface, say Y or M here. ++ ++ If unsure, say N. ++ + config MMC_ARMMMCI + tristate "ARM AMBA Multimedia Card Interface support" + depends on ARM_AMBA +diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile +index f1ee1f7..8c656a5 100644 +--- a/drivers/mmc/host/Makefile ++++ b/drivers/mmc/host/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o + obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o + obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o + obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o ++obj-$(CONFIG_MMC_BCM2835_SDHOST) += bcm2835-sdhost.o + obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o + obj-$(CONFIG_MMC_WBSD) += wbsd.o + obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c +new file mode 100644 +index 0000000..eef8a24 +--- /dev/null ++++ b/drivers/mmc/host/bcm2835-sdhost.c +@@ -0,0 +1,1702 @@ ++/* ++ * BCM2835 SD host driver. ++ * ++ * Author: Phil Elwell ++ * Copyright 2015 ++ * ++ * Based on ++ * mmc-bcm2835.c by Gellert Weisz ++ * which is, in turn, based on ++ * sdhci-bcm2708.c by Broadcom ++ * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko ++ * sdhci.c and sdhci-pci.c by Pierre Ossman ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#define SAFE_READ_THRESHOLD 4 ++#define SAFE_WRITE_THRESHOLD 4 ++#define ALLOW_DMA 1 ++#define ALLOW_CMD23 0 ++#define ALLOW_FAST 1 ++#define USE_BLOCK_IRQ 1 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "sdhost-bcm2835" ++ ++#define SDCMD 0x00 /* Command to SD card - 16 R/W */ ++#define SDARG 0x04 /* Argument to SD card - 32 R/W */ ++#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */ ++#define SDCDIV 0x0c /* Start value for clock divider - 11 R/W */ ++#define SDRSP0 0x10 /* SD card response (31:0) - 32 R */ ++#define SDRSP1 0x14 /* SD card response (63:32) - 32 R */ ++#define SDRSP2 0x18 /* SD card response (95:64) - 32 R */ ++#define SDRSP3 0x1c /* SD card response (127:96) - 32 R */ ++#define SDHSTS 0x20 /* SD host status - 11 R */ ++#define SDVDD 0x30 /* SD card power control - 1 R/W */ ++#define SDEDM 0x34 /* Emergency Debug Mode - 13 R/W */ ++#define SDHCFG 0x38 /* Host configuration - 2 R/W */ ++#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */ ++#define SDDATA 0x40 /* Data to/from SD card - 32 R/W */ ++#define SDHBLC 0x50 /* Host block count (SDIO/SDHC) - 9 R/W */ ++ ++#define SDCMD_NEW_FLAG 0x8000 ++#define SDCMD_FAIL_FLAG 0x4000 ++#define SDCMD_BUSYWAIT 0x800 ++#define SDCMD_NO_RESPONSE 0x400 ++#define SDCMD_LONG_RESPONSE 0x200 ++#define SDCMD_WRITE_CMD 0x80 ++#define SDCMD_READ_CMD 0x40 ++#define SDCMD_CMD_MASK 0x3f ++ ++#define SDCDIV_MAX_CDIV 0x7ff ++ ++#define SDHSTS_BUSY_IRPT 0x400 ++#define SDHSTS_BLOCK_IRPT 0x200 ++#define SDHSTS_SDIO_IRPT 0x100 ++#define SDHSTS_REW_TIME_OUT 0x80 ++#define SDHSTS_CMD_TIME_OUT 0x40 ++#define SDHSTS_CRC16_ERROR 0x20 ++#define SDHSTS_CRC7_ERROR 0x10 ++#define SDHSTS_FIFO_ERROR 0x08 ++/* Reserved */ ++/* Reserved */ ++#define SDHSTS_DATA_FLAG 0x01 ++ ++#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) ++#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) ++/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ ++ ++#define SDHCFG_BUSY_IRPT_EN (1<<10) ++#define SDHCFG_BLOCK_IRPT_EN (1<<8) ++#define SDHCFG_SDIO_IRPT_EN (1<<5) ++#define SDHCFG_DATA_IRPT_EN (1<<4) ++#define SDHCFG_SLOW_CARD (1<<3) ++#define SDHCFG_WIDE_EXT_BUS (1<<2) ++#define SDHCFG_WIDE_INT_BUS (1<<1) ++#define SDHCFG_REL_CMD_LINE (1<<0) ++ ++#define SDEDM_FORCE_DATA_MODE (1<<19) ++#define SDEDM_CLOCK_PULSE (1<<20) ++#define SDEDM_BYPASS (1<<21) ++ ++#define SDEDM_WRITE_THRESHOLD_SHIFT 9 ++#define SDEDM_READ_THRESHOLD_SHIFT 14 ++#define SDEDM_THRESHOLD_MASK 0x1f ++ ++/* the inclusive limit in bytes under which PIO will be used instead of DMA */ ++#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER ++#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER ++#else ++#define PIO_DMA_BARRIER 0 ++#endif ++ ++#define MIN_FREQ 400000 ++#define TIMEOUT_VAL 0xE ++#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) ++ ++#ifndef BCM2708_PERI_BASE ++ #define BCM2708_PERI_BASE 0x20000000 ++#endif ++ ++/* FIXME: Needs IOMMU support */ ++#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) ++ ++ ++struct bcm2835_host { ++ spinlock_t lock; ++ ++ void __iomem *ioaddr; ++ u32 phys_addr; ++ ++ struct mmc_host *mmc; ++ ++ u32 timeout; ++ ++ int clock; /* Current clock speed */ ++ ++ bool slow_card; /* Force 11-bit divisor */ ++ ++ unsigned int max_clk; /* Max possible freq */ ++ unsigned int timeout_clk; /* Timeout freq (KHz) */ ++ ++ struct tasklet_struct finish_tasklet; /* Tasklet structures */ ++ ++ struct timer_list timer; /* Timer for timeouts */ ++ ++ struct sg_mapping_iter sg_miter; /* SG state for PIO */ ++ unsigned int blocks; /* remaining PIO blocks */ ++ ++ int irq; /* Device IRQ */ ++ ++ ++ /* cached registers */ ++ u32 hcfg; ++ u32 cdiv; ++ ++ struct mmc_request *mrq; /* Current request */ ++ struct mmc_command *cmd; /* Current command */ ++ struct mmc_data *data; /* Current data request */ ++ unsigned int data_complete:1; /* Data finished before cmd */ ++ ++ unsigned int flush_fifo:1; /* Drain the fifo when finishing */ ++ ++ unsigned int use_busy:1; /* Wait for busy interrupt */ ++ ++ u32 thread_isr; ++ ++ /*DMA part*/ ++ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ ++ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ ++ ++ bool allow_dma; ++ bool have_dma; ++ bool use_dma; ++ /*end of DMA part*/ ++ ++ int max_delay; /* maximum length of time spent waiting */ ++ struct timeval stop_time; /* when the last stop was issued */ ++ u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ ++ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ ++ u32 max_overclock; /* Highest reported */ ++}; ++ ++ ++static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) ++{ ++ writel(val, host->ioaddr + reg); ++} ++ ++static inline u32 bcm2835_sdhost_read(struct bcm2835_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg) ++{ ++ return readl_relaxed(host->ioaddr + reg); ++} ++ ++static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) ++{ ++ pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", ++ mmc_hostname(host->mmc)); ++ ++ pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", ++ bcm2835_sdhost_read(host, SDCMD)); ++ pr_info(DRIVER_NAME ": SDARG 0x%08x\n", ++ bcm2835_sdhost_read(host, SDARG)); ++ pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", ++ bcm2835_sdhost_read(host, SDTOUT)); ++ pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", ++ bcm2835_sdhost_read(host, SDCDIV)); ++ pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP0)); ++ pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP1)); ++ pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP2)); ++ pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP3)); ++ pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHSTS)); ++ pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", ++ bcm2835_sdhost_read(host, SDVDD)); ++ pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", ++ bcm2835_sdhost_read(host, SDEDM)); ++ pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHCFG)); ++ pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHBCT)); ++ pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHBLC)); ++ ++ pr_debug(DRIVER_NAME ": ===========================================\n"); ++} ++ ++ ++static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) ++{ ++ bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); ++} ++ ++ ++static void bcm2835_sdhost_reset(struct bcm2835_host *host) ++{ ++ u32 temp; ++ ++ pr_debug("bcm2835_sdhost_reset\n"); ++ ++ bcm2835_sdhost_set_power(host, false); ++ ++ bcm2835_sdhost_write(host, 0, SDCMD); ++ bcm2835_sdhost_write(host, 0, SDARG); ++ bcm2835_sdhost_write(host, 0xf00000, SDTOUT); ++ bcm2835_sdhost_write(host, 0, SDCDIV); ++ bcm2835_sdhost_write(host, 0x7f8, SDHSTS); /* Write 1s to clear */ ++ bcm2835_sdhost_write(host, 0, SDHCFG); ++ bcm2835_sdhost_write(host, 0, SDHBCT); ++ bcm2835_sdhost_write(host, 0, SDHBLC); ++ ++ /* Limit fifo usage due to silicon bug */ ++ temp = bcm2835_sdhost_read(host, SDEDM); ++ temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); ++ mmiowb(); ++} ++ ++static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); ++ ++static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) ++{ ++ pr_debug("bcm2835_sdhost_init(%d)\n", soft); ++ ++ /* Set interrupt enables */ ++ host->hcfg = SDHCFG_BUSY_IRPT_EN; ++ ++ bcm2835_sdhost_reset(host); ++ ++ if (soft) { ++ /* force clock reconfiguration */ ++ host->clock = 0; ++ bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); ++ } ++} ++ ++static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) ++{ ++ bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); ++ ++ if (!write_complete) { ++ /* Request an IRQ for the last block */ ++ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { ++ /* The write has now completed. Disable the interrupt ++ and clear the status flag */ ++ host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); ++ write_complete = true; ++ } ++ } ++ ++ return write_complete; ++} ++ ++static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) ++{ ++ int timediff; ++#ifdef DEBUG ++ static struct timeval start_time; ++ static int max_stall_time = 0; ++ static int total_stall_time = 0; ++ struct timeval before, after; ++ ++ do_gettimeofday(&before); ++ if (max_stall_time == 0) ++ start_time = before; ++#endif ++ ++ timediff = 0; ++ ++ while (1) { ++ u32 edm = bcm2835_sdhost_read(host, SDEDM); ++ if ((edm & 0xf) == 1) ++ break; ++ timediff++; ++ if (timediff > 5000000) { ++#ifdef DEBUG ++ do_gettimeofday(&after); ++ timediff = (after.tv_sec - before.tv_sec)*1000000 + ++ (after.tv_usec - before.tv_usec); ++ ++ pr_err(" wait_write_complete - still waiting after %dus\n", ++ timediff); ++#else ++ pr_err(" wait_write_complete - still waiting after %d retries\n", ++ timediff); ++#endif ++ bcm2835_sdhost_dumpregs(host); ++ host->data->error = -ETIMEDOUT; ++ return; ++ } ++ } ++ ++#ifdef DEBUG ++ do_gettimeofday(&after); ++ timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); ++ ++ total_stall_time += timediff; ++ if (timediff > max_stall_time) ++ max_stall_time = timediff; ++ ++ if ((after.tv_sec - start_time.tv_sec) > 10) { ++ pr_debug(" wait_write_complete - max wait %dus, total %dus\n", ++ max_stall_time, total_stall_time); ++ start_time = after; ++ max_stall_time = 0; ++ total_stall_time = 0; ++ } ++#endif ++} ++ ++static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); ++ ++static void bcm2835_sdhost_dma_complete(void *param) ++{ ++ struct bcm2835_host *host = param; ++ struct dma_chan *dma_chan; ++ unsigned long flags; ++ u32 dir_data; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host->data) { ++ bool write_complete; ++ if (USE_BLOCK_IRQ) ++ write_complete = bcm2835_sdhost_is_write_complete(host); ++ else { ++ bcm2835_sdhost_wait_write_complete(host); ++ write_complete = true; ++ } ++ pr_debug("dma_complete() - write_complete=%d\n", ++ write_complete); ++ ++ if (write_complete || (host->data->flags & MMC_DATA_READ)) ++ { ++ if (write_complete) { ++ dma_chan = host->dma_chan_tx; ++ dir_data = DMA_TO_DEVICE; ++ } else { ++ dma_chan = host->dma_chan_rx; ++ dir_data = DMA_FROM_DEVICE; ++ } ++ ++ dma_unmap_sg(dma_chan->device->dev, ++ host->data->sg, host->data->sg_len, ++ dir_data); ++ ++ bcm2835_sdhost_finish_data(host); ++ } ++ } ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) ++{ ++ unsigned long flags; ++ size_t blksize, len; ++ u32 *buf; ++ ++ blksize = host->data->blksz; ++ ++ local_irq_save(flags); ++ ++ while (blksize) { ++ if (!sg_miter_next(&host->sg_miter)) ++ BUG(); ++ ++ len = min(host->sg_miter.length, blksize); ++ BUG_ON(len % 4); ++ ++ blksize -= len; ++ host->sg_miter.consumed = len; ++ ++ buf = (u32 *)host->sg_miter.addr; ++ ++ while (len) { ++ while (1) { ++ u32 hsts; ++ hsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (hsts & SDHSTS_DATA_FLAG) ++ break; ++ ++ if (hsts & SDHSTS_ERROR_MASK) { ++ pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", ++ mmc_hostname(host->mmc), ++ hsts, ++ bcm2835_sdhost_read(host, SDHBCT), ++ blksize + len); ++ if (hsts & SDHSTS_REW_TIME_OUT) ++ host->data->error = -ETIMEDOUT; ++ else if (hsts & (SDHSTS_CRC16_ERROR || ++ SDHSTS_CRC7_ERROR)) ++ host->data->error = -EILSEQ; ++ else { ++ pr_err("%s: unexpected data error\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ } ++ } ++ } ++ ++ *(buf++) = bcm2835_sdhost_read(host, SDDATA); ++ len -= 4; ++ } ++ } ++ ++ sg_miter_stop(&host->sg_miter); ++ ++ local_irq_restore(flags); ++} ++ ++static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) ++{ ++ unsigned long flags; ++ size_t blksize, len; ++ u32 *buf; ++ ++ blksize = host->data->blksz; ++ ++ local_irq_save(flags); ++ ++ while (blksize) { ++ if (!sg_miter_next(&host->sg_miter)) ++ BUG(); ++ ++ len = min(host->sg_miter.length, blksize); ++ BUG_ON(len % 4); ++ ++ blksize -= len; ++ host->sg_miter.consumed = len; ++ ++ buf = host->sg_miter.addr; ++ ++ while (len) { ++ while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) ++ continue; ++ bcm2835_sdhost_write(host, *(buf++), SDDATA); ++ len -= 4; ++ } ++ } ++ ++ sg_miter_stop(&host->sg_miter); ++ ++ local_irq_restore(flags); ++} ++ ++ ++static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) ++{ ++ BUG_ON(!host->data); ++ ++ if (host->data->flags & MMC_DATA_READ) ++ bcm2835_sdhost_read_block_pio(host); ++ else ++ bcm2835_sdhost_write_block_pio(host); ++} ++ ++ ++static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) ++{ ++ u32 len, dir_data, dir_slave; ++ struct dma_async_tx_descriptor *desc = NULL; ++ struct dma_chan *dma_chan; ++ ++ pr_debug("bcm2835_sdhost_transfer_dma()\n"); ++ ++ WARN_ON(!host->data); ++ ++ if (!host->data) ++ return; ++ ++ if (host->data->flags & MMC_DATA_READ) { ++ dma_chan = host->dma_chan_rx; ++ dir_data = DMA_FROM_DEVICE; ++ dir_slave = DMA_DEV_TO_MEM; ++ } else { ++ dma_chan = host->dma_chan_tx; ++ dir_data = DMA_TO_DEVICE; ++ dir_slave = DMA_MEM_TO_DEV; ++ } ++ ++ BUG_ON(!dma_chan->device); ++ BUG_ON(!dma_chan->device->dev); ++ BUG_ON(!host->data->sg); ++ ++ len = dma_map_sg(dma_chan->device->dev, host->data->sg, ++ host->data->sg_len, dir_data); ++ if (len > 0) { ++ desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, ++ len, dir_slave, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ } else { ++ dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); ++ } ++ if (desc) { ++ desc->callback = bcm2835_sdhost_dma_complete; ++ desc->callback_param = host; ++ dmaengine_submit(desc); ++ dma_async_issue_pending(dma_chan); ++ } ++ ++} ++ ++ ++static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) ++{ ++ u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | ++ SDHCFG_BUSY_IRPT_EN; ++ if (host->use_dma) ++ host->hcfg = (host->hcfg & ~all_irqs) | ++ SDHCFG_BUSY_IRPT_EN; ++ else ++ host->hcfg = (host->hcfg & ~all_irqs) | ++ SDHCFG_DATA_IRPT_EN | ++ SDHCFG_BUSY_IRPT_EN; ++ ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++} ++ ++ ++static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) ++{ ++ struct mmc_data *data = cmd->data; ++ ++ WARN_ON(host->data); ++ ++ if (!data) ++ return; ++ ++ /* Sanity checks */ ++ BUG_ON(data->blksz * data->blocks > 524288); ++ BUG_ON(data->blksz > host->mmc->max_blk_size); ++ BUG_ON(data->blocks > 65535); ++ ++ host->data = data; ++ host->data_complete = 0; ++ host->flush_fifo = 0; ++ host->data->bytes_xfered = 0; ++ ++ if (!host->use_dma) { ++ int flags; ++ ++ flags = SG_MITER_ATOMIC; ++ if (data->flags & MMC_DATA_READ) ++ flags |= SG_MITER_TO_SG; ++ else ++ flags |= SG_MITER_FROM_SG; ++ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); ++ host->blocks = data->blocks; ++ } ++ ++ host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; ++ ++ bcm2835_sdhost_set_transfer_irqs(host); ++ ++ bcm2835_sdhost_write(host, data->blksz, SDHBCT); ++ if (host->use_dma) ++ bcm2835_sdhost_write(host, data->blocks, SDHBLC); ++ ++ BUG_ON(!host->data); ++} ++ ++ ++void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) ++{ ++ u32 sdcmd; ++ unsigned long timeout; ++ ++ WARN_ON(host->cmd); ++ ++ if (1) { ++ pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", ++ cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); ++ if (cmd->data) ++ pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ } ++ ++ /* Wait max 10 ms */ ++ timeout = 1000; ++ ++ while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { ++ if (timeout == 0) { ++ pr_err("%s: Previous command never completed.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ cmd->error = -EIO; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ timeout--; ++ udelay(10); ++ } ++ ++ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { ++ host->max_delay = (1000-timeout)/100; ++ pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); ++ } ++ ++ timeout = jiffies; ++#ifdef CONFIG_ARCH_BCM2835 ++ if (!cmd->data && cmd->busy_timeout > 9000) ++ timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; ++ else ++#endif ++ timeout += 10 * HZ; ++ mod_timer(&host->timer, timeout); ++ ++ host->cmd = cmd; ++ ++ bcm2835_sdhost_prepare_data(host, cmd); ++ ++ bcm2835_sdhost_write(host, cmd->arg, SDARG); ++ ++ if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { ++ pr_err("%s: Unsupported response type!\n", ++ mmc_hostname(host->mmc)); ++ cmd->error = -EINVAL; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ ++ sdcmd = cmd->opcode & SDCMD_CMD_MASK; ++ ++ if (!(cmd->flags & MMC_RSP_PRESENT)) ++ sdcmd |= SDCMD_NO_RESPONSE; ++ else { ++ if (cmd->flags & MMC_RSP_136) ++ sdcmd |= SDCMD_LONG_RESPONSE; ++ if (cmd->flags & MMC_RSP_BUSY) { ++ sdcmd |= SDCMD_BUSYWAIT; ++ host->use_busy = 1; ++ } ++ } ++ ++ if (cmd->data) { ++ if (host->delay_after_stop) { ++ struct timeval now; ++ int time_since_stop; ++ do_gettimeofday(&now); ++ time_since_stop = (now.tv_sec - host->stop_time.tv_sec); ++ if (time_since_stop < 2) { ++ /* Possibly less than one second */ ++ time_since_stop = time_since_stop * 1000000 + ++ (now.tv_usec - host->stop_time.tv_usec); ++ if (time_since_stop < host->delay_after_stop) ++ udelay(host->delay_after_stop - ++ time_since_stop); ++ } ++ } ++ ++ if (cmd->data->flags & MMC_DATA_WRITE) ++ sdcmd |= SDCMD_WRITE_CMD; ++ if (cmd->data->flags & MMC_DATA_READ) ++ sdcmd |= SDCMD_READ_CMD; ++ } ++ ++ bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); ++} ++ ++ ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); ++static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); ++ ++static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) ++{ ++ struct mmc_data *data; ++ ++ data = host->data; ++ BUG_ON(!data); ++ ++ pr_debug("finish_data(error %d, stop %d, sbc %d)\n", ++ data->error, data->stop ? 1 : 0, ++ host->mrq->sbc ? 1 : 0); ++ ++ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ ++ if (data->error) { ++ data->bytes_xfered = 0; ++ } else ++ data->bytes_xfered = data->blksz * data->blocks; ++ ++ host->data_complete = 1; ++ ++ if (host->cmd) { ++ /* ++ * Data managed to finish before the ++ * command completed. Make sure we do ++ * things in the proper order. ++ */ ++ pr_debug("Finished early - HSTS %x\n", ++ bcm2835_sdhost_read(host, SDHSTS)); ++ } ++ else ++ bcm2835_sdhost_transfer_complete(host); ++} ++ ++ ++static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) ++{ ++ struct mmc_data *data; ++ ++ BUG_ON(host->cmd); ++ BUG_ON(!host->data); ++ BUG_ON(!host->data_complete); ++ ++ data = host->data; ++ host->data = NULL; ++ ++ pr_debug("transfer_complete(error %d, stop %d)\n", ++ data->error, data->stop ? 1 : 0); ++ ++ if (data->error) ++ /* ++ * The controller needs a reset of internal state machines ++ * upon error conditions. ++ */ ++ bcm2835_sdhost_reset(host); ++ ++ /* ++ * Need to send CMD12 if - ++ * a) open-ended multiblock transfer (no CMD23) ++ * b) error in multiblock transfer ++ */ ++ if (data->stop && ++ (data->error || ++ !host->mrq->sbc)) { ++ host->flush_fifo = 1; ++ bcm2835_sdhost_send_command(host, data->stop); ++ if (host->delay_after_stop) ++ do_gettimeofday(&host->stop_time); ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host); ++ } else { ++ tasklet_schedule(&host->finish_tasklet); ++ } ++} ++ ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) ++{ ++ u32 sdcmd; ++ int timeout = 1000; ++#ifdef DEBUG ++ struct timeval before, after; ++ int timediff = 0; ++#endif ++ ++ pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); ++ ++ BUG_ON(!host->cmd || !host->mrq); ++ ++#ifdef DEBUG ++ do_gettimeofday(&before); ++#endif ++ for (sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ (sdcmd & SDCMD_NEW_FLAG) && timeout; ++ timeout--) { ++ if (host->flush_fifo) { ++ while (bcm2835_sdhost_read(host, SDHSTS) & ++ SDHSTS_DATA_FLAG) ++ (void)bcm2835_sdhost_read(host, SDDATA); ++ } ++ udelay(10); ++ sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ } ++#ifdef DEBUG ++ do_gettimeofday(&after); ++ timediff = (after.tv_sec - before.tv_sec)*1000000 + ++ (after.tv_usec - before.tv_usec); ++ ++ pr_debug(" finish_command - waited %dus\n", timediff); ++#endif ++ ++ if (timeout == 0) { ++ pr_err("%s: Command never completed.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ ++ if (host->flush_fifo) { ++ for (timeout = 100; ++ (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; ++ timeout--) { ++ (void)bcm2835_sdhost_read(host, SDDATA); ++ } ++ host->flush_fifo = 0; ++ if (timeout == 0) { ++ pr_err("%s: FIFO never drained.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ } ++ ++ /* Check for errors */ ++ if (sdcmd & SDCMD_FAIL_FLAG) ++ { ++ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ ++ pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", ++ mmc_hostname(host->mmc), sdcmd, sdhsts, ++ bcm2835_sdhost_read(host, SDEDM)); ++ ++ if (sdhsts & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else ++ { ++ pr_err("%s: unexpected command error\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ } ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ ++ if (host->cmd->flags & MMC_RSP_PRESENT) { ++ if (host->cmd->flags & MMC_RSP_136) { ++ int i; ++ for (i = 0; i < 4; i++) ++ host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); ++ pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", ++ host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); ++ } else { ++ host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); ++ pr_debug("bcm2835_sdhost_finish_command: %08x\n", ++ host->cmd->resp[0]); ++ } ++ } ++ ++ host->cmd->error = 0; ++ ++ if (host->cmd == host->mrq->sbc) { ++ /* Finished CMD23, now send actual command. */ ++ host->cmd = NULL; ++ bcm2835_sdhost_send_command(host, host->mrq->cmd); ++ ++ if (host->cmd->data && host->use_dma) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_transfer_dma(host); ++ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host); ++ } else if (host->cmd == host->mrq->stop) ++ /* Finished CMD12 */ ++ tasklet_schedule(&host->finish_tasklet); ++ else { ++ /* Processed actual command. */ ++ host->cmd = NULL; ++ if (!host->data) ++ tasklet_schedule(&host->finish_tasklet); ++ else if (host->data_complete) ++ bcm2835_sdhost_transfer_complete(host); ++ } ++} ++ ++static void bcm2835_sdhost_timeout_timer(unsigned long data) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ host = (struct bcm2835_host *)data; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host->mrq) { ++ pr_err("%s: Timeout waiting for hardware interrupt.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ ++ if (host->data) { ++ host->data->error = -ETIMEDOUT; ++ bcm2835_sdhost_finish_data(host); ++ } else { ++ if (host->cmd) ++ host->cmd->error = -ETIMEDOUT; ++ else ++ host->mrq->cmd->error = -ETIMEDOUT; ++ ++ pr_debug("timeout_timer tasklet_schedule\n"); ++ tasklet_schedule(&host->finish_tasklet); ++ } ++ } ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) ++{ ++ if (enable) ++ host->hcfg |= SDHCFG_SDIO_IRPT_EN; ++ else ++ host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ mmiowb(); ++} ++ ++static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) ++{ ++ struct bcm2835_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ ++ pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); ++ spin_lock_irqsave(&host->lock, flags); ++ bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) ++{ ++ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ ++ if (!host->cmd) { ++ pr_err("%s: Got command busy interrupt 0x%08x even " ++ "though no command operation was in progress.\n", ++ mmc_hostname(host->mmc), (unsigned)intmask); ++ bcm2835_sdhost_dumpregs(host); ++ return 0; ++ } ++ ++ if (!host->use_busy) { ++ pr_err("%s: Got command busy interrupt 0x%08x even " ++ "though not expecting one.\n", ++ mmc_hostname(host->mmc), (unsigned)intmask); ++ bcm2835_sdhost_dumpregs(host); ++ return 0; ++ } ++ host->use_busy = 0; ++ ++ if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | ++ SDHSTS_FIFO_ERROR)) ++ host->cmd->error = -EILSEQ; ++ ++ if (host->cmd->error) ++ tasklet_schedule(&host->finish_tasklet); ++ else ++ bcm2835_sdhost_finish_command(host); ++ ++ return handled; ++} ++ ++static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) ++{ ++ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ ++ /* There are no dedicated data/space available interrupt ++ status bits, so it is necessary to use the single shared ++ data/space available FIFO status bits. It is therefore not ++ an error to get here when there is no data transfer in ++ progress. */ ++ if (!host->data) ++ return 0; ++ ++ // XXX FIFO_ERROR ++ if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && ++ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) ++ != MMC_BUS_TEST_R)) ++ host->cmd->error = -EILSEQ; ++ ++ /* Use the block interrupt for writes after the first block */ ++ if (host->data->flags & MMC_DATA_WRITE) { ++ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); ++ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ if (host->data->error) ++ bcm2835_sdhost_finish_data(host); ++ else ++ bcm2835_sdhost_transfer_pio(host); ++ } else { ++ if (!host->data->error) { ++ bcm2835_sdhost_transfer_pio(host); ++ host->blocks--; ++ } ++ if ((host->blocks == 0) || host->data->error) ++ bcm2835_sdhost_finish_data(host); ++ } ++ ++ return handled; ++} ++ ++static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) ++{ ++ struct dma_chan *dma_chan; ++ u32 dir_data; ++ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ ++ if (!host->data) { ++ pr_err("%s: Got block interrupt 0x%08x even " ++ "though no data operation was in progress.\n", ++ mmc_hostname(host->mmc), (unsigned)intmask); ++ bcm2835_sdhost_dumpregs(host); ++ return handled; ++ } ++ ++ if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && ++ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) ++ != MMC_BUS_TEST_R)) ++ host->cmd->error = -EILSEQ; ++ ++ if (!host->use_dma) { ++ BUG_ON(!host->blocks); ++ host->blocks--; ++ if ((host->blocks == 0) || host->data->error) ++ bcm2835_sdhost_finish_data(host); ++ else ++ bcm2835_sdhost_transfer_pio(host); ++ } else if (host->data->flags & MMC_DATA_WRITE) { ++ dma_chan = host->dma_chan_tx; ++ dir_data = DMA_TO_DEVICE; ++ dma_unmap_sg(dma_chan->device->dev, ++ host->data->sg, host->data->sg_len, ++ dir_data); ++ ++ bcm2835_sdhost_finish_data(host); ++ } ++ ++ return handled; ++} ++ ++ ++static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) ++{ ++ irqreturn_t result = IRQ_NONE; ++ struct bcm2835_host *host = dev_id; ++ u32 unexpected = 0, early = 0; ++ int loops = 0; ++#ifndef CONFIG_ARCH_BCM2835 ++ int cardint = 0; ++#endif ++ spin_lock(&host->lock); ++ ++ for (loops = 0; loops < 1; loops++) { ++ u32 intmask, handled; ++ ++ intmask = bcm2835_sdhost_read(host, SDHSTS); ++ handled = intmask & (SDHSTS_BUSY_IRPT | ++ SDHSTS_BLOCK_IRPT | ++ SDHSTS_SDIO_IRPT | ++ SDHSTS_DATA_FLAG); ++ if ((handled == SDHSTS_DATA_FLAG) && // XXX ++ (loops == 0) && !host->data) { ++ pr_err("%s: sdhost_irq data interrupt 0x%08x even " ++ "though no data operation was in progress.\n", ++ mmc_hostname(host->mmc), ++ (unsigned)intmask); ++ ++ bcm2835_sdhost_dumpregs(host); ++ } ++ ++ if (!handled) ++ break; ++ ++ if (loops) ++ early |= handled; ++ ++ result = IRQ_HANDLED; ++ ++ /* Clear all interrupts and notifications */ ++ bcm2835_sdhost_write(host, intmask, SDHSTS); ++ ++ if (intmask & SDHSTS_BUSY_IRPT) ++ handled |= bcm2835_sdhost_busy_irq(host, intmask); ++ ++ /* There is no true data interrupt status bit, so it is ++ necessary to qualify the data flag with the interrupt ++ enable bit */ ++ if ((intmask & SDHSTS_DATA_FLAG) && ++ (host->hcfg & SDHCFG_DATA_IRPT_EN)) ++ handled |= bcm2835_sdhost_data_irq(host, intmask); ++ ++ if (intmask & SDHSTS_BLOCK_IRPT) ++ handled |= bcm2835_sdhost_block_irq(host, intmask); ++ ++ if (intmask & SDHSTS_SDIO_IRPT) { ++#ifndef CONFIG_ARCH_BCM2835 ++ cardint = 1; ++#else ++ bcm2835_sdhost_enable_sdio_irq_nolock(host, false); ++ host->thread_isr |= SDHSTS_SDIO_IRPT; ++ result = IRQ_WAKE_THREAD; ++#endif ++ } ++ ++ unexpected |= (intmask & ~handled); ++ } ++ ++ mmiowb(); ++ ++ spin_unlock(&host->lock); ++ ++ if (early) ++ pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); ++ ++ if (unexpected) { ++ pr_err("%s: Unexpected interrupt 0x%08x.\n", ++ mmc_hostname(host->mmc), unexpected); ++ bcm2835_sdhost_dumpregs(host); ++ } ++ ++#ifndef CONFIG_ARCH_BCM2835 ++ if (cardint) ++ mmc_signal_sdio_irq(host->mmc); ++#endif ++ ++ return result; ++} ++ ++#ifdef CONFIG_ARCH_BCM2835 ++static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) ++{ ++ struct bcm2835_host *host = dev_id; ++ unsigned long flags; ++ u32 isr; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ isr = host->thread_isr; ++ host->thread_isr = 0; ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (isr & SDHSTS_SDIO_IRPT) { ++ sdio_run_irqs(host->mmc); ++ ++/* Is this necessary? Why re-enable an interrupt which is enabled? ++ spin_lock_irqsave(&host->lock, flags); ++ if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) ++ bcm2835_sdhost_enable_sdio_irq_nolock(host, true); ++ spin_unlock_irqrestore(&host->lock, flags); ++*/ ++ } ++ ++ return isr ? IRQ_HANDLED : IRQ_NONE; ++} ++#endif ++ ++ ++ ++void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) ++{ ++ int div = 0; /* Initialized for compiler warning */ ++ unsigned int input_clock = clock; ++ ++ if (host->overclock_50 && (clock == 50000000)) ++ clock = host->overclock_50 * 1000000 + 999999; ++ ++ /* The SDCDIV register has 11 bits, and holds (div - 2). ++ But in data mode the max is 50MHz wihout a minimum, and only the ++ bottom 3 bits are used. Since the switch over is automatic (unless ++ we have marked the card as slow...), chosen values have to make ++ sense in both modes. ++ Ident mode must be 100-400KHz, so can range check the requested ++ clock. CMD15 must be used to return to data mode, so this can be ++ monitored. ++ ++ clock 250MHz -> 0->125MHz, 1->83.3MHz, 2->62.5MHz, 3->50.0MHz ++ 4->41.7MHz, 5->35.7MHz, 6->31.3MHz, 7->27.8MHz ++ ++ 623->400KHz/27.8MHz ++ reset value (507)->491159/50MHz ++ ++ BUT, the 3-bit clock divisor in data mode is too small if the ++ core clock is higher than 250MHz, so instead use the SLOW_CARD ++ configuration bit to force the use of the ident clock divisor ++ at all times. ++ */ ++ ++ host->mmc->actual_clock = 0; ++ ++ if (clock < 100000) { ++ /* Can't stop the clock, but make it as slow as possible ++ * to show willing ++ */ ++ host->cdiv = SDCDIV_MAX_CDIV; ++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); ++ return; ++ } ++ ++ div = host->max_clk / clock; ++ if (div < 2) ++ div = 2; ++ if ((host->max_clk / div) > clock) ++ div++; ++ div -= 2; ++ ++ if (div > SDCDIV_MAX_CDIV) ++ div = SDCDIV_MAX_CDIV; ++ ++ clock = host->max_clk / (div + 2); ++ host->mmc->actual_clock = clock; ++ ++ if ((clock > input_clock) && (clock > host->max_overclock)) { ++ pr_warn("%s: Overclocking to %dHz\n", ++ mmc_hostname(host->mmc), clock); ++ host->max_overclock = clock; ++ } ++ ++ host->cdiv = div; ++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); ++ ++ pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", ++ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); ++} ++ ++static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ if (1) { ++ struct mmc_command *cmd = mrq->cmd; ++ const char *src = "cmd"; ++ BUG_ON(!cmd); ++ pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", ++ src, cmd->opcode, cmd->arg, cmd->flags); ++ if (cmd->data) ++ pr_debug("bcm2835_sdhost_request: %s %d*%d\n", ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ } ++ ++ if (mrq->data && !is_power_of_2(mrq->data->blksz)) { ++ pr_err("%s: Unsupported block size (%d bytes)\n", ++ mmc_hostname(mmc), mrq->data->blksz); ++ mrq->cmd->error = -EINVAL; ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ ++ host = mmc_priv(mmc); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ WARN_ON(host->mrq != NULL); ++ ++ host->mrq = mrq; ++ ++ if (mrq->sbc) ++ bcm2835_sdhost_send_command(host, mrq->sbc); ++ else ++ bcm2835_sdhost_send_command(host, mrq->cmd); ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (!mrq->sbc && mrq->cmd->data && host->use_dma) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_transfer_dma(host); ++ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host); ++} ++ ++ ++static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ ++ struct bcm2835_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ ++ pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", ++ ios->clock, ios->power_mode, ios->bus_width, ++ ios->timing, ios->signal_voltage, ios->drv_type); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (!ios->clock || ios->clock != host->clock) { ++ bcm2835_sdhost_set_clock(host, ios->clock); ++ host->clock = ios->clock; ++ } ++ ++ /* set bus width */ ++ host->hcfg &= ~SDHCFG_WIDE_EXT_BUS; ++ if (ios->bus_width == MMC_BUS_WIDTH_4) ++ host->hcfg |= SDHCFG_WIDE_EXT_BUS; ++ ++ host->hcfg |= SDHCFG_WIDE_INT_BUS; ++ ++ /* Disable clever clock switching, to cope with fast core clocks */ ++ host->hcfg |= SDHCFG_SLOW_CARD; ++ ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ ++ mmiowb(); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, ++ unsigned int direction, ++ u32 blk_pos, int blk_size) ++{ ++ /* There is a bug in the host controller hardware that makes ++ reading the final sector of the card as part of a multiple read ++ problematic. Detect that case and shorten the read accordingly. ++ */ ++ /* csd.capacity is in weird units - convert to sectors */ ++ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); ++ ++ if ((direction == MMC_DATA_READ) && ++ ((blk_pos + blk_size) == card_sectors)) ++ blk_size--; ++ ++ return blk_size; ++} ++ ++ ++static struct mmc_host_ops bcm2835_sdhost_ops = { ++ .request = bcm2835_sdhost_request, ++ .set_ios = bcm2835_sdhost_set_ios, ++ .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, ++ .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, ++}; ++ ++ ++static void bcm2835_sdhost_tasklet_finish(unsigned long param) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ struct mmc_request *mrq; ++ ++ host = (struct bcm2835_host *)param; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ /* ++ * If this tasklet gets rescheduled while running, it will ++ * be run again afterwards but without any active request. ++ */ ++ if (!host->mrq) { ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ ++ del_timer(&host->timer); ++ ++ mrq = host->mrq; ++ ++ /* ++ * The controller needs a reset of internal state machines ++ * upon error conditions. ++ */ ++ if (((mrq->cmd && mrq->cmd->error) || ++ (mrq->data && (mrq->data->error || ++ (mrq->data->stop && mrq->data->stop->error))))) { ++ ++ bcm2835_sdhost_reset(host); ++ } ++ ++ host->mrq = NULL; ++ host->cmd = NULL; ++ host->data = NULL; ++ ++ mmiowb(); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++ mmc_request_done(host->mmc, mrq); ++} ++ ++ ++ ++int bcm2835_sdhost_add_host(struct bcm2835_host *host) ++{ ++ struct mmc_host *mmc; ++ struct dma_slave_config cfg; ++ int ret; ++ ++ mmc = host->mmc; ++ ++ bcm2835_sdhost_reset(host); ++ ++ mmc->f_max = host->max_clk; ++ mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; ++ ++ /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ ++ host->timeout_clk = mmc->f_max / 1000; ++#ifdef CONFIG_ARCH_BCM2835 ++ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; ++#endif ++ /* host controller capabilities */ ++ mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | ++ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | ++ MMC_CAP_NEEDS_POLL | ++ (ALLOW_CMD23 * MMC_CAP_CMD23); ++ ++ spin_lock_init(&host->lock); ++ ++ if (host->allow_dma) { ++ if (!host->dma_chan_tx || !host->dma_chan_rx || ++ IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { ++ pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); ++ host->have_dma = false; ++ } else { ++ pr_info("DMA channels allocated for the SDHost driver"); ++ host->have_dma = true; ++ ++ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ cfg.slave_id = 13; /* DREQ channel */ ++ ++ cfg.direction = DMA_MEM_TO_DEV; ++ cfg.src_addr = 0; ++ cfg.dst_addr = host->phys_addr + SDDATA; ++ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); ++ ++ cfg.direction = DMA_DEV_TO_MEM; ++ cfg.src_addr = host->phys_addr + SDDATA; ++ cfg.dst_addr = 0; ++ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); ++ } ++ } else { ++ pr_info("Forcing PIO mode\n"); ++ host->have_dma = false; ++ } ++ ++ mmc->max_segs = 128; ++ mmc->max_req_size = 524288; ++ mmc->max_seg_size = mmc->max_req_size; ++ mmc->max_blk_size = 512; ++ mmc->max_blk_count = 65535; ++ ++ /* report supported voltage ranges */ ++ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; ++ ++ tasklet_init(&host->finish_tasklet, ++ bcm2835_sdhost_tasklet_finish, (unsigned long)host); ++ ++ setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); ++ ++ bcm2835_sdhost_init(host, 0); ++#ifndef CONFIG_ARCH_BCM2835 ++ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, ++ mmc_hostname(mmc), host); ++#else ++ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, ++ IRQF_SHARED, mmc_hostname(mmc), host); ++#endif ++ if (ret) { ++ pr_err("%s: Failed to request IRQ %d: %d\n", ++ mmc_hostname(mmc), host->irq, ret); ++ goto untasklet; ++ } ++ ++ mmiowb(); ++ mmc_add_host(mmc); ++ ++ pr_info("Load BCM2835 SDHost driver\n"); ++ if (host->delay_after_stop) ++ pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", ++ host->delay_after_stop); ++ ++ return 0; ++ ++untasklet: ++ tasklet_kill(&host->finish_tasklet); ++ ++ return ret; ++} ++ ++static int bcm2835_sdhost_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct clk *clk; ++ struct resource *iomem; ++ struct bcm2835_host *host; ++ struct mmc_host *mmc; ++ int ret; ++ ++ pr_debug("bcm2835_sdhost_probe\n"); ++ mmc = mmc_alloc_host(sizeof(*host), dev); ++ if (!mmc) ++ return -ENOMEM; ++ ++ mmc->ops = &bcm2835_sdhost_ops; ++ host = mmc_priv(mmc); ++ host->mmc = mmc; ++ host->timeout = msecs_to_jiffies(1000); ++ spin_lock_init(&host->lock); ++ ++ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ host->ioaddr = devm_ioremap_resource(dev, iomem); ++ if (IS_ERR(host->ioaddr)) { ++ ret = PTR_ERR(host->ioaddr); ++ goto err; ++ } ++ ++ host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT; ++ pr_debug(" - ioaddr %lx, iomem->start %lx, phys_addr %lx\n", ++ (unsigned long)host->ioaddr, ++ (unsigned long)iomem->start, ++ (unsigned long)host->phys_addr); ++ ++ host->allow_dma = ALLOW_DMA; ++ ++ if (node) { ++ /* Read any custom properties */ ++ of_property_read_u32(node, ++ "brcm,delay-after-stop", ++ &host->delay_after_stop); ++ of_property_read_u32(node, ++ "brcm,overclock-50", ++ &host->overclock_50); ++ host->allow_dma = ALLOW_DMA && ++ !of_property_read_bool(node, "brcm,force-pio"); ++ } ++ ++ if (host->allow_dma) { ++ if (node) { ++ host->dma_chan_tx = ++ dma_request_slave_channel(dev, "tx"); ++ host->dma_chan_rx = ++ dma_request_slave_channel(dev, "rx"); ++ } else { ++ dma_cap_mask_t mask; ++ ++ dma_cap_zero(mask); ++ /* we don't care about the channel, any would work */ ++ dma_cap_set(DMA_SLAVE, mask); ++ host->dma_chan_tx = ++ dma_request_channel(mask, NULL, NULL); ++ host->dma_chan_rx = ++ dma_request_channel(mask, NULL, NULL); ++ } ++ } ++ ++ clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(dev, "could not get clk\n"); ++ ret = PTR_ERR(clk); ++ goto err; ++ } ++ ++ host->max_clk = clk_get_rate(clk); ++ ++ host->irq = platform_get_irq(pdev, 0); ++ if (host->irq <= 0) { ++ dev_err(dev, "get IRQ failed\n"); ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ pr_debug(" - max_clk %lx, irq %d\n", ++ (unsigned long)host->max_clk, ++ (int)host->irq); ++ ++ if (node) ++ mmc_of_parse(mmc); ++ else ++ mmc->caps |= MMC_CAP_4_BIT_DATA; ++ ++ ret = bcm2835_sdhost_add_host(host); ++ if (ret) ++ goto err; ++ ++ platform_set_drvdata(pdev, host); ++ ++ pr_debug("bcm2835_sdhost_probe -> OK\n"); ++ ++ return 0; ++ ++err: ++ pr_debug("bcm2835_sdhost_probe -> err %d\n", ret); ++ mmc_free_host(mmc); ++ ++ return ret; ++} ++ ++static int bcm2835_sdhost_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_host *host = platform_get_drvdata(pdev); ++ ++ pr_debug("bcm2835_sdhost_remove\n"); ++ ++ mmc_remove_host(host->mmc); ++ ++ bcm2835_sdhost_set_power(host, false); ++ ++ free_irq(host->irq, host); ++ ++ del_timer_sync(&host->timer); ++ ++ tasklet_kill(&host->finish_tasklet); ++ ++ mmc_free_host(host->mmc); ++ platform_set_drvdata(pdev, NULL); ++ ++ pr_debug("bcm2835_sdhost_remove - OK\n"); ++ return 0; ++} ++ ++ ++static const struct of_device_id bcm2835_sdhost_match[] = { ++ { .compatible = "brcm,bcm2835-sdhost" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); ++ ++ ++ ++static struct platform_driver bcm2835_sdhost_driver = { ++ .probe = bcm2835_sdhost_probe, ++ .remove = bcm2835_sdhost_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_sdhost_match, ++ }, ++}; ++module_platform_driver(bcm2835_sdhost_driver); ++ ++MODULE_ALIAS("platform:sdhost-bcm2835"); ++MODULE_DESCRIPTION("BCM2835 SDHost driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Phil Elwell"); + +From 34fb9ba0190b9f9e18e6c136c64af8dcea23376d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 009/216] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 11/77] cma: Add vc_cma driver to enable use of CMA Signed-off-by: popcornmix @@ -80985,12 +80479,15 @@ index 0000000..5325832 + +#endif /* VC_CMA_H */ -From 6bafd180b5b7672ebbaea3878e78511d309007a0 Mon Sep 17 00:00:00 2001 +From 0e6896e85bf10d584b555ecae4b55f066a774b54 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 010/216] bcm2708: alsa sound driver +Subject: [PATCH 12/77] bcm2708: alsa sound driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit - Signed-off-by: popcornmix +Signed-off-by: popcornmix alsa: add mmap support and some cleanups to bcm2835 ALSA driver @@ -81014,33 +80511,41 @@ snd-bcm2708: Fix dmesg spam for non-error case alsa: Ensure mutexes are released through error paths alsa: Make interrupted close paths quieter + +BCM270x: Add onboard sound device to Device Tree + +Add Device Tree support to alsa driver. +Add device to Device Tree. +Don't add platform devices when booting in DT mode. + +Signed-off-by: Noralf Trønnes --- - arch/arm/mach-bcm2708/bcm2708.c | 54 +++ - sound/arm/Kconfig | 7 + + arch/arm/mach-bcm2708/bcm2708.c | 53 +++ + arch/arm/mach-bcm2709/bcm2709.c | 53 +++ + sound/arm/Kconfig | 8 + sound/arm/Makefile | 5 + sound/arm/bcm2835-ctl.c | 323 +++++++++++++ sound/arm/bcm2835-pcm.c | 557 +++++++++++++++++++++++ sound/arm/bcm2835-vchiq.c | 902 +++++++++++++++++++++++++++++++++++++ - sound/arm/bcm2835.c | 420 +++++++++++++++++ + sound/arm/bcm2835.c | 511 +++++++++++++++++++++ sound/arm/bcm2835.h | 167 +++++++ sound/arm/vc_vchi_audioserv_defs.h | 116 +++++ - 9 files changed, 2551 insertions(+) + 10 files changed, 2695 insertions(+) create mode 100755 sound/arm/bcm2835-ctl.c create mode 100755 sound/arm/bcm2835-pcm.c create mode 100755 sound/arm/bcm2835-vchiq.c - create mode 100755 sound/arm/bcm2835.c + create mode 100644 sound/arm/bcm2835.c create mode 100755 sound/arm/bcm2835.h create mode 100644 sound/arm/vc_vchi_audioserv_defs.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index d1308ed..f54e3e9b 100644 +index 5b10802..06271df 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -447,6 +447,58 @@ struct platform_device bcm2708_powerman_device = { - .coherent_dma_mask = 0xffffffffUL}, +@@ -429,6 +429,57 @@ struct platform_device bcm2835_emmc_device = { }; + #endif /* CONFIG_MMC_BCM2835 */ -+ +static struct platform_device bcm2708_alsa_devices[] = { + [0] = { + .name = "bcm2835_AUD0", @@ -81095,26 +80600,98 @@ index d1308ed..f54e3e9b 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -556,6 +608,8 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2835_emmc_device); +@@ -571,6 +622,8 @@ void __init bcm2708_init(void) #endif bcm2708_init_led(); + bcm2708_init_uart1(); + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); ++ bcm_register_device_dt(&bcm2708_alsa_devices[i]); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 54c5444..0f875ff 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -449,6 +449,57 @@ struct platform_device bcm2835_emmc_device = { + }; + #endif /* CONFIG_MMC_BCM2835 */ + ++static struct platform_device bcm2708_alsa_devices[] = { ++ [0] = { ++ .name = "bcm2835_AUD0", ++ .id = 0, /* first audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [1] = { ++ .name = "bcm2835_AUD1", ++ .id = 1, /* second audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [2] = { ++ .name = "bcm2835_AUD2", ++ .id = 2, /* third audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [3] = { ++ .name = "bcm2835_AUD3", ++ .id = 3, /* forth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [4] = { ++ .name = "bcm2835_AUD4", ++ .id = 4, /* fifth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [5] = { ++ .name = "bcm2835_AUD5", ++ .id = 5, /* sixth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [6] = { ++ .name = "bcm2835_AUD6", ++ .id = 6, /* seventh audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [7] = { ++ .name = "bcm2835_AUD7", ++ .id = 7, /* eighth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++}; ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -591,6 +642,8 @@ void __init bcm2709_init(void) + #endif + bcm2709_init_led(); + bcm2709_init_uart1(); ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device_dt(&bcm2708_alsa_devices[i]); + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig -index 885683a..ada7ba2 100644 +index 885683a..fcbe9d7 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig -@@ -39,5 +39,12 @@ config SND_PXA2XX_AC97 +@@ -39,5 +39,13 @@ 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 || ARCH_BCM2709) && BCM2708_VCHIQ && SND ++ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) \ ++ && BCM2708_VCHIQ && SND + select SND_PCM + help + Say Y or M if you want to support BCM2835 Alsa pcm card driver @@ -82935,11 +82512,11 @@ index 0000000..3de3094 +module_param(force_bulk, bool, 0444); +MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c -new file mode 100755 -index 0000000..7ed5079 +new file mode 100644 +index 0000000..6b545e7 --- /dev/null +++ b/sound/arm/bcm2835.c -@@ -0,0 +1,420 @@ +@@ -0,0 +1,511 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -82959,6 +82536,7 @@ index 0000000..7ed5079 +#include +#include +#include ++#include + +#include "bcm2835.h" + @@ -83023,6 +82601,86 @@ index 0000000..7ed5079 + return 0; +} + ++static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ bcm2835_chip_t *chip; ++ struct snd_card *card; ++ u32 numchans; ++ int err, i; ++ ++ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", ++ &numchans); ++ if (err) { ++ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); ++ return err; ++ } ++ ++ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { ++ numchans = MAX_SUBSTREAMS; ++ dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n", ++ numchans); ++ } ++ ++ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card); ++ if (err) { ++ dev_err(dev, "Failed to create soundcard structure\n"); ++ return err; ++ } ++ ++ snd_card_set_dev(card, dev); ++ strcpy(card->driver, "bcm2835"); ++ strcpy(card->shortname, "bcm2835 ALSA"); ++ sprintf(card->longname, "%s", card->shortname); ++ ++ err = snd_bcm2835_create(card, pdev, &chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create bcm2835 chip\n"); ++ goto err_free; ++ } ++ ++ err = snd_bcm2835_new_pcm(chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create new bcm2835 pcm device\n"); ++ goto err_free; ++ } ++ ++ err = snd_bcm2835_new_spdif_pcm(chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n"); ++ goto err_free; ++ } ++ ++ err = snd_bcm2835_new_ctl(chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create new bcm2835 ctl\n"); ++ goto err_free; ++ } ++ ++ for (i = 0; i < numchans; i++) { ++ chip->avail_substreams |= (1 << i); ++ chip->pdev[i] = pdev; ++ } ++ ++ err = snd_card_register(card); ++ if (err) { ++ dev_err(dev, "Failed to register bcm2835 ALSA card \n"); ++ goto err_free; ++ } ++ ++ g_card = card; ++ g_chip = chip; ++ platform_set_drvdata(pdev, card); ++ audio_info("bcm2835 ALSA card created with %u channels\n", numchans); ++ ++ return 0; ++ ++err_free: ++ snd_card_free(card); ++ ++ return err; ++} ++ +static int snd_bcm2835_alsa_probe(struct platform_device *pdev) +{ + static int dev; @@ -83030,6 +82688,9 @@ index 0000000..7ed5079 + struct snd_card *card; + int err; + ++ if (pdev->dev.of_node) ++ return snd_bcm2835_alsa_probe_dt(pdev); ++ + if (dev >= MAX_SUBSTREAMS) + return -ENODEV; + @@ -83166,6 +82827,12 @@ index 0000000..7ed5079 + +#endif + ++static const struct of_device_id snd_bcm2835_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-audio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); ++ +static struct platform_driver bcm2835_alsa0_driver = { + .probe = snd_bcm2835_alsa_probe, + .remove = snd_bcm2835_alsa_remove, @@ -83176,6 +82843,7 @@ index 0000000..7ed5079 + .driver = { + .name = "bcm2835_AUD0", + .owner = THIS_MODULE, ++ .of_match_table = snd_bcm2835_of_match_table, + }, +}; + @@ -83656,10 +83324,13 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From ddf7318165c6faf5bc73597105a2eed9fece4225 Mon Sep 17 00:00:00 2001 +From b2b5ab24c875e79e1fbb55ae76dc5a914fe301d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 011/216] bcm2708 vchiq driver +Subject: [PATCH 13/77] bcm2708 vchiq driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix @@ -83727,7 +83398,30 @@ vchiq: Fix wrong condition check The log level is checked from within the log call. Remove the check in the call. Signed-off-by: Pranith Kumar + +BCM270x: Add vchiq device to platform file and Device Tree + +Prepare to turn the vchiq module into a driver. + +Signed-off-by: Noralf Trønnes + +bcm2708: vchiq: Add Device Tree support + +Turn vchiq into a driver and stop hardcoding resources. +Use devm_* functions in probe path to simplify cleanup. +A global variable is used to hold the register address. This is done +to keep this patch as small as possible. +Also make available on ARCH_BCM2835. +Based on work by Lubomir Rintel. + +Signed-off-by: Noralf Trønnes + +vchiq: Change logging level for inbound data --- + arch/arm/mach-bcm2708/bcm2708.c | 26 + + arch/arm/mach-bcm2708/include/mach/platform.h | 2 + + arch/arm/mach-bcm2709/bcm2709.c | 26 + + arch/arm/mach-bcm2709/include/mach/platform.h | 2 + drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/vc04_services/Kconfig | 9 + @@ -83741,9 +83435,9 @@ Signed-off-by: Pranith Kumar .../misc/vc04_services/interface/vchi/vchi_mh.h | 42 + .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 40 + .../vc04_services/interface/vchiq_arm/vchiq_2835.h | 42 + - .../interface/vchiq_arm/vchiq_2835_arm.c | 562 +++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2884 ++++++++++++++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 223 ++ + .../interface/vchiq_arm/vchiq_2835_arm.c | 547 +++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2886 ++++++++++++++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 220 ++ .../interface/vchiq_arm/vchiq_build_info.h | 37 + .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 69 + .../interface/vchiq_arm/vchiq_connected.c | 120 + @@ -83763,7 +83457,7 @@ Signed-off-by: Pranith Kumar .../vc04_services/interface/vchiq_arm/vchiq_util.c | 152 + .../vc04_services/interface/vchiq_arm/vchiq_util.h | 81 + .../interface/vchiq_arm/vchiq_version.c | 59 + - 35 files changed, 12770 insertions(+) + 39 files changed, 12810 insertions(+) create mode 100644 drivers/misc/vc04_services/Kconfig create mode 100644 drivers/misc/vc04_services/Makefile create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h @@ -83798,6 +83492,120 @@ Signed-off-by: Pranith Kumar create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 06271df..86011af 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -376,6 +376,31 @@ static struct platform_device bcm2708_vcio_device = { + }, + }; + ++static struct resource bcm2708_vchiq_resources[] = { ++ { ++ .start = ARMCTRL_0_BELL_BASE, ++ .end = ARMCTRL_0_BELL_BASE + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_DOORBELL_0, ++ .end = IRQ_ARM_DOORBELL_0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_vchiq_device = { ++ .name = "bcm2835_vchiq", ++ .id = -1, ++ .resource = bcm2708_vchiq_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), ++ .dev = { ++ .dma_mask = &vchiq_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ + #ifdef CONFIG_BCM2708_GPIO + #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" + +@@ -611,6 +636,7 @@ void __init bcm2708_init(void) + + bcm_register_device_dt(&bcm2708_dmaengine_device); + bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_vchiq_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif +diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h +index 2e7e1bb..69674e9 100644 +--- a/arch/arm/mach-bcm2708/include/mach/platform.h ++++ b/arch/arm/mach-bcm2708/include/mach/platform.h +@@ -81,6 +81,8 @@ + #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ + #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ + #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ ++#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ ++#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ + + + /* +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 0f875ff..bc1ee1c 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -396,6 +396,31 @@ static struct platform_device bcm2708_vcio_device = { + }, + }; + ++static struct resource bcm2708_vchiq_resources[] = { ++ { ++ .start = ARMCTRL_0_BELL_BASE, ++ .end = ARMCTRL_0_BELL_BASE + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_DOORBELL_0, ++ .end = IRQ_ARM_DOORBELL_0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_vchiq_device = { ++ .name = "bcm2835_vchiq", ++ .id = -1, ++ .resource = bcm2708_vchiq_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), ++ .dev = { ++ .dma_mask = &vchiq_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ + #ifdef CONFIG_BCM2708_GPIO + #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" + +@@ -631,6 +656,7 @@ void __init bcm2709_init(void) + + bcm_register_device_dt(&bcm2708_dmaengine_device); + bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_vchiq_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif +diff --git a/arch/arm/mach-bcm2709/include/mach/platform.h b/arch/arm/mach-bcm2709/include/mach/platform.h +index 7157f38..be99733 100644 +--- a/arch/arm/mach-bcm2709/include/mach/platform.h ++++ b/arch/arm/mach-bcm2709/include/mach/platform.h +@@ -81,6 +81,8 @@ + #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ + #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ + #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ ++#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ ++#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ + + + /* diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 006242c..4e6f46c3 100644 --- a/drivers/misc/Kconfig @@ -83824,13 +83632,13 @@ index 7d5c4cd..43d2ac9 100644 obj-$(CONFIG_ECHO) += echo/ diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig new file mode 100644 -index 0000000..b94e6cd +index 0000000..c5ba283 --- /dev/null +++ b/drivers/misc/vc04_services/Kconfig @@ -0,0 +1,9 @@ +config BCM2708_VCHIQ + tristate "Videocore VCHIQ" -+ depends on MACH_BCM2708 || MACH_BCM2709 ++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX + default y + help + Kernel to VideoCore communication interface for the @@ -85417,10 +85225,10 @@ index 0000000..7ea5c64 +#endif /* VCHIQ_2835_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c new file mode 100644 -index 0000000..8ec88bb +index 0000000..c739083 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -0,0 +1,562 @@ +@@ -0,0 +1,547 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -85458,23 +85266,18 @@ index 0000000..8ec88bb +#include +#include +#include -+#include +#include +#include +#include +#include ++#include ++#include +#include +#include + -+#include -+ -+#include -+#include -+ +#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + -+#define VCHIQ_DOORBELL_IRQ IRQ_ARM_DOORBELL_0 -+#define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) ++#define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset)) + +#include "vchiq_arm.h" +#include "vchiq_2835.h" @@ -85483,17 +85286,19 @@ index 0000000..8ec88bb + +#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) + ++#define BELL0 0x00 ++#define BELL2 0x08 ++ +typedef struct vchiq_2835_state_struct { + int inited; + VCHIQ_ARM_STATE_T arm_state; +} VCHIQ_2835_ARM_STATE_T; + -+static char *g_slot_mem; -+static int g_slot_mem_size; -+dma_addr_t g_slot_phys; ++static void __iomem *g_regs; +static FRAGMENTS_T *g_fragments_base; +static FRAGMENTS_T *g_free_fragments; -+struct semaphore g_free_fragments_sema; ++static struct semaphore g_free_fragments_sema; ++static unsigned long g_virt_to_bus_offset; + +extern int vchiq_arm_log_level; + @@ -85509,43 +85314,42 @@ index 0000000..8ec88bb +static void +free_pagelist(PAGELIST_T *pagelist, int actual); + -+int __init -+vchiq_platform_init(VCHIQ_STATE_T *state) ++int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) +{ ++ struct device *dev = &pdev->dev; + VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; -+ int frag_mem_size; -+ int err; -+ int i; ++ struct resource *res; ++ void *slot_mem; ++ dma_addr_t slot_phys; ++ int slot_mem_size, frag_mem_size; ++ int err, irq, i; ++ ++ g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); + + /* Allocate space for the channels in coherent memory */ -+ g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); ++ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); + frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); + -+ g_slot_mem = dma_alloc_coherent(NULL, g_slot_mem_size + frag_mem_size, -+ &g_slot_phys, GFP_KERNEL); -+ -+ if (!g_slot_mem) { -+ vchiq_log_error(vchiq_arm_log_level, -+ "Unable to allocate channel memory"); -+ err = -ENOMEM; -+ goto failed_alloc; ++ slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, ++ &slot_phys, GFP_KERNEL); ++ if (!slot_mem) { ++ dev_err(dev, "could not allocate DMA memory\n"); ++ return -ENOMEM; + } + -+ WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0); ++ WARN_ON(((int)slot_mem & (PAGE_SIZE - 1)) != 0); + -+ vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size); -+ if (!vchiq_slot_zero) { -+ err = -EINVAL; -+ goto failed_init_slots; -+ } ++ vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); ++ if (!vchiq_slot_zero) ++ return -EINVAL; + + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = -+ (int)g_slot_phys + g_slot_mem_size; ++ (int)slot_phys + slot_mem_size; + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = + MAX_FRAGMENTS; + -+ g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size); -+ g_slot_mem_size += frag_mem_size; ++ g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); ++ slot_mem_size += frag_mem_size; + + g_free_fragments = g_fragments_base; + for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { @@ -85555,54 +85359,46 @@ index 0000000..8ec88bb + *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; + sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); + -+ if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) != -+ VCHIQ_SUCCESS) { -+ err = -EINVAL; -+ goto failed_vchiq_init; ++ if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) ++ return -EINVAL; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ g_regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(g_regs)) ++ return PTR_ERR(g_regs); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(dev, "failed to get IRQ\n"); ++ return irq; + } + -+ err = request_irq(VCHIQ_DOORBELL_IRQ, vchiq_doorbell_irq, -+ IRQF_IRQPOLL, "VCHIQ doorbell", -+ state); -+ if (err < 0) { -+ vchiq_log_error(vchiq_arm_log_level, "%s: failed to register " -+ "irq=%d err=%d", __func__, -+ VCHIQ_DOORBELL_IRQ, err); -+ goto failed_request_irq; ++ err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL, ++ "VCHIQ doorbell", state); ++ if (err) { ++ dev_err(dev, "failed to register irq=%d\n", irq); ++ return err; + } + + /* Send the base address of the slots to VideoCore */ + + dsb(); /* Ensure all writes have completed */ + -+ bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys); ++ err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); ++ if (err) { ++ dev_err(dev, "mailbox write failed\n"); ++ return err; ++ } + + vchiq_log_info(vchiq_arm_log_level, -+ "vchiq_init - done (slots %x, phys %x)", -+ (unsigned int)vchiq_slot_zero, g_slot_phys); ++ "vchiq_init - done (slots %x, phys %pad)", ++ (unsigned int)vchiq_slot_zero, &slot_phys); + -+ vchiq_call_connected_callbacks(); ++ vchiq_call_connected_callbacks(); + + return 0; -+ -+failed_request_irq: -+failed_vchiq_init: -+failed_init_slots: -+ dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys); -+ -+failed_alloc: -+ return err; +} + -+void __exit -+vchiq_platform_exit(VCHIQ_STATE_T *state) -+{ -+ free_irq(VCHIQ_DOORBELL_IRQ, state); -+ dma_free_coherent(NULL, g_slot_mem_size, -+ g_slot_mem, g_slot_phys); -+} -+ -+ +VCHIQ_STATUS_T +vchiq_platform_init_state(VCHIQ_STATE_T *state) +{ @@ -85636,11 +85432,8 @@ index 0000000..8ec88bb + + dsb(); /* data barrier operation */ + -+ if (event->armed) { -+ /* trigger vc interrupt */ -+ -+ writel(0, __io_address(ARM_0_BELL2)); -+ } ++ if (event->armed) ++ writel(0, g_regs + BELL2); /* trigger vc interrupt */ +} + +int @@ -85764,7 +85557,7 @@ index 0000000..8ec88bb + unsigned int status; + + /* Read (and clear) the doorbell */ -+ status = readl(__io_address(ARM_0_BELL0)); ++ status = readl(g_regs + BELL0); + + if (status & 0x4) { /* Was the doorbell rung? */ + remote_event_pollall(state); @@ -85985,10 +85778,10 @@ index 0000000..8ec88bb +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c new file mode 100644 -index 0000000..0ad9656 +index 0000000..31e2cba --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -0,0 +1,2884 @@ +@@ -0,0 +1,2886 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -86036,6 +85829,7 @@ index 0000000..0ad9656 +#include +#include +#include ++#include + +#include "vchiq_core.h" +#include "vchiq_ioctl.h" @@ -88781,15 +88575,7 @@ index 0000000..0ad9656 + } +} + -+ -+/**************************************************************************** -+* -+* vchiq_init - called when the module is loaded. -+* -+***************************************************************************/ -+ -+static int __init -+vchiq_init(void) ++static int vchiq_probe(struct platform_device *pdev) +{ + int err; + void *ptr_err; @@ -88826,7 +88612,7 @@ index 0000000..0ad9656 + if (IS_ERR(ptr_err)) + goto failed_device_create; + -+ err = vchiq_platform_init(&g_state); ++ err = vchiq_platform_init(pdev, &g_state); + if (err != 0) + goto failed_platform_init; + @@ -88853,32 +88639,41 @@ index 0000000..0ad9656 + return err; +} + -+/**************************************************************************** -+* -+* vchiq_exit - called when the module is unloaded. -+* -+***************************************************************************/ -+ -+static void __exit -+vchiq_exit(void) ++static int vchiq_remove(struct platform_device *pdev) +{ -+ vchiq_platform_exit(&g_state); + device_destroy(vchiq_class, vchiq_devid); + class_destroy(vchiq_class); + cdev_del(&vchiq_cdev); + unregister_chrdev_region(vchiq_devid, 1); ++ ++ return 0; +} + -+module_init(vchiq_init); -+module_exit(vchiq_exit); ++static const struct of_device_id vchiq_of_match[] = { ++ { .compatible = "brcm,bcm2835-vchiq", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, vchiq_of_match); ++ ++static struct platform_driver vchiq_driver = { ++ .driver = { ++ .name = "bcm2835_vchiq", ++ .owner = THIS_MODULE, ++ .of_match_table = vchiq_of_match, ++ }, ++ .probe = vchiq_probe, ++ .remove = vchiq_remove, ++}; ++module_platform_driver(vchiq_driver); ++ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Broadcom Corporation"); diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h new file mode 100644 -index 0000000..d1e2741 +index 0000000..9740e1a --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -@@ -0,0 +1,223 @@ +@@ -0,0 +1,220 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -88917,6 +88712,7 @@ index 0000000..d1e2741 +#define VCHIQ_ARM_H + +#include ++#include +#include +#include +#include "vchiq_core.h" @@ -89009,11 +88805,7 @@ index 0000000..d1e2741 +extern int vchiq_arm_log_level; +extern int vchiq_susp_log_level; + -+extern int __init -+vchiq_platform_init(VCHIQ_STATE_T *state); -+ -+extern void __exit -+vchiq_platform_exit(VCHIQ_STATE_T *state); ++int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state); + +extern VCHIQ_STATE_T * +vchiq_get_state(void); @@ -89404,7 +89196,7 @@ index 0000000..863b3e3 +#endif /* VCHIQ_CONNECTED_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c new file mode 100644 -index 0000000..835688b +index 0000000..2c98da4 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -0,0 +1,3934 @@ @@ -91192,7 +90984,7 @@ index 0000000..835688b + service->remoteport); + break; + case VCHIQ_MSG_DATA: -+ vchiq_log_trace(vchiq_core_log_level, ++ vchiq_log_info(vchiq_core_log_level, + "%d: prs DATA@%x,%x (%d->%d)", + state->id, (unsigned int)header, size, + remoteport, localport); @@ -96789,10 +96581,1019 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From 859a7d70416a46048ab89165367891de2104ef6f Mon Sep 17 00:00:00 2001 +From 6290b45c0e5fa71d2131718d1b5770e7849aedeb Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 17 Jun 2015 16:07:06 +0100 +Subject: [PATCH 14/77] vc_mem: Add vc_mem driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: popcornmix + +BCM270x: Move vc_mem + +Make the vc_mem module available for ARCH_BCM2835 by moving it. + +Signed-off-by: Noralf Trønnes +--- + arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 --- + arch/arm/mach-bcm2709/vc_mem.c | 431 ---------------------------- + drivers/char/broadcom/Kconfig | 12 +- + drivers/char/broadcom/Makefile | 1 + + drivers/char/broadcom/vc_mem.c | 423 +++++++++++++++++++++++++++ + include/linux/broadcom/vc_mem.h | 35 +++ + 6 files changed, 470 insertions(+), 467 deletions(-) + delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h + delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c + create mode 100644 drivers/char/broadcom/vc_mem.c + create mode 100644 include/linux/broadcom/vc_mem.h + +diff --git a/arch/arm/mach-bcm2709/include/mach/vc_mem.h b/arch/arm/mach-bcm2709/include/mach/vc_mem.h +deleted file mode 100644 +index 4a4a338..0000000 +--- a/arch/arm/mach-bcm2709/include/mach/vc_mem.h ++++ /dev/null +@@ -1,35 +0,0 @@ +-/***************************************************************************** +-* Copyright 2010 - 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. +-*****************************************************************************/ +- +-#if !defined( VC_MEM_H ) +-#define VC_MEM_H +- +-#include +- +-#define VC_MEM_IOC_MAGIC 'v' +- +-#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 ) +-#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) +- +-#if defined( __KERNEL__ ) +-#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF +- +-extern unsigned long mm_vc_mem_phys_addr; +-extern unsigned int mm_vc_mem_size; +-extern int vc_mem_get_current_size( void ); +-#endif +- +-#endif /* VC_MEM_H */ +diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c +deleted file mode 100644 +index d2adfd1..0000000 +--- a/arch/arm/mach-bcm2709/vc_mem.c ++++ /dev/null +@@ -1,431 +0,0 @@ +-/***************************************************************************** +-* Copyright 2010 - 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 +- +-#ifdef CONFIG_ARCH_KONA +-#include +-#elif defined(CONFIG_ARCH_BCM2708) || defined(CONFIG_ARCH_BCM2709) +-#else +-#include +-#endif +- +-#include "mach/vc_mem.h" +- +-#define DRIVER_NAME "vc-mem" +- +-// Device (/dev) related variables +-static dev_t vc_mem_devnum = 0; +-static struct class *vc_mem_class = NULL; +-static struct cdev vc_mem_cdev; +-static int vc_mem_inited = 0; +- +-#ifdef CONFIG_DEBUG_FS +-static struct dentry *vc_mem_debugfs_entry; +-#endif +- +-/* +- * Videocore memory addresses and size +- * +- * Drivers that wish to know the videocore memory addresses and sizes should +- * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in +- * headers. This allows the other drivers to not be tied down to a a certain +- * address/size at compile time. +- * +- * In the future, the goal is to have the videocore memory virtual address and +- * size be calculated at boot time rather than at compile time. The decision of +- * where the videocore memory resides and its size would be in the hands of the +- * bootloader (and/or kernel). When that happens, the values of these variables +- * would be calculated and assigned in the init function. +- */ +-// in the 2835 VC in mapped above ARM, but ARM has full access to VC space +-unsigned long mm_vc_mem_phys_addr = 0x00000000; +-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); +- +-static uint phys_addr = 0; +-static uint mem_size = 0; +-static uint mem_base = 0; +- +- +-/**************************************************************************** +-* +-* vc_mem_open +-* +-***************************************************************************/ +- +-static int +-vc_mem_open(struct inode *inode, struct file *file) +-{ +- (void) inode; +- (void) file; +- +- pr_debug("%s: called file = 0x%p\n", __func__, file); +- +- return 0; +-} +- +-/**************************************************************************** +-* +-* vc_mem_release +-* +-***************************************************************************/ +- +-static int +-vc_mem_release(struct inode *inode, struct file *file) +-{ +- (void) inode; +- (void) file; +- +- pr_debug("%s: called file = 0x%p\n", __func__, file); +- +- return 0; +-} +- +-/**************************************************************************** +-* +-* vc_mem_get_size +-* +-***************************************************************************/ +- +-static void +-vc_mem_get_size(void) +-{ +-} +- +-/**************************************************************************** +-* +-* vc_mem_get_base +-* +-***************************************************************************/ +- +-static void +-vc_mem_get_base(void) +-{ +-} +- +-/**************************************************************************** +-* +-* vc_mem_get_current_size +-* +-***************************************************************************/ +- +-int +-vc_mem_get_current_size(void) +-{ +- return mm_vc_mem_size; +-} +- +-EXPORT_SYMBOL_GPL(vc_mem_get_current_size); +- +-/**************************************************************************** +-* +-* vc_mem_ioctl +-* +-***************************************************************************/ +- +-static long +-vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +-{ +- int rc = 0; +- +- (void) cmd; +- (void) arg; +- +- pr_debug("%s: called file = 0x%p\n", __func__, file); +- +- switch (cmd) { +- case VC_MEM_IOC_MEM_PHYS_ADDR: +- { +- pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", +- __func__, (void *) mm_vc_mem_phys_addr); +- +- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, +- sizeof (mm_vc_mem_phys_addr)) != 0) { +- rc = -EFAULT; +- } +- break; +- } +- case VC_MEM_IOC_MEM_SIZE: +- { +- // Get the videocore memory size first +- vc_mem_get_size(); +- +- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, +- mm_vc_mem_size); +- +- if (copy_to_user((void *) arg, &mm_vc_mem_size, +- sizeof (mm_vc_mem_size)) != 0) { +- rc = -EFAULT; +- } +- break; +- } +- case VC_MEM_IOC_MEM_BASE: +- { +- // Get the videocore memory base +- vc_mem_get_base(); +- +- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, +- mm_vc_mem_base); +- +- if (copy_to_user((void *) arg, &mm_vc_mem_base, +- sizeof (mm_vc_mem_base)) != 0) { +- rc = -EFAULT; +- } +- break; +- } +- case VC_MEM_IOC_MEM_LOAD: +- { +- // Get the videocore memory base +- vc_mem_get_base(); +- +- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: +- { +- return -ENOTTY; +- } +- } +- pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); +- +- return rc; +-} +- +-/**************************************************************************** +-* +-* vc_mem_mmap +-* +-***************************************************************************/ +- +-static int +-vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) +-{ +- int rc = 0; +- unsigned long length = vma->vm_end - vma->vm_start; +- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; +- +- pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", +- __func__, (long) vma->vm_start, (long) vma->vm_end, +- (long) vma->vm_pgoff); +- +- if (offset + length > mm_vc_mem_size) { +- pr_err("%s: length %ld is too big\n", __func__, length); +- return -EINVAL; +- } +- // Do not cache the memory map +- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +- +- rc = remap_pfn_range(vma, vma->vm_start, +- (mm_vc_mem_phys_addr >> PAGE_SHIFT) + +- vma->vm_pgoff, length, vma->vm_page_prot); +- if (rc != 0) { +- pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); +- } +- +- return rc; +-} +- +-/**************************************************************************** +-* +-* File Operations for the driver. +-* +-***************************************************************************/ +- +-static const struct file_operations vc_mem_fops = { +- .owner = THIS_MODULE, +- .open = vc_mem_open, +- .release = vc_mem_release, +- .unlocked_ioctl = vc_mem_ioctl, +- .mmap = vc_mem_mmap, +-}; +- +-#ifdef CONFIG_DEBUG_FS +-static void vc_mem_debugfs_deinit(void) +-{ +- debugfs_remove_recursive(vc_mem_debugfs_entry); +- vc_mem_debugfs_entry = NULL; +-} +- +- +-static int vc_mem_debugfs_init( +- struct device *dev) +-{ +- vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); +- if (!vc_mem_debugfs_entry) { +- dev_warn(dev, "could not create debugfs entry\n"); +- return -EFAULT; +- } +- +- if (!debugfs_create_x32("vc_mem_phys_addr", +- 0444, +- vc_mem_debugfs_entry, +- (u32 *)&mm_vc_mem_phys_addr)) { +- dev_warn(dev, "%s:could not create vc_mem_phys entry\n", +- __func__); +- goto fail; +- } +- +- if (!debugfs_create_x32("vc_mem_size", +- 0444, +- vc_mem_debugfs_entry, +- (u32 *)&mm_vc_mem_size)) { +- dev_warn(dev, "%s:could not create vc_mem_size entry\n", +- __func__); +- goto fail; +- } +- +- if (!debugfs_create_x32("vc_mem_base", +- 0444, +- vc_mem_debugfs_entry, +- (u32 *)&mm_vc_mem_base)) { +- dev_warn(dev, "%s:could not create vc_mem_base entry\n", +- __func__); +- goto fail; +- } +- +- return 0; +- +-fail: +- vc_mem_debugfs_deinit(); +- return -EFAULT; +-} +- +-#endif /* CONFIG_DEBUG_FS */ +- +- +-/**************************************************************************** +-* +-* vc_mem_init +-* +-***************************************************************************/ +- +-static int __init +-vc_mem_init(void) +-{ +- int rc = -EFAULT; +- struct device *dev; +- +- pr_debug("%s: called\n", __func__); +- +- mm_vc_mem_phys_addr = phys_addr; +- mm_vc_mem_size = mem_size; +- mm_vc_mem_base = mem_base; +- +- vc_mem_get_size(); +- +- pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", +- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); +- +- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { +- pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", +- __func__, rc); +- goto out_err; +- } +- +- cdev_init(&vc_mem_cdev, &vc_mem_fops); +- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { +- pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); +- goto out_unregister; +- } +- +- vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); +- if (IS_ERR(vc_mem_class)) { +- rc = PTR_ERR(vc_mem_class); +- pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); +- goto out_cdev_del; +- } +- +- dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, +- DRIVER_NAME); +- if (IS_ERR(dev)) { +- rc = PTR_ERR(dev); +- pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); +- goto out_class_destroy; +- } +- +-#ifdef CONFIG_DEBUG_FS +- /* don't fail if the debug entries cannot be created */ +- vc_mem_debugfs_init(dev); +-#endif +- +- vc_mem_inited = 1; +- return 0; +- +- device_destroy(vc_mem_class, vc_mem_devnum); +- +- out_class_destroy: +- class_destroy(vc_mem_class); +- vc_mem_class = NULL; +- +- out_cdev_del: +- cdev_del(&vc_mem_cdev); +- +- out_unregister: +- unregister_chrdev_region(vc_mem_devnum, 1); +- +- out_err: +- return -1; +-} +- +-/**************************************************************************** +-* +-* vc_mem_exit +-* +-***************************************************************************/ +- +-static void __exit +-vc_mem_exit(void) +-{ +- pr_debug("%s: called\n", __func__); +- +- if (vc_mem_inited) { +-#if CONFIG_DEBUG_FS +- vc_mem_debugfs_deinit(); +-#endif +- device_destroy(vc_mem_class, vc_mem_devnum); +- class_destroy(vc_mem_class); +- cdev_del(&vc_mem_cdev); +- unregister_chrdev_region(vc_mem_devnum, 1); +- } +-} +- +-module_init(vc_mem_init); +-module_exit(vc_mem_exit); +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Broadcom Corporation"); +- +-module_param(phys_addr, uint, 0644); +-module_param(mem_size, uint, 0644); +-module_param(mem_base, uint, 0644); +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index 2d8bd6e..7037928 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -7,9 +7,19 @@ menuconfig BRCM_CHAR_DRIVERS + help + Broadcom's char drivers + ++if BRCM_CHAR_DRIVERS ++ + config BCM_VC_CMA + bool "Videocore CMA" +- depends on CMA && BRCM_CHAR_DRIVERS && BCM2708_VCHIQ ++ depends on CMA && BCM2708_VCHIQ + default n + help + Helper for videocore CMA access. ++ ++config BCM2708_VCMEM ++ bool "Videocore Memory" ++ default y ++ help ++ Helper for videocore memory access and total size allocation. ++ ++endif +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index 13c5bca..fce918c 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -1 +1,2 @@ + obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ ++obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o +diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c +new file mode 100644 +index 0000000..fcde6b1 +--- /dev/null ++++ b/drivers/char/broadcom/vc_mem.c +@@ -0,0 +1,423 @@ ++/***************************************************************************** ++* Copyright 2010 - 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 ++ ++#define DRIVER_NAME "vc-mem" ++ ++// Device (/dev) related variables ++static dev_t vc_mem_devnum = 0; ++static struct class *vc_mem_class = NULL; ++static struct cdev vc_mem_cdev; ++static int vc_mem_inited = 0; ++ ++#ifdef CONFIG_DEBUG_FS ++static struct dentry *vc_mem_debugfs_entry; ++#endif ++ ++/* ++ * Videocore memory addresses and size ++ * ++ * Drivers that wish to know the videocore memory addresses and sizes should ++ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in ++ * headers. This allows the other drivers to not be tied down to a a certain ++ * address/size at compile time. ++ * ++ * In the future, the goal is to have the videocore memory virtual address and ++ * size be calculated at boot time rather than at compile time. The decision of ++ * where the videocore memory resides and its size would be in the hands of the ++ * bootloader (and/or kernel). When that happens, the values of these variables ++ * would be calculated and assigned in the init function. ++ */ ++// in the 2835 VC in mapped above ARM, but ARM has full access to VC space ++unsigned long mm_vc_mem_phys_addr = 0x00000000; ++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); ++ ++static uint phys_addr = 0; ++static uint mem_size = 0; ++static uint mem_base = 0; ++ ++ ++/**************************************************************************** ++* ++* vc_mem_open ++* ++***************************************************************************/ ++ ++static int ++vc_mem_open(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_release ++* ++***************************************************************************/ ++ ++static int ++vc_mem_release(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_size ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_size(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_base ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_base(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_current_size ++* ++***************************************************************************/ ++ ++int ++vc_mem_get_current_size(void) ++{ ++ return mm_vc_mem_size; ++} ++ ++EXPORT_SYMBOL_GPL(vc_mem_get_current_size); ++ ++/**************************************************************************** ++* ++* vc_mem_ioctl ++* ++***************************************************************************/ ++ ++static long ++vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int rc = 0; ++ ++ (void) cmd; ++ (void) arg; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ switch (cmd) { ++ case VC_MEM_IOC_MEM_PHYS_ADDR: ++ { ++ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", ++ __func__, (void *) mm_vc_mem_phys_addr); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, ++ sizeof (mm_vc_mem_phys_addr)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_SIZE: ++ { ++ // Get the videocore memory size first ++ vc_mem_get_size(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, ++ mm_vc_mem_size); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_size, ++ sizeof (mm_vc_mem_size)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_BASE: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_LOAD: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: ++ { ++ return -ENOTTY; ++ } ++ } ++ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_mmap ++* ++***************************************************************************/ ++ ++static int ++vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ int rc = 0; ++ unsigned long length = vma->vm_end - vma->vm_start; ++ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ ++ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", ++ __func__, (long) vma->vm_start, (long) vma->vm_end, ++ (long) vma->vm_pgoff); ++ ++ if (offset + length > mm_vc_mem_size) { ++ pr_err("%s: length %ld is too big\n", __func__, length); ++ return -EINVAL; ++ } ++ // Do not cache the memory map ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ rc = remap_pfn_range(vma, vma->vm_start, ++ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + ++ vma->vm_pgoff, length, vma->vm_page_prot); ++ if (rc != 0) { ++ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); ++ } ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* File Operations for the driver. ++* ++***************************************************************************/ ++ ++static const struct file_operations vc_mem_fops = { ++ .owner = THIS_MODULE, ++ .open = vc_mem_open, ++ .release = vc_mem_release, ++ .unlocked_ioctl = vc_mem_ioctl, ++ .mmap = vc_mem_mmap, ++}; ++ ++#ifdef CONFIG_DEBUG_FS ++static void vc_mem_debugfs_deinit(void) ++{ ++ debugfs_remove_recursive(vc_mem_debugfs_entry); ++ vc_mem_debugfs_entry = NULL; ++} ++ ++ ++static int vc_mem_debugfs_init( ++ struct device *dev) ++{ ++ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); ++ if (!vc_mem_debugfs_entry) { ++ dev_warn(dev, "could not create debugfs entry\n"); ++ return -EFAULT; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_phys_addr", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_phys_addr)) { ++ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_size", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_size)) { ++ dev_warn(dev, "%s:could not create vc_mem_size entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_base", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_base)) { ++ dev_warn(dev, "%s:could not create vc_mem_base entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ vc_mem_debugfs_deinit(); ++ return -EFAULT; ++} ++ ++#endif /* CONFIG_DEBUG_FS */ ++ ++ ++/**************************************************************************** ++* ++* vc_mem_init ++* ++***************************************************************************/ ++ ++static int __init ++vc_mem_init(void) ++{ ++ int rc = -EFAULT; ++ struct device *dev; ++ ++ pr_debug("%s: called\n", __func__); ++ ++ mm_vc_mem_phys_addr = phys_addr; ++ mm_vc_mem_size = mem_size; ++ mm_vc_mem_base = mem_base; ++ ++ vc_mem_get_size(); ++ ++ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", ++ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); ++ ++ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { ++ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", ++ __func__, rc); ++ goto out_err; ++ } ++ ++ cdev_init(&vc_mem_cdev, &vc_mem_fops); ++ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { ++ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); ++ goto out_unregister; ++ } ++ ++ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); ++ if (IS_ERR(vc_mem_class)) { ++ rc = PTR_ERR(vc_mem_class); ++ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); ++ goto out_cdev_del; ++ } ++ ++ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, ++ DRIVER_NAME); ++ if (IS_ERR(dev)) { ++ rc = PTR_ERR(dev); ++ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); ++ goto out_class_destroy; ++ } ++ ++#ifdef CONFIG_DEBUG_FS ++ /* don't fail if the debug entries cannot be created */ ++ vc_mem_debugfs_init(dev); ++#endif ++ ++ vc_mem_inited = 1; ++ return 0; ++ ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ ++ out_class_destroy: ++ class_destroy(vc_mem_class); ++ vc_mem_class = NULL; ++ ++ out_cdev_del: ++ cdev_del(&vc_mem_cdev); ++ ++ out_unregister: ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ ++ out_err: ++ return -1; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_exit ++* ++***************************************************************************/ ++ ++static void __exit ++vc_mem_exit(void) ++{ ++ pr_debug("%s: called\n", __func__); ++ ++ if (vc_mem_inited) { ++#if CONFIG_DEBUG_FS ++ vc_mem_debugfs_deinit(); ++#endif ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ class_destroy(vc_mem_class); ++ cdev_del(&vc_mem_cdev); ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ } ++} ++ ++module_init(vc_mem_init); ++module_exit(vc_mem_exit); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Broadcom Corporation"); ++ ++module_param(phys_addr, uint, 0644); ++module_param(mem_size, uint, 0644); ++module_param(mem_base, uint, 0644); +diff --git a/include/linux/broadcom/vc_mem.h b/include/linux/broadcom/vc_mem.h +new file mode 100644 +index 0000000..20a4753 +--- /dev/null ++++ b/include/linux/broadcom/vc_mem.h +@@ -0,0 +1,35 @@ ++/***************************************************************************** ++* Copyright 2010 - 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_MEM_H ++#define _VC_MEM_H ++ ++#include ++ ++#define VC_MEM_IOC_MAGIC 'v' ++ ++#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 ) ++#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) ++ ++#if defined( __KERNEL__ ) ++#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF ++ ++extern unsigned long mm_vc_mem_phys_addr; ++extern unsigned int mm_vc_mem_size; ++extern int vc_mem_get_current_size( void ); ++#endif ++ ++#endif /* _VC_MEM_H */ + +From e9ebded52208b6164753a82d268cd80e833e2737 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 012/216] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 15/77] vcsm: VideoCore shared memory service for BCM2835 Add experimental support for the VideoCore shared memory service. This allows user processes to allocate memory from VideoCore's @@ -96823,17 +97624,19 @@ On building the bcm_vc_sm as a module we get the following error: v7_dma_flush_range and do_munmap are undefined in vc-sm.ko. Fix by making it not an option to build as module + +vcsm: Add ioctl for custom cache flushing --- arch/arm/mach-bcm2708/include/mach/vc_sm_defs.h | 181 ++ arch/arm/mach-bcm2708/include/mach/vc_sm_knl.h | 55 + arch/arm/mach-bcm2708/include/mach/vc_vchi_sm.h | 82 + - arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h | 233 ++ - drivers/char/broadcom/Kconfig | 7 + + arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h | 248 ++ + drivers/char/broadcom/Kconfig | 9 + drivers/char/broadcom/Makefile | 1 + drivers/char/broadcom/vc_sm/Makefile | 21 + drivers/char/broadcom/vc_sm/vc_vchi_sm.c | 492 +++ - drivers/char/broadcom/vc_sm/vmcs_sm.c | 3163 ++++++++++++++++++++ - 9 files changed, 4235 insertions(+) + drivers/char/broadcom/vc_sm/vmcs_sm.c | 3211 ++++++++++++++++++++ + 9 files changed, 4300 insertions(+) create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_sm_defs.h create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_sm_knl.h create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_vchi_sm.h @@ -97180,10 +97983,10 @@ index 0000000..5e279f5 +#endif /* __VC_VCHI_SM_H__INCLUDED__ */ diff --git a/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h new file mode 100644 -index 0000000..42d0eb0 +index 0000000..334f36d --- /dev/null +++ b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -@@ -0,0 +1,233 @@ +@@ -0,0 +1,248 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -97247,6 +98050,8 @@ index 0000000..42d0eb0 + VMCS_SM_CMD_HOST_WALK_PID_ALLOC, + VMCS_SM_CMD_HOST_WALK_PID_MAP, + ++ VMCS_SM_CMD_CLEAN_INVALID, ++ + VMCS_SM_CMD_LAST /* Do no delete */ +}; + @@ -97349,6 +98154,16 @@ index 0000000..42d0eb0 + unsigned int size; +}; + ++struct vmcs_sm_ioctl_clean_invalid { ++ /* user -> kernel */ ++ struct { ++ unsigned int cmd; ++ unsigned int handle; ++ unsigned int addr; ++ unsigned int size; ++ } s[8]; ++}; ++ +/* IOCTL numbers */ +#define VMCS_SM_IOCTL_MEM_ALLOC\ + _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_ALLOC,\ @@ -97377,6 +98192,9 @@ index 0000000..42d0eb0 +#define VMCS_SM_IOCTL_MEM_INVALID\ + _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\ + struct vmcs_sm_ioctl_cache) ++#define VMCS_SM_IOCTL_MEM_CLEAN_INVALID\ ++ _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_CLEAN_INVALID,\ ++ struct vmcs_sm_ioctl_clean_invalid) + +#define VMCS_SM_IOCTL_SIZE_USR_HDL\ + _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\ @@ -97418,26 +98236,29 @@ index 0000000..42d0eb0 + +#endif /* __VMCS_SM_IOCTL_H__INCLUDED__ */ diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index 2d8bd6e..fd23e00 100644 +index 7037928..75fa1cb 100644 --- a/drivers/char/broadcom/Kconfig +++ b/drivers/char/broadcom/Kconfig -@@ -13,3 +13,10 @@ config BCM_VC_CMA - default n - help - Helper for videocore CMA access. +@@ -23,3 +23,12 @@ config BCM2708_VCMEM + Helper for videocore memory access and total size allocation. + + endif + +config BCM_VC_SM + bool "VMCS Shared Memory" ++ depends on BCM2708_VCHIQ ++ select BCM2708_VCMEM + default n + help + Support for the VC shared memory on the Broadcom reference + design. Uses the VCHIQ stack. diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 13c5bca..0bf7fdf 100644 +index fce918c..de8feb9 100644 --- a/drivers/char/broadcom/Makefile +++ b/drivers/char/broadcom/Makefile -@@ -1 +1,2 @@ +@@ -1,2 +1,3 @@ obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ + obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o +obj-$(CONFIG_BCM_VC_SM) += vc_sm/ diff --git a/drivers/char/broadcom/vc_sm/Makefile b/drivers/char/broadcom/vc_sm/Makefile new file mode 100644 @@ -97966,10 +98787,10 @@ index 0000000..7c6ba1a +} diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c new file mode 100644 -index 0000000..da1c523 +index 0000000..0bfb42e --- /dev/null +++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -0,0 +1,3163 @@ +@@ -0,0 +1,3211 @@ +/***************************************************************************** +* Copyright 2011-2012 Broadcom Corporation. All rights reserved. +* @@ -97987,6 +98808,7 @@ index 0000000..da1c523 +/* ---- Include Files ----------------------------------------------------- */ + +#include ++#include +#include +#include +#include @@ -98007,8 +98829,6 @@ index 0000000..da1c523 +#include +#include + -+#include -+ +#include "vchiq_connected.h" +#include "vc_vchi_sm.h" + @@ -100704,6 +101524,55 @@ index 0000000..da1c523 + } + break; + ++ /* Flush/Invalidate the cache for a given mapping. */ ++ case VMCS_SM_CMD_CLEAN_INVALID: ++ { ++ int i; ++ struct vmcs_sm_ioctl_clean_invalid ioparam; ++ ++ /* Get parameter data. */ ++ if (copy_from_user(&ioparam, ++ (void *)arg, sizeof(ioparam)) != 0) { ++ pr_err("[%s]: failed to copy-from-user for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ goto out; ++ } ++ for (i=0; ires_cached) { ++ unsigned long base = ioparam.s[i].addr & ~(PAGE_SIZE-1); ++ unsigned long end = (ioparam.s[i].addr + ioparam.s[i].size + PAGE_SIZE-1) & ~(PAGE_SIZE-1); ++ resource->res_stats[ioparam.s[i].cmd == 1 ? INVALID:FLUSH]++; ++ ++ /* L1/L2 cache flush */ ++ down_read(¤t->mm->mmap_sem); ++ vcsm_vma_cache_clean_page_range(base, end); ++ up_read(¤t->mm->mmap_sem); ++ } else if (resource == NULL) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (resource) ++ vmcs_sm_release_resource(resource, 0); ++ } ++ break; ++ } ++ } ++ } ++ break; ++ + default: + { + ret = -EINVAL; @@ -101134,23 +102003,32 @@ index 0000000..da1c523 +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); -From 103cb0411fad640ec86640f3fda90a3da782aa68 Mon Sep 17 00:00:00 2001 +From 7f769de038003dcf3f6eff180e2e295888789dc2 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:51:55 +0100 -Subject: [PATCH 013/216] Add hwrng (hardware random number generator) driver +Subject: [PATCH 16/77] Add hwrng (hardware random number generator) driver --- - drivers/char/hw_random/Kconfig | 11 ++++ + drivers/char/hw_random/Kconfig | 13 +++- drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/bcm2708-rng.c | 118 +++++++++++++++++++++++++++++++++++ - 3 files changed, 130 insertions(+) + 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100755 drivers/char/hw_random/bcm2708-rng.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index de57b38..1c97093 100644 +index f48cf11..70f9613 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig -@@ -320,6 +320,17 @@ config HW_RANDOM_TPM +@@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX + + config HW_RANDOM_BCM2835 + tristate "Broadcom BCM2835 Random Number Generator support" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the Random Number +@@ -333,6 +333,17 @@ config HW_RANDOM_TPM If unsure, say Y. @@ -101169,16 +102047,17 @@ index de57b38..1c97093 100644 tristate "Qualcomm SoCs Random Number Generator support" depends on HW_RANDOM && ARCH_QCOM diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile -index 0b4cd57..78b019c 100644 +index 055bb01..36be864 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile -@@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o - obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o - obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o - obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o +@@ -4,6 +4,7 @@ + + obj-$(CONFIG_HW_RANDOM) += rng-core.o + rng-core-y := core.o +obj-$(CONFIG_HW_RANDOM_BCM2708) += bcm2708-rng.o - obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o - obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o + obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o + obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o + obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o diff --git a/drivers/char/hw_random/bcm2708-rng.c b/drivers/char/hw_random/bcm2708-rng.c new file mode 100755 index 0000000..340f004 @@ -101304,10 +102183,10 @@ index 0000000..340f004 +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL and additional rights"); -From 4e3072cbb7ce07057d091188fc1a3897e3169007 Mon Sep 17 00:00:00 2001 +From 68990b28334ea63cdc56bfe9663025dade9d7822 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 014/216] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 17/77] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -101344,11 +102223,19 @@ read_current_timer isn't guaranteed to return values in microseconds, and indeed it doesn't on a Pi2. Issue: linux#827 + +lirc-rpi: Add device tree support, and a suitable overlay + +The overlay supports DT parameters that match the old module +parameters, except that gpio_in_pull should be set using the +strings "up", "down" or "off". + +lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode --- drivers/staging/media/lirc/Kconfig | 6 + drivers/staging/media/lirc/Makefile | 1 + - drivers/staging/media/lirc/lirc_rpi.c | 667 ++++++++++++++++++++++++++++++++++ - 3 files changed, 674 insertions(+) + drivers/staging/media/lirc/lirc_rpi.c | 765 ++++++++++++++++++++++++++++++++++ + 3 files changed, 772 insertions(+) create mode 100644 drivers/staging/media/lirc/lirc_rpi.c diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig @@ -101382,10 +102269,10 @@ index 5430adf..9e53cd0 100644 obj-$(CONFIG_LIRC_SIR) += lirc_sir.o diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c new file mode 100644 -index 0000000..8aa452d +index 0000000..24563ec --- /dev/null +++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -0,0 +1,667 @@ +@@ -0,0 +1,765 @@ +/* + * lirc_rpi.c + * @@ -101429,6 +102316,7 @@ index 0000000..8aa452d +#include +#include +#include ++#include + +#include + @@ -101691,32 +102579,117 @@ index 0000000..8aa452d + return 0; +} + ++static inline int read_bool_property(const struct device_node *np, ++ const char *propname, ++ bool *out_value) ++{ ++ u32 value = 0; ++ int err = of_property_read_u32(np, propname, &value); ++ if (err == 0) ++ *out_value = (value != 0); ++ return err; ++} ++ ++static void read_pin_settings(struct device_node *node) ++{ ++ u32 pin; ++ int index; ++ ++ for (index = 0; ++ of_property_read_u32_index( ++ node, ++ "brcm,pins", ++ index, ++ &pin) == 0; ++ index++) { ++ u32 function; ++ int err; ++ err = of_property_read_u32_index( ++ node, ++ "brcm,function", ++ index, ++ &function); ++ if (err == 0) { ++ if (function == 1) /* Output */ ++ gpio_out_pin = pin; ++ else if (function == 0) /* Input */ ++ gpio_in_pin = pin; ++ } ++ } ++} ++ +static int init_port(void) +{ + int i, nlow, nhigh, ret; ++ struct device_node *node; ++ ++ node = lirc_rpi_dev->dev.of_node; + + gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); + -+ if (!gpiochip) ++ /* ++ * Because of the lack of a setpull function, only support ++ * pinctrl-bcm2835 if using device tree. ++ */ ++ if (!gpiochip && node) ++ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); ++ ++ if (!gpiochip) { ++ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); + return -ENODEV; -+ -+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_out_pin); -+ ret = -ENODEV; -+ goto exit_init_port; + } + -+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_in_pin); -+ ret = -ENODEV; -+ goto exit_gpio_free_out_pin; ++ if (node) { ++ struct device_node *pins_node; ++ ++ pins_node = of_parse_phandle(node, "pinctrl-0", 0); ++ if (!pins_node) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": pinctrl settings not found!\n"); ++ ret = -EINVAL; ++ goto exit_init_port; ++ } ++ ++ read_pin_settings(pins_node); ++ ++ of_property_read_u32(node, "rpi,sense", &sense); ++ ++ read_bool_property(node, "rpi,softcarrier", &softcarrier); ++ ++ read_bool_property(node, "rpi,invert", &invert); ++ ++ read_bool_property(node, "rpi,debug", &debug); ++ ++ } ++ else ++ { ++ if (gpio_in_pin >= BCM2708_NR_GPIOS || ++ gpio_out_pin >= BCM2708_NR_GPIOS) { ++ ret = -EINVAL; ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": invalid GPIO pin(s) specified!\n"); ++ goto exit_init_port; ++ } ++ ++ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { ++ printk(KERN_ALERT LIRC_DRIVER_NAME ++ ": cant claim gpio pin %d\n", gpio_out_pin); ++ ret = -ENODEV; ++ goto exit_init_port; ++ } ++ ++ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { ++ printk(KERN_ALERT LIRC_DRIVER_NAME ++ ": cant claim gpio pin %d\n", gpio_in_pin); ++ ret = -ENODEV; ++ goto exit_gpio_free_out_pin; ++ } ++ ++ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); ++ gpiochip->direction_input(gpiochip, gpio_in_pin); ++ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); + } + -+ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); -+ gpiochip->direction_input(gpiochip, gpio_in_pin); -+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); + gpiochip->set(gpiochip, gpio_out_pin, invert); + + irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); @@ -101910,15 +102883,23 @@ index 0000000..8aa452d + .owner = THIS_MODULE, +}; + ++static const struct of_device_id lirc_rpi_of_match[] = { ++ { .compatible = "rpi,lirc-rpi", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, lirc_rpi_of_match); ++ +static struct platform_driver lirc_rpi_driver = { + .driver = { + .name = LIRC_DRIVER_NAME, + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(lirc_rpi_of_match), + }, +}; + +static int __init lirc_rpi_init(void) +{ ++ struct device_node *node; + int result; + + /* Init read buffer. */ @@ -101933,15 +102914,26 @@ index 0000000..8aa452d + goto exit_buffer_free; + } + -+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); -+ if (!lirc_rpi_dev) { -+ result = -ENOMEM; -+ goto exit_driver_unregister; -+ } ++ node = of_find_compatible_node(NULL, NULL, ++ lirc_rpi_of_match[0].compatible); + -+ result = platform_device_add(lirc_rpi_dev); -+ if (result) -+ goto exit_device_put; ++ if (node) { ++ /* DT-enabled */ ++ lirc_rpi_dev = of_find_device_by_node(node); ++ WARN_ON(lirc_rpi_dev->dev.of_node != node); ++ of_node_put(node); ++ } ++ else { ++ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); ++ if (!lirc_rpi_dev) { ++ result = -ENOMEM; ++ goto exit_driver_unregister; ++ } ++ ++ result = platform_device_add(lirc_rpi_dev); ++ if (result) ++ goto exit_device_put; ++ } + + return 0; + @@ -101973,13 +102965,6 @@ index 0000000..8aa452d + if (result) + return result; + -+ if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) { -+ result = -EINVAL; -+ printk(KERN_ERR LIRC_DRIVER_NAME -+ ": invalid GPIO pin(s) specified!\n"); -+ goto exit_rpi; -+ } -+ + result = init_port(); + if (result < 0) + goto exit_rpi; @@ -102054,40 +103039,29 @@ index 0000000..8aa452d +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -From 123948742379f19e1c2764020d8c523d445550bf Mon Sep 17 00:00:00 2001 +From b359d4ff9144f1ee3f333eee7b49bab1c6d92c1f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 015/216] Add cpufreq driver +Subject: [PATCH 18/77] Add cpufreq driver +Signed-off-by: popcornmix --- - arch/arm/Kconfig | 1 + - drivers/cpufreq/Kconfig.arm | 8 ++ + drivers/cpufreq/Kconfig.arm | 9 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/bcm2835-cpufreq.c | 224 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 234 insertions(+) - create mode 100755 drivers/cpufreq/bcm2835-cpufreq.c + 3 files changed, 234 insertions(+) + create mode 100644 drivers/cpufreq/bcm2835-cpufreq.c -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index ee1bb5e..9fcd395 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -378,6 +378,7 @@ config ARCH_BCM2708 - select NEED_MACH_GPIO_H - select NEED_MACH_MEMORY_H - select CLKDEV_LOOKUP -+ select ARCH_HAS_CPUFREQ - select GENERIC_CLOCKEVENTS - select ARM_ERRATA_411920 - select MACH_BCM2708 diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index 1b06fc4..0b90de8 100644 +index 4f3dbc8..a1039f0 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm -@@ -249,6 +249,14 @@ config ARM_SPEAR_CPUFREQ +@@ -258,6 +258,15 @@ config ARM_SPEAR_CPUFREQ help This adds the CPUFreq driver support for SPEAr SOCs. +config ARM_BCM2835_CPUFREQ ++ depends on BCM2708_MBOX + bool "BCM2835 Driver" + default y + help @@ -102099,10 +103073,10 @@ index 1b06fc4..0b90de8 100644 bool "TEGRA CPUFreq support" depends on ARCH_TEGRA diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 82a1821..50b1954 100644 +index cdce92a..c420f3f 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile -@@ -76,6 +76,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o +@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o @@ -102111,8 +103085,8 @@ index 82a1821..50b1954 100644 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c -new file mode 100755 -index 0000000..447ca09 +new file mode 100644 +index 0000000..6735da9 --- /dev/null +++ b/drivers/cpufreq/bcm2835-cpufreq.c @@ -0,0 +1,224 @@ @@ -102144,7 +103118,7 @@ index 0000000..447ca09 +#include +#include +#include -+#include ++#include + +/* ---------- DEFINES ---------- */ +/*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ @@ -102341,36 +103315,39 @@ index 0000000..447ca09 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From f563316302e117df98e91a8e1366dae653094f04 Mon Sep 17 00:00:00 2001 +From 37e551cc949ea14042539b089e08df475bab0f59 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 016/216] Added hwmon/thermal driver for reporting core +Subject: [PATCH 19/77] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +BCM270x: Move thermal sensor to Device Tree + +Add Device Tree support to bcm2835-thermal driver. +Add thermal sensor device to Device Tree. +Don't add platform device when booting in DT mode. + +Signed-off-by: Noralf Trønnes --- - arch/arm/mach-bcm2708/bcm2708.c | 11 ++ - drivers/hwmon/Kconfig | 10 ++ - drivers/hwmon/Makefile | 1 + - drivers/hwmon/bcm2835-hwmon.c | 219 ++++++++++++++++++++++++++++++++++++++ - drivers/thermal/Kconfig | 6 ++ + arch/arm/mach-bcm2708/bcm2708.c | 6 ++ + arch/arm/mach-bcm2709/bcm2709.c | 6 ++ + drivers/thermal/Kconfig | 7 ++ drivers/thermal/Makefile | 1 + - drivers/thermal/bcm2835-thermal.c | 184 ++++++++++++++++++++++++++++++++ - 7 files changed, 432 insertions(+) - create mode 100644 drivers/hwmon/bcm2835-hwmon.c + drivers/thermal/bcm2835-thermal.c | 190 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 210 insertions(+) create mode 100644 drivers/thermal/bcm2835-thermal.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index f54e3e9b..bae8ba5 100644 +index 86011af..f2d9b03 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -499,6 +499,14 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -505,6 +505,10 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; -+static struct platform_device bcm2835_hwmon_device = { -+ .name = "bcm2835_hwmon", -+}; -+ +static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", +}; @@ -102378,283 +103355,49 @@ index f54e3e9b..bae8ba5 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -611,6 +619,9 @@ void __init bcm2708_init(void) +@@ -651,6 +655,8 @@ void __init bcm2708_init(void) for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device(&bcm2708_alsa_devices[i]); + bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ bcm_register_device(&bcm2835_hwmon_device); -+ bcm_register_device(&bcm2835_thermal_device); ++ bcm_register_device_dt(&bcm2835_thermal_device); + - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 110fade..8c4474d 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -1703,6 +1703,16 @@ config SENSORS_ULTRA45 - This driver provides support for the Ultra45 workstation environmental - sensors. + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index bc1ee1c..9631bdb 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -525,6 +525,10 @@ static struct platform_device bcm2708_alsa_devices[] = { + }, + }; -+config SENSORS_BCM2835 -+ depends on THERMAL_BCM2835=n -+ tristate "Broadcom BCM2835 HWMON Driver" -+ help -+ If you say yes here you get support for the hardware -+ monitoring features of the BCM2835 Chip ++static struct platform_device bcm2835_thermal_device = { ++ .name = "bcm2835_thermal", ++}; + -+ This driver can also be built as a module. If so, the module -+ will be called bcm2835-hwmon. -+ - if ACPI + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -671,6 +675,8 @@ void __init bcm2709_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device_dt(&bcm2708_alsa_devices[i]); - comment "ACPI drivers" -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index 6c94147..e7c60cb 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -155,6 +155,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o - obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o - obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o - obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o -+obj-$(CONFIG_SENSORS_BCM2835) += bcm2835-hwmon.o - - obj-$(CONFIG_PMBUS) += pmbus/ - -diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c -new file mode 100644 -index 0000000..5bbed45 ---- /dev/null -+++ b/drivers/hwmon/bcm2835-hwmon.c -@@ -0,0 +1,219 @@ -+/***************************************************************************** -+* 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. -+*****************************************************************************/ ++ bcm_register_device_dt(&bcm2835_thermal_device); + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MODULE_NAME "bcm2835_hwmon" -+ -+/*#define HWMON_DEBUG_ENABLE*/ -+ -+#ifdef HWMON_DEBUG_ENABLE -+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) -+#else -+#define print_debug(fmt,...) -+#endif -+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) -+#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__) -+ -+#define VC_TAG_GET_TEMP 0x00030006 -+#define VC_TAG_GET_MAX_TEMP 0x0003000A -+ -+/* --- STRUCTS --- */ -+struct bcm2835_hwmon_data { -+ struct device *hwmon_dev; -+}; -+ -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the tag ID for the temperature */ -+ uint32_t buffer_size; /* size of the buffer (should be 8) */ -+ uint32_t request_code; /* identifies message as a request (should be 0) */ -+ uint32_t id; /* extra ID field (should be 0) */ -+ uint32_t val; /* returned value of the temperature */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ -+typedef enum { -+ TEMP, -+ MAX_TEMP, -+} temp_type; -+ -+/* --- PROTOTYPES --- */ -+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf); -+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf); -+ -+/* --- GLOBALS --- */ -+ -+static struct bcm2835_hwmon_data *bcm2835_data; -+static struct platform_driver bcm2835_hwmon_driver; -+ -+static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0); -+static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP); -+static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP); -+ -+static struct attribute* bcm2835_attributes[] = { -+ &sensor_dev_attr_name.dev_attr.attr, -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp1_max.dev_attr.attr, -+ NULL, -+}; -+ -+static struct attribute_group bcm2835_attr_group = { -+ .attrs = bcm2835_attributes, -+}; -+ -+/* --- FUNCTIONS --- */ -+ -+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf,"bcm2835_hwmon\n"); -+} -+ -+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct vc_msg msg; -+ int result; -+ uint temp = 0; -+ int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index; -+ -+ print_debug("IN"); -+ -+ /* wipe all previous message data */ -+ memset(&msg, 0, sizeof msg); -+ -+ /* determine the message type */ -+ if(index == TEMP) -+ msg.tag.tag_id = VC_TAG_GET_TEMP; -+ else if (index == MAX_TEMP) -+ msg.tag.tag_id = VC_TAG_GET_MAX_TEMP; -+ else -+ { -+ print_debug("Unknown temperature message!"); -+ return -EINVAL; -+ } -+ -+ msg.msg_size = sizeof msg; -+ msg.tag.buffer_size = 8; -+ -+ /* send the message */ -+ result = bcm_mailbox_property(&msg, sizeof msg); -+ -+ /* check if it was all ok and return the rate in milli degrees C */ -+ if (result == 0 && (msg.request_code & 0x80000000)) -+ temp = (uint)msg.tag.val; -+ #ifdef HWMON_DEBUG_ENABLE -+ else -+ print_debug("Failed to get temperature!"); -+ #endif -+ print_debug("Got temperature as %u",temp); -+ print_debug("OUT"); -+ return sprintf(buf, "%u\n", temp); -+} -+ -+ -+static int bcm2835_hwmon_probe(struct platform_device *pdev) -+{ -+ int err; -+ -+ print_debug("IN"); -+ print_debug("HWMON Driver has been probed!"); -+ -+ /* check that the device isn't null!*/ -+ if(pdev == NULL) -+ { -+ print_debug("Platform device is empty!"); -+ return -ENODEV; -+ } -+ -+ /* allocate memory for neccessary data */ -+ bcm2835_data = kzalloc(sizeof(struct bcm2835_hwmon_data),GFP_KERNEL); -+ if(!bcm2835_data) -+ { -+ print_debug("Unable to allocate memory for hwmon data!"); -+ err = -ENOMEM; -+ goto kzalloc_error; -+ } -+ -+ /* create the sysfs files */ -+ if(sysfs_create_group(&pdev->dev.kobj, &bcm2835_attr_group)) -+ { -+ print_debug("Unable to create sysfs files!"); -+ err = -EFAULT; -+ goto sysfs_error; -+ } -+ -+ /* register the hwmon device */ -+ bcm2835_data->hwmon_dev = hwmon_device_register(&pdev->dev); -+ if (IS_ERR(bcm2835_data->hwmon_dev)) -+ { -+ err = PTR_ERR(bcm2835_data->hwmon_dev); -+ goto hwmon_error; -+ } -+ print_debug("OUT"); -+ return 0; -+ -+ /* error goto's */ -+ hwmon_error: -+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -+ -+ sysfs_error: -+ kfree(bcm2835_data); -+ -+ kzalloc_error: -+ -+ return err; -+ -+} -+ -+static int bcm2835_hwmon_remove(struct platform_device *pdev) -+{ -+ print_debug("IN"); -+ hwmon_device_unregister(bcm2835_data->hwmon_dev); -+ -+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -+ print_debug("OUT"); -+ return 0; -+} -+ -+/* Hwmon Driver */ -+static struct platform_driver bcm2835_hwmon_driver = { -+ .probe = bcm2835_hwmon_probe, -+ .remove = bcm2835_hwmon_remove, -+ .driver = { -+ .name = "bcm2835_hwmon", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Dorian Peake"); -+MODULE_DESCRIPTION("HW Monitor driver for bcm2835 chip"); -+ -+module_platform_driver(bcm2835_hwmon_driver); + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index af40db0..4584b1e 100644 +index af40db0..ddc77ad 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig -@@ -238,6 +238,12 @@ config INTEL_POWERCLAMP +@@ -238,6 +238,13 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. +config THERMAL_BCM2835 ++ depends on BCM2708_MBOX + tristate "BCM2835 Thermal Driver" + help + This will enable temperature monitoring for the Broadcom BCM2835 @@ -102677,10 +103420,10 @@ index fa0dc48..453d4d9 100644 obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c new file mode 100644 -index 0000000..85fceb5 +index 0000000..3bc80f1 --- /dev/null +++ b/drivers/thermal/bcm2835-thermal.c -@@ -0,0 +1,184 @@ +@@ -0,0 +1,190 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -102698,10 +103441,10 @@ index 0000000..85fceb5 +#include +#include +#include ++#include +#include +#include +#include -+#include +#include + + @@ -102850,13 +103593,19 @@ index 0000000..85fceb5 + .get_mode = bcm2835_get_mode, +}; + -+/* Thermal Driver */ ++static const struct of_device_id bcm2835_thermal_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-thermal", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); ++ +static struct platform_driver bcm2835_thermal_driver = { + .probe = bcm2835_thermal_probe, + .remove = bcm2835_thermal_remove, + .driver = { + .name = "bcm2835_thermal", + .owner = THIS_MODULE, ++ .of_match_table = bcm2835_thermal_of_match_table, + }, +}; + @@ -102866,49 +103615,58 @@ index 0000000..85fceb5 + +module_platform_driver(bcm2835_thermal_driver); -From bb1c2fec8850e0e017e3b80f51df5dc850627555 Mon Sep 17 00:00:00 2001 +From 4d5da3fa21e1d94e38644bf9a5493bb677854e42 Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Mon, 4 Nov 2013 18:56:10 +0000 -Subject: [PATCH 017/216] Add Chris Boot's i2c and spi drivers. +Date: Wed, 17 Jun 2015 15:41:33 +0100 +Subject: [PATCH 20/77] Add Chris Boot's spi driver. -i2c-bcm2708: fixed baudrate +spi: bcm2708: add device tree support -Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock). -In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits. -This resulted in incorrect setting of CDIV and higher baudrate than intended. -Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz -After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz -The correct baudrate is shown in the log after the cdiv > 0xffff correction. +Add DT support to driver and add to .dtsi file. +Setup pins and spidev in .dts file. +SPI is disabled by default. -Perform I2C combined transactions when possible +Signed-off-by: Noralf Tronnes -Perform I2C combined transactions whenever possible, within the -restrictions of the Broadcomm Serial Controller. +BCM2708: don't register SPI controller when using DT -Disable DONE interrupt during TA poll +The device for the SPI controller is in the Device Tree. +Only register the device when not using DT. -Prevent interrupt from being triggered if poll is missed and transfer -starts and finishes. +Signed-off-by: Noralf Tronnes -i2c: Make combined transactions optional and disabled by default +spi: bcm2835: make driver available on ARCH_BCM2708 + +Make this driver available on ARCH_BCM2708 + +Signed-off-by: Noralf Tronnes + +bcm2708: Remove the prohibition on mixing SPIDEV and DT + +spi-bcm2708: Prepare for Common Clock Framework migration + +As part of migrating to use the Common Clock Framework, replace clk_enable() +with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). +This does not affect behaviour under the current clock implementation. + +Also add a missing clk_disable_unprepare() in the probe error path. + +Signed-off-by: Noralf Tronnes --- - arch/arm/mach-bcm2708/Kconfig | 7 + - arch/arm/mach-bcm2708/bcm2708.c | 104 ++++++- - drivers/i2c/busses/Kconfig | 19 ++ - drivers/i2c/busses/Makefile | 2 + - drivers/i2c/busses/i2c-bcm2708.c | 449 ++++++++++++++++++++++++++++ - drivers/spi/Kconfig | 8 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-bcm2708.c | 626 +++++++++++++++++++++++++++++++++++++++ - 8 files changed, 1214 insertions(+), 2 deletions(-) - create mode 100644 drivers/i2c/busses/i2c-bcm2708.c + arch/arm/mach-bcm2708/Kconfig | 7 + + arch/arm/mach-bcm2708/bcm2708.c | 53 ++++ + arch/arm/mach-bcm2709/bcm2709.c | 53 ++++ + drivers/spi/Kconfig | 10 +- + drivers/spi/Makefile | 1 + + drivers/spi/spi-bcm2708.c | 635 ++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 758 insertions(+), 1 deletion(-) create mode 100644 drivers/spi/spi-bcm2708.c diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 9355841..e151ed4 100644 +index 4cbda0c..68e3706 100644 --- a/arch/arm/mach-bcm2708/Kconfig +++ b/arch/arm/mach-bcm2708/Kconfig -@@ -31,4 +31,11 @@ config BCM2708_NOL2CACHE +@@ -35,4 +35,11 @@ config BCM2708_NOL2CACHE help Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt. @@ -102921,50 +103679,18 @@ index 9355841..e151ed4 100644 + Binds spidev driver to the SPI0 master endmenu diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index bae8ba5..752dd46 100644 +index f2d9b03..e3aa6fc 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -31,6 +31,7 @@ - #include +@@ -34,6 +34,7 @@ #include #include + #include +#include + #include #include - #include -@@ -205,7 +206,6 @@ static struct clk osc_clk = { - - /* warning - the USB needs a clock > 34MHz */ - --#ifdef CONFIG_MMC_BCM2708 - static struct clk sdhost_clk = { - #ifdef CONFIG_ARCH_BCM2708_CHIPIT - .rate = 4000000, /* 4MHz */ -@@ -213,7 +213,6 @@ static struct clk sdhost_clk = { - .rate = 250000000, /* 250MHz */ - #endif - }; --#endif - - static struct clk_lookup lookups[] = { - { /* UART0 */ -@@ -223,6 +222,15 @@ static struct clk_lookup lookups[] = { - { /* USB */ - .dev_id = "bcm2708_usb", - .clk = &osc_clk, -+ }, { /* SPI */ -+ .dev_id = "bcm2708_spi.0", -+ .clk = &sdhost_clk, -+ }, { /* BSC0 */ -+ .dev_id = "bcm2708_i2c.0", -+ .clk = &sdhost_clk, -+ }, { /* BSC1 */ -+ .dev_id = "bcm2708_i2c.1", -+ .clk = &sdhost_clk, - } - }; - -@@ -499,6 +507,89 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -505,6 +506,50 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103012,580 +103738,136 @@ index bae8ba5..752dd46 100644 +}; +#endif + -+static struct resource bcm2708_bsc0_resources[] = { -+ { -+ .start = BSC0_BASE, -+ .end = BSC0_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc0_device = { -+ .name = "bcm2708_i2c", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), -+ .resource = bcm2708_bsc0_resources, -+}; -+ -+ -+static struct resource bcm2708_bsc1_resources[] = { -+ { -+ .start = BSC1_BASE, -+ .end = BSC1_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc1_device = { -+ .name = "bcm2708_i2c", -+ .id = 1, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), -+ .resource = bcm2708_bsc1_resources, -+}; -+ - static struct platform_device bcm2835_hwmon_device = { - .name = "bcm2835_hwmon", + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", }; -@@ -619,6 +710,10 @@ void __init bcm2708_init(void) +@@ -655,6 +700,8 @@ void __init bcm2708_init(void) for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device(&bcm2708_alsa_devices[i]); + bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ bcm_register_device(&bcm2708_spi_device); -+ bcm_register_device(&bcm2708_bsc0_device); -+ bcm_register_device(&bcm2708_bsc1_device); ++ bcm_register_device_dt(&bcm2708_spi_device); + - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); + bcm_register_device_dt(&bcm2835_thermal_device); -@@ -628,6 +723,11 @@ void __init bcm2708_init(void) + if (!use_dt) { +@@ -665,6 +712,12 @@ void __init bcm2708_init(void) } system_rev = boardrev; system_serial_low = serial; + +#ifdef CONFIG_BCM2708_SPIDEV -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); ++ if (!use_dt) ++ spi_register_board_info(bcm2708_spi_devices, ++ ARRAY_SIZE(bcm2708_spi_devices)); +#endif } static void timer_set_mode(enum clock_event_mode mode, -diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 22da9c2..00c7baa 100644 ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" - comment "PC SMBus host controller drivers" - depends on PCI +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 9631bdb..5fb99b6 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include -+config I2C_BCM2708 -+ tristate "BCM2708 BSC" -+ depends on MACH_BCM2708 -+ help -+ Enabling this option will add BSC (Broadcom Serial Controller) -+ support for the BCM2708. BSC is a Broadcom proprietary bus compatible -+ with I2C/TWI/SMBus. -+ -+config I2C_BCM2708_BAUDRATE -+ prompt "BCM2708 I2C baudrate" -+ depends on I2C_BCM2708 -+ int -+ default 100000 -+ help -+ Set the I2C baudrate. This will alter the default value. A -+ different baudrate can be set by using a module parameter as well. If -+ no parameter is provided when loading, this is the value that will be -+ used. -+ - config I2C_ALI1535 - tristate "ALI 1535" - depends on PCI -diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index 3638feb..4905fae 100644 ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -2,6 +2,8 @@ - # Makefile for the i2c bus drivers. - # + #include +@@ -525,6 +526,50 @@ static struct platform_device bcm2708_alsa_devices[] = { + }, + }; -+obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o -+ - # ACPI drivers - obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -new file mode 100644 -index 0000000..7d385a3 ---- /dev/null -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,449 @@ -+/* -+ * Driver for Broadcom BCM2708 BSC Controllers -+ * -+ * Copyright (C) 2012 Chris Boot & Frank Buss -+ * -+ * This driver is inspired by: -+ * i2c-ocores.c, by Peter Korsgaard -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* BSC register offsets */ -+#define BSC_C 0x00 -+#define BSC_S 0x04 -+#define BSC_DLEN 0x08 -+#define BSC_A 0x0c -+#define BSC_FIFO 0x10 -+#define BSC_DIV 0x14 -+#define BSC_DEL 0x18 -+#define BSC_CLKT 0x1c -+ -+/* Bitfields in BSC_C */ -+#define BSC_C_I2CEN 0x00008000 -+#define BSC_C_INTR 0x00000400 -+#define BSC_C_INTT 0x00000200 -+#define BSC_C_INTD 0x00000100 -+#define BSC_C_ST 0x00000080 -+#define BSC_C_CLEAR_1 0x00000020 -+#define BSC_C_CLEAR_2 0x00000010 -+#define BSC_C_READ 0x00000001 -+ -+/* Bitfields in BSC_S */ -+#define BSC_S_CLKT 0x00000200 -+#define BSC_S_ERR 0x00000100 -+#define BSC_S_RXF 0x00000080 -+#define BSC_S_TXE 0x00000040 -+#define BSC_S_RXD 0x00000020 -+#define BSC_S_TXD 0x00000010 -+#define BSC_S_RXR 0x00000008 -+#define BSC_S_TXW 0x00000004 -+#define BSC_S_DONE 0x00000002 -+#define BSC_S_TA 0x00000001 -+ -+#define I2C_TIMEOUT_MS 150 -+ -+#define DRV_NAME "bcm2708_i2c" -+ -+static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; -+module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+MODULE_PARM_DESC(baudrate, "The I2C baudrate"); -+ -+static bool combined = false; -+module_param(combined, bool, 0644); -+MODULE_PARM_DESC(combined, "Use combined transactions"); -+ -+struct bcm2708_i2c { -+ struct i2c_adapter adapter; -+ -+ spinlock_t lock; -+ void __iomem *base; -+ int irq; -+ struct clk *clk; -+ -+ struct completion done; -+ -+ struct i2c_msg *msg; -+ int pos; -+ int nmsgs; -+ bool error; -+}; -+ -+/* -+ * This function sets the ALT mode on the I2C pins so that we can use them with -+ * the BSC hardware. -+ * -+ * FIXME: This is a hack. Use pinmux / pinctrl. -+ */ -+static void bcm2708_i2c_init_pinmode(int id) -+{ -+#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) -+#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) -+ -+ int pin; -+ u32 *gpio = ioremap(GPIO_BASE, SZ_16K); -+ -+ BUG_ON(id != 0 && id != 1); -+ /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */ -+ for (pin = id*2+0; pin <= id*2+1; pin++) { -+printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); -+ INP_GPIO(pin); /* set mode to GPIO input first */ -+ SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */ -+ } -+ -+ iounmap(gpio); -+ -+#undef INP_GPIO -+#undef SET_GPIO_ALT -+} -+ -+static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) -+{ -+ return readl(bi->base + reg); -+} -+ -+static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val) -+{ -+ writel(val, bi->base + reg); -+} -+ -+static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi) -+{ -+ bcm2708_wr(bi, BSC_C, 0); -+ bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE); -+} -+ -+static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi) -+{ -+ while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len)) -+ bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO); -+} -+ -+static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) -+{ -+ while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len)) -+ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); -+} -+ -+static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) -+{ -+ unsigned long bus_hz; -+ u32 cdiv, s; -+ u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; -+ -+ bus_hz = clk_get_rate(bi->clk); -+ cdiv = bus_hz / baudrate; -+ if (cdiv > 0xffff) -+ cdiv = 0xffff; -+ -+ if (bi->msg->flags & I2C_M_RD) -+ c |= BSC_C_INTR | BSC_C_READ; -+ else -+ c |= BSC_C_INTT; -+ -+ bcm2708_wr(bi, BSC_DIV, cdiv); -+ bcm2708_wr(bi, BSC_A, bi->msg->addr); -+ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); -+ if (combined) ++static struct resource bcm2708_spi_resources[] = { + { -+ /* Do the next two messages meet combined transaction criteria? -+ - Current message is a write, next message is a read -+ - Both messages to same slave address -+ - Write message can fit inside FIFO (16 bytes or less) */ -+ if ( (bi->nmsgs > 1) && -+ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && -+ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { -+ /* Fill FIFO with entire write message (16 byte FIFO) */ -+ while (bi->pos < bi->msg->len) -+ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); -+ /* Start write transfer (no interrupts, don't clear FIFO) */ -+ bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); -+ /* poll for transfer start bit (should only take 1-20 polls) */ -+ do { -+ s = bcm2708_rd(bi, BSC_S); -+ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE))); -+ /* Send next read message before the write transfer finishes. */ -+ bi->nmsgs--; -+ bi->msg++; -+ bi->pos = 0; -+ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); -+ c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ; -+ } ++ .start = SPI0_BASE, ++ .end = SPI0_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_SPI, ++ .end = IRQ_SPI, ++ .flags = IORESOURCE_IRQ, + } -+ bcm2708_wr(bi, BSC_C, c); -+} -+ -+static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) -+{ -+ struct bcm2708_i2c *bi = dev_id; -+ bool handled = true; -+ u32 s; -+ -+ spin_lock(&bi->lock); -+ -+ /* we may see camera interrupts on the "other" I2C channel -+ Just return if we've not sent anything */ -+ if (!bi->nmsgs || !bi->msg ) -+ goto early_exit; -+ -+ s = bcm2708_rd(bi, BSC_S); -+ -+ if (s & (BSC_S_CLKT | BSC_S_ERR)) { -+ bcm2708_bsc_reset(bi); -+ bi->error = true; -+ -+ /* wake up our bh */ -+ complete(&bi->done); -+ } else if (s & BSC_S_DONE) { -+ bi->nmsgs--; -+ -+ if (bi->msg->flags & I2C_M_RD) -+ bcm2708_bsc_fifo_drain(bi); -+ -+ bcm2708_bsc_reset(bi); -+ -+ if (bi->nmsgs) { -+ /* advance to next message */ -+ bi->msg++; -+ bi->pos = 0; -+ bcm2708_bsc_setup(bi); -+ } else { -+ /* wake up our bh */ -+ complete(&bi->done); -+ } -+ } else if (s & BSC_S_TXW) { -+ bcm2708_bsc_fifo_fill(bi); -+ } else if (s & BSC_S_RXR) { -+ bcm2708_bsc_fifo_drain(bi); -+ } else { -+ handled = false; -+ } -+ -+early_exit: -+ spin_unlock(&bi->lock); -+ -+ return handled ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct bcm2708_i2c *bi = adap->algo_data; -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&bi->lock, flags); -+ -+ reinit_completion(&bi->done); -+ bi->msg = msgs; -+ bi->pos = 0; -+ bi->nmsgs = num; -+ bi->error = false; -+ -+ bcm2708_bsc_setup(bi); -+ -+ /* unlockig _after_ the setup to avoid races with the interrupt routine */ -+ spin_unlock_irqrestore(&bi->lock, flags); -+ -+ ret = wait_for_completion_timeout(&bi->done, -+ msecs_to_jiffies(I2C_TIMEOUT_MS)); -+ if (ret == 0) { -+ dev_err(&adap->dev, "transfer timed out\n"); -+ spin_lock_irqsave(&bi->lock, flags); -+ bcm2708_bsc_reset(bi); -+ spin_unlock_irqrestore(&bi->lock, flags); -+ return -ETIMEDOUT; -+ } -+ -+ return bi->error ? -EIO : num; -+} -+ -+static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL; -+} -+ -+static struct i2c_algorithm bcm2708_i2c_algorithm = { -+ .master_xfer = bcm2708_i2c_master_xfer, -+ .functionality = bcm2708_i2c_functionality, +}; + -+static int bcm2708_i2c_probe(struct platform_device *pdev) -+{ -+ struct resource *regs; -+ int irq, err = -ENOMEM; -+ struct clk *clk; -+ struct bcm2708_i2c *bi; -+ struct i2c_adapter *adap; -+ unsigned long bus_hz; -+ u32 cdiv; + -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) { -+ dev_err(&pdev->dev, "could not get IO memory\n"); -+ return -ENXIO; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "could not get IRQ\n"); -+ return irq; -+ } -+ -+ clk = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk)); -+ return PTR_ERR(clk); -+ } -+ -+ bcm2708_i2c_init_pinmode(pdev->id); -+ -+ bi = kzalloc(sizeof(*bi), GFP_KERNEL); -+ if (!bi) -+ goto out_clk_put; -+ -+ platform_set_drvdata(pdev, bi); -+ -+ adap = &bi->adapter; -+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC; -+ adap->algo = &bcm2708_i2c_algorithm; -+ adap->algo_data = bi; -+ adap->dev.parent = &pdev->dev; -+ adap->nr = pdev->id; -+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ -+ switch (pdev->id) { -+ case 0: -+ adap->class = I2C_CLASS_HWMON; -+ break; -+ case 1: -+ adap->class = I2C_CLASS_DDC; -+ break; -+ default: -+ dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); -+ err = -ENXIO; -+ goto out_free_bi; -+ } -+ -+ spin_lock_init(&bi->lock); -+ init_completion(&bi->done); -+ -+ bi->base = ioremap(regs->start, resource_size(regs)); -+ if (!bi->base) { -+ dev_err(&pdev->dev, "could not remap memory\n"); -+ goto out_free_bi; -+ } -+ -+ bi->irq = irq; -+ bi->clk = clk; -+ -+ err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED, -+ dev_name(&pdev->dev), bi); -+ if (err) { -+ dev_err(&pdev->dev, "could not request IRQ: %d\n", err); -+ goto out_iounmap; -+ } -+ -+ bcm2708_bsc_reset(bi); -+ -+ err = i2c_add_numbered_adapter(adap); -+ if (err < 0) { -+ dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err); -+ goto out_free_irq; -+ } -+ -+ bus_hz = clk_get_rate(bi->clk); -+ cdiv = bus_hz / baudrate; -+ if (cdiv > 0xffff) { -+ cdiv = 0xffff; -+ baudrate = bus_hz / cdiv; -+ } -+ -+ dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", -+ pdev->id, (unsigned long)regs->start, irq, baudrate); -+ -+ return 0; -+ -+out_free_irq: -+ free_irq(bi->irq, bi); -+out_iounmap: -+ iounmap(bi->base); -+out_free_bi: -+ kfree(bi); -+out_clk_put: -+ clk_put(clk); -+ return err; -+} -+ -+static int bcm2708_i2c_remove(struct platform_device *pdev) -+{ -+ struct bcm2708_i2c *bi = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ i2c_del_adapter(&bi->adapter); -+ free_irq(bi->irq, bi); -+ iounmap(bi->base); -+ clk_disable(bi->clk); -+ clk_put(bi->clk); -+ kfree(bi); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm2708_i2c_driver = { -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = bcm2708_i2c_probe, -+ .remove = bcm2708_i2c_remove, ++static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++static struct platform_device bcm2708_spi_device = { ++ .name = "bcm2708_spi", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_spi_resources), ++ .resource = bcm2708_spi_resources, ++ .dev = { ++ .dma_mask = &bcm2708_spi_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)}, +}; + -+// module_platform_driver(bcm2708_i2c_driver); ++#ifdef CONFIG_BCM2708_SPIDEV ++static struct spi_board_info bcm2708_spi_devices[] = { ++#ifdef CONFIG_SPI_SPIDEV ++ { ++ .modalias = "spidev", ++ .max_speed_hz = 500000, ++ .bus_num = 0, ++ .chip_select = 0, ++ .mode = SPI_MODE_0, ++ }, { ++ .modalias = "spidev", ++ .max_speed_hz = 500000, ++ .bus_num = 0, ++ .chip_select = 1, ++ .mode = SPI_MODE_0, ++ } ++#endif ++}; ++#endif + + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; +@@ -675,6 +720,8 @@ void __init bcm2709_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device_dt(&bcm2708_alsa_devices[i]); + ++ bcm_register_device_dt(&bcm2708_spi_device); + -+static int __init bcm2708_i2c_init(void) -+{ -+ return platform_driver_register(&bcm2708_i2c_driver); -+} + bcm_register_device_dt(&bcm2835_thermal_device); + + if (!use_dt) { +@@ -685,6 +732,12 @@ void __init bcm2709_init(void) + } + system_rev = boardrev; + system_serial_low = serial; + -+static void __exit bcm2708_i2c_exit(void) -+{ -+ platform_driver_unregister(&bcm2708_i2c_driver); -+} -+ -+module_init(bcm2708_i2c_init); -+module_exit(bcm2708_i2c_exit); -+ -+ -+ -+MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708"); -+MODULE_AUTHOR("Chris Boot "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRV_NAME); ++#ifdef CONFIG_BCM2708_SPIDEV ++ if (!use_dt) ++ spi_register_board_info(bcm2708_spi_devices, ++ ARRAY_SIZE(bcm2708_spi_devices)); ++#endif + } + + #ifdef SYSTEM_TIMER diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index ab8dfbe..9628e75 100644 +index 72b0590..ea5e5de 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -86,6 +86,14 @@ config SPI_BCM2835 +@@ -77,7 +77,7 @@ config SPI_ATMEL + + config SPI_BCM2835 + tristate "BCM2835 SPI controller" +- depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST + depends on GPIOLIB + help + This selects a driver for the Broadcom BCM2835 SPI master. +@@ -87,6 +87,14 @@ config SPI_BCM2835 is for the regular SPI controller. Slave mode operation is not also not supported. +config SPI_BCM2708 + tristate "BCM2708 SPI controller driver (SPI0)" -+ depends on MACH_BCM2708 ++ depends on MACH_BCM2708 || MACH_BCM2709 + help + This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This + driver is not compatible with the "Universal SPI Master" or the SPI slave @@ -103608,10 +103890,10 @@ index d8cbf65..0dcd03d 100644 obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c new file mode 100644 -index 0000000..b04a57d +index 0000000..041b5e2 --- /dev/null +++ b/drivers/spi/spi-bcm2708.c -@@ -0,0 +1,626 @@ +@@ -0,0 +1,635 @@ +/* + * Driver for Broadcom BCM2708 SPI Controllers + * @@ -104126,6 +104408,7 @@ index 0000000..b04a57d + master->setup = bcm2708_spi_setup; + master->transfer = bcm2708_spi_transfer; + master->cleanup = bcm2708_spi_cleanup; ++ master->dev.of_node = pdev->dev.of_node; + platform_set_drvdata(pdev, master); + + bs = spi_master_get_devdata(master); @@ -104159,7 +104442,7 @@ index 0000000..b04a57d + } + + /* initialise the hardware */ -+ clk_enable(clk); ++ clk_prepare_enable(clk); + bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX); + + err = spi_register_master(master); @@ -104175,6 +104458,7 @@ index 0000000..b04a57d + +out_free_irq: + free_irq(bs->irq, master); ++ clk_disable_unprepare(bs->clk); +out_workqueue: + destroy_workqueue(bs->workq); +out_iounmap: @@ -104199,7 +104483,7 @@ index 0000000..b04a57d + + flush_work(&bs->work); + -+ clk_disable(bs->clk); ++ clk_disable_unprepare(bs->clk); + clk_put(bs->clk); + free_irq(bs->irq, master); + iounmap(bs->base); @@ -104209,10 +104493,17 @@ index 0000000..b04a57d + return 0; +} + ++static const struct of_device_id bcm2708_spi_match[] = { ++ { .compatible = "brcm,bcm2708-spi", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_spi_match); ++ +static struct platform_driver bcm2708_spi_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_spi_match, + }, + .probe = bcm2708_spi_probe, + .remove = bcm2708_spi_remove, @@ -104239,10 +104530,814 @@ index 0000000..b04a57d +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From 530db15891390005623b20a03dda6ef6871607bc Mon Sep 17 00:00:00 2001 +From 75d6625177ee7e4746baf70b60380069d58231ba Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 17 Jun 2015 15:44:08 +0100 +Subject: [PATCH 21/77] Add Chris Boot's i2c driver + +i2c-bcm2708: fixed baudrate + +Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock). +In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits. +This resulted in incorrect setting of CDIV and higher baudrate than intended. +Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz +After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz +The correct baudrate is shown in the log after the cdiv > 0xffff correction. + +Perform I2C combined transactions when possible + +Perform I2C combined transactions whenever possible, within the +restrictions of the Broadcomm Serial Controller. + +Disable DONE interrupt during TA poll + +Prevent interrupt from being triggered if poll is missed and transfer +starts and finishes. + +i2c: Make combined transactions optional and disabled by default + +i2c: bcm2708: add device tree support + +Add DT support to driver and add to .dtsi file. +Setup pins in .dts file. +i2c is disabled by default. + +Signed-off-by: Noralf Tronnes + +bcm2708: don't register i2c controllers when using DT + +The devices for the i2c controllers are in the Device Tree. +Only register devices when not using DT. + +Signed-off-by: Noralf Tronnes + +I2C: Only register the I2C device for the current board revision + +i2c_bcm2708: Fix clock reference counting + +Fix grabbing lock from atomic context in i2c driver + +2 main changes: +- check for timeouts in the bcm2708_bsc_setup function as indicated by this comment: + /* poll for transfer start bit (should only take 1-20 polls) */ + This implies that the setup function can now fail so account for this everywhere it's called +- Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock. + +i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl +--- + arch/arm/mach-bcm2708/bcm2708.c | 51 ++++ + arch/arm/mach-bcm2709/bcm2709.c | 51 ++++ + drivers/i2c/busses/Kconfig | 21 +- + drivers/i2c/busses/Makefile | 2 + + drivers/i2c/busses/i2c-bcm2708.c | 522 +++++++++++++++++++++++++++++++++++++++ + 5 files changed, 646 insertions(+), 1 deletion(-) + create mode 100644 drivers/i2c/busses/i2c-bcm2708.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index e3aa6fc..efb3544 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -83,6 +83,7 @@ static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static bool vc_i2c_override = false; + + static unsigned use_dt = 0; + +@@ -550,6 +551,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { + }; + #endif + ++static struct resource bcm2708_bsc0_resources[] = { ++ { ++ .start = BSC0_BASE, ++ .end = BSC0_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc0_device = { ++ .name = "bcm2708_i2c", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), ++ .resource = bcm2708_bsc0_resources, ++}; ++ ++ ++static struct resource bcm2708_bsc1_resources[] = { ++ { ++ .start = BSC1_BASE, ++ .end = BSC1_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc1_device = { ++ .name = "bcm2708_i2c", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), ++ .resource = bcm2708_bsc1_resources, ++}; ++ + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; +@@ -702,6 +742,15 @@ void __init bcm2708_init(void) + + bcm_register_device_dt(&bcm2708_spi_device); + ++ if (vc_i2c_override) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ } else { ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } ++ + bcm_register_device_dt(&bcm2835_thermal_device); + + if (!use_dt) { +@@ -893,3 +942,5 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(vc_i2c_override, bool, 0644); ++MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 5fb99b6..8017c50 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -85,6 +85,7 @@ static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static bool vc_i2c_override = false; + + static unsigned use_dt = 0; + +@@ -570,6 +571,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { + }; + #endif + ++static struct resource bcm2708_bsc0_resources[] = { ++ { ++ .start = BSC0_BASE, ++ .end = BSC0_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc0_device = { ++ .name = "bcm2708_i2c", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), ++ .resource = bcm2708_bsc0_resources, ++}; ++ ++ ++static struct resource bcm2708_bsc1_resources[] = { ++ { ++ .start = BSC1_BASE, ++ .end = BSC1_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc1_device = { ++ .name = "bcm2708_i2c", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), ++ .resource = bcm2708_bsc1_resources, ++}; ++ + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; +@@ -722,6 +762,15 @@ void __init bcm2709_init(void) + + bcm_register_device_dt(&bcm2708_spi_device); + ++ if (vc_i2c_override) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ } else { ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } ++ + bcm_register_device_dt(&bcm2835_thermal_device); + + if (!use_dt) { +@@ -1061,3 +1110,5 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(vc_i2c_override, bool, 0644); ++MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 2255af2..5b0c772 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" + comment "PC SMBus host controller drivers" + depends on PCI + ++config I2C_BCM2708 ++ tristate "BCM2708 BSC" ++ depends on MACH_BCM2708 || MACH_BCM2709 ++ help ++ Enabling this option will add BSC (Broadcom Serial Controller) ++ support for the BCM2708. BSC is a Broadcom proprietary bus compatible ++ with I2C/TWI/SMBus. ++ ++config I2C_BCM2708_BAUDRATE ++ prompt "BCM2708 I2C baudrate" ++ depends on I2C_BCM2708 ++ int ++ default 100000 ++ help ++ Set the I2C baudrate. This will alter the default value. A ++ different baudrate can be set by using a module parameter as well. If ++ no parameter is provided when loading, this is the value that will be ++ used. ++ + config I2C_ALI1535 + tristate "ALI 1535" + depends on PCI +@@ -362,7 +381,7 @@ config I2C_AXXIA + + config I2C_BCM2835 + tristate "Broadcom BCM2835 I2C controller" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + help + If you say yes to this option, support will be included for the + BCM2835 I2C controller. +diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile +index cdf941d..e0176d7 100644 +--- a/drivers/i2c/busses/Makefile ++++ b/drivers/i2c/busses/Makefile +@@ -2,6 +2,8 @@ + # Makefile for the i2c bus drivers. + # + ++obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o ++ + # ACPI drivers + obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o + +diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c +new file mode 100644 +index 0000000..8773203 +--- /dev/null ++++ b/drivers/i2c/busses/i2c-bcm2708.c +@@ -0,0 +1,522 @@ ++/* ++ * Driver for Broadcom BCM2708 BSC Controllers ++ * ++ * Copyright (C) 2012 Chris Boot & Frank Buss ++ * ++ * This driver is inspired by: ++ * i2c-ocores.c, by Peter Korsgaard ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* BSC register offsets */ ++#define BSC_C 0x00 ++#define BSC_S 0x04 ++#define BSC_DLEN 0x08 ++#define BSC_A 0x0c ++#define BSC_FIFO 0x10 ++#define BSC_DIV 0x14 ++#define BSC_DEL 0x18 ++#define BSC_CLKT 0x1c ++ ++/* Bitfields in BSC_C */ ++#define BSC_C_I2CEN 0x00008000 ++#define BSC_C_INTR 0x00000400 ++#define BSC_C_INTT 0x00000200 ++#define BSC_C_INTD 0x00000100 ++#define BSC_C_ST 0x00000080 ++#define BSC_C_CLEAR_1 0x00000020 ++#define BSC_C_CLEAR_2 0x00000010 ++#define BSC_C_READ 0x00000001 ++ ++/* Bitfields in BSC_S */ ++#define BSC_S_CLKT 0x00000200 ++#define BSC_S_ERR 0x00000100 ++#define BSC_S_RXF 0x00000080 ++#define BSC_S_TXE 0x00000040 ++#define BSC_S_RXD 0x00000020 ++#define BSC_S_TXD 0x00000010 ++#define BSC_S_RXR 0x00000008 ++#define BSC_S_TXW 0x00000004 ++#define BSC_S_DONE 0x00000002 ++#define BSC_S_TA 0x00000001 ++ ++#define I2C_TIMEOUT_MS 150 ++#define I2C_WAIT_LOOP_COUNT 40 ++ ++#define DRV_NAME "bcm2708_i2c" ++ ++static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; ++module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); ++MODULE_PARM_DESC(baudrate, "The I2C baudrate"); ++ ++static bool combined = false; ++module_param(combined, bool, 0644); ++MODULE_PARM_DESC(combined, "Use combined transactions"); ++ ++struct bcm2708_i2c { ++ struct i2c_adapter adapter; ++ ++ spinlock_t lock; ++ void __iomem *base; ++ int irq; ++ struct clk *clk; ++ u32 cdiv; ++ ++ struct completion done; ++ ++ struct i2c_msg *msg; ++ int pos; ++ int nmsgs; ++ bool error; ++}; ++ ++/* ++ * This function sets the ALT mode on the I2C pins so that we can use them with ++ * the BSC hardware. ++ * ++ * FIXME: This is a hack. Use pinmux / pinctrl. ++ */ ++static void bcm2708_i2c_init_pinmode(int id) ++{ ++#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) ++#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) ++ ++ int pin; ++ u32 *gpio = ioremap(GPIO_BASE, SZ_16K); ++ ++ BUG_ON(id != 0 && id != 1); ++ /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */ ++ for (pin = id*2+0; pin <= id*2+1; pin++) { ++ printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); ++ INP_GPIO(pin); /* set mode to GPIO input first */ ++ SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */ ++ } ++ ++ iounmap(gpio); ++ ++#undef INP_GPIO ++#undef SET_GPIO_ALT ++} ++ ++static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) ++{ ++ return readl(bi->base + reg); ++} ++ ++static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val) ++{ ++ writel(val, bi->base + reg); ++} ++ ++static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi) ++{ ++ bcm2708_wr(bi, BSC_C, 0); ++ bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE); ++} ++ ++static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi) ++{ ++ while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len)) ++ bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO); ++} ++ ++static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) ++{ ++ while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len)) ++ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); ++} ++ ++static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) ++{ ++ u32 cdiv, s; ++ u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; ++ int wait_loops = I2C_WAIT_LOOP_COUNT; ++ ++ /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked. ++ * Use the value that we cached in the probe. ++ */ ++ cdiv = bi->cdiv; ++ ++ if (bi->msg->flags & I2C_M_RD) ++ c |= BSC_C_INTR | BSC_C_READ; ++ else ++ c |= BSC_C_INTT; ++ ++ bcm2708_wr(bi, BSC_DIV, cdiv); ++ bcm2708_wr(bi, BSC_A, bi->msg->addr); ++ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); ++ if (combined) ++ { ++ /* Do the next two messages meet combined transaction criteria? ++ - Current message is a write, next message is a read ++ - Both messages to same slave address ++ - Write message can fit inside FIFO (16 bytes or less) */ ++ if ( (bi->nmsgs > 1) && ++ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && ++ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { ++ /* Fill FIFO with entire write message (16 byte FIFO) */ ++ while (bi->pos < bi->msg->len) { ++ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); ++ } ++ /* Start write transfer (no interrupts, don't clear FIFO) */ ++ bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); ++ ++ /* poll for transfer start bit (should only take 1-20 polls) */ ++ do { ++ s = bcm2708_rd(bi, BSC_S); ++ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0); ++ ++ /* did we time out or some error occured? */ ++ if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) { ++ return -1; ++ } ++ ++ /* Send next read message before the write transfer finishes. */ ++ bi->nmsgs--; ++ bi->msg++; ++ bi->pos = 0; ++ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); ++ c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ; ++ } ++ } ++ bcm2708_wr(bi, BSC_C, c); ++ ++ return 0; ++} ++ ++static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) ++{ ++ struct bcm2708_i2c *bi = dev_id; ++ bool handled = true; ++ u32 s; ++ int ret; ++ ++ spin_lock(&bi->lock); ++ ++ /* we may see camera interrupts on the "other" I2C channel ++ Just return if we've not sent anything */ ++ if (!bi->nmsgs || !bi->msg) { ++ goto early_exit; ++ } ++ ++ s = bcm2708_rd(bi, BSC_S); ++ ++ if (s & (BSC_S_CLKT | BSC_S_ERR)) { ++ bcm2708_bsc_reset(bi); ++ bi->error = true; ++ ++ bi->msg = 0; /* to inform the that all work is done */ ++ bi->nmsgs = 0; ++ /* wake up our bh */ ++ complete(&bi->done); ++ } else if (s & BSC_S_DONE) { ++ bi->nmsgs--; ++ ++ if (bi->msg->flags & I2C_M_RD) { ++ bcm2708_bsc_fifo_drain(bi); ++ } ++ ++ bcm2708_bsc_reset(bi); ++ ++ if (bi->nmsgs) { ++ /* advance to next message */ ++ bi->msg++; ++ bi->pos = 0; ++ ret = bcm2708_bsc_setup(bi); ++ if (ret < 0) { ++ bcm2708_bsc_reset(bi); ++ bi->error = true; ++ bi->msg = 0; /* to inform the that all work is done */ ++ bi->nmsgs = 0; ++ /* wake up our bh */ ++ complete(&bi->done); ++ goto early_exit; ++ } ++ } else { ++ bi->msg = 0; /* to inform the that all work is done */ ++ bi->nmsgs = 0; ++ /* wake up our bh */ ++ complete(&bi->done); ++ } ++ } else if (s & BSC_S_TXW) { ++ bcm2708_bsc_fifo_fill(bi); ++ } else if (s & BSC_S_RXR) { ++ bcm2708_bsc_fifo_drain(bi); ++ } else { ++ handled = false; ++ } ++ ++early_exit: ++ spin_unlock(&bi->lock); ++ ++ return handled ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, ++ struct i2c_msg *msgs, int num) ++{ ++ struct bcm2708_i2c *bi = adap->algo_data; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&bi->lock, flags); ++ ++ reinit_completion(&bi->done); ++ bi->msg = msgs; ++ bi->pos = 0; ++ bi->nmsgs = num; ++ bi->error = false; ++ ++ ret = bcm2708_bsc_setup(bi); ++ ++ spin_unlock_irqrestore(&bi->lock, flags); ++ ++ /* check the result of the setup */ ++ if (ret < 0) ++ { ++ dev_err(&adap->dev, "transfer setup timed out\n"); ++ goto error_timeout; ++ } ++ ++ ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); ++ if (ret == 0) { ++ dev_err(&adap->dev, "transfer timed out\n"); ++ goto error_timeout; ++ } ++ ++ ret = bi->error ? -EIO : num; ++ return ret; ++ ++error_timeout: ++ spin_lock_irqsave(&bi->lock, flags); ++ bcm2708_bsc_reset(bi); ++ bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */ ++ bi->nmsgs = 0; ++ spin_unlock_irqrestore(&bi->lock, flags); ++ return -ETIMEDOUT; ++} ++ ++static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL; ++} ++ ++static struct i2c_algorithm bcm2708_i2c_algorithm = { ++ .master_xfer = bcm2708_i2c_master_xfer, ++ .functionality = bcm2708_i2c_functionality, ++}; ++ ++static int bcm2708_i2c_probe(struct platform_device *pdev) ++{ ++ struct resource *regs; ++ int irq, err = -ENOMEM; ++ struct clk *clk; ++ struct bcm2708_i2c *bi; ++ struct i2c_adapter *adap; ++ unsigned long bus_hz; ++ u32 cdiv; ++ ++ if (pdev->dev.of_node) { ++ u32 bus_clk_rate; ++ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); ++ if (pdev->id < 0) { ++ dev_err(&pdev->dev, "alias is missing\n"); ++ return -EINVAL; ++ } ++ if (!of_property_read_u32(pdev->dev.of_node, ++ "clock-frequency", &bus_clk_rate)) ++ baudrate = bus_clk_rate; ++ else ++ dev_warn(&pdev->dev, ++ "Could not read clock-frequency property\n"); ++ } ++ ++ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!regs) { ++ dev_err(&pdev->dev, "could not get IO memory\n"); ++ return -ENXIO; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(&pdev->dev, "could not get IRQ\n"); ++ return irq; ++ } ++ ++ clk = clk_get(&pdev->dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ ++ err = clk_prepare_enable(clk); ++ if (err) { ++ dev_err(&pdev->dev, "could not enable clk: %d\n", err); ++ goto out_clk_put; ++ } ++ ++ if (!pdev->dev.of_node) ++ bcm2708_i2c_init_pinmode(pdev->id); ++ ++ bi = kzalloc(sizeof(*bi), GFP_KERNEL); ++ if (!bi) ++ goto out_clk_disable; ++ ++ platform_set_drvdata(pdev, bi); ++ ++ adap = &bi->adapter; ++ adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC; ++ adap->algo = &bcm2708_i2c_algorithm; ++ adap->algo_data = bi; ++ adap->dev.parent = &pdev->dev; ++ adap->nr = pdev->id; ++ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); ++ adap->dev.of_node = pdev->dev.of_node; ++ ++ switch (pdev->id) { ++ case 0: ++ adap->class = I2C_CLASS_HWMON; ++ break; ++ case 1: ++ adap->class = I2C_CLASS_DDC; ++ break; ++ default: ++ dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); ++ err = -ENXIO; ++ goto out_free_bi; ++ } ++ ++ spin_lock_init(&bi->lock); ++ init_completion(&bi->done); ++ ++ bi->base = ioremap(regs->start, resource_size(regs)); ++ if (!bi->base) { ++ dev_err(&pdev->dev, "could not remap memory\n"); ++ goto out_free_bi; ++ } ++ ++ bi->irq = irq; ++ bi->clk = clk; ++ ++ err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED, ++ dev_name(&pdev->dev), bi); ++ if (err) { ++ dev_err(&pdev->dev, "could not request IRQ: %d\n", err); ++ goto out_iounmap; ++ } ++ ++ bcm2708_bsc_reset(bi); ++ ++ err = i2c_add_numbered_adapter(adap); ++ if (err < 0) { ++ dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err); ++ goto out_free_irq; ++ } ++ ++ bus_hz = clk_get_rate(bi->clk); ++ cdiv = bus_hz / baudrate; ++ if (cdiv > 0xffff) { ++ cdiv = 0xffff; ++ baudrate = bus_hz / cdiv; ++ } ++ bi->cdiv = cdiv; ++ ++ dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", ++ pdev->id, (unsigned long)regs->start, irq, baudrate); ++ ++ return 0; ++ ++out_free_irq: ++ free_irq(bi->irq, bi); ++out_iounmap: ++ iounmap(bi->base); ++out_free_bi: ++ kfree(bi); ++out_clk_disable: ++ clk_disable_unprepare(clk); ++out_clk_put: ++ clk_put(clk); ++ return err; ++} ++ ++static int bcm2708_i2c_remove(struct platform_device *pdev) ++{ ++ struct bcm2708_i2c *bi = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ i2c_del_adapter(&bi->adapter); ++ free_irq(bi->irq, bi); ++ iounmap(bi->base); ++ clk_disable_unprepare(bi->clk); ++ clk_put(bi->clk); ++ kfree(bi); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm2708_i2c_of_match[] = { ++ { .compatible = "brcm,bcm2708-i2c" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); ++ ++static struct platform_driver bcm2708_i2c_driver = { ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2708_i2c_of_match, ++ }, ++ .probe = bcm2708_i2c_probe, ++ .remove = bcm2708_i2c_remove, ++}; ++ ++// module_platform_driver(bcm2708_i2c_driver); ++ ++ ++static int __init bcm2708_i2c_init(void) ++{ ++ return platform_driver_register(&bcm2708_i2c_driver); ++} ++ ++static void __exit bcm2708_i2c_exit(void) ++{ ++ platform_driver_unregister(&bcm2708_i2c_driver); ++} ++ ++module_init(bcm2708_i2c_init); ++module_exit(bcm2708_i2c_exit); ++ ++ ++ ++MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708"); ++MODULE_AUTHOR("Chris Boot "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); + +From 87711afd62feac0850e063b279057c91fe0aabbf Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 018/216] bcm2835: add v4l2 camera device +Subject: [PATCH 22/77] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -104582,7 +105677,7 @@ index 0000000..c585a8f + +$ v4l2-ctl --list-formats diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index d9b872b..2da9264 100644 +index 421f531..34ad311 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -11,6 +11,8 @@ menuconfig V4L_PLATFORM_DRIVERS @@ -104595,7 +105690,7 @@ index d9b872b..2da9264 100644 config VIDEO_VIA_CAMERA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index 3ec1547..d8d5927 100644 +index 8f85561..7b15c24 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,6 +2,8 @@ @@ -104609,7 +105704,7 @@ index 3ec1547..d8d5927 100644 diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig new file mode 100644 -index 0000000..2cb1a68 +index 0000000..99a5cbc --- /dev/null +++ b/drivers/media/platform/bcm2835/Kconfig @@ -0,0 +1,25 @@ @@ -104617,7 +105712,7 @@ index 0000000..2cb1a68 + +config VIDEO_BCM2835 + bool "Broadcom BCM2835 camera interface driver" -+ depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709) ++ depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) + ---help--- + Say Y here to enable camera host interface devices for + Broadcom BCM2835 SoC. This operates over the VCHIQ interface @@ -111569,6942 +112664,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 47303896a0462c49e8bf3e5ef31e744d891a30a4 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 6 Jul 2014 12:07:25 +0200 -Subject: [PATCH 019/216] spi-bcm2708: Prepare for Common Clock Framework - migration - -As part of migrating to use the Common Clock Framework, replace clk_enable() -with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). -This does not affect behaviour under the current clock implementation. - -Also add a missing clk_disable_unprepare() in the probe error path. - -Signed-off-by: Noralf Tronnes ---- - drivers/spi/spi-bcm2708.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index b04a57d..349d21f 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -545,7 +545,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - } - - /* initialise the hardware */ -- clk_enable(clk); -+ clk_prepare_enable(clk); - bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX); - - err = spi_register_master(master); -@@ -561,6 +561,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - - out_free_irq: - free_irq(bs->irq, master); -+ clk_disable_unprepare(bs->clk); - out_workqueue: - destroy_workqueue(bs->workq); - out_iounmap: -@@ -585,7 +586,7 @@ static int bcm2708_spi_remove(struct platform_device *pdev) - - flush_work(&bs->work); - -- clk_disable(bs->clk); -+ clk_disable_unprepare(bs->clk); - clk_put(bs->clk); - free_irq(bs->irq, master); - iounmap(bs->base); - -From d8d78e0bb5731d6fb3f1f813dc795e98be064870 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 6 Jul 2014 12:09:30 +0200 -Subject: [PATCH 020/216] BCM2708: Migrate to the Common Clock Framework - -As part of moving towards using Device Tree, the Common Clock Framework -has to be used instead of the BCM2708 clock implementation. - -Selecting COMMON_CLK removes the need to set CLKDEV_LOOKUP and HAVE_CLK explicitly. - -CONFIG_ARCH_BCM2708_CHIPIT #ifdef's are removed. They are no longer in use. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/Kconfig | 3 +- - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/bcm2708.c | 79 +++++++++++++++++------------------------ - arch/arm/mach-bcm2708/clock.c | 61 ------------------------------- - arch/arm/mach-bcm2708/clock.h | 24 ------------- - 5 files changed, 34 insertions(+), 135 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/clock.c - delete mode 100644 arch/arm/mach-bcm2708/clock.h - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 9fcd395..c495965 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -373,11 +373,10 @@ config ARCH_BCM2708 - bool "Broadcom BCM2708 family" - select CPU_V6 - select ARM_AMBA -- select HAVE_CLK - select HAVE_SCHED_CLOCK - select NEED_MACH_GPIO_H - select NEED_MACH_MEMORY_H -- select CLKDEV_LOOKUP -+ select COMMON_CLK - select ARCH_HAS_CPUFREQ - select GENERIC_CLOCKEVENTS - select ARM_ERRATA_411920 -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index a722f3f..21e3521 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o dma.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 752dd46..080e260 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -27,6 +27,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -57,7 +59,6 @@ - - #include "bcm2708.h" - #include "armctrl.h" --#include "clock.h" - - #ifdef CONFIG_BCM_VC_CMA - #include -@@ -78,7 +79,7 @@ - - /* command line parameters */ - static unsigned boardrev, serial; --static unsigned uart_clock; -+static unsigned uart_clock = UART0_CLOCK; - static unsigned disk_led_gpio = 16; - static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; -@@ -188,51 +189,39 @@ static void __init bcm2708_clocksource_init(void) - } - } - -+struct clk __init *bcm2708_clk_register(const char *name, unsigned long fixed_rate) -+{ -+ struct clk *clk; - --/* -- * These are fixed clocks. -- */ --static struct clk ref24_clk = { -- .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */ --}; -+ clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, -+ fixed_rate); -+ if (IS_ERR(clk)) -+ pr_err("%s not registered\n", name); - --static struct clk osc_clk = { --#ifdef CONFIG_ARCH_BCM2708_CHIPIT -- .rate = 27000000, --#else -- .rate = 500000000, /* ARM clock is set from the VideoCore booter */ --#endif --}; -+ return clk; -+} - --/* warning - the USB needs a clock > 34MHz */ -+void __init bcm2708_register_clkdev(struct clk *clk, const char *name) -+{ -+ int ret; - --static struct clk sdhost_clk = { --#ifdef CONFIG_ARCH_BCM2708_CHIPIT -- .rate = 4000000, /* 4MHz */ --#else -- .rate = 250000000, /* 250MHz */ --#endif --}; -+ ret = clk_register_clkdev(clk, NULL, name); -+ if (ret) -+ pr_err("%s alias not registered\n", name); -+} - --static struct clk_lookup lookups[] = { -- { /* UART0 */ -- .dev_id = "dev:f1", -- .clk = &ref24_clk, -- }, -- { /* USB */ -- .dev_id = "bcm2708_usb", -- .clk = &osc_clk, -- }, { /* SPI */ -- .dev_id = "bcm2708_spi.0", -- .clk = &sdhost_clk, -- }, { /* BSC0 */ -- .dev_id = "bcm2708_i2c.0", -- .clk = &sdhost_clk, -- }, { /* BSC1 */ -- .dev_id = "bcm2708_i2c.1", -- .clk = &sdhost_clk, -- } --}; -+void __init bcm2708_init_clocks(void) -+{ -+ struct clk *clk; -+ -+ clk = bcm2708_clk_register("uart0_clk", uart_clock); -+ bcm2708_register_clkdev(clk, "dev:f1"); -+ -+ clk = bcm2708_clk_register("sdhost_clk", 250000000); -+ bcm2708_register_clkdev(clk, "bcm2708_spi.0"); -+ bcm2708_register_clkdev(clk, "bcm2708_i2c.0"); -+ bcm2708_register_clkdev(clk, "bcm2708_i2c.1"); -+} - - #define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ } - #define UART0_DMA { 15, 14 } -@@ -685,11 +674,7 @@ void __init bcm2708_init(void) - printk("bcm2708.uart_clock = %d\n", uart_clock); - pm_power_off = bcm2708_power_off; - -- if (uart_clock) -- lookups[0].clk->rate = uart_clock; -- -- for (i = 0; i < ARRAY_SIZE(lookups); i++) -- clkdev_add(&lookups[i]); -+ bcm2708_init_clocks(); - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_dmaengine_device); -diff --git a/arch/arm/mach-bcm2708/clock.c b/arch/arm/mach-bcm2708/clock.c -deleted file mode 100644 -index 4fc556e..0000000 ---- a/arch/arm/mach-bcm2708/clock.c -+++ /dev/null -@@ -1,61 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include "clock.h" -- --int clk_enable(struct clk *clk) --{ -- return 0; --} --EXPORT_SYMBOL(clk_enable); -- --void clk_disable(struct clk *clk) --{ --} --EXPORT_SYMBOL(clk_disable); -- --unsigned long clk_get_rate(struct clk *clk) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_get_rate); -- --long clk_round_rate(struct clk *clk, unsigned long rate) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_round_rate); -- --int clk_set_rate(struct clk *clk, unsigned long rate) --{ -- return -EIO; --} --EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2708/clock.h b/arch/arm/mach-bcm2708/clock.h -deleted file mode 100644 -index 5f9d725..0000000 ---- a/arch/arm/mach-bcm2708/clock.h -+++ /dev/null -@@ -1,24 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 -- */ --struct module; -- --struct clk { -- unsigned long rate; --}; - -From 5f8aad35cdb010ca9fc0c58cca2a5a11fce879ec Mon Sep 17 00:00:00 2001 -From: notro -Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 021/216] BCM2708: Add core Device Tree support - -Add the bare minimum needed to boot BCM2708 from a Device Tree. - -Signed-off-by: Noralf Tronnes - -BCM2708: DT: change 'axi' nodename to 'soc' - -Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835. -The VC4 bootloader fills in certain properties in the 'axi' subtree, -but since this is part of an upstreaming effort, the name is changed. - -Signed-off-by: Noralf Tronnes notro@tronnes.org - -BCM2708_DT: Correct length of the peripheral space ---- - arch/arm/boot/dts/Makefile | 21 ++++ - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 81 +++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 81 +++++++++++++++ - arch/arm/boot/dts/bcm2708.dtsi | 86 ++++++++++++++++ - arch/arm/boot/dts/bcm2709.dtsi | 165 +++++++++++++++++++++++++++++++ - arch/arm/mach-bcm2708/Kconfig | 8 ++ - arch/arm/mach-bcm2708/bcm2708.c | 45 ++++++++- - 7 files changed, 484 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts - create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts - create mode 100644 arch/arm/boot/dts/bcm2708.dtsi - create mode 100644 arch/arm/boot/dts/bcm2709.dtsi - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 992ea0b..25fbf52 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,17 @@ - ifeq ($(CONFIG_OF),y) - -+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb -+dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb -+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb -+ -+# Raspberry Pi -+ifeq ($(CONFIG_BCM2708_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ifeq ($(CONFIG_BCM2709_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb - # Keep at91 dtb files sorted alphabetically for each SoC -@@ -645,7 +657,16 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt6592-evb.dtb \ - mt8127-moose.dtb \ - mt8135-evbp1.dtb -+ -+targets += dtbs dtbs_install -+targets += $(dtb-y) -+ - endif - - always := $(dtb-y) - clean-files := *.dtb -+ -+# Enable fixups to support overlays on BCM2708 platforms -+ifeq ($(RPI_DT_OVERLAYS),y) -+ DTC_FLAGS ?= -@ -+endif -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -new file mode 100644 -index 0000000..983c23f ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+ -+/include/ "bcm2708.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ model = "Raspberry Pi Model B+"; -+ -+ aliases { -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ sound = &sound; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -new file mode 100644 -index 0000000..d8c6d15 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+ -+/include/ "bcm2708.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ model = "Raspberry Pi Model B"; -+ -+ aliases { -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ sound = &sound; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <28 29 30 31>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -new file mode 100644 -index 0000000..96b7311 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -0,0 +1,86 @@ -+/include/ "skeleton.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ model = "BCM2708"; -+ -+ interrupt-parent = <&intc>; -+ -+ chosen { -+ /* No padding required - the boot loader can do that. */ -+ bootargs = ""; -+ }; -+ -+ soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x7e000000 0x20000000 0x01000000>; -+ -+ intc: interrupt-controller { -+ compatible = "brcm,bcm2708-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio: gpio { -+ compatible = "brcm,bcm2835-gpio"; -+ reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ i2s: i2s@7e203000 { -+ compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; -+ -+ //dmas = <&dma 2>, -+ // <&dma 3>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@7e204000 { -+ compatible = "brcm,bcm2708-spi"; -+ reg = <0x7e204000 0x1000>; -+ interrupts = <2 22>; -+ clocks = <&clk_spi>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@7e205000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e205000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@7e804000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e804000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ }; -+ -+ clocks { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -new file mode 100644 -index 0000000..15c7e65 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -0,0 +1,165 @@ -+/include/ "skeleton.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2709"; -+ model = "BCM2709"; -+ -+ interrupt-parent = <&intc>; -+ -+ chosen { -+ /* No padding required - the boot loader can do that. */ -+ bootargs = ""; -+ }; -+ -+ soc: soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x7e000000 0x3f000000 0x01000000>; -+ -+ intc: interrupt-controller { -+ compatible = "brcm,bcm2708-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio: gpio { -+ compatible = "brcm,bcm2835-gpio"; -+ reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ i2s: i2s@7e203000 { -+ compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; -+ -+ //dmas = <&dma 2>, -+ // <&dma 3>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@7e204000 { -+ compatible = "brcm,bcm2708-spi"; -+ reg = <0x7e204000 0x1000>; -+ interrupts = <2 22>; -+ clocks = <&clk_spi>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@7e205000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e205000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@7e804000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e804000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ leds: leds { -+ compatible = "gpio-leds"; -+ -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ }; -+ }; -+ -+ arm-pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <3 9>; -+ }; -+ }; -+ -+ clocks { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_i2c: i2c { -+ compatible = "fixed-clock"; -+ reg = <1>; -+ #clock-cells = <0>; -+ clock-frequency = <250000000>; -+ }; -+ -+ clk_spi: clock@2 { -+ compatible = "fixed-clock"; -+ reg = <2>; -+ #clock-cells = <0>; -+ clock-output-names = "spi"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ -+ timer { -+ compatible = "arm,armv7-timer"; -+ clock-frequency = <19200000>; -+ interrupts = <3 0>, // PHYS_SECURE_PPI -+ <3 1>, // PHYS_NONSECURE_PPI -+ <3 3>, // VIRT_PPI -+ <3 2>; // HYP_PPI -+ always-on; -+ }; -+ -+ cpus: cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ v7_cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf00>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf01>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu2: cpu@2 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf02>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu3: cpu@3 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf03>; -+ clock-frequency = <800000000>; -+ }; -+ }; -+ -+ __overrides__ { -+ arm_freq = <&v7_cpu0>, "clock-frequency:0", -+ <&v7_cpu1>, "clock-frequency:0", -+ <&v7_cpu2>, "clock-frequency:0", -+ <&v7_cpu3>, "clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index e151ed4..182e7ba 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -9,6 +9,14 @@ config MACH_BCM2708 - help - Include support for the Broadcom(R) BCM2708 platform. - -+config BCM2708_DT -+ bool "BCM2708 Device Tree support" -+ depends on MACH_BCM2708 -+ default n -+ select USE_OF -+ help -+ Enable Device Tree support for BCM2708 -+ - config BCM2708_GPIO - bool "BCM2708 gpio support" - depends on MACH_BCM2708 -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 080e260..496cbcd 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -33,7 +33,9 @@ - #include - #include - #include -+#include - #include -+#include - - #include - #include -@@ -84,6 +86,8 @@ static unsigned disk_led_gpio = 16; - static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - -+static unsigned use_dt = 0; -+ - static void __init bcm2708_init_led(void); - - void __init bcm2708_init_irq(void) -@@ -599,6 +603,16 @@ int __init bcm_register_device(struct platform_device *pdev) - return ret; - } - -+/* -+ * Use these macros for platform and i2c devices that are present in the -+ * Device Tree. This way the devices are only added on non-DT systems. -+ */ -+#define bcm_register_device_dt(pdev) \ -+ if (!use_dt) bcm_register_device(pdev) -+ -+#define i2c_register_board_info_dt(busnum, info, n) \ -+ if (!use_dt) i2c_register_board_info(busnum, info, n) -+ - int calc_rsts(int partition) - { - return PM_PASSWORD | -@@ -664,6 +678,24 @@ static void bcm2708_power_off(void) - } - } - -+#ifdef CONFIG_OF -+static void __init bcm2708_dt_init(void) -+{ -+ int ret; -+ -+ of_clk_init(NULL); -+ ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -+ if (ret) { -+ pr_err("of_platform_populate failed: %d\n", ret); -+ /* Proceed as if CONFIG_OF was not defined */ -+ } else { -+ use_dt = 1; -+ } -+} -+#else -+static void __init bcm2708_dt_init(void) { } -+#endif /* CONFIG_OF */ -+ - void __init bcm2708_init(void) - { - int i; -@@ -675,6 +707,7 @@ void __init bcm2708_init(void) - pm_power_off = bcm2708_power_off; - - bcm2708_init_clocks(); -+ bcm2708_dt_init(); - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_dmaengine_device); -@@ -842,9 +875,9 @@ static struct platform_device bcm2708_led_device = { - - static void __init bcm2708_init_led(void) - { -- bcm2708_leds[0].gpio = disk_led_gpio; -- bcm2708_leds[0].active_low = disk_led_active_low; -- platform_device_register(&bcm2708_led_device); -+ bcm2708_leds[0].gpio = disk_led_gpio; -+ bcm2708_leds[0].active_low = disk_led_active_low; -+ bcm_register_device_dt(&bcm2708_led_device); - } - #else - static inline void bcm2708_init_led(void) -@@ -869,6 +902,11 @@ static void __init board_reserve(void) - #endif - } - -+static const char * const bcm2708_compat[] = { -+ "brcm,bcm2708", -+ NULL -+}; -+ - MACHINE_START(BCM2708, "BCM2708") - /* Maintainer: Broadcom Europe Ltd. */ - .map_io = bcm2708_map_io, -@@ -878,6 +916,7 @@ MACHINE_START(BCM2708, "BCM2708") - .init_early = bcm2708_init_early, - .reserve = board_reserve, - .restart = bcm2708_restart, -+ .dt_compat = bcm2708_compat, - MACHINE_END - - module_param(boardrev, uint, 0644); - -From 55bd100cb5e042a279b944a4ff3c0f00c51ed64c Mon Sep 17 00:00:00 2001 -From: Siarhei Siamashka -Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 022/216] fbdev: add FBIOCOPYAREA ioctl - -Based on the patch authored by Ali Gholami Rudi at - https://lkml.org/lkml/2009/7/13/153 - -Provide an ioctl for userspace applications, but only if this operation -is hardware accelerated (otherwide it does not make any sense). - -Signed-off-by: Siarhei Siamashka ---- - drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++ - include/uapi/linux/fb.h | 5 +++++ - 2 files changed, 35 insertions(+) - -diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index 0705d88..771992a 100644 ---- a/drivers/video/fbdev/core/fbmem.c -+++ b/drivers/video/fbdev/core/fbmem.c -@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) - } - EXPORT_SYMBOL(fb_blank); - -+static int fb_copyarea_user(struct fb_info *info, -+ struct fb_copyarea *copy) -+{ -+ int ret = 0; -+ if (!lock_fb_info(info)) -+ return -ENODEV; -+ if (copy->dx + copy->width > info->var.xres || -+ copy->sx + copy->width > info->var.xres || -+ copy->dy + copy->height > info->var.yres || -+ copy->sy + copy->height > info->var.yres) { -+ ret = -EINVAL; -+ goto out; -+ } -+ info->fbops->fb_copyarea(info, copy); -+out: -+ unlock_fb_info(info); -+ return ret; -+} -+ - static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) - { -@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - struct fb_cmap cmap_from; - struct fb_cmap_user cmap; - struct fb_event event; -+ struct fb_copyarea copy; - void __user *argp = (void __user *)arg; - long ret = 0; - -@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - unlock_fb_info(info); - console_unlock(); - break; -+ case FBIOCOPYAREA: -+ if (info->flags & FBINFO_HWACCEL_COPYAREA) { -+ /* only provide this ioctl if it is accelerated */ -+ if (copy_from_user(©, argp, sizeof(copy))) -+ return -EFAULT; -+ ret = fb_copyarea_user(info, ©); -+ break; -+ } -+ /* fall through */ - default: - if (!lock_fb_info(info)) - return -ENODEV; -@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, - case FBIOPAN_DISPLAY: - case FBIOGET_CON2FBMAP: - case FBIOPUT_CON2FBMAP: -+ case FBIOCOPYAREA: - arg = (unsigned long) compat_ptr(arg); - case FBIOBLANK: - ret = do_fb_ioctl(info, cmd, arg); -diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h -index fb795c3..fa72af0 100644 ---- a/include/uapi/linux/fb.h -+++ b/include/uapi/linux/fb.h -@@ -34,6 +34,11 @@ - #define FBIOPUT_MODEINFO 0x4617 - #define FBIOGET_DISPINFO 0x4618 - #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -+/* -+ * HACK: use 'z' in order not to clash with any other ioctl numbers which might -+ * be concurrently added to the mainline kernel -+ */ -+#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea) - - #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ - #define FB_TYPE_PLANES 1 /* Non interleaved planes */ - -From ee44a85f3a6b76509c3de7ee16164e8d32eecc24 Mon Sep 17 00:00:00 2001 -From: Harm Hanemaaijer -Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 025/216] Speed up console framebuffer imageblit function - -Especially on platforms with a slower CPU but a relatively high -framebuffer fill bandwidth, like current ARM devices, the existing -console monochrome imageblit function used to draw console text is -suboptimal for common pixel depths such as 16bpp and 32bpp. The existing -code is quite general and can deal with several pixel depths. By creating -special case functions for 16bpp and 32bpp, by far the most common pixel -formats used on modern systems, a significant speed-up is attained -which can be readily felt on ARM-based devices like the Raspberry Pi -and the Allwinner platform, but should help any platform using the -fb layer. - -The special case functions allow constant folding, eliminating a number -of instructions including divide operations, and allow the use of an -unrolled loop, eliminating instructions with a variable shift size, -reducing source memory access instructions, and eliminating excessive -branching. These unrolled loops also allow much better code optimization -by the C compiler. The code that selects which optimized variant is used -is also simplified, eliminating integer divide instructions. - -The speed-up, measured by timing 'cat file.txt' in the console, varies -between 40% and 70%, when testing on the Raspberry Pi and Allwinner -ARM-based platforms, depending on font size and the pixel depth, with -the greater benefit for 32bpp. - -Signed-off-by: Harm Hanemaaijer ---- - drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++-- - 1 file changed, 147 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c -index a2bb276..436494f 100644 ---- a/drivers/video/fbdev/core/cfbimgblt.c -+++ b/drivers/video/fbdev/core/cfbimgblt.c -@@ -28,6 +28,11 @@ - * - * Also need to add code to deal with cards endians that are different than - * the native cpu endians. I also need to deal with MSB position in the word. -+ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013: -+ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are -+ * significantly faster than the previous implementation. -+ * - Simplify the fast/slow_imageblit selection code, avoiding integer -+ * divides. - */ - #include - #include -@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * - } - } - -+/* -+ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded -+ * into the code, main loop unrolled. -+ */ -+ -+static inline void fast_imageblit16(const struct fb_image *image, -+ struct fb_info *p, u8 __iomem * dst1, -+ u32 fgcolor, u32 bgcolor) -+{ -+ u32 fgx = fgcolor, bgx = bgcolor; -+ u32 spitch = (image->width + 7) / 8; -+ u32 end_mask, eorx; -+ const char *s = image->data, *src; -+ u32 __iomem *dst; -+ const u32 *tab = NULL; -+ int i, j, k; -+ -+ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; -+ -+ fgx <<= 16; -+ bgx <<= 16; -+ fgx |= fgcolor; -+ bgx |= bgcolor; -+ -+ eorx = fgx ^ bgx; -+ k = image->width / 2; -+ -+ for (i = image->height; i--;) { -+ dst = (u32 __iomem *) dst1; -+ src = s; -+ -+ j = k; -+ while (j >= 4) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 6) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 4) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 2) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[bits & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ src++; -+ j -= 4; -+ } -+ if (j != 0) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 6) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ if (j >= 2) { -+ end_mask = tab[(bits >> 4) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ if (j == 3) { -+ end_mask = tab[(bits >> 2) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst); -+ } -+ } -+ } -+ dst1 += p->fix.line_length; -+ s += spitch; -+ } -+} -+ -+/* -+ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded -+ * into the code, main loop unrolled. -+ */ -+ -+static inline void fast_imageblit32(const struct fb_image *image, -+ struct fb_info *p, u8 __iomem * dst1, -+ u32 fgcolor, u32 bgcolor) -+{ -+ u32 fgx = fgcolor, bgx = bgcolor; -+ u32 spitch = (image->width + 7) / 8; -+ u32 end_mask, eorx; -+ const char *s = image->data, *src; -+ u32 __iomem *dst; -+ const u32 *tab = NULL; -+ int i, j, k; -+ -+ tab = cfb_tab32; -+ -+ eorx = fgx ^ bgx; -+ k = image->width; -+ -+ for (i = image->height; i--;) { -+ dst = (u32 __iomem *) dst1; -+ src = s; -+ -+ j = k; -+ while (j >= 8) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 6) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 5) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 4) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 3) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 2) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 1) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[bits & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ src++; -+ j -= 8; -+ } -+ if (j != 0) { -+ u32 bits = (u32) * src; -+ while (j > 1) { -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ bits <<= 1; -+ j--; -+ } -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst); -+ } -+ dst1 += p->fix.line_length; -+ s += spitch; -+ } -+} -+ - void cfb_imageblit(struct fb_info *p, const struct fb_image *image) - { - u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; -@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) - bgcolor = image->bg_color; - } - -- if (32 % bpp == 0 && !start_index && !pitch_index && -- ((width & (32/bpp-1)) == 0) && -- bpp >= 8 && bpp <= 32) -- fast_imageblit(image, p, dst1, fgcolor, bgcolor); -- else -+ if (!start_index && !pitch_index) { -+ if (bpp == 32) -+ fast_imageblit32(image, p, dst1, fgcolor, -+ bgcolor); -+ else if (bpp == 16 && (width & 1) == 0) -+ fast_imageblit16(image, p, dst1, fgcolor, -+ bgcolor); -+ else if (bpp == 8 && (width & 3) == 0) -+ fast_imageblit(image, p, dst1, fgcolor, -+ bgcolor); -+ else -+ slow_imageblit(image, p, dst1, fgcolor, -+ bgcolor, -+ start_index, pitch_index); -+ } else - slow_imageblit(image, p, dst1, fgcolor, bgcolor, - start_index, pitch_index); - } else - -From 12b6956e3ba31498771d282025fc4a44b6648559 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 026/216] Allow mac address to be set in smsc95xx - -Signed-off-by: popcornmix ---- - drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 56 insertions(+) - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 26423ad..e29a323 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -59,6 +59,7 @@ - #define SUSPEND_SUSPEND3 (0x08) - #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ - SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) -+#define MAC_ADDR_LEN (6) - - struct smsc95xx_priv { - u32 mac_cr; -@@ -74,6 +75,10 @@ static bool turbo_mode = true; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - -+static char *macaddr = ":"; -+module_param(macaddr, charp, 0); -+MODULE_PARM_DESC(macaddr, "MAC address"); -+ - static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, - u32 *data, int in_pm) - { -@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) - return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); - } - -+/* Check the macaddr module parameter for a MAC address */ -+static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) -+{ -+ int i, j, got_num, num; -+ u8 mtbl[MAC_ADDR_LEN]; -+ -+ if (macaddr[0] == ':') -+ return 0; -+ -+ i = 0; -+ j = 0; -+ num = 0; -+ got_num = 0; -+ while (j < MAC_ADDR_LEN) { -+ if (macaddr[i] && macaddr[i] != ':') { -+ got_num++; -+ if ('0' <= macaddr[i] && macaddr[i] <= '9') -+ num = num * 16 + macaddr[i] - '0'; -+ else if ('A' <= macaddr[i] && macaddr[i] <= 'F') -+ num = num * 16 + 10 + macaddr[i] - 'A'; -+ else if ('a' <= macaddr[i] && macaddr[i] <= 'f') -+ num = num * 16 + 10 + macaddr[i] - 'a'; -+ else -+ break; -+ i++; -+ } else if (got_num == 2) { -+ mtbl[j++] = (u8) num; -+ num = 0; -+ got_num = 0; -+ i++; -+ } else { -+ break; -+ } -+ } -+ -+ if (j == MAC_ADDR_LEN) { -+ netif_dbg(dev, ifup, dev->net, "Overriding MAC address with: " -+ "%02x:%02x:%02x:%02x:%02x:%02x\n", mtbl[0], mtbl[1], mtbl[2], -+ mtbl[3], mtbl[4], mtbl[5]); -+ for (i = 0; i < MAC_ADDR_LEN; i++) -+ dev_mac[i] = mtbl[i]; -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ - static void smsc95xx_init_mac_address(struct usbnet *dev) - { -+ /* Check module parameters */ -+ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr)) -+ return; -+ - /* try reading mac address from EEPROM */ - if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, - dev->net->dev_addr) == 0) { - -From 03ecfd1c727358b884730a06b05d072ef28ebffd Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 027/216] enabling the realtime clock 1-wire chip DS1307 and - 1-wire on GPIO4 (as a module) - -1-wire: Add support for configuring pin for w1-gpio kernel module -See: https://github.com/raspberrypi/linux/pull/457 - -Add bitbanging pullups, use them for w1-gpio - -Allows parasite power to work, uses module option pullup=1 - -bcm2708: Ensure 1-wire pullup is disabled by default, and expose as module parameter - -Signed-off-by: Alex J Lennon - -w1-gpio: Add gpiopin module parameter and correctly free up gpio pull-up pin, if set - -Signed-off-by: Alex J Lennon ---- - arch/arm/mach-bcm2708/bcm2708.c | 29 ++++++++++++++++++++++ - drivers/w1/masters/w1-gpio.c | 55 +++++++++++++++++++++++++++++++++++++---- - drivers/w1/w1.h | 6 +++++ - drivers/w1/w1_int.c | 14 +++++++++++ - drivers/w1/w1_io.c | 18 +++++++++++--- - 5 files changed, 114 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 496cbcd..5873f8b 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -79,12 +80,19 @@ - */ - #define DMA_MASK_BITS_COMMON 32 - -+// use GPIO 4 for the one-wire GPIO pin, if enabled -+#define W1_GPIO 4 -+// ensure one-wire GPIO pullup is disabled by default -+#define W1_PULLUP -1 -+ - /* command line parameters */ - static unsigned boardrev, serial; - static unsigned uart_clock = UART0_CLOCK; - static unsigned disk_led_gpio = 16; - static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; -+static unsigned w1_gpio_pin = W1_GPIO; -+static unsigned w1_gpio_pullup = W1_PULLUP; - - static unsigned use_dt = 0; - -@@ -256,6 +264,20 @@ static struct platform_device bcm2708_dmaengine_device = { - .id = -1, - }; - -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+static struct w1_gpio_platform_data w1_gpio_pdata = { -+ .pin = W1_GPIO, -+ .ext_pullup_enable_pin = W1_PULLUP, -+ .is_open_drain = 0, -+}; -+ -+static struct platform_device w1_device = { -+ .name = "w1-gpio", -+ .id = -1, -+ .dev.platform_data = &w1_gpio_pdata, -+}; -+#endif -+ - static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_fb_device = { -@@ -715,6 +737,11 @@ void __init bcm2708_init(void) - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device(&bcm2708_gpio_device); - #endif -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+ w1_gpio_pdata.pin = w1_gpio_pin; -+ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -+ bcm_register_device_dt(&w1_device); -+#endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); -@@ -925,3 +952,5 @@ module_param(uart_clock, uint, 0644); - module_param(disk_led_gpio, uint, 0644); - module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); -+module_param(w1_gpio_pin, uint, 0644); -+module_param(w1_gpio_pullup, uint, 0644); -diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c -index b99a932..3ad15cc 100644 ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -23,6 +23,15 @@ - #include "../w1.h" - #include "../w1_int.h" - -+static int w1_gpio_pullup = -1; -+static int w1_gpio_pullup_orig = -1; -+module_param_named(pullup, w1_gpio_pullup, int, 0); -+MODULE_PARM_DESC(pullup, "GPIO pin pullup number"); -+static int w1_gpio_pin = -1; -+static int w1_gpio_pin_orig = -1; -+module_param_named(gpiopin, w1_gpio_pin, int, 0); -+MODULE_PARM_DESC(gpiopin, "GPIO pin number"); -+ - static u8 w1_gpio_set_pullup(void *data, int delay) - { - struct w1_gpio_platform_data *pdata = data; -@@ -67,6 +76,16 @@ static u8 w1_gpio_read_bit(void *data) - return gpio_get_value(pdata->pin) ? 1 : 0; - } - -+static void w1_gpio_bitbang_pullup(void *data, u8 on) -+{ -+ struct w1_gpio_platform_data *pdata = data; -+ -+ if (on) -+ gpio_direction_output(pdata->pin, 1); -+ else -+ gpio_direction_input(pdata->pin); -+} -+ - #if defined(CONFIG_OF) - static struct of_device_id w1_gpio_dt_ids[] = { - { .compatible = "w1-gpio" }, -@@ -113,13 +132,15 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - static int w1_gpio_probe(struct platform_device *pdev) - { - struct w1_bus_master *master; -- struct w1_gpio_platform_data *pdata; -+ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; - int err; - -- if (of_have_populated_dt()) { -- err = w1_gpio_probe_dt(pdev); -- if (err < 0) -- return err; -+ if(pdata == NULL) { -+ if (of_have_populated_dt()) { -+ err = w1_gpio_probe_dt(pdev); -+ if (err < 0) -+ return err; -+ } - } - - pdata = dev_get_platdata(&pdev->dev); -@@ -136,6 +157,19 @@ static int w1_gpio_probe(struct platform_device *pdev) - return -ENOMEM; - } - -+ w1_gpio_pin_orig = pdata->pin; -+ w1_gpio_pullup_orig = pdata->ext_pullup_enable_pin; -+ -+ if(gpio_is_valid(w1_gpio_pin)) { -+ pdata->pin = w1_gpio_pin; -+ pdata->ext_pullup_enable_pin = -1; -+ } -+ if(gpio_is_valid(w1_gpio_pullup)) { -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup; -+ } -+ -+ dev_info(&pdev->dev, "gpio pin %d, gpio pullup pin %d\n", pdata->pin, pdata->ext_pullup_enable_pin); -+ - err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); - if (err) { - dev_err(&pdev->dev, "gpio_request (pin) failed\n"); -@@ -165,6 +199,14 @@ static int w1_gpio_probe(struct platform_device *pdev) - master->set_pullup = w1_gpio_set_pullup; - } - -+ if (gpio_is_valid(w1_gpio_pullup)) { -+ if (pdata->is_open_drain) -+ printk(KERN_ERR "w1-gpio 'pullup' option " -+ "doesn't work with open drain GPIO\n"); -+ else -+ master->bitbang_pullup = w1_gpio_bitbang_pullup; -+ } -+ - err = w1_add_master_device(master); - if (err) { - dev_err(&pdev->dev, "w1_add_master device failed\n"); -@@ -195,6 +237,9 @@ static int w1_gpio_remove(struct platform_device *pdev) - - w1_remove_master_device(master); - -+ pdata->pin = w1_gpio_pin_orig; -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_orig; -+ - return 0; - } - -diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h -index 56a49ba..881d728 100644 ---- a/drivers/w1/w1.h -+++ b/drivers/w1/w1.h -@@ -171,6 +171,12 @@ struct w1_bus_master - - u8 (*set_pullup)(void *, int); - -+ /** -+ * Turns the pullup on/off in bitbanging mode, takes an on/off argument. -+ * @return -1=Error, 0=completed -+ */ -+ void (*bitbang_pullup) (void *, u8); -+ - void (*search)(void *, struct w1_master *, - u8, w1_slave_found_callback); - }; -diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c -index 47249a3..a4b4a8d 100644 ---- a/drivers/w1/w1_int.c -+++ b/drivers/w1/w1_int.c -@@ -123,6 +123,20 @@ int w1_add_master_device(struct w1_bus_master *master) - return(-EINVAL); - } - -+ /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup -+ * and takes care of timing itself */ -+ if (!master->write_byte && !master->touch_bit && master->set_pullup) { -+ printk(KERN_ERR "w1_add_master_device: set_pullup requires " -+ "write_byte or touch_bit, disabling\n"); -+ master->set_pullup = NULL; -+ } -+ -+ if (master->set_pullup && master->bitbang_pullup) { -+ printk(KERN_ERR "w1_add_master_device: set_pullup should not " -+ "be set when bitbang_pullup is used, disabling\n"); -+ master->set_pullup = NULL; -+ } -+ - /* Lock until the device is added (or not) to w1_masters. */ - mutex_lock(&w1_mlock); - /* Search for the first available id (starting at 1). */ -diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c -index 2820924..fd0550f 100644 ---- a/drivers/w1/w1_io.c -+++ b/drivers/w1/w1_io.c -@@ -134,10 +134,22 @@ static void w1_pre_write(struct w1_master *dev) - static void w1_post_write(struct w1_master *dev) - { - if (dev->pullup_duration) { -- if (dev->enable_pullup && dev->bus_master->set_pullup) -- dev->bus_master->set_pullup(dev->bus_master->data, 0); -- else -+ if (dev->enable_pullup) { -+ if (dev->bus_master->set_pullup) { -+ dev->bus_master->set_pullup(dev-> -+ bus_master->data, -+ 0); -+ } else if (dev->bus_master->bitbang_pullup) { -+ dev->bus_master-> -+ bitbang_pullup(dev->bus_master->data, 1); -+ msleep(dev->pullup_duration); -+ dev->bus_master-> -+ bitbang_pullup(dev->bus_master->data, 0); -+ } -+ } else { - msleep(dev->pullup_duration); -+ } -+ - dev->pullup_duration = 0; - } - } - -From 4624b823abd044524b26cb4d7111564f141e540f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 029/216] config: Enable CONFIG_MEMCG, but leave it disabled - (due to memory cost). Enable with cgroup_enable=memory. - ---- - kernel/cgroup.c | 23 +++++++++++++++++++++++ - mm/memcontrol.c | 1 + - 2 files changed, 24 insertions(+) - -diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index 29a7b2c..54fd2f0 100644 ---- a/kernel/cgroup.c -+++ b/kernel/cgroup.c -@@ -5393,6 +5393,29 @@ static int __init cgroup_disable(char *str) - } - __setup("cgroup_disable=", cgroup_disable); - -+static int __init cgroup_enable(char *str) -+{ -+ struct cgroup_subsys *ss; -+ char *token; -+ int i; -+ -+ while ((token = strsep(&str, ",")) != NULL) { -+ if (!*token) -+ continue; -+ -+ for_each_subsys(ss, i) { -+ if (!strcmp(token, ss->name)) { -+ ss->disabled = 0; -+ printk(KERN_INFO "Enabling %s control group" -+ " subsystem\n", ss->name); -+ break; -+ } -+ } -+ } -+ return 1; -+} -+__setup("cgroup_enable=", cgroup_enable); -+ - static int __init cgroup_set_legacy_files_on_dfl(char *str) - { - printk("cgroup: using legacy files on the default hierarchy\n"); -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index b34ef4a..c2aa348 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5391,6 +5391,7 @@ struct cgroup_subsys memory_cgrp_subsys = { - .dfl_cftypes = memory_files, - .legacy_cftypes = mem_cgroup_legacy_files, - .early_init = 0, -+ .disabled = 1, - }; - - /** - -From 14913d5804e6cc14027404667dbacd69267fd032 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 14:33:38 +0100 -Subject: [PATCH 030/216] ASoC: Add support for BCM2708 - -This driver adds support for digital audio (I2S) -for the BCM2708 SoC that is used by the -Raspberry Pi. External audio codecs can be -connected to the Raspberry Pi via P5 header. - -It relies on cyclic DMA engine support for BCM2708. - -Signed-off-by: Florian Meier - -ASoC: BCM2708: Add 24 bit support - -This adds 24 bit support to the I2S driver of the BCM2708. -Besides enabling the 24 bit flags, it includes two bug fixes: - -MMAP is not supported. Claiming this leads to strange issues -when the format of driver and file do not match. - -The datasheet states that the width extension bit should be set -for widths greater than 24, but greater or equal would be correct. -This follows from the definition of the width field. - -Signed-off-by: Florian Meier - -bcm2708-i2s: Update bclk_ratio to more correct values - -Move GPIO setup to hw_params. - -This is used to stop the I2S driver from breaking -the GPIO setup for other uses of the PCM interface - -Configure GPIOs for I2S based on revision/card settings - -With RPi model B+, assignment of the I2S GPIO pins has changed. -This patch uses the board revision to auto-detect the GPIOs used -for I2S. It also allows sound card drivers to set the GPIOs that -should be used. This is especially important with the Compute -Module. - -bcm2708-i2s: Avoid leak from iomap when accessing gpio - -bcm2708: Eliminate i2s debugfs directory error - -Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') -to avoid the name clash when registering debugfs entries. ---- - sound/soc/bcm/Kconfig | 11 + - sound/soc/bcm/Makefile | 4 + - sound/soc/bcm/bcm2708-i2s.c | 1009 +++++++++++++++++++++++++++++++++++++++++++ - sound/soc/bcm/bcm2708-i2s.h | 35 ++ - 4 files changed, 1059 insertions(+) - create mode 100644 sound/soc/bcm/bcm2708-i2s.c - create mode 100644 sound/soc/bcm/bcm2708-i2s.h - -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 6a834e1..8642296 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -7,3 +7,14 @@ config SND_BCM2835_SOC_I2S - Say Y or M if you want to add support for codecs attached to - the BCM2835 I2S interface. You will also need - to select the audio interfaces to support below. -+ -+config SND_BCM2708_SOC_I2S -+ tristate "SoC Audio support for the Broadcom BCM2708 I2S module" -+ depends on MACH_BCM2708 || MACH_BCM2709 -+ select REGMAP_MMIO -+ select SND_SOC_DMAENGINE_PCM -+ select SND_SOC_GENERIC_DMAENGINE_PCM -+ help -+ Say Y or M if you want to add support for codecs attached to -+ the BCM2708 I2S interface. You will also need -+ to select the audio interfaces to support below. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index bc816b7..f8bbe1f 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -3,3 +3,7 @@ snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o - - obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o - -+# BCM2708 Platform Support -+snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o -+ -+obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o -diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c -new file mode 100644 -index 0000000..a3b65dc ---- /dev/null -+++ b/sound/soc/bcm/bcm2708-i2s.c -@@ -0,0 +1,1009 @@ -+/* -+ * ALSA SoC I2S Audio Layer for Broadcom BCM2708 SoC -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * Based on -+ * Raspberry Pi PCM I2S ALSA Driver -+ * Copyright (c) by Phil Poole 2013 -+ * -+ * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor -+ * Vladimir Barinov, -+ * Copyright (C) 2007 MontaVista Software, Inc., -+ * -+ * OMAP ALSA SoC DAI driver using McBSP port -+ * Copyright (C) 2008 Nokia Corporation -+ * Contact: Jarkko Nikula -+ * Peter Ujfalusi -+ * -+ * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver -+ * Author: Timur Tabi -+ * Copyright 2007-2010 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * 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. -+ */ -+ -+#include "bcm2708-i2s.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+/* Clock registers */ -+#define BCM2708_CLK_PCMCTL_REG 0x00 -+#define BCM2708_CLK_PCMDIV_REG 0x04 -+ -+/* Clock register settings */ -+#define BCM2708_CLK_PASSWD (0x5a000000) -+#define BCM2708_CLK_PASSWD_MASK (0xff000000) -+#define BCM2708_CLK_MASH(v) ((v) << 9) -+#define BCM2708_CLK_FLIP BIT(8) -+#define BCM2708_CLK_BUSY BIT(7) -+#define BCM2708_CLK_KILL BIT(5) -+#define BCM2708_CLK_ENAB BIT(4) -+#define BCM2708_CLK_SRC(v) (v) -+ -+#define BCM2708_CLK_SHIFT (12) -+#define BCM2708_CLK_DIVI(v) ((v) << BCM2708_CLK_SHIFT) -+#define BCM2708_CLK_DIVF(v) (v) -+#define BCM2708_CLK_DIVF_MASK (0xFFF) -+ -+enum { -+ BCM2708_CLK_MASH_0 = 0, -+ BCM2708_CLK_MASH_1, -+ BCM2708_CLK_MASH_2, -+ BCM2708_CLK_MASH_3, -+}; -+ -+enum { -+ BCM2708_CLK_SRC_GND = 0, -+ BCM2708_CLK_SRC_OSC, -+ BCM2708_CLK_SRC_DBG0, -+ BCM2708_CLK_SRC_DBG1, -+ BCM2708_CLK_SRC_PLLA, -+ BCM2708_CLK_SRC_PLLC, -+ BCM2708_CLK_SRC_PLLD, -+ BCM2708_CLK_SRC_HDMI, -+}; -+ -+/* Most clocks are not useable (freq = 0) */ -+static const unsigned int bcm2708_clk_freq[BCM2708_CLK_SRC_HDMI+1] = { -+ [BCM2708_CLK_SRC_GND] = 0, -+ [BCM2708_CLK_SRC_OSC] = 19200000, -+ [BCM2708_CLK_SRC_DBG0] = 0, -+ [BCM2708_CLK_SRC_DBG1] = 0, -+ [BCM2708_CLK_SRC_PLLA] = 0, -+ [BCM2708_CLK_SRC_PLLC] = 0, -+ [BCM2708_CLK_SRC_PLLD] = 500000000, -+ [BCM2708_CLK_SRC_HDMI] = 0, -+}; -+ -+/* I2S registers */ -+#define BCM2708_I2S_CS_A_REG 0x00 -+#define BCM2708_I2S_FIFO_A_REG 0x04 -+#define BCM2708_I2S_MODE_A_REG 0x08 -+#define BCM2708_I2S_RXC_A_REG 0x0c -+#define BCM2708_I2S_TXC_A_REG 0x10 -+#define BCM2708_I2S_DREQ_A_REG 0x14 -+#define BCM2708_I2S_INTEN_A_REG 0x18 -+#define BCM2708_I2S_INTSTC_A_REG 0x1c -+#define BCM2708_I2S_GRAY_REG 0x20 -+ -+/* I2S register settings */ -+#define BCM2708_I2S_STBY BIT(25) -+#define BCM2708_I2S_SYNC BIT(24) -+#define BCM2708_I2S_RXSEX BIT(23) -+#define BCM2708_I2S_RXF BIT(22) -+#define BCM2708_I2S_TXE BIT(21) -+#define BCM2708_I2S_RXD BIT(20) -+#define BCM2708_I2S_TXD BIT(19) -+#define BCM2708_I2S_RXR BIT(18) -+#define BCM2708_I2S_TXW BIT(17) -+#define BCM2708_I2S_CS_RXERR BIT(16) -+#define BCM2708_I2S_CS_TXERR BIT(15) -+#define BCM2708_I2S_RXSYNC BIT(14) -+#define BCM2708_I2S_TXSYNC BIT(13) -+#define BCM2708_I2S_DMAEN BIT(9) -+#define BCM2708_I2S_RXTHR(v) ((v) << 7) -+#define BCM2708_I2S_TXTHR(v) ((v) << 5) -+#define BCM2708_I2S_RXCLR BIT(4) -+#define BCM2708_I2S_TXCLR BIT(3) -+#define BCM2708_I2S_TXON BIT(2) -+#define BCM2708_I2S_RXON BIT(1) -+#define BCM2708_I2S_EN (1) -+ -+#define BCM2708_I2S_CLKDIS BIT(28) -+#define BCM2708_I2S_PDMN BIT(27) -+#define BCM2708_I2S_PDME BIT(26) -+#define BCM2708_I2S_FRXP BIT(25) -+#define BCM2708_I2S_FTXP BIT(24) -+#define BCM2708_I2S_CLKM BIT(23) -+#define BCM2708_I2S_CLKI BIT(22) -+#define BCM2708_I2S_FSM BIT(21) -+#define BCM2708_I2S_FSI BIT(20) -+#define BCM2708_I2S_FLEN(v) ((v) << 10) -+#define BCM2708_I2S_FSLEN(v) (v) -+ -+#define BCM2708_I2S_CHWEX BIT(15) -+#define BCM2708_I2S_CHEN BIT(14) -+#define BCM2708_I2S_CHPOS(v) ((v) << 4) -+#define BCM2708_I2S_CHWID(v) (v) -+#define BCM2708_I2S_CH1(v) ((v) << 16) -+#define BCM2708_I2S_CH2(v) (v) -+ -+#define BCM2708_I2S_TX_PANIC(v) ((v) << 24) -+#define BCM2708_I2S_RX_PANIC(v) ((v) << 16) -+#define BCM2708_I2S_TX(v) ((v) << 8) -+#define BCM2708_I2S_RX(v) (v) -+ -+#define BCM2708_I2S_INT_RXERR BIT(3) -+#define BCM2708_I2S_INT_TXERR BIT(2) -+#define BCM2708_I2S_INT_RXR BIT(1) -+#define BCM2708_I2S_INT_TXW BIT(0) -+ -+/* I2S DMA interface */ -+#define BCM2708_I2S_FIFO_PHYSICAL_ADDR 0x7E203004 -+#define BCM2708_DMA_DREQ_PCM_TX 2 -+#define BCM2708_DMA_DREQ_PCM_RX 3 -+ -+/* I2S pin configuration */ -+static int bcm2708_i2s_gpio=BCM2708_I2S_GPIO_AUTO; -+ -+/* General device struct */ -+struct bcm2708_i2s_dev { -+ struct device *dev; -+ struct snd_dmaengine_dai_dma_data dma_data[2]; -+ unsigned int fmt; -+ unsigned int bclk_ratio; -+ -+ struct regmap *i2s_regmap; -+ struct regmap *clk_regmap; -+}; -+ -+void bcm2708_i2s_set_gpio(int gpio) { -+ bcm2708_i2s_gpio=gpio; -+} -+EXPORT_SYMBOL(bcm2708_i2s_set_gpio); -+ -+ -+static void bcm2708_i2s_start_clock(struct bcm2708_i2s_dev *dev) -+{ -+ /* Start the clock if in master mode */ -+ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; -+ -+ switch (master) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ case SND_SOC_DAIFMT_CBS_CFM: -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, -+ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void bcm2708_i2s_stop_clock(struct bcm2708_i2s_dev *dev) -+{ -+ uint32_t clkreg; -+ int timeout = 1000; -+ -+ /* Stop clock */ -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, -+ BCM2708_CLK_PASSWD); -+ -+ /* Wait for the BUSY flag going down */ -+ while (--timeout) { -+ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); -+ if (!(clkreg & BCM2708_CLK_BUSY)) -+ break; -+ } -+ -+ if (!timeout) { -+ /* KILL the clock */ -+ dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n"); -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD_MASK, -+ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD); -+ } -+} -+ -+static void bcm2708_i2s_clear_fifos(struct bcm2708_i2s_dev *dev, -+ bool tx, bool rx) -+{ -+ int timeout = 1000; -+ uint32_t syncval; -+ uint32_t csreg; -+ uint32_t i2s_active_state; -+ uint32_t clkreg; -+ uint32_t clk_active_state; -+ uint32_t off; -+ uint32_t clr; -+ -+ off = tx ? BCM2708_I2S_TXON : 0; -+ off |= rx ? BCM2708_I2S_RXON : 0; -+ -+ clr = tx ? BCM2708_I2S_TXCLR : 0; -+ clr |= rx ? BCM2708_I2S_RXCLR : 0; -+ -+ /* Backup the current state */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); -+ i2s_active_state = csreg & (BCM2708_I2S_RXON | BCM2708_I2S_TXON); -+ -+ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); -+ clk_active_state = clkreg & BCM2708_CLK_ENAB; -+ -+ /* Start clock if not running */ -+ if (!clk_active_state) { -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, -+ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); -+ } -+ -+ /* Stop I2S module */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, off, 0); -+ -+ /* -+ * Clear the FIFOs -+ * Requires at least 2 PCM clock cycles to take effect -+ */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, clr, clr); -+ -+ /* Wait for 2 PCM clock cycles */ -+ -+ /* -+ * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back -+ * FIXME: This does not seem to work for slave mode! -+ */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &syncval); -+ syncval &= BCM2708_I2S_SYNC; -+ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_SYNC, ~syncval); -+ -+ /* Wait for the SYNC flag changing it's state */ -+ while (--timeout) { -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); -+ if ((csreg & BCM2708_I2S_SYNC) != syncval) -+ break; -+ } -+ -+ if (!timeout) -+ dev_err(dev->dev, "I2S SYNC error!\n"); -+ -+ /* Stop clock if it was not running before */ -+ if (!clk_active_state) -+ bcm2708_i2s_stop_clock(dev); -+ -+ /* Restore I2S state */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_RXON | BCM2708_I2S_TXON, i2s_active_state); -+} -+ -+static int bcm2708_i2s_set_dai_fmt(struct snd_soc_dai *dai, -+ unsigned int fmt) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ dev->fmt = fmt; -+ return 0; -+} -+ -+static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, -+ unsigned int ratio) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ dev->bclk_ratio = ratio; -+ return 0; -+} -+ -+ -+static int bcm2708_i2s_set_function(unsigned offset, int function) -+{ -+ #define GPIOFSEL(x) (0x00+(x)*4) -+ void __iomem *gpio = __io_address(GPIO_BASE); -+ unsigned alt = function <= 3 ? function + 4: function == 4 ? 3 : 2; -+ unsigned gpiodir; -+ unsigned gpio_bank = offset / 10; -+ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3; -+ -+ if (offset >= BCM2708_NR_GPIOS) -+ return -EINVAL; -+ -+ gpiodir = readl(gpio + GPIOFSEL(gpio_bank)); -+ gpiodir &= ~(7 << gpio_field_offset); -+ gpiodir |= alt << gpio_field_offset; -+ writel(gpiodir, gpio + GPIOFSEL(gpio_bank)); -+ return 0; -+} -+ -+static void bcm2708_i2s_setup_gpio(void) -+{ -+ /* -+ * This is the common way to handle the GPIO pins for -+ * the Raspberry Pi. -+ * TODO Better way would be to handle -+ * this in the device tree! -+ */ -+ int pin,pinconfig,startpin,alt; -+ -+ /* SPI is on different GPIOs on different boards */ -+ /* for Raspberry Pi B+, this is pin GPIO18-21, for original on 28-31 */ -+ if (bcm2708_i2s_gpio==BCM2708_I2S_GPIO_AUTO) { -+ if ((system_rev & 0xffffff) >= 0x10) { -+ /* Model B+ */ -+ pinconfig=BCM2708_I2S_GPIO_PIN18; -+ } else { -+ /* original */ -+ pinconfig=BCM2708_I2S_GPIO_PIN28; -+ } -+ } else { -+ pinconfig=bcm2708_i2s_gpio; -+ } -+ -+ if (pinconfig==BCM2708_I2S_GPIO_PIN18) { -+ startpin=18; -+ alt=BCM2708_I2S_GPIO_PIN18_ALT; -+ } else if (pinconfig==BCM2708_I2S_GPIO_PIN28) { -+ startpin=28; -+ alt=BCM2708_I2S_GPIO_PIN28_ALT; -+ } else { -+ printk(KERN_INFO "Can't configure I2S GPIOs, unknown pin mode for I2S: %i\n",pinconfig); -+ return; -+ } -+ -+ /* configure I2S pins to correct ALT mode */ -+ for (pin = startpin; pin <= startpin+3; pin++) { -+ bcm2708_i2s_set_function(pin, alt); -+ } -+} -+ -+static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ unsigned int sampling_rate = params_rate(params); -+ unsigned int data_length, data_delay, bclk_ratio; -+ unsigned int ch1pos, ch2pos, mode, format; -+ unsigned int mash = BCM2708_CLK_MASH_1; -+ unsigned int divi, divf, target_frequency; -+ int clk_src = -1; -+ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; -+ bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS -+ || master == SND_SOC_DAIFMT_CBS_CFM); -+ -+ bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS -+ || master == SND_SOC_DAIFMT_CBM_CFS); -+ uint32_t csreg; -+ -+ /* -+ * If a stream is already enabled, -+ * the registers are already set properly. -+ */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); -+ -+ if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) -+ return 0; -+ -+ -+ bcm2708_i2s_setup_gpio(); -+ -+ /* -+ * Adjust the data length according to the format. -+ * We prefill the half frame length with an integer -+ * divider of 2400 as explained at the clock settings. -+ * Maybe it is overwritten there, if the Integer mode -+ * does not apply. -+ */ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ data_length = 16; -+ bclk_ratio = 50; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ data_length = 24; -+ bclk_ratio = 50; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ data_length = 32; -+ bclk_ratio = 100; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* If bclk_ratio already set, use that one. */ -+ if (dev->bclk_ratio) -+ bclk_ratio = dev->bclk_ratio; -+ -+ /* -+ * Clock Settings -+ * -+ * The target frequency of the bit clock is -+ * sampling rate * frame length -+ * -+ * Integer mode: -+ * Sampling rates that are multiples of 8000 kHz -+ * can be driven by the oscillator of 19.2 MHz -+ * with an integer divider as long as the frame length -+ * is an integer divider of 19200000/8000=2400 as set up above. -+ * This is no longer possible if the sampling rate -+ * is too high (e.g. 192 kHz), because the oscillator is too slow. -+ * -+ * MASH mode: -+ * For all other sampling rates, it is not possible to -+ * have an integer divider. Approximate the clock -+ * with the MASH module that induces a slight frequency -+ * variance. To minimize that it is best to have the fastest -+ * clock here. That is PLLD with 500 MHz. -+ */ -+ target_frequency = sampling_rate * bclk_ratio; -+ clk_src = BCM2708_CLK_SRC_OSC; -+ mash = BCM2708_CLK_MASH_0; -+ -+ if (bcm2708_clk_freq[clk_src] % target_frequency == 0 -+ && bit_master && frame_master) { -+ divi = bcm2708_clk_freq[clk_src] / target_frequency; -+ divf = 0; -+ } else { -+ uint64_t dividend; -+ -+ if (!dev->bclk_ratio) { -+ /* -+ * Overwrite bclk_ratio, because the -+ * above trick is not needed or can -+ * not be used. -+ */ -+ bclk_ratio = 2 * data_length; -+ } -+ -+ target_frequency = sampling_rate * bclk_ratio; -+ -+ clk_src = BCM2708_CLK_SRC_PLLD; -+ mash = BCM2708_CLK_MASH_1; -+ -+ dividend = bcm2708_clk_freq[clk_src]; -+ dividend <<= BCM2708_CLK_SHIFT; -+ do_div(dividend, target_frequency); -+ divi = dividend >> BCM2708_CLK_SHIFT; -+ divf = dividend & BCM2708_CLK_DIVF_MASK; -+ } -+ -+ /* Clock should only be set up here if CPU is clock master */ -+ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) || -+ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) { -+ /* Set clock divider */ -+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD -+ | BCM2708_CLK_DIVI(divi) -+ | BCM2708_CLK_DIVF(divf)); -+ -+ /* Setup clock, but don't start it yet */ -+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD -+ | BCM2708_CLK_MASH(mash) -+ | BCM2708_CLK_SRC(clk_src)); -+ } -+ -+ /* Setup the frame format */ -+ format = BCM2708_I2S_CHEN; -+ -+ if (data_length >= 24) -+ format |= BCM2708_I2S_CHWEX; -+ -+ format |= BCM2708_I2S_CHWID((data_length-8)&0xf); -+ -+ switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ data_delay = 1; -+ break; -+ default: -+ /* -+ * TODO -+ * Others are possible but are not implemented at the moment. -+ */ -+ dev_err(dev->dev, "%s:bad format\n", __func__); -+ return -EINVAL; -+ } -+ -+ ch1pos = data_delay; -+ ch2pos = bclk_ratio / 2 + data_delay; -+ -+ switch (params_channels(params)) { -+ case 2: -+ format = BCM2708_I2S_CH1(format) | BCM2708_I2S_CH2(format); -+ format |= BCM2708_I2S_CH1(BCM2708_I2S_CHPOS(ch1pos)); -+ format |= BCM2708_I2S_CH2(BCM2708_I2S_CHPOS(ch2pos)); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* -+ * Set format for both streams. -+ * We cannot set another frame length -+ * (and therefore word length) anyway, -+ * so the format will be the same. -+ */ -+ regmap_write(dev->i2s_regmap, BCM2708_I2S_RXC_A_REG, format); -+ regmap_write(dev->i2s_regmap, BCM2708_I2S_TXC_A_REG, format); -+ -+ /* Setup the I2S mode */ -+ mode = 0; -+ -+ if (data_length <= 16) { -+ /* -+ * Use frame packed mode (2 channels per 32 bit word) -+ * We cannot set another frame length in the second stream -+ * (and therefore word length) anyway, -+ * so the format will be the same. -+ */ -+ mode |= BCM2708_I2S_FTXP | BCM2708_I2S_FRXP; -+ } -+ -+ mode |= BCM2708_I2S_FLEN(bclk_ratio - 1); -+ mode |= BCM2708_I2S_FSLEN(bclk_ratio / 2); -+ -+ /* Master or slave? */ -+ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ /* CPU is master */ -+ break; -+ case SND_SOC_DAIFMT_CBM_CFS: -+ /* -+ * CODEC is bit clock master -+ * CPU is frame master -+ */ -+ mode |= BCM2708_I2S_CLKM; -+ break; -+ case SND_SOC_DAIFMT_CBS_CFM: -+ /* -+ * CODEC is frame master -+ * CPU is bit clock master -+ */ -+ mode |= BCM2708_I2S_FSM; -+ break; -+ case SND_SOC_DAIFMT_CBM_CFM: -+ /* CODEC is master */ -+ mode |= BCM2708_I2S_CLKM; -+ mode |= BCM2708_I2S_FSM; -+ break; -+ default: -+ dev_err(dev->dev, "%s:bad master\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* -+ * Invert clocks? -+ * -+ * The BCM approach seems to be inverted to the classical I2S approach. -+ */ -+ switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ /* None. Therefore, both for BCM */ -+ mode |= BCM2708_I2S_CLKI; -+ mode |= BCM2708_I2S_FSI; -+ break; -+ case SND_SOC_DAIFMT_IB_IF: -+ /* Both. Therefore, none for BCM */ -+ break; -+ case SND_SOC_DAIFMT_NB_IF: -+ /* -+ * Invert only frame sync. Therefore, -+ * invert only bit clock for BCM -+ */ -+ mode |= BCM2708_I2S_CLKI; -+ break; -+ case SND_SOC_DAIFMT_IB_NF: -+ /* -+ * Invert only bit clock. Therefore, -+ * invert only frame sync for BCM -+ */ -+ mode |= BCM2708_I2S_FSI; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_write(dev->i2s_regmap, BCM2708_I2S_MODE_A_REG, mode); -+ -+ /* Setup the DMA parameters */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_RXTHR(1) -+ | BCM2708_I2S_TXTHR(1) -+ | BCM2708_I2S_DMAEN, 0xffffffff); -+ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_DREQ_A_REG, -+ BCM2708_I2S_TX_PANIC(0x10) -+ | BCM2708_I2S_RX_PANIC(0x30) -+ | BCM2708_I2S_TX(0x30) -+ | BCM2708_I2S_RX(0x20), 0xffffffff); -+ -+ /* Clear FIFOs */ -+ bcm2708_i2s_clear_fifos(dev, true, true); -+ -+ return 0; -+} -+ -+static int bcm2708_i2s_prepare(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ uint32_t cs_reg; -+ -+ bcm2708_i2s_start_clock(dev); -+ -+ /* -+ * Clear both FIFOs if the one that should be started -+ * is not empty at the moment. This should only happen -+ * after overrun. Otherwise, hw_params would have cleared -+ * the FIFO. -+ */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &cs_reg); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK -+ && !(cs_reg & BCM2708_I2S_TXE)) -+ bcm2708_i2s_clear_fifos(dev, true, false); -+ else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE -+ && (cs_reg & BCM2708_I2S_RXD)) -+ bcm2708_i2s_clear_fifos(dev, false, true); -+ -+ return 0; -+} -+ -+static void bcm2708_i2s_stop(struct bcm2708_i2s_dev *dev, -+ struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ uint32_t mask; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -+ mask = BCM2708_I2S_RXON; -+ else -+ mask = BCM2708_I2S_TXON; -+ -+ regmap_update_bits(dev->i2s_regmap, -+ BCM2708_I2S_CS_A_REG, mask, 0); -+ -+ /* Stop also the clock when not SND_SOC_DAIFMT_CONT */ -+ if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT)) -+ bcm2708_i2s_stop_clock(dev); -+} -+ -+static int bcm2708_i2s_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ uint32_t mask; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ bcm2708_i2s_start_clock(dev); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -+ mask = BCM2708_I2S_RXON; -+ else -+ mask = BCM2708_I2S_TXON; -+ -+ regmap_update_bits(dev->i2s_regmap, -+ BCM2708_I2S_CS_A_REG, mask, mask); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ bcm2708_i2s_stop(dev, substream, dai); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int bcm2708_i2s_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ if (dai->active) -+ return 0; -+ -+ /* Should this still be running stop it */ -+ bcm2708_i2s_stop_clock(dev); -+ -+ /* Enable PCM block */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_EN, BCM2708_I2S_EN); -+ -+ /* -+ * Disable STBY. -+ * Requires at least 4 PCM clock cycles to take effect. -+ */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_STBY, BCM2708_I2S_STBY); -+ -+ return 0; -+} -+ -+static void bcm2708_i2s_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ bcm2708_i2s_stop(dev, substream, dai); -+ -+ /* If both streams are stopped, disable module and clock */ -+ if (dai->active) -+ return; -+ -+ /* Disable the module */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_EN, 0); -+ -+ /* -+ * Stopping clock is necessary, because stop does -+ * not stop the clock when SND_SOC_DAIFMT_CONT -+ */ -+ bcm2708_i2s_stop_clock(dev); -+} -+ -+static const struct snd_soc_dai_ops bcm2708_i2s_dai_ops = { -+ .startup = bcm2708_i2s_startup, -+ .shutdown = bcm2708_i2s_shutdown, -+ .prepare = bcm2708_i2s_prepare, -+ .trigger = bcm2708_i2s_trigger, -+ .hw_params = bcm2708_i2s_hw_params, -+ .set_fmt = bcm2708_i2s_set_dai_fmt, -+ .set_bclk_ratio = bcm2708_i2s_set_dai_bclk_ratio -+}; -+ -+static int bcm2708_i2s_dai_probe(struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; -+ dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; -+ -+ return 0; -+} -+ -+static struct snd_soc_dai_driver bcm2708_i2s_dai = { -+ .name = "bcm2708-i2s", -+ .probe = bcm2708_i2s_dai_probe, -+ .playback = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE -+ | SNDRV_PCM_FMTBIT_S24_LE -+ | SNDRV_PCM_FMTBIT_S32_LE -+ }, -+ .capture = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE -+ | SNDRV_PCM_FMTBIT_S24_LE -+ | SNDRV_PCM_FMTBIT_S32_LE -+ }, -+ .ops = &bcm2708_i2s_dai_ops, -+ .symmetric_rates = 1 -+}; -+ -+static bool bcm2708_i2s_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case BCM2708_I2S_CS_A_REG: -+ case BCM2708_I2S_FIFO_A_REG: -+ case BCM2708_I2S_INTSTC_A_REG: -+ case BCM2708_I2S_GRAY_REG: -+ return true; -+ default: -+ return false; -+ }; -+} -+ -+static bool bcm2708_i2s_precious_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case BCM2708_I2S_FIFO_A_REG: -+ return true; -+ default: -+ return false; -+ }; -+} -+ -+static bool bcm2708_clk_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case BCM2708_CLK_PCMCTL_REG: -+ return true; -+ default: -+ return false; -+ }; -+} -+ -+static const struct regmap_config bcm2708_regmap_config[] = { -+ { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = BCM2708_I2S_GRAY_REG, -+ .precious_reg = bcm2708_i2s_precious_reg, -+ .volatile_reg = bcm2708_i2s_volatile_reg, -+ .cache_type = REGCACHE_RBTREE, -+ .name = "i2s", -+ }, -+ { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = BCM2708_CLK_PCMDIV_REG, -+ .volatile_reg = bcm2708_clk_volatile_reg, -+ .cache_type = REGCACHE_RBTREE, -+ .name = "clk", -+ }, -+}; -+ -+static const struct snd_soc_component_driver bcm2708_i2s_component = { -+ .name = "bcm2708-i2s-comp", -+}; -+ -+static const struct snd_pcm_hardware bcm2708_pcm_hardware = { -+ .info = SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_JOINT_DUPLEX, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE, -+ .period_bytes_min = 32, -+ .period_bytes_max = 64 * PAGE_SIZE, -+ .periods_min = 2, -+ .periods_max = 255, -+ .buffer_bytes_max = 128 * PAGE_SIZE, -+}; -+ -+static const struct snd_dmaengine_pcm_config bcm2708_dmaengine_pcm_config = { -+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, -+ .pcm_hardware = &bcm2708_pcm_hardware, -+ .prealloc_buffer_size = 256 * PAGE_SIZE, -+}; -+ -+ -+static int bcm2708_i2s_probe(struct platform_device *pdev) -+{ -+ struct bcm2708_i2s_dev *dev; -+ int i; -+ int ret; -+ struct regmap *regmap[2]; -+ struct resource *mem[2]; -+ -+ /* Request both ioareas */ -+ for (i = 0; i <= 1; i++) { -+ void __iomem *base; -+ -+ mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); -+ base = devm_ioremap_resource(&pdev->dev, mem[i]); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, -+ &bcm2708_regmap_config[i]); -+ if (IS_ERR(regmap[i])) { -+ dev_err(&pdev->dev, "I2S probe: regmap init failed\n"); -+ return PTR_ERR(regmap[i]); -+ } -+ } -+ -+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), -+ GFP_KERNEL); -+ if (IS_ERR(dev)) -+ return PTR_ERR(dev); -+ -+ dev->i2s_regmap = regmap[0]; -+ dev->clk_regmap = regmap[1]; -+ -+ /* Set the DMA address */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = -+ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; -+ -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = -+ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; -+ -+ /* Set the DREQ */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].slave_id = -+ BCM2708_DMA_DREQ_PCM_TX; -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].slave_id = -+ BCM2708_DMA_DREQ_PCM_RX; -+ -+ /* Set the bus width */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = -+ DMA_SLAVE_BUSWIDTH_4_BYTES; -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = -+ DMA_SLAVE_BUSWIDTH_4_BYTES; -+ -+ /* Set burst */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; -+ -+ /* BCLK ratio - use default */ -+ dev->bclk_ratio = 0; -+ -+ /* Store the pdev */ -+ dev->dev = &pdev->dev; -+ dev_set_drvdata(&pdev->dev, dev); -+ -+ ret = snd_soc_register_component(&pdev->dev, -+ &bcm2708_i2s_component, &bcm2708_i2s_dai, 1); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ ret = snd_dmaengine_pcm_register(&pdev->dev, -+ &bcm2708_dmaengine_pcm_config, -+ SND_DMAENGINE_PCM_FLAG_COMPAT); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); -+ snd_soc_unregister_component(&pdev->dev); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int bcm2708_i2s_remove(struct platform_device *pdev) -+{ -+ snd_dmaengine_pcm_unregister(&pdev->dev); -+ snd_soc_unregister_component(&pdev->dev); -+ return 0; -+} -+ -+static const struct of_device_id bcm2708_i2s_of_match[] = { -+ { .compatible = "brcm,bcm2708-i2s", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match); -+ -+static struct platform_driver bcm2708_i2s_driver = { -+ .probe = bcm2708_i2s_probe, -+ .remove = bcm2708_i2s_remove, -+ .driver = { -+ .name = "bcm2708-i2s", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2708_i2s_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2708_i2s_driver); -+ -+MODULE_ALIAS("platform:bcm2708-i2s"); -+MODULE_DESCRIPTION("BCM2708 I2S interface"); -+MODULE_AUTHOR("Florian Meier "); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/bcm/bcm2708-i2s.h b/sound/soc/bcm/bcm2708-i2s.h -new file mode 100644 -index 0000000..6fdcbc1 ---- /dev/null -+++ b/sound/soc/bcm/bcm2708-i2s.h -@@ -0,0 +1,35 @@ -+/* -+ * I2S configuration for sound cards. -+ * -+ * Copyright (c) 2014 Daniel Matuschek -+ * -+ * 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 BCM2708_I2S_H -+#define BCM2708_I2S_H -+ -+/* I2S pin assignment */ -+#define BCM2708_I2S_GPIO_AUTO 0 -+#define BCM2708_I2S_GPIO_PIN18 1 -+#define BCM2708_I2S_GPIO_PIN28 2 -+ -+/* Alt mode to enable I2S */ -+#define BCM2708_I2S_GPIO_PIN18_ALT 0 -+#define BCM2708_I2S_GPIO_PIN28_ALT 2 -+ -+extern void bcm2708_i2s_set_gpio(int gpio); -+ -+#endif - -From 95f9b87c32e716eb0276c9d6d1228db5a9e38a0e Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 031/216] ASoC: Add support for PCM5102A codec - -Some definitions to support the PCM5102A codec -by Texas Instruments. - -Signed-off-by: Florian Meier ---- - sound/soc/codecs/Kconfig | 4 +++ - sound/soc/codecs/Makefile | 2 ++ - sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 69 insertions(+) - create mode 100644 sound/soc/codecs/pcm5102a.c - -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index ea9f0e3..bc39bbc 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -82,6 +82,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_I2C if I2C - select SND_SOC_PCM512x_SPI if SPI_MASTER - select SND_SOC_RT286 if I2C -+ select SND_SOC_PCM5102A if I2C - select SND_SOC_RT5631 if I2C - select SND_SOC_RT5640 if I2C - select SND_SOC_RT5645 if I2C -@@ -506,6 +507,9 @@ config SND_SOC_RT286 - tristate - depends on I2C - -+config SND_SOC_PCM5102A -+ tristate -+ - config SND_SOC_RT5631 - tristate "Realtek ALC5631/RT5631 CODEC" - depends on I2C -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 69b8666..905ef6f 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -77,6 +77,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o - snd-soc-rt286-objs := rt286.o -+snd-soc-pcm5102a-objs := pcm5102a.o - snd-soc-rt5631-objs := rt5631.o - snd-soc-rt5640-objs := rt5640.o - snd-soc-rt5645-objs := rt5645.o -@@ -259,6 +260,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o -+obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o - obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o - obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o - obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o -diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c -new file mode 100644 -index 0000000..126f1e9 ---- /dev/null -+++ b/sound/soc/codecs/pcm5102a.c -@@ -0,0 +1,63 @@ -+/* -+ * Driver for the PCM5102A codec -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include -+ -+static struct snd_soc_dai_driver pcm5102a_dai = { -+ .name = "pcm5102a-hifi", -+ .playback = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE -+ }, -+}; -+ -+static struct snd_soc_codec_driver soc_codec_dev_pcm5102a; -+ -+static int pcm5102a_probe(struct platform_device *pdev) -+{ -+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a, -+ &pcm5102a_dai, 1); -+} -+ -+static int pcm5102a_remove(struct platform_device *pdev) -+{ -+ snd_soc_unregister_codec(&pdev->dev); -+ return 0; -+} -+ -+static struct platform_driver pcm5102a_codec_driver = { -+ .probe = pcm5102a_probe, -+ .remove = pcm5102a_remove, -+ .driver = { -+ .name = "pcm5102a-codec", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(pcm5102a_codec_driver); -+ -+MODULE_DESCRIPTION("ASoC PCM5102A codec driver"); -+MODULE_AUTHOR("Florian Meier "); -+MODULE_LICENSE("GPL v2"); - -From b8442f0526d6de697deec639e36023a92a2d178a Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 19:04:54 +0100 -Subject: [PATCH 032/216] BCM2708: Add I2S support to board file - -Adds the required initializations for I2S -to the board file of mach-bcm2708. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5873f8b..7f4ebf4 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -613,6 +613,28 @@ static struct platform_device bcm2835_thermal_device = { - .name = "bcm2835_thermal", - }; - -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+static struct resource bcm2708_i2s_resources[] = { -+ { -+ .start = I2S_BASE, -+ .end = I2S_BASE + 0x20, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = PCM_CLOCK_BASE, -+ .end = PCM_CLOCK_BASE + 0x02, -+ .flags = IORESOURCE_MEM, -+ } -+}; -+ -+static struct platform_device bcm2708_i2s_device = { -+ .name = "bcm2708-i2s", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), -+ .resource = bcm2708_i2s_resources, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -762,6 +784,10 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); - -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+ bcm_register_device_dt(&bcm2708_i2s_device); -+#endif -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - -From 40cf34f896f3ac88ad775464619175b5167ddacb Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 033/216] ASoC: Add support for HifiBerry DAC - -This adds a machine driver for the HifiBerry DAC. -It is a sound card that can -be stacked onto the Raspberry Pi. - -Signed-off-by: Florian Meier ---- - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 5 +++ - sound/soc/bcm/hifiberry_dac.c | 100 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 112 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_dac.c - -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 8642296..a92adb2 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -18,3 +18,10 @@ config SND_BCM2708_SOC_I2S - Say Y or M if you want to add support for codecs attached to - the BCM2708 I2S interface. You will also need - to select the audio interfaces to support below. -+ -+config SND_BCM2708_SOC_HIFIBERRY_DAC -+ tristate "Support for HifiBerry DAC" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM5102A -+ help -+ Say Y or M if you want to add support for HifiBerry DAC. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index f8bbe1f..be90a49cb 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -7,3 +7,8 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o - snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o - - obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o -+ -+# BCM2708 Machine Support -+snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+ -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c -new file mode 100644 -index 0000000..4b70b45 ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_dac.c -@@ -0,0 +1,100 @@ -+/* -+ * ASoC Driver for HifiBerry DAC -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_hifiberry_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ unsigned int sample_bits = -+ snd_pcm_format_physical_width(params_format(params)); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_dac_ops = { -+ .hw_params = snd_rpi_hifiberry_dac_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = { -+{ -+ .name = "HifiBerry DAC", -+ .stream_name = "HifiBerry DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm5102a-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm5102a-codec", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_dac_ops, -+ .init = snd_rpi_hifiberry_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_dac = { -+ .name = "snd_rpi_hifiberry_dac", -+ .dai_link = snd_rpi_hifiberry_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), -+}; -+ -+static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_dac.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); -+} -+ -+static struct platform_driver snd_rpi_hifiberry_dac_driver = { -+ .driver = { -+ .name = "snd-hifiberry-dac", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_dac_probe, -+ .remove = snd_rpi_hifiberry_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_hifiberry_dac_driver); -+ -+MODULE_AUTHOR("Florian Meier "); -+MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); -+MODULE_LICENSE("GPL v2"); - -From c2ef063e2adb0e41654dc580ae959a86cde6f6f5 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 034/216] BCM2708: Add HifiBerry DAC to board file - -This adds the initalization of the HifiBerry DAC -to the mach-bcm2708 board file. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 7f4ebf4..94ce8fc 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -635,6 +635,20 @@ static struct platform_device bcm2708_i2s_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+static struct platform_device snd_hifiberry_dac_device = { -+ .name = "snd-hifiberry-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm5102a_codec_device = { -+ .name = "pcm5102a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -788,6 +802,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2708_i2s_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_dac_device); -+ bcm_register_device_dt(&snd_pcm5102a_codec_device); -+#endif -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - -From 1de129c2113a6fb145e654260b683e6c7e30bb51 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 6 Dec 2013 20:50:28 +0100 -Subject: [PATCH 035/216] ASoC: BCM2708: Add support for RPi-DAC - -This adds a machine driver for the RPi-DAC. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ - sound/soc/codecs/Kconfig | 4 ++ - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ - 7 files changed, 193 insertions(+) - create mode 100644 sound/soc/bcm/rpi-dac.c - create mode 100644 sound/soc/codecs/pcm1794a.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 94ce8fc..fb955755 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -649,6 +649,20 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+static struct platform_device snd_rpi_dac_device = { -+ .name = "snd-rpi-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm1794a_codec_device = { -+ .name = "pcm1794a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -807,6 +821,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_dac_device); -+ bcm_register_device_dt(&snd_pcm1794a_codec_device); -+#endif -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index a92adb2..64c61ac 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -25,3 +25,10 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC - select SND_SOC_PCM5102A - help - Say Y or M if you want to add support for HifiBerry DAC. -+ -+config SND_BCM2708_SOC_RPI_DAC -+ tristate "Support for RPi-DAC" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM1794A -+ help -+ Say Y or M if you want to add support for RPi-DAC. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index be90a49cb..ccc9809 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -10,5 +10,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - - # BCM2708 Machine Support - snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+snd-soc-rpi-dac-objs := rpi-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o -diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c -new file mode 100644 -index 0000000..6d6e0ba ---- /dev/null -+++ b/sound/soc/bcm/rpi-dac.c -@@ -0,0 +1,97 @@ -+/* -+ * ASoC Driver for RPi-DAC. -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_rpi_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ return 0; -+} -+ -+static int snd_rpi_rpi_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_rpi_dac_ops = { -+ .hw_params = snd_rpi_rpi_dac_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = { -+{ -+ .name = "RPi-DAC", -+ .stream_name = "RPi-DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm1794a-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm1794a-codec", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_rpi_dac_ops, -+ .init = snd_rpi_rpi_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_rpi_dac = { -+ .name = "snd_rpi_rpi_dac", -+ .dai_link = snd_rpi_rpi_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), -+}; -+ -+static int snd_rpi_rpi_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_rpi_dac.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_rpi_dac); -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_rpi_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_rpi_dac); -+} -+ -+static struct platform_driver snd_rpi_rpi_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-dac", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_rpi_dac_probe, -+ .remove = snd_rpi_rpi_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_rpi_dac_driver); -+ -+MODULE_AUTHOR("Florian Meier "); -+MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index bc39bbc..8682bcf 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -83,6 +83,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_SPI if SPI_MASTER - select SND_SOC_RT286 if I2C - select SND_SOC_PCM5102A if I2C -+ select SND_SOC_PCM1794A if I2C - select SND_SOC_RT5631 if I2C - select SND_SOC_RT5640 if I2C - select SND_SOC_RT5645 if I2C -@@ -507,6 +508,9 @@ config SND_SOC_RT286 - tristate - depends on I2C - -+config SND_SOC_PCM1794A -+ tristate -+ - config SND_SOC_PCM5102A - tristate - -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 905ef6f..c9bceba 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -77,6 +77,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o - snd-soc-rt286-objs := rt286.o -+snd-soc-pcm1794a-objs := pcm1794a.o - snd-soc-pcm5102a-objs := pcm5102a.o - snd-soc-rt5631-objs := rt5631.o - snd-soc-rt5640-objs := rt5640.o -@@ -260,6 +261,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o -+obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o - obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o - obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o - obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o -diff --git a/sound/soc/codecs/pcm1794a.c b/sound/soc/codecs/pcm1794a.c -new file mode 100644 -index 0000000..b4eaa44 ---- /dev/null -+++ b/sound/soc/codecs/pcm1794a.c -@@ -0,0 +1,62 @@ -+/* -+ * Driver for the PCM1794A codec -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include -+ -+static struct snd_soc_dai_driver pcm1794a_dai = { -+ .name = "pcm1794a-hifi", -+ .playback = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE -+ }, -+}; -+ -+static struct snd_soc_codec_driver soc_codec_dev_pcm1794a; -+ -+static int pcm1794a_probe(struct platform_device *pdev) -+{ -+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm1794a, -+ &pcm1794a_dai, 1); -+} -+ -+static int pcm1794a_remove(struct platform_device *pdev) -+{ -+ snd_soc_unregister_codec(&pdev->dev); -+ return 0; -+} -+ -+static struct platform_driver pcm1794a_codec_driver = { -+ .probe = pcm1794a_probe, -+ .remove = pcm1794a_remove, -+ .driver = { -+ .name = "pcm1794a-codec", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(pcm1794a_codec_driver); -+ -+MODULE_DESCRIPTION("ASoC PCM1794A codec driver"); -+MODULE_AUTHOR("Florian Meier "); -+MODULE_LICENSE("GPL v2"); - -From 11dea4325311685b8d38b791b519e74a561476ca Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 036/216] ASoC: wm8804: Implement MCLK configuration options, - add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs - for most sample rates. At 192kHz only 128xfs is supported. The existing - driver selects 128xfs automatically for some lower samples rates. By using an - additional mclk_div divider, it is now possible to control the behaviour. - This allows using 256xfs PLL frequency on all sample rates up to 96kHz. It - should allow lower jitter and better signal quality. The behavior has to be - controlled by the sound card driver, because some sample frequency share the - same setting. e.g. 192kHz and 96kHz use 24.576MHz master clock. The only - difference is the MCLK divider. - -This also added support for 32bit data. - -Signed-off-by: Daniel Matuschek ---- - sound/soc/codecs/wm8804.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index b2b0e68..ba2a0f8 100644 ---- a/sound/soc/codecs/wm8804.c -+++ b/sound/soc/codecs/wm8804.c -@@ -278,6 +278,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream, - blen = 0x1; - break; - case 24: -+ case 32: - blen = 0x2; - break; - default: -@@ -621,7 +622,7 @@ static const struct snd_soc_dai_ops wm8804_dai_ops = { - }; - - #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ -- SNDRV_PCM_FMTBIT_S24_LE) -+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) - - #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ - -From 84aed3cc8e8d60407b60cd132fe7a673024fb1a4 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 037/216] ASoC: BCM:Add support for HiFiBerry Digi. Driver is - based on the patched WM8804 driver. - -Signed-off-by: Daniel Matuschek ---- - sound/soc/bcm/Kconfig | 7 ++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_digi.c | 153 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 162 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_digi.c - -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 64c61ac..d4a00fc 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC - help - Say Y or M if you want to add support for HifiBerry DAC. - -+config SND_BCM2708_SOC_HIFIBERRY_DIGI -+ tristate "Support for HifiBerry Digi" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_WM8804 -+ help -+ Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. -+ - config SND_BCM2708_SOC_RPI_DAC - tristate "Support for RPi-DAC" - depends on SND_BCM2708_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index ccc9809..826df7d 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -10,7 +10,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - - # BCM2708 Machine Support - snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-rpi-dac-objs := rpi-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -new file mode 100644 -index 0000000..446ecdd ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -0,0 +1,153 @@ -+/* -+ * ASoC Driver for HifiBerry Digi -+ * -+ * Author: Daniel Matuschek -+ * based on the HifiBerry DAC driver by Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/wm8804.h" -+ -+static int samplerate=44100; -+ -+static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ /* enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ int sysclk = 27000000; /* This is fixed on this board */ -+ -+ long mclk_freq=0; -+ int mclk_div=1; -+ -+ int ret; -+ -+ samplerate = params_rate(params); -+ -+ switch (samplerate) { -+ case 44100: -+ case 48000: -+ case 88200: -+ case 96000: -+ mclk_freq=samplerate*256; -+ mclk_div=WM8804_MCLKDIV_256FS; -+ break; -+ case 176400: -+ case 192000: -+ mclk_freq=samplerate*128; -+ mclk_div=WM8804_MCLKDIV_128FS; -+ break; -+ default: -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK, unsupported samplerate\n"); -+ } -+ -+ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); -+ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); -+ -+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, -+ sysclk, SND_SOC_CLOCK_OUT); -+ if (ret < 0) { -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK: %d\n", ret); -+ return ret; -+ } -+ -+ /* Enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ /* Power on */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai,64); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = { -+ .hw_params = snd_rpi_hifiberry_digi_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { -+{ -+ .name = "HifiBerry Digi", -+ .stream_name = "HifiBerry Digi HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "wm8804-spdif", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "wm8804.1-003b", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .ops = &snd_rpi_hifiberry_digi_ops, -+ .init = snd_rpi_hifiberry_digi_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_digi = { -+ .name = "snd_rpi_hifiberry_digi", -+ .dai_link = snd_rpi_hifiberry_digi_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), -+}; -+ -+static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_digi.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); -+} -+ -+static struct platform_driver snd_rpi_hifiberry_digi_driver = { -+ .driver = { -+ .name = "snd-hifiberry-digi", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_digi_probe, -+ .remove = snd_rpi_hifiberry_digi_remove, -+}; -+ -+module_platform_driver(snd_rpi_hifiberry_digi_driver); -+ -+MODULE_AUTHOR("Daniel Matuschek "); -+MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); -+MODULE_LICENSE("GPL v2"); - -From 4d5dd3c3d6019cf233add726cbe3aac6e543c540 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Thu, 16 Jan 2014 07:26:08 +0100 -Subject: [PATCH 038/216] BCM2708: Added support for HiFiBerry Digi board Board - initalization by I2C - -Signed-off-by: Daniel Matuschek ---- - arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index fb955755..0ad5343 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -649,6 +649,21 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+static struct platform_device snd_hifiberry_digi_device = { -+ .name = "snd-hifiberry-digi", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("wm8804", 0x3b) -+ }, -+}; -+ -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - static struct platform_device snd_rpi_dac_device = { - .name = "snd-rpi-dac", -@@ -821,6 +836,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_digi_device); -+ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - bcm_register_device_dt(&snd_rpi_dac_device); - bcm_register_device_dt(&snd_pcm1794a_codec_device); - -From 963fd96f5747dd0c693a87cbb23bc1239d3bda72 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 039/216] ASoC: wm8804: Set idle_bias_off to false Idle bias - has been change to remove warning on driver startup - -Signed-off-by: Daniel Matuschek ---- - sound/soc/codecs/wm8804.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index ba2a0f8..91974f9 100644 ---- a/sound/soc/codecs/wm8804.c -+++ b/sound/soc/codecs/wm8804.c -@@ -653,7 +653,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { - .probe = wm8804_probe, - .remove = wm8804_remove, - .set_bias_level = wm8804_set_bias_level, -- .idle_bias_off = true, -+ .idle_bias_off = false, - - .controls = wm8804_snd_controls, - .num_controls = ARRAY_SIZE(wm8804_snd_controls), - -From f5995e9c2cc2d801d5b05e3f4be0bdafb184943a Mon Sep 17 00:00:00 2001 -From: Gordon Garrity -Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 040/216] Add IQaudIO Sound Card support for Raspberry Pi - ---- - arch/arm/mach-bcm2708/bcm2708.c | 22 ++++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/iqaudio-dac.c | 111 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 142 insertions(+) - create mode 100644 sound/soc/bcm/iqaudio-dac.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 0ad5343..a812b51 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -678,6 +678,22 @@ static struct platform_device snd_pcm1794a_codec_device = { - }; - #endif - -+ -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+static struct platform_device snd_rpi_iqaudio_dac_device = { -+ .name = "snd-rpi-iqaudio-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+// Use the actual device name rather than generic driver name -+static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4c) -+ }, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -846,6 +862,12 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm1794a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); -+#endif -+ -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index d4a00fc..faa89ef 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -39,3 +39,10 @@ config SND_BCM2708_SOC_RPI_DAC - select SND_SOC_PCM1794A - help - Say Y or M if you want to add support for RPi-DAC. -+ -+config SND_BCM2708_SOC_IQAUDIO_DAC -+ tristate "Support for IQaudIO-DAC" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM512x_I2C -+ help -+ Say Y or M if you want to add support for IQaudIO-DAC. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index 826df7d..d597fb0 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -12,7 +12,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - snd-soc-hifiberry-dac-objs := hifiberry_dac.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-rpi-dac-objs := rpi-dac.o -+snd-soc-iqaudio-dac-objs := iqaudio-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -new file mode 100644 -index 0000000..8d0e2ae ---- /dev/null -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -0,0 +1,111 @@ -+/* -+ * ASoC Driver for IQaudIO DAC -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+// NOT USED struct snd_soc_codec *codec = rtd->codec; -+ -+ return 0; -+} -+ -+static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+// NOT USED struct snd_soc_dai *codec_dai = rtd->codec_dai; -+// NOT USED struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ unsigned int sample_bits = -+ snd_pcm_format_physical_width(params_format(params)); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = { -+ .hw_params = snd_rpi_iqaudio_dac_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { -+{ -+ .name = "IQaudIO DAC", -+ .stream_name = "IQaudIO DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm512x-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm512x.1-004c", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_iqaudio_dac_ops, -+ .init = snd_rpi_iqaudio_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_iqaudio_dac = { -+ .name = "IQaudIODAC", -+ .dai_link = snd_rpi_iqaudio_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), -+}; -+ -+static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_iqaudio_dac.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_iqaudio_dac); -+} -+ -+static const struct of_device_id iqaudio_of_match[] = { -+ { .compatible = "iqaudio,iqaudio-dac", }, -+ {}, -+}; -+ -+static struct platform_driver snd_rpi_iqaudio_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-iqaudio-dac", -+ .owner = THIS_MODULE, -+ .of_match_table = iqaudio_of_match, -+ }, -+ .probe = snd_rpi_iqaudio_dac_probe, -+ .remove = snd_rpi_iqaudio_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_iqaudio_dac_driver); -+ -+MODULE_AUTHOR("Florian Meier "); -+MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); -+MODULE_LICENSE("GPL v2"); - -From 5d1809ba161ed01404974ad13403d23a008bd181 Mon Sep 17 00:00:00 2001 -From: Howard Mitchell -Date: Mon, 2 Mar 2015 17:28:02 +0000 -Subject: [PATCH 041/216] Set a limit of 0dB on Digital Volume Control - -The main volume control in the PCM512x DAC has a range up to -+24dB. This is dangerously loud and can potentially cause massive -clipping in the output stages. Therefore this sets a sensible -limit of 0dB for this control. ---- - sound/soc/bcm/iqaudio-dac.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index 8d0e2ae..aff7377 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -25,7 +25,13 @@ - - static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) - { --// NOT USED struct snd_soc_codec *codec = rtd->codec; -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); - - return 0; - } - -From 8dbd2bddafe5d604e9f03a702d5ae50c0dd791e6 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 042/216] vmstat: Workaround for issue where dirty page count - goes negative - -See: -https://github.com/raspberrypi/linux/issues/617 -http://www.spinics.net/lists/linux-mm/msg72236.html ---- - include/linux/vmstat.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 82e7db7..f87d16d 100644 ---- a/include/linux/vmstat.h -+++ b/include/linux/vmstat.h -@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) - static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) - { - atomic_long_dec(&zone->vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) -+ atomic_long_set(&zone->vm_stat[item], 0); - atomic_long_dec(&vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) -+ atomic_long_set(&vm_stat[item], 0); - } - - static inline void __inc_zone_page_state(struct page *page, - -From 15bf30debd62320326c6a474f69eabbf3b43029e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 13 Apr 2015 18:55:53 +0100 -Subject: [PATCH 043/216] BCM2708: armctrl: Add IRQ Device Tree support - -Add Device Tree IRQ support for BCM2708. -Usage is the same as for irq-bcm2835. -See binding document: brcm,bcm2835-armctrl-ic.txt - -A bank 3 is added to handle GPIO interrupts. This is done because -armctrl also handles GPIO interrupts. - -Signed-off-by: Noralf Tronnes - -BCM2708: armctrl: remove irq bank 3 - -irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio -combination. It is no longer required. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 96 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index 96fa9b9..74bacb3 100644 ---- a/arch/arm/mach-bcm2708/armctrl.c -+++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -23,6 +23,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct irq_data *d) - } - } - -+#ifdef CONFIG_OF -+ -+#define NR_IRQS_BANK0 21 -+#define NR_BANKS 3 -+#define IRQS_PER_BANK 32 -+ -+/* from drivers/irqchip/irq-bcm2835.c */ -+static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, -+ const u32 *intspec, unsigned int intsize, -+ unsigned long *out_hwirq, unsigned int *out_type) -+{ -+ if (WARN_ON(intsize != 2)) -+ return -EINVAL; -+ -+ if (WARN_ON(intspec[0] >= NR_BANKS)) -+ return -EINVAL; -+ -+ if (WARN_ON(intspec[1] >= IRQS_PER_BANK)) -+ return -EINVAL; -+ -+ if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0)) -+ return -EINVAL; -+ -+ if (intspec[0] == 0) -+ *out_hwirq = ARM_IRQ0_BASE + intspec[1]; -+ else if (intspec[0] == 1) -+ *out_hwirq = ARM_IRQ1_BASE + intspec[1]; -+ else -+ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; -+ -+ /* reverse remap_irqs[] */ -+ switch (*out_hwirq) { -+ case INTERRUPT_VC_JPEG: -+ *out_hwirq = INTERRUPT_JPEG; -+ break; -+ case INTERRUPT_VC_USB: -+ *out_hwirq = INTERRUPT_USB; -+ break; -+ case INTERRUPT_VC_3D: -+ *out_hwirq = INTERRUPT_3D; -+ break; -+ case INTERRUPT_VC_DMA2: -+ *out_hwirq = INTERRUPT_DMA2; -+ break; -+ case INTERRUPT_VC_DMA3: -+ *out_hwirq = INTERRUPT_DMA3; -+ break; -+ case INTERRUPT_VC_I2C: -+ *out_hwirq = INTERRUPT_I2C; -+ break; -+ case INTERRUPT_VC_SPI: -+ *out_hwirq = INTERRUPT_SPI; -+ break; -+ case INTERRUPT_VC_I2SPCM: -+ *out_hwirq = INTERRUPT_I2SPCM; -+ break; -+ case INTERRUPT_VC_SDIO: -+ *out_hwirq = INTERRUPT_SDIO; -+ break; -+ case INTERRUPT_VC_UART: -+ *out_hwirq = INTERRUPT_UART; -+ break; -+ case INTERRUPT_VC_ARASANSDIO: -+ *out_hwirq = INTERRUPT_ARASANSDIO; -+ break; -+ } -+ -+ *out_type = IRQ_TYPE_NONE; -+ return 0; -+} -+ -+static struct irq_domain_ops armctrl_ops = { -+ .xlate = armctrl_xlate -+}; -+ -+void __init armctrl_dt_init(void) -+{ -+ struct device_node *np; -+ struct irq_domain *domain; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic"); -+ if (!np) -+ return; -+ -+ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS, -+ IRQ_ARMCTRL_START, 0, -+ &armctrl_ops, NULL); -+ WARN_ON(!domain); -+} -+#else -+void __init armctrl_dt_init(void) { } -+#endif /* CONFIG_OF */ -+ - #if defined(CONFIG_PM) - - /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ -@@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, - - armctrl_pm_register(base, irq_start, resume_sources); - init_FIQ(FIQ_START); -+ armctrl_dt_init(); - return 0; - } - -From e85c6248222486f0aca8f09ea4bf7ad463b15487 Mon Sep 17 00:00:00 2001 -From: notro -Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 044/216] BCM2708: use pinctrl-bcm2835 - -Use pinctrl-bcm2835 instead of the pinctrl-bcm2708 and bcm2708_gpio -combination. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/Kconfig | 3 +++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - drivers/pinctrl/pinctrl-bcm2835.c | 2 +- - 3 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 182e7ba..4cfae55 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -14,6 +14,9 @@ config BCM2708_DT - depends on MACH_BCM2708 - default n - select USE_OF -+ select ARCH_REQUIRE_GPIOLIB -+ select PINCTRL -+ select PINCTRL_BCM2835 - help - Enable Device Tree support for BCM2708 - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a812b51..a207ad8 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -816,7 +816,7 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO -- bcm_register_device(&bcm2708_gpio_device); -+ bcm_register_device_dt(&bcm2708_gpio_device); - #endif - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index 9aa8a3f..9d1149e 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { - .get = bcm2835_gpio_get, - .set = bcm2835_gpio_set, - .to_irq = bcm2835_gpio_to_irq, -- .base = -1, -+ .base = 0, - .ngpio = BCM2835_NUM_GPIOS, - .can_sleep = false, - }; - -From d00f2dcc5c02b51e10e6516e12570db41509ffe5 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 27 Jul 2014 20:12:58 +0200 -Subject: [PATCH 045/216] spi: bcm2708: add device tree support - -Add DT support to driver and add to .dtsi file. -Setup pins and spidev in .dts file. -SPI is disabled by default. - -Signed-off-by: Noralf Tronnes - -BCM2708: don't register SPI controller when using DT - -The device for the SPI controller is in the Device Tree. -Only register the device when not using DT. - -Signed-off-by: Noralf Tronnes - -spi: bcm2835: make driver available on ARCH_BCM2708 - -Make this driver available on ARCH_BCM2708 - -Signed-off-by: Noralf Tronnes - -bcm2708: Remove the prohibition on mixing SPIDEV and DT ---- - arch/arm/boot/dts/bcm2708.dtsi | 8 ++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 7 ++++--- - drivers/spi/Kconfig | 4 ++-- - drivers/spi/spi-bcm2708.c | 8 ++++++++ - 4 files changed, 22 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 96b7311..93f009a 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -82,5 +82,13 @@ - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; -+ -+ clk_spi: clock@2 { -+ compatible = "fixed-clock"; -+ reg = <2>; -+ #clock-cells = <0>; -+ clock-output-names = "spi"; -+ clock-frequency = <250000000>; -+ }; - }; - }; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a207ad8..e366bb4 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -836,7 +836,7 @@ void __init bcm2708_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device(&bcm2708_alsa_devices[i]); - -- bcm_register_device(&bcm2708_spi_device); -+ bcm_register_device_dt(&bcm2708_spi_device); - bcm_register_device(&bcm2708_bsc0_device); - bcm_register_device(&bcm2708_bsc1_device); - -@@ -876,8 +876,9 @@ void __init bcm2708_init(void) - system_serial_low = serial; - - #ifdef CONFIG_BCM2708_SPIDEV -- spi_register_board_info(bcm2708_spi_devices, -- ARRAY_SIZE(bcm2708_spi_devices)); -+ if (!use_dt) -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); - #endif - } - -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 9628e75..113bf64 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -77,7 +77,7 @@ config SPI_ATMEL - - config SPI_BCM2835 - tristate "BCM2835 SPI controller" -- depends on ARCH_BCM2835 || COMPILE_TEST -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - help - This selects a driver for the Broadcom BCM2835 SPI master. - -@@ -88,7 +88,7 @@ config SPI_BCM2835 - - config SPI_BCM2708 - tristate "BCM2708 SPI controller driver (SPI0)" -- depends on MACH_BCM2708 -+ depends on MACH_BCM2708 || MACH_BCM2709 - help - This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This - driver is not compatible with the "Universal SPI Master" or the SPI slave -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 349d21f..041b5e2 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -512,6 +512,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - master->setup = bcm2708_spi_setup; - master->transfer = bcm2708_spi_transfer; - master->cleanup = bcm2708_spi_cleanup; -+ master->dev.of_node = pdev->dev.of_node; - platform_set_drvdata(pdev, master); - - bs = spi_master_get_devdata(master); -@@ -596,10 +597,17 @@ static int bcm2708_spi_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm2708_spi_match[] = { -+ { .compatible = "brcm,bcm2708-spi", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_spi_match); -+ - static struct platform_driver bcm2708_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_spi_match, - }, - .probe = bcm2708_spi_probe, - .remove = bcm2708_spi_remove, - -From 13cf0c2ef8f80ef3e128343e2d07cd3d31eb9860 Mon Sep 17 00:00:00 2001 -From: notro -Date: Tue, 29 Jul 2014 11:04:49 +0200 -Subject: [PATCH 046/216] i2c: bcm2708: add device tree support - -Add DT support to driver and add to .dtsi file. -Setup pins in .dts file. -i2c is disabled by default. - -Signed-off-by: Noralf Tronnes - -bcm2708: don't register i2c controllers when using DT - -The devices for the i2c controllers are in the Device Tree. -Only register devices when not using DT. - -Signed-off-by: Noralf Tronnes - -i2c: bcm2835: make driver available on ARCH_BCM2708 - -Make this driver available on ARCH_BCM2708 - -Signed-off-by: Noralf Tronnes ---- - arch/arm/boot/dts/bcm2708.dtsi | 7 +++++++ - arch/arm/mach-bcm2708/bcm2708.c | 4 ++-- - drivers/i2c/busses/Kconfig | 4 ++-- - drivers/i2c/busses/i2c-bcm2708.c | 24 ++++++++++++++++++++++++ - 4 files changed, 35 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 93f009a..0a916a4 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -83,6 +83,13 @@ - #address-cells = <1>; - #size-cells = <0>; - -+ clk_i2c: i2c { -+ compatible = "fixed-clock"; -+ reg = <1>; -+ #clock-cells = <0>; -+ clock-frequency = <250000000>; -+ }; -+ - clk_spi: clock@2 { - compatible = "fixed-clock"; - reg = <2>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e366bb4..a81200e 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -837,8 +837,8 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); -- bcm_register_device(&bcm2708_bsc0_device); -- bcm_register_device(&bcm2708_bsc1_device); -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); - - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); -diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 00c7baa..92009dc 100644 ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -10,7 +10,7 @@ comment "PC SMBus host controller drivers" - - config I2C_BCM2708 - tristate "BCM2708 BSC" -- depends on MACH_BCM2708 -+ depends on MACH_BCM2708 || MACH_BCM2709 - help - Enabling this option will add BSC (Broadcom Serial Controller) - support for the BCM2708. BSC is a Broadcom proprietary bus compatible -@@ -381,7 +381,7 @@ config I2C_AXXIA - - config I2C_BCM2835 - tristate "Broadcom BCM2835 I2C controller" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - help - If you say yes to this option, support will be included for the - BCM2835 I2C controller. -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 7d385a3..526129b 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -303,6 +304,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - unsigned long bus_hz; - u32 cdiv; - -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; -+ } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); -+ } -+ - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "could not get IO memory\n"); -@@ -336,6 +352,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - adap->dev.parent = &pdev->dev; - adap->nr = pdev->id; - strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ adap->dev.of_node = pdev->dev.of_node; - - switch (pdev->id) { - case 0: -@@ -416,10 +433,17 @@ static int bcm2708_i2c_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm2708_i2c_of_match[] = { -+ { .compatible = "brcm,bcm2708-i2c" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); -+ - static struct platform_driver bcm2708_i2c_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_i2c_of_match, - }, - .probe = bcm2708_i2c_probe, - .remove = bcm2708_i2c_remove, - -From b36757e9c2eb66112c0cebce20ac608f1f94cbe4 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 047/216] hid: Reduce default mouse polling interval to 60Hz - -Reduces overhead when using X ---- - drivers/hid/usbhid/hid-core.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c -index bfbe1be..a738b25 100644 ---- a/drivers/hid/usbhid/hid-core.c -+++ b/drivers/hid/usbhid/hid-core.c -@@ -49,7 +49,7 @@ - * Module parameters. - */ - --static unsigned int hid_mousepoll_interval; -+static unsigned int hid_mousepoll_interval = ~0; - module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); - MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); - -@@ -1090,8 +1090,12 @@ static int usbhid_start(struct hid_device *hid) - } - - /* Change the polling interval of mice. */ -- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) -- interval = hid_mousepoll_interval; -+ if (hid->collection->usage == HID_GD_MOUSE) { -+ if (hid_mousepoll_interval == ~0 && interval < 16) -+ interval = 16; -+ else if (hid_mousepoll_interval != ~0 && hid_mousepoll_interval != 0) -+ interval = hid_mousepoll_interval; -+ } - - ret = -ENOMEM; - if (usb_endpoint_dir_in(endpoint)) { - -From 72f91c3f7d8b2944ccadbe7d3d57128c1fc08a8b Mon Sep 17 00:00:00 2001 -From: P33M -Date: Thu, 24 Jul 2014 21:24:03 +0100 -Subject: [PATCH 048/216] usb: core: make overcurrent messages more prominent - -Hub overcurrent messages are more serious than "debug". Increase loglevel. ---- - drivers/usb/core/hub.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 3b71516..8324c14 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -4922,7 +4922,7 @@ static void port_event(struct usb_hub *hub, int port1) - if (portchange & USB_PORT_STAT_C_OVERCURRENT) { - u16 status = 0, unused; - -- dev_dbg(&port_dev->dev, "over-current change\n"); -+ dev_notice(&port_dev->dev, "over-current change\n"); - usb_clear_port_feature(hdev, port1, - USB_PORT_FEAT_C_OVER_CURRENT); - msleep(100); /* Cool down */ - -From cf880d700f626df4e4910b8dedea887720bf6018 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 7 Aug 2014 02:03:50 +0100 -Subject: [PATCH 049/216] Revert "ARM: dma: Use dma_pfn_offset for dma address - translation" - -This reverts commit 6ce0d20016925d031f1e24d64302e4c976d7cec6. ---- - arch/arm/include/asm/dma-mapping.h | 18 +----------------- - 1 file changed, 1 insertion(+), 17 deletions(-) - -diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h -index b52101d3..f5572d9 100644 ---- a/arch/arm/include/asm/dma-mapping.h -+++ b/arch/arm/include/asm/dma-mapping.h -@@ -58,37 +58,21 @@ static inline int dma_set_mask(struct device *dev, u64 mask) - #ifndef __arch_pfn_to_dma - static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) - { -- if (dev) -- pfn -= dev->dma_pfn_offset; - return (dma_addr_t)__pfn_to_bus(pfn); - } - - static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) - { -- unsigned long pfn = __bus_to_pfn(addr); -- -- if (dev) -- pfn += dev->dma_pfn_offset; -- -- return pfn; -+ return __bus_to_pfn(addr); - } - - static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) - { -- if (dev) { -- unsigned long pfn = dma_to_pfn(dev, addr); -- -- return phys_to_virt(__pfn_to_phys(pfn)); -- } -- - return (void *)__bus_to_virt((unsigned long)addr); - } - - static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) - { -- if (dev) -- return pfn_to_dma(dev, virt_to_pfn(addr)); -- - return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); - } - - -From 3492b141fbae950fd9614cb643257658e5d89329 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 050/216] Added support for HiFiBerry DAC+ - -The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses -a different codec chip (PCM5122), therefore a new driver is necessary. ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_dacplus.c | 119 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 147 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_dacplus.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a81200e..5f7df9e 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -649,6 +649,20 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+static struct platform_device snd_rpi_hifiberry_dacplus_device = { -+ .name = "snd-rpi-hifiberry-dacplus", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4d) -+ }, -+}; -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) - static struct platform_device snd_hifiberry_digi_device = { - .name = "snd-hifiberry-digi", -@@ -852,6 +866,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) - bcm_register_device_dt(&snd_hifiberry_digi_device); - i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index faa89ef..7675501 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC - help - Say Y or M if you want to add support for HifiBerry DAC. - -+config SND_BCM2708_SOC_HIFIBERRY_DACPLUS -+ tristate "Support for HifiBerry DAC+" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM512x -+ help -+ Say Y or M if you want to add support for HifiBerry DAC+. -+ - config SND_BCM2708_SOC_HIFIBERRY_DIGI - tristate "Support for HifiBerry Digi" - depends on SND_BCM2708_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index d597fb0..c02e3a2 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -10,11 +10,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - - # BCM2708 Machine Support - snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-rpi-dac-objs := rpi-dac.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -new file mode 100644 -index 0000000..c63387b ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -0,0 +1,119 @@ -+/* -+ * ASoC Driver for HiFiBerry DAC+ -+ * -+ * Author: Daniel Matuschek -+ * Copyright 2014 -+ * based on code by Florian Meier -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/pcm512x.h" -+ -+static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+} -+ -+static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ return 0; -+} -+ -+static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = { -+ .hw_params = snd_rpi_hifiberry_dacplus_hw_params, -+ .startup = snd_rpi_hifiberry_dacplus_startup, -+ .shutdown = snd_rpi_hifiberry_dacplus_shutdown, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = { -+{ -+ .name = "HiFiBerry DAC+", -+ .stream_name = "HiFiBerry DAC+ HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm512x-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm512x.1-004d", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_dacplus_ops, -+ .init = snd_rpi_hifiberry_dacplus_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_dacplus = { -+ .name = "snd_rpi_hifiberry_dacplus", -+ .dai_link = snd_rpi_hifiberry_dacplus_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), -+}; -+ -+static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); -+} -+ -+static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { -+ .driver = { -+ .name = "snd-rpi-hifiberry-dacplus", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_dacplus_probe, -+ .remove = snd_rpi_hifiberry_dacplus_remove, -+}; -+ -+module_platform_driver(snd_rpi_hifiberry_dacplus_driver); -+ -+MODULE_AUTHOR("Daniel Matuschek "); -+MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); -+MODULE_LICENSE("GPL v2"); - -From 3663a863bd1a077dfe48177181118e464a1d6f08 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 051/216] Added driver for HiFiBerry Amp amplifier add-on board - -The driver contains a low-level hardware driver for the TAS5713 and the -drivers for the Raspberry Pi I2S subsystem. ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 +++ - sound/soc/bcm/Kconfig | 7 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_amp.c | 106 ++++++++++++ - sound/soc/codecs/Kconfig | 4 + - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/tas5713.c | 362 ++++++++++++++++++++++++++++++++++++++++ - sound/soc/codecs/tas5713.h | 210 +++++++++++++++++++++++ - 8 files changed, 712 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_amp.c - create mode 100644 sound/soc/codecs/tas5713.c - create mode 100644 sound/soc/codecs/tas5713.h - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5f7df9e..66bc839 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -678,6 +678,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { - - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+static struct platform_device snd_hifiberry_amp_device = { -+ .name = "snd-hifiberry-amp", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("tas5713", 0x1b) -+ }, -+}; -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - static struct platform_device snd_rpi_dac_device = { - .name = "snd-rpi-dac", -@@ -876,6 +890,11 @@ void __init bcm2708_init(void) - i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_amp_device); -+ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - bcm_register_device_dt(&snd_rpi_dac_device); - bcm_register_device_dt(&snd_pcm1794a_codec_device); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 7675501..40d27c1 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -40,6 +40,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI - help - Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. - -+config SND_BCM2708_SOC_HIFIBERRY_AMP -+ tristate "Support for the HifiBerry Amp" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_TAS5713 -+ help -+ Say Y or M if you want to add support for the HifiBerry Amp amplifier board. -+ - config SND_BCM2708_SOC_RPI_DAC - tristate "Support for RPi-DAC" - depends on SND_BCM2708_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index c02e3a2..17ea2b0 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -12,11 +12,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - snd-soc-hifiberry-dac-objs := hifiberry_dac.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o -+snd-soc-hifiberry-amp-objs := hifiberry_amp.o - snd-soc-rpi-dac-objs := rpi-dac.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c -new file mode 100644 -index 0000000..1e87ee06 ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_amp.c -@@ -0,0 +1,106 @@ -+/* -+ * ASoC Driver for HifiBerry AMP -+ * -+ * Author: Sebastian Eickhoff -+ * Copyright 2014 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ // ToDo: init of the dsp-registers. -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params ) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+} -+ -+static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = { -+ .hw_params = snd_rpi_hifiberry_amp_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = { -+ { -+ .name = "HifiBerry AMP", -+ .stream_name = "HifiBerry AMP HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "tas5713-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "tas5713.1-001b", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | -+ SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_amp_ops, -+ .init = snd_rpi_hifiberry_amp_init, -+ }, -+}; -+ -+ -+static struct snd_soc_card snd_rpi_hifiberry_amp = { -+ .name = "snd_rpi_hifiberry_amp", -+ .dai_link = snd_rpi_hifiberry_amp_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), -+}; -+ -+ -+static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_amp.dev = &pdev->dev; -+ -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp); -+ -+ if (ret != 0) { -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ } -+ -+ return ret; -+} -+ -+ -+static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_amp); -+} -+ -+ -+static struct platform_driver snd_rpi_hifiberry_amp_driver = { -+ .driver = { -+ .name = "snd-hifiberry-amp", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_amp_probe, -+ .remove = snd_rpi_hifiberry_amp_remove, -+}; -+ -+ -+module_platform_driver(snd_rpi_hifiberry_amp_driver); -+ -+ -+MODULE_AUTHOR("Sebastian Eickhoff "); -+MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 8682bcf..f49e15d 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -108,6 +108,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_TFA9879 if I2C - select SND_SOC_TLV320AIC23_I2C if I2C - select SND_SOC_TLV320AIC23_SPI if SPI_MASTER -+ select SND_SOC_TAS5713 if I2C - select SND_SOC_TLV320AIC26 if SPI_MASTER - select SND_SOC_TLV320AIC31XX if I2C - select SND_SOC_TLV320AIC32X4 if I2C -@@ -618,6 +619,9 @@ config SND_SOC_TFA9879 - tristate "NXP Semiconductors TFA9879 amplifier" - depends on I2C - -+config SND_SOC_TAS5713 -+ tristate -+ - config SND_SOC_TLV320AIC23 - tristate - -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index c9bceba..078943d 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -108,6 +108,7 @@ snd-soc-sta529-objs := sta529.o - snd-soc-stac9766-objs := stac9766.o - snd-soc-tas5086-objs := tas5086.o - snd-soc-tfa9879-objs := tfa9879.o -+snd-soc-tas5713-objs := tas5713.o - snd-soc-tlv320aic23-objs := tlv320aic23.o - snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o - snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o -@@ -289,6 +290,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o - obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o - obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o - obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o -+obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o - obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o - obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o - obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o -diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c -new file mode 100644 -index 0000000..a24c1da ---- /dev/null -+++ b/sound/soc/codecs/tas5713.c -@@ -0,0 +1,362 @@ -+/* -+ * ASoC Driver for TAS5713 -+ * -+ * Author: Sebastian Eickhoff -+ * Copyright 2014 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "tas5713.h" -+ -+ -+static struct i2c_client *i2c; -+ -+struct tas5713_priv { -+ struct regmap *regmap; -+ int mclk_div; -+ struct snd_soc_codec *codec; -+}; -+ -+static struct tas5713_priv *priv_data; -+ -+ -+ -+ -+/* -+ * _ _ ___ _ ___ _ _ -+ * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___ -+ * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-< -+ * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/ -+ * -+ */ -+ -+static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1); -+ -+ -+static const struct snd_kcontrol_new tas5713_snd_controls[] = { -+ SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv), -+ SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv) -+}; -+ -+ -+ -+ -+/* -+ * __ __ _ _ ___ _ -+ * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _ -+ * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_| -+ * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_| -+ * -+ */ -+ -+static int tas5713_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ u16 blen = 0x00; -+ -+ struct snd_soc_codec *codec; -+ codec = dai->codec; -+ priv_data->codec = dai->codec; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ blen = 0x03; -+ break; -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ blen = 0x1; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ blen = 0x04; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ blen = 0x05; -+ break; -+ default: -+ dev_err(dai->dev, "Unsupported word length: %u\n", -+ params_format(params)); -+ return -EINVAL; -+ } -+ -+ // set word length -+ snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen); -+ -+ return 0; -+} -+ -+ -+static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream) -+{ -+ unsigned int val = 0; -+ -+ struct tas5713_priv *tas5713; -+ struct snd_soc_codec *codec = dai->codec; -+ tas5713 = snd_soc_codec_get_drvdata(codec); -+ -+ if (mute) { -+ val = TAS5713_SOFT_MUTE_ALL; -+ } -+ -+ return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val); -+} -+ -+ -+static const struct snd_soc_dai_ops tas5713_dai_ops = { -+ .hw_params = tas5713_hw_params, -+ .mute_stream = tas5713_mute_stream, -+}; -+ -+ -+static struct snd_soc_dai_driver tas5713_dai = { -+ .name = "tas5713-hifi", -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_48000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ), -+ }, -+ .ops = &tas5713_dai_ops, -+}; -+ -+ -+ -+ -+/* -+ * ___ _ ___ _ -+ * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _ -+ * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_| -+ * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_| -+ * -+ */ -+ -+static int tas5713_remove(struct snd_soc_codec *codec) -+{ -+ struct tas5713_priv *tas5713; -+ -+ tas5713 = snd_soc_codec_get_drvdata(codec); -+ -+ return 0; -+} -+ -+ -+static int tas5713_probe(struct snd_soc_codec *codec) -+{ -+ struct tas5713_priv *tas5713; -+ int i, ret; -+ -+ i2c = container_of(codec->dev, struct i2c_client, dev); -+ -+ tas5713 = snd_soc_codec_get_drvdata(codec); -+ -+ // Reset error -+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ -+ // Trim oscillator -+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); -+ msleep(1000); -+ -+ // Reset error -+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ -+ // Clock mode: 44/48kHz, MCLK=64xfs -+ ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); -+ -+ // I2S 24bit -+ ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); -+ -+ // Unmute -+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -+ ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); -+ -+ // Set volume to 0db -+ ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); -+ -+ // Now start programming the default initialization sequence -+ for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { -+ ret = i2c_master_send(i2c, -+ tas5713_init_sequence[i].data, -+ tas5713_init_sequence[i].size); -+ -+ if (ret < 0) { -+ printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); -+ } -+ } -+ -+ // Unmute -+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -+ -+ -+ return 0; -+} -+ -+ -+static struct snd_soc_codec_driver soc_codec_dev_tas5713 = { -+ .probe = tas5713_probe, -+ .remove = tas5713_remove, -+ .controls = tas5713_snd_controls, -+ .num_controls = ARRAY_SIZE(tas5713_snd_controls), -+}; -+ -+ -+ -+ -+/* -+ * ___ ___ ___ ___ _ -+ * |_ _|_ ) __| | \ _ _(_)_ _____ _ _ -+ * | | / / (__ | |) | '_| \ V / -_) '_| -+ * |___/___\___| |___/|_| |_|\_/\___|_| -+ * -+ */ -+ -+static const struct reg_default tas5713_reg_defaults[] = { -+ { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB -+ { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB -+ { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB -+ { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB -+}; -+ -+ -+static bool tas5713_reg_volatile(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case TAS5713_DEVICE_ID: -+ case TAS5713_ERROR_STATUS: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+ -+static const struct of_device_id tas5713_of_match[] = { -+ { .compatible = "ti,tas5713", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, tas5713_of_match); -+ -+ -+static struct regmap_config tas5713_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ -+ .max_register = TAS5713_MAX_REGISTER, -+ .volatile_reg = tas5713_reg_volatile, -+ -+ .cache_type = REGCACHE_RBTREE, -+ .reg_defaults = tas5713_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults), -+}; -+ -+ -+static int tas5713_i2c_probe(struct i2c_client *i2c, -+ const struct i2c_device_id *id) -+{ -+ int ret; -+ -+ priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL); -+ if (!priv_data) -+ return -ENOMEM; -+ -+ priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config); -+ if (IS_ERR(priv_data->regmap)) { -+ ret = PTR_ERR(priv_data->regmap); -+ return ret; -+ } -+ -+ i2c_set_clientdata(i2c, priv_data); -+ -+ ret = snd_soc_register_codec(&i2c->dev, -+ &soc_codec_dev_tas5713, &tas5713_dai, 1); -+ -+ return ret; -+} -+ -+ -+static int tas5713_i2c_remove(struct i2c_client *i2c) -+{ -+ snd_soc_unregister_codec(&i2c->dev); -+ i2c_set_clientdata(i2c, NULL); -+ -+ kfree(priv_data); -+ -+ return 0; -+} -+ -+ -+static const struct i2c_device_id tas5713_i2c_id[] = { -+ { "tas5713", 0 }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id); -+ -+ -+static struct i2c_driver tas5713_i2c_driver = { -+ .driver = { -+ .name = "tas5713", -+ .owner = THIS_MODULE, -+ .of_match_table = tas5713_of_match, -+ }, -+ .probe = tas5713_i2c_probe, -+ .remove = tas5713_i2c_remove, -+ .id_table = tas5713_i2c_id -+}; -+ -+ -+static int __init tas5713_modinit(void) -+{ -+ int ret = 0; -+ -+ ret = i2c_add_driver(&tas5713_i2c_driver); -+ if (ret) { -+ printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n", -+ ret); -+ } -+ -+ return ret; -+} -+module_init(tas5713_modinit); -+ -+ -+static void __exit tas5713_exit(void) -+{ -+ i2c_del_driver(&tas5713_i2c_driver); -+} -+module_exit(tas5713_exit); -+ -+ -+MODULE_AUTHOR("Sebastian Eickhoff "); -+MODULE_DESCRIPTION("ASoC driver for TAS5713"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/tas5713.h b/sound/soc/codecs/tas5713.h -new file mode 100644 -index 0000000..8f019e0 ---- /dev/null -+++ b/sound/soc/codecs/tas5713.h -@@ -0,0 +1,210 @@ -+/* -+ * ASoC Driver for TAS5713 -+ * -+ * Author: Sebastian Eickhoff -+ * Copyright 2014 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#ifndef _TAS5713_H -+#define _TAS5713_H -+ -+ -+// TAS5713 I2C-bus register addresses -+ -+#define TAS5713_CLOCK_CTRL 0x00 -+#define TAS5713_DEVICE_ID 0x01 -+#define TAS5713_ERROR_STATUS 0x02 -+#define TAS5713_SYSTEM_CTRL1 0x03 -+#define TAS5713_SERIAL_DATA_INTERFACE 0x04 -+#define TAS5713_SYSTEM_CTRL2 0x05 -+#define TAS5713_SOFT_MUTE 0x06 -+#define TAS5713_VOL_MASTER 0x07 -+#define TAS5713_VOL_CH1 0x08 -+#define TAS5713_VOL_CH2 0x09 -+#define TAS5713_VOL_HEADPHONE 0x0A -+#define TAS5713_VOL_CONFIG 0x0E -+#define TAS5713_MODULATION_LIMIT 0x10 -+#define TAS5713_IC_DLY_CH1 0x11 -+#define TAS5713_IC_DLY_CH2 0x12 -+#define TAS5713_IC_DLY_CH3 0x13 -+#define TAS5713_IC_DLY_CH4 0x14 -+ -+#define TAS5713_START_STOP_PERIOD 0x1A -+#define TAS5713_OSC_TRIM 0x1B -+#define TAS5713_BKND_ERR 0x1C -+ -+#define TAS5713_INPUT_MUX 0x20 -+#define TAS5713_SRC_SELECT_CH4 0x21 -+#define TAS5713_PWM_MUX 0x25 -+ -+#define TAS5713_CH1_BQ0 0x29 -+#define TAS5713_CH1_BQ1 0x2A -+#define TAS5713_CH1_BQ2 0x2B -+#define TAS5713_CH1_BQ3 0x2C -+#define TAS5713_CH1_BQ4 0x2D -+#define TAS5713_CH1_BQ5 0x2E -+#define TAS5713_CH1_BQ6 0x2F -+#define TAS5713_CH1_BQ7 0x58 -+#define TAS5713_CH1_BQ8 0x59 -+ -+#define TAS5713_CH2_BQ0 0x30 -+#define TAS5713_CH2_BQ1 0x31 -+#define TAS5713_CH2_BQ2 0x32 -+#define TAS5713_CH2_BQ3 0x33 -+#define TAS5713_CH2_BQ4 0x34 -+#define TAS5713_CH2_BQ5 0x35 -+#define TAS5713_CH2_BQ6 0x36 -+#define TAS5713_CH2_BQ7 0x5C -+#define TAS5713_CH2_BQ8 0x5D -+ -+#define TAS5713_CH4_BQ0 0x5A -+#define TAS5713_CH4_BQ1 0x5B -+#define TAS5713_CH3_BQ0 0x5E -+#define TAS5713_CH3_BQ1 0x5F -+ -+#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B -+#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C -+#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E -+#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F -+#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40 -+#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43 -+#define TAS5713_DRC_CTRL 0x46 -+ -+#define TAS5713_BANK_SW_CTRL 0x50 -+#define TAS5713_CH1_OUTPUT_MIXER 0x51 -+#define TAS5713_CH2_OUTPUT_MIXER 0x52 -+#define TAS5713_CH1_INPUT_MIXER 0x53 -+#define TAS5713_CH2_INPUT_MIXER 0x54 -+#define TAS5713_OUTPUT_POST_SCALE 0x56 -+#define TAS5713_OUTPUT_PRESCALE 0x57 -+ -+#define TAS5713_IDF_POST_SCALE 0x62 -+ -+#define TAS5713_CH1_INLINE_MIXER 0x70 -+#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71 -+#define TAS5713_CH1_R_CHANNEL_MIXER 0x72 -+#define TAS5713_CH1_L_CHANNEL_MIXER 0x73 -+#define TAS5713_CH2_INLINE_MIXER 0x74 -+#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75 -+#define TAS5713_CH2_L_CHANNEL_MIXER 0x76 -+#define TAS5713_CH2_R_CHANNEL_MIXER 0x77 -+ -+#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8 -+#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9 -+ -+#define TAS5713_REGISTER_COUNT 0x46 -+#define TAS5713_MAX_REGISTER 0xF9 -+ -+ -+// Bitmasks for registers -+#define TAS5713_SOFT_MUTE_ALL 0x07 -+ -+ -+ -+struct tas5713_init_command { -+ const int size; -+ const char *const data; -+}; -+ -+static const struct tas5713_init_command tas5713_init_sequence[] = { -+ -+ // Trim oscillator -+ { .size = 2, .data = "\x1B\x00" }, -+ // System control register 1 (0x03): block DC -+ { .size = 2, .data = "\x03\x80" }, -+ // Mute everything -+ { .size = 2, .data = "\x05\x40" }, -+ // Modulation limit register (0x10): 97.7% -+ { .size = 2, .data = "\x10\x02" }, -+ // Interchannel delay registers -+ // (0x11, 0x12, 0x13, and 0x14): BD mode -+ { .size = 2, .data = "\x11\xB8" }, -+ { .size = 2, .data = "\x12\x60" }, -+ { .size = 2, .data = "\x13\xA0" }, -+ { .size = 2, .data = "\x14\x48" }, -+ // PWM shutdown group register (0x19): no shutdown -+ { .size = 2, .data = "\x19\x00" }, -+ // Input multiplexer register (0x20): BD mode -+ { .size = 2, .data = "\x20\x00\x89\x77\x72" }, -+ // PWM output mux register (0x25) -+ // Channel 1 --> OUTA, channel 1 neg --> OUTB -+ // Channel 2 --> OUTC, channel 2 neg --> OUTD -+ { .size = 5, .data = "\x25\x01\x02\x13\x45" }, -+ // DRC control (0x46): DRC off -+ { .size = 5, .data = "\x46\x00\x00\x00\x00" }, -+ // BKND_ERR register (0x1C): 299ms reset period -+ { .size = 2, .data = "\x1C\x07" }, -+ // Mute channel 3 -+ { .size = 2, .data = "\x0A\xFF" }, -+ // Volume configuration register (0x0E): volume slew 512 steps -+ { .size = 2, .data = "\x0E\x90" }, -+ // Clock control register (0x00): 44/48kHz, MCLK=64xfs -+ { .size = 2, .data = "\x00\x60" }, -+ // Bank switch and eq control (0x50): no bank switching -+ { .size = 5, .data = "\x50\x00\x00\x00\x00" }, -+ // Volume registers (0x07, 0x08, 0x09, 0x0A) -+ { .size = 2, .data = "\x07\x20" }, -+ { .size = 2, .data = "\x08\x30" }, -+ { .size = 2, .data = "\x09\x30" }, -+ { .size = 2, .data = "\x0A\xFF" }, -+ // 0x72, 0x73, 0x76, 0x77 input mixer: -+ // no intermix between channels -+ { .size = 5, .data = "\x72\x00\x00\x00\x00" }, -+ { .size = 5, .data = "\x73\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x76\x00\x00\x00\x00" }, -+ { .size = 5, .data = "\x77\x00\x80\x00\x00" }, -+ // 0x70, 0x71, 0x74, 0x75 inline DRC mixer: -+ // no inline DRC inmix -+ { .size = 5, .data = "\x70\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x71\x00\x00\x00\x00" }, -+ { .size = 5, .data = "\x74\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x75\x00\x00\x00\x00" }, -+ // 0x56, 0x57 Output scale -+ { .size = 5, .data = "\x56\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x57\x00\x02\x00\x00" }, -+ // 0x3B, 0x3c -+ { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" }, -+ { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" }, -+ { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ // 0x51, 0x52: output mixer -+ { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" }, -+ { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" }, -+ // PEQ defaults -+ { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+}; -+ -+ -+#endif /* _TAS5713_H */ - -From 5cd70cb7da74d3817f6037213f1a79ff31254d89 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 13 Apr 2015 19:14:18 +0100 -Subject: [PATCH 052/216] bcm2708: Allow option card devices to be configured - via DT - -If the kernel is built with Device Tree support, and if a DT blob -is provided for the kernel at boot time, then the platform devices -for option cards are not created. This avoids both the need to -blacklist unwanted devices, and the need to update the board -support code with each new device. ---- - sound/soc/bcm/bcm2835-i2s.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 03fa1cb..c816526 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { - { .compatible = "brcm,bcm2835-i2s", }, - {}, - }; -+MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); - - static struct platform_driver bcm2835_i2s_driver = { - .probe = bcm2835_i2s_probe, - -From b2ee40fa3d362faf4071abda9f1e273b6e80ec78 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 13 Apr 2015 18:45:39 +0100 -Subject: [PATCH 053/216] Adding Device Tree support for some RPi audio cards - ---- - arch/arm/boot/dts/hifiberry-dac-overlay.dts | 34 +++++++++++++++++++++ - arch/arm/boot/dts/hifiberry-dacplus-overlay.dts | 39 +++++++++++++++++++++++++ - arch/arm/boot/dts/hifiberry-digi-overlay.dts | 39 +++++++++++++++++++++++++ - arch/arm/boot/dts/iqaudio-dac-overlay.dts | 39 +++++++++++++++++++++++++ - arch/arm/boot/dts/iqaudio-dacplus-overlay.dts | 39 +++++++++++++++++++++++++ - sound/soc/bcm/hifiberry_dac.c | 22 ++++++++++++++ - sound/soc/bcm/hifiberry_dacplus.c | 22 ++++++++++++++ - sound/soc/bcm/hifiberry_digi.c | 22 ++++++++++++++ - sound/soc/bcm/iqaudio-dac.c | 16 ++++++++++ - sound/soc/codecs/pcm5102a.c | 7 +++++ - 10 files changed, 279 insertions(+) - create mode 100644 arch/arm/boot/dts/hifiberry-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/hifiberry-dacplus-overlay.dts - create mode 100644 arch/arm/boot/dts/hifiberry-digi-overlay.dts - create mode 100644 arch/arm/boot/dts/iqaudio-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/iqaudio-dacplus-overlay.dts - -diff --git a/arch/arm/boot/dts/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/hifiberry-dac-overlay.dts -new file mode 100644 -index 0000000..5e7633a ---- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for HiFiBerry DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm5102a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5102a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -new file mode 100644 -index 0000000..deb9c625 ---- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dacplus"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/hifiberry-digi-overlay.dts -new file mode 100644 -index 0000000..d0e0d8a ---- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-digi-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Digi -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-digi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8804@3b { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8804"; -+ reg = <0x3b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/iqaudio-dac-overlay.dts -new file mode 100644 -index 0000000..ea8173e ---- /dev/null -+++ b/arch/arm/boot/dts/iqaudio-dac-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -new file mode 100644 -index 0000000..735d8ab ---- /dev/null -+++ b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c -index 4b70b45..3ab0f47 100644 ---- a/sound/soc/bcm/hifiberry_dac.c -+++ b/sound/soc/bcm/hifiberry_dac.c -@@ -72,6 +72,21 @@ static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -@@ -84,10 +99,17 @@ static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) - return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); - } - -+static const struct of_device_id snd_rpi_hifiberry_dac_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-dac", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dac_of_match); -+ - static struct platform_driver snd_rpi_hifiberry_dac_driver = { - .driver = { - .name = "snd-hifiberry-dac", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_dac_of_match, - }, - .probe = snd_rpi_hifiberry_dac_probe, - .remove = snd_rpi_hifiberry_dac_remove, -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index c63387b..11e4f39 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -90,6 +90,21 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); - if (ret) - dev_err(&pdev->dev, -@@ -103,10 +118,17 @@ static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) - return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); - } - -+static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-dacplus", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match); -+ - static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { - .driver = { - .name = "snd-rpi-hifiberry-dacplus", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_dacplus_of_match, - }, - .probe = snd_rpi_hifiberry_dacplus_probe, - .remove = snd_rpi_hifiberry_dacplus_remove, -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index 446ecdd..74a8c73 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -125,6 +125,21 @@ static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_digi.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_digi_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -@@ -137,10 +152,17 @@ static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) - return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); - } - -+static const struct of_device_id snd_rpi_hifiberry_digi_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-digi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_digi_of_match); -+ - static struct platform_driver snd_rpi_hifiberry_digi_driver = { - .driver = { - .name = "snd-hifiberry-digi", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_digi_of_match, - }, - .probe = snd_rpi_hifiberry_digi_probe, - .remove = snd_rpi_hifiberry_digi_remove, -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index aff7377..a38e874 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -82,6 +82,21 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_iqaudio_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); - if (ret) - dev_err(&pdev->dev, -@@ -99,6 +114,7 @@ static const struct of_device_id iqaudio_of_match[] = { - { .compatible = "iqaudio,iqaudio-dac", }, - {}, - }; -+MODULE_DEVICE_TABLE(of, iqaudio_of_match); - - static struct platform_driver snd_rpi_iqaudio_dac_driver = { - .driver = { -diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c -index 126f1e9..7c6598e 100644 ---- a/sound/soc/codecs/pcm5102a.c -+++ b/sound/soc/codecs/pcm5102a.c -@@ -47,12 +47,19 @@ static int pcm5102a_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id pcm5102a_of_match[] = { -+ { .compatible = "ti,pcm5102a", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, pcm5102a_of_match); -+ - static struct platform_driver pcm5102a_codec_driver = { - .probe = pcm5102a_probe, - .remove = pcm5102a_remove, - .driver = { - .name = "pcm5102a-codec", - .owner = THIS_MODULE, -+ .of_match_table = pcm5102a_of_match, - }, - }; - - -From ea3aad745389e9631e71c1b175e37d6874ee980b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 054/216] fdt: Add support for the CONFIG_CMDLINE_EXTEND option - ---- - drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- - 1 file changed, 24 insertions(+), 5 deletions(-) - -diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 3a896c9..0320a6f 100644 ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -915,19 +915,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, - - /* Retrieve command line */ - p = of_get_flat_dt_prop(node, "bootargs", &l); -- if (p != NULL && l > 0) -- strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); - - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else - * managed to set the command line, unless CONFIG_CMDLINE_FORCE - * is set in which case we override whatever was found earlier. -+ * -+ * However, it can be useful to be able to treat the default as -+ * a starting point to be extended using CONFIG_CMDLINE_EXTEND. - */ -+ ((char *)data)[0] = '\0'; -+ - #ifdef CONFIG_CMDLINE --#ifndef CONFIG_CMDLINE_FORCE -- if (!((char *)data)[0]) -+ strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -+ -+ if (p != NULL && l > 0) { -+#if defined(CONFIG_CMDLINE_EXTEND) -+ int len = strlen(data); -+ if (len > 0) { -+ strlcat(data, " ", COMMAND_LINE_SIZE); -+ len++; -+ } -+ strlcpy((char *)data + len, p, min((int)l, COMMAND_LINE_SIZE - len)); -+#elif defined(CONFIG_CMDLINE_FORCE) -+ pr_warning("Ignoring bootargs property (using the default kernel command line)\n"); -+#else -+ /* Neither extend nor force - just override */ -+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); - #endif -- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -+ } -+#else /* CONFIG_CMDLINE */ -+ if (p != NULL && l > 0) { -+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); - #endif /* CONFIG_CMDLINE */ - - pr_debug("Command line is: %s\n", (char*)data); - -From a9a57c353bdccbc5cd60d995c53d6146addf78fc Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 16 Dec 2014 10:23:48 +0000 -Subject: [PATCH 055/216] DT: Add overrides to enable i2c0, i2c1, spi and i2s - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 10 ++++++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 10 ++++++++++ - 2 files changed, 20 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 983c23f..d9886c3 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -79,3 +79,13 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2s_pins>; - }; -+ -+ -+/ { -+ __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index d8c6d15..167b22b 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -79,3 +79,13 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2s_pins>; - }; -+ -+ -+/ { -+ __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ }; -+}; - -From 4bdc71b8c2f9444a8ec6fe833cb92ba4fd4130f7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 18 Dec 2014 16:48:32 +0000 -Subject: [PATCH 056/216] lirc-rpi: Add device tree support, and a suitable - overlay - -The overlay supports DT parameters that match the old module -parameters, except that gpio_in_pull should be set using the -strings "up", "down" or "off". - -lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode ---- - arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 ++++++++++++ - drivers/staging/media/lirc/lirc_rpi.c | 154 +++++++++++++++++++++++++++------ - 2 files changed, 183 insertions(+), 28 deletions(-) - create mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts - -diff --git a/arch/arm/boot/dts/lirc-rpi-overlay.dts b/arch/arm/boot/dts/lirc-rpi-overlay.dts -new file mode 100644 -index 0000000..7d5d82b ---- /dev/null -+++ b/arch/arm/boot/dts/lirc-rpi-overlay.dts -@@ -0,0 +1,57 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ lirc_rpi: lirc_rpi { -+ compatible = "rpi,lirc-rpi"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lirc_pins>; -+ status = "okay"; -+ -+ // Override autodetection of IR receiver circuit -+ // (0 = active high, 1 = active low, -1 = no override ) -+ rpi,sense = <0xffffffff>; -+ -+ // Software carrier -+ // (0 = off, 1 = on) -+ rpi,softcarrier = <1>; -+ -+ // Invert output -+ // (0 = off, 1 = on) -+ rpi,invert = <0>; -+ -+ // Enable debugging messages -+ // (0 = off, 1 = on) -+ rpi,debug = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lirc_pins: lirc_pins { -+ brcm,pins = <17 18>; -+ brcm,function = <1 0>; // out in -+ brcm,pull = <0 1>; // off down -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; -+ gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; -+ gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; -+ -+ sense = <&lirc_rpi>,"rpi,sense:0"; -+ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; -+ invert = <&lirc_rpi>,"rpi,invert:0"; -+ debug = <&lirc_rpi>,"rpi,debug:0"; -+ }; -+}; -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index 8aa452d..24563ec 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - - #include - -@@ -303,32 +304,117 @@ static int is_right_chip(struct gpio_chip *chip, void *data) - return 0; - } - -+static inline int read_bool_property(const struct device_node *np, -+ const char *propname, -+ bool *out_value) -+{ -+ u32 value = 0; -+ int err = of_property_read_u32(np, propname, &value); -+ if (err == 0) -+ *out_value = (value != 0); -+ return err; -+} -+ -+static void read_pin_settings(struct device_node *node) -+{ -+ u32 pin; -+ int index; -+ -+ for (index = 0; -+ of_property_read_u32_index( -+ node, -+ "brcm,pins", -+ index, -+ &pin) == 0; -+ index++) { -+ u32 function; -+ int err; -+ err = of_property_read_u32_index( -+ node, -+ "brcm,function", -+ index, -+ &function); -+ if (err == 0) { -+ if (function == 1) /* Output */ -+ gpio_out_pin = pin; -+ else if (function == 0) /* Input */ -+ gpio_in_pin = pin; -+ } -+ } -+} -+ - static int init_port(void) - { - int i, nlow, nhigh, ret; -+ struct device_node *node; -+ -+ node = lirc_rpi_dev->dev.of_node; - - gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); - -- if (!gpiochip) -+ /* -+ * Because of the lack of a setpull function, only support -+ * pinctrl-bcm2835 if using device tree. -+ */ -+ if (!gpiochip && node) -+ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); -+ -+ if (!gpiochip) { -+ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); - return -ENODEV; -+ } -+ -+ if (node) { -+ struct device_node *pins_node; -+ -+ pins_node = of_parse_phandle(node, "pinctrl-0", 0); -+ if (!pins_node) { -+ printk(KERN_ERR LIRC_DRIVER_NAME -+ ": pinctrl settings not found!\n"); -+ ret = -EINVAL; -+ goto exit_init_port; -+ } -+ -+ read_pin_settings(pins_node); -+ -+ of_property_read_u32(node, "rpi,sense", &sense); -+ -+ read_bool_property(node, "rpi,softcarrier", &softcarrier); -+ -+ read_bool_property(node, "rpi,invert", &invert); -+ -+ read_bool_property(node, "rpi,debug", &debug); - -- if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -- printk(KERN_ALERT LIRC_DRIVER_NAME -- ": cant claim gpio pin %d\n", gpio_out_pin); -- ret = -ENODEV; -- goto exit_init_port; - } -+ else -+ { -+ if (gpio_in_pin >= BCM2708_NR_GPIOS || -+ gpio_out_pin >= BCM2708_NR_GPIOS) { -+ ret = -EINVAL; -+ printk(KERN_ERR LIRC_DRIVER_NAME -+ ": invalid GPIO pin(s) specified!\n"); -+ goto exit_init_port; -+ } - -- if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { -- printk(KERN_ALERT LIRC_DRIVER_NAME -- ": cant claim gpio pin %d\n", gpio_in_pin); -- ret = -ENODEV; -- goto exit_gpio_free_out_pin; -+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_out_pin); -+ ret = -ENODEV; -+ goto exit_init_port; -+ } -+ -+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_in_pin); -+ ret = -ENODEV; -+ goto exit_gpio_free_out_pin; -+ } -+ -+ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); -+ gpiochip->direction_input(gpiochip, gpio_in_pin); -+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); - } - -- bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); -- gpiochip->direction_input(gpiochip, gpio_in_pin); -- gpiochip->direction_output(gpiochip, gpio_out_pin, 1); - gpiochip->set(gpiochip, gpio_out_pin, invert); - - irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); -@@ -522,15 +608,23 @@ static struct lirc_driver driver = { - .owner = THIS_MODULE, - }; - -+static const struct of_device_id lirc_rpi_of_match[] = { -+ { .compatible = "rpi,lirc-rpi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, lirc_rpi_of_match); -+ - static struct platform_driver lirc_rpi_driver = { - .driver = { - .name = LIRC_DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(lirc_rpi_of_match), - }, - }; - - static int __init lirc_rpi_init(void) - { -+ struct device_node *node; - int result; - - /* Init read buffer. */ -@@ -545,15 +639,26 @@ static int __init lirc_rpi_init(void) - goto exit_buffer_free; - } - -- lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); -- if (!lirc_rpi_dev) { -- result = -ENOMEM; -- goto exit_driver_unregister; -+ node = of_find_compatible_node(NULL, NULL, -+ lirc_rpi_of_match[0].compatible); -+ -+ if (node) { -+ /* DT-enabled */ -+ lirc_rpi_dev = of_find_device_by_node(node); -+ WARN_ON(lirc_rpi_dev->dev.of_node != node); -+ of_node_put(node); - } -+ else { -+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); -+ if (!lirc_rpi_dev) { -+ result = -ENOMEM; -+ goto exit_driver_unregister; -+ } - -- result = platform_device_add(lirc_rpi_dev); -- if (result) -- goto exit_device_put; -+ result = platform_device_add(lirc_rpi_dev); -+ if (result) -+ goto exit_device_put; -+ } - - return 0; - -@@ -585,13 +690,6 @@ static int __init lirc_rpi_init_module(void) - if (result) - return result; - -- if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) { -- result = -EINVAL; -- printk(KERN_ERR LIRC_DRIVER_NAME -- ": invalid GPIO pin(s) specified!\n"); -- goto exit_rpi; -- } -- - result = init_port(); - if (result < 0) - goto exit_rpi; - -From fb3c953810dfcbba431ad3c70eb5751d014db152 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 6 Jan 2015 12:06:55 +0000 -Subject: [PATCH 057/216] Fix the activity LED in DT mode - -Add a "leds" node to the base DTBs, and a subnode for the activity -LED. You can change the LED function like this: - - dtparam=act_led_trigger=heartbeat - -Add aliases for the other main nodes (soc, intc). - -Issue: linux #757 ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 18 ++++++++++++++---- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 18 ++++++++++++++---- - arch/arm/boot/dts/bcm2708.dtsi | 11 ++++++++++- - 3 files changed, 38 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index d9886c3..95f03ba 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -7,11 +7,14 @@ - model = "Raspberry Pi Model B+"; - - aliases { -+ soc = &soc; - spi0 = &spi0; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2s = &i2s; - gpio = &gpio; -+ intc = &intc; -+ leds = &leds; - sound = &sound; - }; - -@@ -80,12 +83,19 @@ - pinctrl-0 = <&i2s_pins>; - }; - -+&act_led { -+ gpios = <&gpio 47 0>; -+}; - - / { - __overrides__ { -- i2s = <&i2s>,"status"; -- spi = <&spi0>,"status"; -- i2c0 = <&i2c0>,"status"; -- i2c1 = <&i2c1>,"status"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 167b22b..0631f45 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -7,11 +7,14 @@ - model = "Raspberry Pi Model B"; - - aliases { -+ soc = &soc; - spi0 = &spi0; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2s = &i2s; - gpio = &gpio; -+ intc = &intc; -+ leds = &leds; - sound = &sound; - }; - -@@ -80,12 +83,19 @@ - pinctrl-0 = <&i2s_pins>; - }; - -+&act_led { -+ gpios = <&gpio 16 1>; -+}; - - / { - __overrides__ { -- i2s = <&i2s>,"status"; -- spi = <&spi0>,"status"; -- i2c0 = <&i2c0>,"status"; -- i2c1 = <&i2c1>,"status"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 0a916a4..d879316 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -11,7 +11,7 @@ - bootargs = ""; - }; - -- soc { -+ soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; -@@ -76,6 +76,15 @@ - #size-cells = <0>; - status = "disabled"; - }; -+ -+ leds: leds { -+ compatible = "gpio-leds"; -+ -+ act_led: act { -+ label = "ACT"; -+ linux,default-trigger = "mmc0"; -+ }; -+ }; - }; - - clocks { - -From 1c9f91aafc02bd624edc56899972cb13f48f921d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 15 Jan 2015 10:39:06 +0000 -Subject: [PATCH 058/216] Adding w1-gpio device tree overlays - -N.B. Requires firmware supporting multi-target overrides - -w1-gpio-overlay: - Use if a pullup pin is not required. - Parameters: - gpiopin= // default 4 - -w1-gpio-pullup-overlay: - Use if a pullup pin is required. - Parameters: - gpiopin= // default 4 - pullup= // default 5 ---- - arch/arm/boot/dts/w1-gpio-overlay.dts | 37 ++++++++++++++++++++++++++ - arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 39 ++++++++++++++++++++++++++++ - 2 files changed, 76 insertions(+) - create mode 100644 arch/arm/boot/dts/w1-gpio-overlay.dts - create mode 100644 arch/arm/boot/dts/w1-gpio-pullup-overlay.dts - -diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts -new file mode 100644 -index 0000000..b2c5ee2 ---- /dev/null -+++ b/arch/arm/boot/dts/w1-gpio-overlay.dts -@@ -0,0 +1,37 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4>; -+ brcm,function = <0>; // in (initially) -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -new file mode 100644 -index 0000000..b3e97c2 ---- /dev/null -+++ b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>, <&gpio 5 1>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4 5>; -+ brcm,function = <0 1>; // in out -+ brcm,pull = <0 0>; // off off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ pullup = <&w1>,"gpios:16", -+ <&w1_pins>,"brcm,pins:4"; -+ }; -+}; - -From 740e2da8a9fa6f84e95707ee0a10b4a4cfeaed4a Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Fri, 23 Jan 2015 16:41:17 +0100 -Subject: [PATCH 059/216] TAS5713: return error if initialisation fails - -Existing TAS5713 driver logs errors during initialisation, but does not return -an error code. Therefore even if initialisation fails, the driver will still be -loaded, but won't work. This patch fixes this. I2C communication error will now -reported correctly by a non-zero return code. ---- - sound/soc/codecs/tas5713.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c -index a24c1da..9b27138 100644 ---- a/sound/soc/codecs/tas5713.c -+++ b/sound/soc/codecs/tas5713.c -@@ -182,33 +182,40 @@ static int tas5713_probe(struct snd_soc_codec *codec) - - // Reset error - ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ if (ret < 0) return ret; - - // Trim oscillator -- ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); -+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); -+ if (ret < 0) return ret; - msleep(1000); - - // Reset error - ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ if (ret < 0) return ret; - - // Clock mode: 44/48kHz, MCLK=64xfs - ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); -+ if (ret < 0) return ret; - - // I2S 24bit - ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); -+ if (ret < 0) return ret; - - // Unmute - ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -+ if (ret < 0) return ret; - ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); -+ if (ret < 0) return ret; - - // Set volume to 0db - ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); -+ if (ret < 0) return ret; - - // Now start programming the default initialization sequence - for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { - ret = i2c_master_send(i2c, - tas5713_init_sequence[i].data, - tas5713_init_sequence[i].size); -- - if (ret < 0) { - printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); - } -@@ -216,7 +223,7 @@ static int tas5713_probe(struct snd_soc_codec *codec) - - // Unmute - ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -- -+ if (ret < 0) return ret; - - return 0; - } - -From 9615583a44fc9449d77a247d0207b35eab1db982 Mon Sep 17 00:00:00 2001 +From 0ecc87e37d9107eb533346a4a482bbf78920d16c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 23 Jan 2015 14:48:55 +0000 -Subject: [PATCH 060/216] scripts/dtc: Update to upstream version with overlay +Subject: [PATCH 23/77] scripts/dtc: Update to upstream version with overlay patches --- @@ -123717,736 +117880,716 @@ index 54d4e904..d644002 100644 -#define DTC_VERSION "DTC 1.4.0-dirty" +#define DTC_VERSION "DTC 1.4.1-g36c70742" -From 453099dc662c02d1308039ab2dabb176e052eabf Mon Sep 17 00:00:00 2001 +From 4cccd63c16e3ef4e2a35144e2806d1d1c56bc381 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Fri, 23 Jan 2015 15:18:03 +0000 -Subject: [PATCH 061/216] BCM2708_DT: Build the overlays as well +Date: Mon, 11 May 2015 09:00:42 +0100 +Subject: [PATCH 24/77] scripts: Add mkknlimg and knlinfo scripts from tools + repo +The Raspberry Pi firmware looks for a trailer on the kernel image to +determine whether it was compiled with Device Tree support enabled. +If the firmware finds a kernel without this trailer, or which has a +trailer indicating that it isn't DT-capable, it disables DT support +and reverts to using ATAGs. + +The mkknlimg utility adds that trailer, having first analysed the +image to look for signs of DT support and the kernel version string. + +knlinfo displays the contents of the trailer in the given kernel image. + +scripts/mkknlimg: Add support for ARCH_BCM2835 + +Add a new trailer field indicating whether this is an ARCH_BCM2835 +build, as opposed to MACH_BCM2708/9. If the loader finds this flag +is set it changes the default base dtb file name from bcm270x... +to bcm283y... + +Also update knlinfo to show the status of the field. --- - arch/arm/boot/dts/Makefile | 9 +++++++++ - 1 file changed, 9 insertions(+) + scripts/knlinfo | 168 +++++++++++++++++++++++++++++++++ + scripts/mkknlimg | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 443 insertions(+) + create mode 100755 scripts/knlinfo + create mode 100755 scripts/mkknlimg -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 25fbf52..63d902c 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,15 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+ - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb - # Keep at91 dtb files sorted alphabetically for each SoC - -From b39dde193e6242ec53938122e553e3af4cd528ed Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Sun, 25 Jan 2015 19:41:06 +0100 -Subject: [PATCH 062/216] Add device tree overlay for HiFiBerry Amp/Amp+ - -This patch add the missing device tree file for the HiFiBerry Amp and Amp+ boards. ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/hifiberry-amp-overlay.dts | 39 +++++++++++++++++++++++++++++ - 2 files changed, 40 insertions(+) - create mode 100644 arch/arm/boot/dts/hifiberry-amp-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 63d902c..63d89df 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -15,6 +15,7 @@ endif - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -diff --git a/arch/arm/boot/dts/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/hifiberry-amp-overlay.dts -new file mode 100644 -index 0000000..2c81448 +diff --git a/scripts/knlinfo b/scripts/knlinfo +new file mode 100755 +index 0000000..a0e8663 --- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-amp-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Amp/Amp+ -+/dts-v1/; -+/plugin/; ++++ b/scripts/knlinfo +@@ -0,0 +1,168 @@ ++#!/usr/bin/env perl ++# ---------------------------------------------------------------------- ++# knlinfo by Phil Elwell for Raspberry Pi ++# ++# (c) 2014,2015 Raspberry Pi (Trading) Limited ++# ++# Licensed under the terms of the GNU General Public License. ++# ---------------------------------------------------------------------- + -+/ { -+ compatible = "brcm,bcm2708"; ++use strict; ++use integer; + -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-amp"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; ++use Fcntl ":seek"; + -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; ++my $trailer_magic = 'RPTL'; + -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; ++my %atom_formats = ++( ++ 'DTOK' => \&format_bool, ++ 'KVer' => \&format_string, ++ '283x' => \&format_bool, ++); + -+ tas5713@1b { -+ #sound-dai-cells = <0>; -+ compatible = "ti,tas5713"; -+ reg = <0x1b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; - -From da11da093a2c65a9faa481e0688b0f242476ee78 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 26 Jan 2015 09:18:24 +0000 -Subject: [PATCH 063/216] Add pps-gpio DT overlay - -Parameters: - gpiopin= // Default 18 ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pps-gpio-overlay.dts | 34 ++++++++++++++++++++++++++++++++++ - 2 files changed, 35 insertions(+) - create mode 100644 arch/arm/boot/dts/pps-gpio-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 63d89df..18637de 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -19,6 +19,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/pps-gpio-overlay.dts b/arch/arm/boot/dts/pps-gpio-overlay.dts -new file mode 100644 -index 0000000..40bf0e1 ---- /dev/null -+++ b/arch/arm/boot/dts/pps-gpio-overlay.dts -@@ -0,0 +1,34 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ pps: pps { -+ compatible = "pps-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pps_pins>; -+ gpios = <&gpio 18 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pps_pins: pps_pins { -+ brcm,pins = <18>; -+ brcm,function = <0>; // in -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&pps>,"gpios:4", -+ <&pps_pins>,"brcm,pins:0"; -+ }; -+}; - -From 4cddfa6e3758e34eaeeb8457e0f012965436bc1c Mon Sep 17 00:00:00 2001 -From: Timo Kokkonen -Date: Wed, 29 Oct 2014 23:30:30 -0700 -Subject: [PATCH 064/216] Added support to reserve/enable a GPIO pin to be used - from pps-gpio module (LinuxPPS). Enable PPS modules in default config for - RPi. - ---- - arch/arm/mach-bcm2708/bcm2708.c | 27 +++++++++++++++++++++++++++ - arch/arm/mach-bcm2709/bcm2709.c | 27 +++++++++++++++++++++++++++ - 2 files changed, 54 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 66bc839..cc3e56c 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -93,6 +94,7 @@ static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; -+static int pps_gpio_pin = -1; - - static unsigned use_dt = 0; - -@@ -278,6 +280,19 @@ static struct platform_device w1_device = { - }; - #endif - -+static struct pps_gpio_platform_data pps_gpio_info = { -+ .assert_falling_edge = false, -+ .capture_clear = false, -+ .gpio_pin = -1, -+ .gpio_label = "PPS", -+}; -+ -+static struct platform_device pps_gpio_device = { -+ .name = "pps-gpio", -+ .id = PLATFORM_DEVID_NONE, -+ .dev.platform_data = &pps_gpio_info, -+}; -+ - static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_fb_device = { -@@ -846,6 +861,16 @@ void __init bcm2708_init(void) - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -+ -+#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) -+ if (!use_dt && (pps_gpio_pin >= 0)) { -+ pr_info("bcm2708: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); -+ pps_gpio_info.gpio_pin = pps_gpio_pin; -+ pps_gpio_device.id = pps_gpio_pin; -+ bcm_register_device(&pps_gpio_device); -+ } -+#endif -+ - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1099,3 +1124,5 @@ module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); - module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); -+module_param(pps_gpio_pin, int, 0644); -+MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index c4bd0a4..914c970 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -95,6 +96,7 @@ static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; -+static int pps_gpio_pin = -1; - - static unsigned use_dt = 0; - -@@ -288,6 +290,19 @@ static struct platform_device w1_device = { - }; - #endif - -+static struct pps_gpio_platform_data pps_gpio_info = { -+ .assert_falling_edge = false, -+ .capture_clear = false, -+ .gpio_pin = -1, -+ .gpio_label = "PPS", -+}; -+ -+static struct platform_device pps_gpio_device = { -+ .name = "pps-gpio", -+ .id = PLATFORM_DEVID_NONE, -+ .dev.platform_data = &pps_gpio_info, -+}; -+ - static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_fb_device = { -@@ -868,6 +883,16 @@ void __init bcm2709_init(void) - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -+ -+#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) -+ if (!use_dt && (pps_gpio_pin >= 0)) { -+ pr_info("bcm2709: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); -+ pps_gpio_info.gpio_pin = pps_gpio_pin; -+ pps_gpio_device.id = pps_gpio_pin; -+ bcm_register_device(&pps_gpio_device); -+ } -+#endif -+ - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1267,3 +1292,5 @@ module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); - module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); -+module_param(pps_gpio_pin, int, 0644); -+MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); - -From 2ff35a0e682880dbae67c842805ea848285b373f Mon Sep 17 00:00:00 2001 -From: Serge Schneider -Date: Wed, 3 Sep 2014 14:44:22 +0100 -Subject: [PATCH 065/216] I2C: Only register the I2C device for the current - board revision - ---- - arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 14 ++++++++++++-- - 2 files changed, 24 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index cc3e56c..c8aea5b 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -95,6 +95,7 @@ static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; - static int pps_gpio_pin = -1; -+static bool vc_i2c_override = false; - - static unsigned use_dt = 0; - -@@ -890,8 +891,15 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); -- bcm_register_device_dt(&bcm2708_bsc0_device); -- bcm_register_device_dt(&bcm2708_bsc1_device); -+ -+ if (vc_i2c_override) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ } else { -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } - - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); -@@ -1126,3 +1134,5 @@ module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); - module_param(pps_gpio_pin, int, 0644); - MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -+module_param(vc_i2c_override, bool, 0644); -+MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 914c970..259d552 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -97,6 +97,7 @@ static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; - static int pps_gpio_pin = -1; -+static bool vc_i2c_override = false; - - static unsigned use_dt = 0; - -@@ -914,8 +915,15 @@ void __init bcm2709_init(void) - bcm_register_device(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); -- bcm_register_device_dt(&bcm2708_bsc0_device); -- bcm_register_device_dt(&bcm2708_bsc1_device); -+ -+ if (vc_i2c_override) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ } else { -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } - - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); -@@ -1294,3 +1302,5 @@ module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); - module_param(pps_gpio_pin, int, 0644); - MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -+module_param(vc_i2c_override, bool, 0644); -+MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); - -From 32bee38e1fca47be55a48205e850c16901127982 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 28 Jan 2015 16:22:04 +0000 -Subject: [PATCH 066/216] BCM2708_DT: Add pcf8523-rtc overlay - ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pcf8523-rtc-overlay.dts | 22 ++++++++++++++++++++++ - 2 files changed, 23 insertions(+) - create mode 100644 arch/arm/boot/dts/pcf8523-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 18637de..c909f7b 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -19,6 +19,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -diff --git a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -new file mode 100644 -index 0000000..0071f62 ---- /dev/null -+++ b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF8523 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; - -From 7358633426ec4c3897c26cb1575a0ab7309e4f73 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Sat, 31 Jan 2015 16:07:56 +0100 -Subject: [PATCH 067/216] Add a parameter to turn off SPDIF output if no audio - is playing - -This patch adds the paramater auto_shutdown_output to the kernel module. -Default behaviour of the module is the same, but when auto_shutdown_output -is set to 1, the SPDIF oputput will shutdown if no stream is playing. ---- - sound/soc/bcm/hifiberry_digi.c | 29 ++++++++++++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index 74a8c73..a245995 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -26,6 +26,11 @@ - - #include "../codecs/wm8804.h" - -+static short int auto_shutdown_output = 0; -+module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped"); -+ -+ - static int samplerate=44100; - - static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) -@@ -38,6 +43,25 @@ static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) - return 0; - } - -+static int snd_rpi_hifiberry_digi_startup(struct snd_pcm_substream *substream) { -+ /* turn on digital output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00); -+ return 0; ++if (@ARGV != 1) ++{ ++ print ("Usage: knlinfo \n"); ++ exit(1); +} + -+static void snd_rpi_hifiberry_digi_shutdown(struct snd_pcm_substream *substream) { -+ /* turn off output */ -+ if (auto_shutdown_output) { -+ /* turn off output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c); ++my $kernel_file = $ARGV[0]; ++ ++ ++my ($atoms, $pos) = read_trailer($kernel_file); ++ ++exit(1) if (!$atoms); ++ ++printf("Kernel trailer found at %d/0x%x:\n", $pos, $pos); ++ ++foreach my $atom (@$atoms) ++{ ++ printf(" %s: %s\n", $atom->[0], format_atom($atom)); ++} ++ ++exit(0); ++ ++sub read_trailer ++{ ++ my ($kernel_file) = @_; ++ my $fh; ++ ++ if (!open($fh, '<', $kernel_file)) ++ { ++ print ("* Failed to open '$kernel_file'\n"); ++ return undef; + } ++ ++ if (!seek($fh, -12, SEEK_END)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ ++ my $last_bytes; ++ sysread($fh, $last_bytes, 12); ++ ++ my ($trailer_len, $data_len, $magic) = unpack('VVa4', $last_bytes); ++ ++ if (($magic ne $trailer_magic) || ($data_len != 4)) ++ { ++ print ("* no trailer\n"); ++ return undef; ++ } ++ if (!seek($fh, -12, SEEK_END)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ ++ $trailer_len -= 12; ++ ++ while ($trailer_len > 0) ++ { ++ if ($trailer_len < 8) ++ { ++ print ("* truncated atom header in trailer\n"); ++ return undef; ++ } ++ if (!seek($fh, -8, SEEK_CUR)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ $trailer_len -= 8; ++ ++ my $atom_hdr; ++ sysread($fh, $atom_hdr, 8); ++ my ($atom_len, $atom_type) = unpack('Va4', $atom_hdr); ++ ++ if ($trailer_len < $atom_len) ++ { ++ print ("* truncated atom data in trailer\n"); ++ return undef; ++ } ++ ++ my $rounded_len = (($atom_len + 3) & ~3); ++ if (!seek($fh, -(8 + $rounded_len), SEEK_CUR)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ $trailer_len -= $rounded_len; ++ ++ my $atom_data; ++ sysread($fh, $atom_data, $atom_len); ++ ++ if (!seek($fh, -$atom_len, SEEK_CUR)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ ++ push @$atoms, [ $atom_type, $atom_data ]; ++ } ++ ++ if (($$atoms[-1][0] eq "\x00\x00\x00\x00") && ++ ($$atoms[-1][1] eq "")) ++ { ++ pop @$atoms; ++ } ++ else ++ { ++ print ("* end marker missing from trailer\n"); ++ } ++ ++ return ($atoms, tell($fh)); ++} ++ ++sub format_atom ++{ ++ my ($atom) = @_; ++ ++ my $format_func = $atom_formats{$atom->[0]} || \&format_hex; ++ return $format_func->($atom->[1]); ++} ++ ++sub format_bool ++{ ++ my ($data) = @_; ++ return unpack('V', $data) ? 'true' : 'false'; ++} ++ ++sub format_int ++{ ++ my ($data) = @_; ++ return unpack('V', $data); ++} ++ ++sub format_string ++{ ++ my ($data) = @_; ++ return '"'.$data.'"'; ++} ++ ++sub format_hex ++{ ++ my ($data) = @_; ++ return unpack('H*', $data); ++} +diff --git a/scripts/mkknlimg b/scripts/mkknlimg +new file mode 100755 +index 0000000..3dff948 +--- /dev/null ++++ b/scripts/mkknlimg +@@ -0,0 +1,275 @@ ++#!/usr/bin/env perl ++# ---------------------------------------------------------------------- ++# mkknlimg by Phil Elwell for Raspberry Pi ++# based on extract-ikconfig by Dick Streefland ++# ++# (c) 2009,2010 Dick Streefland ++# (c) 2014,2015 Raspberry Pi (Trading) Limited ++# ++# Licensed under the terms of the GNU General Public License. ++# ---------------------------------------------------------------------- ++ ++use strict; ++use warnings; ++use integer; ++ ++my $trailer_magic = 'RPTL'; ++ ++my $tmpfile1 = "/tmp/mkknlimg_$$.1"; ++my $tmpfile2 = "/tmp/mkknlimg_$$.2"; ++ ++my $dtok = 0; ++my $is_283x = 0; ++ ++while (@ARGV && ($ARGV[0] =~ /^-/)) ++{ ++ my $arg = shift(@ARGV); ++ if ($arg eq '--dtok') ++ { ++ $dtok = 1; ++ } ++ elsif ($arg eq '--283x') ++ { ++ $is_283x = 1; ++ } ++ else ++ { ++ print ("* Unknown option '$arg'\n"); ++ usage(); ++ } ++} ++ ++usage() if (@ARGV != 2); ++ ++my $kernel_file = $ARGV[0]; ++my $out_file = $ARGV[1]; ++ ++if (! -r $kernel_file) ++{ ++ print ("* File '$kernel_file' not found\n"); ++ usage(); ++} ++ ++my @wanted_config_lines = ++( ++ 'CONFIG_BCM2708_DT', ++ 'CONFIG_ARCH_BCM2835' ++); ++ ++my @wanted_strings = ++( ++ 'bcm2708_fb', ++ 'brcm,bcm2835-mmc', ++ 'brcm,bcm2835-sdhost', ++ 'brcm,bcm2708-pinctrl', ++ 'brcm,bcm2835-gpio', ++ 'brcm,bcm2835-pm-wdt' ++); ++ ++my $res = try_extract($kernel_file, $tmpfile1); ++$res = try_decompress('\037\213\010', 'xy', 'gunzip', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\3757zXZ\000', 'abcde', 'unxz --single-stream', -1, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('BZh', 'xy', 'bunzip2', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\135\0\0\0', 'xxx', 'unlzma', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\211\114\132', 'xy', 'lzop -d', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\002\041\114\030', 'xy', 'lz4 -d', 1, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++ ++my $append_trailer; ++my $trailer; ++my $kver = '?'; ++ ++$append_trailer = $dtok; ++ ++if ($res) ++{ ++ $kver = $res->{''} || '?'; ++ print("Version: $kver\n"); ++ ++ $append_trailer = $dtok; ++ if (!$dtok) ++ { ++ if (config_bool($res, 'bcm2708_fb') || ++ config_bool($res, 'brcm,bcm2835-mmc') || ++ config_bool($res, 'brcm,bcm2835-sdhost')) ++ { ++ $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); ++ $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); ++ $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); ++ $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); ++ $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); ++ $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt'); ++ $append_trailer = 1; ++ } ++ else ++ { ++ print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n"); ++ } ++ } ++} ++elsif (!$dtok) ++{ ++ print ("* Is this a valid kernel? In pass-through mode.\n"); ++} ++ ++if ($append_trailer) ++{ ++ printf("DT: %s\n", $dtok ? "y" : "n"); ++ printf("283x: %s\n", $is_283x ? "y" : "n"); ++ ++ my @atoms; ++ ++ push @atoms, [ $trailer_magic, pack('V', 0) ]; ++ push @atoms, [ 'KVer', $kver ]; ++ push @atoms, [ 'DTOK', pack('V', $dtok) ]; ++ push @atoms, [ '283x', pack('V', $is_283x) ]; ++ ++ $trailer = pack_trailer(\@atoms); ++ $atoms[0]->[1] = pack('V', length($trailer)); ++ ++ $trailer = pack_trailer(\@atoms); ++} ++ ++my $ofh; ++my $total_len = 0; ++ ++if ($out_file eq $kernel_file) ++{ ++ die "* Failed to open '$out_file' for append\n" ++ if (!open($ofh, '>>', $out_file)); ++ $total_len = tell($ofh); ++} ++else ++{ ++ die "* Failed to open '$kernel_file'\n" ++ if (!open(my $ifh, '<', $kernel_file)); ++ die "* Failed to create '$out_file'\n" ++ if (!open($ofh, '>', $out_file)); ++ ++ my $copybuf; ++ while (1) ++ { ++ my $bytes = sysread($ifh, $copybuf, 64*1024); ++ last if (!$bytes); ++ syswrite($ofh, $copybuf, $bytes); ++ $total_len += $bytes; ++ } ++ close($ifh); ++} ++ ++if ($trailer) ++{ ++ # Pad to word-alignment ++ syswrite($ofh, "\x000\x000\x000", (-$total_len & 0x3)); ++ syswrite($ofh, $trailer); ++} ++ ++close($ofh); ++ ++exit($trailer ? 0 : 1); ++ ++END { ++ unlink($tmpfile1) if ($tmpfile1); ++ unlink($tmpfile2) if ($tmpfile2); +} + + - static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) - { -@@ -70,7 +94,8 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - break; - default: - dev_err(codec->dev, -- "Failed to set WM8804 SYSCLK, unsupported samplerate\n"); -+ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n", -+ samplerate); - } - - snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); -@@ -96,6 +121,8 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - /* machine stream operations */ - static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = { - .hw_params = snd_rpi_hifiberry_digi_hw_params, -+ .startup = snd_rpi_hifiberry_digi_startup, -+ .shutdown = snd_rpi_hifiberry_digi_shutdown, - }; - - static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { - -From fdcfdf08df6289445d33e8acaf68faa5f5b4923b Mon Sep 17 00:00:00 2001 -From: Joerg Hohensohn -Date: Sun, 1 Feb 2015 22:08:03 +0100 -Subject: [PATCH 068/216] bugfix for 32kHz sample rate, was missing - ---- - sound/soc/bcm/hifiberry_digi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index a245995..a294a1b 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -80,6 +80,7 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - samplerate = params_rate(params); - - switch (samplerate) { -+ case 32000: - case 44100: - case 48000: - case 88200: - -From 601bc9883a6bf209e736d2b1cc5991176ed1abf3 Mon Sep 17 00:00:00 2001 -From: Ryan Coe -Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 069/216] Update ds1307 driver for device-tree support - -Signed-off-by: Ryan Coe ---- - drivers/rtc/rtc-ds1307.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index 4ffabb3..c6789a7 100644 ---- a/drivers/rtc/rtc-ds1307.c -+++ b/drivers/rtc/rtc-ds1307.c -@@ -1242,6 +1242,14 @@ static int ds1307_remove(struct i2c_client *client) - return 0; - } - -+#ifdef CONFIG_OF -+static const struct of_device_id ds1307_of_match[] = { -+ { .compatible = "maxim,ds1307" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, ds1307_of_match); -+#endif ++sub usage ++{ ++ print ("Usage: mkknlimg [--dtok] [--283x] \n"); ++ exit(1); ++} + - static struct i2c_driver ds1307_driver = { - .driver = { - .name = "rtc-ds1307", - -From c6e4ebd2dec4446f061cab8fa0a860e0fe7fd30a Mon Sep 17 00:00:00 2001 -From: Ryan Coe -Date: Sat, 31 Jan 2015 18:26:03 -0700 -Subject: [PATCH 070/216] Add device-tree overlay for ds1307 - -Signed-off-by: Ryan Coe ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/ds1307-rtc-overlay.dts | 22 ++++++++++++++++++++++ - 2 files changed, 23 insertions(+) - create mode 100644 arch/arm/boot/dts/ds1307-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index c909f7b..7755a84 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - -+dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -diff --git a/arch/arm/boot/dts/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/ds1307-rtc-overlay.dts -new file mode 100644 -index 0000000..7d27044 ---- /dev/null -+++ b/arch/arm/boot/dts/ds1307-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for DS1307 Real Time Clock -+/dts-v1/; -+/plugin/; ++sub try_extract ++{ ++ my ($knl, $tmp) = @_; + -+/ { -+ compatible = "brcm,bcm2708"; ++ my $ver = `strings "$knl" | grep -a -E "^Linux version [1-9]"`; + -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; ++ return undef if (!$ver); + -+ ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; ++ chomp($ver); ++ ++ my $res = { ''=>$ver }; ++ my $string_pattern = '^('.join('|', @wanted_strings).')$'; ++ ++ my @matches = `strings \"$knl\" | grep -E \"$string_pattern\"`; ++ foreach my $match (@matches) ++ { ++ chomp($match); ++ $res->{$match} = 1; ++ } ++ ++ my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$'; ++ my $cf1 = 'IKCFG_ST\037\213\010'; ++ my $cf2 = '0123456789'; ++ ++ my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`; ++ if ($pos) ++ { ++ $pos =~ s/:.*[\r\n]*$//s; ++ $pos += 8; ++ my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8); ++ if (($err == 0) || ($err == 2)) ++ { ++ if (open(my $fh, '<', $tmp)) ++ { ++ while (my $line = <$fh>) ++ { ++ chomp($line); ++ $res->{$1} = $2 if ($line =~ /$config_pattern/); ++ } ++ ++ close($fh); ++ } ++ } ++ } ++ ++ return $res; ++} ++ ++ ++sub try_decompress ++{ ++ my ($magic, $subst, $zcat, $idx, $knl, $tmp1, $tmp2) = @_; ++ ++ my $pos = `tr "$magic\n$subst" "\n$subst=" < "$knl" | grep -abo "^$subst"`; ++ if ($pos) ++ { ++ chomp($pos); ++ $pos = (split(/[\r\n]+/, $pos))[$idx]; ++ return undef if (!defined($pos)); ++ $pos =~ s/:.*[\r\n]*$//s; ++ my $cmd = "tail -c+$pos \"$knl\" | $zcat > $tmp2 2> /dev/null"; ++ my $err = (system($cmd) >> 8); ++ return undef if (($err != 0) && ($err != 2)); ++ ++ return try_extract($tmp2, $tmp1); ++ } ++ ++ return undef; ++} ++ ++sub pack_trailer ++{ ++ my ($atoms) = @_; ++ my $trailer = pack('VV', 0, 0); ++ for (my $i = $#$atoms; $i>=0; $i--) ++ { ++ my $atom = $atoms->[$i]; ++ $trailer .= pack('a*x!4Va4', $atom->[1], length($atom->[1]), $atom->[0]); ++ } ++ return $trailer; ++} ++ ++sub config_bool ++{ ++ my ($configs, $wanted) = @_; ++ my $val = $configs->{$wanted} || 'n'; ++ return (($val eq 'y') || ($val eq '1')); ++} -From 7abd2997600af8ee74045e490c6db3a41f716636 Mon Sep 17 00:00:00 2001 +From 780d72c0e43679ff58f9f3f005ef17a5fa79ee9f Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 071/216] BCM270x_DT: Add pwr_led, and the required "input" - trigger +Date: Fri, 5 Dec 2014 17:26:26 +0000 +Subject: [PATCH 25/77] fdt: Add support for the CONFIG_CMDLINE_EXTEND option -The "input" trigger makes the associated GPIO an input. This is to support -the Raspberry Pi PWR LED, which is driven by external hardware in normal use. - -N.B. pwr_led is not available on Model A or B boards. --- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 18 ++++- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 8 ++- - arch/arm/boot/dts/bcm2708.dtsi | 7 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 115 +++++++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2709.dtsi | 5 -- - drivers/leds/trigger/Kconfig | 7 ++ - drivers/leds/trigger/Makefile | 1 + - drivers/leds/trigger/ledtrig-input.c | 65 +++++++++++++++++ - 8 files changed, 213 insertions(+), 13 deletions(-) + drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index cde35c5d01..dd7fbfe 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -933,19 +933,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, + + /* Retrieve command line */ + p = of_get_flat_dt_prop(node, "bootargs", &l); +- if (p != NULL && l > 0) +- strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + + /* + * CONFIG_CMDLINE is meant to be a default in case nothing else + * managed to set the command line, unless CONFIG_CMDLINE_FORCE + * is set in which case we override whatever was found earlier. ++ * ++ * However, it can be useful to be able to treat the default as ++ * a starting point to be extended using CONFIG_CMDLINE_EXTEND. + */ ++ ((char *)data)[0] = '\0'; ++ + #ifdef CONFIG_CMDLINE +-#ifndef CONFIG_CMDLINE_FORCE +- if (!((char *)data)[0]) ++ strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); ++ ++ if (p != NULL && l > 0) { ++#if defined(CONFIG_CMDLINE_EXTEND) ++ int len = strlen(data); ++ if (len > 0) { ++ strlcat(data, " ", COMMAND_LINE_SIZE); ++ len++; ++ } ++ strlcpy((char *)data + len, p, min((int)l, COMMAND_LINE_SIZE - len)); ++#elif defined(CONFIG_CMDLINE_FORCE) ++ pr_warning("Ignoring bootargs property (using the default kernel command line)\n"); ++#else ++ /* Neither extend nor force - just override */ ++ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + #endif +- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); ++ } ++#else /* CONFIG_CMDLINE */ ++ if (p != NULL && l > 0) { ++ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + #endif /* CONFIG_CMDLINE */ + + pr_debug("Command line is: %s\n", (char*)data); + +From 7ff1afbc6732a16d87c5640be8fec1de73a39770 Mon Sep 17 00:00:00 2001 +From: notro +Date: Wed, 9 Jul 2014 14:46:08 +0200 +Subject: [PATCH 26/77] BCM2708: Add core Device Tree support + +Add the bare minimum needed to boot BCM2708 from a Device Tree. + +Signed-off-by: Noralf Tronnes + +BCM2708: DT: change 'axi' nodename to 'soc' + +Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835. +The VC4 bootloader fills in certain properties in the 'axi' subtree, +but since this is part of an upstreaming effort, the name is changed. + +Signed-off-by: Noralf Tronnes notro@tronnes.org + +BCM2708_DT: Correct length of the peripheral space +--- + arch/arm/boot/dts/Makefile | 27 ++ + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 140 ++++++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 130 ++++++ + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 18 + + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 51 +++ + arch/arm/boot/dts/bcm2708.dtsi | 19 + + arch/arm/boot/dts/bcm2708_common.dtsi | 230 ++++++++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 140 ++++++ + arch/arm/boot/dts/bcm2709.dtsi | 70 +++ + arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 45 +- + arch/arm/boot/dts/bcm2835-rpi-b.dts | 29 +- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 97 +++- + arch/arm/boot/dts/bcm2835.dtsi | 45 +- + arch/arm/boot/dts/overlays/Makefile | 57 +++ + arch/arm/boot/dts/overlays/README | 493 +++++++++++++++++++++ + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 ++++ + .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + + arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 +++ + .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ + .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ + .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ + .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 ++++ + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 ++++++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 49 ++ + arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ + .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 +++ + .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 +++ + arch/arm/boot/dts/overlays/mmc-overlay.dts | 19 + + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 109 +++++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 ++++ + .../dts/overlays/pitft28-resistive-overlay.dts | 115 +++++ + arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ + arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 ++++ + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 78 ++++ + arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 18 + + arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts | 18 + + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++++ + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ + .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ + 45 files changed, 3316 insertions(+), 54 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts + create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi + create mode 100644 arch/arm/boot/dts/bcm2708.dtsi + create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts - create mode 100644 drivers/leds/trigger/ledtrig-input.c + create mode 100644 arch/arm/boot/dts/bcm2709.dtsi + create mode 100644 arch/arm/boot/dts/overlays/Makefile + create mode 100644 arch/arm/boot/dts/overlays/README + create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts + create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 992736b..12de305 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1,5 +1,21 @@ + ifeq ($(CONFIG_OF),y) + ++dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb ++dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb ++dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb ++dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb ++ ++# Raspberry Pi ++ifeq ($(CONFIG_BCM2708_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_BCM2709_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_ARCH_BCM2835),y) ++ RPI_DT_OVERLAYS=y ++endif ++ + dtb-$(CONFIG_ARCH_ALPINE) += \ + alpine-db.dtb + dtb-$(CONFIG_MACH_ASM9260) += \ +@@ -660,7 +676,18 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt6592-evb.dtb \ + mt8127-moose.dtb \ + mt8135-evbp1.dtb ++ ++targets += dtbs dtbs_install ++targets += $(dtb-y) ++ + endif + + always := $(dtb-y) + clean-files := *.dtb ++ ++# Enable fixups to support overlays on BCM2708 platforms ++ifeq ($(RPI_DT_OVERLAYS),y) ++ DTC_FLAGS ?= -@ ++endif ++ ++subdir-y += overlays diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 95f03ba..b409c2c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -83,8 +83,18 @@ - pinctrl-0 = <&i2s_pins>; - }; - --&act_led { -- gpios = <&gpio 47 0>; -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 47 0>; -+ }; -+ -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; -+ }; - }; - - / { -@@ -97,5 +107,9 @@ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 0631f45..1ecd1a1 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -83,8 +83,12 @@ - pinctrl-0 = <&i2s_pins>; - }; - --&act_led { -- gpios = <&gpio 16 1>; -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 16 1>; -+ }; - }; - - / { -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index d879316..0713a1ed 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -79,11 +79,10 @@ - - leds: leds { - compatible = "gpio-leds"; -+ }; - -- act_led: act { -- label = "ACT"; -- linux,default-trigger = "mmc0"; -- }; -+ arm-pmu { -+ compatible = "arm,arm1176-pmu"; - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts new file mode 100644 -index 0000000..46f4908 +index 0000000..0fa2210 --- /dev/null -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -0,0 +1,115 @@ ++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +@@ -0,0 +1,140 @@ +/dts-v1/; + -+/include/ "bcm2709.dtsi" ++/include/ "bcm2708.dtsi" + +/ { -+ compatible = "brcm,bcm2709"; -+ model = "Raspberry Pi 2 Model B"; ++ compatible = "brcm,bcm2708"; ++ model = "Raspberry Pi Model B+"; + + aliases { + soc = &soc; @@ -124457,7 +118600,11 @@ index 0000000..46f4908 + gpio = &gpio; + intc = &intc; + leds = &leds; ++ audio = &audio; + sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; + }; + + sound: sound { @@ -124486,6 +118633,19 @@ index 0000000..46f4908 + }; +}; + ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; @@ -124541,10 +118701,14 @@ index 0000000..46f4908 + +/ { + __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -124553,24 +118717,8655 @@ index 0000000..46f4908 + pwr_led_gpio = <&pwr_led>,"gpios:4"; + pwr_led_activelow = <&pwr_led>,"gpios:8"; + pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts +new file mode 100644 +index 0000000..3fd49d0 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts +@@ -0,0 +1,130 @@ ++/dts-v1/; ++ ++/include/ "bcm2708.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ model = "Raspberry Pi Model B"; ++ ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ audio = &audio; ++ sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; ++ }; ++ ++ sound: sound { ++ }; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <28 29 30 31>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 16 1>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts +new file mode 100755 +index 0000000..238bd65 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts +@@ -0,0 +1,18 @@ ++/dts-v1/; ++ ++/include/ "bcm2708-rpi-cm.dtsi" ++ ++/ { ++ model = "Raspberry Pi Compute Module"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi +new file mode 100644 +index 0000000..3da7d3b +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi +@@ -0,0 +1,51 @@ ++/include/ "bcm2708.dtsi" ++ ++/ { ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ audio = &audio; ++ sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; ++ }; ++ ++ sound: sound { ++ }; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&audio { ++ status = "okay"; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi +new file mode 100644 +index 0000000..0d47427 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708.dtsi +@@ -0,0 +1,19 @@ ++/include/ "bcm2708_common.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ model = "BCM2708"; ++ ++ chosen { ++ /* No padding required - the boot loader can do that. */ ++ bootargs = ""; ++ }; ++ ++ soc { ++ ranges = <0x7e000000 0x20000000 0x01000000>; ++ ++ arm-pmu { ++ compatible = "arm,arm1176-pmu"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi +new file mode 100644 +index 0000000..8caa234 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708_common.dtsi +@@ -0,0 +1,230 @@ ++/include/ "skeleton.dtsi" ++ ++/ { ++ interrupt-parent = <&intc>; ++ ++ /* Onboard audio */ ++ audio: audio { ++ compatible = "brcm,bcm2835-audio"; ++ brcm,pwm-channels = <8>; ++ status = "disabled"; ++ }; ++ ++ soc: soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ dma: dma@7e007000 { ++ compatible = "brcm,bcm2835-dma"; ++ reg = <0x7e007000 0xf00>; ++ interrupts = <1 16>, ++ <1 17>, ++ <1 18>, ++ <1 19>, ++ <1 20>, ++ <1 21>, ++ <1 22>, ++ <1 23>, ++ <1 24>, ++ <1 25>, ++ <1 26>, ++ <1 27>, ++ <1 28>; ++ ++ #dma-cells = <1>; ++ brcm,dma-channel-mask = <0x7f35>; ++ }; ++ ++ intc: interrupt-controller { ++ compatible = "brcm,bcm2708-armctrl-ic"; ++ reg = <0x7e00b200 0x200>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ watchdog: watchdog@7e100000 { ++ compatible = "brcm,bcm2835-pm-wdt"; ++ reg = <0x7e100000 0x28>; ++ status = "disabled"; ++ }; ++ ++ random: rng@7e104000 { ++ compatible = "brcm,bcm2835-rng"; ++ reg = <0x7e104000 0x10>; ++ status = "disabled"; ++ }; ++ ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2708-vcio"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ }; ++ ++ gpio: gpio { ++ compatible = "brcm,bcm2835-gpio"; ++ reg = <0x7e200000 0xb4>; ++ interrupts = <2 17>, <2 18>; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ mmc: mmc@7e300000 { ++ compatible = "brcm,bcm2835-mmc"; ++ reg = <0x7e300000 0x100>; ++ interrupts = <2 30>; ++ clocks = <&clk_mmc>; ++ dmas = <&dma 11>, ++ <&dma 11>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ uart0: uart@7e201000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x7e201000 0x1000>; ++ interrupts = <2 25>; ++ clocks = <&clk_uart0 &clk_apb_p>; ++ clock-names = "uartclk","apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; // For an explanation, see ++ // https://github.com/raspberrypi/linux/commit/13731d862cf5219216533a3b0de052cee4cc5038 ++ status = "disabled"; ++ }; ++ ++ i2s: i2s@7e203000 { ++ compatible = "brcm,bcm2708-i2s"; ++ reg = <0x7e203000 0x20>, ++ <0x7e101098 0x02>; ++ ++ //dmas = <&dma 2>, ++ // <&dma 3>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ spi0: spi@7e204000 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204000 0x1000>; ++ interrupts = <2 22>; ++ clocks = <&clk_spi>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ /* the dma channels */ ++ dmas = <&dma 6>, <&dma 7>; ++ dma-names = "tx", "rx"; ++ /* the chipselects used - <0> means native GPIO ++ * add more gpios if necessary as <&gpio 6 1> ++ * (but do not forget to make them output!) ++ */ ++ cs-gpios = <0>, <0>; ++ }; ++ ++ i2c0: i2c@7e205000 { ++ compatible = "brcm,bcm2708-i2c"; ++ reg = <0x7e205000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clk_i2c>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ uart1: uart@7e215040 { ++ compatible = "brcm,bcm2835-aux-uart", "ns16550"; ++ reg = <0x7e215040 0x40>; ++ interrupts = <1 29>; ++ clock-frequency = <500000000>; ++ reg-shift = <2>; ++ no-loopback-test; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@7e804000 { ++ compatible = "brcm,bcm2708-i2c"; ++ reg = <0x7e804000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clk_i2c>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usb: usb@7e980000 { ++ compatible = "brcm,bcm2708-usb"; ++ reg = <0x7e980000 0x10000>, ++ <0x7e006000 0x1000>; ++ interrupts = <2 0>, ++ <1 9>; ++ }; ++ ++ leds: leds { ++ compatible = "gpio-leds"; ++ }; ++ ++ fb: fb { ++ compatible = "brcm,bcm2708-fb"; ++ status = "disabled"; ++ }; ++ ++ vchiq: vchiq { ++ compatible = "brcm,bcm2835-vchiq"; ++ reg = <0x7e00b840 0xf>; ++ interrupts = <0 2>; ++ }; ++ ++ thermal: thermal { ++ compatible = "brcm,bcm2835-thermal"; ++ }; ++ }; ++ ++ clocks: clocks { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ clk_mmc: clock@0 { ++ compatible = "fixed-clock"; ++ reg = <0>; ++ #clock-cells = <0>; ++ clock-output-names = "mmc"; ++ clock-frequency = <250000000>; ++ }; ++ ++ clk_i2c: clock@1 { ++ compatible = "fixed-clock"; ++ reg = <1>; ++ #clock-cells = <0>; ++ clock-output-names = "i2c"; ++ clock-frequency = <250000000>; ++ }; ++ ++ clk_spi: clock@2 { ++ compatible = "fixed-clock"; ++ reg = <2>; ++ #clock-cells = <0>; ++ clock-output-names = "spi"; ++ clock-frequency = <250000000>; ++ }; ++ ++ clk_uart0: clock@3 { ++ compatible = "fixed-clock"; ++ reg = <3>; ++ #clock-cells = <0>; ++ clock-output-names = "uart0_pclk"; ++ clock-frequency = <3000000>; ++ }; ++ ++ clk_apb_p: clock@4 { ++ compatible = "fixed-clock"; ++ reg = <4>; ++ #clock-cells = <0>; ++ clock-output-names = "apb_pclk"; ++ clock-frequency = <126000000>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +new file mode 100644 +index 0000000..8aaaf1f +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +@@ -0,0 +1,140 @@ ++/dts-v1/; ++ ++/include/ "bcm2709.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2709"; ++ model = "Raspberry Pi 2 Model B"; ++ ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ audio = &audio; ++ sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; ++ }; ++ ++ sound: sound { ++ }; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&gpio 35 0>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index 15c7e65..34d2226 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi +new file mode 100644 +index 0000000..5e0b935 +--- /dev/null +++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -79,11 +79,6 @@ +@@ -0,0 +1,70 @@ ++/include/ "bcm2708_common.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2709"; ++ model = "BCM2709"; ++ ++ chosen { ++ /* No padding required - the boot loader can do that. */ ++ bootargs = ""; ++ }; ++ ++ soc { ++ ranges = <0x7e000000 0x3f000000 0x01000000>; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = <3 9>; ++ }; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ clock-frequency = <19200000>; ++ interrupts = <3 0>, // PHYS_SECURE_PPI ++ <3 1>, // PHYS_NONSECURE_PPI ++ <3 3>, // VIRT_PPI ++ <3 2>; // HYP_PPI ++ always-on; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ v7_cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf00>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf01>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf02>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf03>; ++ clock-frequency = <800000000>; ++ }; ++ }; ++ ++ __overrides__ { ++ arm_freq = <&v7_cpu0>, "clock-frequency:0", ++ <&v7_cpu1>, "clock-frequency:0", ++ <&v7_cpu2>, "clock-frequency:0", ++ <&v7_cpu3>, "clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +index e479515..b0fb0e8 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +@@ -4,27 +4,40 @@ + / { + compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; + model = "Raspberry Pi Model B+"; ++}; ++ ++&gpio { ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; - leds: leds { - compatible = "gpio-leds"; +- leds { +- act { +- gpios = <&gpio 47 0>; +- }; ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&act_led { ++ gpios = <&gpio 47 0>; ++}; + +- pwr { +- label = "PWR"; +- gpios = <&gpio 35 0>; +- default-state = "keep"; +- linux,default-trigger = "default-on"; +- }; ++&leds { ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&gpio 35 0>; + }; + }; + +-&gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; + +- /* I2S interface */ +- i2s_alt0: i2s_alt0 { +- brcm,pins = <18 19 20 21>; +- brcm,function = <4>; /* alt0 */ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts +index bafa46f..b867224 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts +@@ -5,19 +5,28 @@ + compatible = "raspberrypi,model-b", "brcm,bcm2835"; + model = "Raspberry Pi Model B"; + +- leds { +- act { +- gpios = <&gpio 16 1>; +- }; +- }; + }; + + &gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; - -- act_led: act { -- label = "led0"; -- linux,default-trigger = "mmc0"; -- }; +- /* I2S interface */ +- i2s_alt2: i2s_alt2 { ++ i2s_pins: i2s { + brcm,pins = <28 29 30 31>; +- brcm,function = <6>; /* alt2 */ ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&act_led { ++ gpios = <&gpio 16 1>; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index c706448..466f02b 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -1,51 +1,112 @@ + /include/ "bcm2835.dtsi" + + / { ++ /* This is left here in case u-boot needs it */ + memory { + reg = <0 0x10000000>; + }; + +- leds { ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ sound = &sound; ++ }; ++ ++ leds: leds { + compatible = "gpio-leds"; + +- act { +- label = "ACT"; +- default-state = "keep"; +- linux,default-trigger = "heartbeat"; ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; + }; + }; ++ ++ /* Onboard audio */ ++ audio: audio { ++ compatible = "brcm,bcm2835-audio"; ++ brcm,pwm-channels = <8>; ++ status = "disabled"; ++ }; ++ ++ /* External sound card */ ++ sound: sound { ++ }; + }; + + &gpio { +- pinctrl-names = "default"; ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; + +- gpioout: gpioout { +- brcm,pins = <6>; +- brcm,function = <1>; /* GPIO out */ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; + }; + +- alt0: alt0 { +- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; +- brcm,function = <4>; /* alt0 */ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; + }; + +- alt3: alt3 { +- brcm,pins = <48 49 50 51 52 53>; +- brcm,function = <7>; /* alt3 */ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; + }; + }; + + &i2c0 { +- status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; + }; + + &i2c1 { +- status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; + }; + +-&sdhci { ++&mmc { + status = "okay"; + bus-width = <4>; + }; ++ ++&fb { ++ status = "okay"; ++}; ++ ++/ { ++ __overrides__ { ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ audio = <&audio>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index 3342cb1..4b6dd65f 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -6,14 +6,15 @@ + interrupt-parent = <&intc>; + + chosen { +- bootargs = "earlyprintk console=ttyAMA0"; ++ bootargs = ""; + }; + +- soc { ++ soc: soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x7e000000 0x20000000 0x02000000>; ++ dma-ranges = <0x40000000 0x00000000 0x20000000>; + + timer@7e003000 { + compatible = "brcm,bcm2835-system-timer"; +@@ -50,16 +51,22 @@ + #interrupt-cells = <2>; }; +- watchdog@7e100000 { ++ watchdog: watchdog@7e100000 { + compatible = "brcm,bcm2835-pm-wdt"; + reg = <0x7e100000 0x28>; + }; + +- rng@7e104000 { ++ random: rng@7e104000 { + compatible = "brcm,bcm2835-rng"; + reg = <0x7e104000 0x10>; + }; + ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2708-vcio"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ }; ++ + gpio: gpio@7e200000 { + compatible = "brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; +@@ -83,7 +90,7 @@ + #interrupt-cells = <2>; + }; + +- uart@7e201000 { ++ uart0: uart@7e201000 { + compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; + reg = <0x7e201000 0x1000>; + interrupts = <2 25>; +@@ -102,7 +109,7 @@ + status = "disabled"; + }; + +- spi: spi@7e204000 { ++ spi0: spi@7e204000 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x1000>; + interrupts = <2 22>; +@@ -122,11 +129,14 @@ + status = "disabled"; + }; + +- sdhci: sdhci@7e300000 { +- compatible = "brcm,bcm2835-sdhci"; ++ mmc: mmc@7e300000 { ++ compatible = "brcm,bcm2835-mmc"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clk_mmc>; ++ dmas = <&dma 11>, ++ <&dma 11>; ++ dma-names = "tx", "rx"; + status = "disabled"; + }; + +@@ -140,7 +150,7 @@ + status = "disabled"; + }; + +- usb@7e980000 { ++ usb: usb@7e980000 { + compatible = "brcm,bcm2835-usb"; + reg = <0x7e980000 0x10000>; + interrupts = <1 9>; +@@ -149,6 +159,21 @@ arm-pmu { + compatible = "arm,arm1176-pmu"; + }; ++ ++ fb: fb { ++ compatible = "brcm,bcm2708-fb"; ++ status = "disabled"; ++ }; ++ ++ vchiq: vchiq { ++ compatible = "brcm,bcm2835-vchiq"; ++ reg = <0x7e00b840 0xf>; ++ interrupts = <0 2>; ++ }; ++ ++ thermal: thermal { ++ compatible = "brcm,bcm2835-thermal"; ++ }; + }; + + clocks { +@@ -161,7 +186,7 @@ + reg = <0>; + #clock-cells = <0>; + clock-output-names = "mmc"; +- clock-frequency = <100000000>; ++ clock-frequency = <250000000>; + }; + + clk_i2c: clock@1 { +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +new file mode 100644 +index 0000000..6947556 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -0,0 +1,57 @@ ++ifeq ($(CONFIG_OF),y) ++ ++# Overlays for the Raspberry Pi platform ++ ++ifeq ($(CONFIG_BCM2708_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_BCM2709_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_ARCH_BCM2835),y) ++ RPI_DT_OVERLAYS=y ++endif ++ ++dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb ++ ++targets += dtbs dtbs_install ++targets += $(dtb-y) ++ ++endif ++ ++always := $(dtb-y) ++clean-files := *.dtb ++ ++# Enable fixups to support overlays on BCM2708 platforms ++ifeq ($(RPI_DT_OVERLAYS),y) ++ DTC_FLAGS ?= -@ ++endif +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +new file mode 100644 +index 0000000..3e08f98 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/README +@@ -0,0 +1,493 @@ ++Introduction ++============ ++ ++This directory contains Device Tree overlays. Device Tree makes it possible ++to support many hardware configurations with a single kernel and without the ++need to explicitly load or blacklist kernel modules. Note that this isn't a ++"pure" Device Tree configuration (c.f. MACH_BCM2835) - some on-board devices ++are still configured by the board support code, but the intention is to ++eventually reach that goal. ++ ++On Raspberry Pi, Device Tree usage is controlled from /boot/config.txt. By ++default, the Raspberry Pi kernel boots with device tree enabled. You can ++completely disable DT usage (for now) by adding: ++ ++ device_tree= ++ ++to your config.txt, which should cause your Pi to revert to the old way of ++doing things after a reboot. ++ ++In /boot you will find a .dtb for each base platform. This describes the ++hardware that is part of the Raspberry Pi board. The loader (start.elf and its ++siblings) selects the .dtb file appropriate for the platform by name, and reads ++it into memory. At this point, all of the optional interfaces (i2c, i2s, spi) ++are disabled, but they can be enabled using Device Tree parameters: ++ ++ dtparam=i2c=on,i2s=on,spi=on ++ ++However, this shouldn't be necessary in many use cases because loading an ++overlay that requires one of those interfaces will cause it to be enabled ++automatically, and it is advisable to only enable interfaces if they are ++needed. ++ ++Configuring additional, optional hardware is done using Device Tree overlays ++(see below). ++ ++raspi-config ++============ ++ ++The Advanced Options section of the raspi-config utility can enable and disable ++Device Tree use, as well as toggling the I2C and SPI interfaces. Note that it ++is possible to both enable an interface and blacklist the driver, if for some ++reason you should want to defer the loading. ++ ++Modules ++======= ++ ++As well as describing the hardware, Device Tree also gives enough information ++to allow suitable driver modules to be located and loaded, with the corollary ++that unneeded modules are not loaded. As a result it should be possible to ++remove lines from /etc/modules, and /etc/modprobe.d/raspi-blacklist.conf can ++have its contents deleted (or commented out). ++ ++Using Overlays ++============== ++ ++Overlays are loaded using the "dtoverlay" directive. As an example, consider the ++popular lirc-rpi module, the Linux Infrared Remote Control driver. In the ++pre-DT world this would be loaded from /etc/modules, with an explicit ++"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, ++this becomes a line in config.txt: ++ ++ dtoverlay=lirc-rpi ++ ++This causes the file /boot/overlays/lirc-rpi-overlay.dtb to be loaded. By ++default it will use GPIOs 17 (out) and 18 (in), but this can be modified using ++DT parameters: ++ ++ dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 ++ ++Parameters always have default values, although in some cases (e.g. "w1-gpio") ++it is necessary to provided multiple overlays in order to get the desired ++behaviour. See the list of overlays below for a description of the parameters and their defaults. ++ ++The Overlay and Parameter Reference ++=================================== ++ ++Name: ++Info: Configures the base Raspberry Pi hardware ++Load: ++Params: ++ audio Set to "on" to disable the onboard ALSA audio ++ interface (default "off") ++ ++ i2c_arm Set to "on" to enable the ARM's i2c interface ++ (default "off") ++ ++ i2c_vc Set to "on" to enable the i2c interface ++ usually reserved for the VideoCore processor ++ (default "off") ++ ++ i2c An alias for i2c_arm ++ ++ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface ++ (default "100000") ++ ++ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface ++ (default "100000") ++ ++ i2c_baudrate An alias for i2c_arm_baudrate ++ ++ i2s Set to "on" to enable the i2s interface ++ (default "off") ++ ++ spi Set to "on" to enable the spi interfaces ++ (default "off") ++ ++ random Set to "on" to enable the hardware random ++ number generator (default "off") ++ ++ uart0 Set to "off" to disable uart0 (default "on") ++ ++ watchdog Set to "on" to enable the hardware watchdog ++ (default "off") ++ ++ act_led_trigger Choose which activity the LED tracks. ++ Use "heartbeat" for a nice load indicator. ++ (default "mmc") ++ ++ act_led_activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ ++ act_led_gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ (default "16" on a non-Plus board, "47" on a ++ Plus or Pi 2) ++ ++ pwr_led_trigger ++ pwr_led_activelow ++ pwr_led_gpio ++ As for act_led_*, but using the PWR LED. ++ Not available on Model A/B boards. ++ ++ N.B. It is recommended to only enable those interfaces that are needed. ++ Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc ++ interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) ++ Note also that i2c, i2c_arm and i2c_vc are aliases for the physical ++ interfaces i2c0 and i2c1. Use of the numeric variants is still possible ++ but deprecated because the ARM/VC assignments differ between board ++ revisions. The same board-specific mapping applies to i2c_baudrate, ++ and the other i2c baudrate parameters. ++ ++ ++Name: ads7846 ++Info: ADS7846 Touch controller ++Load: dtoverlay=ads7846,= ++Params: cs SPI bus Chip Select (default 1) ++ speed SPI bus speed (default 2Mhz, max 3.25MHz) ++ penirq GPIO used for PENIRQ. REQUIRED ++ penirq_pull Set GPIO pull (default 0=none, 2=pullup) ++ swapxy Swap x and y axis ++ xmin Minimum value on the X axis (default 0) ++ ymin Minimum value on the Y axis (default 0) ++ xmax Maximum value on the X axis (default 4095) ++ ymax Maximum value on the Y axis (default 4095) ++ pmin Minimum reported pressure value (default 0) ++ pmax Maximum reported pressure value (default 65535) ++ xohms Touchpanel sensitivity (X-plate resistance) ++ (default 400) ++ ++ penirq is required and usually xohms (60-100) has to be set as well. ++ Apart from that, pmax (255) and swapxy are also common. ++ The rest of the calibration can be done with xinput-calibrator. ++ See: github.com/notro/fbtft/wiki/FBTFT-on-Raspian ++ Device Tree binding document: ++ www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt ++ ++ ++Name: bmp085_i2c-sensor ++Info: Configures the BMP085/BMP180 digital barometric pressure and temperature ++ sensors from Bosch Sensortec ++Load: dtoverlay=bmp085_i2c-sensor ++Params: ++ ++ ++[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++Name: enc28j60 ++Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) ++Load: dtoverlay=enc28j60,= ++Params: int_pin GPIO used for INT (default 25) ++ ++ speed SPI bus speed (default 12000000) ++ ++ ++Name: hifiberry-amp ++Info: Configures the HifiBerry Amp and Amp+ audio cards ++Load: dtoverlay=hifiberry-amp ++Params: ++ ++ ++Name: hifiberry-dac ++Info: Configures the HifiBerry DAC audio card ++Load: dtoverlay=hifiberry-dac ++Params: ++ ++ ++Name: hifiberry-dacplus ++Info: Configures the HifiBerry DAC+ audio card ++Load: dtoverlay=hifiberry-dacplus ++Params: ++ ++ ++Name: hifiberry-digi ++Info: Configures the HifiBerry Digi audio card ++Load: dtoverlay=hifiberry-digi ++Params: ++ ++ ++Name: hy28a ++Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics ++ Default values match Texy's display shield ++Load: dtoverlay=hy28a,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ resetgpio GPIO used to reset controller ++ ++ ledgpio GPIO used to control backlight ++ ++ ++Name: hy28b ++Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics ++ Default values match Texy's display shield ++Load: dtoverlay=hy28b,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ resetgpio GPIO used to reset controller ++ ++ ledgpio GPIO used to control backlight ++ ++ ++Name: i2c-rtc ++Info: Adds support for a number of I2C Real Time Clock devices ++Load: dtoverlay=i2c-rtc, ++Params: ds1307 Select the DS1307 device ++ ++ ds3231 Select the DS3231 device ++ ++ pcf2127 Select the PCF2127 device ++ ++ pcf8523 Select the PCF8523 device ++ ++ pcf8563 Select the PCF8563 device ++ ++ ++Name: iqaudio-dac ++Info: Configures the IQaudio DAC audio card ++Load: dtoverlay=iqaudio-dac ++Params: ++ ++ ++Name: iqaudio-dacplus ++Info: Configures the IQaudio DAC+ audio card ++Load: dtoverlay=iqaudio-dacplus ++Params: ++ ++ ++Name: lirc-rpi ++Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) ++ Consult the module documentation for more details. ++Load: dtoverlay=lirc-rpi,=,... ++Params: gpio_out_pin GPIO for output (default "17") ++ ++ gpio_in_pin GPIO for input (default "18") ++ ++ gpio_in_pull Pull up/down/off on the input pin ++ (default "down") ++ ++ sense Override the IR receive auto-detection logic: ++ "1" = force active high ++ "0" = force active low ++ "-1" = use auto-detection ++ (default "-1") ++ ++ softcarrier Turn the software carrier "on" or "off" ++ (default "on") ++ ++ invert "on" = invert the output pin (default "off") ++ ++ debug "on" = enable additional debug messages ++ (default "off") ++ ++ ++Name: mcp2515-can0 ++Info: Configures the MCP2515 CAN controller ++Load: dtoverlay=mcp2515-can0,= ++Params: oscillator Clock frequency for the CAN controller (Hz) ++ ++ spimaxfrequency Maximum SPI frequence (Hz) ++ ++ interrupt GPIO for interrupt signal ++ ++ ++Name: mmc ++Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock ++Load: dtoverlay=mmc,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ force_pio Disable DMA support ++ ++ ++Name: mz61581 ++Info: MZ61581 display by Tontec ++Load: dtoverlay=mz61581,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++[ The pcf8523-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++Name: piscreen ++Info: PiScreen display by OzzMaker.com ++Load: dtoverlay=piscreen,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: pitft28-resistive ++Info: Adafruit PiTFT 2.8" resistive touch screen ++Load: dtoverlay=pitft28-resistive,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ ++Name: pps-gpio ++Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). ++Load: dtoverlay=pps-gpio,= ++Params: gpiopin Input GPIO (default "18") ++ ++ ++Name: rpi-dac ++Info: Configures the RPi DAC audio card ++Load: dtoverlay=rpi-dac ++Params: ++ ++ ++Name: rpi-display ++Info: RPi-Display - 2.8" Touch Display by Watterott ++Load: dtoverlay=rpi-display,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: rpi-proto ++Info: Configures the RPi Proto audio card ++Load: dtoverlay=rpi-proto ++Params: ++ ++ ++Name: sdhost ++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock ++Load: dtoverlay=sdhost,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ force_pio Disable DMA support ++ ++ ++Name: spi-bcm2708 ++Info: Selects the bcm2708-spi SPI driver ++Load: dtoverlay=spi-bcm2708 ++Params: ++ ++ ++Name: spi-bcm2835 ++Info: Selects the bcm2835-spi SPI driver ++Load: dtoverlay=spi-bcm2835 ++Params: ++ ++ ++Name: tinylcd35 ++Info: 3.5" Color TFT Display by www.tinylcd.com ++ Options: Touch, RTC, keypad ++Load: dtoverlay=tinylcd35,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ touch Enable touch panel ++ ++ touchgpio Touch controller IRQ GPIO ++ ++ xohms Touchpanel: Resistance of X-plate in ohms ++ ++ rtc-pcf PCF8563 Real Time Clock ++ ++ rtc-ds DS1307 Real Time Clock ++ ++ keypad Enable keypad ++ ++ Examples: ++ Display with touchpanel, PCF8563 RTC and keypad: ++ dtoverlay=tinylcd35,touch,rtc-pcf,keypad ++ Old touch display: ++ dtoverlay=tinylcd35,touch,touchgpio=3 ++ ++ ++Name: w1-gpio ++Info: Configures the w1-gpio Onewire interface module. ++ Use this overlay if you *don't* need a GPIO to drive an external pullup. ++Load: dtoverlay=w1-gpio,= ++Params: gpiopin GPIO for I/O (default "4") ++ ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature ++ ++ ++Name: w1-gpio-pullup ++Info: Configures the w1-gpio Onewire interface module. ++ Use this overlay if you *do* need a GPIO to drive an external pullup. ++Load: dtoverlay=w1-gpio-pullup,=,... ++Params: gpiopin GPIO for I/O (default "4") ++ ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature ++ ++ extpullup GPIO for external pullup (default "5") ++ ++ ++Troubleshooting ++=============== ++ ++If you are experiencing problems that you think are DT-related, enable DT ++diagnostic output by adding this to /boot/config.txt: ++ ++ dtdebug=on ++ ++and rebooting. Then run: ++ ++ sudo vcdbg log msg ++ ++and look for relevant messages. ++ ++Further reading ++=============== ++ ++This is only meant to be a quick introduction to the subject of Device Tree on ++Raspberry Pi. There is a more complete explanation here: ++ ++http://www.raspberrypi.org/documentation/configuration/device-tree.md +diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts +new file mode 100644 +index 0000000..6a92cd1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts +@@ -0,0 +1,83 @@ ++/* ++ * Generic Device Tree overlay for the ADS7846 touch controller ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ ads7846_pins: ads7846_pins { ++ brcm,pins = <255>; /* illegal default value */ ++ brcm,function = <0>; /* in */ ++ brcm,pull = <0>; /* none */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ads7846: ads7846@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ads7846_pins>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <255 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 255 0>; ++ ++ /* driver defaults */ ++ ti,x-min = /bits/ 16 <0>; ++ ti,y-min = /bits/ 16 <0>; ++ ti,x-max = /bits/ 16 <0x0FFF>; ++ ti,y-max = /bits/ 16 <0x0FFF>; ++ ti,pressure-min = /bits/ 16 <0>; ++ ti,pressure-max = /bits/ 16 <0xFFFF>; ++ ti,x-plate-ohms = /bits/ 16 <400>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ cs = <&ads7846>,"reg:0"; ++ speed = <&ads7846>,"spi-max-frequency:0"; ++ penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ ++ <&ads7846>,"interrupts:0", ++ <&ads7846>,"pendown-gpio:4"; ++ penirq_pull = <&ads7846_pins>,"brcm,pull:0"; ++ swapxy = <&ads7846>,"ti,swap-xy?"; ++ xmin = <&ads7846>,"ti,x-min;0"; ++ ymin = <&ads7846>,"ti,y-min;0"; ++ xmax = <&ads7846>,"ti,x-max;0"; ++ ymax = <&ads7846>,"ti,y-max;0"; ++ pmin = <&ads7846>,"ti,pressure-min;0"; ++ pmax = <&ads7846>,"ti,pressure-max;0"; ++ xohms = <&ads7846>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts +new file mode 100644 +index 0000000..b830bf2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts +@@ -0,0 +1,23 @@ ++// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ bmp085@77 { ++ compatible = "bosch,bmp085"; ++ reg = <0x77>; ++ default-oversampling = <3>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/dht11-overlay.dts b/arch/arm/boot/dts/overlays/dht11-overlay.dts +new file mode 100644 +index 0000000..9bf67fd +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dht11-overlay.dts +@@ -0,0 +1,39 @@ ++/* ++ * Overlay for the DHT11/21/22 humidity/temperature sensor modules. ++ */ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ dht11: dht11@0 { ++ compatible = "dht11"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dht11_pins>; ++ gpios = <&gpio 4 0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ dht11_pins: dht11_pins { ++ brcm,pins = <4>; ++ brcm,function = <0>; // in ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&dht11_pins>,"brcm,pins:0", ++ <&dht11>,"gpios:4"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts +new file mode 100644 +index 0000000..8fae869 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts +@@ -0,0 +1,50 @@ ++// Overlay for the Microchip ENC28J60 Ethernet Controller ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ eth1: enc28j60@0{ ++ compatible = "microchip,enc28j60"; ++ reg = <0>; /* CE0 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð1_pins>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 0x2>; /* falling edge */ ++ spi-max-frequency = <12000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ eth1_pins: eth1_pins { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <0>; /* none */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ int_pin = <ð1>, "interrupts:0", ++ <ð1_pins>, "brcm,pins:0"; ++ speed = <ð1>, "spi-max-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts +new file mode 100644 +index 0000000..2c81448 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for HiFiBerry Amp/Amp+ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-amp"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ tas5713@1b { ++ #sound-dai-cells = <0>; ++ compatible = "ti,tas5713"; ++ reg = <0x1b>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts +new file mode 100644 +index 0000000..5e7633a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts +@@ -0,0 +1,34 @@ ++// Definitions for HiFiBerry DAC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ pcm5102a-codec { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5102a"; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts +new file mode 100644 +index 0000000..deb9c625 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for HiFiBerry DAC+ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-dacplus"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4d { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts +new file mode 100644 +index 0000000..d0e0d8a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for HiFiBerry Digi ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-digi"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ wm8804@3b { ++ #sound-dai-cells = <0>; ++ compatible = "wlf,wm8804"; ++ reg = <0x3b>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts +new file mode 100644 +index 0000000..3cd3083 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts +@@ -0,0 +1,87 @@ ++/* ++ * Device Tree overlay for HY28A display ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ hy28a_pins: hy28a_pins { ++ brcm,pins = <17 25 18>; ++ brcm,function = <0 1 1>; /* in out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hy28a: hy28a@0{ ++ compatible = "ilitek,ili9320"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hy28a_pins>; ++ ++ spi-max-frequency = <32000000>; ++ spi-cpol; ++ spi-cpha; ++ rotate = <270>; ++ bgr; ++ fps = <50>; ++ buswidth = <8>; ++ startbyte = <0x70>; ++ reset-gpios = <&gpio 25 0>; ++ led-gpios = <&gpio 18 1>; ++ debug = <0>; ++ }; ++ ++ hy28a_ts: hy28a-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&hy28a>,"spi-max-frequency:0"; ++ rotate = <&hy28a>,"rotate:0"; ++ fps = <&hy28a>,"fps:0"; ++ debug = <&hy28a>,"debug:0"; ++ xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; ++ resetgpio = <&hy28a>,"reset-gpios:4", ++ <&hy28a_pins>, "brcm,pins:1"; ++ ledgpio = <&hy28a>,"led-gpios:4", ++ <&hy28a_pins>, "brcm,pins:2"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts +new file mode 100644 +index 0000000..f774c4a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts +@@ -0,0 +1,142 @@ ++/* ++ * Device Tree overlay for HY28b display shield by Texy ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ hy28b_pins: hy28b_pins { ++ brcm,pins = <17 25 18>; ++ brcm,function = <0 1 1>; /* in out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hy28b: hy28b@0{ ++ compatible = "ilitek,ili9325"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hy28b_pins>; ++ ++ spi-max-frequency = <48000000>; ++ spi-cpol; ++ spi-cpha; ++ rotate = <270>; ++ bgr; ++ fps = <50>; ++ buswidth = <8>; ++ startbyte = <0x70>; ++ reset-gpios = <&gpio 25 0>; ++ led-gpios = <&gpio 18 1>; ++ ++ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; ++ ++ init = <0x10000e7 0x0010 ++ 0x1000000 0x0001 ++ 0x1000001 0x0100 ++ 0x1000002 0x0700 ++ 0x1000003 0x1030 ++ 0x1000004 0x0000 ++ 0x1000008 0x0207 ++ 0x1000009 0x0000 ++ 0x100000a 0x0000 ++ 0x100000c 0x0001 ++ 0x100000d 0x0000 ++ 0x100000f 0x0000 ++ 0x1000010 0x0000 ++ 0x1000011 0x0007 ++ 0x1000012 0x0000 ++ 0x1000013 0x0000 ++ 0x2000032 ++ 0x1000010 0x1590 ++ 0x1000011 0x0227 ++ 0x2000032 ++ 0x1000012 0x009c ++ 0x2000032 ++ 0x1000013 0x1900 ++ 0x1000029 0x0023 ++ 0x100002b 0x000e ++ 0x2000032 ++ 0x1000020 0x0000 ++ 0x1000021 0x0000 ++ 0x2000032 ++ 0x1000050 0x0000 ++ 0x1000051 0x00ef ++ 0x1000052 0x0000 ++ 0x1000053 0x013f ++ 0x1000060 0xa700 ++ 0x1000061 0x0001 ++ 0x100006a 0x0000 ++ 0x1000080 0x0000 ++ 0x1000081 0x0000 ++ 0x1000082 0x0000 ++ 0x1000083 0x0000 ++ 0x1000084 0x0000 ++ 0x1000085 0x0000 ++ 0x1000090 0x0010 ++ 0x1000092 0x0000 ++ 0x1000093 0x0003 ++ 0x1000095 0x0110 ++ 0x1000097 0x0000 ++ 0x1000098 0x0000 ++ 0x1000007 0x0133 ++ 0x1000020 0x0000 ++ 0x1000021 0x0000 ++ 0x2000064>; ++ debug = <0>; ++ }; ++ ++ hy28b_ts: hy28b-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&hy28b>,"spi-max-frequency:0"; ++ rotate = <&hy28b>,"rotate:0"; ++ fps = <&hy28b>,"fps:0"; ++ debug = <&hy28b>,"debug:0"; ++ xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; ++ resetgpio = <&hy28b>,"reset-gpios:4", ++ <&hy28b_pins>, "brcm,pins:1"; ++ ledgpio = <&hy28b>,"led-gpios:4", ++ <&hy28b_pins>, "brcm,pins:2"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +new file mode 100644 +index 0000000..6bccfdc +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -0,0 +1,49 @@ ++// Definitions for several I2C based Real Time Clocks ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ds1307: ds1307@68 { ++ compatible = "maxim,ds1307"; ++ reg = <0x68>; ++ status = "disable"; ++ }; ++ ds3231: ds3231@68 { ++ compatible = "maxim,ds3231"; ++ reg = <0x68>; ++ status = "disable"; ++ }; ++ pcf2127: pcf2127@51 { ++ compatible = "nxp,pcf2127"; ++ reg = <0x51>; ++ status = "disable"; ++ }; ++ pcf8523: pcf8523@68 { ++ compatible = "nxp,pcf8523"; ++ reg = <0x68>; ++ status = "disable"; ++ }; ++ pcf8563: pcf8563@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ status = "disable"; ++ }; ++ }; ++ }; ++ __overrides__ { ++ ds1307 = <&ds1307>,"status"; ++ ds3231 = <&ds3231>,"status"; ++ pcf2127 = <&pcf2127>,"status"; ++ pcf8523 = <&pcf8523>,"status"; ++ pcf8563 = <&pcf8563>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts +new file mode 100644 +index 0000000..a11160a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ brcm,enable-mmap; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts +new file mode 100644 +index 0000000..ea8173e +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for IQaudIO DAC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "iqaudio,iqaudio-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts +new file mode 100644 +index 0000000..735d8ab +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for IQaudIO DAC+ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "iqaudio,iqaudio-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts +new file mode 100644 +index 0000000..7d5d82b +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts +@@ -0,0 +1,57 @@ ++// Definitions for lirc-rpi module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ lirc_rpi: lirc_rpi { ++ compatible = "rpi,lirc-rpi"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lirc_pins>; ++ status = "okay"; ++ ++ // Override autodetection of IR receiver circuit ++ // (0 = active high, 1 = active low, -1 = no override ) ++ rpi,sense = <0xffffffff>; ++ ++ // Software carrier ++ // (0 = off, 1 = on) ++ rpi,softcarrier = <1>; ++ ++ // Invert output ++ // (0 = off, 1 = on) ++ rpi,invert = <0>; ++ ++ // Enable debugging messages ++ // (0 = off, 1 = on) ++ rpi,debug = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ lirc_pins: lirc_pins { ++ brcm,pins = <17 18>; ++ brcm,function = <1 0>; // out in ++ brcm,pull = <0 1>; // off down ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; ++ gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; ++ gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; ++ ++ sense = <&lirc_rpi>,"rpi,sense:0"; ++ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; ++ invert = <&lirc_rpi>,"rpi,invert:0"; ++ debug = <&lirc_rpi>,"rpi,debug:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts +new file mode 100755 +index 0000000..398d59c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts +@@ -0,0 +1,69 @@ ++/* ++ * Device tree overlay for mcp251x/can0 on spi0.0 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* disable spi-dev for spi0.0 */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ spidev@0{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ can0_pins: can0_pins { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* input */ ++ }; ++ }; ++ }; ++ ++ /* the clock/oscillator of the can-controller */ ++ fragment@2 { ++ target-path = "/clocks"; ++ __overlay__ { ++ /* external oscillator of mcp2515 on SPI0.0 */ ++ can0_osc: can0_osc { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <16000000>; ++ }; ++ }; ++ }; ++ ++ /* the spi config of the can-controller itself binding everything together */ ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ can0: mcp2515@0 { ++ reg = <0>; ++ compatible = "microchip,mcp2515"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can0_pins>; ++ spi-max-frequency = <10000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 0x2>; ++ clocks = <&can0_osc>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ oscillator = <&can0_osc>,"clock-frequency:0"; ++ spimaxfrequency = <&can0>,"spi-max-frequency:0"; ++ interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts +new file mode 100644 +index 0000000..0a37cf4 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts +@@ -0,0 +1,19 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&mmc>; ++ ++ __overlay__ { ++ brcm,overclock-50 = <0>; ++ }; ++ }; ++ ++ __overrides__ { ++ overclock_50 = <&mmc>,"brcm,overclock-50:0"; ++ force_pio = <&mmc>,"brcm,force-pio?"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts +new file mode 100644 +index 0000000..c06fe12 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts +@@ -0,0 +1,109 @@ ++/* ++ * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ mz61581_pins: mz61581_pins { ++ brcm,pins = <4 15 18 25>; ++ brcm,function = <0 1 1 1>; /* in out out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ mz61581: mz61581@0{ ++ compatible = "samsung,s6d02a1"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mz61581_pins>; ++ ++ spi-max-frequency = <128000000>; ++ spi-cpol; ++ spi-cpha; ++ ++ width = <320>; ++ height = <480>; ++ rotate = <270>; ++ bgr; ++ fps = <30>; ++ buswidth = <8>; ++ ++ reset-gpios = <&gpio 15 0>; ++ dc-gpios = <&gpio 25 0>; ++ led-gpios = <&gpio 18 0>; ++ ++ init = <0x10000b0 00 ++ 0x1000011 ++ 0x20000ff ++ 0x10000b3 0x02 0x00 0x00 0x00 ++ 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 ++ 0x10000c1 0x08 0x16 0x08 0x08 ++ 0x10000c4 0x11 0x07 0x03 0x03 ++ 0x10000c6 0x00 ++ 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 ++ 0x1000035 0x00 ++ 0x1000036 0xa0 ++ 0x100003a 0x55 ++ 0x1000044 0x00 0x01 ++ 0x10000d0 0x07 0x07 0x1d 0x03 ++ 0x10000d1 0x03 0x30 0x10 ++ 0x10000d2 0x03 0x14 0x04 ++ 0x1000029 ++ 0x100002c>; ++ ++ /* This is a workaround to make sure the init sequence slows down and doesn't fail */ ++ debug = <3>; ++ }; ++ ++ mz61581_ts: mz61581_ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <4 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 4 0>; ++ ++ ti,x-plate-ohms = /bits/ 16 <60>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&mz61581>, "spi-max-frequency:0"; ++ rotate = <&mz61581>, "rotate:0"; ++ fps = <&mz61581>, "fps:0"; ++ debug = <&mz61581>, "debug:0"; ++ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +new file mode 100644 +index 0000000..ba4ad33 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +@@ -0,0 +1,96 @@ ++/* ++ * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ piscreen_pins: piscreen_pins { ++ brcm,pins = <17 25 24 22>; ++ brcm,function = <0 1 1 1>; /* in out out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ piscreen: piscreen@0{ ++ compatible = "ilitek,ili9486"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&piscreen_pins>; ++ ++ spi-max-frequency = <24000000>; ++ rotate = <270>; ++ bgr; ++ fps = <30>; ++ buswidth = <8>; ++ regwidth = <16>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 22 1>; ++ debug = <0>; ++ ++ init = <0x10000b0 0x00 ++ 0x1000011 ++ 0x20000ff ++ 0x100003a 0x55 ++ 0x1000036 0x28 ++ 0x10000c2 0x44 ++ 0x10000c5 0x00 0x00 0x00 0x00 ++ 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 ++ 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 ++ 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 ++ 0x1000011 ++ 0x1000029>; ++ }; ++ ++ piscreen_ts: piscreen-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,swap-xy; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&piscreen>,"spi-max-frequency:0"; ++ rotate = <&piscreen>,"rotate:0"; ++ fps = <&piscreen>,"fps:0"; ++ debug = <&piscreen>,"debug:0"; ++ xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts +new file mode 100644 +index 0000000..d506eae +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts +@@ -0,0 +1,115 @@ ++/* ++ * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ pitft_pins: pitft_pins { ++ brcm,pins = <24 25>; ++ brcm,function = <0 1>; /* in out */ ++ brcm,pull = <2 0>; /* pullup none */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pitft: pitft@0{ ++ compatible = "ilitek,ili9340"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pitft_pins>; ++ ++ spi-max-frequency = <32000000>; ++ rotate = <90>; ++ fps = <25>; ++ bgr; ++ buswidth = <8>; ++ dc-gpios = <&gpio 25 0>; ++ debug = <0>; ++ }; ++ ++ pitft_ts@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stmpe610"; ++ reg = <1>; ++ ++ spi-max-frequency = <500000>; ++ irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ ++ interrupts = <24 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ interrupt-controller; ++ ++ stmpe_touchscreen { ++ compatible = "st,stmpe-ts"; ++ st,sample-time = <4>; ++ st,mod-12b = <1>; ++ st,ref-sel = <0>; ++ st,adc-freq = <2>; ++ st,ave-ctrl = <3>; ++ st,touch-det-delay = <4>; ++ st,settling = <2>; ++ st,fraction-z = <7>; ++ st,i-drive = <0>; ++ }; ++ ++ stmpe_gpio: stmpe_gpio { ++ #gpio-cells = <2>; ++ compatible = "st,stmpe-gpio"; ++ /* ++ * only GPIO2 is wired/available ++ * and it is wired to the backlight ++ */ ++ st,norequest-mask = <0x7b>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "/soc"; ++ __overlay__ { ++ backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&stmpe_gpio 2 0>; ++ default-on; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ speed = <&pitft>,"spi-max-frequency:0"; ++ rotate = <&pitft>,"rotate:0"; ++ fps = <&pitft>,"fps:0"; ++ debug = <&pitft>,"debug:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts +new file mode 100644 +index 0000000..40bf0e1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts +@@ -0,0 +1,34 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ pps: pps { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&gpio 18 0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ brcm,pins = <18>; ++ brcm,function = <0>; // in ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&pps>,"gpios:4", ++ <&pps_pins>,"brcm,pins:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts +new file mode 100644 +index 0000000..7fc6ac9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts +@@ -0,0 +1,34 @@ ++// Definitions for RPi DAC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "rpi,rpi-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ pcm1794a-codec { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm1794a"; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts +new file mode 100644 +index 0000000..a8fa974 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts +@@ -0,0 +1,82 @@ ++/* ++ * Device Tree overlay for rpi-display by Watterott ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ rpi_display_pins: rpi_display_pins { ++ brcm,pins = <18 23 24 25>; ++ brcm,function = <1 1 1 0>; /* out out out in */ ++ brcm,pull = <0 0 0 2>; /* - - - up */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rpidisplay: rpi-display@0{ ++ compatible = "ilitek,ili9341"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rpi_display_pins>; ++ ++ spi-max-frequency = <32000000>; ++ rotate = <270>; ++ bgr; ++ fps = <30>; ++ buswidth = <8>; ++ reset-gpios = <&gpio 23 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 18 1>; ++ debug = <0>; ++ }; ++ ++ rpidisplay_ts: rpi-display-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <25 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 25 0>; ++ ti,x-plate-ohms = /bits/ 16 <60>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&rpidisplay>,"spi-max-frequency:0"; ++ rotate = <&rpidisplay>,"rotate:0"; ++ fps = <&rpidisplay>,"fps:0"; ++ debug = <&rpidisplay>,"debug:0"; ++ xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts +new file mode 100644 +index 0000000..2029930 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for Rpi-Proto ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "rpi,rpi-proto"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ wm8731@1a { ++ #sound-dai-cells = <0>; ++ compatible = "wlf,wm8731"; ++ reg = <0x1a>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts +new file mode 100644 +index 0000000..8fb28e9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts +@@ -0,0 +1,78 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&soc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ sdhost: sdhost@7e202000 { ++ compatible = "brcm,bcm2835-sdhost"; ++ reg = <0x7e202000 0x100>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_pins>; ++ interrupts = <2 24>; ++ clocks = <&clk_sdhost>; ++ dmas = <&dma 13>, ++ <&dma 13>; ++ dma-names = "tx", "rx"; ++ brcm,delay-after-stop = <0>; ++ brcm,overclock-50 = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&clocks>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ clk_sdhost: sdhost { ++ compatible = "fixed-clock"; ++ reg = <0>; ++ #clock-cells = <0>; ++ clock-output-names = "sdhost"; ++ clock-frequency = <250000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ sdhost_pins: sdhost_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&mmc>; ++ __overlay__ { ++ /* Find a way to disable the other driver */ ++ compatible = ""; ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/__overrides__"; ++ __overlay__ { ++ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ }; ++ }; ++ ++ __overrides__ { ++ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; ++ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; ++ force_pio = <&sdhost>,"brcm,force-pio?"; ++ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts +new file mode 100644 +index 0000000..e378ef1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts +@@ -0,0 +1,18 @@ ++/* ++ * Device tree overlay for spi-bcm2835 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ compatible = "brcm,bcm2708-spi"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts +new file mode 100644 +index 0000000..fc1e39b +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts +@@ -0,0 +1,18 @@ ++/* ++ * Device tree overlay for spi-bcm2835 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ compatible = "brcm,bcm2835-spi"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +new file mode 100644 +index 0000000..f7102c8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +@@ -0,0 +1,216 @@ ++/* ++ * tinylcd35-overlay.dts ++ * ++ * ------------------------------------------------- ++ * www.tinlylcd.com ++ * ------------------------------------------------- ++ * Device---Driver-----BUS GPIO's ++ * display tinylcd35 spi0.0 25 24 18 ++ * touch ads7846 spi0.1 5 ++ * rtc ds1307 i2c1-0068 ++ * rtc pcf8563 i2c1-0051 ++ * keypad gpio-keys --------- 17 22 27 23 28 ++ * ++ * ++ * TinyLCD.com 3.5 inch TFT ++ * ++ * Version 001 ++ * 5/3/2015 -- Noralf Trønnes Initial Device tree framework ++ * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ tinylcd35_pins: tinylcd35_pins { ++ brcm,pins = <25 24 18>; ++ brcm,function = <1>; /* out */ ++ }; ++ tinylcd35_ts_pins: tinylcd35_ts_pins { ++ brcm,pins = <5>; ++ brcm,function = <0>; /* in */ ++ }; ++ keypad_pins: keypad_pins { ++ brcm,pins = <4 17 22 23 27>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <1>; /* down */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ tinylcd35: tinylcd35@0{ ++ compatible = "neosec,tinylcd"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&tinylcd35_pins>, ++ <&tinylcd35_ts_pins>; ++ ++ spi-max-frequency = <48000000>; ++ rotate = <270>; ++ fps = <20>; ++ bgr; ++ buswidth = <8>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 18 1>; ++ debug = <0>; ++ ++ init = <0x10000B0 0x80 ++ 0x10000C0 0x0A 0x0A ++ 0x10000C1 0x01 0x01 ++ 0x10000C2 0x33 ++ 0x10000C5 0x00 0x42 0x80 ++ 0x10000B1 0xD0 0x11 ++ 0x10000B4 0x02 ++ 0x10000B6 0x00 0x22 0x3B ++ 0x10000B7 0x07 ++ 0x1000036 0x58 ++ 0x10000F0 0x36 0xA5 0xD3 ++ 0x10000E5 0x80 ++ 0x10000E5 0x01 ++ 0x10000B3 0x00 ++ 0x10000E5 0x00 ++ 0x10000F0 0x36 0xA5 0x53 ++ 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 ++ 0x100003A 0x55 ++ 0x1000011 ++ 0x2000001 ++ 0x1000029>; ++ }; ++ ++ tinylcd35_ts: tinylcd35_ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ status = "disabled"; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <5 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 5 0>; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ ++ /* RTC */ ++ ++ fragment@3 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pcf8563: pcf8563@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ds1307: ds1307@68 { ++ compatible = "maxim,ds1307"; ++ reg = <0x68>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ /* ++ * Values for input event code is found under the ++ * 'Keys and buttons' heading in include/uapi/linux/input.h ++ */ ++ fragment@5 { ++ target-path = "/soc"; ++ __overlay__ { ++ keypad: keypad { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&keypad_pins>; ++ status = "disabled"; ++ autorepeat; ++ ++ button@17 { ++ label = "GPIO KEY_UP"; ++ linux,code = <103>; ++ gpios = <&gpio 17 0>; ++ }; ++ button@22 { ++ label = "GPIO KEY_DOWN"; ++ linux,code = <108>; ++ gpios = <&gpio 22 0>; ++ }; ++ button@27 { ++ label = "GPIO KEY_LEFT"; ++ linux,code = <105>; ++ gpios = <&gpio 27 0>; ++ }; ++ button@23 { ++ label = "GPIO KEY_RIGHT"; ++ linux,code = <106>; ++ gpios = <&gpio 23 0>; ++ }; ++ button@4 { ++ label = "GPIO KEY_ENTER"; ++ linux,code = <28>; ++ gpios = <&gpio 4 0>; ++ }; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ speed = <&tinylcd35>,"spi-max-frequency:0"; ++ rotate = <&tinylcd35>,"rotate:0"; ++ fps = <&tinylcd35>,"fps:0"; ++ debug = <&tinylcd35>,"debug:0"; ++ touch = <&tinylcd35_ts>,"status"; ++ touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", ++ <&tinylcd35_ts>,"interrupts:0", ++ <&tinylcd35_ts>,"pendown-gpio:4"; ++ xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; ++ rtc-pcf = <&i2c1>,"status", ++ <&pcf8563>,"status"; ++ rtc-ds = <&i2c1>,"status", ++ <&ds1307>,"status"; ++ keypad = <&keypad>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts +new file mode 100644 +index 0000000..29a3b48 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for w1-gpio module (without external pullup) ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ w1: onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&gpio 4 0>; ++ rpi,parasitic-power = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ brcm,pins = <4>; ++ brcm,function = <0>; // in (initially) ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&w1>,"gpios:4", ++ <&w1_pins>,"brcm,pins:0"; ++ pullup = <&w1>,"rpi,parasitic-power:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +new file mode 100644 +index 0000000..66a98f6 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +@@ -0,0 +1,41 @@ ++// Definitions for w1-gpio module (with external pullup) ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ w1: onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&gpio 4 0>, <&gpio 5 1>; ++ rpi,parasitic-power = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ brcm,pins = <4 5>; ++ brcm,function = <0 1>; // in out ++ brcm,pull = <0 0>; // off off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&w1>,"gpios:4", ++ <&w1_pins>,"brcm,pins:0"; ++ extpullup = <&w1>,"gpios:16", ++ <&w1_pins>,"brcm,pins:4"; ++ pullup = <&w1>,"rpi,parasitic-power:0"; ++ }; ++}; + +From 4bd17cf8893beb8fb36fe6e321abfe2bc091eb17 Mon Sep 17 00:00:00 2001 +From: Siarhei Siamashka +Date: Mon, 17 Jun 2013 13:32:11 +0300 +Subject: [PATCH 27/77] fbdev: add FBIOCOPYAREA ioctl + +Based on the patch authored by Ali Gholami Rudi at + https://lkml.org/lkml/2009/7/13/153 + +Provide an ioctl for userspace applications, but only if this operation +is hardware accelerated (otherwide it does not make any sense). + +Signed-off-by: Siarhei Siamashka +--- + drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++ + include/uapi/linux/fb.h | 5 +++++ + 2 files changed, 35 insertions(+) + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index 0705d88..771992a 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) + } + EXPORT_SYMBOL(fb_blank); + ++static int fb_copyarea_user(struct fb_info *info, ++ struct fb_copyarea *copy) ++{ ++ int ret = 0; ++ if (!lock_fb_info(info)) ++ return -ENODEV; ++ if (copy->dx + copy->width > info->var.xres || ++ copy->sx + copy->width > info->var.xres || ++ copy->dy + copy->height > info->var.yres || ++ copy->sy + copy->height > info->var.yres) { ++ ret = -EINVAL; ++ goto out; ++ } ++ info->fbops->fb_copyarea(info, copy); ++out: ++ unlock_fb_info(info); ++ return ret; ++} ++ + static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) + { +@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + struct fb_cmap cmap_from; + struct fb_cmap_user cmap; + struct fb_event event; ++ struct fb_copyarea copy; + void __user *argp = (void __user *)arg; + long ret = 0; + +@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + unlock_fb_info(info); + console_unlock(); + break; ++ case FBIOCOPYAREA: ++ if (info->flags & FBINFO_HWACCEL_COPYAREA) { ++ /* only provide this ioctl if it is accelerated */ ++ if (copy_from_user(©, argp, sizeof(copy))) ++ return -EFAULT; ++ ret = fb_copyarea_user(info, ©); ++ break; ++ } ++ /* fall through */ + default: + if (!lock_fb_info(info)) + return -ENODEV; +@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, + case FBIOPAN_DISPLAY: + case FBIOGET_CON2FBMAP: + case FBIOPUT_CON2FBMAP: ++ case FBIOCOPYAREA: + arg = (unsigned long) compat_ptr(arg); + case FBIOBLANK: + ret = do_fb_ioctl(info, cmd, arg); +diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h +index fb795c3..fa72af0 100644 +--- a/include/uapi/linux/fb.h ++++ b/include/uapi/linux/fb.h +@@ -34,6 +34,11 @@ + #define FBIOPUT_MODEINFO 0x4617 + #define FBIOGET_DISPINFO 0x4618 + #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) ++/* ++ * HACK: use 'z' in order not to clash with any other ioctl numbers which might ++ * be concurrently added to the mainline kernel ++ */ ++#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea) + + #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ + #define FB_TYPE_PLANES 1 /* Non interleaved planes */ + +From 54459bf0dcbd9019a1bc98cdc77a5c37811c1be5 Mon Sep 17 00:00:00 2001 +From: Harm Hanemaaijer +Date: Thu, 20 Jun 2013 20:21:39 +0200 +Subject: [PATCH 30/77] Speed up console framebuffer imageblit function + +Especially on platforms with a slower CPU but a relatively high +framebuffer fill bandwidth, like current ARM devices, the existing +console monochrome imageblit function used to draw console text is +suboptimal for common pixel depths such as 16bpp and 32bpp. The existing +code is quite general and can deal with several pixel depths. By creating +special case functions for 16bpp and 32bpp, by far the most common pixel +formats used on modern systems, a significant speed-up is attained +which can be readily felt on ARM-based devices like the Raspberry Pi +and the Allwinner platform, but should help any platform using the +fb layer. + +The special case functions allow constant folding, eliminating a number +of instructions including divide operations, and allow the use of an +unrolled loop, eliminating instructions with a variable shift size, +reducing source memory access instructions, and eliminating excessive +branching. These unrolled loops also allow much better code optimization +by the C compiler. The code that selects which optimized variant is used +is also simplified, eliminating integer divide instructions. + +The speed-up, measured by timing 'cat file.txt' in the console, varies +between 40% and 70%, when testing on the Raspberry Pi and Allwinner +ARM-based platforms, depending on font size and the pixel depth, with +the greater benefit for 32bpp. + +Signed-off-by: Harm Hanemaaijer +--- + drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++-- + 1 file changed, 147 insertions(+), 5 deletions(-) + +diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c +index a2bb276..436494f 100644 +--- a/drivers/video/fbdev/core/cfbimgblt.c ++++ b/drivers/video/fbdev/core/cfbimgblt.c +@@ -28,6 +28,11 @@ + * + * Also need to add code to deal with cards endians that are different than + * the native cpu endians. I also need to deal with MSB position in the word. ++ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013: ++ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are ++ * significantly faster than the previous implementation. ++ * - Simplify the fast/slow_imageblit selection code, avoiding integer ++ * divides. + */ + #include + #include +@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * + } + } + ++/* ++ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded ++ * into the code, main loop unrolled. ++ */ ++ ++static inline void fast_imageblit16(const struct fb_image *image, ++ struct fb_info *p, u8 __iomem * dst1, ++ u32 fgcolor, u32 bgcolor) ++{ ++ u32 fgx = fgcolor, bgx = bgcolor; ++ u32 spitch = (image->width + 7) / 8; ++ u32 end_mask, eorx; ++ const char *s = image->data, *src; ++ u32 __iomem *dst; ++ const u32 *tab = NULL; ++ int i, j, k; ++ ++ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; ++ ++ fgx <<= 16; ++ bgx <<= 16; ++ fgx |= fgcolor; ++ bgx |= bgcolor; ++ ++ eorx = fgx ^ bgx; ++ k = image->width / 2; ++ ++ for (i = image->height; i--;) { ++ dst = (u32 __iomem *) dst1; ++ src = s; ++ ++ j = k; ++ while (j >= 4) { ++ u8 bits = *src; ++ end_mask = tab[(bits >> 6) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 4) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 2) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[bits & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ src++; ++ j -= 4; ++ } ++ if (j != 0) { ++ u8 bits = *src; ++ end_mask = tab[(bits >> 6) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ if (j >= 2) { ++ end_mask = tab[(bits >> 4) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ if (j == 3) { ++ end_mask = tab[(bits >> 2) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst); ++ } ++ } ++ } ++ dst1 += p->fix.line_length; ++ s += spitch; ++ } ++} ++ ++/* ++ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded ++ * into the code, main loop unrolled. ++ */ ++ ++static inline void fast_imageblit32(const struct fb_image *image, ++ struct fb_info *p, u8 __iomem * dst1, ++ u32 fgcolor, u32 bgcolor) ++{ ++ u32 fgx = fgcolor, bgx = bgcolor; ++ u32 spitch = (image->width + 7) / 8; ++ u32 end_mask, eorx; ++ const char *s = image->data, *src; ++ u32 __iomem *dst; ++ const u32 *tab = NULL; ++ int i, j, k; ++ ++ tab = cfb_tab32; ++ ++ eorx = fgx ^ bgx; ++ k = image->width; ++ ++ for (i = image->height; i--;) { ++ dst = (u32 __iomem *) dst1; ++ src = s; ++ ++ j = k; ++ while (j >= 8) { ++ u8 bits = *src; ++ end_mask = tab[(bits >> 7) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 6) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 5) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 4) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 3) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 2) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 1) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[bits & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ src++; ++ j -= 8; ++ } ++ if (j != 0) { ++ u32 bits = (u32) * src; ++ while (j > 1) { ++ end_mask = tab[(bits >> 7) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ bits <<= 1; ++ j--; ++ } ++ end_mask = tab[(bits >> 7) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst); ++ } ++ dst1 += p->fix.line_length; ++ s += spitch; ++ } ++} ++ + void cfb_imageblit(struct fb_info *p, const struct fb_image *image) + { + u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; +@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) + bgcolor = image->bg_color; + } + +- if (32 % bpp == 0 && !start_index && !pitch_index && +- ((width & (32/bpp-1)) == 0) && +- bpp >= 8 && bpp <= 32) +- fast_imageblit(image, p, dst1, fgcolor, bgcolor); +- else ++ if (!start_index && !pitch_index) { ++ if (bpp == 32) ++ fast_imageblit32(image, p, dst1, fgcolor, ++ bgcolor); ++ else if (bpp == 16 && (width & 1) == 0) ++ fast_imageblit16(image, p, dst1, fgcolor, ++ bgcolor); ++ else if (bpp == 8 && (width & 3) == 0) ++ fast_imageblit(image, p, dst1, fgcolor, ++ bgcolor); ++ else ++ slow_imageblit(image, p, dst1, fgcolor, ++ bgcolor, ++ start_index, pitch_index); ++ } else + slow_imageblit(image, p, dst1, fgcolor, bgcolor, + start_index, pitch_index); + } else + +From b78abfc78e582f82fda5e69816eaa97b1097c853 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 26 Mar 2013 17:26:38 +0000 +Subject: [PATCH 31/77] Allow mac address to be set in smsc95xx + +Signed-off-by: popcornmix +--- + drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index 26423ad..e29a323 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -59,6 +59,7 @@ + #define SUSPEND_SUSPEND3 (0x08) + #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ + SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) ++#define MAC_ADDR_LEN (6) + + struct smsc95xx_priv { + u32 mac_cr; +@@ -74,6 +75,10 @@ static bool turbo_mode = true; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + ++static char *macaddr = ":"; ++module_param(macaddr, charp, 0); ++MODULE_PARM_DESC(macaddr, "MAC address"); ++ + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) + { +@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) + return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); + } + ++/* Check the macaddr module parameter for a MAC address */ ++static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) ++{ ++ int i, j, got_num, num; ++ u8 mtbl[MAC_ADDR_LEN]; ++ ++ if (macaddr[0] == ':') ++ return 0; ++ ++ i = 0; ++ j = 0; ++ num = 0; ++ got_num = 0; ++ while (j < MAC_ADDR_LEN) { ++ if (macaddr[i] && macaddr[i] != ':') { ++ got_num++; ++ if ('0' <= macaddr[i] && macaddr[i] <= '9') ++ num = num * 16 + macaddr[i] - '0'; ++ else if ('A' <= macaddr[i] && macaddr[i] <= 'F') ++ num = num * 16 + 10 + macaddr[i] - 'A'; ++ else if ('a' <= macaddr[i] && macaddr[i] <= 'f') ++ num = num * 16 + 10 + macaddr[i] - 'a'; ++ else ++ break; ++ i++; ++ } else if (got_num == 2) { ++ mtbl[j++] = (u8) num; ++ num = 0; ++ got_num = 0; ++ i++; ++ } else { ++ break; ++ } ++ } ++ ++ if (j == MAC_ADDR_LEN) { ++ netif_dbg(dev, ifup, dev->net, "Overriding MAC address with: " ++ "%02x:%02x:%02x:%02x:%02x:%02x\n", mtbl[0], mtbl[1], mtbl[2], ++ mtbl[3], mtbl[4], mtbl[5]); ++ for (i = 0; i < MAC_ADDR_LEN; i++) ++ dev_mac[i] = mtbl[i]; ++ return 1; ++ } else { ++ return 0; ++ } ++} ++ + static void smsc95xx_init_mac_address(struct usbnet *dev) + { ++ /* Check module parameters */ ++ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr)) ++ return; ++ + /* try reading mac address from EEPROM */ + if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, + dev->net->dev_addr) == 0) { + +From 468a5ebe451a5e3bc693fdbd67173f2fadb7d217 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 8 May 2013 11:46:50 +0100 +Subject: [PATCH 32/77] enabling the realtime clock 1-wire chip DS1307 and + 1-wire on GPIO4 (as a module) + +1-wire: Add support for configuring pin for w1-gpio kernel module +See: https://github.com/raspberrypi/linux/pull/457 + +Add bitbanging pullups, use them for w1-gpio + +Allows parasite power to work, uses module option pullup=1 + +bcm2708: Ensure 1-wire pullup is disabled by default, and expose as module parameter + +Signed-off-by: Alex J Lennon + +w1-gpio: Add gpiopin module parameter and correctly free up gpio pull-up pin, if set + +Signed-off-by: Alex J Lennon + +w1-gpio: Sort out the pullup/parasitic power tangle +--- + arch/arm/mach-bcm2708/bcm2708.c | 29 +++++++++++++++++ + arch/arm/mach-bcm2709/bcm2709.c | 29 +++++++++++++++++ + drivers/w1/masters/w1-gpio.c | 69 +++++++++++++++++++++++++++++++++++++---- + drivers/w1/w1.h | 6 ++++ + drivers/w1/w1_int.c | 14 +++++++++ + drivers/w1/w1_io.c | 18 +++++++++-- + include/linux/w1-gpio.h | 1 + + 7 files changed, 157 insertions(+), 9 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index efb3544..c7b4b61 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -77,12 +78,19 @@ + */ + #define DMA_MASK_BITS_COMMON 32 + ++// use GPIO 4 for the one-wire GPIO pin, if enabled ++#define W1_GPIO 4 ++// ensure one-wire GPIO pullup is disabled by default ++#define W1_PULLUP -1 ++ + /* command line parameters */ + static unsigned boardrev, serial; + static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static unsigned w1_gpio_pin = W1_GPIO; ++static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; + + static unsigned use_dt = 0; +@@ -303,6 +311,20 @@ static struct platform_device bcm2708_dmaengine_device = { + .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), + }; + ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++static struct w1_gpio_platform_data w1_gpio_pdata = { ++ .pin = W1_GPIO, ++ .ext_pullup_enable_pin = W1_PULLUP, ++ .is_open_drain = 0, ++}; ++ ++static struct platform_device w1_device = { ++ .name = "w1-gpio", ++ .id = -1, ++ .dev.platform_data = &w1_gpio_pdata, ++}; ++#endif ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -729,6 +751,11 @@ void __init bcm2708_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++ w1_gpio_pdata.pin = w1_gpio_pin; ++ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; ++ bcm_register_device_dt(&w1_device); ++#endif + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); + +@@ -942,5 +969,7 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(w1_gpio_pin, uint, 0644); ++module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 8017c50..03e208b 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -79,12 +80,19 @@ + */ + #define DMA_MASK_BITS_COMMON 32 + ++// use GPIO 4 for the one-wire GPIO pin, if enabled ++#define W1_GPIO 4 ++// ensure one-wire GPIO pullup is disabled by default ++#define W1_PULLUP -1 ++ + /* command line parameters */ + static unsigned boardrev, serial; + static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static unsigned w1_gpio_pin = W1_GPIO; ++static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; + + static unsigned use_dt = 0; +@@ -313,6 +321,20 @@ static struct platform_device bcm2708_dmaengine_device = { + .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), + }; + ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++static struct w1_gpio_platform_data w1_gpio_pdata = { ++ .pin = W1_GPIO, ++ .ext_pullup_enable_pin = W1_PULLUP, ++ .is_open_drain = 0, ++}; ++ ++static struct platform_device w1_device = { ++ .name = "w1-gpio", ++ .id = -1, ++ .dev.platform_data = &w1_gpio_pdata, ++}; ++#endif ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -749,6 +771,11 @@ void __init bcm2709_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++ w1_gpio_pdata.pin = w1_gpio_pin; ++ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; ++ bcm_register_device_dt(&w1_device); ++#endif + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); + +@@ -1110,5 +1137,7 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(w1_gpio_pin, uint, 0644); ++module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c +index 8f7848c6..2240f32 100644 +--- a/drivers/w1/masters/w1-gpio.c ++++ b/drivers/w1/masters/w1-gpio.c +@@ -23,6 +23,19 @@ + #include "../w1.h" + #include "../w1_int.h" + ++static int w1_gpio_pullup = 0; ++static int w1_gpio_pullup_orig = 0; ++module_param_named(pullup, w1_gpio_pullup, int, 0); ++MODULE_PARM_DESC(pullup, "Enable parasitic power (power on data) mode"); ++static int w1_gpio_pullup_pin = -1; ++static int w1_gpio_pullup_pin_orig = -1; ++module_param_named(extpullup, w1_gpio_pullup_pin, int, 0); ++MODULE_PARM_DESC(extpullup, "GPIO external pullup pin number"); ++static int w1_gpio_pin = -1; ++static int w1_gpio_pin_orig = -1; ++module_param_named(gpiopin, w1_gpio_pin, int, 0); ++MODULE_PARM_DESC(gpiopin, "GPIO pin number"); ++ + static u8 w1_gpio_set_pullup(void *data, int delay) + { + struct w1_gpio_platform_data *pdata = data; +@@ -67,6 +80,16 @@ static u8 w1_gpio_read_bit(void *data) + return gpio_get_value(pdata->pin) ? 1 : 0; + } + ++static void w1_gpio_bitbang_pullup(void *data, u8 on) ++{ ++ struct w1_gpio_platform_data *pdata = data; ++ ++ if (on) ++ gpio_direction_output(pdata->pin, 1); ++ else ++ gpio_direction_input(pdata->pin); ++} ++ + #if defined(CONFIG_OF) + static const struct of_device_id w1_gpio_dt_ids[] = { + { .compatible = "w1-gpio" }, +@@ -80,6 +103,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct device_node *np = pdev->dev.of_node; + int gpio; ++ u32 value; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) +@@ -88,6 +112,9 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + if (of_get_property(np, "linux,open-drain", NULL)) + pdata->is_open_drain = 1; + ++ if (of_property_read_u32(np, "rpi,parasitic-power", &value) == 0) ++ pdata->parasitic_power = (value != 0); ++ + gpio = of_get_gpio(np, 0); + if (gpio < 0) { + if (gpio != -EPROBE_DEFER) +@@ -103,7 +130,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + if (gpio == -EPROBE_DEFER) + return gpio; + /* ignore other errors as the pullup gpio is optional */ +- pdata->ext_pullup_enable_pin = gpio; ++ pdata->ext_pullup_enable_pin = (gpio >= 0) ? gpio : -1; + + pdev->dev.platform_data = pdata; + +@@ -113,13 +140,15 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + static int w1_gpio_probe(struct platform_device *pdev) + { + struct w1_bus_master *master; +- struct w1_gpio_platform_data *pdata; ++ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; + int err; + +- if (of_have_populated_dt()) { +- err = w1_gpio_probe_dt(pdev); +- if (err < 0) +- return err; ++ if(pdata == NULL) { ++ if (of_have_populated_dt()) { ++ err = w1_gpio_probe_dt(pdev); ++ if (err < 0) ++ return err; ++ } + } + + pdata = dev_get_platdata(&pdev->dev); +@@ -136,6 +165,22 @@ static int w1_gpio_probe(struct platform_device *pdev) + return -ENOMEM; + } + ++ w1_gpio_pin_orig = pdata->pin; ++ w1_gpio_pullup_pin_orig = pdata->ext_pullup_enable_pin; ++ w1_gpio_pullup_orig = pdata->parasitic_power; ++ ++ if(gpio_is_valid(w1_gpio_pin)) { ++ pdata->pin = w1_gpio_pin; ++ pdata->ext_pullup_enable_pin = -1; ++ pdata->parasitic_power = -1; ++ } ++ pdata->parasitic_power |= w1_gpio_pullup; ++ if(gpio_is_valid(w1_gpio_pullup_pin)) { ++ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin; ++ } ++ ++ dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power); ++ + err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); + if (err) { + dev_err(&pdev->dev, "gpio_request (pin) failed\n"); +@@ -165,6 +210,14 @@ static int w1_gpio_probe(struct platform_device *pdev) + master->set_pullup = w1_gpio_set_pullup; + } + ++ if (pdata->parasitic_power) { ++ if (pdata->is_open_drain) ++ printk(KERN_ERR "w1-gpio 'pullup'(parasitic power) " ++ "option doesn't work with open drain GPIO\n"); ++ else ++ master->bitbang_pullup = w1_gpio_bitbang_pullup; ++ } ++ + err = w1_add_master_device(master); + if (err) { + dev_err(&pdev->dev, "w1_add_master device failed\n"); +@@ -195,6 +248,10 @@ static int w1_gpio_remove(struct platform_device *pdev) + + w1_remove_master_device(master); + ++ pdata->pin = w1_gpio_pin_orig; ++ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin_orig; ++ pdata->parasitic_power = w1_gpio_pullup_orig; ++ + return 0; + } + +diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h +index 56a49ba..881d728 100644 +--- a/drivers/w1/w1.h ++++ b/drivers/w1/w1.h +@@ -171,6 +171,12 @@ struct w1_bus_master + + u8 (*set_pullup)(void *, int); + ++ /** ++ * Turns the pullup on/off in bitbanging mode, takes an on/off argument. ++ * @return -1=Error, 0=completed ++ */ ++ void (*bitbang_pullup) (void *, u8); ++ + void (*search)(void *, struct w1_master *, + u8, w1_slave_found_callback); + }; +diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c +index 47249a3..a4b4a8d 100644 +--- a/drivers/w1/w1_int.c ++++ b/drivers/w1/w1_int.c +@@ -123,6 +123,20 @@ int w1_add_master_device(struct w1_bus_master *master) + return(-EINVAL); + } + ++ /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup ++ * and takes care of timing itself */ ++ if (!master->write_byte && !master->touch_bit && master->set_pullup) { ++ printk(KERN_ERR "w1_add_master_device: set_pullup requires " ++ "write_byte or touch_bit, disabling\n"); ++ master->set_pullup = NULL; ++ } ++ ++ if (master->set_pullup && master->bitbang_pullup) { ++ printk(KERN_ERR "w1_add_master_device: set_pullup should not " ++ "be set when bitbang_pullup is used, disabling\n"); ++ master->set_pullup = NULL; ++ } ++ + /* Lock until the device is added (or not) to w1_masters. */ + mutex_lock(&w1_mlock); + /* Search for the first available id (starting at 1). */ +diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c +index 2820924..fd0550f 100644 +--- a/drivers/w1/w1_io.c ++++ b/drivers/w1/w1_io.c +@@ -134,10 +134,22 @@ static void w1_pre_write(struct w1_master *dev) + static void w1_post_write(struct w1_master *dev) + { + if (dev->pullup_duration) { +- if (dev->enable_pullup && dev->bus_master->set_pullup) +- dev->bus_master->set_pullup(dev->bus_master->data, 0); +- else ++ if (dev->enable_pullup) { ++ if (dev->bus_master->set_pullup) { ++ dev->bus_master->set_pullup(dev-> ++ bus_master->data, ++ 0); ++ } else if (dev->bus_master->bitbang_pullup) { ++ dev->bus_master-> ++ bitbang_pullup(dev->bus_master->data, 1); ++ msleep(dev->pullup_duration); ++ dev->bus_master-> ++ bitbang_pullup(dev->bus_master->data, 0); ++ } ++ } else { + msleep(dev->pullup_duration); ++ } ++ + dev->pullup_duration = 0; + } + } +diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h +index d58594a..feae942 100644 +--- a/include/linux/w1-gpio.h ++++ b/include/linux/w1-gpio.h +@@ -18,6 +18,7 @@ + struct w1_gpio_platform_data { + unsigned int pin; + unsigned int is_open_drain:1; ++ unsigned int parasitic_power:1; + void (*enable_external_pullup)(int enable); + unsigned int ext_pullup_enable_pin; + unsigned int pullup_duration; + +From 00d8013737c9e736f70e04e07b761517559e495e Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 18 Dec 2013 22:16:19 +0000 +Subject: [PATCH 34/77] config: Enable CONFIG_MEMCG, but leave it disabled (due + to memory cost). Enable with cgroup_enable=memory. + +--- + kernel/cgroup.c | 23 +++++++++++++++++++++++ + mm/memcontrol.c | 1 + + 2 files changed, 24 insertions(+) + +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index 469dd54..c9684da 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -5395,6 +5395,29 @@ static int __init cgroup_disable(char *str) + } + __setup("cgroup_disable=", cgroup_disable); + ++static int __init cgroup_enable(char *str) ++{ ++ struct cgroup_subsys *ss; ++ char *token; ++ int i; ++ ++ while ((token = strsep(&str, ",")) != NULL) { ++ if (!*token) ++ continue; ++ ++ for_each_subsys(ss, i) { ++ if (!strcmp(token, ss->name)) { ++ ss->disabled = 0; ++ printk(KERN_INFO "Enabling %s control group" ++ " subsystem\n", ss->name); ++ break; ++ } ++ } ++ } ++ return 1; ++} ++__setup("cgroup_enable=", cgroup_enable); ++ + static int __init cgroup_set_legacy_files_on_dfl(char *str) + { + printk("cgroup: using legacy files on the default hierarchy\n"); +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index a04225d..a2ef8af 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -5388,6 +5388,7 @@ struct cgroup_subsys memory_cgrp_subsys = { + .dfl_cftypes = memory_files, + .legacy_cftypes = mem_cgroup_legacy_files, + .early_init = 0, ++ .disabled = 1, + }; + + /** + +From 5e192d7296061c5d70da39b3fbd1eeedef467923 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 14:33:38 +0100 +Subject: [PATCH 35/77] ASoC: Add support for BCM2708 + +This driver adds support for digital audio (I2S) +for the BCM2708 SoC that is used by the +Raspberry Pi. External audio codecs can be +connected to the Raspberry Pi via P5 header. + +It relies on cyclic DMA engine support for BCM2708. + +Signed-off-by: Florian Meier + +ASoC: BCM2708: Add 24 bit support + +This adds 24 bit support to the I2S driver of the BCM2708. +Besides enabling the 24 bit flags, it includes two bug fixes: + +MMAP is not supported. Claiming this leads to strange issues +when the format of driver and file do not match. + +The datasheet states that the width extension bit should be set +for widths greater than 24, but greater or equal would be correct. +This follows from the definition of the width field. + +Signed-off-by: Florian Meier + +bcm2708-i2s: Update bclk_ratio to more correct values + +Move GPIO setup to hw_params. + +This is used to stop the I2S driver from breaking +the GPIO setup for other uses of the PCM interface + +Configure GPIOs for I2S based on revision/card settings + +With RPi model B+, assignment of the I2S GPIO pins has changed. +This patch uses the board revision to auto-detect the GPIOs used +for I2S. It also allows sound card drivers to set the GPIOs that +should be used. This is especially important with the Compute +Module. + +bcm2708-i2s: Avoid leak from iomap when accessing gpio + +bcm2708: Eliminate i2s debugfs directory error + +Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') +to avoid the name clash when registering debugfs entries. +--- + sound/soc/bcm/Kconfig | 11 + + sound/soc/bcm/Makefile | 4 + + sound/soc/bcm/bcm2708-i2s.c | 1009 +++++++++++++++++++++++++++++++++++++++++++ + sound/soc/bcm/bcm2708-i2s.h | 35 ++ + 4 files changed, 1059 insertions(+) + create mode 100644 sound/soc/bcm/bcm2708-i2s.c + create mode 100644 sound/soc/bcm/bcm2708-i2s.h + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 6a834e1..8642296 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -7,3 +7,14 @@ config SND_BCM2835_SOC_I2S + Say Y or M if you want to add support for codecs attached to + the BCM2835 I2S interface. You will also need + to select the audio interfaces to support below. ++ ++config SND_BCM2708_SOC_I2S ++ tristate "SoC Audio support for the Broadcom BCM2708 I2S module" ++ depends on MACH_BCM2708 || MACH_BCM2709 ++ select REGMAP_MMIO ++ select SND_SOC_DMAENGINE_PCM ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ help ++ Say Y or M if you want to add support for codecs attached to ++ the BCM2708 I2S interface. You will also need ++ to select the audio interfaces to support below. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index bc816b7..f8bbe1f 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -3,3 +3,7 @@ snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o + + obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o + ++# BCM2708 Platform Support ++snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o ++ ++obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +new file mode 100644 +index 0000000..a3b65dc +--- /dev/null ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -0,0 +1,1009 @@ ++/* ++ * ALSA SoC I2S Audio Layer for Broadcom BCM2708 SoC ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * Based on ++ * Raspberry Pi PCM I2S ALSA Driver ++ * Copyright (c) by Phil Poole 2013 ++ * ++ * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor ++ * Vladimir Barinov, ++ * Copyright (C) 2007 MontaVista Software, Inc., ++ * ++ * OMAP ALSA SoC DAI driver using McBSP port ++ * Copyright (C) 2008 Nokia Corporation ++ * Contact: Jarkko Nikula ++ * Peter Ujfalusi ++ * ++ * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver ++ * Author: Timur Tabi ++ * Copyright 2007-2010 Freescale Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * 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. ++ */ ++ ++#include "bcm2708-i2s.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* Clock registers */ ++#define BCM2708_CLK_PCMCTL_REG 0x00 ++#define BCM2708_CLK_PCMDIV_REG 0x04 ++ ++/* Clock register settings */ ++#define BCM2708_CLK_PASSWD (0x5a000000) ++#define BCM2708_CLK_PASSWD_MASK (0xff000000) ++#define BCM2708_CLK_MASH(v) ((v) << 9) ++#define BCM2708_CLK_FLIP BIT(8) ++#define BCM2708_CLK_BUSY BIT(7) ++#define BCM2708_CLK_KILL BIT(5) ++#define BCM2708_CLK_ENAB BIT(4) ++#define BCM2708_CLK_SRC(v) (v) ++ ++#define BCM2708_CLK_SHIFT (12) ++#define BCM2708_CLK_DIVI(v) ((v) << BCM2708_CLK_SHIFT) ++#define BCM2708_CLK_DIVF(v) (v) ++#define BCM2708_CLK_DIVF_MASK (0xFFF) ++ ++enum { ++ BCM2708_CLK_MASH_0 = 0, ++ BCM2708_CLK_MASH_1, ++ BCM2708_CLK_MASH_2, ++ BCM2708_CLK_MASH_3, ++}; ++ ++enum { ++ BCM2708_CLK_SRC_GND = 0, ++ BCM2708_CLK_SRC_OSC, ++ BCM2708_CLK_SRC_DBG0, ++ BCM2708_CLK_SRC_DBG1, ++ BCM2708_CLK_SRC_PLLA, ++ BCM2708_CLK_SRC_PLLC, ++ BCM2708_CLK_SRC_PLLD, ++ BCM2708_CLK_SRC_HDMI, ++}; ++ ++/* Most clocks are not useable (freq = 0) */ ++static const unsigned int bcm2708_clk_freq[BCM2708_CLK_SRC_HDMI+1] = { ++ [BCM2708_CLK_SRC_GND] = 0, ++ [BCM2708_CLK_SRC_OSC] = 19200000, ++ [BCM2708_CLK_SRC_DBG0] = 0, ++ [BCM2708_CLK_SRC_DBG1] = 0, ++ [BCM2708_CLK_SRC_PLLA] = 0, ++ [BCM2708_CLK_SRC_PLLC] = 0, ++ [BCM2708_CLK_SRC_PLLD] = 500000000, ++ [BCM2708_CLK_SRC_HDMI] = 0, ++}; ++ ++/* I2S registers */ ++#define BCM2708_I2S_CS_A_REG 0x00 ++#define BCM2708_I2S_FIFO_A_REG 0x04 ++#define BCM2708_I2S_MODE_A_REG 0x08 ++#define BCM2708_I2S_RXC_A_REG 0x0c ++#define BCM2708_I2S_TXC_A_REG 0x10 ++#define BCM2708_I2S_DREQ_A_REG 0x14 ++#define BCM2708_I2S_INTEN_A_REG 0x18 ++#define BCM2708_I2S_INTSTC_A_REG 0x1c ++#define BCM2708_I2S_GRAY_REG 0x20 ++ ++/* I2S register settings */ ++#define BCM2708_I2S_STBY BIT(25) ++#define BCM2708_I2S_SYNC BIT(24) ++#define BCM2708_I2S_RXSEX BIT(23) ++#define BCM2708_I2S_RXF BIT(22) ++#define BCM2708_I2S_TXE BIT(21) ++#define BCM2708_I2S_RXD BIT(20) ++#define BCM2708_I2S_TXD BIT(19) ++#define BCM2708_I2S_RXR BIT(18) ++#define BCM2708_I2S_TXW BIT(17) ++#define BCM2708_I2S_CS_RXERR BIT(16) ++#define BCM2708_I2S_CS_TXERR BIT(15) ++#define BCM2708_I2S_RXSYNC BIT(14) ++#define BCM2708_I2S_TXSYNC BIT(13) ++#define BCM2708_I2S_DMAEN BIT(9) ++#define BCM2708_I2S_RXTHR(v) ((v) << 7) ++#define BCM2708_I2S_TXTHR(v) ((v) << 5) ++#define BCM2708_I2S_RXCLR BIT(4) ++#define BCM2708_I2S_TXCLR BIT(3) ++#define BCM2708_I2S_TXON BIT(2) ++#define BCM2708_I2S_RXON BIT(1) ++#define BCM2708_I2S_EN (1) ++ ++#define BCM2708_I2S_CLKDIS BIT(28) ++#define BCM2708_I2S_PDMN BIT(27) ++#define BCM2708_I2S_PDME BIT(26) ++#define BCM2708_I2S_FRXP BIT(25) ++#define BCM2708_I2S_FTXP BIT(24) ++#define BCM2708_I2S_CLKM BIT(23) ++#define BCM2708_I2S_CLKI BIT(22) ++#define BCM2708_I2S_FSM BIT(21) ++#define BCM2708_I2S_FSI BIT(20) ++#define BCM2708_I2S_FLEN(v) ((v) << 10) ++#define BCM2708_I2S_FSLEN(v) (v) ++ ++#define BCM2708_I2S_CHWEX BIT(15) ++#define BCM2708_I2S_CHEN BIT(14) ++#define BCM2708_I2S_CHPOS(v) ((v) << 4) ++#define BCM2708_I2S_CHWID(v) (v) ++#define BCM2708_I2S_CH1(v) ((v) << 16) ++#define BCM2708_I2S_CH2(v) (v) ++ ++#define BCM2708_I2S_TX_PANIC(v) ((v) << 24) ++#define BCM2708_I2S_RX_PANIC(v) ((v) << 16) ++#define BCM2708_I2S_TX(v) ((v) << 8) ++#define BCM2708_I2S_RX(v) (v) ++ ++#define BCM2708_I2S_INT_RXERR BIT(3) ++#define BCM2708_I2S_INT_TXERR BIT(2) ++#define BCM2708_I2S_INT_RXR BIT(1) ++#define BCM2708_I2S_INT_TXW BIT(0) ++ ++/* I2S DMA interface */ ++#define BCM2708_I2S_FIFO_PHYSICAL_ADDR 0x7E203004 ++#define BCM2708_DMA_DREQ_PCM_TX 2 ++#define BCM2708_DMA_DREQ_PCM_RX 3 ++ ++/* I2S pin configuration */ ++static int bcm2708_i2s_gpio=BCM2708_I2S_GPIO_AUTO; ++ ++/* General device struct */ ++struct bcm2708_i2s_dev { ++ struct device *dev; ++ struct snd_dmaengine_dai_dma_data dma_data[2]; ++ unsigned int fmt; ++ unsigned int bclk_ratio; ++ ++ struct regmap *i2s_regmap; ++ struct regmap *clk_regmap; ++}; ++ ++void bcm2708_i2s_set_gpio(int gpio) { ++ bcm2708_i2s_gpio=gpio; ++} ++EXPORT_SYMBOL(bcm2708_i2s_set_gpio); ++ ++ ++static void bcm2708_i2s_start_clock(struct bcm2708_i2s_dev *dev) ++{ ++ /* Start the clock if in master mode */ ++ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; ++ ++ switch (master) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ case SND_SOC_DAIFMT_CBS_CFM: ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, ++ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void bcm2708_i2s_stop_clock(struct bcm2708_i2s_dev *dev) ++{ ++ uint32_t clkreg; ++ int timeout = 1000; ++ ++ /* Stop clock */ ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, ++ BCM2708_CLK_PASSWD); ++ ++ /* Wait for the BUSY flag going down */ ++ while (--timeout) { ++ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); ++ if (!(clkreg & BCM2708_CLK_BUSY)) ++ break; ++ } ++ ++ if (!timeout) { ++ /* KILL the clock */ ++ dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n"); ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD_MASK, ++ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD); ++ } ++} ++ ++static void bcm2708_i2s_clear_fifos(struct bcm2708_i2s_dev *dev, ++ bool tx, bool rx) ++{ ++ int timeout = 1000; ++ uint32_t syncval; ++ uint32_t csreg; ++ uint32_t i2s_active_state; ++ uint32_t clkreg; ++ uint32_t clk_active_state; ++ uint32_t off; ++ uint32_t clr; ++ ++ off = tx ? BCM2708_I2S_TXON : 0; ++ off |= rx ? BCM2708_I2S_RXON : 0; ++ ++ clr = tx ? BCM2708_I2S_TXCLR : 0; ++ clr |= rx ? BCM2708_I2S_RXCLR : 0; ++ ++ /* Backup the current state */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); ++ i2s_active_state = csreg & (BCM2708_I2S_RXON | BCM2708_I2S_TXON); ++ ++ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); ++ clk_active_state = clkreg & BCM2708_CLK_ENAB; ++ ++ /* Start clock if not running */ ++ if (!clk_active_state) { ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, ++ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); ++ } ++ ++ /* Stop I2S module */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, off, 0); ++ ++ /* ++ * Clear the FIFOs ++ * Requires at least 2 PCM clock cycles to take effect ++ */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, clr, clr); ++ ++ /* Wait for 2 PCM clock cycles */ ++ ++ /* ++ * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back ++ * FIXME: This does not seem to work for slave mode! ++ */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &syncval); ++ syncval &= BCM2708_I2S_SYNC; ++ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_SYNC, ~syncval); ++ ++ /* Wait for the SYNC flag changing it's state */ ++ while (--timeout) { ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); ++ if ((csreg & BCM2708_I2S_SYNC) != syncval) ++ break; ++ } ++ ++ if (!timeout) ++ dev_err(dev->dev, "I2S SYNC error!\n"); ++ ++ /* Stop clock if it was not running before */ ++ if (!clk_active_state) ++ bcm2708_i2s_stop_clock(dev); ++ ++ /* Restore I2S state */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_RXON | BCM2708_I2S_TXON, i2s_active_state); ++} ++ ++static int bcm2708_i2s_set_dai_fmt(struct snd_soc_dai *dai, ++ unsigned int fmt) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ dev->fmt = fmt; ++ return 0; ++} ++ ++static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, ++ unsigned int ratio) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ dev->bclk_ratio = ratio; ++ return 0; ++} ++ ++ ++static int bcm2708_i2s_set_function(unsigned offset, int function) ++{ ++ #define GPIOFSEL(x) (0x00+(x)*4) ++ void __iomem *gpio = __io_address(GPIO_BASE); ++ unsigned alt = function <= 3 ? function + 4: function == 4 ? 3 : 2; ++ unsigned gpiodir; ++ unsigned gpio_bank = offset / 10; ++ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3; ++ ++ if (offset >= BCM2708_NR_GPIOS) ++ return -EINVAL; ++ ++ gpiodir = readl(gpio + GPIOFSEL(gpio_bank)); ++ gpiodir &= ~(7 << gpio_field_offset); ++ gpiodir |= alt << gpio_field_offset; ++ writel(gpiodir, gpio + GPIOFSEL(gpio_bank)); ++ return 0; ++} ++ ++static void bcm2708_i2s_setup_gpio(void) ++{ ++ /* ++ * This is the common way to handle the GPIO pins for ++ * the Raspberry Pi. ++ * TODO Better way would be to handle ++ * this in the device tree! ++ */ ++ int pin,pinconfig,startpin,alt; ++ ++ /* SPI is on different GPIOs on different boards */ ++ /* for Raspberry Pi B+, this is pin GPIO18-21, for original on 28-31 */ ++ if (bcm2708_i2s_gpio==BCM2708_I2S_GPIO_AUTO) { ++ if ((system_rev & 0xffffff) >= 0x10) { ++ /* Model B+ */ ++ pinconfig=BCM2708_I2S_GPIO_PIN18; ++ } else { ++ /* original */ ++ pinconfig=BCM2708_I2S_GPIO_PIN28; ++ } ++ } else { ++ pinconfig=bcm2708_i2s_gpio; ++ } ++ ++ if (pinconfig==BCM2708_I2S_GPIO_PIN18) { ++ startpin=18; ++ alt=BCM2708_I2S_GPIO_PIN18_ALT; ++ } else if (pinconfig==BCM2708_I2S_GPIO_PIN28) { ++ startpin=28; ++ alt=BCM2708_I2S_GPIO_PIN28_ALT; ++ } else { ++ printk(KERN_INFO "Can't configure I2S GPIOs, unknown pin mode for I2S: %i\n",pinconfig); ++ return; ++ } ++ ++ /* configure I2S pins to correct ALT mode */ ++ for (pin = startpin; pin <= startpin+3; pin++) { ++ bcm2708_i2s_set_function(pin, alt); ++ } ++} ++ ++static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ unsigned int sampling_rate = params_rate(params); ++ unsigned int data_length, data_delay, bclk_ratio; ++ unsigned int ch1pos, ch2pos, mode, format; ++ unsigned int mash = BCM2708_CLK_MASH_1; ++ unsigned int divi, divf, target_frequency; ++ int clk_src = -1; ++ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; ++ bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS ++ || master == SND_SOC_DAIFMT_CBS_CFM); ++ ++ bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS ++ || master == SND_SOC_DAIFMT_CBM_CFS); ++ uint32_t csreg; ++ ++ /* ++ * If a stream is already enabled, ++ * the registers are already set properly. ++ */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); ++ ++ if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) ++ return 0; ++ ++ ++ bcm2708_i2s_setup_gpio(); ++ ++ /* ++ * Adjust the data length according to the format. ++ * We prefill the half frame length with an integer ++ * divider of 2400 as explained at the clock settings. ++ * Maybe it is overwritten there, if the Integer mode ++ * does not apply. ++ */ ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ data_length = 16; ++ bclk_ratio = 50; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ data_length = 24; ++ bclk_ratio = 50; ++ break; ++ case SNDRV_PCM_FORMAT_S32_LE: ++ data_length = 32; ++ bclk_ratio = 100; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* If bclk_ratio already set, use that one. */ ++ if (dev->bclk_ratio) ++ bclk_ratio = dev->bclk_ratio; ++ ++ /* ++ * Clock Settings ++ * ++ * The target frequency of the bit clock is ++ * sampling rate * frame length ++ * ++ * Integer mode: ++ * Sampling rates that are multiples of 8000 kHz ++ * can be driven by the oscillator of 19.2 MHz ++ * with an integer divider as long as the frame length ++ * is an integer divider of 19200000/8000=2400 as set up above. ++ * This is no longer possible if the sampling rate ++ * is too high (e.g. 192 kHz), because the oscillator is too slow. ++ * ++ * MASH mode: ++ * For all other sampling rates, it is not possible to ++ * have an integer divider. Approximate the clock ++ * with the MASH module that induces a slight frequency ++ * variance. To minimize that it is best to have the fastest ++ * clock here. That is PLLD with 500 MHz. ++ */ ++ target_frequency = sampling_rate * bclk_ratio; ++ clk_src = BCM2708_CLK_SRC_OSC; ++ mash = BCM2708_CLK_MASH_0; ++ ++ if (bcm2708_clk_freq[clk_src] % target_frequency == 0 ++ && bit_master && frame_master) { ++ divi = bcm2708_clk_freq[clk_src] / target_frequency; ++ divf = 0; ++ } else { ++ uint64_t dividend; ++ ++ if (!dev->bclk_ratio) { ++ /* ++ * Overwrite bclk_ratio, because the ++ * above trick is not needed or can ++ * not be used. ++ */ ++ bclk_ratio = 2 * data_length; ++ } ++ ++ target_frequency = sampling_rate * bclk_ratio; ++ ++ clk_src = BCM2708_CLK_SRC_PLLD; ++ mash = BCM2708_CLK_MASH_1; ++ ++ dividend = bcm2708_clk_freq[clk_src]; ++ dividend <<= BCM2708_CLK_SHIFT; ++ do_div(dividend, target_frequency); ++ divi = dividend >> BCM2708_CLK_SHIFT; ++ divf = dividend & BCM2708_CLK_DIVF_MASK; ++ } ++ ++ /* Clock should only be set up here if CPU is clock master */ ++ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) || ++ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) { ++ /* Set clock divider */ ++ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD ++ | BCM2708_CLK_DIVI(divi) ++ | BCM2708_CLK_DIVF(divf)); ++ ++ /* Setup clock, but don't start it yet */ ++ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD ++ | BCM2708_CLK_MASH(mash) ++ | BCM2708_CLK_SRC(clk_src)); ++ } ++ ++ /* Setup the frame format */ ++ format = BCM2708_I2S_CHEN; ++ ++ if (data_length >= 24) ++ format |= BCM2708_I2S_CHWEX; ++ ++ format |= BCM2708_I2S_CHWID((data_length-8)&0xf); ++ ++ switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ data_delay = 1; ++ break; ++ default: ++ /* ++ * TODO ++ * Others are possible but are not implemented at the moment. ++ */ ++ dev_err(dev->dev, "%s:bad format\n", __func__); ++ return -EINVAL; ++ } ++ ++ ch1pos = data_delay; ++ ch2pos = bclk_ratio / 2 + data_delay; ++ ++ switch (params_channels(params)) { ++ case 2: ++ format = BCM2708_I2S_CH1(format) | BCM2708_I2S_CH2(format); ++ format |= BCM2708_I2S_CH1(BCM2708_I2S_CHPOS(ch1pos)); ++ format |= BCM2708_I2S_CH2(BCM2708_I2S_CHPOS(ch2pos)); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* ++ * Set format for both streams. ++ * We cannot set another frame length ++ * (and therefore word length) anyway, ++ * so the format will be the same. ++ */ ++ regmap_write(dev->i2s_regmap, BCM2708_I2S_RXC_A_REG, format); ++ regmap_write(dev->i2s_regmap, BCM2708_I2S_TXC_A_REG, format); ++ ++ /* Setup the I2S mode */ ++ mode = 0; ++ ++ if (data_length <= 16) { ++ /* ++ * Use frame packed mode (2 channels per 32 bit word) ++ * We cannot set another frame length in the second stream ++ * (and therefore word length) anyway, ++ * so the format will be the same. ++ */ ++ mode |= BCM2708_I2S_FTXP | BCM2708_I2S_FRXP; ++ } ++ ++ mode |= BCM2708_I2S_FLEN(bclk_ratio - 1); ++ mode |= BCM2708_I2S_FSLEN(bclk_ratio / 2); ++ ++ /* Master or slave? */ ++ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ /* CPU is master */ ++ break; ++ case SND_SOC_DAIFMT_CBM_CFS: ++ /* ++ * CODEC is bit clock master ++ * CPU is frame master ++ */ ++ mode |= BCM2708_I2S_CLKM; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFM: ++ /* ++ * CODEC is frame master ++ * CPU is bit clock master ++ */ ++ mode |= BCM2708_I2S_FSM; ++ break; ++ case SND_SOC_DAIFMT_CBM_CFM: ++ /* CODEC is master */ ++ mode |= BCM2708_I2S_CLKM; ++ mode |= BCM2708_I2S_FSM; ++ break; ++ default: ++ dev_err(dev->dev, "%s:bad master\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* ++ * Invert clocks? ++ * ++ * The BCM approach seems to be inverted to the classical I2S approach. ++ */ ++ switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_NB_NF: ++ /* None. Therefore, both for BCM */ ++ mode |= BCM2708_I2S_CLKI; ++ mode |= BCM2708_I2S_FSI; ++ break; ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Both. Therefore, none for BCM */ ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* ++ * Invert only frame sync. Therefore, ++ * invert only bit clock for BCM ++ */ ++ mode |= BCM2708_I2S_CLKI; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* ++ * Invert only bit clock. Therefore, ++ * invert only frame sync for BCM ++ */ ++ mode |= BCM2708_I2S_FSI; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_write(dev->i2s_regmap, BCM2708_I2S_MODE_A_REG, mode); ++ ++ /* Setup the DMA parameters */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_RXTHR(1) ++ | BCM2708_I2S_TXTHR(1) ++ | BCM2708_I2S_DMAEN, 0xffffffff); ++ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_DREQ_A_REG, ++ BCM2708_I2S_TX_PANIC(0x10) ++ | BCM2708_I2S_RX_PANIC(0x30) ++ | BCM2708_I2S_TX(0x30) ++ | BCM2708_I2S_RX(0x20), 0xffffffff); ++ ++ /* Clear FIFOs */ ++ bcm2708_i2s_clear_fifos(dev, true, true); ++ ++ return 0; ++} ++ ++static int bcm2708_i2s_prepare(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ uint32_t cs_reg; ++ ++ bcm2708_i2s_start_clock(dev); ++ ++ /* ++ * Clear both FIFOs if the one that should be started ++ * is not empty at the moment. This should only happen ++ * after overrun. Otherwise, hw_params would have cleared ++ * the FIFO. ++ */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &cs_reg); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ++ && !(cs_reg & BCM2708_I2S_TXE)) ++ bcm2708_i2s_clear_fifos(dev, true, false); ++ else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE ++ && (cs_reg & BCM2708_I2S_RXD)) ++ bcm2708_i2s_clear_fifos(dev, false, true); ++ ++ return 0; ++} ++ ++static void bcm2708_i2s_stop(struct bcm2708_i2s_dev *dev, ++ struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ uint32_t mask; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ++ mask = BCM2708_I2S_RXON; ++ else ++ mask = BCM2708_I2S_TXON; ++ ++ regmap_update_bits(dev->i2s_regmap, ++ BCM2708_I2S_CS_A_REG, mask, 0); ++ ++ /* Stop also the clock when not SND_SOC_DAIFMT_CONT */ ++ if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT)) ++ bcm2708_i2s_stop_clock(dev); ++} ++ ++static int bcm2708_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ uint32_t mask; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ bcm2708_i2s_start_clock(dev); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ++ mask = BCM2708_I2S_RXON; ++ else ++ mask = BCM2708_I2S_TXON; ++ ++ regmap_update_bits(dev->i2s_regmap, ++ BCM2708_I2S_CS_A_REG, mask, mask); ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ bcm2708_i2s_stop(dev, substream, dai); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int bcm2708_i2s_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ if (dai->active) ++ return 0; ++ ++ /* Should this still be running stop it */ ++ bcm2708_i2s_stop_clock(dev); ++ ++ /* Enable PCM block */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_EN, BCM2708_I2S_EN); ++ ++ /* ++ * Disable STBY. ++ * Requires at least 4 PCM clock cycles to take effect. ++ */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_STBY, BCM2708_I2S_STBY); ++ ++ return 0; ++} ++ ++static void bcm2708_i2s_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ bcm2708_i2s_stop(dev, substream, dai); ++ ++ /* If both streams are stopped, disable module and clock */ ++ if (dai->active) ++ return; ++ ++ /* Disable the module */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_EN, 0); ++ ++ /* ++ * Stopping clock is necessary, because stop does ++ * not stop the clock when SND_SOC_DAIFMT_CONT ++ */ ++ bcm2708_i2s_stop_clock(dev); ++} ++ ++static const struct snd_soc_dai_ops bcm2708_i2s_dai_ops = { ++ .startup = bcm2708_i2s_startup, ++ .shutdown = bcm2708_i2s_shutdown, ++ .prepare = bcm2708_i2s_prepare, ++ .trigger = bcm2708_i2s_trigger, ++ .hw_params = bcm2708_i2s_hw_params, ++ .set_fmt = bcm2708_i2s_set_dai_fmt, ++ .set_bclk_ratio = bcm2708_i2s_set_dai_bclk_ratio ++}; ++ ++static int bcm2708_i2s_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; ++ dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_driver bcm2708_i2s_dai = { ++ .name = "bcm2708-i2s", ++ .probe = bcm2708_i2s_dai_probe, ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE ++ | SNDRV_PCM_FMTBIT_S32_LE ++ }, ++ .capture = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE ++ | SNDRV_PCM_FMTBIT_S32_LE ++ }, ++ .ops = &bcm2708_i2s_dai_ops, ++ .symmetric_rates = 1 ++}; ++ ++static bool bcm2708_i2s_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case BCM2708_I2S_CS_A_REG: ++ case BCM2708_I2S_FIFO_A_REG: ++ case BCM2708_I2S_INTSTC_A_REG: ++ case BCM2708_I2S_GRAY_REG: ++ return true; ++ default: ++ return false; ++ }; ++} ++ ++static bool bcm2708_i2s_precious_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case BCM2708_I2S_FIFO_A_REG: ++ return true; ++ default: ++ return false; ++ }; ++} ++ ++static bool bcm2708_clk_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case BCM2708_CLK_PCMCTL_REG: ++ return true; ++ default: ++ return false; ++ }; ++} ++ ++static const struct regmap_config bcm2708_regmap_config[] = { ++ { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .max_register = BCM2708_I2S_GRAY_REG, ++ .precious_reg = bcm2708_i2s_precious_reg, ++ .volatile_reg = bcm2708_i2s_volatile_reg, ++ .cache_type = REGCACHE_RBTREE, ++ .name = "i2s", ++ }, ++ { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .max_register = BCM2708_CLK_PCMDIV_REG, ++ .volatile_reg = bcm2708_clk_volatile_reg, ++ .cache_type = REGCACHE_RBTREE, ++ .name = "clk", ++ }, ++}; ++ ++static const struct snd_soc_component_driver bcm2708_i2s_component = { ++ .name = "bcm2708-i2s-comp", ++}; ++ ++static const struct snd_pcm_hardware bcm2708_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_JOINT_DUPLEX, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE, ++ .period_bytes_min = 32, ++ .period_bytes_max = 64 * PAGE_SIZE, ++ .periods_min = 2, ++ .periods_max = 255, ++ .buffer_bytes_max = 128 * PAGE_SIZE, ++}; ++ ++static const struct snd_dmaengine_pcm_config bcm2708_dmaengine_pcm_config = { ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++ .pcm_hardware = &bcm2708_pcm_hardware, ++ .prealloc_buffer_size = 256 * PAGE_SIZE, ++}; ++ ++ ++static int bcm2708_i2s_probe(struct platform_device *pdev) ++{ ++ struct bcm2708_i2s_dev *dev; ++ int i; ++ int ret; ++ struct regmap *regmap[2]; ++ struct resource *mem[2]; ++ ++ /* Request both ioareas */ ++ for (i = 0; i <= 1; i++) { ++ void __iomem *base; ++ ++ mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ base = devm_ioremap_resource(&pdev->dev, mem[i]); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, ++ &bcm2708_regmap_config[i]); ++ if (IS_ERR(regmap[i])) { ++ dev_err(&pdev->dev, "I2S probe: regmap init failed\n"); ++ return PTR_ERR(regmap[i]); ++ } ++ } ++ ++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), ++ GFP_KERNEL); ++ if (IS_ERR(dev)) ++ return PTR_ERR(dev); ++ ++ dev->i2s_regmap = regmap[0]; ++ dev->clk_regmap = regmap[1]; ++ ++ /* Set the DMA address */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = ++ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; ++ ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = ++ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; ++ ++ /* Set the DREQ */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].slave_id = ++ BCM2708_DMA_DREQ_PCM_TX; ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].slave_id = ++ BCM2708_DMA_DREQ_PCM_RX; ++ ++ /* Set the bus width */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = ++ DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = ++ DMA_SLAVE_BUSWIDTH_4_BYTES; ++ ++ /* Set burst */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; ++ ++ /* BCLK ratio - use default */ ++ dev->bclk_ratio = 0; ++ ++ /* Store the pdev */ ++ dev->dev = &pdev->dev; ++ dev_set_drvdata(&pdev->dev, dev); ++ ++ ret = snd_soc_register_component(&pdev->dev, ++ &bcm2708_i2s_component, &bcm2708_i2s_dai, 1); ++ ++ if (ret) { ++ dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ++ ret = -ENOMEM; ++ return ret; ++ } ++ ++ ret = snd_dmaengine_pcm_register(&pdev->dev, ++ &bcm2708_dmaengine_pcm_config, ++ SND_DMAENGINE_PCM_FLAG_COMPAT); ++ if (ret) { ++ dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); ++ snd_soc_unregister_component(&pdev->dev); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bcm2708_i2s_remove(struct platform_device *pdev) ++{ ++ snd_dmaengine_pcm_unregister(&pdev->dev); ++ snd_soc_unregister_component(&pdev->dev); ++ return 0; ++} ++ ++static const struct of_device_id bcm2708_i2s_of_match[] = { ++ { .compatible = "brcm,bcm2708-i2s", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match); ++ ++static struct platform_driver bcm2708_i2s_driver = { ++ .probe = bcm2708_i2s_probe, ++ .remove = bcm2708_i2s_remove, ++ .driver = { ++ .name = "bcm2708-i2s", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2708_i2s_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2708_i2s_driver); ++ ++MODULE_ALIAS("platform:bcm2708-i2s"); ++MODULE_DESCRIPTION("BCM2708 I2S interface"); ++MODULE_AUTHOR("Florian Meier "); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/bcm/bcm2708-i2s.h b/sound/soc/bcm/bcm2708-i2s.h +new file mode 100644 +index 0000000..6fdcbc1 +--- /dev/null ++++ b/sound/soc/bcm/bcm2708-i2s.h +@@ -0,0 +1,35 @@ ++/* ++ * I2S configuration for sound cards. ++ * ++ * Copyright (c) 2014 Daniel Matuschek ++ * ++ * 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 BCM2708_I2S_H ++#define BCM2708_I2S_H ++ ++/* I2S pin assignment */ ++#define BCM2708_I2S_GPIO_AUTO 0 ++#define BCM2708_I2S_GPIO_PIN18 1 ++#define BCM2708_I2S_GPIO_PIN28 2 ++ ++/* Alt mode to enable I2S */ ++#define BCM2708_I2S_GPIO_PIN18_ALT 0 ++#define BCM2708_I2S_GPIO_PIN28_ALT 2 ++ ++extern void bcm2708_i2s_set_gpio(int gpio); ++ ++#endif + +From 355253cae3f2e9200926bfeb8d21646600d0768e Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 14:59:51 +0100 +Subject: [PATCH 36/77] ASoC: Add support for PCM5102A codec + +Some definitions to support the PCM5102A codec +by Texas Instruments. + +Signed-off-by: Florian Meier +--- + sound/soc/codecs/Kconfig | 4 +++ + sound/soc/codecs/Makefile | 2 ++ + sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 69 insertions(+) + create mode 100644 sound/soc/codecs/pcm5102a.c + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 061c465..a3d70f9 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -83,6 +83,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_PCM512x_I2C if I2C + select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RT286 if I2C ++ select SND_SOC_PCM5102A if I2C + select SND_SOC_RT5631 if I2C + select SND_SOC_RT5640 if I2C + select SND_SOC_RT5645 if I2C +@@ -511,6 +512,9 @@ config SND_SOC_RT286 + tristate + depends on I2C + ++config SND_SOC_PCM5102A ++ tristate ++ + config SND_SOC_RT5631 + tristate "Realtek ALC5631/RT5631 CODEC" + depends on I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index abe2d7e..a0fda52 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o + snd-soc-pcm512x-spi-objs := pcm512x-spi.o + snd-soc-rl6231-objs := rl6231.o + snd-soc-rt286-objs := rt286.o ++snd-soc-pcm5102a-objs := pcm5102a.o + snd-soc-rt5631-objs := rt5631.o + snd-soc-rt5640-objs := rt5640.o + snd-soc-rt5645-objs := rt5645.o +@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o + obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o + obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o ++obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o + obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o + obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o + obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o +diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c +new file mode 100644 +index 0000000..126f1e9 +--- /dev/null ++++ b/sound/soc/codecs/pcm5102a.c +@@ -0,0 +1,63 @@ ++/* ++ * Driver for the PCM5102A codec ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++ ++#include ++#include ++#include ++ ++#include ++ ++static struct snd_soc_dai_driver pcm5102a_dai = { ++ .name = "pcm5102a-hifi", ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE ++ }, ++}; ++ ++static struct snd_soc_codec_driver soc_codec_dev_pcm5102a; ++ ++static int pcm5102a_probe(struct platform_device *pdev) ++{ ++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a, ++ &pcm5102a_dai, 1); ++} ++ ++static int pcm5102a_remove(struct platform_device *pdev) ++{ ++ snd_soc_unregister_codec(&pdev->dev); ++ return 0; ++} ++ ++static struct platform_driver pcm5102a_codec_driver = { ++ .probe = pcm5102a_probe, ++ .remove = pcm5102a_remove, ++ .driver = { ++ .name = "pcm5102a-codec", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(pcm5102a_codec_driver); ++ ++MODULE_DESCRIPTION("ASoC PCM5102A codec driver"); ++MODULE_AUTHOR("Florian Meier "); ++MODULE_LICENSE("GPL v2"); + +From 49e137bd21361ad8f4439f35956ceab424013411 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 19:04:54 +0100 +Subject: [PATCH 37/77] BCM2708: Add I2S support to board file + +Adds the required initializations for I2S +to the board file of mach-bcm2708. + +Signed-off-by: Florian Meier + +bcm2708-i2s: Enable MMAP support via a DT property and overlay + +The i2s driver used to claim to support MMAP, but that feature was disabled +when some problems were found. Add the ability to enable this feature +through Device Tree, using the i2s-mmap overlay. + +See: #1004 +--- + arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ + sound/soc/bcm/bcm2708-i2s.c | 7 ++++++- + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index c7b4b61..dc57983 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -616,6 +616,28 @@ static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++static struct resource bcm2708_i2s_resources[] = { ++ { ++ .start = I2S_BASE, ++ .end = I2S_BASE + 0x20, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = PCM_CLOCK_BASE, ++ .end = PCM_CLOCK_BASE + 0x02, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device bcm2708_i2s_device = { ++ .name = "bcm2708-i2s", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), ++ .resource = bcm2708_i2s_resources, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -780,6 +802,10 @@ void __init bcm2708_init(void) + + bcm_register_device_dt(&bcm2835_thermal_device); + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++ bcm_register_device_dt(&bcm2708_i2s_device); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +index a3b65dc..a515992 100644 +--- a/sound/soc/bcm/bcm2708-i2s.c ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -874,7 +874,7 @@ static const struct snd_soc_component_driver bcm2708_i2s_component = { + .name = "bcm2708-i2s-comp", + }; + +-static const struct snd_pcm_hardware bcm2708_pcm_hardware = { ++static struct snd_pcm_hardware bcm2708_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_JOINT_DUPLEX, + .formats = SNDRV_PCM_FMTBIT_S16_LE | +@@ -902,6 +902,11 @@ static int bcm2708_i2s_probe(struct platform_device *pdev) + struct regmap *regmap[2]; + struct resource *mem[2]; + ++ if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) ++ bcm2708_pcm_hardware.info |= ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID; ++ + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { + void __iomem *base; + +From 5786483930fcb7863012d8bb81d1f73a67b258da Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 19:19:08 +0100 +Subject: [PATCH 38/77] ASoC: Add support for HifiBerry DAC + +This adds a machine driver for the HifiBerry DAC. +It is a sound card that can +be stacked onto the Raspberry Pi. + +Signed-off-by: Florian Meier +--- + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 5 +++ + sound/soc/bcm/hifiberry_dac.c | 100 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 112 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_dac.c + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 8642296..a4a3e86 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -18,3 +18,10 @@ config SND_BCM2708_SOC_I2S + Say Y or M if you want to add support for codecs attached to + the BCM2708 I2S interface. You will also need + to select the audio interfaces to support below. ++ ++config SND_BCM2708_SOC_HIFIBERRY_DAC ++ tristate "Support for HifiBerry DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM5102A ++ help ++ Say Y or M if you want to add support for HifiBerry DAC. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index f8bbe1f..be90a49cb 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -7,3 +7,8 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o + snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o + + obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o ++ ++# BCM2708 Machine Support ++snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++ ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o +diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c +new file mode 100644 +index 0000000..4b70b45 +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_dac.c +@@ -0,0 +1,100 @@ ++/* ++ * ASoC Driver for HifiBerry DAC ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_hifiberry_dac_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dac_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ unsigned int sample_bits = ++ snd_pcm_format_physical_width(params_format(params)); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_dac_ops = { ++ .hw_params = snd_rpi_hifiberry_dac_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = { ++{ ++ .name = "HifiBerry DAC", ++ .stream_name = "HifiBerry DAC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm5102a-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm5102a-codec", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_dac_ops, ++ .init = snd_rpi_hifiberry_dac_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_dac = { ++ .name = "snd_rpi_hifiberry_dac", ++ .dai_link = snd_rpi_hifiberry_dac_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), ++}; ++ ++static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_dac.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); ++} ++ ++static struct platform_driver snd_rpi_hifiberry_dac_driver = { ++ .driver = { ++ .name = "snd-hifiberry-dac", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_hifiberry_dac_probe, ++ .remove = snd_rpi_hifiberry_dac_remove, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_dac_driver); ++ ++MODULE_AUTHOR("Florian Meier "); ++MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); ++MODULE_LICENSE("GPL v2"); + +From 47d7a2a48fd4b2da2f9400de4307febe755b2ef2 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 19:21:34 +0100 +Subject: [PATCH 39/77] BCM2708: Add HifiBerry DAC to board file + +This adds the initalization of the HifiBerry DAC +to the mach-bcm2708 board file. + +Signed-off-by: Florian Meier +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index dc57983..ef7c48d 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -638,6 +638,20 @@ static struct platform_device bcm2708_i2s_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++static struct platform_device snd_hifiberry_dac_device = { ++ .name = "snd-hifiberry-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm5102a_codec_device = { ++ .name = "pcm5102a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -806,6 +820,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&bcm2708_i2s_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + +From 403dc5c76505dd5813174532b2f032e52cbe06b8 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 6 Dec 2013 20:50:28 +0100 +Subject: [PATCH 40/77] ASoC: BCM2708: Add support for RPi-DAC + +This adds a machine driver for the RPi-DAC. + +Signed-off-by: Florian Meier +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/Kconfig | 4 ++ + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ + 7 files changed, 193 insertions(+) + create mode 100644 sound/soc/bcm/rpi-dac.c + create mode 100644 sound/soc/codecs/pcm1794a.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index ef7c48d..be27073 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++static struct platform_device snd_rpi_dac_device = { ++ .name = "snd-rpi-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm1794a_codec_device = { ++ .name = "pcm1794a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -825,6 +839,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_dac_device); ++ bcm_register_device_dt(&snd_pcm1794a_codec_device); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index a4a3e86..cb7c0c2 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -25,3 +25,10 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC + select SND_SOC_PCM5102A + help + Say Y or M if you want to add support for HifiBerry DAC. ++ ++config SND_BCM2708_SOC_RPI_DAC ++ tristate "Support for RPi-DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM1794A ++ help ++ Say Y or M if you want to add support for RPi-DAC. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index be90a49cb..ccc9809 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -10,5 +10,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + + # BCM2708 Machine Support + snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++snd-soc-rpi-dac-objs := rpi-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o +diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c +new file mode 100644 +index 0000000..6d6e0ba +--- /dev/null ++++ b/sound/soc/bcm/rpi-dac.c +@@ -0,0 +1,97 @@ ++/* ++ * ASoC Driver for RPi-DAC. ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_rpi_dac_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return 0; ++} ++ ++static int snd_rpi_rpi_dac_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_rpi_dac_ops = { ++ .hw_params = snd_rpi_rpi_dac_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = { ++{ ++ .name = "RPi-DAC", ++ .stream_name = "RPi-DAC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm1794a-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm1794a-codec", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_rpi_dac_ops, ++ .init = snd_rpi_rpi_dac_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_rpi_dac = { ++ .name = "snd_rpi_rpi_dac", ++ .dai_link = snd_rpi_rpi_dac_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), ++}; ++ ++static int snd_rpi_rpi_dac_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_rpi_dac.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_rpi_dac); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_rpi_dac_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_rpi_dac); ++} ++ ++static struct platform_driver snd_rpi_rpi_dac_driver = { ++ .driver = { ++ .name = "snd-rpi-dac", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_rpi_dac_probe, ++ .remove = snd_rpi_rpi_dac_remove, ++}; ++ ++module_platform_driver(snd_rpi_rpi_dac_driver); ++ ++MODULE_AUTHOR("Florian Meier "); ++MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index a3d70f9..dc3df1a 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -84,6 +84,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RT286 if I2C + select SND_SOC_PCM5102A if I2C ++ select SND_SOC_PCM1794A if I2C + select SND_SOC_RT5631 if I2C + select SND_SOC_RT5640 if I2C + select SND_SOC_RT5645 if I2C +@@ -512,6 +513,9 @@ config SND_SOC_RT286 + tristate + depends on I2C + ++config SND_SOC_PCM1794A ++ tristate ++ + config SND_SOC_PCM5102A + tristate + +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index a0fda52..c1f6ba6 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o + snd-soc-pcm512x-spi-objs := pcm512x-spi.o + snd-soc-rl6231-objs := rl6231.o + snd-soc-rt286-objs := rt286.o ++snd-soc-pcm1794a-objs := pcm1794a.o + snd-soc-pcm5102a-objs := pcm5102a.o + snd-soc-rt5631-objs := rt5631.o + snd-soc-rt5640-objs := rt5640.o +@@ -264,6 +265,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o + obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o + obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o ++obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o + obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o + obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o + obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o +diff --git a/sound/soc/codecs/pcm1794a.c b/sound/soc/codecs/pcm1794a.c +new file mode 100644 +index 0000000..b4eaa44 +--- /dev/null ++++ b/sound/soc/codecs/pcm1794a.c +@@ -0,0 +1,62 @@ ++/* ++ * Driver for the PCM1794A codec ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++ ++#include ++#include ++#include ++ ++#include ++ ++static struct snd_soc_dai_driver pcm1794a_dai = { ++ .name = "pcm1794a-hifi", ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE ++ }, ++}; ++ ++static struct snd_soc_codec_driver soc_codec_dev_pcm1794a; ++ ++static int pcm1794a_probe(struct platform_device *pdev) ++{ ++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm1794a, ++ &pcm1794a_dai, 1); ++} ++ ++static int pcm1794a_remove(struct platform_device *pdev) ++{ ++ snd_soc_unregister_codec(&pdev->dev); ++ return 0; ++} ++ ++static struct platform_driver pcm1794a_codec_driver = { ++ .probe = pcm1794a_probe, ++ .remove = pcm1794a_remove, ++ .driver = { ++ .name = "pcm1794a-codec", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(pcm1794a_codec_driver); ++ ++MODULE_DESCRIPTION("ASoC PCM1794A codec driver"); ++MODULE_AUTHOR("Florian Meier "); ++MODULE_LICENSE("GPL v2"); + +From 0418e9bd3eab8e21b5d69ed0b7899dd5a80263f1 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Wed, 15 Jan 2014 21:41:23 +0100 +Subject: [PATCH 41/77] ASoC: wm8804: Implement MCLK configuration options, add + 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for + most sample rates. At 192kHz only 128xfs is supported. The existing driver + selects 128xfs automatically for some lower samples rates. By using an + additional mclk_div divider, it is now possible to control the behaviour. + This allows using 256xfs PLL frequency on all sample rates up to 96kHz. It + should allow lower jitter and better signal quality. The behavior has to be + controlled by the sound card driver, because some sample frequency share the + same setting. e.g. 192kHz and 96kHz use 24.576MHz master clock. The only + difference is the MCLK divider. + +This also added support for 32bit data. + +Signed-off-by: Daniel Matuschek +--- + sound/soc/codecs/wm8804.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c +index 1e403f6..d4efa85 100644 +--- a/sound/soc/codecs/wm8804.c ++++ b/sound/soc/codecs/wm8804.c +@@ -304,6 +304,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream, + blen = 0x1; + break; + case 24: ++ case 32: + blen = 0x2; + break; + default: +@@ -515,7 +516,7 @@ static const struct snd_soc_dai_ops wm8804_dai_ops = { + }; + + #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ +- SNDRV_PCM_FMTBIT_S24_LE) ++ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + + #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ + +From 82c2f5a297701240bf5a77611d2d93c041497246 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Wed, 15 Jan 2014 21:42:08 +0100 +Subject: [PATCH 42/77] ASoC: BCM:Add support for HiFiBerry Digi. Driver is + based on the patched WM8804 driver. + +Signed-off-by: Daniel Matuschek + +Add a parameter to turn off SPDIF output if no audio is playing + +This patch adds the paramater auto_shutdown_output to the kernel module. +Default behaviour of the module is the same, but when auto_shutdown_output +is set to 1, the SPDIF oputput will shutdown if no stream is playing. + +bugfix for 32kHz sample rate, was missing + +HiFiBerry Digi: set SPDIF status bits for sample rate + +The HiFiBerry Digi driver did not signal the sample rate in the SPDIF status bits. +While this is optional, some DACs and receivers do not accept this signal. This patch +adds the sample rate bits in the SPDIF status block. +--- + sound/soc/bcm/Kconfig | 7 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_digi.c | 201 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 210 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_digi.c + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index cb7c0c2..2e26e12 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC + help + Say Y or M if you want to add support for HifiBerry DAC. + ++config SND_BCM2708_SOC_HIFIBERRY_DIGI ++ tristate "Support for HifiBerry Digi" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_WM8804 ++ help ++ Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. ++ + config SND_BCM2708_SOC_RPI_DAC + tristate "Support for RPi-DAC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index ccc9809..826df7d 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -10,7 +10,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + + # BCM2708 Machine Support + snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++snd-soc-hifiberry-digi-objs := hifiberry_digi.o + snd-soc-rpi-dac-objs := rpi-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o +diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c +new file mode 100644 +index 0000000..92e9e46 +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_digi.c +@@ -0,0 +1,201 @@ ++/* ++ * ASoC Driver for HifiBerry Digi ++ * ++ * Author: Daniel Matuschek ++ * based on the HifiBerry DAC driver by Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/wm8804.h" ++ ++static short int auto_shutdown_output = 0; ++module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); ++MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped"); ++ ++ ++static int samplerate=44100; ++ ++static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ /* enable TX output */ ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); ++ ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_digi_startup(struct snd_pcm_substream *substream) { ++ /* turn on digital output */ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_digi_shutdown(struct snd_pcm_substream *substream) { ++ /* turn off output */ ++ if (auto_shutdown_output) { ++ /* turn off output */ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c); ++ } ++} ++ ++ ++static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ struct snd_soc_codec *codec = rtd->codec; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ int sysclk = 27000000; /* This is fixed on this board */ ++ ++ long mclk_freq=0; ++ int mclk_div=1; ++ int sampling_freq=1; ++ ++ int ret; ++ ++ samplerate = params_rate(params); ++ ++ if (samplerate<=96000) { ++ mclk_freq=samplerate*256; ++ mclk_div=WM8804_MCLKDIV_256FS; ++ } else { ++ mclk_freq=samplerate*128; ++ mclk_div=WM8804_MCLKDIV_128FS; ++ } ++ ++ switch (samplerate) { ++ case 32000: ++ sampling_freq=0x03; ++ break; ++ case 44100: ++ sampling_freq=0x00; ++ break; ++ case 48000: ++ sampling_freq=0x02; ++ break; ++ case 88200: ++ sampling_freq=0x08; ++ break; ++ case 96000: ++ sampling_freq=0x0a; ++ break; ++ case 176400: ++ sampling_freq=0x0c; ++ break; ++ case 192000: ++ sampling_freq=0x0e; ++ break; ++ default: ++ dev_err(codec->dev, ++ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n", ++ samplerate); ++ } ++ ++ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); ++ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); ++ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, ++ sysclk, SND_SOC_CLOCK_OUT); ++ if (ret < 0) { ++ dev_err(codec->dev, ++ "Failed to set WM8804 SYSCLK: %d\n", ret); ++ return ret; ++ } ++ ++ /* Enable TX output */ ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); ++ ++ /* Power on */ ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); ++ ++ /* set sampling frequency status bits */ ++ snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai,64); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = { ++ .hw_params = snd_rpi_hifiberry_digi_hw_params, ++ .startup = snd_rpi_hifiberry_digi_startup, ++ .shutdown = snd_rpi_hifiberry_digi_shutdown, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { ++{ ++ .name = "HifiBerry Digi", ++ .stream_name = "HifiBerry Digi HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "wm8804-spdif", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "wm8804.1-003b", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .ops = &snd_rpi_hifiberry_digi_ops, ++ .init = snd_rpi_hifiberry_digi_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_digi = { ++ .name = "snd_rpi_hifiberry_digi", ++ .dai_link = snd_rpi_hifiberry_digi_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), ++}; ++ ++static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_digi.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); ++} ++ ++static struct platform_driver snd_rpi_hifiberry_digi_driver = { ++ .driver = { ++ .name = "snd-hifiberry-digi", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_hifiberry_digi_probe, ++ .remove = snd_rpi_hifiberry_digi_remove, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_digi_driver); ++ ++MODULE_AUTHOR("Daniel Matuschek "); ++MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); ++MODULE_LICENSE("GPL v2"); + +From df14e52cd5e411324c58e28ec158f503d4905dbb Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Thu, 16 Jan 2014 07:26:08 +0100 +Subject: [PATCH 43/77] BCM2708: Added support for HiFiBerry Digi board Board + initalization by I2C + +Signed-off-by: Daniel Matuschek +--- + arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index be27073..2a33663 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -652,6 +652,21 @@ static struct platform_device snd_pcm5102a_codec_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++static struct platform_device snd_hifiberry_digi_device = { ++ .name = "snd-hifiberry-digi", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("wm8804", 0x3b) ++ }, ++}; ++ ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + static struct platform_device snd_rpi_dac_device = { + .name = "snd-rpi-dac", +@@ -839,6 +854,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_digi_device); ++ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + bcm_register_device_dt(&snd_rpi_dac_device); + bcm_register_device_dt(&snd_pcm1794a_codec_device); + +From d8de9644604c68b7148b023608d70d8ac3bf466f Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Thu, 16 Jan 2014 07:36:35 +0100 +Subject: [PATCH 44/77] ASoC: wm8804: Set idle_bias_off to false Idle bias has + been change to remove warning on driver startup + +Signed-off-by: Daniel Matuschek +--- + sound/soc/codecs/wm8804.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c +index d4efa85..f3f26a2 100644 +--- a/sound/soc/codecs/wm8804.c ++++ b/sound/soc/codecs/wm8804.c +@@ -544,7 +544,7 @@ static struct snd_soc_dai_driver wm8804_dai = { + }; + + static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { +- .idle_bias_off = true, ++ .idle_bias_off = false, + + .dapm_widgets = wm8804_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), + +From 40f01186460630fa704c88adbefbc347e5e402e4 Mon Sep 17 00:00:00 2001 +From: Gordon Garrity +Date: Sat, 8 Mar 2014 16:56:57 +0000 +Subject: [PATCH 45/77] Add IQaudIO Sound Card support for Raspberry Pi + +Set a limit of 0dB on Digital Volume Control + +The main volume control in the PCM512x DAC has a range up to ++24dB. This is dangerously loud and can potentially cause massive +clipping in the output stages. Therefore this sets a sensible +limit of 0dB for this control. +--- + arch/arm/mach-bcm2708/bcm2708.c | 21 ++++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/iqaudio-dac.c | 117 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 147 insertions(+) + create mode 100644 sound/soc/bcm/iqaudio-dac.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 2a33663..957504e 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -681,6 +681,22 @@ static struct platform_device snd_pcm1794a_codec_device = { + }; + #endif + ++ ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++static struct platform_device snd_rpi_iqaudio_dac_device = { ++ .name = "snd-rpi-iqaudio-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++// Use the actual device name rather than generic driver name ++static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4c) ++ }, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -864,6 +880,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm1794a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 2e26e12..f6f8ec1 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -39,3 +39,10 @@ config SND_BCM2708_SOC_RPI_DAC + select SND_SOC_PCM1794A + help + Say Y or M if you want to add support for RPi-DAC. ++ ++config SND_BCM2708_SOC_IQAUDIO_DAC ++ tristate "Support for IQaudIO-DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM512x_I2C ++ help ++ Say Y or M if you want to add support for IQaudIO-DAC. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 826df7d..d597fb0 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -12,7 +12,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + snd-soc-hifiberry-dac-objs := hifiberry_dac.o + snd-soc-hifiberry-digi-objs := hifiberry_digi.o + snd-soc-rpi-dac-objs := rpi-dac.o ++snd-soc-iqaudio-dac-objs := iqaudio-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c +new file mode 100644 +index 0000000..aff7377 +--- /dev/null ++++ b/sound/soc/bcm/iqaudio-dac.c +@@ -0,0 +1,117 @@ ++/* ++ * ASoC Driver for IQaudIO DAC ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ int ret; ++ struct snd_soc_card *card = rtd->card; ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ ++ return 0; ++} ++ ++static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++// NOT USED struct snd_soc_dai *codec_dai = rtd->codec_dai; ++// NOT USED struct snd_soc_codec *codec = rtd->codec; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ unsigned int sample_bits = ++ snd_pcm_format_physical_width(params_format(params)); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = { ++ .hw_params = snd_rpi_iqaudio_dac_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { ++{ ++ .name = "IQaudIO DAC", ++ .stream_name = "IQaudIO DAC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm512x-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm512x.1-004c", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_iqaudio_dac_ops, ++ .init = snd_rpi_iqaudio_dac_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_iqaudio_dac = { ++ .name = "IQaudIODAC", ++ .dai_link = snd_rpi_iqaudio_dac_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), ++}; ++ ++static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_iqaudio_dac.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); ++ if (ret) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_iqaudio_dac); ++} ++ ++static const struct of_device_id iqaudio_of_match[] = { ++ { .compatible = "iqaudio,iqaudio-dac", }, ++ {}, ++}; ++ ++static struct platform_driver snd_rpi_iqaudio_dac_driver = { ++ .driver = { ++ .name = "snd-rpi-iqaudio-dac", ++ .owner = THIS_MODULE, ++ .of_match_table = iqaudio_of_match, ++ }, ++ .probe = snd_rpi_iqaudio_dac_probe, ++ .remove = snd_rpi_iqaudio_dac_remove, ++}; ++ ++module_platform_driver(snd_rpi_iqaudio_dac_driver); ++ ++MODULE_AUTHOR("Florian Meier "); ++MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); ++MODULE_LICENSE("GPL v2"); + +From 5d1014e6dfa91f7f4b07851eefaa0a8bc544fda8 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 18 Jun 2014 13:42:01 +0100 +Subject: [PATCH 46/77] vmstat: Workaround for issue where dirty page count + goes negative + +See: +https://github.com/raspberrypi/linux/issues/617 +http://www.spinics.net/lists/linux-mm/msg72236.html +--- + include/linux/vmstat.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h +index 82e7db7..f87d16d 100644 +--- a/include/linux/vmstat.h ++++ b/include/linux/vmstat.h +@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + { + atomic_long_dec(&zone->vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) ++ atomic_long_set(&zone->vm_stat[item], 0); + atomic_long_dec(&vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) ++ atomic_long_set(&vm_stat[item], 0); + } + + static inline void __inc_zone_page_state(struct page *page, + +From 462ac627ee409f190f5519727c80942afafd0d6d Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 14 Jul 2014 22:02:09 +0100 +Subject: [PATCH 47/77] hid: Reduce default mouse polling interval to 60Hz + +Reduces overhead when using X +--- + drivers/hid/usbhid/hid-core.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c +index bfbe1be..a738b25 100644 +--- a/drivers/hid/usbhid/hid-core.c ++++ b/drivers/hid/usbhid/hid-core.c +@@ -49,7 +49,7 @@ + * Module parameters. + */ + +-static unsigned int hid_mousepoll_interval; ++static unsigned int hid_mousepoll_interval = ~0; + module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); + MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); + +@@ -1090,8 +1090,12 @@ static int usbhid_start(struct hid_device *hid) + } + + /* Change the polling interval of mice. */ +- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) +- interval = hid_mousepoll_interval; ++ if (hid->collection->usage == HID_GD_MOUSE) { ++ if (hid_mousepoll_interval == ~0 && interval < 16) ++ interval = 16; ++ else if (hid_mousepoll_interval != ~0 && hid_mousepoll_interval != 0) ++ interval = hid_mousepoll_interval; ++ } + + ret = -ENOMEM; + if (usb_endpoint_dir_in(endpoint)) { + +From 6a68d9854eed6f1c5741aff8466cb5877deecd54 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Mon, 4 Aug 2014 10:06:56 +0200 +Subject: [PATCH 48/77] Added support for HiFiBerry DAC+ + +The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses +a different codec chip (PCM5122), therefore a new driver is necessary. +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_dacplus.c | 119 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 147 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_dacplus.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 957504e..90459b8 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++static struct platform_device snd_rpi_hifiberry_dacplus_device = { ++ .name = "snd-rpi-hifiberry-dacplus", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4d) ++ }, ++}; ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) + static struct platform_device snd_hifiberry_digi_device = { + .name = "snd-hifiberry-digi", +@@ -870,6 +884,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) + bcm_register_device_dt(&snd_hifiberry_digi_device); + i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index f6f8ec1..8b45ac5 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC + help + Say Y or M if you want to add support for HifiBerry DAC. + ++config SND_BCM2708_SOC_HIFIBERRY_DACPLUS ++ tristate "Support for HifiBerry DAC+" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM512x ++ help ++ Say Y or M if you want to add support for HifiBerry DAC+. ++ + config SND_BCM2708_SOC_HIFIBERRY_DIGI + tristate "Support for HifiBerry Digi" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index d597fb0..c02e3a2 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -10,11 +10,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + + # BCM2708 Machine Support + snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-digi-objs := hifiberry_digi.o + snd-soc-rpi-dac-objs := rpi-dac.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c +new file mode 100644 +index 0000000..c63387b +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -0,0 +1,119 @@ ++/* ++ * ASoC Driver for HiFiBerry DAC+ ++ * ++ * Author: Daniel Matuschek ++ * Copyright 2014 ++ * based on code by Florian Meier ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/pcm512x.h" ++ ++static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++} ++ ++static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = { ++ .hw_params = snd_rpi_hifiberry_dacplus_hw_params, ++ .startup = snd_rpi_hifiberry_dacplus_startup, ++ .shutdown = snd_rpi_hifiberry_dacplus_shutdown, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = { ++{ ++ .name = "HiFiBerry DAC+", ++ .stream_name = "HiFiBerry DAC+ HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm512x-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm512x.1-004d", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_dacplus_ops, ++ .init = snd_rpi_hifiberry_dacplus_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_dacplus = { ++ .name = "snd_rpi_hifiberry_dacplus", ++ .dai_link = snd_rpi_hifiberry_dacplus_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), ++}; ++ ++static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_dacplus.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); ++ if (ret) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); ++} ++ ++static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { ++ .driver = { ++ .name = "snd-rpi-hifiberry-dacplus", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_hifiberry_dacplus_probe, ++ .remove = snd_rpi_hifiberry_dacplus_remove, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_dacplus_driver); ++ ++MODULE_AUTHOR("Daniel Matuschek "); ++MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); ++MODULE_LICENSE("GPL v2"); + +From 1ca3777a5f3e17847136937e1bab1717281c73ca Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Mon, 4 Aug 2014 11:09:58 +0200 +Subject: [PATCH 49/77] Added driver for HiFiBerry Amp amplifier add-on board + +The driver contains a low-level hardware driver for the TAS5713 and the +drivers for the Raspberry Pi I2S subsystem. + +TAS5713: return error if initialisation fails + +Existing TAS5713 driver logs errors during initialisation, but does not return +an error code. Therefore even if initialisation fails, the driver will still be +loaded, but won't work. This patch fixes this. I2C communication error will now +reported correctly by a non-zero return code. + +HiFiBerry Amp: fix device-tree problems + +Some code to load the driver based on device-tree-overlays was missing. This is added by this patch. +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 +++ + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_amp.c | 127 ++++++++++++++ + sound/soc/codecs/Kconfig | 4 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/tas5713.c | 369 ++++++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/tas5713.h | 210 +++++++++++++++++++++++ + 8 files changed, 740 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_amp.c + create mode 100644 sound/soc/codecs/tas5713.c + create mode 100644 sound/soc/codecs/tas5713.h + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 90459b8..785cf1a 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -681,6 +681,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { + + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++static struct platform_device snd_hifiberry_amp_device = { ++ .name = "snd-hifiberry-amp", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("tas5713", 0x1b) ++ }, ++}; ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + static struct platform_device snd_rpi_dac_device = { + .name = "snd-rpi-dac", +@@ -894,6 +908,11 @@ void __init bcm2708_init(void) + i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_amp_device); ++ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + bcm_register_device_dt(&snd_rpi_dac_device); + bcm_register_device_dt(&snd_pcm1794a_codec_device); +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 8b45ac5..bdcf12f 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -40,6 +40,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI + help + Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. + ++config SND_BCM2708_SOC_HIFIBERRY_AMP ++ tristate "Support for the HifiBerry Amp" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_TAS5713 ++ help ++ Say Y or M if you want to add support for the HifiBerry Amp amplifier board. ++ + config SND_BCM2708_SOC_RPI_DAC + tristate "Support for RPi-DAC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index c02e3a2..17ea2b0 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -12,11 +12,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + snd-soc-hifiberry-dac-objs := hifiberry_dac.o + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-digi-objs := hifiberry_digi.o ++snd-soc-hifiberry-amp-objs := hifiberry_amp.o + snd-soc-rpi-dac-objs := rpi-dac.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c +new file mode 100644 +index 0000000..5903915 +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_amp.c +@@ -0,0 +1,127 @@ ++/* ++ * ASoC Driver for HifiBerry AMP ++ * ++ * Author: Sebastian Eickhoff ++ * Copyright 2014 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ // ToDo: init of the dsp-registers. ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params ) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++} ++ ++static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = { ++ .hw_params = snd_rpi_hifiberry_amp_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = { ++ { ++ .name = "HifiBerry AMP", ++ .stream_name = "HifiBerry AMP HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "tas5713-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "tas5713.1-001b", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_amp_ops, ++ .init = snd_rpi_hifiberry_amp_init, ++ }, ++}; ++ ++ ++static struct snd_soc_card snd_rpi_hifiberry_amp = { ++ .name = "snd_rpi_hifiberry_amp", ++ .dai_link = snd_rpi_hifiberry_amp_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), ++}; ++ ++static const struct of_device_id snd_rpi_hifiberry_amp_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-amp", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_amp_of_match); ++ ++ ++static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_amp.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_amp_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp); ++ ++ if (ret != 0) { ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ } ++ ++ return ret; ++} ++ ++ ++static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_amp); ++} ++ ++ ++static struct platform_driver snd_rpi_hifiberry_amp_driver = { ++ .driver = { ++ .name = "snd-hifiberry-amp", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_amp_of_match, ++ }, ++ .probe = snd_rpi_hifiberry_amp_probe, ++ .remove = snd_rpi_hifiberry_amp_remove, ++}; ++ ++ ++module_platform_driver(snd_rpi_hifiberry_amp_driver); ++ ++ ++MODULE_AUTHOR("Sebastian Eickhoff "); ++MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index dc3df1a..8a9f07c 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -109,6 +109,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_TFA9879 if I2C + select SND_SOC_TLV320AIC23_I2C if I2C + select SND_SOC_TLV320AIC23_SPI if SPI_MASTER ++ select SND_SOC_TAS5713 if I2C + select SND_SOC_TLV320AIC26 if SPI_MASTER + select SND_SOC_TLV320AIC31XX if I2C + select SND_SOC_TLV320AIC32X4 if I2C +@@ -623,6 +624,9 @@ config SND_SOC_TFA9879 + tristate "NXP Semiconductors TFA9879 amplifier" + depends on I2C + ++config SND_SOC_TAS5713 ++ tristate ++ + config SND_SOC_TLV320AIC23 + tristate + +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index c1f6ba6..8ebf7f1 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -109,6 +109,7 @@ snd-soc-sta529-objs := sta529.o + snd-soc-stac9766-objs := stac9766.o + snd-soc-tas5086-objs := tas5086.o + snd-soc-tfa9879-objs := tfa9879.o ++snd-soc-tas5713-objs := tas5713.o + snd-soc-tlv320aic23-objs := tlv320aic23.o + snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o + snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o +@@ -293,6 +294,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o + obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o + obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o + obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o ++obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o + obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o + obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o + obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o +diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c +new file mode 100644 +index 0000000..9b27138 +--- /dev/null ++++ b/sound/soc/codecs/tas5713.c +@@ -0,0 +1,369 @@ ++/* ++ * ASoC Driver for TAS5713 ++ * ++ * Author: Sebastian Eickhoff ++ * Copyright 2014 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "tas5713.h" ++ ++ ++static struct i2c_client *i2c; ++ ++struct tas5713_priv { ++ struct regmap *regmap; ++ int mclk_div; ++ struct snd_soc_codec *codec; ++}; ++ ++static struct tas5713_priv *priv_data; ++ ++ ++ ++ ++/* ++ * _ _ ___ _ ___ _ _ ++ * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___ ++ * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-< ++ * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/ ++ * ++ */ ++ ++static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1); ++ ++ ++static const struct snd_kcontrol_new tas5713_snd_controls[] = { ++ SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv), ++ SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv) ++}; ++ ++ ++ ++ ++/* ++ * __ __ _ _ ___ _ ++ * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _ ++ * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_| ++ * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_| ++ * ++ */ ++ ++static int tas5713_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ u16 blen = 0x00; ++ ++ struct snd_soc_codec *codec; ++ codec = dai->codec; ++ priv_data->codec = dai->codec; ++ ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ blen = 0x03; ++ break; ++ case SNDRV_PCM_FORMAT_S20_3LE: ++ blen = 0x1; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ blen = 0x04; ++ break; ++ case SNDRV_PCM_FORMAT_S32_LE: ++ blen = 0x05; ++ break; ++ default: ++ dev_err(dai->dev, "Unsupported word length: %u\n", ++ params_format(params)); ++ return -EINVAL; ++ } ++ ++ // set word length ++ snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen); ++ ++ return 0; ++} ++ ++ ++static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream) ++{ ++ unsigned int val = 0; ++ ++ struct tas5713_priv *tas5713; ++ struct snd_soc_codec *codec = dai->codec; ++ tas5713 = snd_soc_codec_get_drvdata(codec); ++ ++ if (mute) { ++ val = TAS5713_SOFT_MUTE_ALL; ++ } ++ ++ return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val); ++} ++ ++ ++static const struct snd_soc_dai_ops tas5713_dai_ops = { ++ .hw_params = tas5713_hw_params, ++ .mute_stream = tas5713_mute_stream, ++}; ++ ++ ++static struct snd_soc_dai_driver tas5713_dai = { ++ .name = "tas5713-hifi", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_48000, ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ), ++ }, ++ .ops = &tas5713_dai_ops, ++}; ++ ++ ++ ++ ++/* ++ * ___ _ ___ _ ++ * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _ ++ * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_| ++ * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_| ++ * ++ */ ++ ++static int tas5713_remove(struct snd_soc_codec *codec) ++{ ++ struct tas5713_priv *tas5713; ++ ++ tas5713 = snd_soc_codec_get_drvdata(codec); ++ ++ return 0; ++} ++ ++ ++static int tas5713_probe(struct snd_soc_codec *codec) ++{ ++ struct tas5713_priv *tas5713; ++ int i, ret; ++ ++ i2c = container_of(codec->dev, struct i2c_client, dev); ++ ++ tas5713 = snd_soc_codec_get_drvdata(codec); ++ ++ // Reset error ++ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); ++ if (ret < 0) return ret; ++ ++ // Trim oscillator ++ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); ++ if (ret < 0) return ret; ++ msleep(1000); ++ ++ // Reset error ++ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); ++ if (ret < 0) return ret; ++ ++ // Clock mode: 44/48kHz, MCLK=64xfs ++ ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); ++ if (ret < 0) return ret; ++ ++ // I2S 24bit ++ ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); ++ if (ret < 0) return ret; ++ ++ // Unmute ++ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); ++ if (ret < 0) return ret; ++ ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); ++ if (ret < 0) return ret; ++ ++ // Set volume to 0db ++ ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); ++ if (ret < 0) return ret; ++ ++ // Now start programming the default initialization sequence ++ for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { ++ ret = i2c_master_send(i2c, ++ tas5713_init_sequence[i].data, ++ tas5713_init_sequence[i].size); ++ if (ret < 0) { ++ printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); ++ } ++ } ++ ++ // Unmute ++ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); ++ if (ret < 0) return ret; ++ ++ return 0; ++} ++ ++ ++static struct snd_soc_codec_driver soc_codec_dev_tas5713 = { ++ .probe = tas5713_probe, ++ .remove = tas5713_remove, ++ .controls = tas5713_snd_controls, ++ .num_controls = ARRAY_SIZE(tas5713_snd_controls), ++}; ++ ++ ++ ++ ++/* ++ * ___ ___ ___ ___ _ ++ * |_ _|_ ) __| | \ _ _(_)_ _____ _ _ ++ * | | / / (__ | |) | '_| \ V / -_) '_| ++ * |___/___\___| |___/|_| |_|\_/\___|_| ++ * ++ */ ++ ++static const struct reg_default tas5713_reg_defaults[] = { ++ { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB ++ { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB ++ { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB ++ { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB ++}; ++ ++ ++static bool tas5713_reg_volatile(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case TAS5713_DEVICE_ID: ++ case TAS5713_ERROR_STATUS: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++ ++static const struct of_device_id tas5713_of_match[] = { ++ { .compatible = "ti,tas5713", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, tas5713_of_match); ++ ++ ++static struct regmap_config tas5713_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ ++ .max_register = TAS5713_MAX_REGISTER, ++ .volatile_reg = tas5713_reg_volatile, ++ ++ .cache_type = REGCACHE_RBTREE, ++ .reg_defaults = tas5713_reg_defaults, ++ .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults), ++}; ++ ++ ++static int tas5713_i2c_probe(struct i2c_client *i2c, ++ const struct i2c_device_id *id) ++{ ++ int ret; ++ ++ priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL); ++ if (!priv_data) ++ return -ENOMEM; ++ ++ priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config); ++ if (IS_ERR(priv_data->regmap)) { ++ ret = PTR_ERR(priv_data->regmap); ++ return ret; ++ } ++ ++ i2c_set_clientdata(i2c, priv_data); ++ ++ ret = snd_soc_register_codec(&i2c->dev, ++ &soc_codec_dev_tas5713, &tas5713_dai, 1); ++ ++ return ret; ++} ++ ++ ++static int tas5713_i2c_remove(struct i2c_client *i2c) ++{ ++ snd_soc_unregister_codec(&i2c->dev); ++ i2c_set_clientdata(i2c, NULL); ++ ++ kfree(priv_data); ++ ++ return 0; ++} ++ ++ ++static const struct i2c_device_id tas5713_i2c_id[] = { ++ { "tas5713", 0 }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id); ++ ++ ++static struct i2c_driver tas5713_i2c_driver = { ++ .driver = { ++ .name = "tas5713", ++ .owner = THIS_MODULE, ++ .of_match_table = tas5713_of_match, ++ }, ++ .probe = tas5713_i2c_probe, ++ .remove = tas5713_i2c_remove, ++ .id_table = tas5713_i2c_id ++}; ++ ++ ++static int __init tas5713_modinit(void) ++{ ++ int ret = 0; ++ ++ ret = i2c_add_driver(&tas5713_i2c_driver); ++ if (ret) { ++ printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n", ++ ret); ++ } ++ ++ return ret; ++} ++module_init(tas5713_modinit); ++ ++ ++static void __exit tas5713_exit(void) ++{ ++ i2c_del_driver(&tas5713_i2c_driver); ++} ++module_exit(tas5713_exit); ++ ++ ++MODULE_AUTHOR("Sebastian Eickhoff "); ++MODULE_DESCRIPTION("ASoC driver for TAS5713"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/tas5713.h b/sound/soc/codecs/tas5713.h +new file mode 100644 +index 0000000..8f019e0 +--- /dev/null ++++ b/sound/soc/codecs/tas5713.h +@@ -0,0 +1,210 @@ ++/* ++ * ASoC Driver for TAS5713 ++ * ++ * Author: Sebastian Eickhoff ++ * Copyright 2014 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef _TAS5713_H ++#define _TAS5713_H ++ ++ ++// TAS5713 I2C-bus register addresses ++ ++#define TAS5713_CLOCK_CTRL 0x00 ++#define TAS5713_DEVICE_ID 0x01 ++#define TAS5713_ERROR_STATUS 0x02 ++#define TAS5713_SYSTEM_CTRL1 0x03 ++#define TAS5713_SERIAL_DATA_INTERFACE 0x04 ++#define TAS5713_SYSTEM_CTRL2 0x05 ++#define TAS5713_SOFT_MUTE 0x06 ++#define TAS5713_VOL_MASTER 0x07 ++#define TAS5713_VOL_CH1 0x08 ++#define TAS5713_VOL_CH2 0x09 ++#define TAS5713_VOL_HEADPHONE 0x0A ++#define TAS5713_VOL_CONFIG 0x0E ++#define TAS5713_MODULATION_LIMIT 0x10 ++#define TAS5713_IC_DLY_CH1 0x11 ++#define TAS5713_IC_DLY_CH2 0x12 ++#define TAS5713_IC_DLY_CH3 0x13 ++#define TAS5713_IC_DLY_CH4 0x14 ++ ++#define TAS5713_START_STOP_PERIOD 0x1A ++#define TAS5713_OSC_TRIM 0x1B ++#define TAS5713_BKND_ERR 0x1C ++ ++#define TAS5713_INPUT_MUX 0x20 ++#define TAS5713_SRC_SELECT_CH4 0x21 ++#define TAS5713_PWM_MUX 0x25 ++ ++#define TAS5713_CH1_BQ0 0x29 ++#define TAS5713_CH1_BQ1 0x2A ++#define TAS5713_CH1_BQ2 0x2B ++#define TAS5713_CH1_BQ3 0x2C ++#define TAS5713_CH1_BQ4 0x2D ++#define TAS5713_CH1_BQ5 0x2E ++#define TAS5713_CH1_BQ6 0x2F ++#define TAS5713_CH1_BQ7 0x58 ++#define TAS5713_CH1_BQ8 0x59 ++ ++#define TAS5713_CH2_BQ0 0x30 ++#define TAS5713_CH2_BQ1 0x31 ++#define TAS5713_CH2_BQ2 0x32 ++#define TAS5713_CH2_BQ3 0x33 ++#define TAS5713_CH2_BQ4 0x34 ++#define TAS5713_CH2_BQ5 0x35 ++#define TAS5713_CH2_BQ6 0x36 ++#define TAS5713_CH2_BQ7 0x5C ++#define TAS5713_CH2_BQ8 0x5D ++ ++#define TAS5713_CH4_BQ0 0x5A ++#define TAS5713_CH4_BQ1 0x5B ++#define TAS5713_CH3_BQ0 0x5E ++#define TAS5713_CH3_BQ1 0x5F ++ ++#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B ++#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C ++#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E ++#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F ++#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40 ++#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43 ++#define TAS5713_DRC_CTRL 0x46 ++ ++#define TAS5713_BANK_SW_CTRL 0x50 ++#define TAS5713_CH1_OUTPUT_MIXER 0x51 ++#define TAS5713_CH2_OUTPUT_MIXER 0x52 ++#define TAS5713_CH1_INPUT_MIXER 0x53 ++#define TAS5713_CH2_INPUT_MIXER 0x54 ++#define TAS5713_OUTPUT_POST_SCALE 0x56 ++#define TAS5713_OUTPUT_PRESCALE 0x57 ++ ++#define TAS5713_IDF_POST_SCALE 0x62 ++ ++#define TAS5713_CH1_INLINE_MIXER 0x70 ++#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71 ++#define TAS5713_CH1_R_CHANNEL_MIXER 0x72 ++#define TAS5713_CH1_L_CHANNEL_MIXER 0x73 ++#define TAS5713_CH2_INLINE_MIXER 0x74 ++#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75 ++#define TAS5713_CH2_L_CHANNEL_MIXER 0x76 ++#define TAS5713_CH2_R_CHANNEL_MIXER 0x77 ++ ++#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8 ++#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9 ++ ++#define TAS5713_REGISTER_COUNT 0x46 ++#define TAS5713_MAX_REGISTER 0xF9 ++ ++ ++// Bitmasks for registers ++#define TAS5713_SOFT_MUTE_ALL 0x07 ++ ++ ++ ++struct tas5713_init_command { ++ const int size; ++ const char *const data; ++}; ++ ++static const struct tas5713_init_command tas5713_init_sequence[] = { ++ ++ // Trim oscillator ++ { .size = 2, .data = "\x1B\x00" }, ++ // System control register 1 (0x03): block DC ++ { .size = 2, .data = "\x03\x80" }, ++ // Mute everything ++ { .size = 2, .data = "\x05\x40" }, ++ // Modulation limit register (0x10): 97.7% ++ { .size = 2, .data = "\x10\x02" }, ++ // Interchannel delay registers ++ // (0x11, 0x12, 0x13, and 0x14): BD mode ++ { .size = 2, .data = "\x11\xB8" }, ++ { .size = 2, .data = "\x12\x60" }, ++ { .size = 2, .data = "\x13\xA0" }, ++ { .size = 2, .data = "\x14\x48" }, ++ // PWM shutdown group register (0x19): no shutdown ++ { .size = 2, .data = "\x19\x00" }, ++ // Input multiplexer register (0x20): BD mode ++ { .size = 2, .data = "\x20\x00\x89\x77\x72" }, ++ // PWM output mux register (0x25) ++ // Channel 1 --> OUTA, channel 1 neg --> OUTB ++ // Channel 2 --> OUTC, channel 2 neg --> OUTD ++ { .size = 5, .data = "\x25\x01\x02\x13\x45" }, ++ // DRC control (0x46): DRC off ++ { .size = 5, .data = "\x46\x00\x00\x00\x00" }, ++ // BKND_ERR register (0x1C): 299ms reset period ++ { .size = 2, .data = "\x1C\x07" }, ++ // Mute channel 3 ++ { .size = 2, .data = "\x0A\xFF" }, ++ // Volume configuration register (0x0E): volume slew 512 steps ++ { .size = 2, .data = "\x0E\x90" }, ++ // Clock control register (0x00): 44/48kHz, MCLK=64xfs ++ { .size = 2, .data = "\x00\x60" }, ++ // Bank switch and eq control (0x50): no bank switching ++ { .size = 5, .data = "\x50\x00\x00\x00\x00" }, ++ // Volume registers (0x07, 0x08, 0x09, 0x0A) ++ { .size = 2, .data = "\x07\x20" }, ++ { .size = 2, .data = "\x08\x30" }, ++ { .size = 2, .data = "\x09\x30" }, ++ { .size = 2, .data = "\x0A\xFF" }, ++ // 0x72, 0x73, 0x76, 0x77 input mixer: ++ // no intermix between channels ++ { .size = 5, .data = "\x72\x00\x00\x00\x00" }, ++ { .size = 5, .data = "\x73\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x76\x00\x00\x00\x00" }, ++ { .size = 5, .data = "\x77\x00\x80\x00\x00" }, ++ // 0x70, 0x71, 0x74, 0x75 inline DRC mixer: ++ // no inline DRC inmix ++ { .size = 5, .data = "\x70\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x71\x00\x00\x00\x00" }, ++ { .size = 5, .data = "\x74\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x75\x00\x00\x00\x00" }, ++ // 0x56, 0x57 Output scale ++ { .size = 5, .data = "\x56\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x57\x00\x02\x00\x00" }, ++ // 0x3B, 0x3c ++ { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" }, ++ { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" }, ++ { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ // 0x51, 0x52: output mixer ++ { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" }, ++ { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" }, ++ // PEQ defaults ++ { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++}; ++ ++ ++#endif /* _TAS5713_H */ + +From 06c9b132b1340b495048f8814be13fe71b5cd77e Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 13 Apr 2015 19:14:18 +0100 +Subject: [PATCH 50/77] bcm2708: Allow option card devices to be configured via + DT + +If the kernel is built with Device Tree support, and if a DT blob +is provided for the kernel at boot time, then the platform devices +for option cards are not created. This avoids both the need to +blacklist unwanted devices, and the need to update the board +support code with each new device. +--- + sound/soc/bcm/bcm2835-i2s.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 03fa1cb..c816526 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { + { .compatible = "brcm,bcm2835-i2s", }, + {}, + }; ++MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); + + static struct platform_driver bcm2835_i2s_driver = { + .probe = bcm2835_i2s_probe, + +From a9fff3c9005e6658977bd5e7df92114e70e1f813 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 13 Apr 2015 18:45:39 +0100 +Subject: [PATCH 51/77] Adding Device Tree support for some RPi audio cards + +--- + arch/arm/mach-bcm2709/bcm2709.c | 143 ++++++++++++++++++++++++++++++++++++++ + sound/soc/bcm/hifiberry_dac.c | 22 ++++++ + sound/soc/bcm/hifiberry_dacplus.c | 22 ++++++ + sound/soc/bcm/hifiberry_digi.c | 22 ++++++ + sound/soc/bcm/iqaudio-dac.c | 16 +++++ + sound/soc/codecs/pcm5102a.c | 7 ++ + 6 files changed, 232 insertions(+) + +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 03e208b..2ae79d9 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -636,6 +636,115 @@ static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++static struct resource bcm2708_i2s_resources[] = { ++ { ++ .start = I2S_BASE, ++ .end = I2S_BASE + 0x20, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = PCM_CLOCK_BASE, ++ .end = PCM_CLOCK_BASE + 0x02, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device bcm2708_i2s_device = { ++ .name = "bcm2708-i2s", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), ++ .resource = bcm2708_i2s_resources, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++static struct platform_device snd_hifiberry_dac_device = { ++ .name = "snd-hifiberry-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm5102a_codec_device = { ++ .name = "pcm5102a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++static struct platform_device snd_rpi_hifiberry_dacplus_device = { ++ .name = "snd-rpi-hifiberry-dacplus", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4d) ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++static struct platform_device snd_hifiberry_digi_device = { ++ .name = "snd-hifiberry-digi", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("wm8804", 0x3b) ++ }, ++}; ++ ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++static struct platform_device snd_hifiberry_amp_device = { ++ .name = "snd-hifiberry-amp", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("tas5713", 0x1b) ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++static struct platform_device snd_rpi_dac_device = { ++ .name = "snd-rpi-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm1794a_codec_device = { ++ .name = "pcm1794a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ ++ ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++static struct platform_device snd_rpi_iqaudio_dac_device = { ++ .name = "snd-rpi-iqaudio-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++// Use the actual device name rather than generic driver name ++static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4c) ++ }, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -800,6 +909,40 @@ void __init bcm2709_init(void) + + bcm_register_device_dt(&bcm2835_thermal_device); + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++ bcm_register_device_dt(&bcm2708_i2s_device); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_digi_device); ++ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_amp_device); ++ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_dac_device); ++ bcm_register_device_dt(&snd_pcm1794a_codec_device); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c +index 4b70b45..3ab0f47 100644 +--- a/sound/soc/bcm/hifiberry_dac.c ++++ b/sound/soc/bcm/hifiberry_dac.c +@@ -72,6 +72,21 @@ static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_hifiberry_dac.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dac_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); +@@ -84,10 +99,17 @@ static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) + return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); + } + ++static const struct of_device_id snd_rpi_hifiberry_dac_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-dac", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dac_of_match); ++ + static struct platform_driver snd_rpi_hifiberry_dac_driver = { + .driver = { + .name = "snd-hifiberry-dac", + .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_dac_of_match, + }, + .probe = snd_rpi_hifiberry_dac_probe, + .remove = snd_rpi_hifiberry_dac_remove, +diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c +index c63387b..11e4f39 100644 +--- a/sound/soc/bcm/hifiberry_dacplus.c ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -90,6 +90,21 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_hifiberry_dacplus.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); + if (ret) + dev_err(&pdev->dev, +@@ -103,10 +118,17 @@ static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) + return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); + } + ++static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-dacplus", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match); ++ + static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { + .driver = { + .name = "snd-rpi-hifiberry-dacplus", + .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_dacplus_of_match, + }, + .probe = snd_rpi_hifiberry_dacplus_probe, + .remove = snd_rpi_hifiberry_dacplus_remove, +diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c +index 92e9e46..80732b8 100644 +--- a/sound/soc/bcm/hifiberry_digi.c ++++ b/sound/soc/bcm/hifiberry_digi.c +@@ -173,6 +173,21 @@ static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_hifiberry_digi.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_digi_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); +@@ -185,10 +200,17 @@ static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) + return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); + } + ++static const struct of_device_id snd_rpi_hifiberry_digi_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-digi", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_digi_of_match); ++ + static struct platform_driver snd_rpi_hifiberry_digi_driver = { + .driver = { + .name = "snd-hifiberry-digi", + .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_digi_of_match, + }, + .probe = snd_rpi_hifiberry_digi_probe, + .remove = snd_rpi_hifiberry_digi_remove, +diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c +index aff7377..a38e874 100644 +--- a/sound/soc/bcm/iqaudio-dac.c ++++ b/sound/soc/bcm/iqaudio-dac.c +@@ -82,6 +82,21 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_iqaudio_dac.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); + if (ret) + dev_err(&pdev->dev, +@@ -99,6 +114,7 @@ static const struct of_device_id iqaudio_of_match[] = { + { .compatible = "iqaudio,iqaudio-dac", }, + {}, + }; ++MODULE_DEVICE_TABLE(of, iqaudio_of_match); + + static struct platform_driver snd_rpi_iqaudio_dac_driver = { + .driver = { +diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c +index 126f1e9..7c6598e 100644 +--- a/sound/soc/codecs/pcm5102a.c ++++ b/sound/soc/codecs/pcm5102a.c +@@ -47,12 +47,19 @@ static int pcm5102a_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id pcm5102a_of_match[] = { ++ { .compatible = "ti,pcm5102a", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, pcm5102a_of_match); ++ + static struct platform_driver pcm5102a_codec_driver = { + .probe = pcm5102a_probe, + .remove = pcm5102a_remove, + .driver = { + .name = "pcm5102a-codec", + .owner = THIS_MODULE, ++ .of_match_table = pcm5102a_of_match, + }, + }; + + +From 9518bd237c4fb516a0ec78f7ec81e5784f8425e0 Mon Sep 17 00:00:00 2001 +From: Timo Kokkonen +Date: Wed, 29 Oct 2014 23:30:30 -0700 +Subject: [PATCH 52/77] Added support to reserve/enable a GPIO pin to be used + from pps-gpio module (LinuxPPS). Enable PPS modules in default config for + RPi. + +--- + arch/arm/mach-bcm2708/bcm2708.c | 27 +++++++++++++++++++++++++++ + arch/arm/mach-bcm2709/bcm2709.c | 27 +++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 785cf1a..e42f5a5 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -92,6 +93,7 @@ static unsigned reboot_part = 0; + static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; ++static int pps_gpio_pin = -1; + + static unsigned use_dt = 0; + +@@ -325,6 +327,19 @@ static struct platform_device w1_device = { + }; + #endif + ++static struct pps_gpio_platform_data pps_gpio_info = { ++ .assert_falling_edge = false, ++ .capture_clear = false, ++ .gpio_pin = -1, ++ .gpio_label = "PPS", ++}; ++ ++static struct platform_device pps_gpio_device = { ++ .name = "pps-gpio", ++ .id = PLATFORM_DEVID_NONE, ++ .dev.platform_data = &pps_gpio_info, ++}; ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -860,6 +875,16 @@ void __init bcm2708_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++ ++#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) ++ if (!use_dt && (pps_gpio_pin >= 0)) { ++ pr_info("bcm2708: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); ++ pps_gpio_info.gpio_pin = pps_gpio_pin; ++ pps_gpio_device.id = pps_gpio_pin; ++ bcm_register_device(&pps_gpio_device); ++ } ++#endif ++ + #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + w1_gpio_pdata.pin = w1_gpio_pin; + w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; +@@ -1116,3 +1141,5 @@ module_param(w1_gpio_pin, uint, 0644); + module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); ++module_param(pps_gpio_pin, int, 0644); ++MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 2ae79d9..95223ff 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -94,6 +95,7 @@ static unsigned reboot_part = 0; + static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; ++static int pps_gpio_pin = -1; + + static unsigned use_dt = 0; + +@@ -335,6 +337,19 @@ static struct platform_device w1_device = { + }; + #endif + ++static struct pps_gpio_platform_data pps_gpio_info = { ++ .assert_falling_edge = false, ++ .capture_clear = false, ++ .gpio_pin = -1, ++ .gpio_label = "PPS", ++}; ++ ++static struct platform_device pps_gpio_device = { ++ .name = "pps-gpio", ++ .id = PLATFORM_DEVID_NONE, ++ .dev.platform_data = &pps_gpio_info, ++}; ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -880,6 +895,16 @@ void __init bcm2709_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++ ++#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) ++ if (!use_dt && (pps_gpio_pin >= 0)) { ++ pr_info("bcm2709: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); ++ pps_gpio_info.gpio_pin = pps_gpio_pin; ++ pps_gpio_device.id = pps_gpio_pin; ++ bcm_register_device(&pps_gpio_device); ++ } ++#endif ++ + #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + w1_gpio_pdata.pin = w1_gpio_pin; + w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; +@@ -1284,3 +1309,5 @@ module_param(w1_gpio_pin, uint, 0644); + module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); ++module_param(pps_gpio_pin, int, 0644); ++MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); + +From 6831eded602a01774036cb24d3195dbbd51f9135 Mon Sep 17 00:00:00 2001 +From: Ryan Coe +Date: Sat, 31 Jan 2015 18:25:49 -0700 +Subject: [PATCH 53/77] Update ds1307 driver for device-tree support + +Signed-off-by: Ryan Coe +--- + drivers/rtc/rtc-ds1307.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c +index 4ffabb3..c6789a7 100644 +--- a/drivers/rtc/rtc-ds1307.c ++++ b/drivers/rtc/rtc-ds1307.c +@@ -1242,6 +1242,14 @@ static int ds1307_remove(struct i2c_client *client) + return 0; + } + ++#ifdef CONFIG_OF ++static const struct of_device_id ds1307_of_match[] = { ++ { .compatible = "maxim,ds1307" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, ds1307_of_match); ++#endif ++ + static struct i2c_driver ds1307_driver = { + .driver = { + .name = "rtc-ds1307", + +From 47ca2482bc03a888435d35139cd2f5989354ee1b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 6 Feb 2015 13:50:57 +0000 +Subject: [PATCH 54/77] BCM270x_DT: Add pwr_led, and the required "input" + trigger + +The "input" trigger makes the associated GPIO an input. This is to support +the Raspberry Pi PWR LED, which is driven by external hardware in normal use. + +N.B. pwr_led is not available on Model A or B boards. +--- + drivers/leds/trigger/Kconfig | 7 ++++ + drivers/leds/trigger/Makefile | 1 + + drivers/leds/trigger/ledtrig-input.c | 65 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 73 insertions(+) + create mode 100644 drivers/leds/trigger/ledtrig-input.c + diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig index 49794b4..640756b 100644 --- a/drivers/leds/trigger/Kconfig @@ -124668,10 +127463,10 @@ index 0000000..2ca2b98 +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); -From be825a324f0b4e90f3fc396b0ed17442c5cb771d Mon Sep 17 00:00:00 2001 +From 38c278bba1388423ba1508d0712babb717685530 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 20 Jun 2014 17:19:27 +0100 -Subject: [PATCH 072/216] bcm2709: Simplify and strip down IRQ handler +Subject: [PATCH 55/77] bcm2709: Simplify and strip down IRQ handler --- arch/arm/include/asm/entry-macro-multi.S | 2 + @@ -124890,737 +127685,10 @@ index d08591b..08d184c 100644 +1: get_irqnr_and_base r0, r2, r6, lr + .endm -From 219ae1b83de018ba2a3e3d909c0cbfce14579c14 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Tue, 3 Feb 2015 07:15:19 +0100 -Subject: [PATCH 073/216] HiFiBerry Amp: fix device-tree problems - -Some code to load the driver based on device-tree-overlays was missing. This is added by this patch. ---- - sound/soc/bcm/hifiberry_amp.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c -index 1e87ee06..5903915 100644 ---- a/sound/soc/bcm/hifiberry_amp.c -+++ b/sound/soc/bcm/hifiberry_amp.c -@@ -65,6 +65,12 @@ static struct snd_soc_card snd_rpi_hifiberry_amp = { - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), - }; - -+static const struct of_device_id snd_rpi_hifiberry_amp_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-amp", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_amp_of_match); -+ - - static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) - { -@@ -72,6 +78,20 @@ static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) - - snd_rpi_hifiberry_amp.dev = &pdev->dev; - -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_amp_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_amp); - - if (ret != 0) { -@@ -92,6 +112,7 @@ static struct platform_driver snd_rpi_hifiberry_amp_driver = { - .driver = { - .name = "snd-hifiberry-amp", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_amp_of_match, - }, - .probe = snd_rpi_hifiberry_amp_probe, - .remove = snd_rpi_hifiberry_amp_remove, - -From 81042a79740e7b0c61fcbfa97e76c3d97c40b630 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 3 Feb 2015 11:41:38 +0000 -Subject: [PATCH 074/216] BCM270x_DT: Add i2c0_baudrate and i2c1_baudrate - parameters - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index b409c2c..7f84473 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -103,6 +103,8 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 1ecd1a1..a39562f 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -97,6 +97,8 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 46f4908..75c222f 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -103,6 +103,8 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - -From 4ff8b4c54db8215c8daa7a1d70c623b642143f16 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 4 Feb 2015 10:02:24 +0000 -Subject: [PATCH 075/216] pinctrl-bcm2835: bcm2835_gpio_direction_output must - set the value - ---- - drivers/pinctrl/pinctrl-bcm2835.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index 9d1149e..d9c727b 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -355,7 +355,14 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) - static int bcm2835_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) - { -- return pinctrl_gpio_direction_output(chip->base + offset); -+ struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); -+ int ret; -+ -+ ret = pinctrl_gpio_direction_output(chip->base + offset); -+ if (ret >= 0) -+ bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset); -+ -+ return ret; - } - - static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) - -From 1184251f953b0cd578ee44fa36d67f7f9091e6a5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 4 Feb 2015 12:59:36 +0000 -Subject: [PATCH 076/216] w1-gpio: Sort out the pullup/parasitic power tangle - ---- - arch/arm/boot/dts/w1-gpio-overlay.dts | 4 +++- - arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 6 +++-- - drivers/w1/masters/w1-gpio.c | 36 ++++++++++++++++++---------- - include/linux/w1-gpio.h | 1 + - 4 files changed, 32 insertions(+), 15 deletions(-) - -diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts -index b2c5ee2..29a3b48 100644 ---- a/arch/arm/boot/dts/w1-gpio-overlay.dts -+++ b/arch/arm/boot/dts/w1-gpio-overlay.dts -@@ -1,4 +1,4 @@ --// Definitions for lirc-rpi module -+// Definitions for w1-gpio module (without external pullup) - /dts-v1/; - /plugin/; - -@@ -14,6 +14,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&w1_pins>; - gpios = <&gpio 4 0>; -+ rpi,parasitic-power = <0>; - status = "okay"; - }; - }; -@@ -33,5 +34,6 @@ - __overrides__ { - gpiopin = <&w1>,"gpios:4", - <&w1_pins>,"brcm,pins:0"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; - }; - }; -diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -index b3e97c2..66a98f6 100644 ---- a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -+++ b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -@@ -1,4 +1,4 @@ --// Definitions for lirc-rpi module -+// Definitions for w1-gpio module (with external pullup) - /dts-v1/; - /plugin/; - -@@ -14,6 +14,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&w1_pins>; - gpios = <&gpio 4 0>, <&gpio 5 1>; -+ rpi,parasitic-power = <0>; - status = "okay"; - }; - }; -@@ -33,7 +34,8 @@ - __overrides__ { - gpiopin = <&w1>,"gpios:4", - <&w1_pins>,"brcm,pins:0"; -- pullup = <&w1>,"gpios:16", -+ extpullup = <&w1>,"gpios:16", - <&w1_pins>,"brcm,pins:4"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; - }; - }; -diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c -index 3ad15cc..e34d418 100644 ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -23,10 +23,14 @@ - #include "../w1.h" - #include "../w1_int.h" - --static int w1_gpio_pullup = -1; --static int w1_gpio_pullup_orig = -1; -+static int w1_gpio_pullup = 0; -+static int w1_gpio_pullup_orig = 0; - module_param_named(pullup, w1_gpio_pullup, int, 0); --MODULE_PARM_DESC(pullup, "GPIO pin pullup number"); -+MODULE_PARM_DESC(pullup, "Enable parasitic power (power on data) mode"); -+static int w1_gpio_pullup_pin = -1; -+static int w1_gpio_pullup_pin_orig = -1; -+module_param_named(extpullup, w1_gpio_pullup_pin, int, 0); -+MODULE_PARM_DESC(extpullup, "GPIO external pullup pin number"); - static int w1_gpio_pin = -1; - static int w1_gpio_pin_orig = -1; - module_param_named(gpiopin, w1_gpio_pin, int, 0); -@@ -99,6 +103,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; - int gpio; -+ u32 value; - - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) -@@ -107,6 +112,9 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - if (of_get_property(np, "linux,open-drain", NULL)) - pdata->is_open_drain = 1; - -+ if (of_property_read_u32(np, "rpi,parasitic-power", &value) == 0) -+ pdata->parasitic_power = (value != 0); -+ - gpio = of_get_gpio(np, 0); - if (gpio < 0) { - if (gpio != -EPROBE_DEFER) -@@ -122,7 +130,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - if (gpio == -EPROBE_DEFER) - return gpio; - /* ignore other errors as the pullup gpio is optional */ -- pdata->ext_pullup_enable_pin = gpio; -+ pdata->ext_pullup_enable_pin = (gpio >= 0) ? gpio : -1; - - pdev->dev.platform_data = pdata; - -@@ -158,17 +166,20 @@ static int w1_gpio_probe(struct platform_device *pdev) - } - - w1_gpio_pin_orig = pdata->pin; -- w1_gpio_pullup_orig = pdata->ext_pullup_enable_pin; -+ w1_gpio_pullup_pin_orig = pdata->ext_pullup_enable_pin; -+ w1_gpio_pullup_orig = pdata->parasitic_power; - - if(gpio_is_valid(w1_gpio_pin)) { - pdata->pin = w1_gpio_pin; - pdata->ext_pullup_enable_pin = -1; -+ pdata->parasitic_power = -1; - } -- if(gpio_is_valid(w1_gpio_pullup)) { -- pdata->ext_pullup_enable_pin = w1_gpio_pullup; -+ pdata->parasitic_power |= w1_gpio_pullup; -+ if(gpio_is_valid(w1_gpio_pullup_pin)) { -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin; - } - -- dev_info(&pdev->dev, "gpio pin %d, gpio pullup pin %d\n", pdata->pin, pdata->ext_pullup_enable_pin); -+ dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power); - - err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); - if (err) { -@@ -199,10 +210,10 @@ static int w1_gpio_probe(struct platform_device *pdev) - master->set_pullup = w1_gpio_set_pullup; - } - -- if (gpio_is_valid(w1_gpio_pullup)) { -+ if (pdata->parasitic_power) { - if (pdata->is_open_drain) -- printk(KERN_ERR "w1-gpio 'pullup' option " -- "doesn't work with open drain GPIO\n"); -+ printk(KERN_ERR "w1-gpio 'pullup'(parasitic power) " -+ "option doesn't work with open drain GPIO\n"); - else - master->bitbang_pullup = w1_gpio_bitbang_pullup; - } -@@ -238,7 +249,8 @@ static int w1_gpio_remove(struct platform_device *pdev) - w1_remove_master_device(master); - - pdata->pin = w1_gpio_pin_orig; -- pdata->ext_pullup_enable_pin = w1_gpio_pullup_orig; -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin_orig; -+ pdata->parasitic_power = w1_gpio_pullup_orig; - - return 0; - } -diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h -index d58594a..feae942 100644 ---- a/include/linux/w1-gpio.h -+++ b/include/linux/w1-gpio.h -@@ -18,6 +18,7 @@ - struct w1_gpio_platform_data { - unsigned int pin; - unsigned int is_open_drain:1; -+ unsigned int parasitic_power:1; - void (*enable_external_pullup)(int enable); - unsigned int ext_pullup_enable_pin; - unsigned int pullup_duration; - -From a0d0e3ba49f5daa0ece5234cdf688fb490ee15a7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 5 Feb 2015 16:01:44 +0000 -Subject: [PATCH 077/216] i2c_bcm2708: Fix clock reference counting - ---- - drivers/i2c/busses/i2c-bcm2708.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 526129b..fda59ba 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -337,11 +337,17 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - return PTR_ERR(clk); - } - -+ err = clk_prepare_enable(clk); -+ if (err) { -+ dev_err(&pdev->dev, "could not enable clk: %d\n", err); -+ goto out_clk_put; -+ } -+ - bcm2708_i2c_init_pinmode(pdev->id); - - bi = kzalloc(sizeof(*bi), GFP_KERNEL); - if (!bi) -- goto out_clk_put; -+ goto out_clk_disable; - - platform_set_drvdata(pdev, bi); - -@@ -412,6 +418,8 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - iounmap(bi->base); - out_free_bi: - kfree(bi); -+out_clk_disable: -+ clk_disable_unprepare(clk); - out_clk_put: - clk_put(clk); - return err; -@@ -426,7 +434,7 @@ static int bcm2708_i2c_remove(struct platform_device *pdev) - i2c_del_adapter(&bi->adapter); - free_irq(bi->irq, bi); - iounmap(bi->base); -- clk_disable(bi->clk); -+ clk_disable_unprepare(bi->clk); - clk_put(bi->clk); - kfree(bi); - - -From dffb6179317e46f3f2d60c62b6b4c6c1008990ef Mon Sep 17 00:00:00 2001 -From: Byron Bradley -Date: Fri, 6 Feb 2015 14:19:41 +0000 -Subject: [PATCH 078/216] Add device-tree overlay for pcf2127 - -Signed-off-by: Byron Bradley ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pcf2127-rtc-overlay.dts | 22 ++++++++++++++++++++++ - 2 files changed, 23 insertions(+) - create mode 100644 arch/arm/boot/dts/pcf2127-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 7755a84..6cb743a 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -20,6 +20,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -diff --git a/arch/arm/boot/dts/pcf2127-rtc-overlay.dts b/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -new file mode 100644 -index 0000000..01fc81d ---- /dev/null -+++ b/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF2127 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; - -From 6547e99ab9f5be7bc839f36becfc18e6dd879d0d Mon Sep 17 00:00:00 2001 -From: android -Date: Mon, 25 Aug 2014 13:18:21 +0100 -Subject: [PATCH 079/216] BCM2708_VCIO : Add automatic creation of device node - ---- - arch/arm/mach-bcm2708/vcio.c | 12 +++++++++++- - arch/arm/mach-bcm2709/vcio.c | 12 +++++++++++- - 2 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 5e43e85..700bff4 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -61,7 +61,7 @@ - #define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) - - #define MBOX_MAGIC 0xd0d0c0de -- -+static struct class *vcio_class = NULL; - struct vc_mailbox { - struct device *dev; /* parent device */ - void __iomem *status; -@@ -421,6 +421,13 @@ static int bcm_vcio_probe(struct platform_device *pdev) - "Failed registering the character device %d\n", ret); - return ret; - } -+ vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ return ret ; -+ } -+ device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); - } - return ret; - } -@@ -462,6 +469,9 @@ static int __init bcm_mbox_init(void) - - static void __exit bcm_mbox_exit(void) - { -+ device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - } - -diff --git a/arch/arm/mach-bcm2709/vcio.c b/arch/arm/mach-bcm2709/vcio.c -index 5e43e85..700bff4 100644 ---- a/arch/arm/mach-bcm2709/vcio.c -+++ b/arch/arm/mach-bcm2709/vcio.c -@@ -61,7 +61,7 @@ - #define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) - - #define MBOX_MAGIC 0xd0d0c0de -- -+static struct class *vcio_class = NULL; - struct vc_mailbox { - struct device *dev; /* parent device */ - void __iomem *status; -@@ -421,6 +421,13 @@ static int bcm_vcio_probe(struct platform_device *pdev) - "Failed registering the character device %d\n", ret); - return ret; - } -+ vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ return ret ; -+ } -+ device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); - } - return ret; - } -@@ -462,6 +469,9 @@ static int __init bcm_mbox_init(void) - - static void __exit bcm_mbox_exit(void) - { -+ device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - } - - -From 05b37dedc10f2da009b868c101623c742eda1c3f Mon Sep 17 00:00:00 2001 -From: jeanleflambeur -Date: Sun, 1 Feb 2015 12:35:38 +0100 -Subject: [PATCH 080/216] Fix grabbing lock from atomic context in i2c driver - -2 main changes: -- check for timeouts in the bcm2708_bsc_setup function as indicated by this comment: - /* poll for transfer start bit (should only take 1-20 polls) */ - This implies that the setup function can now fail so account for this everywhere it's called -- Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock. - -removed dead code and update comment - -fixed typo in comment ---- - drivers/i2c/busses/i2c-bcm2708.c | 90 +++++++++++++++++++++++++++++----------- - 1 file changed, 65 insertions(+), 25 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index fda59ba..81e9374 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -68,6 +68,7 @@ - #define BSC_S_TA 0x00000001 - - #define I2C_TIMEOUT_MS 150 -+#define I2C_WAIT_LOOP_COUNT 40 - - #define DRV_NAME "bcm2708_i2c" - -@@ -86,6 +87,7 @@ struct bcm2708_i2c { - void __iomem *base; - int irq; - struct clk *clk; -+ u32 cdiv; - - struct completion done; - -@@ -109,10 +111,10 @@ static void bcm2708_i2c_init_pinmode(int id) - int pin; - u32 *gpio = ioremap(GPIO_BASE, SZ_16K); - -- BUG_ON(id != 0 && id != 1); -+ BUG_ON(id != 0 && id != 1); - /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */ - for (pin = id*2+0; pin <= id*2+1; pin++) { --printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); -+ printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); - INP_GPIO(pin); /* set mode to GPIO input first */ - SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */ - } -@@ -151,16 +153,16 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) - bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); - } - --static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) -+static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) - { -- unsigned long bus_hz; - u32 cdiv, s; - u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; -+ int wait_loops = I2C_WAIT_LOOP_COUNT; - -- bus_hz = clk_get_rate(bi->clk); -- cdiv = bus_hz / baudrate; -- if (cdiv > 0xffff) -- cdiv = 0xffff; -+ /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked. -+ * Use the value that we cached in the probe. -+ */ -+ cdiv = bi->cdiv; - - if (bi->msg->flags & I2C_M_RD) - c |= BSC_C_INTR | BSC_C_READ; -@@ -177,17 +179,25 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) - - Both messages to same slave address - - Write message can fit inside FIFO (16 bytes or less) */ - if ( (bi->nmsgs > 1) && -- !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && -- (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { -+ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && -+ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { - /* Fill FIFO with entire write message (16 byte FIFO) */ -- while (bi->pos < bi->msg->len) -+ while (bi->pos < bi->msg->len) { - bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); -+ } - /* Start write transfer (no interrupts, don't clear FIFO) */ - bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); -+ - /* poll for transfer start bit (should only take 1-20 polls) */ - do { - s = bcm2708_rd(bi, BSC_S); -- } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE))); -+ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0); -+ -+ /* did we time out or some error occured? */ -+ if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) { -+ return -1; -+ } -+ - /* Send next read message before the write transfer finishes. */ - bi->nmsgs--; - bi->msg++; -@@ -197,6 +207,8 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) - } - } - bcm2708_wr(bi, BSC_C, c); -+ -+ return 0; - } - - static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) -@@ -204,13 +216,15 @@ static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) - struct bcm2708_i2c *bi = dev_id; - bool handled = true; - u32 s; -+ int ret; - - spin_lock(&bi->lock); - - /* we may see camera interrupts on the "other" I2C channel -- Just return if we've not sent anything */ -- if (!bi->nmsgs || !bi->msg ) -+ Just return if we've not sent anything */ -+ if (!bi->nmsgs || !bi->msg) { - goto early_exit; -+ } - - s = bcm2708_rd(bi, BSC_S); - -@@ -218,13 +232,16 @@ static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) - bcm2708_bsc_reset(bi); - bi->error = true; - -+ bi->msg = 0; /* to inform the that all work is done */ -+ bi->nmsgs = 0; - /* wake up our bh */ - complete(&bi->done); - } else if (s & BSC_S_DONE) { - bi->nmsgs--; - -- if (bi->msg->flags & I2C_M_RD) -+ if (bi->msg->flags & I2C_M_RD) { - bcm2708_bsc_fifo_drain(bi); -+ } - - bcm2708_bsc_reset(bi); - -@@ -232,8 +249,19 @@ static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) - /* advance to next message */ - bi->msg++; - bi->pos = 0; -- bcm2708_bsc_setup(bi); -+ ret = bcm2708_bsc_setup(bi); -+ if (ret < 0) { -+ bcm2708_bsc_reset(bi); -+ bi->error = true; -+ bi->msg = 0; /* to inform the that all work is done */ -+ bi->nmsgs = 0; -+ /* wake up our bh */ -+ complete(&bi->done); -+ goto early_exit; -+ } - } else { -+ bi->msg = 0; /* to inform the that all work is done */ -+ bi->nmsgs = 0; - /* wake up our bh */ - complete(&bi->done); - } -@@ -266,22 +294,33 @@ static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, - bi->nmsgs = num; - bi->error = false; - -- bcm2708_bsc_setup(bi); -+ ret = bcm2708_bsc_setup(bi); - -- /* unlockig _after_ the setup to avoid races with the interrupt routine */ - spin_unlock_irqrestore(&bi->lock, flags); - -- ret = wait_for_completion_timeout(&bi->done, -- msecs_to_jiffies(I2C_TIMEOUT_MS)); -+ /* check the result of the setup */ -+ if (ret < 0) -+ { -+ dev_err(&adap->dev, "transfer setup timed out\n"); -+ goto error_timeout; -+ } -+ -+ ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); - if (ret == 0) { - dev_err(&adap->dev, "transfer timed out\n"); -- spin_lock_irqsave(&bi->lock, flags); -- bcm2708_bsc_reset(bi); -- spin_unlock_irqrestore(&bi->lock, flags); -- return -ETIMEDOUT; -+ goto error_timeout; - } - -- return bi->error ? -EIO : num; -+ ret = bi->error ? -EIO : num; -+ return ret; -+ -+error_timeout: -+ spin_lock_irqsave(&bi->lock, flags); -+ bcm2708_bsc_reset(bi); -+ bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */ -+ bi->nmsgs = 0; -+ spin_unlock_irqrestore(&bi->lock, flags); -+ return -ETIMEDOUT; - } - - static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) -@@ -406,6 +445,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - cdiv = 0xffff; - baudrate = bus_hz / cdiv; - } -+ bi->cdiv = cdiv; - - dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", - pdev->id, (unsigned long)regs->start, irq, baudrate); - -From 2e3d8378c9031150eda4fd030b14d6c4ea762786 Mon Sep 17 00:00:00 2001 +From a69146643bae1215ab2860b9646f0f380bd3c50f Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 12 Feb 2015 11:17:53 +0000 -Subject: [PATCH 081/216] Fix LED "input" trigger implementation for 3.19 +Subject: [PATCH 56/77] Fix LED "input" trigger implementation for 3.19 --- drivers/leds/leds-gpio.c | 10 +++++++++- @@ -125629,7 +127697,7 @@ Subject: [PATCH 081/216] Fix LED "input" trigger implementation for 3.19 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index d26af0a..9e49c72 100644 +index 15eb3f8..3cfbd6a 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -41,6 +41,13 @@ static void gpio_led_work(struct work_struct *work) @@ -125693,13 +127761,13 @@ index 2ca2b98..07d1219 100644 static struct led_trigger input_led_trigger = { diff --git a/include/linux/leds.h b/include/linux/leds.h -index f70f84f..f3fcaa1 100644 +index 9a2b000..60accc5 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h -@@ -48,6 +48,9 @@ struct led_classdev { +@@ -47,6 +47,9 @@ struct led_classdev { + #define SET_BRIGHTNESS_ASYNC (1 << 21) #define SET_BRIGHTNESS_SYNC (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) - #define LED_DEV_CAP_SYNC_STROBE (1 << 24) + /* Additions for Raspberry Pi PWR LED */ +#define SET_GPIO_INPUT (1 << 30) +#define SET_GPIO_OUTPUT (1 << 31) @@ -125707,65 +127775,67 @@ index f70f84f..f3fcaa1 100644 /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ -From 9bdca5da4acd1e4893a10183c0202b2b1293b9cd Mon Sep 17 00:00:00 2001 -From: Rainer Herbers -Date: Sun, 15 Feb 2015 13:44:14 +0100 -Subject: [PATCH 082/216] Create bmp085_i2c-sensor-overlay.dts and update - Makefile +From d8f6c527b14c125e58173e8bd0e7c6c59bab4919 Mon Sep 17 00:00:00 2001 +From: notro +Date: Thu, 10 Jul 2014 13:59:47 +0200 +Subject: [PATCH 57/77] pinctrl-bcm2835: Set base to 0 give expected gpio + numbering + +Signed-off-by: Noralf Tronnes +--- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 8d908e3..7a1900d 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { + .get = bcm2835_gpio_get, + .set = bcm2835_gpio_set, + .to_irq = bcm2835_gpio_to_irq, +- .base = -1, ++ .base = 0, + .ngpio = BCM2835_NUM_GPIOS, + .can_sleep = false, + }; + +From bf8c97c74733237b219a22da649cb6cb7029615d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 4 Feb 2015 10:02:24 +0000 +Subject: [PATCH 58/77] pinctrl-bcm2835: bcm2835_gpio_direction_output must set + the value --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts | 23 +++++++++++++++++++++++ - 2 files changed, 24 insertions(+) - create mode 100644 arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 6cb743a..7946143 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 7a1900d..62f85aa 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -355,7 +355,14 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) + static int bcm2835_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int value) + { +- return pinctrl_gpio_direction_output(chip->base + offset); ++ struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); ++ int ret; ++ ++ ret = pinctrl_gpio_direction_output(chip->base + offset); ++ if (ret >= 0) ++ bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset); ++ ++ return ret; + } -+dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -new file mode 100644 -index 0000000..b830bf2 ---- /dev/null -+++ b/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -@@ -0,0 +1,23 @@ -+// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ bmp085@77 { -+ compatible = "bosch,bmp085"; -+ reg = <0x77>; -+ default-oversampling = <3>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; + static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -From 92765161f74e60edf1eb2c752f2cd3ea9d531d14 Mon Sep 17 00:00:00 2001 +From 1262602778ac5adbe798e7ace41b22262a578fcf Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Feb 2015 13:40:50 +0000 -Subject: [PATCH 083/216] pinctrl-bcm2835: Fix interrupt handling for GPIOs - 28-31 and 46-53 +Subject: [PATCH 59/77] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 + and 46-53 Contrary to the documentation, the BCM2835 GPIO controller actually has four interrupt lines - one each for the three IRQ groups and one common. Rather @@ -125781,13 +127851,13 @@ This bug has only just been observed because GPIOs above 27 can only be accessed on an old Raspberry Pi with the optional P5 header fitted, where the pins are often used for I2S instead. --- - drivers/pinctrl/pinctrl-bcm2835.c | 51 ++++++++++++++++++++++++++++++--------- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 51 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index d9c727b..ae68710 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 62f85aa..c7cf266 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -47,6 +47,7 @@ #define MODULE_NAME "pinctrl-bcm2835" #define BCM2835_NUM_GPIOS 54 @@ -125842,9 +127912,9 @@ index d9c727b..ae68710 100644 events &= pc->enabled_irq_map[bank]; for_each_set_bit(offset, &events, 32) { gpio = (32 * bank) + offset; -@@ -420,7 +420,30 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) - if (type & IRQ_TYPE_LEVEL_MASK) - bcm2835_gpio_set_bit(pc, GPEDS0, gpio); +@@ -412,7 +412,30 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) + + generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio)); } - return events ? IRQ_HANDLED : IRQ_NONE; + @@ -125874,7 +127944,7 @@ index d9c727b..ae68710 100644 } static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, -@@ -992,8 +1015,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1000,8 +1023,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for (i = 0; i < BCM2835_NUM_BANKS; i++) { unsigned long events; unsigned offset; @@ -125883,7 +127953,7 @@ index d9c727b..ae68710 100644 /* clear event detection flags */ bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0); -@@ -1008,10 +1029,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1016,10 +1037,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for_each_set_bit(offset, &events, 32) bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); @@ -125901,7 +127971,7 @@ index d9c727b..ae68710 100644 len = strlen(dev_name(pc->dev)) + 16; name = devm_kzalloc(pc->dev, len, GFP_KERNEL); -@@ -1069,6 +1095,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { +@@ -1077,6 +1103,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { .remove = bcm2835_pinctrl_remove, .driver = { .name = MODULE_NAME, @@ -125910,11 +127980,11 @@ index d9c727b..ae68710 100644 }, }; -From d1f5e57c873c1acf3be524693888af970a08f4fb Mon Sep 17 00:00:00 2001 +From fd7e740e1c83bd550444192a8beff54ea5291c50 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 084/216] pinctrl-bcm2835: Only request the interrupts listed - in the DTB +Subject: [PATCH 60/77] pinctrl-bcm2835: Only request the interrupts listed in + the DTB Although the GPIO controller can generate three interrupts (four counting the common one), the device tree files currently only specify two. In the @@ -125923,14 +127993,14 @@ registering 0), which has the effect of making it impossible to generate interrupts for GPIOs 46-53 which, since they share pins with the SD card interface, is unlikely to be a problem. --- - drivers/pinctrl/pinctrl-bcm2835.c | 2 ++ + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index ae68710..87b7a4a 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -1036,6 +1036,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index c7cf266..986779a 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -1044,6 +1044,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) int len; char *name; pc->irq[i] = irq_of_parse_and_map(np, i); @@ -125940,1282 +128010,16 @@ index ae68710..87b7a4a 100644 pc->irq_data[i].irqgroup = i; -From a10a9f8313c8fff626c82bf63608f3f00188c5db Mon Sep 17 00:00:00 2001 -From: Dave Martin -Date: Fri, 27 Feb 2015 15:51:37 +0000 -Subject: [PATCH 085/216] serial/amba-pl011: Activate TX IRQ passively - -The current PL011 driver transmits a dummy character when the UART -is opened, to assert the TX IRQ for the first time -(see pl011_startup()). The UART is put in loopback mode temporarily, -so the receiver presumably shouldn't see anything. - -However... - -At least some platforms containing a PL011 send characters down the -wire even when loopback mode is enabled. This means that a -spurious NUL character may be seen at the receiver when the PL011 is -opened through the TTY layer. - -The current code also temporarily sets the baud rate to maximum and -the character width to the minimum, to that the dummy TX completes -as quickly as possible. If this is seen by the receiver it will -result in a framing error and can knock the receiver out of sync -- -turning subsequent output into garbage until synchronisation -is reestablished. (Particularly problematic during boot with systemd.) - -To avoid spurious transmissions, this patch removes assumptions about -whether the TX IRQ will fire until at least one TX IRQ has been seen. - -Instead, the UART will unmask the TX IRQ and then slow-start via -polling and timer-based soft IRQs initially. If the TTY layer writes -enough data to fill the FIFO to the interrupt threshold in one go, -the TX IRQ should assert, at which point the driver changes to -fully interrupt-driven TX. - -In this way, the TX IRQ is activated as a side-effect instead of -being done deliberately. - -This should also mean that the driver works on the SBSA Generic -UART[1] (a cut-down PL011) without invasive changes. The Generic -UART lacks some features needed for the dummy TX approach to work -(FIFO disabling and loopback). - -[1] Server Base System Architecture (ARM-DEN-0029-v2.3) - http://infocenter.arm.com/ - (click-thru required :/) - -Signed-off-by: Dave Martin ---- - drivers/tty/serial/amba-pl011.c | 165 ++++++++++++++++++++++++++++------------ - 1 file changed, 115 insertions(+), 50 deletions(-) - -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 16ca535..c243729 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -58,6 +58,7 @@ - #include - #include - #include -+#include - - #define UART_NR 14 - -@@ -156,7 +157,9 @@ struct uart_amba_port { - unsigned int lcrh_tx; /* vendor-specific */ - unsigned int lcrh_rx; /* vendor-specific */ - unsigned int old_cr; /* state during shutdown */ -+ struct delayed_work tx_softirq_work; - bool autorts; -+ unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */ - char type[12]; - #ifdef CONFIG_DMA_ENGINE - /* DMA stuff */ -@@ -440,8 +443,9 @@ static void pl011_dma_remove(struct uart_amba_port *uap) - dma_release_channel(uap->dmarx.chan); - } - --/* Forward declare this for the refill routine */ -+/* Forward declare these for the refill routine */ - static int pl011_dma_tx_refill(struct uart_amba_port *uap); -+static void pl011_start_tx_pio(struct uart_amba_port *uap); - - /* - * The current DMA TX buffer has been sent. -@@ -479,14 +483,13 @@ static void pl011_dma_tx_callback(void *data) - return; - } - -- if (pl011_dma_tx_refill(uap) <= 0) { -+ if (pl011_dma_tx_refill(uap) <= 0) - /* - * We didn't queue a DMA buffer for some reason, but we - * have data pending to be sent. Re-enable the TX IRQ. - */ -- uap->im |= UART011_TXIM; -- writew(uap->im, uap->port.membase + UART011_IMSC); -- } -+ pl011_start_tx_pio(uap); -+ - spin_unlock_irqrestore(&uap->port.lock, flags); - } - -@@ -664,12 +667,10 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) - if (!uap->dmatx.queued) { - if (pl011_dma_tx_refill(uap) > 0) { - uap->im &= ~UART011_TXIM; -- ret = true; -- } else { -- uap->im |= UART011_TXIM; -+ writew(uap->im, uap->port.membase + -+ UART011_IMSC); -+ } else - ret = false; -- } -- writew(uap->im, uap->port.membase + UART011_IMSC); - } else if (!(uap->dmacr & UART011_TXDMAE)) { - uap->dmacr |= UART011_TXDMAE; - writew(uap->dmacr, -@@ -1208,15 +1209,24 @@ static void pl011_stop_tx(struct uart_port *port) - pl011_dma_tx_stop(uap); - } - -+static bool pl011_tx_chars(struct uart_amba_port *uap); -+ -+/* Start TX with programmed I/O only (no DMA) */ -+static void pl011_start_tx_pio(struct uart_amba_port *uap) -+{ -+ uap->im |= UART011_TXIM; -+ writew(uap->im, uap->port.membase + UART011_IMSC); -+ if (!uap->tx_irq_seen) -+ pl011_tx_chars(uap); -+} -+ - static void pl011_start_tx(struct uart_port *port) - { - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); - -- if (!pl011_dma_tx_start(uap)) { -- uap->im |= UART011_TXIM; -- writew(uap->im, uap->port.membase + UART011_IMSC); -- } -+ if (!pl011_dma_tx_start(uap)) -+ pl011_start_tx_pio(uap); - } - - static void pl011_stop_rx(struct uart_port *port) -@@ -1274,40 +1284,87 @@ __acquires(&uap->port.lock) - spin_lock(&uap->port.lock); - } - --static void pl011_tx_chars(struct uart_amba_port *uap) -+/* -+ * Transmit a character -+ * There must be at least one free entry in the TX FIFO to accept the char. -+ * -+ * Returns true if the FIFO might have space in it afterwards; -+ * returns false if the FIFO definitely became full. -+ */ -+static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) -+{ -+ writew(c, uap->port.membase + UART01x_DR); -+ uap->port.icount.tx++; -+ -+ if (likely(uap->tx_irq_seen > 1)) -+ return true; -+ -+ return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); -+} -+ -+static bool pl011_tx_chars(struct uart_amba_port *uap) - { - struct circ_buf *xmit = &uap->port.state->xmit; - int count; - -+ if (unlikely(uap->tx_irq_seen < 2)) -+ /* -+ * Initial FIFO fill level unknown: we must check TXFF -+ * after each write, so just try to fill up the FIFO. -+ */ -+ count = uap->fifosize; -+ else /* tx_irq_seen >= 2 */ -+ /* -+ * FIFO initially at least half-empty, so we can simply -+ * write half the FIFO without polling TXFF. -+ -+ * Note: the *first* TX IRQ can still race with -+ * pl011_start_tx_pio(), which can result in the FIFO -+ * being fuller than expected in that case. -+ */ -+ count = uap->fifosize >> 1; -+ -+ /* -+ * If the FIFO is full we're guaranteed a TX IRQ at some later point, -+ * and can't transmit immediately in any case: -+ */ -+ if (unlikely(uap->tx_irq_seen < 2 && -+ readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)) -+ return false; -+ - if (uap->port.x_char) { -- writew(uap->port.x_char, uap->port.membase + UART01x_DR); -- uap->port.icount.tx++; -+ pl011_tx_char(uap, uap->port.x_char); - uap->port.x_char = 0; -- return; -+ --count; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { - pl011_stop_tx(&uap->port); -- return; -+ goto done; - } - - /* If we are using DMA mode, try to send some characters. */ - if (pl011_dma_tx_irq(uap)) -- return; -+ goto done; - -- count = uap->fifosize >> 1; -- do { -- writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); -+ while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) { - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -- uap->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; -- } while (--count > 0); -+ } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uap->port); - -- if (uart_circ_empty(xmit)) -+ if (uart_circ_empty(xmit)) { - pl011_stop_tx(&uap->port); -+ goto done; -+ } -+ -+ if (unlikely(!uap->tx_irq_seen)) -+ schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout); -+ -+done: -+ return false; - } - - static void pl011_modem_status(struct uart_amba_port *uap) -@@ -1334,6 +1391,28 @@ static void pl011_modem_status(struct uart_amba_port *uap) - wake_up_interruptible(&uap->port.state->port.delta_msr_wait); - } - -+static void pl011_tx_softirq(struct work_struct *work) -+{ -+ struct delayed_work *dwork = to_delayed_work(work); -+ struct uart_amba_port *uap = -+ container_of(dwork, struct uart_amba_port, tx_softirq_work); -+ -+ spin_lock(&uap->port.lock); -+ while (pl011_tx_chars(uap)) ; -+ spin_unlock(&uap->port.lock); -+} -+ -+static void pl011_tx_irq_seen(struct uart_amba_port *uap) -+{ -+ if (likely(uap->tx_irq_seen > 1)) -+ return; -+ -+ uap->tx_irq_seen++; -+ if (uap->tx_irq_seen < 2) -+ /* first TX IRQ */ -+ cancel_delayed_work(&uap->tx_softirq_work); -+} -+ - static irqreturn_t pl011_int(int irq, void *dev_id) - { - struct uart_amba_port *uap = dev_id; -@@ -1372,8 +1451,10 @@ static irqreturn_t pl011_int(int irq, void *dev_id) - if (status & (UART011_DSRMIS|UART011_DCDMIS| - UART011_CTSMIS|UART011_RIMIS)) - pl011_modem_status(uap); -- if (status & UART011_TXIS) -+ if (status & UART011_TXIS) { -+ pl011_tx_irq_seen(uap); - pl011_tx_chars(uap); -+ } - - if (pass_counter-- == 0) - break; -@@ -1577,7 +1658,7 @@ static int pl011_startup(struct uart_port *port) - { - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); -- unsigned int cr, lcr_h, fbrd, ibrd; -+ unsigned int cr; - int retval; - - retval = pl011_hwinit(port); -@@ -1595,29 +1676,10 @@ static int pl011_startup(struct uart_port *port) - - writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); - -- /* -- * Provoke TX FIFO interrupt into asserting. Taking care to preserve -- * baud rate and data format specified by FBRD, IBRD and LCRH as the -- * UART may already be in use as a console. -- */ -- spin_lock_irq(&uap->port.lock); -- -- fbrd = readw(uap->port.membase + UART011_FBRD); -- ibrd = readw(uap->port.membase + UART011_IBRD); -- lcr_h = readw(uap->port.membase + uap->lcrh_rx); -- -- cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE; -- writew(cr, uap->port.membase + UART011_CR); -- writew(0, uap->port.membase + UART011_FBRD); -- writew(1, uap->port.membase + UART011_IBRD); -- pl011_write_lcr_h(uap, 0); -- writew(0, uap->port.membase + UART01x_DR); -- while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) -- barrier(); -+ /* Assume that TX IRQ doesn't work until we see one: */ -+ uap->tx_irq_seen = 0; - -- writew(fbrd, uap->port.membase + UART011_FBRD); -- writew(ibrd, uap->port.membase + UART011_IBRD); -- pl011_write_lcr_h(uap, lcr_h); -+ spin_lock_irq(&uap->port.lock); - - /* restore RTS and DTR */ - cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); -@@ -1672,6 +1734,8 @@ static void pl011_shutdown(struct uart_port *port) - container_of(port, struct uart_amba_port, port); - unsigned int cr; - -+ cancel_delayed_work_sync(&uap->tx_softirq_work); -+ - /* - * disable all interrupts - */ -@@ -2218,6 +2282,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) - uap->port.ops = &amba_pl011_pops; - uap->port.flags = UPF_BOOT_AUTOCONF; - uap->port.line = i; -+ INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); - pl011_dma_probe(&dev->dev, uap); - - /* Ensure interrupts from this UART are masked and cleared */ - -From 75d9fae636d84117aa46cf0c2dcc556d02d67aca Mon Sep 17 00:00:00 2001 -From: Dave Martin -Date: Wed, 1 Apr 2015 14:08:31 +0100 -Subject: [PATCH 086/216] serial/amba-pl011: Refactor and simplify TX FIFO - handling - -Commit 734745c serial/amba-pl011: Activate TX IRQ passively -adds some complexity and overhead in the form of a softirq -mechanism for transmitting in the absence of interrupts. - -This patch simplifies the code flow to reduce the reliance on -subtle behaviour and avoid fragility under future maintenance. - -To this end, the TX softirq mechanism is removed and instead -pl011_start_tx() will now simply stuff the FIFO until full -(guaranteeing future TX IRQs), or until there are no more chars -to write (in which case we don't care whether an IRQ happens). - -Signed-off-by: Dave Martin -Signed-off-by: Jakub Kicinski ---- - drivers/tty/serial/amba-pl011.c | 119 +++++++++------------------------------- - 1 file changed, 26 insertions(+), 93 deletions(-) - -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index c243729..e32f4d7 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -58,7 +58,6 @@ - #include - #include - #include --#include - - #define UART_NR 14 - -@@ -157,9 +156,7 @@ struct uart_amba_port { - unsigned int lcrh_tx; /* vendor-specific */ - unsigned int lcrh_rx; /* vendor-specific */ - unsigned int old_cr; /* state during shutdown */ -- struct delayed_work tx_softirq_work; - bool autorts; -- unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */ - char type[12]; - #ifdef CONFIG_DMA_ENGINE - /* DMA stuff */ -@@ -1209,15 +1206,14 @@ static void pl011_stop_tx(struct uart_port *port) - pl011_dma_tx_stop(uap); - } - --static bool pl011_tx_chars(struct uart_amba_port *uap); -+static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); - - /* Start TX with programmed I/O only (no DMA) */ - static void pl011_start_tx_pio(struct uart_amba_port *uap) - { - uap->im |= UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); -- if (!uap->tx_irq_seen) -- pl011_tx_chars(uap); -+ pl011_tx_chars(uap, false); - } - - static void pl011_start_tx(struct uart_port *port) -@@ -1284,87 +1280,54 @@ __acquires(&uap->port.lock) - spin_lock(&uap->port.lock); - } - --/* -- * Transmit a character -- * There must be at least one free entry in the TX FIFO to accept the char. -- * -- * Returns true if the FIFO might have space in it afterwards; -- * returns false if the FIFO definitely became full. -- */ --static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) -+static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, -+ bool from_irq) - { -+ if (unlikely(!from_irq) && -+ readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) -+ return false; /* unable to transmit character */ -+ - writew(c, uap->port.membase + UART01x_DR); - uap->port.icount.tx++; - -- if (likely(uap->tx_irq_seen > 1)) -- return true; -- -- return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); -+ return true; - } - --static bool pl011_tx_chars(struct uart_amba_port *uap) -+static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) - { - struct circ_buf *xmit = &uap->port.state->xmit; -- int count; -- -- if (unlikely(uap->tx_irq_seen < 2)) -- /* -- * Initial FIFO fill level unknown: we must check TXFF -- * after each write, so just try to fill up the FIFO. -- */ -- count = uap->fifosize; -- else /* tx_irq_seen >= 2 */ -- /* -- * FIFO initially at least half-empty, so we can simply -- * write half the FIFO without polling TXFF. -- -- * Note: the *first* TX IRQ can still race with -- * pl011_start_tx_pio(), which can result in the FIFO -- * being fuller than expected in that case. -- */ -- count = uap->fifosize >> 1; -- -- /* -- * If the FIFO is full we're guaranteed a TX IRQ at some later point, -- * and can't transmit immediately in any case: -- */ -- if (unlikely(uap->tx_irq_seen < 2 && -- readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)) -- return false; -+ int count = uap->fifosize >> 1; - - if (uap->port.x_char) { -- pl011_tx_char(uap, uap->port.x_char); -+ if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) -+ return; - uap->port.x_char = 0; - --count; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { - pl011_stop_tx(&uap->port); -- goto done; -+ return; - } - - /* If we are using DMA mode, try to send some characters. */ - if (pl011_dma_tx_irq(uap)) -- goto done; -+ return; - -- while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) { -- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -- if (uart_circ_empty(xmit)) -+ do { -+ if (likely(from_irq) && count-- == 0) - break; -- } -+ -+ if (!pl011_tx_char(uap, xmit->buf[xmit->tail], from_irq)) -+ break; -+ -+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -+ } while (!uart_circ_empty(xmit)); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uap->port); - -- if (uart_circ_empty(xmit)) { -+ if (uart_circ_empty(xmit)) - pl011_stop_tx(&uap->port); -- goto done; -- } -- -- if (unlikely(!uap->tx_irq_seen)) -- schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout); -- --done: -- return false; - } - - static void pl011_modem_status(struct uart_amba_port *uap) -@@ -1391,28 +1354,6 @@ static void pl011_modem_status(struct uart_amba_port *uap) - wake_up_interruptible(&uap->port.state->port.delta_msr_wait); - } - --static void pl011_tx_softirq(struct work_struct *work) --{ -- struct delayed_work *dwork = to_delayed_work(work); -- struct uart_amba_port *uap = -- container_of(dwork, struct uart_amba_port, tx_softirq_work); -- -- spin_lock(&uap->port.lock); -- while (pl011_tx_chars(uap)) ; -- spin_unlock(&uap->port.lock); --} -- --static void pl011_tx_irq_seen(struct uart_amba_port *uap) --{ -- if (likely(uap->tx_irq_seen > 1)) -- return; -- -- uap->tx_irq_seen++; -- if (uap->tx_irq_seen < 2) -- /* first TX IRQ */ -- cancel_delayed_work(&uap->tx_softirq_work); --} -- - static irqreturn_t pl011_int(int irq, void *dev_id) - { - struct uart_amba_port *uap = dev_id; -@@ -1451,10 +1392,8 @@ static irqreturn_t pl011_int(int irq, void *dev_id) - if (status & (UART011_DSRMIS|UART011_DCDMIS| - UART011_CTSMIS|UART011_RIMIS)) - pl011_modem_status(uap); -- if (status & UART011_TXIS) { -- pl011_tx_irq_seen(uap); -- pl011_tx_chars(uap); -- } -+ if (status & UART011_TXIS) -+ pl011_tx_chars(uap, true); - - if (pass_counter-- == 0) - break; -@@ -1676,9 +1615,6 @@ static int pl011_startup(struct uart_port *port) - - writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); - -- /* Assume that TX IRQ doesn't work until we see one: */ -- uap->tx_irq_seen = 0; -- - spin_lock_irq(&uap->port.lock); - - /* restore RTS and DTR */ -@@ -1734,8 +1670,6 @@ static void pl011_shutdown(struct uart_port *port) - container_of(port, struct uart_amba_port, port); - unsigned int cr; - -- cancel_delayed_work_sync(&uap->tx_softirq_work); -- - /* - * disable all interrupts - */ -@@ -2282,7 +2216,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) - uap->port.ops = &amba_pl011_pops; - uap->port.flags = UPF_BOOT_AUTOCONF; - uap->port.line = i; -- INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); - pl011_dma_probe(&dev->dev, uap); - - /* Ensure interrupts from this UART are masked and cleared */ - -From 29cd864c0ec9d9d593e569ee5d4fcb463d36cb35 Mon Sep 17 00:00:00 2001 -From: Jon Burgess -Date: Tue, 17 Feb 2015 13:22:17 +0000 -Subject: [PATCH 087/216] Create generic i2c-rtc overlay for supporting ds1307, - ds3231, pcf2127 and pcf8523. - -Signed-off-by: Jon Burgess ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/i2c-rtc-overlay.dts | 43 +++++++++++++++++++++++++++++++++++ - 2 files changed, 44 insertions(+) - create mode 100644 arch/arm/boot/dts/i2c-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 7946143..6753fcb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -14,6 +14,7 @@ endif - - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -diff --git a/arch/arm/boot/dts/i2c-rtc-overlay.dts b/arch/arm/boot/dts/i2c-rtc-overlay.dts -new file mode 100644 -index 0000000..5d5abb1 ---- /dev/null -+++ b/arch/arm/boot/dts/i2c-rtc-overlay.dts -@@ -0,0 +1,43 @@ -+// Definitions for several I2C based Real Time Clocks -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ ds3231: ds3231@68 { -+ compatible = "maxim,ds3231"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ pcf2127: pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "disable"; -+ }; -+ pcf8523: pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ }; -+ }; -+ __overrides__ { -+ ds1307 = <&ds1307>,"status"; -+ ds3231 = <&ds3231>,"status"; -+ pcf2127 = <&pcf2127>,"status"; -+ pcf8523 = <&pcf8523>,"status"; -+ }; -+}; - -From 600d5e0e89ecc723b7ffb29209b058d0275502e2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:24:05 +0100 -Subject: [PATCH 088/216] dts: overlay: add support for rpi-display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for rpi-display by Watterott. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/rpi-display-overlay.dts | 81 +++++++++++++++++++++++++++++++ - 2 files changed, 82 insertions(+) - create mode 100644 arch/arm/boot/dts/rpi-display-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 6753fcb..de47748 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -25,6 +25,7 @@ dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/rpi-display-overlay.dts b/arch/arm/boot/dts/rpi-display-overlay.dts -new file mode 100644 -index 0000000..0578810 ---- /dev/null -+++ b/arch/arm/boot/dts/rpi-display-overlay.dts -@@ -0,0 +1,81 @@ -+/* -+ * Device Tree overlay for rpi-display by Watterott -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ rpi_display_pins: rpi_display_pins { -+ brcm,pins = <18 23 24 25>; -+ brcm,function = <1 1 1 0>; /* out out out in */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rpidisplay: rpi-display@0{ -+ compatible = "ilitek,ili9341"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rpi_display_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ reset-gpios = <&gpio 23 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ rpidisplay_ts: rpi-display-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <25 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 25 0>; -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&rpidisplay>,"spi-max-frequency:0"; -+ rotate = <&rpidisplay>,"rotate:0"; -+ fps = <&rpidisplay>,"fps:0"; -+ debug = <&rpidisplay>,"debug:0"; -+ xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; - -From 525949ace298ff41d93fc2025ac768654e745642 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:36:27 +0100 -Subject: [PATCH 089/216] dts: overlay: add support for HY28A display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for HY28A display by HAOYU Electronics. -Default values are set to match Texy's display shield. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/hy28a-overlay.dts | 87 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 88 insertions(+) - create mode 100644 arch/arm/boot/dts/hy28a-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index de47748..8d7e535 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -19,6 +19,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -diff --git a/arch/arm/boot/dts/hy28a-overlay.dts b/arch/arm/boot/dts/hy28a-overlay.dts -new file mode 100644 -index 0000000..3cd3083 ---- /dev/null -+++ b/arch/arm/boot/dts/hy28a-overlay.dts -@@ -0,0 +1,87 @@ -+/* -+ * Device Tree overlay for HY28A display -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28a_pins: hy28a_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28a: hy28a@0{ -+ compatible = "ilitek,ili9320"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28a_pins>; -+ -+ spi-max-frequency = <32000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ hy28a_ts: hy28a-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28a>,"spi-max-frequency:0"; -+ rotate = <&hy28a>,"rotate:0"; -+ fps = <&hy28a>,"fps:0"; -+ debug = <&hy28a>,"debug:0"; -+ xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28a>,"reset-gpios:4", -+ <&hy28a_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28a>,"led-gpios:4", -+ <&hy28a_pins>, "brcm,pins:2"; -+ }; -+}; - -From 131c6ba7b078b8536755c8cae2e31c09053b5804 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:38:00 +0100 -Subject: [PATCH 090/216] dts: overlay: add support for HY28B display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for HY28B display by HAOYU Electronics. -Default values are set to match Texy's display shield. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/hy28b-overlay.dts | 142 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 143 insertions(+) - create mode 100644 arch/arm/boot/dts/hy28b-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 8d7e535..ec26431b1 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -20,6 +20,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -diff --git a/arch/arm/boot/dts/hy28b-overlay.dts b/arch/arm/boot/dts/hy28b-overlay.dts -new file mode 100644 -index 0000000..f774c4a ---- /dev/null -+++ b/arch/arm/boot/dts/hy28b-overlay.dts -@@ -0,0 +1,142 @@ -+/* -+ * Device Tree overlay for HY28b display shield by Texy -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28b_pins: hy28b_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28b: hy28b@0{ -+ compatible = "ilitek,ili9325"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28b_pins>; -+ -+ spi-max-frequency = <48000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ -+ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -+ -+ init = <0x10000e7 0x0010 -+ 0x1000000 0x0001 -+ 0x1000001 0x0100 -+ 0x1000002 0x0700 -+ 0x1000003 0x1030 -+ 0x1000004 0x0000 -+ 0x1000008 0x0207 -+ 0x1000009 0x0000 -+ 0x100000a 0x0000 -+ 0x100000c 0x0001 -+ 0x100000d 0x0000 -+ 0x100000f 0x0000 -+ 0x1000010 0x0000 -+ 0x1000011 0x0007 -+ 0x1000012 0x0000 -+ 0x1000013 0x0000 -+ 0x2000032 -+ 0x1000010 0x1590 -+ 0x1000011 0x0227 -+ 0x2000032 -+ 0x1000012 0x009c -+ 0x2000032 -+ 0x1000013 0x1900 -+ 0x1000029 0x0023 -+ 0x100002b 0x000e -+ 0x2000032 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000032 -+ 0x1000050 0x0000 -+ 0x1000051 0x00ef -+ 0x1000052 0x0000 -+ 0x1000053 0x013f -+ 0x1000060 0xa700 -+ 0x1000061 0x0001 -+ 0x100006a 0x0000 -+ 0x1000080 0x0000 -+ 0x1000081 0x0000 -+ 0x1000082 0x0000 -+ 0x1000083 0x0000 -+ 0x1000084 0x0000 -+ 0x1000085 0x0000 -+ 0x1000090 0x0010 -+ 0x1000092 0x0000 -+ 0x1000093 0x0003 -+ 0x1000095 0x0110 -+ 0x1000097 0x0000 -+ 0x1000098 0x0000 -+ 0x1000007 0x0133 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000064>; -+ debug = <0>; -+ }; -+ -+ hy28b_ts: hy28b-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28b>,"spi-max-frequency:0"; -+ rotate = <&hy28b>,"rotate:0"; -+ fps = <&hy28b>,"fps:0"; -+ debug = <&hy28b>,"debug:0"; -+ xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28b>,"reset-gpios:4", -+ <&hy28b_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28b>,"led-gpios:4", -+ <&hy28b_pins>, "brcm,pins:2"; -+ }; -+}; - -From 33ce6c6c093580873f0f54b8633f44479d31786b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:38:47 +0100 -Subject: [PATCH 091/216] dts: overlay: add support for PiScreen display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for PiScreen display by OzzMaker.com - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/piscreen-overlay.dts | 94 ++++++++++++++++++++++++++++++++++ - 2 files changed, 95 insertions(+) - create mode 100644 arch/arm/boot/dts/piscreen-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index ec26431b1..107448d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -26,6 +26,7 @@ dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -diff --git a/arch/arm/boot/dts/piscreen-overlay.dts b/arch/arm/boot/dts/piscreen-overlay.dts -new file mode 100644 -index 0000000..8cd6a95 ---- /dev/null -+++ b/arch/arm/boot/dts/piscreen-overlay.dts -@@ -0,0 +1,94 @@ -+/* -+ * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen_pins: piscreen_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen: piscreen@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c2 0x44 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 -+ 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x1000011 -+ 0x1000029>; -+ }; -+ -+ piscreen-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen>,"spi-max-frequency:0"; -+ rotate = <&piscreen>,"rotate:0"; -+ fps = <&piscreen>,"fps:0"; -+ debug = <&piscreen>,"debug:0"; -+ }; -+}; - -From 5ef8657c77133ceed5a8ddf80fed6d3002ac9dca Mon Sep 17 00:00:00 2001 +From c24fbfc7a5bc3c7cb35f51d0a40ad25b98a8a422 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Feb 2015 15:10:24 +0000 -Subject: [PATCH 092/216] enc28j60: Add device tree compatible string and an +Subject: [PATCH 61/77] enc28j60: Add device tree compatible string and an overlay --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/enc28j60-overlay.dts | 29 +++++++++++++++++++++++++++++ drivers/net/ethernet/microchip/enc28j60.c | 11 +++++++++++ - 3 files changed, 41 insertions(+) - create mode 100755 arch/arm/boot/dts/enc28j60-overlay.dts + 1 file changed, 11 insertions(+) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 107448d..81afe85 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -14,6 +14,7 @@ endif - - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/enc28j60-overlay.dts b/arch/arm/boot/dts/enc28j60-overlay.dts -new file mode 100755 -index 0000000..aa9b645 ---- /dev/null -+++ b/arch/arm/boot/dts/enc28j60-overlay.dts -@@ -0,0 +1,29 @@ -+// Overlay for the Microchip ENC28J60 Ethernet Controller -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ enc28j60@0{ -+ compatible = "microchip,enc28j60"; -+ reg = <0>; /* CE0 */ -+ spi-max-frequency = <12000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index b1b5f66..c6b6e1a 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c @@ -127243,1131 +128047,10 @@ index b1b5f66..c6b6e1a 100644 .probe = enc28j60_probe, .remove = enc28j60_remove, -From 04e8bf899200ef72d464ce9ee362d4377fbd7d87 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 27 Feb 2015 18:17:25 +0100 -Subject: [PATCH 093/216] dts: overlay: add support for Adafruit PiTFT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add DT overlay for the Adafruit PiTFT 2.8" resistive touch screen - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pitft28-resistive-overlay.dts | 115 ++++++++++++++++++++++++ - 2 files changed, 116 insertions(+) - create mode 100644 arch/arm/boot/dts/pitft28-resistive-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 81afe85..07c6eeb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -28,6 +28,7 @@ dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -diff --git a/arch/arm/boot/dts/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/pitft28-resistive-overlay.dts -new file mode 100644 -index 0000000..d506eae ---- /dev/null -+++ b/arch/arm/boot/dts/pitft28-resistive-overlay.dts -@@ -0,0 +1,115 @@ -+/* -+ * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pitft_pins: pitft_pins { -+ brcm,pins = <24 25>; -+ brcm,function = <0 1>; /* in out */ -+ brcm,pull = <2 0>; /* pullup none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pitft: pitft@0{ -+ compatible = "ilitek,ili9340"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pitft_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <90>; -+ fps = <25>; -+ bgr; -+ buswidth = <8>; -+ dc-gpios = <&gpio 25 0>; -+ debug = <0>; -+ }; -+ -+ pitft_ts@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stmpe610"; -+ reg = <1>; -+ -+ spi-max-frequency = <500000>; -+ irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ -+ interrupts = <24 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ interrupt-controller; -+ -+ stmpe_touchscreen { -+ compatible = "st,stmpe-ts"; -+ st,sample-time = <4>; -+ st,mod-12b = <1>; -+ st,ref-sel = <0>; -+ st,adc-freq = <2>; -+ st,ave-ctrl = <3>; -+ st,touch-det-delay = <4>; -+ st,settling = <2>; -+ st,fraction-z = <7>; -+ st,i-drive = <0>; -+ }; -+ -+ stmpe_gpio: stmpe_gpio { -+ #gpio-cells = <2>; -+ compatible = "st,stmpe-gpio"; -+ /* -+ * only GPIO2 is wired/available -+ * and it is wired to the backlight -+ */ -+ st,norequest-mask = <0x7b>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/soc"; -+ __overlay__ { -+ backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&stmpe_gpio 2 0>; -+ default-on; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&pitft>,"spi-max-frequency:0"; -+ rotate = <&pitft>,"rotate:0"; -+ fps = <&pitft>,"fps:0"; -+ debug = <&pitft>,"debug:0"; -+ }; -+}; - -From 917597bfd056d8d37b02a21e7ea4e56023a3e630 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 2 Mar 2015 09:37:02 +0000 -Subject: [PATCH 094/216] enable compiling spi-bcm2835 and add overlay to allow - us to load the driver - ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/spi-bcm2835-overlay.dts | 18 ++++++++++++++++++ - 2 files changed, 19 insertions(+) - create mode 100644 arch/arm/boot/dts/spi-bcm2835-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 07c6eeb..e83179f 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -33,6 +33,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -diff --git a/arch/arm/boot/dts/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/spi-bcm2835-overlay.dts -new file mode 100644 -index 0000000..fc1e39b ---- /dev/null -+++ b/arch/arm/boot/dts/spi-bcm2835-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2835-spi"; -+ }; -+ }; -+}; - -From 58f834d50fb0e6eb0f1a8c48bdb3551866addc62 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 7 Mar 2015 20:39:30 +0100 -Subject: [PATCH 095/216] dts: overlay: add support for MZ61581 display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for MZ61581 display by Tontec. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/mz61581-overlay.dts | 109 ++++++++++++++++++++++++++++++++++ - 2 files changed, 110 insertions(+) - create mode 100644 arch/arm/boot/dts/mz61581-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index e83179f..f99eccf 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -25,6 +25,7 @@ dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -diff --git a/arch/arm/boot/dts/mz61581-overlay.dts b/arch/arm/boot/dts/mz61581-overlay.dts -new file mode 100644 -index 0000000..c06fe12 ---- /dev/null -+++ b/arch/arm/boot/dts/mz61581-overlay.dts -@@ -0,0 +1,109 @@ -+/* -+ * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ mz61581_pins: mz61581_pins { -+ brcm,pins = <4 15 18 25>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mz61581: mz61581@0{ -+ compatible = "samsung,s6d02a1"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mz61581_pins>; -+ -+ spi-max-frequency = <128000000>; -+ spi-cpol; -+ spi-cpha; -+ -+ width = <320>; -+ height = <480>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ -+ reset-gpios = <&gpio 15 0>; -+ dc-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 0>; -+ -+ init = <0x10000b0 00 -+ 0x1000011 -+ 0x20000ff -+ 0x10000b3 0x02 0x00 0x00 0x00 -+ 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 -+ 0x10000c1 0x08 0x16 0x08 0x08 -+ 0x10000c4 0x11 0x07 0x03 0x03 -+ 0x10000c6 0x00 -+ 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 -+ 0x1000035 0x00 -+ 0x1000036 0xa0 -+ 0x100003a 0x55 -+ 0x1000044 0x00 0x01 -+ 0x10000d0 0x07 0x07 0x1d 0x03 -+ 0x10000d1 0x03 0x30 0x10 -+ 0x10000d2 0x03 0x14 0x04 -+ 0x1000029 -+ 0x100002c>; -+ -+ /* This is a workaround to make sure the init sequence slows down and doesn't fail */ -+ debug = <3>; -+ }; -+ -+ mz61581_ts: mz61581_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <4 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 4 0>; -+ -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&mz61581>, "spi-max-frequency:0"; -+ rotate = <&mz61581>, "rotate:0"; -+ fps = <&mz61581>, "fps:0"; -+ debug = <&mz61581>, "debug:0"; -+ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; - -From 080c66dfc13694a3c6123d6732d6255361e49733 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 7 Mar 2015 20:40:07 +0100 -Subject: [PATCH 096/216] dts: overlay: piscreen: set speed to 24MHz -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some of the displays can't handle the 32MHz speed. -Lower the default speed to 24MHz. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/piscreen-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/piscreen-overlay.dts b/arch/arm/boot/dts/piscreen-overlay.dts -index 8cd6a95..b7fd7ea 100644 ---- a/arch/arm/boot/dts/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/piscreen-overlay.dts -@@ -47,7 +47,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&piscreen_pins>; - -- spi-max-frequency = <32000000>; -+ spi-max-frequency = <24000000>; - rotate = <270>; - bgr; - fps = <30>; - -From c34aef0866b8605b64dd7b7c1bf4c1db77933089 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 7 Mar 2015 20:40:43 +0100 -Subject: [PATCH 097/216] dts: overlay: rpi-display: pullup irq gpio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -An early version of rpi-display needs the touch controller irq -to be pulled up. This is the version with 9-bit SPI as default. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/rpi-display-overlay.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/rpi-display-overlay.dts b/arch/arm/boot/dts/rpi-display-overlay.dts -index 0578810..a8fa974 100644 ---- a/arch/arm/boot/dts/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/rpi-display-overlay.dts -@@ -30,6 +30,7 @@ - rpi_display_pins: rpi_display_pins { - brcm,pins = <18 23 24 25>; - brcm,function = <1 1 1 0>; /* out out out in */ -+ brcm,pull = <0 0 0 2>; /* - - - up */ - }; - }; - }; - -From 7268b2f16833d36f6568add569f15325b398497b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 24 Mar 2015 14:48:30 +0100 -Subject: [PATCH 098/216] BCM270x_DT: add bcm2835-dma entry -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree entry for bcm2835-dma. -The entry doesn't contain any resources since they are handled -by the arch/arm/mach-bcm270x/dma.c driver. -In non-DT mode, don't add the device in the board file. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708.dtsi | 5 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 5 +++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 4 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 0713a1ed..846f148 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -17,6 +17,11 @@ - #size-cells = <1>; - ranges = <0x7e000000 0x20000000 0x01000000>; - -+ dma: dma@7e007000 { -+ compatible = "brcm,bcm2835-dma"; -+ #dma-cells = <1>; -+ }; -+ - intc: interrupt-controller { - compatible = "brcm,bcm2708-armctrl-ic"; - reg = <0x7e00b200 0x200>; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index 34d2226..d468363 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -17,6 +17,11 @@ - #size-cells = <1>; - ranges = <0x7e000000 0x3f000000 0x01000000>; - -+ dma: dma@7e007000 { -+ compatible = "brcm,bcm2835-dma"; -+ #dma-cells = <1>; -+ }; -+ - intc: interrupt-controller { - compatible = "brcm,bcm2708-armctrl-ic"; - reg = <0x7e00b200 0x200>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index c8aea5b..6a08e95 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -857,7 +857,7 @@ void __init bcm2708_init(void) - bcm2708_dt_init(); - - bcm_register_device(&bcm2708_dmaman_device); -- bcm_register_device(&bcm2708_dmaengine_device); -+ bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 259d552..3c1c1dc 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -879,7 +879,7 @@ void __init bcm2709_init(void) - bcm2709_dt_init(); - - bcm_register_device(&bcm2708_dmaman_device); -- bcm_register_device(&bcm2708_dmaengine_device); -+ bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - -From ccc2b25ac7ffe4252a482901541a1894c86bb4c3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 24 Mar 2015 14:50:19 +0100 -Subject: [PATCH 099/216] bcm270x: add mmc-bcm2835 clock -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add clock for the mmc-bcm2835.0 device. -Will be used in non-DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 1 + - arch/arm/mach-bcm2709/bcm2709.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6a08e95..b5f22e2 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -233,6 +233,7 @@ void __init bcm2708_init_clocks(void) - bcm2708_register_clkdev(clk, "dev:f1"); - - clk = bcm2708_clk_register("sdhost_clk", 250000000); -+ bcm2708_register_clkdev(clk, "mmc-bcm2835.0"); - bcm2708_register_clkdev(clk, "bcm2708_spi.0"); - bcm2708_register_clkdev(clk, "bcm2708_i2c.0"); - bcm2708_register_clkdev(clk, "bcm2708_i2c.1"); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 3c1c1dc..e10667d 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -243,6 +243,7 @@ void __init bcm2709_init_clocks(void) - bcm2709_register_clkdev(clk, "dev:f1"); - - clk = bcm2709_clk_register("sdhost_clk", 250000000); -+ bcm2709_register_clkdev(clk, "mmc-bcm2835.0"); - bcm2709_register_clkdev(clk, "bcm2708_spi.0"); - bcm2709_register_clkdev(clk, "bcm2708_i2c.0"); - bcm2709_register_clkdev(clk, "bcm2708_i2c.1"); - -From 7520bcefca288277ace88e3df254045eee89c189 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 24 Mar 2015 15:12:35 +0100 -Subject: [PATCH 100/216] BCM270x_DT: add bcm2835-mmc entry -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree entry for bcm2835-mmc. -In non-DT mode, don't add the device in the board file. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 5 +++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 5 +++++ - arch/arm/boot/dts/bcm2708.dtsi | 19 +++++++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 5 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 19 +++++++++++++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 7 files changed, 55 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 7f84473..f25563a 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -44,6 +44,11 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index a39562f..17b4b8c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -44,6 +44,11 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 846f148..42edda5 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -41,6 +41,17 @@ - #interrupt-cells = <2>; - }; - -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; - reg = <0x7e203000 0x20>, -@@ -96,6 +107,14 @@ - #address-cells = <1>; - #size-cells = <0>; - -+ clk_mmc: clock@0 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "mmc"; -+ clock-frequency = <250000000>; -+ }; -+ - clk_i2c: i2c { - compatible = "fixed-clock"; - reg = <1>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 75c222f..c73249b 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -44,6 +44,11 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index d468363..bd6605d 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -41,6 +41,17 @@ - #interrupt-cells = <2>; - }; - -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; - reg = <0x7e203000 0x20>, -@@ -97,6 +108,14 @@ - #address-cells = <1>; - #size-cells = <0>; - -+ clk_mmc: clock@0 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "mmc"; -+ clock-frequency = <250000000>; -+ }; -+ - clk_i2c: i2c { - compatible = "fixed-clock"; - reg = <1>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index b5f22e2..16ba248 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -885,7 +885,7 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 -- bcm_register_device(&bcm2835_emmc_device); -+ bcm_register_device_dt(&bcm2835_emmc_device); - #endif - bcm2708_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index e10667d..dcad008 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -909,7 +909,7 @@ void __init bcm2709_init(void) - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 -- bcm_register_device(&bcm2835_emmc_device); -+ bcm_register_device_dt(&bcm2835_emmc_device); - #endif - bcm2709_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - -From 7504524f3f951bf8c40c5decf231ea6538d1380b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 27 Mar 2015 11:45:44 +0000 -Subject: [PATCH 101/216] BCM270x_DT: Refactor bcm2708.dtsi and bcm2709.dtsi - -Extract the common elements, creating bcm2708_common.dtsi ---- - arch/arm/boot/dts/bcm2708.dtsi | 118 +-------------------------------- - arch/arm/boot/dts/bcm2708_common.dtsi | 120 ++++++++++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2709.dtsi | 118 +-------------------------------- - 3 files changed, 124 insertions(+), 232 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 42edda5..0d47427 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -1,133 +1,19 @@ --/include/ "skeleton.dtsi" -+/include/ "bcm2708_common.dtsi" - - / { - compatible = "brcm,bcm2708"; - model = "BCM2708"; - -- interrupt-parent = <&intc>; -- - chosen { - /* No padding required - the boot loader can do that. */ - bootargs = ""; - }; - -- soc: soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -+ soc { - ranges = <0x7e000000 0x20000000 0x01000000>; - -- dma: dma@7e007000 { -- compatible = "brcm,bcm2835-dma"; -- #dma-cells = <1>; -- }; -- -- intc: interrupt-controller { -- compatible = "brcm,bcm2708-armctrl-ic"; -- reg = <0x7e00b200 0x200>; -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- gpio: gpio { -- compatible = "brcm,bcm2835-gpio"; -- reg = <0x7e200000 0xb4>; -- interrupts = <2 17>, <2 18>; -- -- gpio-controller; -- #gpio-cells = <2>; -- -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- mmc: mmc@7e300000 { -- compatible = "brcm,bcm2835-mmc"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- i2s: i2s@7e203000 { -- compatible = "brcm,bcm2708-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -- -- //dmas = <&dma 2>, -- // <&dma 3>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- spi0: spi@7e204000 { -- compatible = "brcm,bcm2708-spi"; -- reg = <0x7e204000 0x1000>; -- interrupts = <2 22>; -- clocks = <&clk_spi>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c0: i2c@7e205000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e205000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c1: i2c@7e804000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e804000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- leds: leds { -- compatible = "gpio-leds"; -- }; -- - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; - }; -- -- clocks { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_mmc: clock@0 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "mmc"; -- clock-frequency = <250000000>; -- }; -- -- clk_i2c: i2c { -- compatible = "fixed-clock"; -- reg = <1>; -- #clock-cells = <0>; -- clock-frequency = <250000000>; -- }; -- -- clk_spi: clock@2 { -- compatible = "fixed-clock"; -- reg = <2>; -- #clock-cells = <0>; -- clock-output-names = "spi"; -- clock-frequency = <250000000>; -- }; -- }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -new file mode 100644 -index 0000000..ff70c58 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -0,0 +1,120 @@ -+/include/ "skeleton.dtsi" -+ -+/ { -+ interrupt-parent = <&intc>; -+ -+ soc: soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ dma: dma@7e007000 { -+ compatible = "brcm,bcm2835-dma"; -+ #dma-cells = <1>; -+ }; -+ -+ intc: interrupt-controller { -+ compatible = "brcm,bcm2708-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio: gpio { -+ compatible = "brcm,bcm2835-gpio"; -+ reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ i2s: i2s@7e203000 { -+ compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; -+ -+ //dmas = <&dma 2>, -+ // <&dma 3>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@7e204000 { -+ compatible = "brcm,bcm2708-spi"; -+ reg = <0x7e204000 0x1000>; -+ interrupts = <2 22>; -+ clocks = <&clk_spi>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@7e205000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e205000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@7e804000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e804000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ leds: leds { -+ compatible = "gpio-leds"; -+ }; -+ }; -+ -+ clocks { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_mmc: clock@0 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "mmc"; -+ clock-frequency = <250000000>; -+ }; -+ -+ clk_i2c: i2c { -+ compatible = "fixed-clock"; -+ reg = <1>; -+ #clock-cells = <0>; -+ clock-frequency = <250000000>; -+ }; -+ -+ clk_spi: clock@2 { -+ compatible = "fixed-clock"; -+ reg = <2>; -+ #clock-cells = <0>; -+ clock-output-names = "spi"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index bd6605d..5e0b935 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -1,137 +1,23 @@ --/include/ "skeleton.dtsi" -+/include/ "bcm2708_common.dtsi" - - / { - compatible = "brcm,bcm2709"; - model = "BCM2709"; - -- interrupt-parent = <&intc>; -- - chosen { - /* No padding required - the boot loader can do that. */ - bootargs = ""; - }; - -- soc: soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -+ soc { - ranges = <0x7e000000 0x3f000000 0x01000000>; - -- dma: dma@7e007000 { -- compatible = "brcm,bcm2835-dma"; -- #dma-cells = <1>; -- }; -- -- intc: interrupt-controller { -- compatible = "brcm,bcm2708-armctrl-ic"; -- reg = <0x7e00b200 0x200>; -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- gpio: gpio { -- compatible = "brcm,bcm2835-gpio"; -- reg = <0x7e200000 0xb4>; -- interrupts = <2 17>, <2 18>; -- -- gpio-controller; -- #gpio-cells = <2>; -- -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- mmc: mmc@7e300000 { -- compatible = "brcm,bcm2835-mmc"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- i2s: i2s@7e203000 { -- compatible = "brcm,bcm2708-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -- -- //dmas = <&dma 2>, -- // <&dma 3>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- spi0: spi@7e204000 { -- compatible = "brcm,bcm2708-spi"; -- reg = <0x7e204000 0x1000>; -- interrupts = <2 22>; -- clocks = <&clk_spi>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c0: i2c@7e205000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e205000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c1: i2c@7e804000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e804000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- leds: leds { -- compatible = "gpio-leds"; -- }; -- - arm-pmu { - compatible = "arm,cortex-a7-pmu"; - interrupts = <3 9>; - }; - }; - -- clocks { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_mmc: clock@0 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "mmc"; -- clock-frequency = <250000000>; -- }; -- -- clk_i2c: i2c { -- compatible = "fixed-clock"; -- reg = <1>; -- #clock-cells = <0>; -- clock-frequency = <250000000>; -- }; -- -- clk_spi: clock@2 { -- compatible = "fixed-clock"; -- reg = <2>; -- #clock-cells = <0>; -- clock-output-names = "spi"; -- clock-frequency = <250000000>; -- }; -- }; -- - timer { - compatible = "arm,armv7-timer"; - clock-frequency = <19200000>; - -From 5d44aea95dbfd69851ffeb426ccf419f5894e70e Mon Sep 17 00:00:00 2001 +From 331cdec0de30933d5e7839f0e3def9b98d3fa968 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 102/216] Add driver for rpi-proto +Subject: [PATCH 62/77] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x @@ -128380,74 +128063,14 @@ Playback tested with devicetree enabled. Signed-off-by: Waldemar Brodkorb --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/rpi-proto-overlay.dts | 39 ++++++++ - sound/soc/bcm/Kconfig | 7 ++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++ - 5 files changed, 202 insertions(+) - create mode 100644 arch/arm/boot/dts/rpi-proto-overlay.dts + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 162 insertions(+) create mode 100644 sound/soc/bcm/rpi-proto.c -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index f99eccf..daf51d2 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -24,6 +24,7 @@ dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb -diff --git a/arch/arm/boot/dts/rpi-proto-overlay.dts b/arch/arm/boot/dts/rpi-proto-overlay.dts -new file mode 100644 -index 0000000..2029930 ---- /dev/null -+++ b/arch/arm/boot/dts/rpi-proto-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for Rpi-Proto -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-proto"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8731@1a { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8731"; -+ reg = <0x1a>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 40d27c1..003ae28 100644 +index bdcf12f..fc151ea 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -54,6 +54,13 @@ config SND_BCM2708_SOC_RPI_DAC @@ -128456,14 +128079,14 @@ index 40d27c1..003ae28 100644 +config SND_BCM2708_SOC_RPI_PROTO + tristate "Support for Rpi-PROTO" -+ depends on SND_BCM2708_SOC_I2S ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_WM8731 + help + Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731). + config SND_BCM2708_SOC_IQAUDIO_DAC tristate "Support for IQaudIO-DAC" - depends on SND_BCM2708_SOC_I2S + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile index 17ea2b0..883241b 100644 --- a/sound/soc/bcm/Makefile @@ -128642,71 +128265,16 @@ index 0000000..c6e45a0 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From b1c2c58f341642e8bcc337b592f19d5543ae51ad Mon Sep 17 00:00:00 2001 +From 2079392f1bde4f50d8c1ad65c2f7b52a6ff34848 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Thu, 2 Apr 2015 12:22:55 +0100 -Subject: [PATCH 103/216] Add Device Tree support for RPi-DAC. +Subject: [PATCH 63/77] Add Device Tree support for RPi-DAC. --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/rpi-dac-overlay.dts | 34 ++++++++++++++++++++++++++++++++++ - sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++ - sound/soc/codecs/pcm1794a.c | 7 +++++++ - 4 files changed, 63 insertions(+) - create mode 100644 arch/arm/boot/dts/rpi-dac-overlay.dts + sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++ + sound/soc/codecs/pcm1794a.c | 7 +++++++ + 2 files changed, 28 insertions(+) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index daf51d2..980b78e0 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -24,6 +24,7 @@ dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -diff --git a/arch/arm/boot/dts/rpi-dac-overlay.dts b/arch/arm/boot/dts/rpi-dac-overlay.dts -new file mode 100644 -index 0000000..7fc6ac9 ---- /dev/null -+++ b/arch/arm/boot/dts/rpi-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for RPi DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm1794a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm1794a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c index 6d6e0ba..d5fac1b 100644 --- a/sound/soc/bcm/rpi-dac.c @@ -128775,24 +128343,24 @@ index b4eaa44..afe1b41 100644 }; -From c3bd8511bef07e4a3ebf9e78fc1ed0889aaf1d62 Mon Sep 17 00:00:00 2001 +From 4725644a3f7c09811486c1324f9653e79ecbdcb7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 104/216] config: Add default configs +Subject: [PATCH 64/77] config: Add default configs --- - arch/arm/configs/bcm2709_defconfig | 1191 ++++++++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 1186 +++++++++++++++++++++++++++++++++++ - 2 files changed, 2377 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1204 ++++++++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 1199 +++++++++++++++++++++++++++++++++++ + 2 files changed, 2403 insertions(+) create mode 100644 arch/arm/configs/bcm2709_defconfig create mode 100644 arch/arm/configs/bcmrpi_defconfig diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig new file mode 100644 -index 0000000..7cec5f8 +index 0000000..a3067bf --- /dev/null +++ b/arch/arm/configs/bcm2709_defconfig -@@ -0,0 +1,1191 @@ +@@ -0,0 +1,1204 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +CONFIG_LOCALVERSION="-v7" @@ -129315,7 +128883,8 @@ index 0000000..7cec5f8 +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m -+# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m @@ -129350,6 +128919,7 @@ index 0000000..7cec5f8 +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y +CONFIG_BRCM_CHAR_DRIVERS=y @@ -129392,6 +128962,7 @@ index 0000000..7cec5f8 +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y +CONFIG_BCM2708_WDT=m ++CONFIG_BCM2835_WDT=m +CONFIG_UCB1400_CORE=m +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y @@ -129564,6 +129135,7 @@ index 0000000..7cec5f8 +CONFIG_VIDEO_MT9V011=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y ++CONFIG_FB_SSD1307=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -129751,6 +129323,7 @@ index 0000000..7cec5f8 +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835=y +CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=m @@ -129846,9 +129419,16 @@ index 0000000..7cec5f8 +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2708_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_DHT11=m +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -129910,6 +129490,7 @@ index 0000000..7cec5f8 +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_9P_FS=m @@ -129986,10 +129567,10 @@ index 0000000..7cec5f8 +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig new file mode 100644 -index 0000000..e77173b +index 0000000..6a41231 --- /dev/null +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,1186 @@ +@@ -0,0 +1,1199 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +# CONFIG_LOCALVERSION_AUTO is not set @@ -130505,7 +130086,8 @@ index 0000000..e77173b +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m -+# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m @@ -130540,6 +130122,7 @@ index 0000000..e77173b +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y +CONFIG_BRCM_CHAR_DRIVERS=y @@ -130582,6 +130165,7 @@ index 0000000..e77173b +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y +CONFIG_BCM2708_WDT=m ++CONFIG_BCM2835_WDT=m +CONFIG_UCB1400_CORE=m +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y @@ -130754,6 +130338,7 @@ index 0000000..e77173b +CONFIG_VIDEO_MT9V011=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y ++CONFIG_FB_SSD1307=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -130941,6 +130526,7 @@ index 0000000..e77173b +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835=y +CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=m @@ -131036,9 +130622,16 @@ index 0000000..e77173b +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2708_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_DHT11=m +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -131100,6 +130693,7 @@ index 0000000..e77173b +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_9P_FS=m @@ -131177,1110 +130771,10 @@ index 0000000..e77173b +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 196c354f9d8f85f9e56bd2ce11113883f98bccaa Mon Sep 17 00:00:00 2001 -From: Jakub Kicinski -Date: Mon, 2 Mar 2015 16:34:37 +0100 -Subject: [PATCH 105/216] bcm2708: fix uart1 parameters - -System clock is 250MHz, but the device uses a non-standard -oversampling rate (8 instead of 16) hence the clock rate -has to be multiplied by 16/8 = 2. Currently the clock -rate seems to be divided by 2. - -Also correct the .type and .flags. - -Signed-off-by: Jakub Kicinski ---- - arch/arm/mach-bcm2708/bcm2708.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 16ba248..b848e4a 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -312,11 +312,12 @@ static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { - { - .mapbase = UART1_BASE + 0x40, - .irq = IRQ_AUX, -- .uartclk = 125000000, -+ .uartclk = 500000000, - .regshift = 2, - .iotype = UPIO_MEM, -- .flags = UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST, -- .type = PORT_8250, -+ .flags = UPF_SHARE_IRQ | UPF_FIXED_TYPE | UPF_FIXED_PORT | -+ UPF_IOREMAP | UPF_SKIP_TEST, -+ .type = PORT_16550, - }, - {}, - }; - -From 8243fc28ee2c92452173c695fdb7990e3758fdc3 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Fri, 20 Mar 2015 15:26:11 +0100 -Subject: [PATCH 106/216] spi: bcm2835: fix all checkpath --strict messages - -The following errors/warnings issued by checkpatch.pl --strict have been fixed: -drivers/spi/spi-bcm2835.c:182: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:191: CHECK: braces {} should be used on all arms of this statement -drivers/spi/spi-bcm2835.c:234: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:256: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:271: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:346: CHECK: Alignment should match open parenthesis -total: 0 errors, 0 warnings, 6 checks, 403 lines checked - -In 2 locations the arguments had to get split/moved to the next line so that the -line width stays below 80 chars. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 419a782..779d3a8 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -179,7 +179,7 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - } - - static int bcm2835_spi_start_transfer(struct spi_device *spi, -- struct spi_transfer *tfr) -+ struct spi_transfer *tfr) - { - struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); - unsigned long spi_hz, clk_hz, cdiv; -@@ -196,8 +196,9 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - - if (cdiv >= 65536) - cdiv = 0; /* 0 is the slowest we can go */ -- } else -+ } else { - cdiv = 0; /* 0 is the slowest we can go */ -+ } - - if (spi->mode & SPI_CPOL) - cs |= BCM2835_SPI_CS_CPOL; -@@ -231,7 +232,8 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - } - - static int bcm2835_spi_finish_transfer(struct spi_device *spi, -- struct spi_transfer *tfr, bool cs_change) -+ struct spi_transfer *tfr, -+ bool cs_change) - { - struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -@@ -253,7 +255,7 @@ static int bcm2835_spi_finish_transfer(struct spi_device *spi, - } - - static int bcm2835_spi_transfer_one(struct spi_master *master, -- struct spi_message *mesg) -+ struct spi_message *mesg) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - struct spi_transfer *tfr; -@@ -267,8 +269,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - if (err) - goto out; - -- timeout = wait_for_completion_timeout(&bs->done, -- msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS)); -+ timeout = wait_for_completion_timeout( -+ &bs->done, -+ msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS) -+ ); - if (!timeout) { - err = -ETIMEDOUT; - goto out; -@@ -343,7 +347,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - clk_prepare_enable(bs->clk); - - err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, -- dev_name(&pdev->dev), master); -+ dev_name(&pdev->dev), master); - if (err) { - dev_err(&pdev->dev, "could not request IRQ: %d\n", err); - goto out_clk_disable; - -From 54e38f321ea8bb1990d6f496c0710532224a35ad Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 23 Mar 2015 15:11:53 +0100 -Subject: [PATCH 107/216] spi: bcm2835: fill/drain SPI-fifo as much as possible - during interrupt - -Implement the recommendation from the BCM2835 data-sheet -with regards to polling drivers to fill/drain the FIFO as much data as possible -also for the interrupt-driven case (which this driver is making use of). - -This means that for long transfers (>64bytes) we need one interrupt -every 64 bytes instead of every 12 bytes, as the FIFO is 16 words (not bytes) wide. - -Tested with mcp251x (can bus), fb_st7735 (TFT framebuffer device) -and enc28j60 (ethernet) drivers. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 78 +++++++++++------------------------------------ - 1 file changed, 17 insertions(+), 61 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 779d3a8..960dcce 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -91,25 +91,23 @@ static inline void bcm2835_wr(struct bcm2835_spi *bs, unsigned reg, u32 val) - writel(val, bs->regs + reg); - } - --static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs, int len) -+static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- while (len--) { -+ while (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD) { - byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); - if (bs->rx_buf) - *bs->rx_buf++ = byte; - } - } - --static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs, int len) -+static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- if (len > bs->len) -- len = bs->len; -- -- while (len--) { -+ while ((bs->len) && -+ (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) { - byte = bs->tx_buf ? *bs->tx_buf++ : 0; - bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); - bs->len--; -@@ -122,60 +120,24 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - struct bcm2835_spi *bs = spi_master_get_devdata(master); - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - -- /* -- * RXR - RX needs Reading. This means 12 (or more) bytes have been -- * transmitted and hence 12 (or more) bytes have been received. -- * -- * The FIFO is 16-bytes deep. We check for this interrupt to keep the -- * FIFO full; we have a 4-byte-time buffer for IRQ latency. We check -- * this before DONE (TX empty) just in case we delayed processing this -- * interrupt for some reason. -- * -- * We only check for this case if we have more bytes to TX; at the end -- * of the transfer, we ignore this pipelining optimization, and let -- * bcm2835_spi_finish_transfer() drain the RX FIFO. -- */ -- if (bs->len && (cs & BCM2835_SPI_CS_RXR)) { -- /* Read 12 bytes of data */ -- bcm2835_rd_fifo(bs, 12); -+ /* Read as many bytes as possible from FIFO */ -+ bcm2835_rd_fifo(bs); - -- /* Write up to 12 bytes */ -- bcm2835_wr_fifo(bs, 12); -+ if (bs->len) { /* there is more data to transmit */ -+ bcm2835_wr_fifo(bs); -+ } else { /* Transfer complete */ -+ /* Disable SPI interrupts */ -+ cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); - - /* -- * We must have written something to the TX FIFO due to the -- * bs->len check above, so cannot be DONE. Hence, return -- * early. Note that DONE could also be set if we serviced an -- * RXR interrupt really late. -+ * Wake up bcm2835_spi_transfer_one(), which will call -+ * bcm2835_spi_finish_transfer(), to drain the RX FIFO. - */ -- return IRQ_HANDLED; -+ complete(&bs->done); - } - -- /* -- * DONE - TX empty. This occurs when we first enable the transfer -- * since we do not pre-fill the TX FIFO. At any other time, given that -- * we refill the TX FIFO above based on RXR, and hence ignore DONE if -- * RXR is set, DONE really does mean end-of-transfer. -- */ -- if (cs & BCM2835_SPI_CS_DONE) { -- if (bs->len) { /* First interrupt in a transfer */ -- bcm2835_wr_fifo(bs, 16); -- } else { /* Transfer complete */ -- /* Disable SPI interrupts */ -- cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); -- bcm2835_wr(bs, BCM2835_SPI_CS, cs); -- -- /* -- * Wake up bcm2835_spi_transfer_one(), which will call -- * bcm2835_spi_finish_transfer(), to drain the RX FIFO. -- */ -- complete(&bs->done); -- } -- -- return IRQ_HANDLED; -- } -- -- return IRQ_NONE; -+ return IRQ_HANDLED; - } - - static int bcm2835_spi_start_transfer(struct spi_device *spi, -@@ -238,12 +200,6 @@ static int bcm2835_spi_finish_transfer(struct spi_device *spi, - struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - -- /* Drain RX FIFO */ -- while (cs & BCM2835_SPI_CS_RXD) { -- bcm2835_rd_fifo(bs, 1); -- cs = bcm2835_rd(bs, BCM2835_SPI_CS); -- } -- - if (tfr->delay_usecs) - udelay(tfr->delay_usecs); - - -From 52469b2a3843dbd5aad2109a73e1b41371f83be3 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 19 Mar 2015 09:01:52 +0000 -Subject: [PATCH 108/216] spi: bcm2835: clock divider can be a multiple of 2 - -The official documentation is wrong in this respect. -Has been tested empirically for dividers 2-1024 - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 960dcce..8de1925 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -153,8 +153,9 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - if (spi_hz >= clk_hz / 2) { - cdiv = 2; /* clk_hz/2 is the fastest we can go */ - } else if (spi_hz) { -- /* CDIV must be a power of two */ -- cdiv = roundup_pow_of_two(DIV_ROUND_UP(clk_hz, spi_hz)); -+ /* CDIV must be a multiple of two */ -+ cdiv = DIV_ROUND_UP(clk_hz, spi_hz); -+ cdiv += (cdiv % 2); - - if (cdiv >= 65536) - cdiv = 0; /* 0 is the slowest we can go */ - -From b3622510de92a35d73778905be9ab4ad4235bd66 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 19 Mar 2015 09:01:53 +0000 -Subject: [PATCH 109/216] spi: bcm2835: enable support of 3-wire mode - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 8de1925..3f93718 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -67,7 +67,8 @@ - #define BCM2835_SPI_CS_CS_01 0x00000001 - - #define BCM2835_SPI_TIMEOUT_MS 30000 --#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS) -+#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ -+ | SPI_NO_CS | SPI_3WIRE) - - #define DRV_NAME "spi-bcm2835" - -@@ -163,6 +164,9 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - cdiv = 0; /* 0 is the slowest we can go */ - } - -+ if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) -+ cs |= BCM2835_SPI_CS_REN; -+ - if (spi->mode & SPI_CPOL) - cs |= BCM2835_SPI_CS_CPOL; - if (spi->mode & SPI_CPHA) - -From c71501bcc7b07a82119e2f7b27309a62f90aa02a Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 26 Mar 2015 11:08:36 +0100 -Subject: [PATCH 110/216] spi: bcm2835: move to the transfer_one driver model - -This also allows for GPIO-CS to get used removing the limitation of -2/3 SPI devises on the SPI bus. - -Fixes: spi-cs-high with native CS with multiple devices on the spi-bus -resetting the chip selects to "normal" polarity after a finished -transfer. - -No other functionality/improvements added. - -Tested with the following 4 devices on the spi-bus: -* mcp2515 with native CS -* mcp2515 with gpio CS -* fb_st7735r with native CS - (plus spi-cs-high via transistor inverting polarity) -* enc28j60 with gpio-CS -Tested-by: Martin Sperl - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 212 +++++++++++++++++++++++++++------------------- - 1 file changed, 124 insertions(+), 88 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 3f93718..31d80eb0 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -3,6 +3,7 @@ - * - * Copyright (C) 2012 Chris Boot - * Copyright (C) 2013 Stephen Warren -+ * Copyright (C) 2015 Martin Sperl - * - * This driver is inspired by: - * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos -@@ -29,6 +30,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -76,10 +78,10 @@ struct bcm2835_spi { - void __iomem *regs; - struct clk *clk; - int irq; -- struct completion done; - const u8 *tx_buf; - u8 *rx_buf; -- int len; -+ int tx_len; -+ int rx_len; - }; - - static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg) -@@ -96,10 +98,12 @@ static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- while (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD) { -+ while ((bs->rx_len) && -+ (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD)) { - byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); - if (bs->rx_buf) - *bs->rx_buf++ = byte; -+ bs->rx_len--; - } - } - -@@ -107,47 +111,60 @@ static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- while ((bs->len) && -+ while ((bs->tx_len) && - (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) { - byte = bs->tx_buf ? *bs->tx_buf++ : 0; - bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); -- bs->len--; -+ bs->tx_len--; - } - } - -+static void bcm2835_spi_reset_hw(struct spi_master *master) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -+ -+ /* Disable SPI interrupts and transfer */ -+ cs &= ~(BCM2835_SPI_CS_INTR | -+ BCM2835_SPI_CS_INTD | -+ BCM2835_SPI_CS_TA); -+ /* and reset RX/TX FIFOS */ -+ cs |= BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX; -+ -+ /* and reset the SPI_HW */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+} -+ - static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - { - struct spi_master *master = dev_id; - struct bcm2835_spi *bs = spi_master_get_devdata(master); -- u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - - /* Read as many bytes as possible from FIFO */ - bcm2835_rd_fifo(bs); -- -- if (bs->len) { /* there is more data to transmit */ -- bcm2835_wr_fifo(bs); -- } else { /* Transfer complete */ -- /* Disable SPI interrupts */ -- cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); -- bcm2835_wr(bs, BCM2835_SPI_CS, cs); -- -- /* -- * Wake up bcm2835_spi_transfer_one(), which will call -- * bcm2835_spi_finish_transfer(), to drain the RX FIFO. -- */ -- complete(&bs->done); -+ /* Write as many bytes as possible to FIFO */ -+ bcm2835_wr_fifo(bs); -+ -+ /* based on flags decide if we can finish the transfer */ -+ if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) { -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* wake up the framework */ -+ complete(&master->xfer_completion); - } - - return IRQ_HANDLED; - } - --static int bcm2835_spi_start_transfer(struct spi_device *spi, -- struct spi_transfer *tfr) -+static int bcm2835_spi_transfer_one(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr) - { -- struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long spi_hz, clk_hz, cdiv; -- u32 cs = BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - -+ /* set clock */ - spi_hz = tfr->speed_hz; - clk_hz = clk_get_rate(bs->clk); - -@@ -163,100 +180,118 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - } else { - cdiv = 0; /* 0 is the slowest we can go */ - } -+ bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); - -+ /* handle all the modes */ - if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) - cs |= BCM2835_SPI_CS_REN; -- - if (spi->mode & SPI_CPOL) - cs |= BCM2835_SPI_CS_CPOL; - if (spi->mode & SPI_CPHA) - cs |= BCM2835_SPI_CS_CPHA; - -- if (!(spi->mode & SPI_NO_CS)) { -- if (spi->mode & SPI_CS_HIGH) { -- cs |= BCM2835_SPI_CS_CSPOL; -- cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select; -- } -- -- cs |= spi->chip_select; -- } -+ /* for gpio_cs set dummy CS so that no HW-CS get changed -+ * we can not run this in bcm2835_spi_set_cs, as it does -+ * not get called for cs_gpio cases, so we need to do it here -+ */ -+ if (gpio_is_valid(spi->cs_gpio) || (spi->mode & SPI_NO_CS)) -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; - -- reinit_completion(&bs->done); -+ /* set transmit buffers and length */ - bs->tx_buf = tfr->tx_buf; - bs->rx_buf = tfr->rx_buf; -- bs->len = tfr->len; -+ bs->tx_len = tfr->len; -+ bs->rx_len = tfr->len; - -- bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); - /* - * Enable the HW block. This will immediately trigger a DONE (TX - * empty) interrupt, upon which we will fill the TX FIFO with the - * first TX bytes. Pre-filling the TX FIFO here to avoid the - * interrupt doesn't work:-( - */ -+ cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; - bcm2835_wr(bs, BCM2835_SPI_CS, cs); - -- return 0; -+ /* signal that we need to wait for completion */ -+ return 1; - } - --static int bcm2835_spi_finish_transfer(struct spi_device *spi, -- struct spi_transfer *tfr, -- bool cs_change) -+static void bcm2835_spi_handle_err(struct spi_master *master, -+ struct spi_message *msg) - { -- struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); -- u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -- -- if (tfr->delay_usecs) -- udelay(tfr->delay_usecs); -- -- if (cs_change) -- /* Clear TA flag */ -- bcm2835_wr(bs, BCM2835_SPI_CS, cs & ~BCM2835_SPI_CS_TA); -- -- return 0; -+ bcm2835_spi_reset_hw(master); - } - --static int bcm2835_spi_transfer_one(struct spi_master *master, -- struct spi_message *mesg) -+static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level) - { -+ /* -+ * we can assume that we are "native" as per spi_set_cs -+ * calling us ONLY when cs_gpio is not set -+ * we can also assume that we are CS < 3 as per bcm2835_spi_setup -+ * we would not get called because of error handling there. -+ * the level passed is the electrical level not enabled/disabled -+ * so it has to get translated back to enable/disable -+ * see spi_set_cs in spi.c for the implementation -+ */ -+ -+ struct spi_master *master = spi->master; - struct bcm2835_spi *bs = spi_master_get_devdata(master); -- struct spi_transfer *tfr; -- struct spi_device *spi = mesg->spi; -- int err = 0; -- unsigned int timeout; -- bool cs_change; -- -- list_for_each_entry(tfr, &mesg->transfers, transfer_list) { -- err = bcm2835_spi_start_transfer(spi, tfr); -- if (err) -- goto out; -- -- timeout = wait_for_completion_timeout( -- &bs->done, -- msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS) -- ); -- if (!timeout) { -- err = -ETIMEDOUT; -- goto out; -- } -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -+ bool enable; - -- cs_change = tfr->cs_change || -- list_is_last(&tfr->transfer_list, &mesg->transfers); -+ /* calculate the enable flag from the passed gpio_level */ -+ enable = (spi->mode & SPI_CS_HIGH) ? gpio_level : !gpio_level; - -- err = bcm2835_spi_finish_transfer(spi, tfr, cs_change); -- if (err) -- goto out; -+ /* set flags for "reverse" polarity in the registers */ -+ if (spi->mode & SPI_CS_HIGH) { -+ /* set the correct CS-bits */ -+ cs |= BCM2835_SPI_CS_CSPOL; -+ cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select; -+ } else { -+ /* clean the CS-bits */ -+ cs &= ~BCM2835_SPI_CS_CSPOL; -+ cs &= ~(BCM2835_SPI_CS_CSPOL0 << spi->chip_select); -+ } - -- mesg->actual_length += (tfr->len - bs->len); -+ /* select the correct chip_select depending on disabled/enabled */ -+ if (enable) { -+ /* set cs correctly */ -+ if (spi->mode & SPI_NO_CS) { -+ /* use the "undefined" chip-select */ -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; -+ } else { -+ /* set the chip select */ -+ cs &= ~(BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01); -+ cs |= spi->chip_select; -+ } -+ } else { -+ /* disable CSPOL which puts HW-CS into deselected state */ -+ cs &= ~BCM2835_SPI_CS_CSPOL; -+ /* use the "undefined" chip-select as precaution */ -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; - } - --out: -- /* Clear FIFOs, and disable the HW block */ -- bcm2835_wr(bs, BCM2835_SPI_CS, -- BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); -- mesg->status = err; -- spi_finalize_current_message(master); -+ /* finally set the calculated flags in SPI_CS */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+} - -- return 0; -+static int bcm2835_spi_setup(struct spi_device *spi) -+{ -+ /* -+ * sanity checking the native-chipselects -+ */ -+ if (spi->mode & SPI_NO_CS) -+ return 0; -+ if (gpio_is_valid(spi->cs_gpio)) -+ return 0; -+ if (spi->chip_select < 3) -+ return 0; -+ -+ /* error in the case of native CS requested with CS-id > 2 */ -+ dev_err(&spi->dev, -+ "setup: only three native chip-selects are supported\n" -+ ); -+ return -EINVAL; - } - - static int bcm2835_spi_probe(struct platform_device *pdev) -@@ -277,13 +312,14 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - master->mode_bits = BCM2835_SPI_MODE_BITS; - master->bits_per_word_mask = SPI_BPW_MASK(8); - master->num_chipselect = 3; -- master->transfer_one_message = bcm2835_spi_transfer_one; -+ master->setup = bcm2835_spi_setup; -+ master->set_cs = bcm2835_spi_set_cs; -+ master->transfer_one = bcm2835_spi_transfer_one; -+ //master->handle_err = bcm2835_spi_handle_err; - master->dev.of_node = pdev->dev.of_node; - - bs = spi_master_get_devdata(master); - -- init_completion(&bs->done); -- - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - bs->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(bs->regs)) { -@@ -314,7 +350,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - goto out_clk_disable; - } - -- /* initialise the hardware */ -+ /* initialise the hardware with the default polarities */ - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - - -From cf51ed163d8109aa02dfc267633ed4c0a4a81f08 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 29 Mar 2015 16:03:23 +0200 -Subject: [PATCH 111/216] spi: bcm2835: fix code formatting issue - -Signed-off-by: Martin Sperl -Tested-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 31d80eb0..4aa80fd 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -289,8 +289,7 @@ static int bcm2835_spi_setup(struct spi_device *spi) - - /* error in the case of native CS requested with CS-id > 2 */ - dev_err(&spi->dev, -- "setup: only three native chip-selects are supported\n" -- ); -+ "setup: only three native chip-selects are supported\n"); - return -EINVAL; - } - - -From 8f0e96a797cebd49ab5054b3c150386a5f840855 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 29 Mar 2015 16:03:25 +0200 -Subject: [PATCH 112/216] spi: bcm2835: fill FIFO before enabling interrupts to - reduce interrupts/message - -To reduce the number of interrupts/message we fill the FIFO before -enabling interrupts - for short messages this reduces the interrupt count -from 2 to 1 interrupt. - -There have been rare cases where short (<200ns) chip-select switches with -native CS have been observed during such operation, this is why this -optimization is only enabled for GPIO-CS. - -Signed-off-by: Martin Sperl -Tested-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 4aa80fd..321dbe2 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -203,6 +203,22 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - bs->tx_len = tfr->len; - bs->rx_len = tfr->len; - -+ /* fill in fifo if we have gpio-cs -+ * note that there have been rare events where the native-CS -+ * flapped for <1us which may change the behaviour -+ * with gpio-cs this does not happen, so it is implemented -+ * only for this case -+ */ -+ if (gpio_is_valid(spi->cs_gpio)) { -+ /* enable HW block, but without interrupts enabled -+ * this would triggern an immediate interrupt -+ */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, -+ cs | BCM2835_SPI_CS_TA); -+ /* fill in tx fifo as much as possible */ -+ bcm2835_wr_fifo(bs); -+ } -+ - /* - * Enable the HW block. This will immediately trigger a DONE (TX - * empty) interrupt, upon which we will fill the TX FIFO with the - -From 31a827ccaeac10f8a5ac4ee4dc4fcdda68470eb7 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 6 Apr 2015 17:16:31 +0000 -Subject: [PATCH 113/216] spi: bcm2835: transform native-cs to gpio-cs on first - spi_setup - -Transforms the bcm-2835 native SPI-chip select to their gpio-cs equivalent. - -This allows for some support of some optimizations that are not -possible due to HW-gliches on the CS line - especially filling -the FIFO before enabling SPI interrupts (by writing to CS register) -while the transfer is already in progress (See commit: e3a2be3030e2) - -This patch also works arround some issues in bcm2835-pinctrl which does not -set the value when setting the GPIO as output - it just sets up output and -(typically) leaves the GPIO as low. When a fix for this is merged then this -gpio_set_value can get removed from bcm2835_spi_setup. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 49 ++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 44 insertions(+), 5 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 321dbe2..033b93f 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -291,8 +291,15 @@ static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level) - bcm2835_wr(bs, BCM2835_SPI_CS, cs); - } - -+static int chip_match_name(struct gpio_chip *chip, void *data) -+{ -+ return !strcmp(chip->label, data); -+} -+ - static int bcm2835_spi_setup(struct spi_device *spi) - { -+ int err; -+ struct gpio_chip *chip; - /* - * sanity checking the native-chipselects - */ -@@ -300,13 +307,45 @@ static int bcm2835_spi_setup(struct spi_device *spi) - return 0; - if (gpio_is_valid(spi->cs_gpio)) - return 0; -- if (spi->chip_select < 3) -+ if (spi->chip_select > 1) { -+ /* error in the case of native CS requested with CS > 1 -+ * officially there is a CS2, but it is not documented -+ * which GPIO is connected with that... -+ */ -+ dev_err(&spi->dev, -+ "setup: only two native chip-selects are supported\n"); -+ return -EINVAL; -+ } -+ /* now translate native cs to GPIO */ -+ -+ /* get the gpio chip for the base */ -+ chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); -+ if (!chip) - return 0; - -- /* error in the case of native CS requested with CS-id > 2 */ -- dev_err(&spi->dev, -- "setup: only three native chip-selects are supported\n"); -- return -EINVAL; -+ /* and calculate the real CS */ -+ spi->cs_gpio = chip->base + 8 - spi->chip_select; -+ -+ /* and set up the "mode" and level */ -+ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -+ spi->chip_select, spi->cs_gpio); -+ -+ /* set up GPIO as output and pull to the correct level */ -+ err = gpio_direction_output(spi->cs_gpio, -+ (spi->mode & SPI_CS_HIGH) ? 0 : 1); -+ if (err) { -+ dev_err(&spi->dev, -+ "could not set CS%i gpio %i as output: %i", -+ spi->chip_select, spi->cs_gpio, err); -+ return err; -+ } -+ /* the implementation of pinctrl-bcm2835 currently does not -+ * set the GPIO value when using gpio_direction_output -+ * so we are setting it here explicitly -+ */ -+ gpio_set_value(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? 0 : 1); -+ -+ return 0; - } - - static int bcm2835_spi_probe(struct platform_device *pdev) - -From 776aadc5da23cf97862d5eb535d8d9b8a038552f Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 6 Apr 2015 17:16:30 +0000 -Subject: [PATCH 114/216] spi: bcm2835: enabling polling mode for transfers - shorter than 30us - -In cases of short transfer times the CPU is spending lots of time -in the interrupt handler and scheduler to reschedule the worker thread. - -Measurements show that we have times where it takes 29.32us to between -the last clock change and the time that the worker-thread is running again -returning from wait_for_completion_timeout(). - -During this time the interrupt-handler is running calling complete() -and then also the scheduler is rescheduling the worker thread. - -This time can vary depending on how much of the code is still in -CPU-caches, when there is a burst of spi transfers the subsequent delays -are in the order of 25us, so the value of 30us seems reasonable. - -With polling the whole transfer of 4 bytes at 10MHz finishes after 6.16us -(CS down to up) with the real transfer (clock running) taking 3.56us. -So the efficiency has much improved and is also freeing CPU cycles, -reducing interrupts and context switches. - -Because of the above 30us seems to be a reasonable limit for polling. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 112 +++++++++++++++++++++++++++++++++++----------- - 1 file changed, 86 insertions(+), 26 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 033b93f..44ee1f3 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -68,7 +68,8 @@ - #define BCM2835_SPI_CS_CS_10 0x00000002 - #define BCM2835_SPI_CS_CS_01 0x00000001 - --#define BCM2835_SPI_TIMEOUT_MS 30000 -+#define BCM2835_SPI_POLLING_LIMIT_US 30 -+#define BCM2835_SPI_TIMEOUT_MS 30000 - #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_NO_CS | SPI_3WIRE) - -@@ -156,12 +157,86 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - return IRQ_HANDLED; - } - -+static int bcm2835_spi_transfer_one_poll(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs, -+ unsigned long xfer_time_us) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ unsigned long timeout = jiffies + -+ max(4 * xfer_time_us * HZ / 1000000, 2uL); -+ -+ /* enable HW block without interrupts */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); -+ -+ /* set timeout to 4x the expected time, or 2 jiffies */ -+ /* loop until finished the transfer */ -+ while (bs->rx_len) { -+ /* read from fifo as much as possible */ -+ bcm2835_rd_fifo(bs); -+ /* fill in tx fifo as much as possible */ -+ bcm2835_wr_fifo(bs); -+ /* if we still expect some data after the read, -+ * check for a possible timeout -+ */ -+ if (bs->rx_len && time_after(jiffies, timeout)) { -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* and return timeout */ -+ return -ETIMEDOUT; -+ } -+ } -+ -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* and return without waiting for completion */ -+ return 0; -+} -+ -+static int bcm2835_spi_transfer_one_irq(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ -+ /* fill in fifo if we have gpio-cs -+ * note that there have been rare events where the native-CS -+ * flapped for <1us which may change the behaviour -+ * with gpio-cs this does not happen, so it is implemented -+ * only for this case -+ */ -+ if (gpio_is_valid(spi->cs_gpio)) { -+ /* enable HW block, but without interrupts enabled -+ * this would triggern an immediate interrupt -+ */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, -+ cs | BCM2835_SPI_CS_TA); -+ /* fill in tx fifo as much as possible */ -+ bcm2835_wr_fifo(bs); -+ } -+ -+ /* -+ * Enable the HW block. This will immediately trigger a DONE (TX -+ * empty) interrupt, upon which we will fill the TX FIFO with the -+ * first TX bytes. Pre-filling the TX FIFO here to avoid the -+ * interrupt doesn't work:-( -+ */ -+ cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+ -+ /* signal that we need to wait for completion */ -+ return 1; -+} -+ - static int bcm2835_spi_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long spi_hz, clk_hz, cdiv; -+ unsigned long spi_used_hz, xfer_time_us; - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - - /* set clock */ -@@ -180,6 +255,7 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - } else { - cdiv = 0; /* 0 is the slowest we can go */ - } -+ spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); - bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); - - /* handle all the modes */ -@@ -203,33 +279,17 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - bs->tx_len = tfr->len; - bs->rx_len = tfr->len; - -- /* fill in fifo if we have gpio-cs -- * note that there have been rare events where the native-CS -- * flapped for <1us which may change the behaviour -- * with gpio-cs this does not happen, so it is implemented -- * only for this case -- */ -- if (gpio_is_valid(spi->cs_gpio)) { -- /* enable HW block, but without interrupts enabled -- * this would triggern an immediate interrupt -- */ -- bcm2835_wr(bs, BCM2835_SPI_CS, -- cs | BCM2835_SPI_CS_TA); -- /* fill in tx fifo as much as possible */ -- bcm2835_wr_fifo(bs); -- } -+ /* calculate the estimated time in us the transfer runs */ -+ xfer_time_us = tfr->len -+ * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */ -+ * 1000000 / spi_used_hz; - -- /* -- * Enable the HW block. This will immediately trigger a DONE (TX -- * empty) interrupt, upon which we will fill the TX FIFO with the -- * first TX bytes. Pre-filling the TX FIFO here to avoid the -- * interrupt doesn't work:-( -- */ -- cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; -- bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+ /* for short requests run polling*/ -+ if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US) -+ return bcm2835_spi_transfer_one_poll(master, spi, tfr, -+ cs, xfer_time_us); - -- /* signal that we need to wait for completion */ -- return 1; -+ return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); - } - - static void bcm2835_spi_handle_err(struct spi_master *master, - -From 0a92a30733013eae878dc15c597dfa718f2865f5 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 16 Apr 2015 21:18:47 +0100 -Subject: [PATCH 115/216] spi: bcm2835: change timeout of polling driver to 1s - -The way that the timeout code is written in the polling function -the timeout does also trigger when interrupted or rescheduled while -in the polling loop. - -This patch changes the timeout from effectively 20ms (=2 jiffies) to -1 second and removes the time that the transfer really takes out of -the computation, as - per design - this is <30us and the jiffie resolution -is 10ms so that does not make any difference what so ever. - -Signed-off-by: Martin Sperl ---- - drivers/spi/spi-bcm2835.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 44ee1f3..1a915e5 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, - unsigned long xfer_time_us) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); -- unsigned long timeout = jiffies + -- max(4 * xfer_time_us * HZ / 1000000, 2uL); -+ /* set timeout to 1 second of maximum polling */ -+ unsigned long timeout = jiffies + HZ; - - /* enable HW block without interrupts */ - bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); - -- /* set timeout to 4x the expected time, or 2 jiffies */ - /* loop until finished the transfer */ - while (bs->rx_len) { - /* read from fifo as much as possible */ - -From a53606a32ae4bdadc08985d0a67a6924c09633f1 Mon Sep 17 00:00:00 2001 +From 7de29243d1ac891a526c77e17129d6e2d547361d Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 116/216] smsx95xx: fix crimes against truesize +Subject: [PATCH 65/77] smsx95xx: fix crimes against truesize smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. @@ -132315,10 +130809,10 @@ index e29a323..aff63dc usbnet_skb_return(dev, ax_skb); } -From a6f41e34aeb0834ce943e48ee5f6655716dd53c4 Mon Sep 17 00:00:00 2001 +From 4772a6e4cc3921cb41515b7b0a91ad646d1491aa Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 17 Apr 2015 16:58:45 +0100 -Subject: [PATCH 117/216] smsc95xx: Disable turbo mode by default +Subject: [PATCH 66/77] smsc95xx: Disable turbo mode by default --- drivers/net/usb/smsc95xx.c | 2 +- @@ -132338,133 +130832,10 @@ index aff63dc..08a8a8c 100755 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); -From d8512fe40402051a7fb3ec7e7ad25f38d0abab65 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Wed, 18 Mar 2015 18:06:52 +0100 -Subject: [PATCH 118/216] HiFiBerry Digi: set SPDIF status bits for sample rate - -The HiFiBerry Digi driver did not signal the sample rate in the SPDIF status bits. -While this is optional, some DACs and receivers do not accept this signal. This patch -adds the sample rate bits in the SPDIF status block. ---- - sound/soc/bcm/hifiberry_digi.c | 28 ++++++++++++++++++++++++---- - 1 file changed, 24 insertions(+), 4 deletions(-) - -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index a294a1b..80732b8 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -74,24 +74,41 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - - long mclk_freq=0; - int mclk_div=1; -+ int sampling_freq=1; - - int ret; - - samplerate = params_rate(params); - -+ if (samplerate<=96000) { -+ mclk_freq=samplerate*256; -+ mclk_div=WM8804_MCLKDIV_256FS; -+ } else { -+ mclk_freq=samplerate*128; -+ mclk_div=WM8804_MCLKDIV_128FS; -+ } -+ - switch (samplerate) { - case 32000: -+ sampling_freq=0x03; -+ break; - case 44100: -+ sampling_freq=0x00; -+ break; - case 48000: -+ sampling_freq=0x02; -+ break; - case 88200: -+ sampling_freq=0x08; -+ break; - case 96000: -- mclk_freq=samplerate*256; -- mclk_div=WM8804_MCLKDIV_256FS; -+ sampling_freq=0x0a; - break; - case 176400: -+ sampling_freq=0x0c; -+ break; - case 192000: -- mclk_freq=samplerate*128; -- mclk_div=WM8804_MCLKDIV_128FS; -+ sampling_freq=0x0e; - break; - default: - dev_err(codec->dev, -@@ -116,6 +133,9 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - /* Power on */ - snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); - -+ /* set sampling frequency status bits */ -+ snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq); -+ - return snd_soc_dai_set_bclk_ratio(cpu_dai,64); - } - - -From 496a822ba4493536df3181be27d4b2d2906d4fde Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 18 Apr 2015 17:20:14 +0100 -Subject: [PATCH 119/216] bcm2708-dmaengine: Add debug options - ---- - drivers/dma/bcm2708-dmaengine.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 6150b8f..8182b16 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -56,6 +56,7 @@ - - #include "virt-dma.h" - -+static unsigned dma_debug; - - struct bcm2835_dmadev { - struct dma_device ddev; -@@ -600,7 +601,10 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( - } - - /* Common part */ -- control_block->info |= BCM2835_DMA_WAITS(SDHCI_BCM_DMA_WAITS); -+ u32 waits = SDHCI_BCM_DMA_WAITS; -+ if ((dma_debug >> 0) & 0x1f) -+ waits = (dma_debug >> 0) & 0x1f; -+ control_block->info |= BCM2835_DMA_WAITS(waits); - control_block->info |= BCM2835_DMA_WAIT_RESP; - - /* Enable */ -@@ -952,6 +956,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - } - - dev_info(&pdev->dev, "Load BCM2835 DMA engine driver\n"); -+ dev_info(&pdev->dev, "dma_debug:%x\n", dma_debug); - - return 0; - -@@ -982,6 +987,7 @@ static struct platform_driver bcm2835_dma_driver = { - - module_platform_driver(bcm2835_dma_driver); - -+module_param(dma_debug, uint, 0644); - MODULE_ALIAS("platform:bcm2835-dma"); - MODULE_DESCRIPTION("BCM2835 DMA engine driver"); - MODULE_AUTHOR("Florian Meier "); - -From 4dc3a781a0d5718153bc38b1f1294523d44b8f66 Mon Sep 17 00:00:00 2001 +From 9d1fbb7b2dbe16c506f54984c361a55d1b2603fb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Apr 2015 19:30:22 +0100 -Subject: [PATCH 120/216] Add blk_pos parameter to mmc multi_io_quirk callback +Subject: [PATCH 67/77] Add blk_pos parameter to mmc multi_io_quirk callback --- drivers/mmc/card/block.c | 1 + @@ -132475,7 +130846,7 @@ Subject: [PATCH 120/216] Add blk_pos parameter to mmc multi_io_quirk callback 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index ed2e71a..ce854a9 100644 +index 60f7141..1f15cb5 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1413,6 +1413,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, @@ -132487,10 +130858,10 @@ index ed2e71a..ce854a9 100644 } diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index f84cfb0..fec8c12 100644 +index 9df2b68..8c0ee4a 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1798,7 +1798,9 @@ static int omap_hsmmc_disable_fclk(struct mmc_host *mmc) +@@ -1749,7 +1749,9 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) } static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, @@ -132502,7 +130873,7 @@ index f84cfb0..fec8c12 100644 /* This controller can't do multiblock reads due to hw bugs */ if (direction == MMC_DATA_READ) diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c -index 6906a90..1fb7577 100644 +index 354f4f3..4f1ccf3 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -170,7 +170,9 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) @@ -132532,10 +130903,10 @@ index dba7e1c..0c87f4f 100644 struct tmio_mmc_host *host = mmc_priv(card->host); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index c3b84a2..c1c3868f 100644 +index b0258e8..d3cdad9 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h -@@ -146,7 +146,9 @@ struct mmc_host_ops { +@@ -140,7 +140,9 @@ struct mmc_host_ops { * I/O. Returns the number of supported blocks for the request. */ int (*multi_io_quirk)(struct mmc_card *card, @@ -132547,3870 +130918,10 @@ index c3b84a2..c1c3868f 100644 struct mmc_card; -From 12b12cf1a7a825c46dcefa06bdde683cac053189 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 121/216] Adding bcm2835-sdhost driver, and an overlay to - enable it - -BCM2835 has two SD card interfaces. This driver uses the other one. ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/sdhost-overlay.dts | 73 ++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/mmc/host/Kconfig | 10 + - drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 1685 ++++++++++++++++++++++++++++++++++ - 7 files changed, 1772 insertions(+) - create mode 100644 arch/arm/boot/dts/sdhost-overlay.dts - create mode 100644 drivers/mmc/host/bcm2835-sdhost.c - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 980b78e0..9cb5a2d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -34,6 +34,7 @@ dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -diff --git a/arch/arm/boot/dts/sdhost-overlay.dts b/arch/arm/boot/dts/sdhost-overlay.dts -new file mode 100644 -index 0000000..33db96e ---- /dev/null -+++ b/arch/arm/boot/dts/sdhost-overlay.dts -@@ -0,0 +1,73 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sdhost: sdhost@7e202000 { -+ compatible = "brcm,bcm2835-sdhost"; -+ reg = <0x7e202000 0x100>; -+ interrupts = <2 24>; -+ clocks = <&clk_sdhost>; -+ dmas = <&dma 13>, -+ <&dma 13>; -+ dma-names = "tx", "rx"; -+ brcm,delay-after-stop = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ status = "okay"; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_sdhost: clock@3 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mmc>; -+ __overlay__ { -+ /* Find a way to disable the other driver */ -+ compatible = ""; -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/__overrides__"; -+ __overlay__ { -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+ }; -+ -+ __overrides__ { -+ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ force_pio = <&sdhost>,"brcm,force-pio?"; -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7cec5f8..367a04a 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -956,6 +956,7 @@ CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 - CONFIG_MMC_BCM2835=y - CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SPI=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e77173b..db287f3 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -949,6 +949,7 @@ CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 - CONFIG_MMC_BCM2835=y - CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SPI=m -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 7c093a6..1666c6c 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER - - If unsure, say 2 here. - -+config MMC_BCM2835_SDHOST -+ tristate "Support for the SDHost controller on BCM2708/9" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ help -+ This selects the SDHost controller on BCM2835/6. -+ -+ If you have a controller with this interface, say Y or M here. -+ -+ If unsure, say N. -+ - config MMC_ARMMMCI - tristate "ARM AMBA Multimedia Card Interface support" - depends on ARM_AMBA -diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 9d41de9..8a7e43e 100644 ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o - obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o - obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o - obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o -+obj-$(CONFIG_MMC_BCM2835_SDHOST) += bcm2835-sdhost.o - obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o - obj-$(CONFIG_MMC_WBSD) += wbsd.o - obj-$(CONFIG_MMC_AU1X) += au1xmmc.o -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -new file mode 100644 -index 0000000..0c311b5 ---- /dev/null -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -0,0 +1,1685 @@ -+/* -+ * BCM2835 SD host driver. -+ * -+ * Author: Phil Elwell -+ * Copyright 2015 -+ * -+ * Based on -+ * mmc-bcm2835.c by Gellert Weisz -+ * which is, in turn, based on -+ * sdhci-bcm2708.c by Broadcom -+ * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko -+ * sdhci.c and sdhci-pci.c by Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#define SAFE_READ_THRESHOLD 4 -+#define SAFE_WRITE_THRESHOLD 4 -+#define ALLOW_DMA 1 -+#define ALLOW_CMD23 0 -+#define ALLOW_FAST 1 -+#define USE_BLOCK_IRQ 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "sdhost-bcm2835" -+ -+#define SDCMD 0x00 /* Command to SD card - 16 R/W */ -+#define SDARG 0x04 /* Argument to SD card - 32 R/W */ -+#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */ -+#define SDCDIV 0x0c /* Start value for clock divider - 11 R/W */ -+#define SDRSP0 0x10 /* SD card response (31:0) - 32 R */ -+#define SDRSP1 0x14 /* SD card response (63:32) - 32 R */ -+#define SDRSP2 0x18 /* SD card response (95:64) - 32 R */ -+#define SDRSP3 0x1c /* SD card response (127:96) - 32 R */ -+#define SDHSTS 0x20 /* SD host status - 11 R */ -+#define SDVDD 0x30 /* SD card power control - 1 R/W */ -+#define SDEDM 0x34 /* Emergency Debug Mode - 13 R/W */ -+#define SDHCFG 0x38 /* Host configuration - 2 R/W */ -+#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */ -+#define SDDATA 0x40 /* Data to/from SD card - 32 R/W */ -+#define SDHBLC 0x50 /* Host block count (SDIO/SDHC) - 9 R/W */ -+ -+#define SDCMD_NEW_FLAG 0x8000 -+#define SDCMD_FAIL_FLAG 0x4000 -+#define SDCMD_BUSYWAIT 0x800 -+#define SDCMD_NO_RESPONSE 0x400 -+#define SDCMD_LONG_RESPONSE 0x200 -+#define SDCMD_WRITE_CMD 0x80 -+#define SDCMD_READ_CMD 0x40 -+#define SDCMD_CMD_MASK 0x3f -+ -+#define SDCDIV_MAX_CDIV 0x7ff -+ -+#define SDHSTS_BUSY_IRPT 0x400 -+#define SDHSTS_BLOCK_IRPT 0x200 -+#define SDHSTS_SDIO_IRPT 0x100 -+#define SDHSTS_REW_TIME_OUT 0x80 -+#define SDHSTS_CMD_TIME_OUT 0x40 -+#define SDHSTS_CRC16_ERROR 0x20 -+#define SDHSTS_CRC7_ERROR 0x10 -+#define SDHSTS_FIFO_ERROR 0x08 -+/* Reserved */ -+/* Reserved */ -+#define SDHSTS_DATA_FLAG 0x01 -+ -+#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) -+#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) -+/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ -+ -+#define SDHCFG_BUSY_IRPT_EN (1<<10) -+#define SDHCFG_BLOCK_IRPT_EN (1<<8) -+#define SDHCFG_SDIO_IRPT_EN (1<<5) -+#define SDHCFG_DATA_IRPT_EN (1<<4) -+#define SDHCFG_SLOW_CARD (1<<3) -+#define SDHCFG_WIDE_EXT_BUS (1<<2) -+#define SDHCFG_WIDE_INT_BUS (1<<1) -+#define SDHCFG_REL_CMD_LINE (1<<0) -+ -+#define SDEDM_FORCE_DATA_MODE (1<<19) -+#define SDEDM_CLOCK_PULSE (1<<20) -+#define SDEDM_BYPASS (1<<21) -+ -+#define SDEDM_WRITE_THRESHOLD_SHIFT 9 -+#define SDEDM_READ_THRESHOLD_SHIFT 14 -+#define SDEDM_THRESHOLD_MASK 0x1f -+ -+/* the inclusive limit in bytes under which PIO will be used instead of DMA */ -+#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#else -+#define PIO_DMA_BARRIER 0 -+#endif -+ -+#define MIN_FREQ 400000 -+#define TIMEOUT_VAL 0xE -+#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) -+ -+#ifndef BCM2708_PERI_BASE -+ #define BCM2708_PERI_BASE 0x20000000 -+#endif -+ -+/* FIXME: Needs IOMMU support */ -+#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) -+ -+ -+struct bcm2835_host { -+ spinlock_t lock; -+ -+ void __iomem *ioaddr; -+ u32 phys_addr; -+ -+ struct mmc_host *mmc; -+ -+ u32 timeout; -+ -+ int clock; /* Current clock speed */ -+ -+ bool slow_card; /* Force 11-bit divisor */ -+ -+ unsigned int max_clk; /* Max possible freq */ -+ unsigned int timeout_clk; /* Timeout freq (KHz) */ -+ -+ struct tasklet_struct finish_tasklet; /* Tasklet structures */ -+ -+ struct timer_list timer; /* Timer for timeouts */ -+ -+ struct sg_mapping_iter sg_miter; /* SG state for PIO */ -+ unsigned int blocks; /* remaining PIO blocks */ -+ -+ int irq; /* Device IRQ */ -+ -+ -+ /* cached registers */ -+ u32 hcfg; -+ u32 cdiv; -+ -+ struct mmc_request *mrq; /* Current request */ -+ struct mmc_command *cmd; /* Current command */ -+ struct mmc_data *data; /* Current data request */ -+ unsigned int data_complete:1; /* Data finished before cmd */ -+ -+ unsigned int flush_fifo:1; /* Drain the fifo when finishing */ -+ -+ unsigned int use_busy:1; /* Wait for busy interrupt */ -+ -+ u32 thread_isr; -+ -+ /*DMA part*/ -+ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -+ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -+ -+ bool allow_dma; -+ bool have_dma; -+ bool use_dma; -+ /*end of DMA part*/ -+ -+ int max_delay; /* maximum length of time spent waiting */ -+ struct timeval stop_time; /* when the last stop was issued */ -+ u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ -+}; -+ -+ -+static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) -+{ -+ writel(val, host->ioaddr + reg); -+} -+ -+static inline u32 bcm2835_sdhost_read(struct bcm2835_host *host, int reg) -+{ -+ return readl(host->ioaddr + reg); -+} -+ -+static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg) -+{ -+ return readl_relaxed(host->ioaddr + reg); -+} -+ -+static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) -+{ -+ pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", -+ mmc_hostname(host->mmc)); -+ -+ pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", -+ bcm2835_sdhost_read(host, SDCMD)); -+ pr_info(DRIVER_NAME ": SDARG 0x%08x\n", -+ bcm2835_sdhost_read(host, SDARG)); -+ pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", -+ bcm2835_sdhost_read(host, SDTOUT)); -+ pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", -+ bcm2835_sdhost_read(host, SDCDIV)); -+ pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP0)); -+ pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP1)); -+ pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP2)); -+ pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP3)); -+ pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHSTS)); -+ pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", -+ bcm2835_sdhost_read(host, SDVDD)); -+ pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", -+ bcm2835_sdhost_read(host, SDEDM)); -+ pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHCFG)); -+ pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHBCT)); -+ pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHBLC)); -+ -+ pr_debug(DRIVER_NAME ": ===========================================\n"); -+} -+ -+ -+static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) -+{ -+ bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); -+} -+ -+ -+static void bcm2835_sdhost_reset(struct bcm2835_host *host) -+{ -+ u32 temp; -+ -+ pr_debug("bcm2835_sdhost_reset\n"); -+ -+ bcm2835_sdhost_set_power(host, false); -+ -+ bcm2835_sdhost_write(host, 0, SDCMD); -+ bcm2835_sdhost_write(host, 0, SDARG); -+ bcm2835_sdhost_write(host, 0xf00000, SDTOUT); -+ bcm2835_sdhost_write(host, 0, SDCDIV); -+ bcm2835_sdhost_write(host, 0x7f8, SDHSTS); /* Write 1s to clear */ -+ bcm2835_sdhost_write(host, 0, SDHCFG); -+ bcm2835_sdhost_write(host, 0, SDHBCT); -+ bcm2835_sdhost_write(host, 0, SDHBLC); -+ -+ /* Limit fifo usage due to silicon bug */ -+ temp = bcm2835_sdhost_read(host, SDEDM); -+ temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ mmiowb(); -+} -+ -+static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); -+ -+static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) -+{ -+ pr_debug("bcm2835_sdhost_init(%d)\n", soft); -+ -+ /* Set interrupt enables */ -+ host->hcfg = SDHCFG_BUSY_IRPT_EN; -+ -+ bcm2835_sdhost_reset(host); -+ -+ if (soft) { -+ /* force clock reconfiguration */ -+ host->clock = 0; -+ bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); -+ } -+} -+ -+static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) -+{ -+ bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); -+ -+ if (!write_complete) { -+ /* Request an IRQ for the last block */ -+ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { -+ /* The write has now completed. Disable the interrupt -+ and clear the status flag */ -+ host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); -+ write_complete = true; -+ } -+ } -+ -+ return write_complete; -+} -+ -+static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) -+{ -+ int timediff; -+#ifdef DEBUG -+ static struct timeval start_time; -+ static int max_stall_time = 0; -+ static int total_stall_time = 0; -+ struct timeval before, after; -+ -+ do_gettimeofday(&before); -+ if (max_stall_time == 0) -+ start_time = before; -+#endif -+ -+ timediff = 0; -+ -+ while (1) { -+ u32 edm = bcm2835_sdhost_read(host, SDEDM); -+ if ((edm & 0xf) == 1) -+ break; -+ timediff++; -+ if (timediff > 5000000) { -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); -+ -+ pr_err(" wait_write_complete - still waiting after %dus\n", -+ timediff); -+#else -+ pr_err(" wait_write_complete - still waiting after %d retries\n", -+ timediff); -+#endif -+ bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; -+ return; -+ } -+ } -+ -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); -+ -+ total_stall_time += timediff; -+ if (timediff > max_stall_time) -+ max_stall_time = timediff; -+ -+ if ((after.tv_sec - start_time.tv_sec) > 10) { -+ pr_debug(" wait_write_complete - max wait %dus, total %dus\n", -+ max_stall_time, total_stall_time); -+ start_time = after; -+ max_stall_time = 0; -+ total_stall_time = 0; -+ } -+#endif -+} -+ -+static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); -+ -+static void bcm2835_sdhost_dma_complete(void *param) -+{ -+ struct bcm2835_host *host = param; -+ struct dma_chan *dma_chan; -+ unsigned long flags; -+ u32 dir_data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->data) { -+ bool write_complete; -+ if (USE_BLOCK_IRQ) -+ write_complete = bcm2835_sdhost_is_write_complete(host); -+ else { -+ bcm2835_sdhost_wait_write_complete(host); -+ write_complete = true; -+ } -+ pr_debug("dma_complete() - write_complete=%d\n", -+ write_complete); -+ -+ if (write_complete || (host->data->flags & MMC_DATA_READ)) -+ { -+ if (write_complete) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ } else { -+ dma_chan = host->dma_chan_rx; -+ dir_data = DMA_FROM_DEVICE; -+ } -+ -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ } -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) -+{ -+ unsigned long flags; -+ size_t blksize, len; -+ u32 *buf; -+ -+ blksize = host->data->blksz; -+ -+ local_irq_save(flags); -+ -+ while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); -+ -+ len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); -+ -+ blksize -= len; -+ host->sg_miter.consumed = len; -+ -+ buf = (u32 *)host->sg_miter.addr; -+ -+ while (len) { -+ while (1) { -+ u32 hsts; -+ hsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (hsts & SDHSTS_DATA_FLAG) -+ break; -+ -+ if (hsts & SDHSTS_ERROR_MASK) { -+ pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", -+ mmc_hostname(host->mmc), -+ hsts, -+ bcm2835_sdhost_read(host, SDHBCT), -+ blksize + len); -+ if (hsts & SDHSTS_REW_TIME_OUT) -+ host->data->error = -ETIMEDOUT; -+ else if (hsts & (SDHSTS_CRC16_ERROR || -+ SDHSTS_CRC7_ERROR)) -+ host->data->error = -EILSEQ; -+ else { -+ pr_err("%s: unexpected data error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ } -+ } -+ } -+ -+ *(buf++) = bcm2835_sdhost_read(host, SDDATA); -+ len -= 4; -+ } -+ } -+ -+ sg_miter_stop(&host->sg_miter); -+ -+ local_irq_restore(flags); -+} -+ -+static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) -+{ -+ unsigned long flags; -+ size_t blksize, len; -+ u32 *buf; -+ -+ blksize = host->data->blksz; -+ -+ local_irq_save(flags); -+ -+ while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); -+ -+ len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); -+ -+ blksize -= len; -+ host->sg_miter.consumed = len; -+ -+ buf = host->sg_miter.addr; -+ -+ while (len) { -+ while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) -+ continue; -+ bcm2835_sdhost_write(host, *(buf++), SDDATA); -+ len -= 4; -+ } -+ } -+ -+ sg_miter_stop(&host->sg_miter); -+ -+ local_irq_restore(flags); -+} -+ -+ -+static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) -+{ -+ BUG_ON(!host->data); -+ -+ if (host->data->flags & MMC_DATA_READ) -+ bcm2835_sdhost_read_block_pio(host); -+ else -+ bcm2835_sdhost_write_block_pio(host); -+} -+ -+ -+static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) -+{ -+ u32 len, dir_data, dir_slave; -+ struct dma_async_tx_descriptor *desc = NULL; -+ struct dma_chan *dma_chan; -+ -+ pr_debug("bcm2835_sdhost_transfer_dma()\n"); -+ -+ WARN_ON(!host->data); -+ -+ if (!host->data) -+ return; -+ -+ if (host->data->flags & MMC_DATA_READ) { -+ dma_chan = host->dma_chan_rx; -+ dir_data = DMA_FROM_DEVICE; -+ dir_slave = DMA_DEV_TO_MEM; -+ } else { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ dir_slave = DMA_MEM_TO_DEV; -+ } -+ -+ BUG_ON(!dma_chan->device); -+ BUG_ON(!dma_chan->device->dev); -+ BUG_ON(!host->data->sg); -+ -+ len = dma_map_sg(dma_chan->device->dev, host->data->sg, -+ host->data->sg_len, dir_data); -+ if (len > 0) { -+ desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, -+ len, dir_slave, -+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -+ } else { -+ dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); -+ } -+ if (desc) { -+ desc->callback = bcm2835_sdhost_dma_complete; -+ desc->callback_param = host; -+ dmaengine_submit(desc); -+ dma_async_issue_pending(dma_chan); -+ } -+ -+} -+ -+ -+static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) -+{ -+ u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | -+ SDHCFG_BUSY_IRPT_EN; -+ if (host->use_dma) -+ host->hcfg = (host->hcfg & ~all_irqs) | -+ SDHCFG_BUSY_IRPT_EN; -+ else -+ host->hcfg = (host->hcfg & ~all_irqs) | -+ SDHCFG_DATA_IRPT_EN | -+ SDHCFG_BUSY_IRPT_EN; -+ -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+} -+ -+ -+static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) -+{ -+ struct mmc_data *data = cmd->data; -+ -+ WARN_ON(host->data); -+ -+ if (!data) -+ return; -+ -+ /* Sanity checks */ -+ BUG_ON(data->blksz * data->blocks > 524288); -+ BUG_ON(data->blksz > host->mmc->max_blk_size); -+ BUG_ON(data->blocks > 65535); -+ -+ host->data = data; -+ host->data_complete = 0; -+ host->flush_fifo = 0; -+ host->data->bytes_xfered = 0; -+ -+ if (!host->use_dma) { -+ int flags; -+ -+ flags = SG_MITER_ATOMIC; -+ if (data->flags & MMC_DATA_READ) -+ flags |= SG_MITER_TO_SG; -+ else -+ flags |= SG_MITER_FROM_SG; -+ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); -+ host->blocks = data->blocks; -+ } -+ -+ host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; -+ -+ bcm2835_sdhost_set_transfer_irqs(host); -+ -+ bcm2835_sdhost_write(host, data->blksz, SDHBCT); -+ if (host->use_dma) -+ bcm2835_sdhost_write(host, data->blocks, SDHBLC); -+ -+ BUG_ON(!host->data); -+} -+ -+ -+void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) -+{ -+ u32 sdcmd; -+ unsigned long timeout; -+ -+ WARN_ON(host->cmd); -+ -+ if (1) { -+ pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", -+ cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); -+ if (cmd->data) -+ pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ } -+ -+ /* Wait max 10 ms */ -+ timeout = 1000; -+ -+ while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { -+ if (timeout == 0) { -+ pr_err("%s: Previous command never completed.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ timeout--; -+ udelay(10); -+ } -+ -+ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { -+ host->max_delay = (1000-timeout)/100; -+ pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); -+ } -+ -+ timeout = jiffies; -+#ifdef CONFIG_ARCH_BCM2835 -+ if (!cmd->data && cmd->busy_timeout > 9000) -+ timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; -+ else -+#endif -+ timeout += 10 * HZ; -+ mod_timer(&host->timer, timeout); -+ -+ host->cmd = cmd; -+ -+ bcm2835_sdhost_prepare_data(host, cmd); -+ -+ bcm2835_sdhost_write(host, cmd->arg, SDARG); -+ -+ if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { -+ pr_err("%s: Unsupported response type!\n", -+ mmc_hostname(host->mmc)); -+ cmd->error = -EINVAL; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ -+ sdcmd = cmd->opcode & SDCMD_CMD_MASK; -+ -+ if (!(cmd->flags & MMC_RSP_PRESENT)) -+ sdcmd |= SDCMD_NO_RESPONSE; -+ else { -+ if (cmd->flags & MMC_RSP_136) -+ sdcmd |= SDCMD_LONG_RESPONSE; -+ if (cmd->flags & MMC_RSP_BUSY) { -+ sdcmd |= SDCMD_BUSYWAIT; -+ host->use_busy = 1; -+ } -+ } -+ -+ if (cmd->data) { -+ if (host->delay_after_stop) { -+ struct timeval now; -+ int time_since_stop; -+ do_gettimeofday(&now); -+ time_since_stop = (now.tv_sec - host->stop_time.tv_sec); -+ if (time_since_stop < 2) { -+ /* Possibly less than one second */ -+ time_since_stop = time_since_stop * 1000000 + -+ (now.tv_usec - host->stop_time.tv_usec); -+ if (time_since_stop < host->delay_after_stop) -+ udelay(host->delay_after_stop - -+ time_since_stop); -+ } -+ } -+ -+ if (cmd->data->flags & MMC_DATA_WRITE) -+ sdcmd |= SDCMD_WRITE_CMD; -+ if (cmd->data->flags & MMC_DATA_READ) -+ sdcmd |= SDCMD_READ_CMD; -+ } -+ -+ bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); -+} -+ -+ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); -+static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); -+ -+static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) -+{ -+ struct mmc_data *data; -+ -+ data = host->data; -+ BUG_ON(!data); -+ -+ pr_debug("finish_data(error %d, stop %d, sbc %d)\n", -+ data->error, data->stop ? 1 : 0, -+ host->mrq->sbc ? 1 : 0); -+ -+ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ -+ if (data->error) { -+ data->bytes_xfered = 0; -+ } else -+ data->bytes_xfered = data->blksz * data->blocks; -+ -+ host->data_complete = 1; -+ -+ if (host->cmd) { -+ /* -+ * Data managed to finish before the -+ * command completed. Make sure we do -+ * things in the proper order. -+ */ -+ pr_debug("Finished early - HSTS %x\n", -+ bcm2835_sdhost_read(host, SDHSTS)); -+ } -+ else -+ bcm2835_sdhost_transfer_complete(host); -+} -+ -+ -+static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) -+{ -+ struct mmc_data *data; -+ -+ BUG_ON(host->cmd); -+ BUG_ON(!host->data); -+ BUG_ON(!host->data_complete); -+ -+ data = host->data; -+ host->data = NULL; -+ -+ pr_debug("transfer_complete(error %d, stop %d)\n", -+ data->error, data->stop ? 1 : 0); -+ -+ if (data->error) -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ bcm2835_sdhost_reset(host); -+ -+ /* -+ * Need to send CMD12 if - -+ * a) open-ended multiblock transfer (no CMD23) -+ * b) error in multiblock transfer -+ */ -+ if (data->stop && -+ (data->error || -+ !host->mrq->sbc)) { -+ host->flush_fifo = 1; -+ bcm2835_sdhost_send_command(host, data->stop); -+ if (host->delay_after_stop) -+ do_gettimeofday(&host->stop_time); -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+ } else { -+ tasklet_schedule(&host->finish_tasklet); -+ } -+} -+ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) -+{ -+ u32 sdcmd; -+ int timeout = 1000; -+#ifdef DEBUG -+ struct timeval before, after; -+ int timediff = 0; -+#endif -+ -+ pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); -+ -+ BUG_ON(!host->cmd || !host->mrq); -+ -+#ifdef DEBUG -+ do_gettimeofday(&before); -+#endif -+ for (sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ (sdcmd & SDCMD_NEW_FLAG) && timeout; -+ timeout--) { -+ if (host->flush_fifo) { -+ while (bcm2835_sdhost_read(host, SDHSTS) & -+ SDHSTS_DATA_FLAG) -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ udelay(10); -+ sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ } -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); -+ -+ pr_debug(" finish_command - waited %dus\n", timediff); -+#endif -+ -+ if (timeout == 0) { -+ pr_err("%s: Command never completed.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ -+ if (host->flush_fifo) { -+ for (timeout = 100; -+ (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; -+ timeout--) { -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ host->flush_fifo = 0; -+ if (timeout == 0) { -+ pr_err("%s: FIFO never drained.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ } -+ -+ /* Check for errors */ -+ if (sdcmd & SDCMD_FAIL_FLAG) -+ { -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ -+ pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -+ mmc_hostname(host->mmc), sdcmd, sdhsts, -+ bcm2835_sdhost_read(host, SDEDM)); -+ -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ { -+ pr_err("%s: unexpected command error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ } -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ -+ if (host->cmd->flags & MMC_RSP_PRESENT) { -+ if (host->cmd->flags & MMC_RSP_136) { -+ int i; -+ for (i = 0; i < 4; i++) -+ host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); -+ pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", -+ host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); -+ } else { -+ host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); -+ pr_debug("bcm2835_sdhost_finish_command: %08x\n", -+ host->cmd->resp[0]); -+ } -+ } -+ -+ host->cmd->error = 0; -+ -+ if (host->cmd == host->mrq->sbc) { -+ /* Finished CMD23, now send actual command. */ -+ host->cmd = NULL; -+ bcm2835_sdhost_send_command(host, host->mrq->cmd); -+ -+ if (host->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+ } else if (host->cmd == host->mrq->stop) -+ /* Finished CMD12 */ -+ tasklet_schedule(&host->finish_tasklet); -+ else { -+ /* Processed actual command. */ -+ host->cmd = NULL; -+ if (!host->data) -+ tasklet_schedule(&host->finish_tasklet); -+ else if (host->data_complete) -+ bcm2835_sdhost_transfer_complete(host); -+ } -+} -+ -+static void bcm2835_sdhost_timeout_timer(unsigned long data) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ host = (struct bcm2835_host *)data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->mrq) { -+ pr_err("%s: Timeout waiting for hardware interrupt.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ -+ if (host->data) { -+ host->data->error = -ETIMEDOUT; -+ bcm2835_sdhost_finish_data(host); -+ } else { -+ if (host->cmd) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ host->mrq->cmd->error = -ETIMEDOUT; -+ -+ pr_debug("timeout_timer tasklet_schedule\n"); -+ tasklet_schedule(&host->finish_tasklet); -+ } -+ } -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) -+{ -+ if (enable) -+ host->hcfg |= SDHCFG_SDIO_IRPT_EN; -+ else -+ host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ mmiowb(); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ -+ pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); -+ spin_lock_irqsave(&host->lock, flags); -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ -+ if (!host->cmd) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " -+ "though no command operation was in progress.\n", -+ mmc_hostname(host->mmc), (unsigned)intmask); -+ bcm2835_sdhost_dumpregs(host); -+ return 0; -+ } -+ -+ if (!host->use_busy) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " -+ "though not expecting one.\n", -+ mmc_hostname(host->mmc), (unsigned)intmask); -+ bcm2835_sdhost_dumpregs(host); -+ return 0; -+ } -+ host->use_busy = 0; -+ -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->cmd->error = -EILSEQ; -+ -+ if (host->cmd->error) -+ tasklet_schedule(&host->finish_tasklet); -+ else -+ bcm2835_sdhost_finish_command(host); -+ -+ return handled; -+} -+ -+static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ -+ /* There are no dedicated data/space available interrupt -+ status bits, so it is necessary to use the single shared -+ data/space available FIFO status bits. It is therefore not -+ an error to get here when there is no data transfer in -+ progress. */ -+ if (!host->data) -+ return 0; -+ -+ // XXX FIFO_ERROR -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; -+ -+ /* Use the block interrupt for writes after the first block */ -+ if (!(host->data->flags & MMC_DATA_READ)) { -+ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); -+ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if (host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ bcm2835_sdhost_transfer_pio(host); -+ } else { -+ if (!host->data->error) { -+ bcm2835_sdhost_transfer_pio(host); -+ host->blocks--; -+ } -+ if ((host->blocks == 0) || host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ return handled; -+} -+ -+static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ struct dma_chan *dma_chan; -+ u32 dir_data; -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ -+ if (!host->data) { -+ pr_err("%s: Got block interrupt 0x%08x even " -+ "though no data operation was in progress.\n", -+ mmc_hostname(host->mmc), (unsigned)intmask); -+ bcm2835_sdhost_dumpregs(host); -+ return handled; -+ } -+ -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; -+ -+ if (!host->use_dma) { -+ BUG_ON(!host->blocks); -+ host->blocks--; -+ if ((host->blocks == 0) || host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ else -+ bcm2835_sdhost_transfer_pio(host); -+ } else if (host->data->flags & MMC_DATA_WRITE) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ return handled; -+} -+ -+ -+static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) -+{ -+ irqreturn_t result = IRQ_NONE; -+ struct bcm2835_host *host = dev_id; -+ u32 unexpected = 0, early = 0; -+ int loops = 0; -+#ifndef CONFIG_ARCH_BCM2835 -+ int cardint = 0; -+#endif -+ spin_lock(&host->lock); -+ -+ for (loops = 0; loops < 1; loops++) { -+ u32 intmask, handled; -+ -+ intmask = bcm2835_sdhost_read(host, SDHSTS); -+ handled = intmask & (SDHSTS_BUSY_IRPT | -+ SDHSTS_BLOCK_IRPT | -+ SDHSTS_SDIO_IRPT | -+ SDHSTS_DATA_FLAG); -+ if ((handled == SDHSTS_DATA_FLAG) && // XXX -+ (loops == 0) && !host->data) { -+ pr_err("%s: sdhost_irq data interrupt 0x%08x even " -+ "though no data operation was in progress.\n", -+ mmc_hostname(host->mmc), -+ (unsigned)intmask); -+ -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ if (loops) -+ early |= handled; -+ -+ if (!handled) -+ break; -+ -+ result = IRQ_HANDLED; -+ -+ /* Clear all interrupts and notifications */ -+ bcm2835_sdhost_write(host, intmask, SDHSTS); -+ -+ if (intmask & SDHSTS_BUSY_IRPT) -+ handled |= bcm2835_sdhost_busy_irq(host, intmask); -+ -+ /* There is no true data interrupt status bit, so it is -+ necessary to qualify the data flag with the interrupt -+ enable bit */ -+ if ((intmask & SDHSTS_DATA_FLAG) && -+ (host->hcfg & SDHCFG_DATA_IRPT_EN)) -+ handled |= bcm2835_sdhost_data_irq(host, intmask); -+ -+ if (intmask & SDHSTS_BLOCK_IRPT) -+ handled |= bcm2835_sdhost_block_irq(host, intmask); -+ -+ if (intmask & SDHSTS_SDIO_IRPT) { -+#ifndef CONFIG_ARCH_BCM2835 -+ cardint = 1; -+#else -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, false); -+ host->thread_isr |= SDHSTS_SDIO_IRPT; -+ result = IRQ_WAKE_THREAD; -+#endif -+ } -+ -+ unexpected |= (intmask & ~handled); -+ } -+ -+ mmiowb(); -+ -+ spin_unlock(&host->lock); -+ -+ if (early) -+ pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); -+ -+ if (unexpected) { -+ pr_err("%s: Unexpected interrupt 0x%08x.\n", -+ mmc_hostname(host->mmc), unexpected); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+#ifndef CONFIG_ARCH_BCM2835 -+ if (cardint) -+ mmc_signal_sdio_irq(host->mmc); -+#endif -+ -+ return result; -+} -+ -+#ifdef CONFIG_ARCH_BCM2835 -+static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) -+{ -+ struct bcm2835_host *host = dev_id; -+ unsigned long flags; -+ u32 isr; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ isr = host->thread_isr; -+ host->thread_isr = 0; -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (isr & SDHSTS_SDIO_IRPT) { -+ sdio_run_irqs(host->mmc); -+ -+/* Is this necessary? Why re-enable an interrupt which is enabled? -+ spin_lock_irqsave(&host->lock, flags); -+ if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, true); -+ spin_unlock_irqrestore(&host->lock, flags); -+*/ -+ } -+ -+ return isr ? IRQ_HANDLED : IRQ_NONE; -+} -+#endif -+ -+ -+ -+void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) -+{ -+ int div = 0; /* Initialized for compiler warning */ -+ -+ /* The SDCDIV register has 11 bits, and holds (div - 2). -+ But in data mode the max is 50MHz wihout a minimum, and only the -+ bottom 3 bits are used. Since the switch over is automatic (unless -+ we have marked the card as slow...), chosen values have to make -+ sense in both modes. -+ Ident mode must be 100-400KHz, so can range check the requested -+ clock. CMD15 must be used to return to data mode, so this can be -+ monitored. -+ -+ clock 250MHz -> 0->125MHz, 1->83.3MHz, 2->62.5MHz, 3->50.0MHz -+ 4->41.7MHz, 5->35.7MHz, 6->31.3MHz, 7->27.8MHz -+ -+ 623->400KHz/27.8MHz -+ reset value (507)->491159/50MHz -+ -+ BUT, the 3-bit clock divisor in data mode is too small if the -+ core clock is higher than 250MHz, so instead use the SLOW_CARD -+ configuration bit to force the use of the ident clock divisor -+ at all times. -+ */ -+ -+ host->mmc->actual_clock = 0; -+ -+ if (clock < 100000) { -+ /* Can't stop the clock, but make it as slow as possible -+ * to show willing -+ */ -+ host->cdiv = SDCDIV_MAX_CDIV; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ return; -+ } -+ -+ div = host->max_clk / clock; -+ if (div < 2) -+ div = 2; -+ if ((host->max_clk / div) > clock) -+ div++; -+ div -= 2; -+ -+ if (div > SDCDIV_MAX_CDIV) -+ div = SDCDIV_MAX_CDIV; -+ -+ host->mmc->actual_clock = host->max_clk / (div + 2); -+ -+ host->cdiv = div; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ -+ pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ clock, host->max_clk, host->cdiv, host->mmc->actual_clock); -+} -+ -+static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ if (1) { -+ struct mmc_command *cmd = mrq->cmd; -+ const char *src = "cmd"; -+ BUG_ON(!cmd); -+ pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", -+ src, cmd->opcode, cmd->arg, cmd->flags); -+ if (cmd->data) -+ pr_debug("bcm2835_sdhost_request: %s %d*%d\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ } -+ -+ if (mrq->data && !is_power_of_2(mrq->data->blksz)) { -+ pr_err("%s: Unsupported block size (%d bytes)\n", -+ mmc_hostname(mmc), mrq->data->blksz); -+ mrq->cmd->error = -EINVAL; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ -+ host = mmc_priv(mmc); -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ WARN_ON(host->mrq != NULL); -+ -+ host->mrq = mrq; -+ -+ if (mrq->sbc) -+ bcm2835_sdhost_send_command(host, mrq->sbc); -+ else -+ bcm2835_sdhost_send_command(host, mrq->cmd); -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (!mrq->sbc && mrq->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+} -+ -+ -+static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ -+ pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (!ios->clock || ios->clock != host->clock) { -+ bcm2835_sdhost_set_clock(host, ios->clock); -+ host->clock = ios->clock; -+ } -+ -+ /* set bus width */ -+ host->hcfg &= ~SDHCFG_WIDE_EXT_BUS; -+ if (ios->bus_width == MMC_BUS_WIDTH_4) -+ host->hcfg |= SDHCFG_WIDE_EXT_BUS; -+ -+ host->hcfg |= SDHCFG_WIDE_INT_BUS; -+ -+ /* Disable clever clock switching, to cope with fast core clocks */ -+ host->hcfg |= SDHCFG_SLOW_CARD; -+ -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ -+ mmiowb(); -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, -+ unsigned int direction, -+ u32 blk_pos, int blk_size) -+{ -+ /* There is a bug in the host controller hardware that makes -+ reading the final sector of the card as part of a multiple read -+ problematic. Detect that case and shorten the read accordingly. -+ */ -+ /* csd.capacity is in weird units - convert to sectors */ -+ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ -+ if ((direction == MMC_DATA_READ) && -+ ((blk_pos + blk_size) == card_sectors)) -+ blk_size--; -+ -+ return blk_size; -+} -+ -+ -+static struct mmc_host_ops bcm2835_sdhost_ops = { -+ .request = bcm2835_sdhost_request, -+ .set_ios = bcm2835_sdhost_set_ios, -+ .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, -+ .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, -+}; -+ -+ -+static void bcm2835_sdhost_tasklet_finish(unsigned long param) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ struct mmc_request *mrq; -+ -+ host = (struct bcm2835_host *)param; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ /* -+ * If this tasklet gets rescheduled while running, it will -+ * be run again afterwards but without any active request. -+ */ -+ if (!host->mrq) { -+ spin_unlock_irqrestore(&host->lock, flags); -+ return; -+ } -+ -+ del_timer(&host->timer); -+ -+ mrq = host->mrq; -+ -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ if (((mrq->cmd && mrq->cmd->error) || -+ (mrq->data && (mrq->data->error || -+ (mrq->data->stop && mrq->data->stop->error))))) { -+ -+ bcm2835_sdhost_reset(host); -+ } -+ -+ host->mrq = NULL; -+ host->cmd = NULL; -+ host->data = NULL; -+ -+ mmiowb(); -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+ mmc_request_done(host->mmc, mrq); -+} -+ -+ -+ -+int bcm2835_sdhost_add_host(struct bcm2835_host *host) -+{ -+ struct mmc_host *mmc; -+ struct dma_slave_config cfg; -+ int ret; -+ -+ mmc = host->mmc; -+ -+ bcm2835_sdhost_reset(host); -+ -+ mmc->f_max = host->max_clk; -+ mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; -+ -+ /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ -+ host->timeout_clk = mmc->f_max / 1000; -+#ifdef CONFIG_ARCH_BCM2835 -+ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; -+#endif -+ /* host controller capabilities */ -+ mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | -+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -+ MMC_CAP_NEEDS_POLL | -+ (ALLOW_CMD23 * MMC_CAP_CMD23); -+ -+ spin_lock_init(&host->lock); -+ -+ if (host->allow_dma) { -+ if (!host->dma_chan_tx || !host->dma_chan_rx || -+ IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { -+ pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); -+ host->have_dma = false; -+ } else { -+ pr_info("DMA channels allocated for the SDHost driver"); -+ host->have_dma = true; -+ -+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ cfg.slave_id = 13; /* DREQ channel */ -+ -+ cfg.direction = DMA_MEM_TO_DEV; -+ cfg.src_addr = 0; -+ cfg.dst_addr = host->phys_addr + SDDATA; -+ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); -+ -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->phys_addr + SDDATA; -+ cfg.dst_addr = 0; -+ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); -+ } -+ } else { -+ pr_info("Forcing PIO mode\n"); -+ host->have_dma = false; -+ } -+ -+ mmc->max_segs = 128; -+ mmc->max_req_size = 524288; -+ mmc->max_seg_size = mmc->max_req_size; -+ mmc->max_blk_size = 512; -+ mmc->max_blk_count = 65535; -+ -+ /* report supported voltage ranges */ -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ -+ tasklet_init(&host->finish_tasklet, -+ bcm2835_sdhost_tasklet_finish, (unsigned long)host); -+ -+ setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); -+ -+ bcm2835_sdhost_init(host, 0); -+#ifndef CONFIG_ARCH_BCM2835 -+ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -+ mmc_hostname(mmc), host); -+#else -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, -+ IRQF_SHARED, mmc_hostname(mmc), host); -+#endif -+ if (ret) { -+ pr_err("%s: Failed to request IRQ %d: %d\n", -+ mmc_hostname(mmc), host->irq, ret); -+ goto untasklet; -+ } -+ -+ mmiowb(); -+ mmc_add_host(mmc); -+ -+ pr_info("Load BCM2835 SDHost driver\n"); -+ if (host->delay_after_stop) -+ pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", -+ host->delay_after_stop); -+ -+ return 0; -+ -+untasklet: -+ tasklet_kill(&host->finish_tasklet); -+ -+ return ret; -+} -+ -+static int bcm2835_sdhost_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct clk *clk; -+ struct resource *iomem; -+ struct bcm2835_host *host; -+ struct mmc_host *mmc; -+ int ret; -+ -+ pr_debug("bcm2835_sdhost_probe\n"); -+ mmc = mmc_alloc_host(sizeof(*host), dev); -+ if (!mmc) -+ return -ENOMEM; -+ -+ mmc->ops = &bcm2835_sdhost_ops; -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ host->timeout = msecs_to_jiffies(1000); -+ spin_lock_init(&host->lock); -+ -+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ host->ioaddr = devm_ioremap_resource(dev, iomem); -+ if (IS_ERR(host->ioaddr)) { -+ ret = PTR_ERR(host->ioaddr); -+ goto err; -+ } -+ -+ host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT; -+ pr_debug(" - ioaddr %lx, iomem->start %lx, phys_addr %lx\n", -+ (unsigned long)host->ioaddr, -+ (unsigned long)iomem->start, -+ (unsigned long)host->phys_addr); -+ -+ host->allow_dma = ALLOW_DMA; -+ -+ if (node) { -+ /* Read any custom properties */ -+ of_property_read_u32(node, -+ "brcm,delay-after-stop", -+ &host->delay_after_stop); -+ host->allow_dma = ALLOW_DMA && -+ !of_property_read_bool(node, "brcm,force-pio"); -+ } -+ -+ if (host->allow_dma) { -+ if (node) { -+ host->dma_chan_tx = -+ dma_request_slave_channel(dev, "tx"); -+ host->dma_chan_rx = -+ dma_request_slave_channel(dev, "rx"); -+ } else { -+ dma_cap_mask_t mask; -+ -+ dma_cap_zero(mask); -+ /* we don't care about the channel, any would work */ -+ dma_cap_set(DMA_SLAVE, mask); -+ host->dma_chan_tx = -+ dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rx = -+ dma_request_channel(mask, NULL, NULL); -+ } -+ } -+ -+ clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(dev, "could not get clk\n"); -+ ret = PTR_ERR(clk); -+ goto err; -+ } -+ -+ host->max_clk = clk_get_rate(clk); -+ -+ host->irq = platform_get_irq(pdev, 0); -+ if (host->irq <= 0) { -+ dev_err(dev, "get IRQ failed\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ pr_debug(" - max_clk %lx, irq %d\n", -+ (unsigned long)host->max_clk, -+ (int)host->irq); -+ -+ if (node) -+ mmc_of_parse(mmc); -+ else -+ mmc->caps |= MMC_CAP_4_BIT_DATA; -+ -+ ret = bcm2835_sdhost_add_host(host); -+ if (ret) -+ goto err; -+ -+ platform_set_drvdata(pdev, host); -+ -+ pr_debug("bcm2835_sdhost_probe -> OK\n"); -+ -+ return 0; -+ -+err: -+ pr_debug("bcm2835_sdhost_probe -> err %d\n", ret); -+ mmc_free_host(mmc); -+ -+ return ret; -+} -+ -+static int bcm2835_sdhost_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_host *host = platform_get_drvdata(pdev); -+ -+ pr_debug("bcm2835_sdhost_remove\n"); -+ -+ mmc_remove_host(host->mmc); -+ -+ bcm2835_sdhost_set_power(host, false); -+ -+ free_irq(host->irq, host); -+ -+ del_timer_sync(&host->timer); -+ -+ tasklet_kill(&host->finish_tasklet); -+ -+ mmc_free_host(host->mmc); -+ platform_set_drvdata(pdev, NULL); -+ -+ pr_debug("bcm2835_sdhost_remove - OK\n"); -+ return 0; -+} -+ -+ -+static const struct of_device_id bcm2835_sdhost_match[] = { -+ { .compatible = "brcm,bcm2835-sdhost" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); -+ -+ -+ -+static struct platform_driver bcm2835_sdhost_driver = { -+ .probe = bcm2835_sdhost_probe, -+ .remove = bcm2835_sdhost_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_sdhost_match, -+ }, -+}; -+module_platform_driver(bcm2835_sdhost_driver); -+ -+MODULE_ALIAS("platform:sdhost-bcm2835"); -+MODULE_DESCRIPTION("BCM2835 SDHost driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Phil Elwell"); - -From 4504d17456cfc2f8b8b987d8709adcf759c8ea2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:24:30 +0200 -Subject: [PATCH 122/216] BCM270x: Add memory and irq resources to dmaengine - device and DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Prepare for merging of the legacy DMA API arch driver dma.c -with bcm2708-dmaengine by adding memory and irq resources both -to platform file device and Device Tree node. -Don't use BCM_DMAMAN_DRIVER_NAME so we don't have to include mach/dma.h - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 16 +++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 65 +++++++++++++++++++++++++++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 65 +++++++++++++++++++++++++++++++++-- - 3 files changed, 142 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index ff70c58..065a424 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -10,7 +10,23 @@ - - dma: dma@7e007000 { - compatible = "brcm,bcm2835-dma"; -+ reg = <0x7e007000 0xf00>; -+ interrupts = <1 16>, -+ <1 17>, -+ <1 18>, -+ <1 19>, -+ <1 20>, -+ <1 21>, -+ <1 22>, -+ <1 23>, -+ <1 24>, -+ <1 25>, -+ <1 26>, -+ <1 27>, -+ <1 28>; -+ - #dma-cells = <1>; -+ brcm,dma-channel-mask = <0x7f35>; - }; - - intc: interrupt-controller { -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index b848e4a..703215d 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -55,7 +55,6 @@ - #include - - #include --#include - #include - #include - -@@ -257,15 +256,77 @@ static struct resource bcm2708_dmaman_resources[] = { - }; - - static struct platform_device bcm2708_dmaman_device = { -- .name = BCM_DMAMAN_DRIVER_NAME, -+ .name = "bcm2708_dma", - .id = 0, /* first bcm2708_dma */ - .resource = bcm2708_dmaman_resources, - .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), - }; - -+static struct resource bcm2708_dmaengine_resources[] = { -+ { -+ .start = DMA_BASE, -+ .end = DMA_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_DMA0, -+ .end = IRQ_DMA0, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA1, -+ .end = IRQ_DMA1, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA2, -+ .end = IRQ_DMA2, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA3, -+ .end = IRQ_DMA3, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA4, -+ .end = IRQ_DMA4, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA5, -+ .end = IRQ_DMA5, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA6, -+ .end = IRQ_DMA6, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA7, -+ .end = IRQ_DMA7, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA8, -+ .end = IRQ_DMA8, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA9, -+ .end = IRQ_DMA9, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA10, -+ .end = IRQ_DMA10, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA11, -+ .end = IRQ_DMA11, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA12, -+ .end = IRQ_DMA12, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ - static struct platform_device bcm2708_dmaengine_device = { - .name = "bcm2708-dmaengine", - .id = -1, -+ .resource = bcm2708_dmaengine_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), - }; - - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index dcad008..97116c3 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -56,7 +56,6 @@ - #include - - #include --#include - #include - #include - -@@ -267,15 +266,77 @@ static struct resource bcm2708_dmaman_resources[] = { - }; - - static struct platform_device bcm2708_dmaman_device = { -- .name = BCM_DMAMAN_DRIVER_NAME, -+ .name = "bcm2708_dma", - .id = 0, /* first bcm2708_dma */ - .resource = bcm2708_dmaman_resources, - .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), - }; - -+static struct resource bcm2708_dmaengine_resources[] = { -+ { -+ .start = DMA_BASE, -+ .end = DMA_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_DMA0, -+ .end = IRQ_DMA0, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA1, -+ .end = IRQ_DMA1, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA2, -+ .end = IRQ_DMA2, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA3, -+ .end = IRQ_DMA3, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA4, -+ .end = IRQ_DMA4, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA5, -+ .end = IRQ_DMA5, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA6, -+ .end = IRQ_DMA6, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA7, -+ .end = IRQ_DMA7, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA8, -+ .end = IRQ_DMA8, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA9, -+ .end = IRQ_DMA9, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA10, -+ .end = IRQ_DMA10, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA11, -+ .end = IRQ_DMA11, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA12, -+ .end = IRQ_DMA12, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ - static struct platform_device bcm2708_dmaengine_device = { - .name = "bcm2708-dmaengine", - .id = -1, -+ .resource = bcm2708_dmaengine_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), - }; - - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - -From 4111e2c08fdfcfaa72b531689e2b9bc2b8c29453 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:25:43 +0200 -Subject: [PATCH 123/216] dmaengine: bcm2708: Merge with arch dma.c driver and - disable dma.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Merge the legacy DMA API driver with bcm2708-dmaengine. -This is done so we can use bcm2708_fb on ARCH_BCM2835 (mailbox -driver is also needed). - -Changes to the dma.c code: -- Use BIT() macro. -- Cutdown some comments to one line. -- Add mutex to vc_dmaman and use this, since the dev lock is locked - during probing of the engine part. -- Add global g_dmaman variable since drvdata is used by the engine part. -- Restructure for readability: - vc_dmaman_chan_alloc() - vc_dmaman_chan_free() - bcm_dma_chan_free() -- Restructure bcm_dma_chan_alloc() to simplify error handling. -- Use device irq resources instead of hardcoded bcm_dma_irqs table. -- Remove dev_dmaman_register() and code it directly. -- Remove dev_dmaman_deregister() and code it directly. -- Simplify bcm_dmaman_probe() using devm_* functions. -- Get dmachans from DT if available. -- Keep 'dma.dmachans' module argument name for backwards compatibility. - -Make it available on ARCH_BCM2835 as well. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/include/mach/dma.h | 96 +-------- - arch/arm/mach-bcm2709/Makefile | 2 +- - arch/arm/mach-bcm2709/include/mach/dma.h | 96 +-------- - drivers/dma/Kconfig | 9 +- - drivers/dma/bcm2708-dmaengine.c | 333 ++++++++++++++++++++++++++++-- - include/linux/platform_data/dma-bcm2708.h | 127 ++++++++++++ - 7 files changed, 457 insertions(+), 208 deletions(-) - create mode 100644 include/linux/platform_data/dma-bcm2708.h - -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index 21e3521..454408c 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index d03e7b5..d826705 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -1,94 +1,2 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/dma.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- -- --#ifndef _MACH_BCM2708_DMA_H --#define _MACH_BCM2708_DMA_H -- --#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -- --/* DMA CS Control and Status bits */ --#define BCM2708_DMA_ACTIVE (1 << 0) --#define BCM2708_DMA_INT (1 << 2) --#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ --#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ --#define BCM2708_DMA_ERR (1 << 8) --#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ --#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -- --/* DMA control block "info" field bits */ --#define BCM2708_DMA_INT_EN (1 << 0) --#define BCM2708_DMA_TDMODE (1 << 1) --#define BCM2708_DMA_WAIT_RESP (1 << 3) --#define BCM2708_DMA_D_INC (1 << 4) --#define BCM2708_DMA_D_WIDTH (1 << 5) --#define BCM2708_DMA_D_DREQ (1 << 6) --#define BCM2708_DMA_S_INC (1 << 8) --#define BCM2708_DMA_S_WIDTH (1 << 9) --#define BCM2708_DMA_S_DREQ (1 << 10) -- --#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) --#define BCM2708_DMA_PER_MAP(x) ((x) << 16) --#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -- --#define BCM2708_DMA_DREQ_EMMC 11 --#define BCM2708_DMA_DREQ_SDHOST 13 -- --#define BCM2708_DMA_CS 0x00 /* Control and Status */ --#define BCM2708_DMA_ADDR 0x04 --/* the current control block appears in the following registers - read only */ --#define BCM2708_DMA_INFO 0x08 --#define BCM2708_DMA_SOURCE_AD 0x0c --#define BCM2708_DMA_DEST_AD 0x10 --#define BCM2708_DMA_NEXTCB 0x1C --#define BCM2708_DMA_DEBUG 0x20 -- --#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) --#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -- --#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -- --struct bcm2708_dma_cb { -- unsigned long info; -- unsigned long src; -- unsigned long dst; -- unsigned long length; -- unsigned long stride; -- unsigned long next; -- unsigned long pad[2]; --}; --struct scatterlist; -- --extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); --extern void bcm_dma_start(void __iomem *dma_chan_base, -- dma_addr_t control_block); --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); --extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -- --/* When listing features we can ask for when allocating DMA channels give -- those with higher priority smaller ordinal numbers */ --#define BCM_DMA_FEATURE_FAST_ORD 0 --#define BCM_DMA_FEATURE_BULK_ORD 1 --#define BCM_DMA_FEATURE_NORMAL_ORD 2 --#define BCM_DMA_FEATURE_LITE_ORD 3 --#define BCM_DMA_FEATURE_FAST (1< -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index 2a803bb..f07c38b 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/include/mach/dma.h b/arch/arm/mach-bcm2709/include/mach/dma.h -index d03e7b5..d826705 100644 ---- a/arch/arm/mach-bcm2709/include/mach/dma.h -+++ b/arch/arm/mach-bcm2709/include/mach/dma.h -@@ -1,94 +1,2 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/dma.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- -- --#ifndef _MACH_BCM2708_DMA_H --#define _MACH_BCM2708_DMA_H -- --#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -- --/* DMA CS Control and Status bits */ --#define BCM2708_DMA_ACTIVE (1 << 0) --#define BCM2708_DMA_INT (1 << 2) --#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ --#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ --#define BCM2708_DMA_ERR (1 << 8) --#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ --#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -- --/* DMA control block "info" field bits */ --#define BCM2708_DMA_INT_EN (1 << 0) --#define BCM2708_DMA_TDMODE (1 << 1) --#define BCM2708_DMA_WAIT_RESP (1 << 3) --#define BCM2708_DMA_D_INC (1 << 4) --#define BCM2708_DMA_D_WIDTH (1 << 5) --#define BCM2708_DMA_D_DREQ (1 << 6) --#define BCM2708_DMA_S_INC (1 << 8) --#define BCM2708_DMA_S_WIDTH (1 << 9) --#define BCM2708_DMA_S_DREQ (1 << 10) -- --#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) --#define BCM2708_DMA_PER_MAP(x) ((x) << 16) --#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -- --#define BCM2708_DMA_DREQ_EMMC 11 --#define BCM2708_DMA_DREQ_SDHOST 13 -- --#define BCM2708_DMA_CS 0x00 /* Control and Status */ --#define BCM2708_DMA_ADDR 0x04 --/* the current control block appears in the following registers - read only */ --#define BCM2708_DMA_INFO 0x08 --#define BCM2708_DMA_SOURCE_AD 0x0c --#define BCM2708_DMA_DEST_AD 0x10 --#define BCM2708_DMA_NEXTCB 0x1C --#define BCM2708_DMA_DEBUG 0x20 -- --#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) --#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -- --#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -- --struct bcm2708_dma_cb { -- unsigned long info; -- unsigned long src; -- unsigned long dst; -- unsigned long length; -- unsigned long stride; -- unsigned long next; -- unsigned long pad[2]; --}; --struct scatterlist; -- --extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); --extern void bcm_dma_start(void __iomem *dma_chan_base, -- dma_addr_t control_block); --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); --extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -- --/* When listing features we can ask for when allocating DMA channels give -- those with higher priority smaller ordinal numbers */ --#define BCM_DMA_FEATURE_FAST_ORD 0 --#define BCM_DMA_FEATURE_BULK_ORD 1 --#define BCM_DMA_FEATURE_NORMAL_ORD 2 --#define BCM_DMA_FEATURE_LITE_ORD 3 --#define BCM_DMA_FEATURE_FAST (1< -diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index 2395f63..41097c7 100644 ---- a/drivers/dma/Kconfig -+++ b/drivers/dma/Kconfig -@@ -339,10 +339,15 @@ config DMA_BCM2835 - - config DMA_BCM2708 - tristate "BCM2708 DMA engine support" -- depends on MACH_BCM2708 || MACH_BCM2709 -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - -+config DMA_BCM2708_LEGACY -+ bool "BCM2708 DMA legacy API support" -+ depends on DMA_BCM2708 -+ default y -+ - config TI_CPPI41 - tristate "AM33xx CPPI41 DMA support" - depends on ARCH_OMAP -@@ -381,7 +386,7 @@ config MOXART_DMA - select DMA_VIRTUAL_CHANNELS - help - Enable support for the MOXA ART SoC DMA controller. -- -+ - config FSL_EDMA - tristate "Freescale eDMA engine support" - depends on OF -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 8182b16..937fd60 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -37,26 +37,304 @@ - #include - #include - #include -+#include - #include - #include - #include - #include -+#include -+#include - --#ifndef CONFIG_ARCH_BCM2835 -+#include "virt-dma.h" - --/* dma manager */ --#include -+static unsigned dma_debug; - --//#define DMA_COMPLETE DMA_SUCCESS -+/* -+ * Legacy DMA API -+ */ - --#endif -+#ifdef CONFIG_DMA_BCM2708_LEGACY - --#include --#include -+#define CACHE_LINE_MASK 31 -+#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ - --#include "virt-dma.h" -+/* valid only for channels 0 - 14, 15 has its own base address */ -+#define BCM2708_DMA_CHAN(n) ((n) << 8) /* base address */ -+#define BCM2708_DMA_CHANIO(dma_base, n) \ -+ ((void __iomem *)((char *)(dma_base) + BCM2708_DMA_CHAN(n))) - --static unsigned dma_debug; -+struct vc_dmaman { -+ void __iomem *dma_base; -+ u32 chan_available; /* bitmap of available channels */ -+ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ -+ struct mutex lock; -+}; -+ -+static struct device *dmaman_dev; /* we assume there's only one! */ -+static struct vc_dmaman *g_dmaman; /* DMA manager */ -+static int dmachans = -1; /* module parameter */ -+ -+/* DMA Auxiliary Functions */ -+ -+/* A DMA buffer on an arbitrary boundary may separate a cache line into a -+ section inside the DMA buffer and another section outside it. -+ Even if we flush DMA buffers from the cache there is always the chance that -+ during a DMA someone will access the part of a cache line that is outside -+ the DMA buffer - which will then bring in unwelcome data. -+ Without being able to dictate our own buffer pools we must insist that -+ DMA buffers consist of a whole number of cache lines. -+*/ -+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) -+{ -+ int i; -+ -+ for (i = 0; i < sg_len; i++) { -+ if (sg_ptr[i].offset & CACHE_LINE_MASK || -+ sg_ptr[i].length & CACHE_LINE_MASK) -+ return 0; -+ } -+ -+ return 1; -+} -+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -+ -+extern void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block) -+{ -+ dsb(); /* ARM data synchronization (push) operation */ -+ -+ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -+ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); -+} -+EXPORT_SYMBOL_GPL(bcm_dma_start); -+ -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ /* ugly busy wait only option for now */ -+ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -+ cpu_relax(); -+} -+EXPORT_SYMBOL_GPL(bcm_dma_wait_idle); -+ -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ -+/* Complete an ongoing DMA (assuming its results are to be ignored) -+ Does nothing if there is no DMA in progress. -+ This routine waits for the current AXI transfer to complete before -+ terminating the current DMA. If the current transfer is hung on a DREQ used -+ by an uncooperative peripheral the AXI transfer may never complete. In this -+ case the routine times out and return a non-zero error code. -+ Use of this routine doesn't guarantee that the ongoing or aborted DMA -+ does not produce an interrupt. -+*/ -+extern int bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ unsigned long int cs; -+ int rc = 0; -+ -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (BCM2708_DMA_ACTIVE & cs) { -+ long int timeout = 10000; -+ -+ /* write 0 to the active bit - pause the DMA */ -+ writel(0, dma_chan_base + BCM2708_DMA_CS); -+ -+ /* wait for any current AXI transfer to complete */ -+ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -+ /* we'll un-pause when we set of our next DMA */ -+ rc = -ETIMEDOUT; -+ -+ } else if (BCM2708_DMA_ACTIVE & cs) { -+ /* terminate the control block chain */ -+ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -+ -+ /* abort the whole DMA */ -+ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -+ dma_chan_base + BCM2708_DMA_CS); -+ } -+ } -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_abort); -+ -+ /* DMA Manager Device Methods */ -+ -+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -+ u32 chans_available) -+{ -+ dmaman->dma_base = dma_base; -+ dmaman->chan_available = chans_available; -+ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* 2 & 3 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* 0 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* 1 to 7 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* 8 to 14 */ -+} -+ -+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) -+{ -+ u32 chans; -+ int chan = 0; -+ int feature; -+ -+ chans = dmaman->chan_available; -+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -+ /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) -+ chans &= dmaman->has_feature[feature]; -+ -+ if (!chans) -+ return -ENOENT; -+ -+ /* return the ordinal of the first channel in the bitmap */ -+ while (chans != 0 && (chans & 1) == 0) { -+ chans >>= 1; -+ chan++; -+ } -+ /* claim the channel */ -+ dmaman->chan_available &= ~(1 << chan); -+ -+ return chan; -+} -+ -+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) -+{ -+ if (chan < 0) -+ return -EINVAL; -+ -+ if ((1 << chan) & dmaman->chan_available) -+ return -EIDRM; -+ -+ dmaman->chan_available |= (1 << chan); -+ -+ return 0; -+} -+ -+/* DMA Manager Monitor */ -+ -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq) -+{ -+ struct vc_dmaman *dmaman = g_dmaman; -+ struct platform_device *pdev = to_platform_device(dmaman_dev); -+ struct resource *r; -+ int chan; -+ -+ if (!dmaman_dev) -+ return -ENODEV; -+ -+ mutex_lock(&dmaman->lock); -+ chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ if (chan < 0) -+ goto out; -+ -+ r = platform_get_resource(pdev, IORESOURCE_IRQ, (unsigned int)chan); -+ if (!r) { -+ dev_err(dmaman_dev, "failed to get irq for DMA channel %d\n", -+ chan); -+ vc_dmaman_chan_free(dmaman, chan); -+ chan = -ENOENT; -+ goto out; -+ } -+ -+ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, chan); -+ *out_dma_irq = r->start; -+ dev_dbg(dmaman_dev, -+ "Legacy API allocated channel=%d, base=%p, irq=%i\n", -+ chan, *out_dma_base, *out_dma_irq); -+ -+out: -+ mutex_unlock(&dmaman->lock); -+ -+ return chan; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -+ -+extern int bcm_dma_chan_free(int channel) -+{ -+ struct vc_dmaman *dmaman = g_dmaman; -+ int rc; -+ -+ if (!dmaman_dev) -+ return -ENODEV; -+ -+ mutex_lock(&dmaman->lock); -+ rc = vc_dmaman_chan_free(dmaman, channel); -+ mutex_unlock(&dmaman->lock); -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -+ -+static int bcm_dmaman_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct vc_dmaman *dmaman; -+ struct resource *r; -+ void __iomem *dma_base; -+ uint32_t val; -+ -+ if (!of_property_read_u32(dev->of_node, -+ "brcm,dma-channel-mask", &val)) -+ dmachans = val; -+ else if (dmachans == -1) -+ dmachans = DEFAULT_DMACHAN_BITMAP; -+ -+ dmaman = devm_kzalloc(dev, sizeof(*dmaman), GFP_KERNEL); -+ if (!dmaman) -+ return -ENOMEM; -+ -+ mutex_init(&dmaman->lock); -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ dma_base = devm_ioremap_resource(dev, r); -+ if (IS_ERR(dma_base)) -+ return PTR_ERR(dma_base); -+ -+ vc_dmaman_init(dmaman, dma_base, dmachans); -+ g_dmaman = dmaman; -+ dmaman_dev = dev; -+ -+ dev_info(dev, "DMA legacy API manager at %p, dmachans=0x%x\n", -+ dma_base, dmachans); -+ -+ return 0; -+} -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ dmaman_dev = NULL; -+ -+ return 0; -+} -+ -+#else /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+/* -+ * DMA engine -+ */ - - struct bcm2835_dmadev { - struct dma_device ddev; -@@ -709,7 +987,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan) - return 0; - } - --#ifdef CONFIG_ARCH_BCM2835 -+#ifndef CONFIG_DMA_BCM2708_LEGACY - static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) - { - struct bcm2835_chan *c; -@@ -787,7 +1065,7 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec, - static int bcm2835_dma_probe(struct platform_device *pdev) - { - struct bcm2835_dmadev *od; --#ifdef CONFIG_ARCH_BCM2835 -+#ifndef CONFIG_DMA_BCM2708_LEGACY - struct resource *res; - void __iomem *base; - uint32_t chans_available; -@@ -800,10 +1078,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - -- /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */ -- /* hence the difference between probing */ -- --#ifndef CONFIG_ARCH_BCM2835 -+#ifdef CONFIG_DMA_BCM2708_LEGACY - - rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (rc) -@@ -815,6 +1090,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - if (!od) - return -ENOMEM; - -+ rc = bcm_dmaman_probe(pdev); -+ if (rc) -+ return rc; -+ - pdev->dev.dma_parms = &od->dma_parms; - dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); - -@@ -971,6 +1250,7 @@ static int bcm2835_dma_remove(struct platform_device *pdev) - - dma_async_device_unregister(&od->ddev); - bcm2835_dma_free(od); -+ bcm_dmaman_remove(pdev); - - return 0; - } -@@ -985,9 +1265,30 @@ static struct platform_driver bcm2835_dma_driver = { - }, - }; - --module_platform_driver(bcm2835_dma_driver); -+static int bcm2835_init(void) -+{ -+ return platform_driver_register(&bcm2835_dma_driver); -+} -+ -+static void bcm2835_exit(void) -+{ -+ platform_driver_unregister(&bcm2835_dma_driver); -+} -+ -+/* -+ * Load after serial driver (arch_initcall) so we see the messages if it fails, -+ * but before drivers (module_init) that need a DMA channel. -+ */ -+subsys_initcall(bcm2835_init); -+module_exit(bcm2835_exit); - - module_param(dma_debug, uint, 0644); -+#ifdef CONFIG_DMA_BCM2708_LEGACY -+/* Keep backward compatibility: dma.dmachans= */ -+#undef MODULE_PARAM_PREFIX -+#define MODULE_PARAM_PREFIX "dma." -+module_param(dmachans, int, 0644); -+#endif - MODULE_ALIAS("platform:bcm2835-dma"); - MODULE_DESCRIPTION("BCM2835 DMA engine driver"); - MODULE_AUTHOR("Florian Meier "); -diff --git a/include/linux/platform_data/dma-bcm2708.h b/include/linux/platform_data/dma-bcm2708.h -new file mode 100644 -index 0000000..2310e34 ---- /dev/null -+++ b/include/linux/platform_data/dma-bcm2708.h -@@ -0,0 +1,127 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef _PLAT_BCM2708_DMA_H -+#define _PLAT_BCM2708_DMA_H -+ -+/* DMA CS Control and Status bits */ -+#define BCM2708_DMA_ACTIVE BIT(0) -+#define BCM2708_DMA_INT BIT(2) -+#define BCM2708_DMA_ISPAUSED BIT(4) /* Pause requested or not active */ -+#define BCM2708_DMA_ISHELD BIT(5) /* Is held by DREQ flow control */ -+#define BCM2708_DMA_ERR BIT(8) -+#define BCM2708_DMA_ABORT BIT(30) /* stop current CB, go to next, WO */ -+#define BCM2708_DMA_RESET BIT(31) /* WO, self clearing */ -+ -+/* DMA control block "info" field bits */ -+#define BCM2708_DMA_INT_EN BIT(0) -+#define BCM2708_DMA_TDMODE BIT(1) -+#define BCM2708_DMA_WAIT_RESP BIT(3) -+#define BCM2708_DMA_D_INC BIT(4) -+#define BCM2708_DMA_D_WIDTH BIT(5) -+#define BCM2708_DMA_D_DREQ BIT(6) -+#define BCM2708_DMA_S_INC BIT(8) -+#define BCM2708_DMA_S_WIDTH BIT(9) -+#define BCM2708_DMA_S_DREQ BIT(10) -+ -+#define BCM2708_DMA_BURST(x) (((x) & 0xf) << 12) -+#define BCM2708_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2708_DMA_WAITS(x) (((x) & 0x1f) << 21) -+ -+#define BCM2708_DMA_DREQ_EMMC 11 -+#define BCM2708_DMA_DREQ_SDHOST 13 -+ -+#define BCM2708_DMA_CS 0x00 /* Control and Status */ -+#define BCM2708_DMA_ADDR 0x04 -+/* the current control block appears in the following registers - read only */ -+#define BCM2708_DMA_INFO 0x08 -+#define BCM2708_DMA_SOURCE_AD 0x0c -+#define BCM2708_DMA_DEST_AD 0x10 -+#define BCM2708_DMA_NEXTCB 0x1C -+#define BCM2708_DMA_DEBUG 0x20 -+ -+#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4) + BCM2708_DMA_CS) -+#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4) + BCM2708_DMA_ADDR) -+ -+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -+ -+/* When listing features we can ask for when allocating DMA channels give -+ those with higher priority smaller ordinal numbers */ -+#define BCM_DMA_FEATURE_FAST_ORD 0 -+#define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_NORMAL_ORD 2 -+#define BCM_DMA_FEATURE_LITE_ORD 3 -+#define BCM_DMA_FEATURE_FAST BIT(BCM_DMA_FEATURE_FAST_ORD) -+#define BCM_DMA_FEATURE_BULK BIT(BCM_DMA_FEATURE_BULK_ORD) -+#define BCM_DMA_FEATURE_NORMAL BIT(BCM_DMA_FEATURE_NORMAL_ORD) -+#define BCM_DMA_FEATURE_LITE BIT(BCM_DMA_FEATURE_LITE_ORD) -+#define BCM_DMA_FEATURE_COUNT 4 -+ -+struct bcm2708_dma_cb { -+ unsigned long info; -+ unsigned long src; -+ unsigned long dst; -+ unsigned long length; -+ unsigned long stride; -+ unsigned long next; -+ unsigned long pad[2]; -+}; -+ -+struct scatterlist; -+ -+#ifdef CONFIG_DMA_BCM2708_LEGACY -+ -+int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); -+void bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block); -+void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+bool bcm_dma_is_busy(void __iomem *dma_chan_base); -+int bcm_dma_abort(void __iomem *dma_chan_base); -+ -+/* return channel no or -ve error */ -+int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq); -+int bcm_dma_chan_free(int channel); -+ -+#else /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+static inline int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, -+ int sg_len) -+{ -+ return 0; -+} -+ -+static inline void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block) { } -+ -+static inline void bcm_dma_wait_idle(void __iomem *dma_chan_base) { } -+ -+static inline bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ return false; -+} -+ -+static inline int bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ return -EINVAL; -+} -+ -+static inline int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, -+ int *out_dma_irq) -+{ -+ return -EINVAL; -+} -+ -+static inline int bcm_dma_chan_free(int channel) -+{ -+ return -EINVAL; -+} -+ -+#endif /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+#endif /* _PLAT_BCM2708_DMA_H */ - -From 2b9f3386a080d00da4e6335272fe3b94cc51cfef Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:26:59 +0200 -Subject: [PATCH 124/216] BCM270x: dma: Remove driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove dma.c driver which is now merged with bcm2708-dmaengine. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/dma.c | 409 -------------------------------------------- - arch/arm/mach-bcm2709/dma.c | 409 -------------------------------------------- - 2 files changed, 818 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/dma.c - delete mode 100644 arch/arm/mach-bcm2709/dma.c - -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -deleted file mode 100644 -index a5e58d1..0000000 ---- a/arch/arm/mach-bcm2708/dma.c -+++ /dev/null -@@ -1,409 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/dma.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- --#include --#include --#include --#include --#include -- --#include --#include -- --/*****************************************************************************\ -- * * -- * Configuration * -- * * --\*****************************************************************************/ -- --#define CACHE_LINE_MASK 31 --#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME --#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -- --/* valid only for channels 0 - 14, 15 has its own base address */ --#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ --#define BCM2708_DMA_CHANIO(dma_base, n) \ -- ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -- -- --/*****************************************************************************\ -- * * -- * DMA Auxilliary Functions * -- * * --\*****************************************************************************/ -- --/* A DMA buffer on an arbitrary boundary may separate a cache line into a -- section inside the DMA buffer and another section outside it. -- Even if we flush DMA buffers from the cache there is always the chance that -- during a DMA someone will access the part of a cache line that is outside -- the DMA buffer - which will then bring in unwelcome data. -- Without being able to dictate our own buffer pools we must insist that -- DMA buffers consist of a whole number of cache lines. --*/ -- --extern int --bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) --{ -- int i; -- -- for (i = 0; i < sg_len; i++) { -- if (sg_ptr[i].offset & CACHE_LINE_MASK || -- sg_ptr[i].length & CACHE_LINE_MASK) -- return 0; -- } -- -- return 1; --} --EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -- --extern void --bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) --{ -- dsb(); /* ARM data synchronization (push) operation */ -- -- writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -- writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); --} -- --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) --{ -- dsb(); -- -- /* ugly busy wait only option for now */ -- while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -- cpu_relax(); --} -- --EXPORT_SYMBOL_GPL(bcm_dma_start); -- --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) --{ -- dsb(); -- -- return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; --} --EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -- --/* Complete an ongoing DMA (assuming its results are to be ignored) -- Does nothing if there is no DMA in progress. -- This routine waits for the current AXI transfer to complete before -- terminating the current DMA. If the current transfer is hung on a DREQ used -- by an uncooperative peripheral the AXI transfer may never complete. In this -- case the routine times out and return a non-zero error code. -- Use of this routine doesn't guarantee that the ongoing or aborted DMA -- does not produce an interrupt. --*/ --extern int --bcm_dma_abort(void __iomem *dma_chan_base) --{ -- unsigned long int cs; -- int rc = 0; -- -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (BCM2708_DMA_ACTIVE & cs) { -- long int timeout = 10000; -- -- /* write 0 to the active bit - pause the DMA */ -- writel(0, dma_chan_base + BCM2708_DMA_CS); -- -- /* wait for any current AXI transfer to complete */ -- while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -- /* we'll un-pause when we set of our next DMA */ -- rc = -ETIMEDOUT; -- -- } else if (BCM2708_DMA_ACTIVE & cs) { -- /* terminate the control block chain */ -- writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -- -- /* abort the whole DMA */ -- writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -- dma_chan_base + BCM2708_DMA_CS); -- } -- } -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_dma_abort); -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Device Methods * -- * * --\*****************************************************************************/ -- --struct vc_dmaman { -- void __iomem *dma_base; -- u32 chan_available; /* bitmap of available channels */ -- u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ --}; -- --static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -- u32 chans_available) --{ -- dmaman->dma_base = dma_base; -- dmaman->chan_available = chans_available; -- dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -- dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -- dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -- dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ --} -- --static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -- unsigned preferred_feature_set) --{ -- u32 chans; -- int feature; -- -- chans = dmaman->chan_available; -- for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -- /* select the subset of available channels with the desired -- feature so long as some of the candidate channels have that -- feature */ -- if ((preferred_feature_set & (1 << feature)) && -- (chans & dmaman->has_feature[feature])) -- chans &= dmaman->has_feature[feature]; -- -- if (chans) { -- int chan = 0; -- /* return the ordinal of the first channel in the bitmap */ -- while (chans != 0 && (chans & 1) == 0) { -- chans >>= 1; -- chan++; -- } -- /* claim the channel */ -- dmaman->chan_available &= ~(1 << chan); -- return chan; -- } else -- return -ENOMEM; --} -- --static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) --{ -- if (chan < 0) -- return -EINVAL; -- else if ((1 << chan) & dmaman->chan_available) -- return -EIDRM; -- else { -- dmaman->chan_available |= (1 << chan); -- return 0; -- } --} -- --/*****************************************************************************\ -- * * -- * DMA IRQs * -- * * --\*****************************************************************************/ -- --static unsigned char bcm_dma_irqs[] = { -- IRQ_DMA0, -- IRQ_DMA1, -- IRQ_DMA2, -- IRQ_DMA3, -- IRQ_DMA4, -- IRQ_DMA5, -- IRQ_DMA6, -- IRQ_DMA7, -- IRQ_DMA8, -- IRQ_DMA9, -- IRQ_DMA10, -- IRQ_DMA11, -- IRQ_DMA12 --}; -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Monitor * -- * * --\*****************************************************************************/ -- --static struct device *dmaman_dev; /* we assume there's only one! */ -- --extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -- void __iomem **out_dma_base, int *out_dma_irq) --{ -- if (!dmaman_dev) -- return -ENODEV; -- else { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -- if (rc >= 0) { -- *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -- rc); -- *out_dma_irq = bcm_dma_irqs[rc]; -- } -- device_unlock(dmaman_dev); -- -- return rc; -- } --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -- --extern int bcm_dma_chan_free(int channel) --{ -- if (dmaman_dev) { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_free(dmaman, channel); -- device_unlock(dmaman_dev); -- -- return rc; -- } else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -- --static int dev_dmaman_register(const char *dev_name, struct device *dev) --{ -- int rc = dmaman_dev ? -EINVAL : 0; -- dmaman_dev = dev; -- return rc; --} -- --static void dev_dmaman_deregister(const char *dev_name, struct device *dev) --{ -- dmaman_dev = NULL; --} -- --/*****************************************************************************\ -- * * -- * DMA Device * -- * * --\*****************************************************************************/ -- --static int dmachans = -1; /* module parameter */ -- --static int bcm_dmaman_probe(struct platform_device *pdev) --{ -- int ret = 0; -- struct vc_dmaman *dmaman; -- struct resource *dma_res = NULL; -- void __iomem *dma_base = NULL; -- int have_dma_region = 0; -- -- dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -- if (NULL == dmaman) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "DMA management memory\n"); -- ret = -ENOMEM; -- } else { -- -- dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (dma_res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -- ret = -ENODEV; -- } else if (!request_mem_region(dma_res->start, -- resource_size(dma_res), -- DRIVER_NAME)) { -- dev_err(&pdev->dev, "cannot obtain DMA region\n"); -- ret = -EBUSY; -- } else { -- have_dma_region = 1; -- dma_base = ioremap(dma_res->start, -- resource_size(dma_res)); -- if (!dma_base) { -- dev_err(&pdev->dev, "cannot map DMA region\n"); -- ret = -ENOMEM; -- } else { -- /* use module parameter if one was provided */ -- if (dmachans > 0) -- vc_dmaman_init(dmaman, dma_base, -- dmachans); -- else -- vc_dmaman_init(dmaman, dma_base, -- DEFAULT_DMACHAN_BITMAP); -- -- platform_set_drvdata(pdev, dmaman); -- dev_dmaman_register(DRIVER_NAME, &pdev->dev); -- -- printk(KERN_INFO DRIVER_NAME ": DMA manager " -- "at %p\n", dma_base); -- } -- } -- } -- if (ret != 0) { -- if (dma_base) -- iounmap(dma_base); -- if (dma_res && have_dma_region) -- release_mem_region(dma_res->start, -- resource_size(dma_res)); -- if (dmaman) -- kfree(dmaman); -- } -- return ret; --} -- --static int bcm_dmaman_remove(struct platform_device *pdev) --{ -- struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -- -- platform_set_drvdata(pdev, NULL); -- dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -- kfree(dmaman); -- -- return 0; --} -- --static struct platform_driver bcm_dmaman_driver = { -- .probe = bcm_dmaman_probe, -- .remove = bcm_dmaman_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; -- --/*****************************************************************************\ -- * * -- * Driver init/exit * -- * * --\*****************************************************************************/ -- --static int __init bcm_dmaman_drv_init(void) --{ -- int ret; -- -- ret = platform_driver_register(&bcm_dmaman_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -- -- return ret; --} -- --static void __exit bcm_dmaman_drv_exit(void) --{ -- platform_driver_unregister(&bcm_dmaman_driver); --} -- --module_init(bcm_dmaman_drv_init); --module_exit(bcm_dmaman_drv_exit); -- --module_param(dmachans, int, 0644); -- --MODULE_AUTHOR("Gray Girling "); --MODULE_DESCRIPTION("DMA channel manager driver"); --MODULE_LICENSE("GPL"); -- --MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); -diff --git a/arch/arm/mach-bcm2709/dma.c b/arch/arm/mach-bcm2709/dma.c -deleted file mode 100644 -index a5e58d1..0000000 ---- a/arch/arm/mach-bcm2709/dma.c -+++ /dev/null -@@ -1,409 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/dma.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- --#include --#include --#include --#include --#include -- --#include --#include -- --/*****************************************************************************\ -- * * -- * Configuration * -- * * --\*****************************************************************************/ -- --#define CACHE_LINE_MASK 31 --#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME --#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -- --/* valid only for channels 0 - 14, 15 has its own base address */ --#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ --#define BCM2708_DMA_CHANIO(dma_base, n) \ -- ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -- -- --/*****************************************************************************\ -- * * -- * DMA Auxilliary Functions * -- * * --\*****************************************************************************/ -- --/* A DMA buffer on an arbitrary boundary may separate a cache line into a -- section inside the DMA buffer and another section outside it. -- Even if we flush DMA buffers from the cache there is always the chance that -- during a DMA someone will access the part of a cache line that is outside -- the DMA buffer - which will then bring in unwelcome data. -- Without being able to dictate our own buffer pools we must insist that -- DMA buffers consist of a whole number of cache lines. --*/ -- --extern int --bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) --{ -- int i; -- -- for (i = 0; i < sg_len; i++) { -- if (sg_ptr[i].offset & CACHE_LINE_MASK || -- sg_ptr[i].length & CACHE_LINE_MASK) -- return 0; -- } -- -- return 1; --} --EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -- --extern void --bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) --{ -- dsb(); /* ARM data synchronization (push) operation */ -- -- writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -- writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); --} -- --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) --{ -- dsb(); -- -- /* ugly busy wait only option for now */ -- while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -- cpu_relax(); --} -- --EXPORT_SYMBOL_GPL(bcm_dma_start); -- --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) --{ -- dsb(); -- -- return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; --} --EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -- --/* Complete an ongoing DMA (assuming its results are to be ignored) -- Does nothing if there is no DMA in progress. -- This routine waits for the current AXI transfer to complete before -- terminating the current DMA. If the current transfer is hung on a DREQ used -- by an uncooperative peripheral the AXI transfer may never complete. In this -- case the routine times out and return a non-zero error code. -- Use of this routine doesn't guarantee that the ongoing or aborted DMA -- does not produce an interrupt. --*/ --extern int --bcm_dma_abort(void __iomem *dma_chan_base) --{ -- unsigned long int cs; -- int rc = 0; -- -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (BCM2708_DMA_ACTIVE & cs) { -- long int timeout = 10000; -- -- /* write 0 to the active bit - pause the DMA */ -- writel(0, dma_chan_base + BCM2708_DMA_CS); -- -- /* wait for any current AXI transfer to complete */ -- while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -- /* we'll un-pause when we set of our next DMA */ -- rc = -ETIMEDOUT; -- -- } else if (BCM2708_DMA_ACTIVE & cs) { -- /* terminate the control block chain */ -- writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -- -- /* abort the whole DMA */ -- writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -- dma_chan_base + BCM2708_DMA_CS); -- } -- } -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_dma_abort); -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Device Methods * -- * * --\*****************************************************************************/ -- --struct vc_dmaman { -- void __iomem *dma_base; -- u32 chan_available; /* bitmap of available channels */ -- u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ --}; -- --static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -- u32 chans_available) --{ -- dmaman->dma_base = dma_base; -- dmaman->chan_available = chans_available; -- dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -- dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -- dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -- dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ --} -- --static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -- unsigned preferred_feature_set) --{ -- u32 chans; -- int feature; -- -- chans = dmaman->chan_available; -- for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -- /* select the subset of available channels with the desired -- feature so long as some of the candidate channels have that -- feature */ -- if ((preferred_feature_set & (1 << feature)) && -- (chans & dmaman->has_feature[feature])) -- chans &= dmaman->has_feature[feature]; -- -- if (chans) { -- int chan = 0; -- /* return the ordinal of the first channel in the bitmap */ -- while (chans != 0 && (chans & 1) == 0) { -- chans >>= 1; -- chan++; -- } -- /* claim the channel */ -- dmaman->chan_available &= ~(1 << chan); -- return chan; -- } else -- return -ENOMEM; --} -- --static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) --{ -- if (chan < 0) -- return -EINVAL; -- else if ((1 << chan) & dmaman->chan_available) -- return -EIDRM; -- else { -- dmaman->chan_available |= (1 << chan); -- return 0; -- } --} -- --/*****************************************************************************\ -- * * -- * DMA IRQs * -- * * --\*****************************************************************************/ -- --static unsigned char bcm_dma_irqs[] = { -- IRQ_DMA0, -- IRQ_DMA1, -- IRQ_DMA2, -- IRQ_DMA3, -- IRQ_DMA4, -- IRQ_DMA5, -- IRQ_DMA6, -- IRQ_DMA7, -- IRQ_DMA8, -- IRQ_DMA9, -- IRQ_DMA10, -- IRQ_DMA11, -- IRQ_DMA12 --}; -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Monitor * -- * * --\*****************************************************************************/ -- --static struct device *dmaman_dev; /* we assume there's only one! */ -- --extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -- void __iomem **out_dma_base, int *out_dma_irq) --{ -- if (!dmaman_dev) -- return -ENODEV; -- else { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -- if (rc >= 0) { -- *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -- rc); -- *out_dma_irq = bcm_dma_irqs[rc]; -- } -- device_unlock(dmaman_dev); -- -- return rc; -- } --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -- --extern int bcm_dma_chan_free(int channel) --{ -- if (dmaman_dev) { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_free(dmaman, channel); -- device_unlock(dmaman_dev); -- -- return rc; -- } else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -- --static int dev_dmaman_register(const char *dev_name, struct device *dev) --{ -- int rc = dmaman_dev ? -EINVAL : 0; -- dmaman_dev = dev; -- return rc; --} -- --static void dev_dmaman_deregister(const char *dev_name, struct device *dev) --{ -- dmaman_dev = NULL; --} -- --/*****************************************************************************\ -- * * -- * DMA Device * -- * * --\*****************************************************************************/ -- --static int dmachans = -1; /* module parameter */ -- --static int bcm_dmaman_probe(struct platform_device *pdev) --{ -- int ret = 0; -- struct vc_dmaman *dmaman; -- struct resource *dma_res = NULL; -- void __iomem *dma_base = NULL; -- int have_dma_region = 0; -- -- dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -- if (NULL == dmaman) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "DMA management memory\n"); -- ret = -ENOMEM; -- } else { -- -- dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (dma_res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -- ret = -ENODEV; -- } else if (!request_mem_region(dma_res->start, -- resource_size(dma_res), -- DRIVER_NAME)) { -- dev_err(&pdev->dev, "cannot obtain DMA region\n"); -- ret = -EBUSY; -- } else { -- have_dma_region = 1; -- dma_base = ioremap(dma_res->start, -- resource_size(dma_res)); -- if (!dma_base) { -- dev_err(&pdev->dev, "cannot map DMA region\n"); -- ret = -ENOMEM; -- } else { -- /* use module parameter if one was provided */ -- if (dmachans > 0) -- vc_dmaman_init(dmaman, dma_base, -- dmachans); -- else -- vc_dmaman_init(dmaman, dma_base, -- DEFAULT_DMACHAN_BITMAP); -- -- platform_set_drvdata(pdev, dmaman); -- dev_dmaman_register(DRIVER_NAME, &pdev->dev); -- -- printk(KERN_INFO DRIVER_NAME ": DMA manager " -- "at %p\n", dma_base); -- } -- } -- } -- if (ret != 0) { -- if (dma_base) -- iounmap(dma_base); -- if (dma_res && have_dma_region) -- release_mem_region(dma_res->start, -- resource_size(dma_res)); -- if (dmaman) -- kfree(dmaman); -- } -- return ret; --} -- --static int bcm_dmaman_remove(struct platform_device *pdev) --{ -- struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -- -- platform_set_drvdata(pdev, NULL); -- dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -- kfree(dmaman); -- -- return 0; --} -- --static struct platform_driver bcm_dmaman_driver = { -- .probe = bcm_dmaman_probe, -- .remove = bcm_dmaman_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; -- --/*****************************************************************************\ -- * * -- * Driver init/exit * -- * * --\*****************************************************************************/ -- --static int __init bcm_dmaman_drv_init(void) --{ -- int ret; -- -- ret = platform_driver_register(&bcm_dmaman_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -- -- return ret; --} -- --static void __exit bcm_dmaman_drv_exit(void) --{ -- platform_driver_unregister(&bcm_dmaman_driver); --} -- --module_init(bcm_dmaman_drv_init); --module_exit(bcm_dmaman_drv_exit); -- --module_param(dmachans, int, 0644); -- --MODULE_AUTHOR("Gray Girling "); --MODULE_DESCRIPTION("DMA channel manager driver"); --MODULE_LICENSE("GPL"); -- --MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); - -From d2647dd924553835bc9b8f6ec0dce6cc25662d32 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:54:17 +0200 -Subject: [PATCH 125/216] BCM270x: Remove dmaman device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove the dmaman device since the dmaengine now handles -the legacy API manager. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 16 ---------------- - arch/arm/mach-bcm2709/bcm2709.c | 16 ---------------- - 2 files changed, 32 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 703215d..486e090 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -247,21 +247,6 @@ static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - }; - --static struct resource bcm2708_dmaman_resources[] = { -- { -- .start = DMA_BASE, -- .end = DMA_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- } --}; -- --static struct platform_device bcm2708_dmaman_device = { -- .name = "bcm2708_dma", -- .id = 0, /* first bcm2708_dma */ -- .resource = bcm2708_dmaman_resources, -- .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), --}; -- - static struct resource bcm2708_dmaengine_resources[] = { - { - .start = DMA_BASE, -@@ -919,7 +904,6 @@ void __init bcm2708_init(void) - bcm2708_init_clocks(); - bcm2708_dt_init(); - -- bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 97116c3..44bfc50 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -257,21 +257,6 @@ static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - }; - --static struct resource bcm2708_dmaman_resources[] = { -- { -- .start = DMA_BASE, -- .end = DMA_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- } --}; -- --static struct platform_device bcm2708_dmaman_device = { -- .name = "bcm2708_dma", -- .id = 0, /* first bcm2708_dma */ -- .resource = bcm2708_dmaman_resources, -- .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), --}; -- - static struct resource bcm2708_dmaengine_resources[] = { - { - .start = DMA_BASE, -@@ -940,7 +925,6 @@ void __init bcm2709_init(void) - bcm2709_init_clocks(); - bcm2709_dt_init(); - -- bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO - -From 149df0acaf7510d53047e19054e3b13607f60afd Mon Sep 17 00:00:00 2001 +From d8492b31751e7eda1b9b2c92dd381b5d7df1679d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 29 Apr 2015 17:24:02 +0200 -Subject: [PATCH 126/216] bcm2835: bcm2835_defconfig +Subject: [PATCH 68/77] bcm2835: bcm2835_defconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -136420,4129 +130931,1330 @@ some have changed. Update to keep functionality. No longer available: SCSI_MULTI_LUN and RESOURCE_COUNTERS. +Signed-off-by: Noralf Trønnes + +bcm2835: bcm2835_defconfig enable MMC_BCM2835 + +Enable the downstream bcm2835-mmc driver and DMA support. + +Signed-off-by: Noralf Trønnes + +bcm2835: bcm2835_defconfig enable BCM2708_MBOX + +Enable the mailbox driver. + +Signed-off-by: Noralf Trønnes + +bcm2835: bcm2835_defconfig use FB_BCM2708 + +Enable the bcm2708 framebuffer driver. +Disable the simple framebuffer driver, which matches the +device handed over by u-boot. + +Signed-off-by: Noralf Trønnes + +bcm2835: Merge bcm2835_defconfig with bcmrpi_defconfig + +These commands where used to make this commit: + +./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg + +cat << EOF > filter +CONFIG_ARCH_BCM2708 +CONFIG_BCM2708_DT +CONFIG_ARM_PATCH_PHYS_VIRT +CONFIG_PHYS_OFFSET +CONFIG_CMDLINE +CONFIG_BCM2708_WDT +CONFIG_HW_RANDOM_BCM2708 +CONFIG_I2C_BCM2708 +CONFIG_SPI_BCM2708 +CONFIG_SND_BCM2708_SOC_I2S +CONFIG_USB_DWCOTG +CONFIG_LIRC_RPI +EOF + +grep -F -v -f filter merge.cfg > filtered.cfg + +cat << EOF > added.cfg +CONFIG_WATCHDOG=y +CONFIG_BCM2835_WDT=y +CONFIG_MISC_FILESYSTEMS=y +CONFIG_SND_BCM2835_SOC_I2S=m +EOF + +ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg +ARCH=arm make oldconfig + +ARCH=arm make savedefconfig +cp defconfig arch/arm/configs/bcm2835_defconfig + +rm merge.cfg filter filtered.cfg added.cfg defconfig + +ARCH=arm make bcm2835_defconfig +ARCH=arm make oldconfig + Signed-off-by: Noralf Trønnes --- - arch/arm/configs/bcm2835_defconfig | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) + arch/arm/configs/bcm2835_defconfig | 1132 +++++++++++++++++++++++++++++++++++- + 1 file changed, 1107 insertions(+), 25 deletions(-) diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 31cb073..245aede 100644 +index 31cb073..2e8a95a 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig -@@ -10,7 +10,6 @@ CONFIG_CGROUP_FREEZER=y +@@ -1,105 +1,1071 @@ + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y + CONFIG_FHANDLE=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_BSD_PROCESS_ACCT=y + CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=18 + CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y ++CONFIG_MEMCG=y CONFIG_CGROUP_PERF=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y -@@ -18,10 +17,6 @@ CONFIG_NAMESPACES=y ++CONFIG_BLK_CGROUP=y + CONFIG_NAMESPACES=y CONFIG_SCHED_AUTOGROUP=y - CONFIG_RELAY=y +-CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y - CONFIG_KALLSYMS_ALL=y +-CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y -@@ -29,6 +24,7 @@ CONFIG_EMBEDDED=y + # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y - CONFIG_OPROFILE=y +-CONFIG_OPROFILE=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_ARCH_MULTI_V6=y # CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_BCM=y -@@ -38,7 +34,6 @@ CONFIG_AEABI=y + CONFIG_ARCH_BCM2835=y +-CONFIG_PREEMPT_VOLUNTARY=y ++CONFIG_PREEMPT=y + CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y CONFIG_KSM=y CONFIG_CLEANCACHE=y ++CONFIG_FRONTSWAP=y ++CONFIG_CMA=y ++CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_SECCOMP=y -CONFIG_CC_STACKPROTECTOR=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=m ++CONFIG_CPU_FREQ_STAT_DETAILS=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_VFP=y -@@ -57,7 +52,6 @@ CONFIG_DEVTMPFS_MOUNT=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_BINFMT_MISC=m + # CONFIG_SUSPEND is not set + 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_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IPGRE=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_INET_AH=m ++CONFIG_INET_ESP=m ++CONFIG_INET_IPCOMP=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_LRO=m ++CONFIG_INET_DIAG=m ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_MROUTE=y ++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IPV6_PIMSM_V2=y + CONFIG_NETWORK_SECMARK=y + CONFIG_NETFILTER=y +-CONFIG_CFG80211=y +-CONFIG_MAC80211=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_ZONES=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CT_PROTO_DCCP=m ++CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NETFILTER_XT_SET=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++CONFIG_IP_SET=m ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++CONFIG_IP_VS_FTP=m ++CONFIG_IP_VS_PE_SIP=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_SCTP_COOKIE_HMAC_SHA1=y ++CONFIG_ATM=m ++CONFIG_L2TP=m ++CONFIG_L2TP_V3=y ++CONFIG_L2TP_IP=m ++CONFIG_L2TP_ETH=m ++CONFIG_BRIDGE=m ++CONFIG_VLAN_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_ATALK=m ++CONFIG_6LOWPAN=m ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_HFSC=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFB=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_DRR=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_CHOKE=m ++CONFIG_NET_SCH_QFQ=m ++CONFIG_NET_SCH_CODEL=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_PLUG=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_CLS_U32_MARK=y ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_FLOW=m ++CONFIG_NET_CLS_CGROUP=m ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_CMP=m ++CONFIG_NET_EMATCH_NBYTE=m ++CONFIG_NET_EMATCH_U32=m ++CONFIG_NET_EMATCH_META=m ++CONFIG_NET_EMATCH_TEXT=m ++CONFIG_NET_EMATCH_IPSET=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_GACT_PROB=y ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_BATMAN_ADV=m ++CONFIG_OPENVSWITCH=m ++CONFIG_NET_PKTGEN=m ++CONFIG_HAMRADIO=y ++CONFIG_AX25=m ++CONFIG_NETROM=m ++CONFIG_ROSE=m ++CONFIG_MKISS=m ++CONFIG_6PACK=m ++CONFIG_BPQETHER=m ++CONFIG_BAYCOM_SER_FDX=m ++CONFIG_BAYCOM_SER_HDX=m ++CONFIG_YAM=m ++CONFIG_CAN=m ++CONFIG_CAN_VCAN=m ++CONFIG_CAN_MCP251X=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRNET=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_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_6LOWPAN=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_BT_WILINK=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_RFKILL=m ++CONFIG_RFKILL_INPUT=y ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m + CONFIG_DEVTMPFS=y + CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_DRBD=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_ATA_OVER_ETH=m ++CONFIG_EEPROM_AT24=m CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_MULTI_LUN=y ++CONFIG_CHR_DEV_ST=m ++CONFIG_CHR_DEV_OSST=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y ++CONFIG_SCSI_ISCSI_ATTRS=y ++CONFIG_ISCSI_TCP=m ++CONFIG_ISCSI_BOOT_SYSFS=m ++CONFIG_MD=y ++CONFIG_MD_LINEAR=m ++CONFIG_MD_RAID0=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_LOG_USERSPACE=m ++CONFIG_DM_RAID=m ++CONFIG_DM_ZERO=m ++CONFIG_DM_DELAY=m CONFIG_NETDEVICES=y -@@ -83,11 +77,15 @@ CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_BONDING=m ++CONFIG_DUMMY=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_VETH=m ++CONFIG_ENC28J60=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=m ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOATM=m ++CONFIG_PPPOE=m ++CONFIG_PPPOL2TP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_SLIP_SMART=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=m + CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_AX88179_178A=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m + CONFIG_USB_NET_SMSC95XX=y +-CONFIG_ZD1211RW=y +-CONFIG_INPUT_EVDEV=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_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_HSO=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++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_CARDS=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_ATH6KL=m ++CONFIG_ATH6KL_USB=m ++CONFIG_AR5523=m ++CONFIG_B43=m ++# CONFIG_B43_PHY_N is not set ++CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y ++CONFIG_HOSTAP=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_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RTL8192CU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_IFORCE=m ++CONFIG_JOYSTICK_IFORCE_USB=y ++CONFIG_JOYSTICK_XPAD=m ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ADS7846=m ++CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ++CONFIG_TOUCHSCREEN_STMPE=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=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_DEVPTS_MULTIPLE_INSTANCES=y + # CONFIG_LEGACY_PTYS is not set + # CONFIG_DEVKMEM is not set + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y + CONFIG_TTY_PRINTK=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_BCM2835=m ++CONFIG_RAW_DRIVER=y ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VC_SM=y + CONFIG_I2C=y +-CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_CHARDEV=m + CONFIG_I2C_BCM2835=y + CONFIG_SPI=y +-CONFIG_SPI_BCM2835=y ++CONFIG_SPI_BCM2835=m ++CONFIG_SPI_SPIDEV=y ++CONFIG_PPS=m ++CONFIG_PPS_CLIENT_LDISC=m ++CONFIG_PPS_CLIENT_GPIO=m + CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_ARIZONA=m ++CONFIG_GPIO_STMPE=y ++CONFIG_W1=m ++CONFIG_W1_MASTER_DS2490=m ++CONFIG_W1_MASTER_DS2482=m ++CONFIG_W1_MASTER_DS1WM=m ++CONFIG_W1_MASTER_GPIO=m ++CONFIG_W1_SLAVE_THERM=m ++CONFIG_W1_SLAVE_SMEM=m ++CONFIG_W1_SLAVE_DS2408=m ++CONFIG_W1_SLAVE_DS2413=m ++CONFIG_W1_SLAVE_DS2406=m ++CONFIG_W1_SLAVE_DS2423=m ++CONFIG_W1_SLAVE_DS2431=m ++CONFIG_W1_SLAVE_DS2433=m ++CONFIG_W1_SLAVE_DS2760=m ++CONFIG_W1_SLAVE_DS2780=m ++CONFIG_W1_SLAVE_DS2781=m ++CONFIG_W1_SLAVE_DS28E04=m ++CONFIG_W1_SLAVE_BQ27000=m ++CONFIG_BATTERY_DS2760=m + # CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_THERMAL_BCM2835=y ++CONFIG_WATCHDOG=y ++CONFIG_BCM2835_WDT=y ++CONFIG_UCB1400_CORE=m ++CONFIG_MFD_STMPE=y ++CONFIG_STMPE_SPI=y ++CONFIG_MFD_ARIZONA_I2C=m ++CONFIG_MFD_ARIZONA_SPI=m ++CONFIG_MFD_WM5102=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_RC_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_LIRC=m ++CONFIG_RC_DEVICES=y ++CONFIG_RC_ATI_REMOTE=m ++CONFIG_IR_IMON=m ++CONFIG_IR_MCEUSB=m ++CONFIG_IR_REDRAT3=m ++CONFIG_IR_STREAMZAP=m ++CONFIG_IR_IGUANA=m ++CONFIG_IR_TTUSBIR=m ++CONFIG_RC_LOOPBACK=m ++CONFIG_IR_GPIO_CIR=m ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_USB_M5602=m ++CONFIG_USB_STV06XX=m ++CONFIG_USB_GL860=m ++CONFIG_USB_GSPCA_BENQ=m ++CONFIG_USB_GSPCA_CONEX=m ++CONFIG_USB_GSPCA_CPIA1=m ++CONFIG_USB_GSPCA_DTCS033=m ++CONFIG_USB_GSPCA_ETOMS=m ++CONFIG_USB_GSPCA_FINEPIX=m ++CONFIG_USB_GSPCA_JEILINJ=m ++CONFIG_USB_GSPCA_JL2005BCD=m ++CONFIG_USB_GSPCA_KINECT=m ++CONFIG_USB_GSPCA_KONICA=m ++CONFIG_USB_GSPCA_MARS=m ++CONFIG_USB_GSPCA_MR97310A=m ++CONFIG_USB_GSPCA_NW80X=m ++CONFIG_USB_GSPCA_OV519=m ++CONFIG_USB_GSPCA_OV534=m ++CONFIG_USB_GSPCA_OV534_9=m ++CONFIG_USB_GSPCA_PAC207=m ++CONFIG_USB_GSPCA_PAC7302=m ++CONFIG_USB_GSPCA_PAC7311=m ++CONFIG_USB_GSPCA_SE401=m ++CONFIG_USB_GSPCA_SN9C2028=m ++CONFIG_USB_GSPCA_SN9C20X=m ++CONFIG_USB_GSPCA_SONIXB=m ++CONFIG_USB_GSPCA_SONIXJ=m ++CONFIG_USB_GSPCA_SPCA500=m ++CONFIG_USB_GSPCA_SPCA501=m ++CONFIG_USB_GSPCA_SPCA505=m ++CONFIG_USB_GSPCA_SPCA506=m ++CONFIG_USB_GSPCA_SPCA508=m ++CONFIG_USB_GSPCA_SPCA561=m ++CONFIG_USB_GSPCA_SPCA1528=m ++CONFIG_USB_GSPCA_SQ905=m ++CONFIG_USB_GSPCA_SQ905C=m ++CONFIG_USB_GSPCA_SQ930X=m ++CONFIG_USB_GSPCA_STK014=m ++CONFIG_USB_GSPCA_STK1135=m ++CONFIG_USB_GSPCA_STV0680=m ++CONFIG_USB_GSPCA_SUNPLUS=m ++CONFIG_USB_GSPCA_T613=m ++CONFIG_USB_GSPCA_TOPRO=m ++CONFIG_USB_GSPCA_TV8532=m ++CONFIG_USB_GSPCA_VC032X=m ++CONFIG_USB_GSPCA_VICAM=m ++CONFIG_USB_GSPCA_XIRLINK_CIT=m ++CONFIG_USB_GSPCA_ZC3XX=m ++CONFIG_USB_PWC=m ++CONFIG_VIDEO_CPIA2=m ++CONFIG_USB_ZR364XX=m ++CONFIG_USB_STKWEBCAM=m ++CONFIG_USB_S2255=m ++CONFIG_VIDEO_USBTV=m ++CONFIG_VIDEO_PVRUSB2=m ++CONFIG_VIDEO_HDPVR=m ++CONFIG_VIDEO_USBVISION=m ++CONFIG_VIDEO_STK1160_COMMON=m ++CONFIG_VIDEO_STK1160_AC97=y ++CONFIG_VIDEO_GO7007=m ++CONFIG_VIDEO_GO7007_USB=m ++CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m ++CONFIG_VIDEO_AU0828=m ++CONFIG_VIDEO_AU0828_RC=y ++CONFIG_VIDEO_CX231XX=m ++CONFIG_VIDEO_CX231XX_ALSA=m ++CONFIG_VIDEO_CX231XX_DVB=m ++CONFIG_VIDEO_TM6000=m ++CONFIG_VIDEO_TM6000_ALSA=m ++CONFIG_VIDEO_TM6000_DVB=m ++CONFIG_DVB_USB=m ++CONFIG_DVB_USB_A800=m ++CONFIG_DVB_USB_DIBUSB_MB=m ++CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y ++CONFIG_DVB_USB_DIBUSB_MC=m ++CONFIG_DVB_USB_DIB0700=m ++CONFIG_DVB_USB_UMT_010=m ++CONFIG_DVB_USB_CXUSB=m ++CONFIG_DVB_USB_M920X=m ++CONFIG_DVB_USB_DIGITV=m ++CONFIG_DVB_USB_VP7045=m ++CONFIG_DVB_USB_VP702X=m ++CONFIG_DVB_USB_GP8PSK=m ++CONFIG_DVB_USB_NOVA_T_USB2=m ++CONFIG_DVB_USB_TTUSB2=m ++CONFIG_DVB_USB_DTT200U=m ++CONFIG_DVB_USB_OPERA1=m ++CONFIG_DVB_USB_AF9005=m ++CONFIG_DVB_USB_AF9005_REMOTE=m ++CONFIG_DVB_USB_PCTV452E=m ++CONFIG_DVB_USB_DW2102=m ++CONFIG_DVB_USB_CINERGY_T2=m ++CONFIG_DVB_USB_DTV5100=m ++CONFIG_DVB_USB_FRIIO=m ++CONFIG_DVB_USB_AZ6027=m ++CONFIG_DVB_USB_TECHNISAT_USB2=m ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9015=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_LME2510=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_RTL28XXU=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_SMS_USB_DRV=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++CONFIG_DVB_AS102=m ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_BCM2835=y ++CONFIG_VIDEO_BCM2835_MMAL=m ++CONFIG_RADIO_SI470X=y ++CONFIG_USB_SI470X=m ++CONFIG_I2C_SI470X=m ++CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m ++CONFIG_USB_MR800=m ++CONFIG_USB_DSBR=m ++CONFIG_RADIO_SHARK=m ++CONFIG_RADIO_SHARK2=m ++CONFIG_USB_KEENE=m ++CONFIG_USB_MA901=m ++CONFIG_RADIO_TEA5764=m ++CONFIG_RADIO_SAA7706H=m ++CONFIG_RADIO_TEF6862=m ++CONFIG_RADIO_WL1273=m ++CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV7640=m ++CONFIG_VIDEO_MT9V011=m + CONFIG_FB=y +-CONFIG_FB_SIMPLE=y ++CONFIG_FB_BCM2708=y ++CONFIG_FB_SSD1307=m ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_GPIO=m + CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=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_CAIAQ_INPUT=y ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ++CONFIG_SND_BCM2708_SOC_RPI_DAC=m ++CONFIG_SND_BCM2708_SOC_RPI_PROTO=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_SIMPLE_CARD=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HIDRAW=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_ELO=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_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_THINGM=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_XINMO=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_PRINTER=m 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_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USBIP_CORE=m ++CONFIG_USBIP_VHCI_HCD=m ++CONFIG_USBIP_HOST=m +CONFIG_USB_DWC2=y ++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_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_F81232=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_METRO=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=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_SAFE=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_XSENS_MT=m ++CONFIG_USB_SERIAL_WISHBONE=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_QT2=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_USB_ATM=m ++CONFIG_USB_SPEEDTOUCH=m ++CONFIG_USB_CXACRU=m ++CONFIG_USB_UEAGLEATM=m ++CONFIG_USB_XUSBATM=m CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BCM2835=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_BCM2835=y -+CONFIG_NEW_LEDS=y ++CONFIG_MMC_SPI=m +CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -@@ -97,8 +95,6 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - CONFIG_LEDS_TRIGGER_TRANSIENT=y - CONFIG_LEDS_TRIGGER_CAMERA=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y + CONFIG_LEDS_TRIGGER_CPU=y + CONFIG_LEDS_TRIGGER_GPIO=y + CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +-CONFIG_LEDS_TRIGGER_TRANSIENT=y +-CONFIG_LEDS_TRIGGER_CAMERA=y ++CONFIG_LEDS_TRIGGER_TRANSIENT=m ++CONFIG_LEDS_TRIGGER_CAMERA=m ++CONFIG_LEDS_TRIGGER_INPUT=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_ISL12057=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_RTC_DRV_PCF8523=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_DS3234=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_RX4581=m ++CONFIG_DMADEVICES=y ++CONFIG_DMA_BCM2708=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m CONFIG_STAGING=y -CONFIG_USB_DWC2=y -CONFIG_USB_DWC2_HOST=y ++CONFIG_PRISM2_USB=m ++CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_R8723AU=m ++CONFIG_VT6656=m ++CONFIG_SPEAKUP=m ++CONFIG_SPEAKUP_SYNTH_SOFT=m ++CONFIG_STAGING_MEDIA=y ++CONFIG_LIRC_STAGING=y ++CONFIG_LIRC_IMON=m ++CONFIG_LIRC_SASEM=m ++CONFIG_LIRC_SERIAL=m ++CONFIG_FB_TFT=m ++CONFIG_FB_TFT_AGM1264K_FL=m ++CONFIG_FB_TFT_BD663474=m ++CONFIG_FB_TFT_HX8340BN=m ++CONFIG_FB_TFT_HX8347D=m ++CONFIG_FB_TFT_HX8353D=m ++CONFIG_FB_TFT_ILI9320=m ++CONFIG_FB_TFT_ILI9325=m ++CONFIG_FB_TFT_ILI9340=m ++CONFIG_FB_TFT_ILI9341=m ++CONFIG_FB_TFT_ILI9481=m ++CONFIG_FB_TFT_ILI9486=m ++CONFIG_FB_TFT_PCD8544=m ++CONFIG_FB_TFT_RA8875=m ++CONFIG_FB_TFT_S6D02A1=m ++CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SSD1289=m ++CONFIG_FB_TFT_SSD1306=m ++CONFIG_FB_TFT_SSD1331=m ++CONFIG_FB_TFT_SSD1351=m ++CONFIG_FB_TFT_ST7735R=m ++CONFIG_FB_TFT_TINYLCD=m ++CONFIG_FB_TFT_TLS8204=m ++CONFIG_FB_TFT_UC1701=m ++CONFIG_FB_TFT_UPD161704=m ++CONFIG_FB_TFT_WATTEROTT=m ++CONFIG_FB_FLEX=m ++CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2708_MBOX=y # CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXTCON=m ++CONFIG_EXTCON_ARIZONA=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y - -From 40cd8a80edbedd6bef0da2bcd55e777f80ef30ae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:24:46 +0200 -Subject: [PATCH 127/216] mmc: bcm2835-mmc: Make available on ARCH_BCM2835 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make the bcm2835-mmc driver available for use on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - drivers/mmc/host/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 1666c6c..41d6e47 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -6,7 +6,7 @@ comment "MMC/SD/SDIO Host Controller Drivers" - - config MMC_BCM2835 - tristate "MMC support on BCM2835" -- depends on (MACH_BCM2708 || MACH_BCM2709) -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 - help - This selects the MMC Interface on BCM2835. - - -From 6c0c225509561cc261c594db00d429f2c032ebfa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:28:22 +0200 -Subject: [PATCH 128/216] bcm2835: bcm2835_defconfig enable MMC_BCM2835 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enable the downstream bcm2835-mmc driver and DMA support. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 245aede..cf2e7a6 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -79,6 +79,8 @@ CONFIG_USB=y - CONFIG_USB_STORAGE=y - CONFIG_USB_DWC2=y - CONFIG_MMC=y -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2835=y -@@ -94,6 +96,8 @@ CONFIG_LEDS_TRIGGER_GPIO=y - CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - CONFIG_LEDS_TRIGGER_TRANSIENT=y - CONFIG_LEDS_TRIGGER_CAMERA=y -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2708=y - CONFIG_STAGING=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXT2_FS=y - -From 8bff84b0504771b895a12dcc5975b26345a3f9a1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:29:04 +0200 -Subject: [PATCH 129/216] bcm2835: Change to use bcm2835-mmc in Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use downstream bcm2835-mmc driver to get increased throughput -and DMA support. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- - arch/arm/boot/dts/bcm2835.dtsi | 9 ++++++--- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index c706448..9f4ed2f 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -45,7 +45,7 @@ - clock-frequency = <100000>; - }; - --&sdhci { -+&mmc { - status = "okay"; - bus-width = <4>; - }; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 3342cb1..f2dec21 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -122,11 +122,14 @@ - status = "disabled"; - }; - -- sdhci: sdhci@7e300000 { -- compatible = "brcm,bcm2835-sdhci"; -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; - reg = <0x7e300000 0x100>; - interrupts = <2 30>; - clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; - status = "disabled"; - }; - -@@ -161,7 +164,7 @@ - reg = <0>; - #clock-cells = <0>; - clock-output-names = "mmc"; -- clock-frequency = <100000000>; -+ clock-frequency = <250000000>; - }; - - clk_i2c: clock@1 { - -From 89df9a42f6e60b3c54c4b49b1fafff7ef201ac72 Mon Sep 17 00:00:00 2001 -From: Christopher Freeman -Date: Wed, 4 Mar 2015 01:16:58 -0800 -Subject: [PATCH 130/216] dmaengine: increment privatecnt when using - dma_get_any_slave_channel - -Channels allocated via dma_get_any_slave_channel were not increasing -the counter tracking private allocations. When these channels were -released, privatecnt may erroneously fall to zero. The DMA device -would then lose its DMA_PRIVATE cap and fail to allocate future private -channels (via private_candidate) as any allocations still outstanding -would incorrectly be seen as public allocations. - -Signed-off-by: Christopher Freeman -Signed-off-by: Vinod Koul ---- - drivers/dma/dmaengine.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c -index ac336a9..bb2b914 100644 ---- a/drivers/dma/dmaengine.c -+++ b/drivers/dma/dmaengine.c -@@ -589,11 +589,15 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) - - chan = private_candidate(&mask, device, NULL, NULL); - if (chan) { -+ dma_cap_set(DMA_PRIVATE, device->cap_mask); -+ device->privatecnt++; - err = dma_chan_get(chan); - if (err) { - pr_debug("%s: failed to get %s: (%d)\n", - __func__, dma_chan_name(chan), err); - chan = NULL; -+ if (--device->privatecnt == 0) -+ dma_cap_clear(DMA_PRIVATE, device->cap_mask); - } - } - - -From 0ecdaeb739edb714add6d8ae452d12d2ce821573 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 1 May 2015 17:46:56 +0100 -Subject: [PATCH 131/216] bcm2835-mmc: Add locks when accessing sdhost - registers - ---- - drivers/mmc/host/bcm2835-mmc.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index eef0d351..1c34f476 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -133,17 +133,20 @@ struct bcm2835_host { - - static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) - { -+ lockdep_assert_held_once(&host->lock); - writel(val, host->ioaddr + reg); - udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); - } - - static inline void mmc_raw_writel(struct bcm2835_host *host, u32 val, int reg) - { -+ lockdep_assert_held_once(&host->lock); - writel(val, host->ioaddr + reg); - } - - static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) - { -+ lockdep_assert_held_once(&host->lock); - return readl(host->ioaddr + reg); - } - -@@ -255,7 +258,9 @@ static void bcm2835_mmc_dumpregs(struct bcm2835_host *host) - static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) - { - unsigned long timeout; -+ unsigned long flags; - -+ spin_lock_irqsave(&host->lock, flags); - bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); - - if (mask & SDHCI_RESET_ALL) -@@ -273,19 +278,23 @@ static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) - return; - } - timeout--; -+ spin_unlock_irqrestore(&host->lock, flags); - mdelay(1); -+ spin_lock_irqsave(&host->lock, flags); - } - - if (100-timeout > 10 && 100-timeout > host->max_delay) { - host->max_delay = 100-timeout; - pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); - } -+ spin_unlock_irqrestore(&host->lock, flags); - } - - static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - - static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) - { -+ unsigned long flags; - if (soft) - bcm2835_mmc_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); - else -@@ -297,8 +306,10 @@ static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) - SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | - SDHCI_INT_RESPONSE; - -+ spin_lock_irqsave(&host->lock, flags); - bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); - bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ spin_unlock_irqrestore(&host->lock, flags); - - if (soft) { - /* force clock reconfiguration */ -@@ -497,11 +508,14 @@ static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host) - dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); - } - if (desc) { -+ unsigned long flags; -+ spin_lock_irqsave(&host->lock, flags); - bcm2835_mmc_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | - SDHCI_INT_SPACE_AVAIL); - host->tx_desc = desc; - desc->callback = bcm2835_mmc_dma_complete; - desc->callback_param = host; -+ spin_unlock_irqrestore(&host->lock, flags); - dmaengine_submit(desc); - dma_async_issue_pending(dma_chan); - } -@@ -1243,8 +1257,10 @@ static void bcm2835_mmc_tasklet_finish(unsigned long param) - (mrq->data && (mrq->data->error || - (mrq->data->stop && mrq->data->stop->error))))) { - -+ spin_unlock_irqrestore(&host->lock, flags); - bcm2835_mmc_reset(host, SDHCI_RESET_CMD); - bcm2835_mmc_reset(host, SDHCI_RESET_DATA); -+ spin_lock_irqsave(&host->lock, flags); - } - - host->mrq = NULL; -@@ -1259,7 +1275,7 @@ static void bcm2835_mmc_tasklet_finish(unsigned long param) - - - --int bcm2835_mmc_add_host(struct bcm2835_host *host) -+static int bcm2835_mmc_add_host(struct bcm2835_host *host) - { - struct mmc_host *mmc = host->mmc; - struct device *dev = mmc->parent; -@@ -1287,8 +1303,6 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) - - host->flags = SDHCI_AUTO_CMD23; - -- spin_lock_init(&host->lock); -- - #ifdef FORCE_PIO - dev_info(dev, "Forcing PIO mode\n"); - host->have_dma = false; - -From d7580af2f81793fd3312608de95a9009123d8710 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 13 Apr 2015 23:34:50 +0100 -Subject: [PATCH 132/216] bcm2835-mmc: Add range of debug options for slowing - things down - -bcm2835-mmc: Add option to disable some delays - -bcm2835-mmc: Add option to disable MMC_QUIRK_BLK_NO_CMD23 - -bcm2835-mmc: Default to disabling MMC_QUIRK_BLK_NO_CMD23 ---- - drivers/mmc/core/quirks.c | 2 ++ - drivers/mmc/host/bcm2835-mmc.c | 44 ++++++++++++++++++++++++++++-------------- - 2 files changed, 32 insertions(+), 14 deletions(-) - -diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index f472082..bc3bbad 100644 ---- a/drivers/mmc/core/quirks.c -+++ b/drivers/mmc/core/quirks.c -@@ -71,6 +71,7 @@ static const struct mmc_fixup mmc_fixup_methods[] = { - - void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - { -+ extern unsigned mmc_debug; - const struct mmc_fixup *f; - u64 rev = cid_rev_card(card); - -@@ -98,6 +99,7 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. - * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). - */ -+ if (mmc_debug & (1<<13)) - card->quirks |= MMC_QUIRK_BLK_NO_CMD23; - } - EXPORT_SYMBOL(mmc_fixup_device); -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 1c34f476..68314d5 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -71,6 +71,9 @@ pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x) - #define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) - - -+unsigned mmc_debug; -+unsigned mmc_debug2; -+ - struct bcm2835_host { - spinlock_t lock; - -@@ -131,17 +134,27 @@ struct bcm2835_host { - }; - - --static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) -+static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg, int from) - { -+ unsigned delay; - lockdep_assert_held_once(&host->lock); - writel(val, host->ioaddr + reg); - udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); -+ -+ delay = ((mmc_debug >> 16) & 0xf) << ((mmc_debug >> 20) & 0xf); -+ if (delay && !((1<lock); - writel(val, host->ioaddr + reg); -+ -+ delay = ((mmc_debug >> 24) & 0xf) << ((mmc_debug >> 28) & 0xf); -+ if (delay) -+ udelay(delay); - } - - static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) -@@ -162,7 +175,7 @@ static inline void bcm2835_mmc_writew(struct bcm2835_host *host, u16 val, int re - if (reg == SDHCI_TRANSFER_MODE) - host->shadow = newval; - else -- bcm2835_mmc_writel(host, newval, reg & ~3); -+ bcm2835_mmc_writel(host, newval, reg & ~3, 0); - - } - -@@ -174,7 +187,7 @@ static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg - u32 mask = 0xff << byte_shift; - u32 newval = (oldval & ~mask) | (val << byte_shift); - -- bcm2835_mmc_writel(host, newval, reg & ~3); -+ bcm2835_mmc_writel(host, newval, reg & ~3, 1); - } - - -@@ -206,7 +219,7 @@ static void bcm2835_mmc_unsignal_irqs(struct bcm2835_host *host, u32 clear) - ier &= ~clear; - /* change which requests generate IRQs - makes no difference to - the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ -- bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE, 2); - } - - -@@ -307,8 +320,8 @@ static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) - SDHCI_INT_RESPONSE; - - spin_lock_irqsave(&host->lock, flags); -- bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -- bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 3); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 3); - spin_unlock_irqrestore(&host->lock, flags); - - if (soft) { -@@ -534,8 +547,8 @@ static void bcm2835_mmc_set_transfer_irqs(struct bcm2835_host *host) - else - host->ier = (host->ier & ~dma_irqs) | pio_irqs; - -- bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -- bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 4); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 4); - } - - -@@ -617,7 +630,7 @@ static void bcm2835_mmc_set_transfer_mode(struct bcm2835_host *host, - mode |= SDHCI_TRNS_AUTO_CMD12; - else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { - mode |= SDHCI_TRNS_AUTO_CMD23; -- bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); -+ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2, 5); - } - } - -@@ -680,7 +693,7 @@ void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd - - bcm2835_mmc_prepare_data(host, cmd); - -- bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT); -+ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT, 6); - - bcm2835_mmc_set_transfer_mode(host, cmd); - -@@ -837,8 +850,8 @@ static void bcm2835_mmc_enable_sdio_irq_nolock(struct bcm2835_host *host, int en - else - host->ier &= ~SDHCI_INT_CARD_INT; - -- bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -- bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 7); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 7); - mmiowb(); - } - } -@@ -985,7 +998,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) - /* Clear selected interrupts. */ - mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | - SDHCI_INT_BUS_POWER); -- bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS); -+ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS, 8); - - - if (intmask & SDHCI_INT_CMD_MASK) -@@ -1015,7 +1028,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) - - if (intmask) { - unexpected |= intmask; -- bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS); -+ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS, 9); - } - - if (result == IRQ_NONE) -@@ -1303,6 +1316,7 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - - host->flags = SDHCI_AUTO_CMD23; - -+ dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); - #ifdef FORCE_PIO - dev_info(dev, "Forcing PIO mode\n"); - host->have_dma = false; -@@ -1514,6 +1528,8 @@ static struct platform_driver bcm2835_mmc_driver = { - }; - module_platform_driver(bcm2835_mmc_driver); - -+module_param(mmc_debug, uint, 0644); -+module_param(mmc_debug2, uint, 0644); - MODULE_ALIAS("platform:mmc-bcm2835"); - MODULE_DESCRIPTION("BCM2835 SDHCI driver"); - MODULE_LICENSE("GPL v2"); - -From e34578092803603a960a2a7bcccde5d0c8240b9a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 19:08:54 +0200 -Subject: [PATCH 133/216] BCM270x: Correct vcio device memory resource and add - irq resource -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The vcio driver hardcodes these resources, so this is the first -step in correcting this. Spell out the device name so we don't -have to include mach/vcio.h, since this header file will eventually -go away when the driver is later moved to drivers/mailbox. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 17 ++++++++++------- - arch/arm/mach-bcm2708/include/mach/platform.h | 1 + - arch/arm/mach-bcm2709/bcm2709.c | 17 ++++++++++------- - arch/arm/mach-bcm2709/include/mach/platform.h | 1 + - 4 files changed, 22 insertions(+), 14 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 486e090..51f8efa 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -55,7 +55,6 @@ - #include - - #include --#include - #include - - #include -@@ -414,17 +413,21 @@ static struct platform_device bcm2708_usb_device = { - }; - - static struct resource bcm2708_vcio_resources[] = { -- [0] = { /* mailbox/semaphore/doorbell access */ -- .start = MCORE_BASE, -- .end = MCORE_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- }, -+ { -+ .start = ARMCTRL_0_MAIL0_BASE, -+ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_MAILBOX, -+ .end = IRQ_ARM_MAILBOX, -+ .flags = IORESOURCE_IRQ, -+ }, - }; - - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = BCM_VCIO_DRIVER_NAME, -+ .name = "bcm2708_vcio", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h -index 2e7e1bb..bef3e5a 100644 ---- a/arch/arm/mach-bcm2708/include/mach/platform.h -+++ b/arch/arm/mach-bcm2708/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - - /* -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 44bfc50..8ed88b4 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -56,7 +56,6 @@ - #include - - #include --#include - #include - - #include -@@ -433,17 +432,21 @@ static struct platform_device bcm2708_usb_device = { - }; - - static struct resource bcm2708_vcio_resources[] = { -- [0] = { /* mailbox/semaphore/doorbell access */ -- .start = MCORE_BASE, -- .end = MCORE_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- }, -+ { -+ .start = ARMCTRL_0_MAIL0_BASE, -+ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_MAILBOX, -+ .end = IRQ_ARM_MAILBOX, -+ .flags = IORESOURCE_IRQ, -+ }, - }; - - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = BCM_VCIO_DRIVER_NAME, -+ .name = "bcm2708_vcio", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -diff --git a/arch/arm/mach-bcm2709/include/mach/platform.h b/arch/arm/mach-bcm2709/include/mach/platform.h -index 7157f38..5574bb5 100644 ---- a/arch/arm/mach-bcm2709/include/mach/platform.h -+++ b/arch/arm/mach-bcm2709/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - - /* - -From 4b03fd4291b9ed1cd100b359967f1b1fdc39984a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 2 May 2015 09:55:53 +0200 -Subject: [PATCH 134/216] video: fbdev: bcm2708_fb: Don't panic on error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to panic the kernel if the video driver fails. -Just print a message and return an error. - -Signed-off-by: Noralf Trønnes ---- - drivers/video/fbdev/bcm2708_fb.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 9179291..52e655a 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -325,8 +325,8 @@ static int bcm2708_fb_set_par(struct fb_info *info) - /* the console may currently be locked */ - console_trylock(); - console_unlock(); -- -- BUG(); /* what can we do here */ -+ pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); -+ return -EIO; - } - } - print_debug -@@ -677,7 +677,9 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - */ - - fb_set_var(&fb->fb, &fb->fb.var); -- bcm2708_fb_set_par(&fb->fb); -+ ret = bcm2708_fb_set_par(&fb->fb); -+ if (ret) -+ return ret; - - print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", fbwidth, - fbheight, fbdepth, fbswap); - -From 1965f1d8dcc748e1f9ba3ff28c8fb5191e081a4d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 20:49:04 +0200 -Subject: [PATCH 135/216] BCM2708: vcio: Fix checkpatch issues -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -checkpatch.pl errors and warnings: -Many whitespace related issues in some form or another. -Consider using instead of . -braces {} are not necessary for single statement blocks. -Use pr_* instead of printk. -Do not initialise statics to 0 or NULL. -Avoid CamelCase. -sizeof size should be sizeof(size). -break is not useful after a goto or return. -struct file_operations should normally be const -Possible unnecessary 'out of memory' message -Comparison to NULL could be written "!res" -quoted string split across lines. - -This has not been adressed: -WARNING: consider using a completion - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/vcio.h | 12 ++- - arch/arm/mach-bcm2708/vcio.c | 123 ++++++++++++++---------------- - 2 files changed, 62 insertions(+), 73 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -index 8e11d67e..58188b74 100644 ---- a/arch/arm/mach-bcm2708/include/mach/vcio.h -+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h -@@ -12,10 +12,6 @@ - * 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 _MACH_BCM2708_VCIO_H - #define _MACH_BCM2708_VCIO_H -@@ -34,12 +30,14 @@ - #define MBOX_CHAN_COUNT 9 - - enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 -+ VCMSG_PROCESS_REQUEST = 0x00000000 - }; -+ - enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 - }; -+ - /* Mailbox property tags */ - enum { - VCMSG_PROPERTY_END = 0x00000000, -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 700bff4..5e9e777 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -37,8 +37,7 @@ - #include - #include - --#include -- -+#include - - #define DRIVER_NAME BCM_VCIO_DRIVER_NAME - -@@ -61,7 +60,9 @@ - #define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) - - #define MBOX_MAGIC 0xd0d0c0de --static struct class *vcio_class = NULL; -+ -+static struct class *vcio_class; -+ - struct vc_mailbox { - struct device *dev; /* parent device */ - void __iomem *status; -@@ -102,9 +103,9 @@ static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - { - int rc; - -- if (mbox->magic != MBOX_MAGIC) -+ if (mbox->magic != MBOX_MAGIC) { - rc = -EINVAL; -- else { -+ } else { - /* wait for the mailbox FIFO to have some space in it */ - while (0 != (readl(mbox->status) & ARM_MS_FULL)) - cpu_relax(); -@@ -119,9 +120,9 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - { - int rc; - -- if (mbox->magic != MBOX_MAGIC) -+ if (mbox->magic != MBOX_MAGIC) { - rc = -EINVAL; -- else { -+ } else { - down(&mbox->sema[chan]); - *data28 = MBOX_DATA28(mbox->msg[chan]); - mbox->msg[chan] = 0; -@@ -133,17 +134,18 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - static irqreturn_t mbox_irq(int irq, void *dev_id) - { - /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -+ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; - int status = readl(mbox->status); - int ret = IRQ_NONE; - - while (!(status & ARM_MS_EMPTY)) { - uint32_t msg = readl(mbox->read); - int chan = MBOX_CHAN(msg); -+ - if (chan < MBOX_CHAN_COUNT) { - if (mbox->msg[chan]) { - /* Overflow */ -- printk(KERN_ERR DRIVER_NAME -+ pr_err(DRIVER_NAME - ": mbox chan %d overflow - drop %08x\n", - chan, msg); - } else { -@@ -151,7 +153,7 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - up(&mbox->sema[chan]); - } - } else { -- printk(KERN_ERR DRIVER_NAME -+ pr_err(DRIVER_NAME - ": invalid channel selector (msg %08x)\n", msg); - } - ret = IRQ_HANDLED; -@@ -174,9 +176,9 @@ static struct device *mbox_dev; /* we assume there's only one! */ - - static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) - { -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); - int rc; - -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); - device_lock(dev); - rc = mbox_write(mailbox, chan, data28); - device_unlock(dev); -@@ -186,9 +188,9 @@ static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) - - static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) - { -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); - int rc; - -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); - device_lock(dev); - rc = mbox_read(mailbox, chan, data28); - device_unlock(dev); -@@ -221,41 +223,36 @@ static void dev_mbox_register(const char *dev_name, struct device *dev) - - static int mbox_copy_from_user(void *dst, const void *src, int size) - { -- if ( (uint32_t)src < TASK_SIZE) -- { -+ if ((uint32_t)src < TASK_SIZE) - return copy_from_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } -+ -+ memcpy(dst, src, size); -+ -+ return 0; - } - - static int mbox_copy_to_user(void *dst, const void *src, int size) - { -- if ( (uint32_t)dst < TASK_SIZE) -- { -+ if ((uint32_t)dst < TASK_SIZE) - return copy_to_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } -+ -+ memcpy(dst, src, size); -+ -+ return 0; - } - - static DEFINE_MUTEX(mailbox_lock); - extern int bcm_mailbox_property(void *data, int size) - { - uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ - int s = 0; - -- mutex_lock(&mailbox_lock); -+ mutex_lock(&mailbox_lock); - /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -+ GFP_ATOMIC); - if (mem_kern) { - /* create the message */ - mbox_copy_from_user(mem_kern, data, size); -@@ -263,9 +260,8 @@ extern int bcm_mailbox_property(void *data, int size) - /* send the message */ - wmb(); - s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) { -+ if (s == 0) - s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- } - if (s == 0) { - /* copy the response */ - rmb(); -@@ -276,9 +272,9 @@ extern int bcm_mailbox_property(void *data, int size) - s = -ENOMEM; - } - if (s != 0) -- printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); - -- mutex_unlock(&mailbox_lock); -+ mutex_unlock(&mailbox_lock); - return s; - } - EXPORT_SYMBOL_GPL(bcm_mailbox_property); -@@ -291,7 +287,7 @@ EXPORT_SYMBOL_GPL(bcm_mailbox_property); - * Is the device open right now? Used to prevent - * concurent access into the same device - */ --static int Device_Open = 0; -+static bool device_is_open; - - /* - * This is called whenever a process attempts to open the device file -@@ -301,10 +297,10 @@ static int device_open(struct inode *inode, struct file *file) - /* - * We don't want to talk to two processes at the same time - */ -- if (Device_Open) -+ if (device_is_open) - return -EBUSY; - -- Device_Open++; -+ device_is_open = true; - /* - * Initialize the message - */ -@@ -317,7 +313,7 @@ static int device_release(struct inode *inode, struct file *file) - /* - * We're now ready for our next caller - */ -- Device_Open--; -+ device_is_open = false; - - module_put(THIS_MODULE); - return 0; -@@ -333,9 +329,8 @@ static int device_release(struct inode *inode, struct file *file) - * calling process), the ioctl call returns the output of this function. - * - */ --static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -- unsigned int ioctl_num, /* number and param for ioctl */ -- unsigned long ioctl_param) -+static long device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) - { - unsigned size; - /* -@@ -348,11 +343,10 @@ static long device_ioctl(struct file *file, /* see include/linux/fs.h */ - * to be the device's message. Get the parameter given to - * ioctl by the process. - */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); - return bcm_mailbox_property((void *)ioctl_param, size); -- break; - default: -- printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); - return -EINVAL; - } - -@@ -368,7 +362,7 @@ static long device_ioctl(struct file *file, /* see include/linux/fs.h */ - * the devices table, it can't be local to - * init_module. NULL is for unimplemented functios. - */ --struct file_operations fops = { -+const struct file_operations fops = { - .unlocked_ioctl = device_ioctl, - .open = device_open, - .release = device_release, /* a.k.a. close */ -@@ -380,17 +374,15 @@ static int bcm_vcio_probe(struct platform_device *pdev) - struct vc_mailbox *mailbox; - - mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -- if (NULL == mailbox) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "mailbox memory\n"); -+ if (!mailbox) { - ret = -ENOMEM; - } else { - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -+ if (!res) { -+ pr_err(DRIVER_NAME -+ ": failed to obtain memory resource\n"); - ret = -ENODEV; - kfree(mailbox); - } else { -@@ -402,8 +394,8 @@ static int bcm_vcio_probe(struct platform_device *pdev) - - mbox_irqaction.dev_id = mailbox; - setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -- printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -- __io_address(ARM_0_MAIL0_RD)); -+ dev_info(&pdev->dev, "mailbox at %p\n", -+ __io_address(ARM_0_MAIL0_RD)); - } - } - -@@ -417,17 +409,18 @@ static int bcm_vcio_probe(struct platform_device *pdev) - * Negative values signify an error - */ - if (ret < 0) { -- printk(KERN_ERR DRIVER_NAME -- "Failed registering the character device %d\n", ret); -+ pr_err(DRIVER_NAME -+ "Failed registering the character device %d\n", -+ ret); - return ret; - } - vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); - if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- return ret ; -+ ret = PTR_ERR(vcio_class); -+ return ret; - } - device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -+ "vcio"); - } - return ret; - } -@@ -456,20 +449,18 @@ static int __init bcm_mbox_init(void) - { - int ret; - -- printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -+ pr_info("mailbox: Broadcom VideoCore Mailbox driver\n"); - - ret = platform_driver_register(&bcm_mbox_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -+ if (ret) -+ pr_err(DRIVER_NAME ": failed to register on platform\n"); - - return ret; - } - - static void __exit bcm_mbox_exit(void) - { -- device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); - class_destroy(vcio_class); - unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - -From f7567a97143abdc87b5dc258b3b628ba115ce0b2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:02:44 +0200 -Subject: [PATCH 136/216] BCM2708: vcio: Remove unused code and compact - comments -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The config reference SERIAL_BCM_MBOX_CONSOLE does not exist, -so remove the whole clause as it will always be false. - -Remove includes that are not needed. -Add . -Also sort include headers alphabetically, since this -is now the preferred coding style. - -Remove vc_mailbox->dev since it is not used. - -Compact some comments to one line. -Remove superfluous comments. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 68 ++++++++++---------------------------------- - 1 file changed, 15 insertions(+), 53 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 5e9e777..270f126 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -12,39 +12,24 @@ - * VideoCore processor - */ - --#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) --#define SUPPORT_SYSRQ --#endif -- -+#include -+#include - #include --#include --#include --#include - #include --#include -+#include - #include --#include --#include --#include --#include --#include --#include - #include --#include -- - #include -+#include -+#include -+#include -+#include - - #include - #include - --#include -- - #define DRIVER_NAME BCM_VCIO_DRIVER_NAME - --/* ---------------------------------------------------------------------- -- * Mailbox -- * -------------------------------------------------------------------- */ -- - /* offsets from a mail box base address */ - #define MAIL_WRT 0x00 /* write - and next 4 words */ - #define MAIL_RD 0x00 /* read - and next 4 words */ -@@ -64,7 +49,6 @@ - static struct class *vcio_class; - - struct vc_mailbox { -- struct device *dev; /* parent device */ - void __iomem *status; - void __iomem *config; - void __iomem *read; -@@ -79,7 +63,6 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - { - int i; - -- mbox_out->dev = dev; - mbox_out->status = __io_address(addr_mbox + MAIL_STA); - mbox_out->config = __io_address(addr_mbox + MAIL_CNF); - mbox_out->read = __io_address(addr_mbox + MAIL_RD); -@@ -144,7 +127,6 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - - if (chan < MBOX_CHAN_COUNT) { - if (mbox->msg[chan]) { -- /* Overflow */ - pr_err(DRIVER_NAME - ": mbox chan %d overflow - drop %08x\n", - chan, msg); -@@ -168,9 +150,7 @@ static struct irqaction mbox_irqaction = { - .handler = mbox_irq, - }; - --/* ---------------------------------------------------------------------- -- * Mailbox Methods -- * -------------------------------------------------------------------- */ -+/* Mailbox Methods */ - - static struct device *mbox_dev; /* we assume there's only one! */ - -@@ -279,9 +259,7 @@ extern int bcm_mailbox_property(void *data, int size) - } - EXPORT_SYMBOL_GPL(bcm_mailbox_property); - --/* ---------------------------------------------------------------------- -- * Platform Device for Mailbox -- * -------------------------------------------------------------------- */ -+/* Platform Device for Mailbox */ - - /* - * Is the device open right now? Used to prevent -@@ -289,33 +267,26 @@ EXPORT_SYMBOL_GPL(bcm_mailbox_property); - */ - static bool device_is_open; - --/* -- * This is called whenever a process attempts to open the device file -- */ -+/* This is called whenever a process attempts to open the device file */ - static int device_open(struct inode *inode, struct file *file) - { -- /* -- * We don't want to talk to two processes at the same time -- */ -+ /* We don't want to talk to two processes at the same time */ - if (device_is_open) - return -EBUSY; - - device_is_open = true; -- /* -- * Initialize the message -- */ - try_module_get(THIS_MODULE); -+ - return 0; - } - - static int device_release(struct inode *inode, struct file *file) - { -- /* -- * We're now ready for our next caller -- */ -+ /* We're now ready for our next caller */ - device_is_open = false; - - module_put(THIS_MODULE); -+ - return 0; - } - -@@ -333,9 +304,7 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num, - unsigned long ioctl_param) - { - unsigned size; -- /* -- * Switch according to the ioctl called -- */ -+ - switch (ioctl_num) { - case IOCTL_MBOX_PROPERTY: - /* -@@ -400,14 +369,7 @@ static int bcm_vcio_probe(struct platform_device *pdev) - } - - if (ret == 0) { -- /* -- * Register the character device -- */ - ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- -- /* -- * Negative values signify an error -- */ - if (ret < 0) { - pr_err(DRIVER_NAME - "Failed registering the character device %d\n", - -From 406f0f628a2f978a1da4d25dda3b5eafb94cefd0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:10:18 +0200 -Subject: [PATCH 137/216] BCM2708: vcio: Move character device teardown to - driver remove -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -chrdev is created in the probe function, but teared down in module exit. -Move chrdev teardown to happen on device removal. -Also add missing mbox_dev disabling. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 270f126..cac8dd7 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -391,8 +391,12 @@ static int bcm_vcio_remove(struct platform_device *pdev) - { - struct vc_mailbox *mailbox = platform_get_drvdata(pdev); - -+ mbox_dev = NULL; - platform_set_drvdata(pdev, NULL); - kfree(mailbox); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - - return 0; - } -@@ -422,9 +426,6 @@ static int __init bcm_mbox_init(void) - - static void __exit bcm_mbox_exit(void) - { -- device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - } - - -From fa189cd5d18e5cda8438873181a329fc489a6649 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:20:46 +0200 -Subject: [PATCH 138/216] BCM2708: vcio: Restructure error paths -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to use if/else clauses on error when return can be used directly. -Also test for errors first if possible. -This is done to enhance readability. -bcm_vcio_probe() is not touched, it will be reworked later. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 48 +++++++++++++++++++------------------------- - 1 file changed, 21 insertions(+), 27 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index cac8dd7..36e0f1e 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -84,34 +84,28 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - - static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - { -- int rc; -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; - -- if (mbox->magic != MBOX_MAGIC) { -- rc = -EINVAL; -- } else { -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->status) & ARM_MS_FULL)) -- cpu_relax(); -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ cpu_relax(); - -- writel(MBOX_MSG(chan, data28), mbox->write); -- rc = 0; -- } -- return rc; -+ writel(MBOX_MSG(chan, data28), mbox->write); -+ -+ return 0; - } - - static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - { -- int rc; -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; - -- if (mbox->magic != MBOX_MAGIC) { -- rc = -EINVAL; -- } else { -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- rc = 0; -- } -- return rc; -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ -+ return 0; - } - - static irqreturn_t mbox_irq(int irq, void *dev_id) -@@ -180,19 +174,19 @@ static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) - - extern int bcm_mailbox_write(unsigned chan, uint32_t data28) - { -- if (mbox_dev) -- return dev_mbox_write(mbox_dev, chan, data28); -- else -+ if (!mbox_dev) - return -ENODEV; -+ -+ return dev_mbox_write(mbox_dev, chan, data28); - } - EXPORT_SYMBOL_GPL(bcm_mailbox_write); - - extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) - { -- if (mbox_dev) -- return dev_mbox_read(mbox_dev, chan, data28); -- else -+ if (!mbox_dev) - return -ENODEV; -+ -+ return dev_mbox_read(mbox_dev, chan, data28); - } - EXPORT_SYMBOL_GPL(bcm_mailbox_read); - - -From ce2c991a11f0a94679423655dceed9bb80604892 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:28:31 +0200 -Subject: [PATCH 139/216] BCM2708: vcio: Move some macros from header to driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Move some macros that are only used by the driver: -MAJOR_NUM -IOCTL_MBOX_PROPERTY -DEVICE_FILE_NAME - -This one becomes superfluous: BCM_VCIO_DRIVER_NAME - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/vcio.h | 35 ------------------------------- - arch/arm/mach-bcm2708/vcio.c | 9 ++++++-- - 2 files changed, 7 insertions(+), 37 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -index 58188b74..95ad121 100644 ---- a/arch/arm/mach-bcm2708/include/mach/vcio.h -+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h -@@ -20,8 +20,6 @@ - * (semaphores, doorbells, mailboxes) - */ - --#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -- - /* Constants shared with the ARM identifying separate mailbox channels */ - #define MBOX_CHAN_POWER 0 /* for use by the power management interface */ - #define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -@@ -127,37 +125,4 @@ extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); - extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); - extern int /*rc*/ bcm_mailbox_property(void *data, int size); - --#include -- --/* -- * The major device number. We can't rely on dynamic -- * registration any more, because ioctls need to know -- * it. -- */ --#define MAJOR_NUM 100 -- --/* -- * Set the message of the device driver -- */ --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) --/* -- * _IOWR means that we're creating an ioctl command -- * number for passing information from a user process -- * to the kernel module and from the kernel module to user process -- * -- * The first arguments, MAJOR_NUM, is the major device -- * number we're using. -- * -- * The second argument is the number of the command -- * (there could be several with different meanings). -- * -- * The third argument is the type we want to get from -- * the process to the kernel. -- */ -- --/* -- * The name of the device file -- */ --#define DEVICE_FILE_NAME "vcio" -- - #endif -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 36e0f1e..75cf955 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -28,7 +29,8 @@ - #include - #include - --#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -+#define DRIVER_NAME "bcm2708_vcio" -+#define DEVICE_FILE_NAME "vcio" - - /* offsets from a mail box base address */ - #define MAIL_WRT 0x00 /* write - and next 4 words */ -@@ -46,6 +48,9 @@ - - #define MBOX_MAGIC 0xd0d0c0de - -+#define MAJOR_NUM 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+ - static struct class *vcio_class; - - struct vc_mailbox { -@@ -370,7 +375,7 @@ static int bcm_vcio_probe(struct platform_device *pdev) - ret); - return ret; - } -- vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); - if (IS_ERR(vcio_class)) { - ret = PTR_ERR(vcio_class); - return ret; - -From 71c6a7270af56930e1e31ff243048c1ac12ebc1f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:40:03 +0200 -Subject: [PATCH 140/216] BCM2708: vcio: Only store the register base address -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to keep pointers to the sub registers. Only -store the base address. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 37 ++++++++++++++----------------------- - 1 file changed, 14 insertions(+), 23 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 75cf955..e67fa3e 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -33,12 +33,12 @@ - #define DEVICE_FILE_NAME "vcio" - - /* offsets from a mail box base address */ --#define MAIL_WRT 0x00 /* write - and next 4 words */ --#define MAIL_RD 0x00 /* read - and next 4 words */ --#define MAIL_POL 0x10 /* read without popping the fifo */ --#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL_STA 0x18 /* status */ --#define MAIL_CNF 0x1C /* configuration */ -+#define MAIL0_RD 0x00 /* read - and next 4 words */ -+#define MAIL0_POL 0x10 /* read without popping the fifo */ -+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL0_STA 0x18 /* status */ -+#define MAIL0_CNF 0x1C /* configuration */ -+#define MAIL1_WRT 0x20 /* write - and next 4 words */ - - #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) - #define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -@@ -54,10 +54,7 @@ - static struct class *vcio_class; - - struct vc_mailbox { -- void __iomem *status; -- void __iomem *config; -- void __iomem *read; -- void __iomem *write; -+ void __iomem *regs; - uint32_t msg[MBOX_CHAN_COUNT]; - struct semaphore sema[MBOX_CHAN_COUNT]; - uint32_t magic; -@@ -68,13 +65,7 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - { - int i; - -- mbox_out->status = __io_address(addr_mbox + MAIL_STA); -- mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -- mbox_out->read = __io_address(addr_mbox + MAIL_RD); -- /* Write to the other mailbox */ -- mbox_out->write = -- __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -- MAIL_WRT); -+ mbox_out->regs = __io_address(addr_mbox); - - for (i = 0; i < MBOX_CHAN_COUNT; i++) { - mbox_out->msg[i] = 0; -@@ -82,7 +73,7 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - } - - /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); - - mbox_out->magic = MBOX_MAGIC; - } -@@ -93,10 +84,10 @@ static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - return -EINVAL; - - /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) - cpu_relax(); - -- writel(MBOX_MSG(chan, data28), mbox->write); -+ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); - - return 0; - } -@@ -117,11 +108,11 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - { - /* wait for the mailbox FIFO to have some data in it */ - struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -- int status = readl(mbox->status); -+ int status = readl(mbox->regs + MAIL0_STA); - int ret = IRQ_NONE; - - while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->read); -+ uint32_t msg = readl(mbox->regs + MAIL0_RD); - int chan = MBOX_CHAN(msg); - - if (chan < MBOX_CHAN_COUNT) { -@@ -138,7 +129,7 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - ": invalid channel selector (msg %08x)\n", msg); - } - ret = IRQ_HANDLED; -- status = readl(mbox->status); -+ status = readl(mbox->regs + MAIL0_STA); - } - return ret; - } - -From 30e7622ceffd50a31b6544e3a3e05bb0743c3bc2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:44:39 +0200 -Subject: [PATCH 141/216] BCM2708: vcio: Do not print messages in module init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It is not common practice to print messages from a -module init function that only register a driver. -Remove obsolete module alias. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 11 +---------- - 1 file changed, 1 insertion(+), 10 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index e67fa3e..ff50ebd 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -403,15 +403,7 @@ static struct platform_driver bcm_mbox_driver = { - - static int __init bcm_mbox_init(void) - { -- int ret; -- -- pr_info("mailbox: Broadcom VideoCore Mailbox driver\n"); -- -- ret = platform_driver_register(&bcm_mbox_driver); -- if (ret) -- pr_err(DRIVER_NAME ": failed to register on platform\n"); -- -- return ret; -+ return platform_driver_register(&bcm_mbox_driver); - } - - static void __exit bcm_mbox_exit(void) -@@ -425,4 +417,3 @@ module_exit(bcm_mbox_exit); - MODULE_AUTHOR("Gray Girling"); - MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); - MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm-mbox"); - -From 7a9128973d51200625a3d3f8ff72a4580cb9f14b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 23:33:43 +0200 -Subject: [PATCH 142/216] BCM2708: vcio: Use device resources -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use device resources instead of hardcoding them. -Use devm_* functions where possible. -Merge dev_mbox_register() with probe function. -Add Device Tree support. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 122 +++++++++++++++++++++---------------------- - 1 file changed, 61 insertions(+), 61 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index ff50ebd..c4c2bcd 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -21,13 +21,10 @@ - #include - #include - #include --#include - #include --#include - #include - - #include --#include - - #define DRIVER_NAME "bcm2708_vcio" - #define DEVICE_FILE_NAME "vcio" -@@ -60,13 +57,10 @@ struct vc_mailbox { - uint32_t magic; - }; - --static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -- uint32_t addr_mbox) -+static void mbox_init(struct vc_mailbox *mbox_out) - { - int i; - -- mbox_out->regs = __io_address(addr_mbox); -- - for (i = 0; i < MBOX_CHAN_COUNT; i++) { - mbox_out->msg[i] = 0; - sema_init(&mbox_out->sema[i], 0); -@@ -104,7 +98,7 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - return 0; - } - --static irqreturn_t mbox_irq(int irq, void *dev_id) -+static irqreturn_t mbox_irq_handler(int irq, void *dev_id) - { - /* wait for the mailbox FIFO to have some data in it */ - struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -@@ -134,12 +128,6 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - return ret; - } - --static struct irqaction mbox_irqaction = { -- .name = "ARM Mailbox IRQ", -- .flags = IRQF_DISABLED | IRQF_IRQPOLL, -- .handler = mbox_irq, --}; -- - /* Mailbox Methods */ - - static struct device *mbox_dev; /* we assume there's only one! */ -@@ -186,11 +174,6 @@ extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) - } - EXPORT_SYMBOL_GPL(bcm_mailbox_read); - --static void dev_mbox_register(const char *dev_name, struct device *dev) --{ -- mbox_dev = dev; --} -- - static int mbox_copy_from_user(void *dst, const void *src, int size) - { - if ((uint32_t)src < TASK_SIZE) -@@ -329,61 +312,71 @@ const struct file_operations fops = { - - static int bcm_vcio_probe(struct platform_device *pdev) - { -- int ret = 0; -+ struct device *dev = &pdev->dev; -+ struct device *vdev; - struct vc_mailbox *mailbox; -+ struct resource *res; -+ int irq, ret; -+ -+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -+ if (!mailbox) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mailbox->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mailbox->regs)) -+ return PTR_ERR(mailbox->regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, irq, mbox_irq_handler, -+ IRQF_DISABLED | IRQF_IRQPOLL, -+ dev_name(dev), mailbox); -+ if (ret) { -+ dev_err(dev, "Interrupt request failed %d\n", ret); -+ return ret; -+ } - -- mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -- if (!mailbox) { -- ret = -ENOMEM; -- } else { -- struct resource *res; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!res) { -- pr_err(DRIVER_NAME -- ": failed to obtain memory resource\n"); -- ret = -ENODEV; -- kfree(mailbox); -- } else { -- /* should be based on the registers from res really */ -- mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -- -- platform_set_drvdata(pdev, mailbox); -- dev_mbox_register(DRIVER_NAME, &pdev->dev); -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ if (ret < 0) { -+ pr_err("Character device registration failed %d\n", ret); -+ return ret; -+ } - -- mbox_irqaction.dev_id = mailbox; -- setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -- dev_info(&pdev->dev, "mailbox at %p\n", -- __io_address(ARM_0_MAIL0_RD)); -- } -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ pr_err("Class creation failed %d\n", ret); -+ goto err_class; - } - -- if (ret == 0) { -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- if (ret < 0) { -- pr_err(DRIVER_NAME -- "Failed registering the character device %d\n", -- ret); -- return ret; -- } -- vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- return ret; -- } -- device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -+ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); -+ if (IS_ERR(vdev)) { -+ ret = PTR_ERR(vdev); -+ pr_err("Device creation failed %d\n", ret); -+ goto err_dev; - } -+ -+ mbox_init(mailbox); -+ platform_set_drvdata(pdev, mailbox); -+ mbox_dev = dev; -+ -+ dev_info(dev, "mailbox at %p\n", mailbox->regs); -+ -+ return 0; -+ -+err_dev: -+ class_destroy(vcio_class); -+err_class: -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ - return ret; - } - - static int bcm_vcio_remove(struct platform_device *pdev) - { -- struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -- - mbox_dev = NULL; - platform_set_drvdata(pdev, NULL); -- kfree(mailbox); - device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); - class_destroy(vcio_class); - unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -@@ -391,6 +384,12 @@ static int bcm_vcio_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm_vcio_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-vcio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -+ - static struct platform_driver bcm_mbox_driver = { - .probe = bcm_vcio_probe, - .remove = bcm_vcio_remove, -@@ -398,6 +397,7 @@ static struct platform_driver bcm_mbox_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm_vcio_of_match_table, - }, - }; - - -From bb294088d80bcba531bc3d58b4a6c08b8cdcb0b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 19:11:03 +0200 -Subject: [PATCH 143/216] mailbox: bcm2708: Add bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Copy the arch vcio.c driver to drivers/mailbox. -This is done to make it available on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 6 + - drivers/mailbox/Makefile | 2 + - drivers/mailbox/bcm2708-vcio.c | 426 ++++++++++++++++++++++++++ - include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++ - 4 files changed, 560 insertions(+) - create mode 100644 drivers/mailbox/bcm2708-vcio.c - create mode 100644 include/linux/platform_data/mailbox-bcm2708.h - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 84325f2..fdcb206 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -6,6 +6,12 @@ menuconfig MAILBOX - signals. Say Y if your platform supports hardware mailboxes. - - if MAILBOX -+config BCM2708_MBOX -+ bool "Broadcom BCM2708 Mailbox (vcio)" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ help -+ Broadcom BCM2708 Mailbox (vcio) -+ - config PL320_MBOX - bool "ARM PL320 Mailbox" - depends on ARM_AMBA -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index 2e79231..c2d2bed 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -2,6 +2,8 @@ - - obj-$(CONFIG_MAILBOX) += mailbox.o - -+obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o -+ - obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o - - obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -new file mode 100644 -index 0000000..ee3e778 ---- /dev/null -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -0,0 +1,426 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_vcio" -+#define DEVICE_FILE_NAME "vcio" -+ -+/* offsets from a mail box base address */ -+#define MAIL0_RD 0x00 /* read - and next 4 words */ -+#define MAIL0_POL 0x10 /* read without popping the fifo */ -+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL0_STA 0x18 /* status */ -+#define MAIL0_CNF 0x1C /* configuration */ -+#define MAIL1_WRT 0x20 /* write - and next 4 words */ -+ -+/* On MACH_BCM270x these come through (arm_control.h ) */ -+#ifndef ARM_MS_EMPTY -+#define ARM_MS_EMPTY BIT(30) -+#define ARM_MS_FULL BIT(31) -+ -+#define ARM_MC_IHAVEDATAIRQEN BIT(0) -+#endif -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+#define MAJOR_NUM 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+ -+static struct class *vcio_class; -+ -+struct vc_mailbox { -+ void __iomem *regs; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out) -+{ -+ int i; -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -+ -+ return 0; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ -+ return 0; -+} -+ -+static irqreturn_t mbox_irq_handler(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -+ int status = readl(mbox->regs + MAIL0_STA); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->regs + MAIL0_RD); -+ int chan = MBOX_CHAN(msg); -+ -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ pr_err(DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ pr_err(DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->regs + MAIL0_STA); -+ } -+ return ret; -+} -+ -+/* Mailbox Methods */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_write(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_read(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)src < TASK_SIZE) -+ return copy_from_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)dst < TASK_SIZE) -+ return copy_to_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -+ GFP_ATOMIC); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* Platform Device for Mailbox */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static bool device_is_open; -+ -+/* This is called whenever a process attempts to open the device file */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* We don't want to talk to two processes at the same time */ -+ if (device_is_open) -+ return -EBUSY; -+ -+ device_is_open = true; -+ try_module_get(THIS_MODULE); -+ -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* We're now ready for our next caller */ -+ device_is_open = false; -+ -+ module_put(THIS_MODULE); -+ -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ default: -+ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+const struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device *vdev; -+ struct vc_mailbox *mailbox; -+ struct resource *res; -+ int irq, ret; -+ -+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -+ if (!mailbox) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mailbox->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mailbox->regs)) -+ return PTR_ERR(mailbox->regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, irq, mbox_irq_handler, -+ IRQF_DISABLED | IRQF_IRQPOLL, -+ dev_name(dev), mailbox); -+ if (ret) { -+ dev_err(dev, "Interrupt request failed %d\n", ret); -+ return ret; -+ } -+ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ if (ret < 0) { -+ pr_err("Character device registration failed %d\n", ret); -+ return ret; -+ } -+ -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ pr_err("Class creation failed %d\n", ret); -+ goto err_class; -+ } -+ -+ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); -+ if (IS_ERR(vdev)) { -+ ret = PTR_ERR(vdev); -+ pr_err("Device creation failed %d\n", ret); -+ goto err_dev; -+ } -+ -+ mbox_init(mailbox); -+ platform_set_drvdata(pdev, mailbox); -+ mbox_dev = dev; -+ -+ dev_info(dev, "mailbox at %p\n", mailbox->regs); -+ -+ return 0; -+ -+err_dev: -+ class_destroy(vcio_class); -+err_class: -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ mbox_dev = NULL; -+ platform_set_drvdata(pdev, NULL); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm_vcio_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-vcio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm_vcio_of_match_table, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ return platform_driver_register(&bcm_mbox_driver); -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -new file mode 100644 -index 0000000..cc284ed ---- /dev/null -+++ b/include/linux/platform_data/mailbox-bcm2708.h -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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. -+ */ -+#ifndef _PLAT_MAILBOX_BCM2708_H -+#define _PLAT_MAILBOX_BCM2708_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+ -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+ -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+int bcm_mailbox_read(unsigned chan, uint32_t *data28); -+int bcm_mailbox_write(unsigned chan, uint32_t data28); -+int bcm_mailbox_property(void *data, int size); -+ -+#endif - -From 1e5c7135fc145addcf195d02759a45e162f2daac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 19:11:58 +0200 -Subject: [PATCH 144/216] BCM270x: power: Change initcall level to subsys -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Load ordering of modules are determined by the initcall used. -If it's the same initcall level, makefile ordering decides. -Now that the mailbox driver is being moved, it's no longer -placed before the power driver by the linker. -So use a later initcall level to let the mailbox driver -load first. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/power.c | 6 +++++- - arch/arm/mach-bcm2709/power.c | 6 +++++- - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -index 2696be9..0db355d 100644 ---- a/arch/arm/mach-bcm2708/power.c -+++ b/arch/arm/mach-bcm2708/power.c -@@ -189,7 +189,11 @@ static void __exit bcm_power_exit(void) - bcm_mailbox_write(MBOX_CHAN_POWER, 0); - } - --arch_initcall(bcm_power_init); /* Initialize early */ -+/* -+ * Load after the mailbox driver is initialized (arch_initcall), -+ * but before depending drivers (module_init). -+ */ -+subsys_initcall(bcm_power_init); - module_exit(bcm_power_exit); - - MODULE_AUTHOR("Phil Elwell"); -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -index 3421057..88c1e28 100644 ---- a/arch/arm/mach-bcm2709/power.c -+++ b/arch/arm/mach-bcm2709/power.c -@@ -187,7 +187,11 @@ static void __exit bcm_power_exit(void) - bcm_mailbox_write(MBOX_CHAN_POWER, 0); - } - --arch_initcall(bcm_power_init); /* Initialize early */ -+/* -+ * Load after the mailbox driver is initialized (arch_initcall), -+ * but before depending drivers (module_init). -+ */ -+subsys_initcall(bcm_power_init); - module_exit(bcm_power_exit); - - MODULE_AUTHOR("Phil Elwell"); - -From 41e80f86dc78015856087cccd8e4f9a251042f9d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 2 May 2015 09:34:26 +0200 -Subject: [PATCH 145/216] BCM270x: Use bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use bcm2708-vcio instead of the arch version. -Change affected drivers to use linux/platform_data/mailbox-bcm2708.h - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/power.c | 2 +- - arch/arm/mach-bcm2708/vc_mem.c | 2 +- - arch/arm/mach-bcm2709/Makefile | 2 +- - arch/arm/mach-bcm2709/power.c | 2 +- - arch/arm/mach-bcm2709/vc_mem.c | 2 +- - arch/arm/mach-bcm2709/vc_support.c | 2 +- - drivers/cpufreq/bcm2835-cpufreq.c | 2 +- - drivers/hwmon/bcm2835-hwmon.c | 2 +- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +- - drivers/thermal/bcm2835-thermal.c | 2 +- - drivers/video/fbdev/bcm2708_fb.c | 2 +- - 14 files changed, 16 insertions(+), 12 deletions(-) - mode change 100755 => 100644 arch/arm/mach-bcm2709/vc_support.c - mode change 100755 => 100644 drivers/cpufreq/bcm2835-cpufreq.c - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 367a04a..ff87581 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1052,6 +1052,8 @@ CONFIG_FB_TFT_UPD161704=m - CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index db287f3..e339979 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1045,6 +1045,8 @@ CONFIG_FB_TFT_UPD161704=m - CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index 454408c..c1e7d41 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -index 0db355d..796837f 100644 ---- a/arch/arm/mach-bcm2708/power.c -+++ b/arch/arm/mach-bcm2708/power.c -@@ -14,8 +14,8 @@ - #include - #include - #include -+#include - #include --#include - #include - - #define DRIVER_NAME "bcm2708_power" -diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c -index 2982af7..226b737 100644 ---- a/arch/arm/mach-bcm2708/vc_mem.c -+++ b/arch/arm/mach-bcm2708/vc_mem.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_ARCH_KONA - #include -@@ -31,7 +32,6 @@ - #endif - - #include "mach/vc_mem.h" --#include - - #define DRIVER_NAME "vc-mem" - -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index f07c38b..77b8429 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -index 88c1e28..960e472 100644 ---- a/arch/arm/mach-bcm2709/power.c -+++ b/arch/arm/mach-bcm2709/power.c -@@ -14,8 +14,8 @@ - #include - #include - #include -+#include - #include --#include - #include - - #define DRIVER_NAME "bcm2708_power" -diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c -index ac578db..d2adfd1 100644 ---- a/arch/arm/mach-bcm2709/vc_mem.c -+++ b/arch/arm/mach-bcm2709/vc_mem.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_ARCH_KONA - #include -@@ -31,7 +32,6 @@ - #endif - - #include "mach/vc_mem.h" --#include - - #define DRIVER_NAME "vc-mem" - -diff --git a/arch/arm/mach-bcm2709/vc_support.c b/arch/arm/mach-bcm2709/vc_support.c -old mode 100755 -new mode 100644 -index 0bc41c4..c4dc7d6 ---- a/arch/arm/mach-bcm2709/vc_support.c -+++ b/arch/arm/mach-bcm2709/vc_support.c -@@ -6,7 +6,7 @@ - */ - - #include --#include -+#include - - #ifdef ECLIPSE_IGNORE - -diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c -old mode 100755 -new mode 100644 -index 447ca09..6735da9 ---- a/drivers/cpufreq/bcm2835-cpufreq.c -+++ b/drivers/cpufreq/bcm2835-cpufreq.c -@@ -26,7 +26,7 @@ - #include - #include - #include --#include -+#include - - /* ---------- DEFINES ---------- */ - /*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ -diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c -index 5bbed45..d14502c 100644 ---- a/drivers/hwmon/bcm2835-hwmon.c -+++ b/drivers/hwmon/bcm2835-hwmon.c -@@ -17,9 +17,9 @@ - #include - #include - #include -+#include - #include - #include --#include - #include - #include - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 8ec88bb..70e5086 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -40,13 +40,13 @@ - #include - #include - #include -+#include - #include - #include - - #include - - #include --#include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - -diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c -index 85fceb5..0c556d1 100644 ---- a/drivers/thermal/bcm2835-thermal.c -+++ b/drivers/thermal/bcm2835-thermal.c -@@ -15,10 +15,10 @@ - #include - #include - #include -+#include - #include - #include - #include --#include - #include - - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 52e655a..345c15e 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -32,7 +33,6 @@ - - #include - #include --#include - - #include - #include - -From 5bb0a0c80fc46ae0edea87f97244f28fb167dfe0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 2 May 2015 09:35:07 +0200 -Subject: [PATCH 146/216] BCM270x: Remove arch driver vcio.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove the arch vcio.c driver and header file. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/vcio.h | 128 -------- - arch/arm/mach-bcm2708/vcio.c | 419 -------------------------- - arch/arm/mach-bcm2709/include/mach/vcio.h | 165 ---------- - arch/arm/mach-bcm2709/vcio.c | 484 ------------------------------ - 4 files changed, 1196 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/vcio.h - delete mode 100644 arch/arm/mach-bcm2708/vcio.c - delete mode 100644 arch/arm/mach-bcm2709/include/mach/vcio.h - delete mode 100644 arch/arm/mach-bcm2709/vcio.c - -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -deleted file mode 100644 -index 95ad121..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/vcio.h -+++ /dev/null -@@ -1,128 +0,0 @@ --/* -- * arch/arm/mach-bcm2708/include/mach/vcio.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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. -- */ --#ifndef _MACH_BCM2708_VCIO_H --#define _MACH_BCM2708_VCIO_H -- --/* Routines to handle I/O via the VideoCore "ARM control" registers -- * (semaphores, doorbells, mailboxes) -- */ -- --/* Constants shared with the ARM identifying separate mailbox channels */ --#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ --#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ --#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ --#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ --#define MBOX_CHAN_COUNT 9 -- --enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 --}; -- --enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 --}; -- --/* Mailbox property tags */ --enum { -- VCMSG_PROPERTY_END = 0x00000000, -- VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -- VCMSG_GET_BOARD_MODEL = 0x00010001, -- VCMSG_GET_BOARD_REVISION = 0x00010002, -- VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -- VCMSG_GET_BOARD_SERIAL = 0x00010004, -- VCMSG_GET_ARM_MEMORY = 0x00010005, -- VCMSG_GET_VC_MEMORY = 0x00010006, -- VCMSG_GET_CLOCKS = 0x00010007, -- VCMSG_GET_COMMAND_LINE = 0x00050001, -- VCMSG_GET_DMA_CHANNELS = 0x00060001, -- VCMSG_GET_POWER_STATE = 0x00020001, -- VCMSG_GET_TIMING = 0x00020002, -- VCMSG_SET_POWER_STATE = 0x00028001, -- VCMSG_GET_CLOCK_STATE = 0x00030001, -- VCMSG_SET_CLOCK_STATE = 0x00038001, -- VCMSG_GET_CLOCK_RATE = 0x00030002, -- VCMSG_SET_CLOCK_RATE = 0x00038002, -- VCMSG_GET_VOLTAGE = 0x00030003, -- VCMSG_SET_VOLTAGE = 0x00038003, -- VCMSG_GET_MAX_CLOCK = 0x00030004, -- VCMSG_GET_MAX_VOLTAGE = 0x00030005, -- VCMSG_GET_TEMPERATURE = 0x00030006, -- VCMSG_GET_MIN_CLOCK = 0x00030007, -- VCMSG_GET_MIN_VOLTAGE = 0x00030008, -- VCMSG_GET_TURBO = 0x00030009, -- VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -- VCMSG_GET_STC = 0x0003000b, -- VCMSG_SET_TURBO = 0x00038009, -- VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -- VCMSG_SET_LOCK_MEM = 0x0003000d, -- VCMSG_SET_UNLOCK_MEM = 0x0003000e, -- VCMSG_SET_RELEASE_MEM = 0x0003000f, -- VCMSG_SET_EXECUTE_CODE = 0x00030010, -- VCMSG_SET_EXECUTE_QPU = 0x00030011, -- VCMSG_SET_ENABLE_QPU = 0x00030012, -- VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -- VCMSG_GET_EDID_BLOCK = 0x00030020, -- VCMSG_GET_CUSTOMER_OTP = 0x00030021, -- VCMSG_SET_CUSTOMER_OTP = 0x00038021, -- VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -- VCMSG_SET_RELEASE_BUFFER = 0x00048001, -- VCMSG_SET_BLANK_SCREEN = 0x00040002, -- VCMSG_TST_BLANK_SCREEN = 0x00044002, -- VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -- VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -- VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -- VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -- VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -- VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -- VCMSG_GET_DEPTH = 0x00040005, -- VCMSG_TST_DEPTH = 0x00044005, -- VCMSG_SET_DEPTH = 0x00048005, -- VCMSG_GET_PIXEL_ORDER = 0x00040006, -- VCMSG_TST_PIXEL_ORDER = 0x00044006, -- VCMSG_SET_PIXEL_ORDER = 0x00048006, -- VCMSG_GET_ALPHA_MODE = 0x00040007, -- VCMSG_TST_ALPHA_MODE = 0x00044007, -- VCMSG_SET_ALPHA_MODE = 0x00048007, -- VCMSG_GET_PITCH = 0x00040008, -- VCMSG_TST_PITCH = 0x00044008, -- VCMSG_SET_PITCH = 0x00048008, -- VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -- VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -- VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -- VCMSG_GET_OVERSCAN = 0x0004000a, -- VCMSG_TST_OVERSCAN = 0x0004400a, -- VCMSG_SET_OVERSCAN = 0x0004800a, -- VCMSG_GET_PALETTE = 0x0004000b, -- VCMSG_TST_PALETTE = 0x0004400b, -- VCMSG_SET_PALETTE = 0x0004800b, -- VCMSG_GET_LAYER = 0x0004000c, -- VCMSG_TST_LAYER = 0x0004400c, -- VCMSG_SET_LAYER = 0x0004800c, -- VCMSG_GET_TRANSFORM = 0x0004000d, -- VCMSG_TST_TRANSFORM = 0x0004400d, -- VCMSG_SET_TRANSFORM = 0x0004800d, -- VCMSG_TST_VSYNC = 0x0004400e, -- VCMSG_SET_VSYNC = 0x0004800e, -- VCMSG_SET_CURSOR_INFO = 0x00008010, -- VCMSG_SET_CURSOR_STATE = 0x00008011, --}; -- --extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); --extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); --extern int /*rc*/ bcm_mailbox_property(void *data, int size); -- --#endif -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -deleted file mode 100644 -index c4c2bcd..0000000 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ /dev/null -@@ -1,419 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/vcio.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for writing to the mailboxes, -- * semaphores, doorbells etc. that are shared between the ARM and the -- * VideoCore processor -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#define DRIVER_NAME "bcm2708_vcio" --#define DEVICE_FILE_NAME "vcio" -- --/* offsets from a mail box base address */ --#define MAIL0_RD 0x00 /* read - and next 4 words */ --#define MAIL0_POL 0x10 /* read without popping the fifo */ --#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL0_STA 0x18 /* status */ --#define MAIL0_CNF 0x1C /* configuration */ --#define MAIL1_WRT 0x20 /* write - and next 4 words */ -- --#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) --#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) --#define MBOX_CHAN(msg) ((msg) & 0xf) --#define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -- --#define MBOX_MAGIC 0xd0d0c0de -- --#define MAJOR_NUM 100 --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -- --static struct class *vcio_class; -- --struct vc_mailbox { -- void __iomem *regs; -- uint32_t msg[MBOX_CHAN_COUNT]; -- struct semaphore sema[MBOX_CHAN_COUNT]; -- uint32_t magic; --}; -- --static void mbox_init(struct vc_mailbox *mbox_out) --{ -- int i; -- -- for (i = 0; i < MBOX_CHAN_COUNT; i++) { -- mbox_out->msg[i] = 0; -- sema_init(&mbox_out->sema[i], 0); -- } -- -- /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -- -- mbox_out->magic = MBOX_MAGIC; --} -- --static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) -- cpu_relax(); -- -- writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -- -- return 0; --} -- --static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- -- return 0; --} -- --static irqreturn_t mbox_irq_handler(int irq, void *dev_id) --{ -- /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -- int status = readl(mbox->regs + MAIL0_STA); -- int ret = IRQ_NONE; -- -- while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->regs + MAIL0_RD); -- int chan = MBOX_CHAN(msg); -- -- if (chan < MBOX_CHAN_COUNT) { -- if (mbox->msg[chan]) { -- pr_err(DRIVER_NAME -- ": mbox chan %d overflow - drop %08x\n", -- chan, msg); -- } else { -- mbox->msg[chan] = (msg | 0xf); -- up(&mbox->sema[chan]); -- } -- } else { -- pr_err(DRIVER_NAME -- ": invalid channel selector (msg %08x)\n", msg); -- } -- ret = IRQ_HANDLED; -- status = readl(mbox->regs + MAIL0_STA); -- } -- return ret; --} -- --/* Mailbox Methods */ -- --static struct device *mbox_dev; /* we assume there's only one! */ -- --static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_write(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_read(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --extern int bcm_mailbox_write(unsigned chan, uint32_t data28) --{ -- if (!mbox_dev) -- return -ENODEV; -- -- return dev_mbox_write(mbox_dev, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_write); -- --extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) --{ -- if (!mbox_dev) -- return -ENODEV; -- -- return dev_mbox_read(mbox_dev, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -- --static int mbox_copy_from_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)src < TASK_SIZE) -- return copy_from_user(dst, src, size); -- -- memcpy(dst, src, size); -- -- return 0; --} -- --static int mbox_copy_to_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)dst < TASK_SIZE) -- return copy_to_user(dst, src, size); -- -- memcpy(dst, src, size); -- -- return 0; --} -- --static DEFINE_MUTEX(mailbox_lock); --extern int bcm_mailbox_property(void *data, int size) --{ -- uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -- int s = 0; -- -- mutex_lock(&mailbox_lock); -- /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -- GFP_ATOMIC); -- if (mem_kern) { -- /* create the message */ -- mbox_copy_from_user(mem_kern, data, size); -- -- /* send the message */ -- wmb(); -- s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) -- s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- if (s == 0) { -- /* copy the response */ -- rmb(); -- mbox_copy_to_user(data, mem_kern, size); -- } -- dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -- } else { -- s = -ENOMEM; -- } -- if (s != 0) -- pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -- -- mutex_unlock(&mailbox_lock); -- return s; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_property); -- --/* Platform Device for Mailbox */ -- --/* -- * Is the device open right now? Used to prevent -- * concurent access into the same device -- */ --static bool device_is_open; -- --/* This is called whenever a process attempts to open the device file */ --static int device_open(struct inode *inode, struct file *file) --{ -- /* We don't want to talk to two processes at the same time */ -- if (device_is_open) -- return -EBUSY; -- -- device_is_open = true; -- try_module_get(THIS_MODULE); -- -- return 0; --} -- --static int device_release(struct inode *inode, struct file *file) --{ -- /* We're now ready for our next caller */ -- device_is_open = false; -- -- module_put(THIS_MODULE); -- -- return 0; --} -- --/* -- * This function is called whenever a process tries to do an ioctl on our -- * device file. We get two extra parameters (additional to the inode and file -- * structures, which all device functions get): the number of the ioctl called -- * and the parameter given to the ioctl function. -- * -- * If the ioctl is write or read/write (meaning output is returned to the -- * calling process), the ioctl call returns the output of this function. -- * -- */ --static long device_ioctl(struct file *file, unsigned int ioctl_num, -- unsigned long ioctl_param) --{ -- unsigned size; -- -- switch (ioctl_num) { -- case IOCTL_MBOX_PROPERTY: -- /* -- * Receive a pointer to a message (in user space) and set that -- * to be the device's message. Get the parameter given to -- * ioctl by the process. -- */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -- return bcm_mailbox_property((void *)ioctl_param, size); -- default: -- pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -- return -EINVAL; -- } -- -- return 0; --} -- --/* Module Declarations */ -- --/* -- * This structure will hold the functions to be called -- * when a process does something to the device we -- * created. Since a pointer to this structure is kept in -- * the devices table, it can't be local to -- * init_module. NULL is for unimplemented functios. -- */ --const struct file_operations fops = { -- .unlocked_ioctl = device_ioctl, -- .open = device_open, -- .release = device_release, /* a.k.a. close */ --}; -- --static int bcm_vcio_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct device *vdev; -- struct vc_mailbox *mailbox; -- struct resource *res; -- int irq, ret; -- -- mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -- if (!mailbox) -- return -ENOMEM; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- mailbox->regs = devm_ioremap_resource(dev, res); -- if (IS_ERR(mailbox->regs)) -- return PTR_ERR(mailbox->regs); -- -- irq = platform_get_irq(pdev, 0); -- ret = devm_request_irq(dev, irq, mbox_irq_handler, -- IRQF_DISABLED | IRQF_IRQPOLL, -- dev_name(dev), mailbox); -- if (ret) { -- dev_err(dev, "Interrupt request failed %d\n", ret); -- return ret; -- } -- -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- if (ret < 0) { -- pr_err("Character device registration failed %d\n", ret); -- return ret; -- } -- -- vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- pr_err("Class creation failed %d\n", ret); -- goto err_class; -- } -- -- vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -- if (IS_ERR(vdev)) { -- ret = PTR_ERR(vdev); -- pr_err("Device creation failed %d\n", ret); -- goto err_dev; -- } -- -- mbox_init(mailbox); -- platform_set_drvdata(pdev, mailbox); -- mbox_dev = dev; -- -- dev_info(dev, "mailbox at %p\n", mailbox->regs); -- -- return 0; -- --err_dev: -- class_destroy(vcio_class); --err_class: -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return ret; --} -- --static int bcm_vcio_remove(struct platform_device *pdev) --{ -- mbox_dev = NULL; -- platform_set_drvdata(pdev, NULL); -- device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return 0; --} -- --static const struct of_device_id bcm_vcio_of_match_table[] = { -- { .compatible = "brcm,bcm2708-vcio", }, -- {}, --}; --MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -- --static struct platform_driver bcm_mbox_driver = { -- .probe = bcm_vcio_probe, -- .remove = bcm_vcio_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- .of_match_table = bcm_vcio_of_match_table, -- }, --}; -- --static int __init bcm_mbox_init(void) --{ -- return platform_driver_register(&bcm_mbox_driver); --} -- --static void __exit bcm_mbox_exit(void) --{ -- platform_driver_unregister(&bcm_mbox_driver); --} -- --arch_initcall(bcm_mbox_init); /* Initialize early */ --module_exit(bcm_mbox_exit); -- --MODULE_AUTHOR("Gray Girling"); --MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); --MODULE_LICENSE("GPL"); -diff --git a/arch/arm/mach-bcm2709/include/mach/vcio.h b/arch/arm/mach-bcm2709/include/mach/vcio.h -deleted file mode 100644 -index 8e11d67e..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/vcio.h -+++ /dev/null -@@ -1,165 +0,0 @@ --/* -- * arch/arm/mach-bcm2708/include/mach/vcio.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 _MACH_BCM2708_VCIO_H --#define _MACH_BCM2708_VCIO_H -- --/* Routines to handle I/O via the VideoCore "ARM control" registers -- * (semaphores, doorbells, mailboxes) -- */ -- --#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -- --/* Constants shared with the ARM identifying separate mailbox channels */ --#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ --#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ --#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ --#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ --#define MBOX_CHAN_COUNT 9 -- --enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 --}; --enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 --}; --/* Mailbox property tags */ --enum { -- VCMSG_PROPERTY_END = 0x00000000, -- VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -- VCMSG_GET_BOARD_MODEL = 0x00010001, -- VCMSG_GET_BOARD_REVISION = 0x00010002, -- VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -- VCMSG_GET_BOARD_SERIAL = 0x00010004, -- VCMSG_GET_ARM_MEMORY = 0x00010005, -- VCMSG_GET_VC_MEMORY = 0x00010006, -- VCMSG_GET_CLOCKS = 0x00010007, -- VCMSG_GET_COMMAND_LINE = 0x00050001, -- VCMSG_GET_DMA_CHANNELS = 0x00060001, -- VCMSG_GET_POWER_STATE = 0x00020001, -- VCMSG_GET_TIMING = 0x00020002, -- VCMSG_SET_POWER_STATE = 0x00028001, -- VCMSG_GET_CLOCK_STATE = 0x00030001, -- VCMSG_SET_CLOCK_STATE = 0x00038001, -- VCMSG_GET_CLOCK_RATE = 0x00030002, -- VCMSG_SET_CLOCK_RATE = 0x00038002, -- VCMSG_GET_VOLTAGE = 0x00030003, -- VCMSG_SET_VOLTAGE = 0x00038003, -- VCMSG_GET_MAX_CLOCK = 0x00030004, -- VCMSG_GET_MAX_VOLTAGE = 0x00030005, -- VCMSG_GET_TEMPERATURE = 0x00030006, -- VCMSG_GET_MIN_CLOCK = 0x00030007, -- VCMSG_GET_MIN_VOLTAGE = 0x00030008, -- VCMSG_GET_TURBO = 0x00030009, -- VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -- VCMSG_GET_STC = 0x0003000b, -- VCMSG_SET_TURBO = 0x00038009, -- VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -- VCMSG_SET_LOCK_MEM = 0x0003000d, -- VCMSG_SET_UNLOCK_MEM = 0x0003000e, -- VCMSG_SET_RELEASE_MEM = 0x0003000f, -- VCMSG_SET_EXECUTE_CODE = 0x00030010, -- VCMSG_SET_EXECUTE_QPU = 0x00030011, -- VCMSG_SET_ENABLE_QPU = 0x00030012, -- VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -- VCMSG_GET_EDID_BLOCK = 0x00030020, -- VCMSG_GET_CUSTOMER_OTP = 0x00030021, -- VCMSG_SET_CUSTOMER_OTP = 0x00038021, -- VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -- VCMSG_SET_RELEASE_BUFFER = 0x00048001, -- VCMSG_SET_BLANK_SCREEN = 0x00040002, -- VCMSG_TST_BLANK_SCREEN = 0x00044002, -- VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -- VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -- VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -- VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -- VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -- VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -- VCMSG_GET_DEPTH = 0x00040005, -- VCMSG_TST_DEPTH = 0x00044005, -- VCMSG_SET_DEPTH = 0x00048005, -- VCMSG_GET_PIXEL_ORDER = 0x00040006, -- VCMSG_TST_PIXEL_ORDER = 0x00044006, -- VCMSG_SET_PIXEL_ORDER = 0x00048006, -- VCMSG_GET_ALPHA_MODE = 0x00040007, -- VCMSG_TST_ALPHA_MODE = 0x00044007, -- VCMSG_SET_ALPHA_MODE = 0x00048007, -- VCMSG_GET_PITCH = 0x00040008, -- VCMSG_TST_PITCH = 0x00044008, -- VCMSG_SET_PITCH = 0x00048008, -- VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -- VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -- VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -- VCMSG_GET_OVERSCAN = 0x0004000a, -- VCMSG_TST_OVERSCAN = 0x0004400a, -- VCMSG_SET_OVERSCAN = 0x0004800a, -- VCMSG_GET_PALETTE = 0x0004000b, -- VCMSG_TST_PALETTE = 0x0004400b, -- VCMSG_SET_PALETTE = 0x0004800b, -- VCMSG_GET_LAYER = 0x0004000c, -- VCMSG_TST_LAYER = 0x0004400c, -- VCMSG_SET_LAYER = 0x0004800c, -- VCMSG_GET_TRANSFORM = 0x0004000d, -- VCMSG_TST_TRANSFORM = 0x0004400d, -- VCMSG_SET_TRANSFORM = 0x0004800d, -- VCMSG_TST_VSYNC = 0x0004400e, -- VCMSG_SET_VSYNC = 0x0004800e, -- VCMSG_SET_CURSOR_INFO = 0x00008010, -- VCMSG_SET_CURSOR_STATE = 0x00008011, --}; -- --extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); --extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); --extern int /*rc*/ bcm_mailbox_property(void *data, int size); -- --#include -- --/* -- * The major device number. We can't rely on dynamic -- * registration any more, because ioctls need to know -- * it. -- */ --#define MAJOR_NUM 100 -- --/* -- * Set the message of the device driver -- */ --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) --/* -- * _IOWR means that we're creating an ioctl command -- * number for passing information from a user process -- * to the kernel module and from the kernel module to user process -- * -- * The first arguments, MAJOR_NUM, is the major device -- * number we're using. -- * -- * The second argument is the number of the command -- * (there could be several with different meanings). -- * -- * The third argument is the type we want to get from -- * the process to the kernel. -- */ -- --/* -- * The name of the device file -- */ --#define DEVICE_FILE_NAME "vcio" -- --#endif -diff --git a/arch/arm/mach-bcm2709/vcio.c b/arch/arm/mach-bcm2709/vcio.c -deleted file mode 100644 -index 700bff4..0000000 ---- a/arch/arm/mach-bcm2709/vcio.c -+++ /dev/null -@@ -1,484 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/vcio.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for writing to the mailboxes, -- * semaphores, doorbells etc. that are shared between the ARM and the -- * VideoCore processor -- */ -- --#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) --#define SUPPORT_SYSRQ --#endif -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include --#include -- --#include -- -- --#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -- --/* ---------------------------------------------------------------------- -- * Mailbox -- * -------------------------------------------------------------------- */ -- --/* offsets from a mail box base address */ --#define MAIL_WRT 0x00 /* write - and next 4 words */ --#define MAIL_RD 0x00 /* read - and next 4 words */ --#define MAIL_POL 0x10 /* read without popping the fifo */ --#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL_STA 0x18 /* status */ --#define MAIL_CNF 0x1C /* configuration */ -- --#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) --#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) --#define MBOX_CHAN(msg) ((msg) & 0xf) --#define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -- --#define MBOX_MAGIC 0xd0d0c0de --static struct class *vcio_class = NULL; --struct vc_mailbox { -- struct device *dev; /* parent device */ -- void __iomem *status; -- void __iomem *config; -- void __iomem *read; -- void __iomem *write; -- uint32_t msg[MBOX_CHAN_COUNT]; -- struct semaphore sema[MBOX_CHAN_COUNT]; -- uint32_t magic; --}; -- --static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -- uint32_t addr_mbox) --{ -- int i; -- -- mbox_out->dev = dev; -- mbox_out->status = __io_address(addr_mbox + MAIL_STA); -- mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -- mbox_out->read = __io_address(addr_mbox + MAIL_RD); -- /* Write to the other mailbox */ -- mbox_out->write = -- __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -- MAIL_WRT); -- -- for (i = 0; i < MBOX_CHAN_COUNT; i++) { -- mbox_out->msg[i] = 0; -- sema_init(&mbox_out->sema[i], 0); -- } -- -- /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -- -- mbox_out->magic = MBOX_MAGIC; --} -- --static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) --{ -- int rc; -- -- if (mbox->magic != MBOX_MAGIC) -- rc = -EINVAL; -- else { -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->status) & ARM_MS_FULL)) -- cpu_relax(); -- -- writel(MBOX_MSG(chan, data28), mbox->write); -- rc = 0; -- } -- return rc; --} -- --static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) --{ -- int rc; -- -- if (mbox->magic != MBOX_MAGIC) -- rc = -EINVAL; -- else { -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- rc = 0; -- } -- return rc; --} -- --static irqreturn_t mbox_irq(int irq, void *dev_id) --{ -- /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -- int status = readl(mbox->status); -- int ret = IRQ_NONE; -- -- while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->read); -- int chan = MBOX_CHAN(msg); -- if (chan < MBOX_CHAN_COUNT) { -- if (mbox->msg[chan]) { -- /* Overflow */ -- printk(KERN_ERR DRIVER_NAME -- ": mbox chan %d overflow - drop %08x\n", -- chan, msg); -- } else { -- mbox->msg[chan] = (msg | 0xf); -- up(&mbox->sema[chan]); -- } -- } else { -- printk(KERN_ERR DRIVER_NAME -- ": invalid channel selector (msg %08x)\n", msg); -- } -- ret = IRQ_HANDLED; -- status = readl(mbox->status); -- } -- return ret; --} -- --static struct irqaction mbox_irqaction = { -- .name = "ARM Mailbox IRQ", -- .flags = IRQF_DISABLED | IRQF_IRQPOLL, -- .handler = mbox_irq, --}; -- --/* ---------------------------------------------------------------------- -- * Mailbox Methods -- * -------------------------------------------------------------------- */ -- --static struct device *mbox_dev; /* we assume there's only one! */ -- --static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) --{ -- int rc; -- -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- device_lock(dev); -- rc = mbox_write(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) --{ -- int rc; -- -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- device_lock(dev); -- rc = mbox_read(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --extern int bcm_mailbox_write(unsigned chan, uint32_t data28) --{ -- if (mbox_dev) -- return dev_mbox_write(mbox_dev, chan, data28); -- else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_write); -- --extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) --{ -- if (mbox_dev) -- return dev_mbox_read(mbox_dev, chan, data28); -- else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -- --static void dev_mbox_register(const char *dev_name, struct device *dev) --{ -- mbox_dev = dev; --} -- --static int mbox_copy_from_user(void *dst, const void *src, int size) --{ -- if ( (uint32_t)src < TASK_SIZE) -- { -- return copy_from_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } --} -- --static int mbox_copy_to_user(void *dst, const void *src, int size) --{ -- if ( (uint32_t)dst < TASK_SIZE) -- { -- return copy_to_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } --} -- --static DEFINE_MUTEX(mailbox_lock); --extern int bcm_mailbox_property(void *data, int size) --{ -- uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -- int s = 0; -- -- mutex_lock(&mailbox_lock); -- /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -- if (mem_kern) { -- /* create the message */ -- mbox_copy_from_user(mem_kern, data, size); -- -- /* send the message */ -- wmb(); -- s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) { -- s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- } -- if (s == 0) { -- /* copy the response */ -- rmb(); -- mbox_copy_to_user(data, mem_kern, size); -- } -- dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -- } else { -- s = -ENOMEM; -- } -- if (s != 0) -- printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -- -- mutex_unlock(&mailbox_lock); -- return s; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_property); -- --/* ---------------------------------------------------------------------- -- * Platform Device for Mailbox -- * -------------------------------------------------------------------- */ -- --/* -- * Is the device open right now? Used to prevent -- * concurent access into the same device -- */ --static int Device_Open = 0; -- --/* -- * This is called whenever a process attempts to open the device file -- */ --static int device_open(struct inode *inode, struct file *file) --{ -- /* -- * We don't want to talk to two processes at the same time -- */ -- if (Device_Open) -- return -EBUSY; -- -- Device_Open++; -- /* -- * Initialize the message -- */ -- try_module_get(THIS_MODULE); -- return 0; --} -- --static int device_release(struct inode *inode, struct file *file) --{ -- /* -- * We're now ready for our next caller -- */ -- Device_Open--; -- -- module_put(THIS_MODULE); -- return 0; --} -- --/* -- * This function is called whenever a process tries to do an ioctl on our -- * device file. We get two extra parameters (additional to the inode and file -- * structures, which all device functions get): the number of the ioctl called -- * and the parameter given to the ioctl function. -- * -- * If the ioctl is write or read/write (meaning output is returned to the -- * calling process), the ioctl call returns the output of this function. -- * -- */ --static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -- unsigned int ioctl_num, /* number and param for ioctl */ -- unsigned long ioctl_param) --{ -- unsigned size; -- /* -- * Switch according to the ioctl called -- */ -- switch (ioctl_num) { -- case IOCTL_MBOX_PROPERTY: -- /* -- * Receive a pointer to a message (in user space) and set that -- * to be the device's message. Get the parameter given to -- * ioctl by the process. -- */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -- return bcm_mailbox_property((void *)ioctl_param, size); -- break; -- default: -- printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -- return -EINVAL; -- } -- -- return 0; --} -- --/* Module Declarations */ -- --/* -- * This structure will hold the functions to be called -- * when a process does something to the device we -- * created. Since a pointer to this structure is kept in -- * the devices table, it can't be local to -- * init_module. NULL is for unimplemented functios. -- */ --struct file_operations fops = { -- .unlocked_ioctl = device_ioctl, -- .open = device_open, -- .release = device_release, /* a.k.a. close */ --}; -- --static int bcm_vcio_probe(struct platform_device *pdev) --{ -- int ret = 0; -- struct vc_mailbox *mailbox; -- -- mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -- if (NULL == mailbox) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "mailbox memory\n"); -- ret = -ENOMEM; -- } else { -- struct resource *res; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -- ret = -ENODEV; -- kfree(mailbox); -- } else { -- /* should be based on the registers from res really */ -- mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -- -- platform_set_drvdata(pdev, mailbox); -- dev_mbox_register(DRIVER_NAME, &pdev->dev); -- -- mbox_irqaction.dev_id = mailbox; -- setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -- printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -- __io_address(ARM_0_MAIL0_RD)); -- } -- } -- -- if (ret == 0) { -- /* -- * Register the character device -- */ -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- -- /* -- * Negative values signify an error -- */ -- if (ret < 0) { -- printk(KERN_ERR DRIVER_NAME -- "Failed registering the character device %d\n", ret); -- return ret; -- } -- vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- return ret ; -- } -- device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -- } -- return ret; --} -- --static int bcm_vcio_remove(struct platform_device *pdev) --{ -- struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -- -- platform_set_drvdata(pdev, NULL); -- kfree(mailbox); -- -- return 0; --} -- --static struct platform_driver bcm_mbox_driver = { -- .probe = bcm_vcio_probe, -- .remove = bcm_vcio_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; -- --static int __init bcm_mbox_init(void) --{ -- int ret; -- -- printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -- -- ret = platform_driver_register(&bcm_mbox_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -- -- return ret; --} -- --static void __exit bcm_mbox_exit(void) --{ -- device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- platform_driver_unregister(&bcm_mbox_driver); --} -- --arch_initcall(bcm_mbox_init); /* Initialize early */ --module_exit(bcm_mbox_exit); -- --MODULE_AUTHOR("Gray Girling"); --MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); --MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm-mbox"); - -From ca452e4734877d6b36d1a836d473b81f3d561c3f Mon Sep 17 00:00:00 2001 + CONFIG_EXT2_FS_POSIX_ACL=y +@@ -107,18 +1073,110 @@ CONFIG_EXT3_FS=y + CONFIG_EXT3_FS_POSIX_ACL=y + 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_QFMT_V1=m ++CONFIG_QFMT_V2=m ++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_NTFS_RW=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y +-# CONFIG_MISC_FILESYSTEMS is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_ECRYPT_FS=m ++CONFIG_HFS_FS=m ++CONFIG_HFSPLUS_FS=m ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_F2FS_FS=y + CONFIG_NFS_FS=y +-CONFIG_NFSD=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=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=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=y ++CONFIG_DLM=m + CONFIG_PRINTK_TIME=y + CONFIG_BOOT_PRINTK_DELAY=y + CONFIG_DYNAMIC_DEBUG=y +@@ -128,14 +1186,38 @@ CONFIG_DEBUG_INFO=y + CONFIG_UNUSED_SYMBOLS=y + CONFIG_DEBUG_MEMORY_INIT=y + CONFIG_LOCKUP_DETECTOR=y ++CONFIG_TIMER_STATS=y ++# CONFIG_DEBUG_PREEMPT is not set ++CONFIG_LATENCYTOP=y ++CONFIG_IRQSOFF_TRACER=y + CONFIG_SCHED_TRACER=y + CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++# CONFIG_KPROBE_EVENT is not set + CONFIG_FUNCTION_PROFILER=y + CONFIG_TEST_KSTRTOX=y + CONFIG_KGDB=y + CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y + CONFIG_STRICT_DEVMEM=y + CONFIG_DEBUG_LL=y + CONFIG_EARLY_PRINTK=y ++CONFIG_CRYPTO_USER=m ++CONFIG_CRYPTO_CRYPTD=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_XTS=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_AES_ARM=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y + # CONFIG_XZ_DEC_ARM is not set + # CONFIG_XZ_DEC_ARMTHUMB is not set + +From 4e2ed4a7a7971ea763017bc6234d30cdc5bfb984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 1 May 2015 23:00:15 +0200 -Subject: [PATCH 147/216] BCM270x_DT: Add mailbox bcm2708-vcio +Subject: [PATCH 69/77] BCM270x_DT: Add mailbox bcm2708-vcio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -140552,193 +132264,41 @@ platform device when booting in DT mode. Signed-off-by: Noralf Trønnes --- - arch/arm/boot/dts/bcm2708_common.dtsi | 6 ++++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 3 files changed, 8 insertions(+), 2 deletions(-) + arch/arm/mach-bcm2708/bcm2708.c | 2 +- + arch/arm/mach-bcm2709/bcm2709.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 065a424..1c8c1af 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -36,6 +36,12 @@ - #interrupt-cells = <2>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - gpio: gpio { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 51f8efa..7cc47c1 100644 +index e42f5a5..de2f93a 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -908,7 +908,7 @@ void __init bcm2708_init(void) +@@ -870,7 +870,7 @@ void __init bcm2708_init(void) bcm2708_dt_init(); bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); - #endif diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 8ed88b4..2c0a664 100644 +index 95223ff..350647a 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -929,7 +929,7 @@ void __init bcm2709_init(void) +@@ -890,7 +890,7 @@ void __init bcm2709_init(void) bcm2709_dt_init(); bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); - #endif -From 8cb40db6e93540a4cf0d45ee23eb9b0441050543 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 23:00:45 +0200 -Subject: [PATCH 148/216] bcm2835: bcm2835_defconfig enable BCM2708_MBOX -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enable the mailbox driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index cf2e7a6..26b4c75 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -99,6 +99,8 @@ CONFIG_LEDS_TRIGGER_CAMERA=y - CONFIG_DMADEVICES=y - CONFIG_DMA_BCM2708=y - CONFIG_STAGING=y -+CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - -From c03f517d41d6da89f70794d6bf20974e81ac72f1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 23:02:46 +0200 -Subject: [PATCH 149/216] bcm2835: Add mailbox bcm2708-vcio to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add mailbox to Device Tree. There are no kernel users yet, -but it's available to userspace. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index f2dec21..06cba29 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -60,6 +60,12 @@ - reg = <0x7e104000 0x10>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - gpio: gpio@7e200000 { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; - -From 2010049aa53c210156598c979fd38dc893baa049 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 12 May 2015 11:48:18 +0200 -Subject: [PATCH 150/216] mailbox: bcm2708-vcio: Allocation does not need to be - atomic -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to do atomic allocation in a context that can sleep. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/bcm2708-vcio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index ee3e778..74a7fcb 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -212,7 +212,7 @@ extern int bcm_mailbox_property(void *data, int size) - mutex_lock(&mailbox_lock); - /* allocate some memory for the messages communicating with GPU */ - mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -- GFP_ATOMIC); -+ GFP_KERNEL); - if (mem_kern) { - /* create the message */ - mbox_copy_from_user(mem_kern, data, size); - -From f86559819816a393e05426b6dac30d84582fa13d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 12 May 2015 13:45:32 +0200 -Subject: [PATCH 151/216] mailbox: bcm2708-vcio: Check the correct status - register before writing -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With the VC reader blocked and the ARM writing, MAIL0_STA reads -empty permanently while MAIL1_STA goes from empty (0x40000000) -to non-empty (0x00000001-0x00000007) to full (0x80000008). - -Suggested-by: Phil Elwell -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/bcm2708-vcio.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index 74a7fcb..19ecfe8 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -35,6 +35,7 @@ - #define MAIL0_STA 0x18 /* status */ - #define MAIL0_CNF 0x1C /* configuration */ - #define MAIL1_WRT 0x20 /* write - and next 4 words */ -+#define MAIL1_STA 0x38 /* status */ - - /* On MACH_BCM270x these come through (arm_control.h ) */ - #ifndef ARM_MS_EMPTY -@@ -85,7 +86,7 @@ static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - return -EINVAL; - - /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) -+ while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) - cpu_relax(); - - writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); - -From 94bbfc4066df94c006edec5a48fe4df6547a1b01 Mon Sep 17 00:00:00 2001 +From 2867da0a54803e6eb8e748b63a474877e16899b0 Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 152/216] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 70/77] rpi-ft5406: Add touchscreen driver for pi LCD display --- drivers/input/touchscreen/Kconfig | 7 + @@ -140749,10 +132309,10 @@ Subject: [PATCH 152/216] rpi-ft5406: Add touchscreen driver for pi LCD display create mode 100644 drivers/input/touchscreen/rpi-ft5406.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 6261fd6..e7e9416 100644 +index 80f6386..5848562 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -557,6 +557,13 @@ config TOUCHSCREEN_EDT_FT5X06 +@@ -583,6 +583,13 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. @@ -140767,10 +132327,10 @@ index 6261fd6..e7e9416 100644 tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index 0242fea..e0268f0 100644 +index 44deea7..a1be09f 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile -@@ -28,6 +28,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o +@@ -29,6 +29,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o @@ -141055,1985 +132615,10 @@ index cc284ed..d3ea839 100644 VCMSG_SET_CURSOR_STATE = 0x00008011, }; -From 7a6f093876247b186c1465ef0f45132b0c804af2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 7 May 2015 09:22:23 +0100 -Subject: [PATCH 153/216] bcm2835-sdhost: Error handling fix, and code - clarification - ---- - drivers/mmc/host/bcm2835-sdhost.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 0c311b5..542ae12 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -1041,13 +1041,14 @@ static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - host->cmd->error = -EILSEQ; - - /* Use the block interrupt for writes after the first block */ -- if (!(host->data->flags & MMC_DATA_READ)) { -+ if (host->data->flags & MMC_DATA_WRITE) { - host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); - host->hcfg |= SDHCFG_BLOCK_IRPT_EN; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - if (host->data->error) - bcm2835_sdhost_finish_data(host); -- bcm2835_sdhost_transfer_pio(host); -+ else -+ bcm2835_sdhost_transfer_pio(host); - } else { - if (!host->data->error) { - bcm2835_sdhost_transfer_pio(host); -@@ -1132,12 +1133,12 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - bcm2835_sdhost_dumpregs(host); - } - -- if (loops) -- early |= handled; -- - if (!handled) - break; - -+ if (loops) -+ early |= handled; -+ - result = IRQ_HANDLED; - - /* Clear all interrupts and notifications */ - -From d502512774e7121bd6787008f5956daefa3ac138 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 14 May 2015 11:48:40 +0100 -Subject: [PATCH 154/216] bcm2835-sdhost: Adding overclocking option - -Allow a different clock speed to be substitued for a requested 50MHz. -This option is exposed using the "overclock_50" DT parameter. -Note that the sdhost interface is restricted to integer divisions of -core_freq, and the highest sensible option for a core_freq of 250MHz -is 84 (250/3 = 83.3MHz), the next being 125 (250/2) which is much too -high. - -Use at your own risk. ---- - arch/arm/boot/dts/sdhost-overlay.dts | 6 ++++-- - drivers/mmc/host/bcm2835-sdhost.c | 17 +++++++++++++++-- - 2 files changed, 19 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/sdhost-overlay.dts b/arch/arm/boot/dts/sdhost-overlay.dts -index 33db96e..b2653e9 100644 ---- a/arch/arm/boot/dts/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/sdhost-overlay.dts -@@ -13,14 +13,15 @@ - sdhost: sdhost@7e202000 { - compatible = "brcm,bcm2835-sdhost"; - reg = <0x7e202000 0x100>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; - interrupts = <2 24>; - clocks = <&clk_sdhost>; - dmas = <&dma 13>, - <&dma 13>; - dma-names = "tx", "rx"; - brcm,delay-after-stop = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_pins>; -+ brcm,overclock-50 = <0>; - status = "okay"; - }; - -@@ -67,6 +68,7 @@ - - __overrides__ { - delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; - force_pio = <&sdhost>,"brcm,force-pio?"; - sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - }; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 542ae12..2a9eb9f 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -184,6 +184,7 @@ struct bcm2835_host { - int max_delay; /* maximum length of time spent waiting */ - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ -+ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - }; - - -@@ -1223,6 +1224,10 @@ static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) - void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - { - int div = 0; /* Initialized for compiler warning */ -+ unsigned int input_clock = clock; -+ -+ if (host->overclock_50 && (clock == 50000000)) -+ clock = host->overclock_50 * 1000000; - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1266,13 +1271,18 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; - -- host->mmc->actual_clock = host->max_clk / (div + 2); -+ clock = host->max_clk / (div + 2); -+ host->mmc->actual_clock = clock; -+ -+ if (clock > input_clock) -+ pr_warn("%s: Overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); - - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - - pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -- clock, host->max_clk, host->cdiv, host->mmc->actual_clock); -+ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1572,6 +1582,9 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - of_property_read_u32(node, - "brcm,delay-after-stop", - &host->delay_after_stop); -+ of_property_read_u32(node, -+ "brcm,overclock-50", -+ &host->overclock_50); - host->allow_dma = ALLOW_DMA && - !of_property_read_bool(node, "brcm,force-pio"); - } - -From ae7169ee054f60e3db61f1a5bb6eb1f52913886a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 14 May 2015 11:55:57 +0100 -Subject: [PATCH 155/216] bcm2835-mmc: Adding overclocking option - -Allow a different clock speed to be substitued for a requested 50MHz. -This option is exposed using the "overclock_50" DT parameter. -Note that the mmc interface is restricted to EVEN integer divisions of -250MHz, and the highest sensible option is 63 (250/4 = 62.5), the -next being 125 (250/2) which is much too high. - -Use at your own risk. ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/mmc-overlay.dts | 19 +++++++++++++++++++ - drivers/mmc/host/bcm2835-mmc.c | 25 ++++++++++++++++++++++--- - 3 files changed, 42 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/mmc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 9cb5a2d..a21afc5 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -27,6 +27,7 @@ dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb -diff --git a/arch/arm/boot/dts/mmc-overlay.dts b/arch/arm/boot/dts/mmc-overlay.dts -new file mode 100644 -index 0000000..0a37cf4 ---- /dev/null -+++ b/arch/arm/boot/dts/mmc-overlay.dts -@@ -0,0 +1,19 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&mmc>; -+ -+ __overlay__ { -+ brcm,overclock-50 = <0>; -+ }; -+ }; -+ -+ __overrides__ { -+ overclock_50 = <&mmc>,"brcm,overclock-50:0"; -+ force_pio = <&mmc>,"brcm,force-pio?"; -+ }; -+}; -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 68314d5..c7c2ca1 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -131,6 +131,8 @@ struct bcm2835_host { - #define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ - #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ - #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ -+ -+ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - }; - - -@@ -1086,7 +1088,10 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - int real_div = div, clk_mul = 1; - u16 clk = 0; - unsigned long timeout; -+ unsigned int input_clock = clock; - -+ if (host->overclock_50 && (clock == 50000000)) -+ clock = host->overclock_50 * 1000000; - - host->mmc->actual_clock = 0; - -@@ -1110,7 +1115,12 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - div >>= 1; - - if (real_div) -- host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; -+ clock = (host->max_clk * clk_mul) / real_div; -+ host->mmc->actual_clock = clock; -+ -+ if (clock > input_clock) -+ pr_warn("%s: Overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); - - clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; - clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) -@@ -1177,6 +1187,9 @@ static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - u8 ctrl; - u16 clk, ctrl_2; - -+ pr_debug("bcm2835_mmc_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); - - spin_lock_irqsave(&host->lock, flags); - -@@ -1444,10 +1457,16 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) - goto err; - } - -- if (node) -+ if (node) { - mmc_of_parse(mmc); -- else -+ -+ /* Read any custom properties */ -+ of_property_read_u32(node, -+ "brcm,overclock-50", -+ &host->overclock_50); -+ } else { - mmc->caps |= MMC_CAP_4_BIT_DATA; -+ } - - ret = bcm2835_mmc_add_host(host); - if (ret) - -From 4b4b9568bc6fbfc222d59a28b2727ae5c725a92a Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Fri, 15 May 2015 14:21:32 +0200 -Subject: [PATCH 156/216] dmaengine: bcm2708: set residue_granularity field - -bcm2708-dmaengine supports residue reporting at burst level -but didn't report this via the residue_granularity field. - -Without this field set properly we get playback issues with I2S cards. ---- - drivers/dma/bcm2708-dmaengine.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 937fd60..987ed53 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -1112,6 +1112,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -+ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; - od->ddev.dev = &pdev->dev; - INIT_LIST_HEAD(&od->ddev.channels); - spin_lock_init(&od->lock); -@@ -1180,6 +1181,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -+ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; - od->ddev.dev = &pdev->dev; - INIT_LIST_HEAD(&od->ddev.channels); - spin_lock_init(&od->lock); - -From 1ddcc631437e913995361718209077d8247c10b0 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 12 May 2015 17:26:35 +0100 -Subject: [PATCH 157/216] BCM2708_DT: Adding starter Compute Module DTS files - ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 7 +++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 30 ++++++++++++++++++++++++++++++ - 3 files changed, 38 insertions(+) - create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts - create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index a21afc5..f3558df 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -3,6 +3,7 @@ ifeq ($(CONFIG_OF),y) - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb - dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb -+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb - - # Raspberry Pi - ifeq ($(CONFIG_BCM2708_DT),y) -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -new file mode 100755 -index 0000000..45f8244 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -0,0 +1,7 @@ -+/dts-v1/; -+ -+/include/ "bcm2708-rpi-cm.dtsi" -+ -+/ { -+ model = "Raspberry Pi Compute Module"; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -new file mode 100755 -index 0000000..d0a6fb8 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -0,0 +1,30 @@ -+/include/ "bcm2708.dtsi" -+ -+/ { -+ aliases { -+ soc = &soc; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ sound = &sound; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 47 0>; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ }; -+}; - -From 210157c8363fc0ac4c99273d3ed8f54ed9929b0f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 May 2015 11:57:29 +0100 -Subject: [PATCH 158/216] bcm2835-sdhost: Round up the overclock, so 62 works - for 62.5Mhz - -Also only warn once for each overclock setting. ---- - drivers/mmc/host/bcm2835-sdhost.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 2a9eb9f..eef8a24 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -185,6 +185,7 @@ struct bcm2835_host { - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -+ u32 max_overclock; /* Highest reported */ - }; - - -@@ -1227,7 +1228,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - unsigned int input_clock = clock; - - if (host->overclock_50 && (clock == 50000000)) -- clock = host->overclock_50 * 1000000; -+ clock = host->overclock_50 * 1000000 + 999999; - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1274,9 +1275,11 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - -- if (clock > input_clock) -+ if ((clock > input_clock) && (clock > host->max_overclock)) { - pr_warn("%s: Overclocking to %dHz\n", - mmc_hostname(host->mmc), clock); -+ host->max_overclock = clock; -+ } - - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -From a946e70fd45a1f24f99816f72f5bbb0a7de0c1f3 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 May 2015 12:29:42 +0100 -Subject: [PATCH 159/216] bcm2835-mmc: Round up the overclock, so 62 works for - 62.5Mhz - -Also only warn once for each overclock setting. ---- - drivers/mmc/host/bcm2835-mmc.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index c7c2ca1..b7c4883 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -133,6 +133,7 @@ struct bcm2835_host { - #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ - - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -+ u32 max_overclock; /* Highest reported */ - }; - - -@@ -1091,7 +1092,7 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - unsigned int input_clock = clock; - - if (host->overclock_50 && (clock == 50000000)) -- clock = host->overclock_50 * 1000000; -+ clock = host->overclock_50 * 1000000 + 999999; - - host->mmc->actual_clock = 0; - -@@ -1118,9 +1119,11 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = (host->max_clk * clk_mul) / real_div; - host->mmc->actual_clock = clock; - -- if (clock > input_clock) -+ if ((clock > input_clock) && (clock > host->max_overclock)) { - pr_warn("%s: Overclocking to %dHz\n", - mmc_hostname(host->mmc), clock); -+ host->max_overclock = clock; -+ } - - clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; - clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) - -From f80dd3188715edaa5c23e3d99793170aa7dbd877 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 May 2015 13:05:27 +0100 -Subject: [PATCH 160/216] BCM2708_DT: Add missing CM aliases - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index d0a6fb8..8340c1e 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -3,6 +3,10 @@ - / { - aliases { - soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; - gpio = &gpio; - intc = &intc; - leds = &leds; - -From 90c3a2ff9838fdf619c6f391c27ce2fe02f083cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 15 May 2015 20:20:09 +0200 -Subject: [PATCH 161/216] usb: dwc_otg: Don't use dma_to_virt() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 6ce0d20 changes dma_to_virt() which breaks this driver. -Open code the old dma_to_virt() implementation to work around this. - -Limit the use of __bus_to_virt() to cases where transfer_buffer_length -is set and transfer_buffer is not set. This is done to increase the -chance that this driver will also work on ARCH_BCM2835. - -transfer_buffer should not be NULL if the length is set, but the -comment in the code indicates that there are situations where this -might happen. drivers/usb/isp1760/isp1760-hcd.c also has a similar -comment pointing to a possible: 'usb storage / SCSI bug'. - -Signed-off-by: Noralf Trønnes ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -index 1d28459..6aad9c4 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -766,16 +766,17 @@ static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, - !(usb_pipein(urb->pipe)))); - - buf = urb->transfer_buffer; -- if (hcd->self.uses_dma) { -+ if (hcd->self.uses_dma && !buf && urb->transfer_buffer_length) { - /* - * Calculate virtual address from physical address, - * because some class driver may not fill transfer_buffer. - * In Buffer DMA mode virual address is used, - * when handling non DWORD aligned buffers. - */ -- //buf = phys_to_virt(urb->transfer_dma); -- // DMA addresses are bus addresses not physical addresses! -- buf = dma_to_virt(&urb->dev->dev, urb->transfer_dma); -+ buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma); -+ dev_warn_once(&urb->dev->dev, -+ "USB transfer_buffer was NULL, will use __bus_to_virt(%pad)=%p\n", -+ &urb->transfer_dma, buf); - } - - if (!(urb->transfer_flags & URB_NO_INTERRUPT)) - -From 785584eaa255550270eb4496bdc31f241561b26c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 15 May 2015 20:20:26 +0200 -Subject: [PATCH 162/216] fixup: restore dma-mapping.h -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dwc_otg has been fixed, so no need to revert 6ce0d20: -ARM: dma: Use dma_pfn_offset for dma address translation - -The pfn_to_dma/dma_to_pfn changes that came with that commit -is needed to use the 'dma-ranges' DT property on ARCH_BCM2835. -dma-ranges is needed by bcm2708_fb and vchiq on ARCH_BCM2835. -If not the mailbox call fails to hand over the correct -bus address to videocore. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/include/asm/dma-mapping.h | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h -index f5572d9..b52101d3 100644 ---- a/arch/arm/include/asm/dma-mapping.h -+++ b/arch/arm/include/asm/dma-mapping.h -@@ -58,21 +58,37 @@ static inline int dma_set_mask(struct device *dev, u64 mask) - #ifndef __arch_pfn_to_dma - static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) - { -+ if (dev) -+ pfn -= dev->dma_pfn_offset; - return (dma_addr_t)__pfn_to_bus(pfn); - } - - static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) - { -- return __bus_to_pfn(addr); -+ unsigned long pfn = __bus_to_pfn(addr); -+ -+ if (dev) -+ pfn += dev->dma_pfn_offset; -+ -+ return pfn; - } - - static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) - { -+ if (dev) { -+ unsigned long pfn = dma_to_pfn(dev, addr); -+ -+ return phys_to_virt(__pfn_to_phys(pfn)); -+ } -+ - return (void *)__bus_to_virt((unsigned long)addr); - } - - static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) - { -+ if (dev) -+ return pfn_to_dma(dev, virt_to_pfn(addr)); -+ - return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); - } - - -From 1b1de68277ff97f836021328e6ac6fbb24494c73 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:18:28 +0200 -Subject: [PATCH 163/216] fbdev: bcm2708_fb: Add ARCH_BCM2835 support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support. -Pass the device to dma_alloc_coherent() in order to get the -correct bus address on ARCH_BCM2835. -Use the new DMA legacy API header file. -Including is not necessary. - -Signed-off-by: Noralf Trønnes ---- - drivers/video/fbdev/bcm2708_fb.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 345c15e..f6ac7da 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -24,16 +24,13 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include - #include -- --#include --#include -- - #include - #include - #include -@@ -628,7 +625,7 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - void *mem; - - mem = -- dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, -+ dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, - GFP_KERNEL); - - if (NULL == mem) { -@@ -783,12 +780,19 @@ static int bcm2708_fb_remove(struct platform_device *dev) - return 0; - } - -+static const struct of_device_id bcm2708_fb_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-fb", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_fb_of_match_table); -+ - static struct platform_driver bcm2708_fb_driver = { - .probe = bcm2708_fb_probe, - .remove = bcm2708_fb_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_fb_of_match_table, - }, - }; - - -From e6d3d3d4102639777a7261d9eb6f195176fc50bb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:20:00 +0200 -Subject: [PATCH 164/216] BCM270x: Remove header file mach/dma.h -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This header file can be removed since there are no more users. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/dma.h | 2 -- - arch/arm/mach-bcm2709/include/mach/dma.h | 2 -- - 2 files changed, 4 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/dma.h - delete mode 100644 arch/arm/mach-bcm2709/include/mach/dma.h - -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -deleted file mode 100644 -index d826705..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ /dev/null -@@ -1,2 +0,0 @@ --/* This file can be removed when all the drivers have been updated */ --#include -diff --git a/arch/arm/mach-bcm2709/include/mach/dma.h b/arch/arm/mach-bcm2709/include/mach/dma.h -deleted file mode 100644 -index d826705..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/dma.h -+++ /dev/null -@@ -1,2 +0,0 @@ --/* This file can be removed when all the drivers have been updated */ --#include - -From 11e908510cac293a92b124f36476ae7fe4c581ec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:21:31 +0200 -Subject: [PATCH 165/216] BCM270x_DT: Add bcm2708-fb device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add bcm2708-fb to Device Tree and don't add the -platform device when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 5 +++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 6 files changed, 19 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index f25563a..9a8fed0 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -49,6 +49,10 @@ - bus-width = <4>; - }; - -+&fb { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 17b4b8c..cf67ec9 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -49,6 +49,10 @@ - bus-width = <4>; - }; - -+&fb { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 1c8c1af..c5ed34b 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -109,6 +109,11 @@ - leds: leds { - compatible = "gpio-leds"; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ status = "disabled"; -+ }; - }; - - clocks { -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index c73249b..1c865de 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -49,6 +49,10 @@ - bus-width = <4>; - }; - -+&fb { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 7cc47c1..cde2124 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -928,7 +928,7 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&w1_device); - #endif - bcm_register_device(&bcm2708_systemtimer_device); -- bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 2c0a664..95db41ff 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -951,7 +951,7 @@ void __init bcm2709_init(void) - #ifdef SYSTEM_TIMER - bcm_register_device(&bcm2708_systemtimer_device); - #endif -- bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - -From 0abe9b6fa045617f9fb0f8afe64b69072821d241 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 5 May 2015 13:10:11 -0700 -Subject: [PATCH 166/216] ARM: bcm2835: Use 0x4 prefix for DMA bus addresses to - SDRAM. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There exists a tiny MMU, configurable only by the VC (running the -closed firmware), which maps from the ARM's physical addresses to bus -addresses. These bus addresses determine the caching behavior in the -VC's L1/L2 (note: separate from the ARM's L1/L2) according to the top -2 bits. The bits in the bus address mean: - -From the VideoCore processor: -0x0... L1 and L2 cache allocating and coherent -0x4... L1 non-allocating, but coherent. L2 allocating and coherent -0x8... L1 non-allocating, but coherent. L2 non-allocating, but coherent -0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent - -From the GPU peripherals (note: all peripherals bypass the L1 -cache. The ARM will see this view once through the VC MMU): -0x0... Do not use -0x4... L1 non-allocating, and incoherent. L2 allocating and coherent. -0x8... L1 non-allocating, and incoherent. L2 non-allocating, but coherent -0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent - -The 2835 firmware always configures the MMU to turn ARM physical -addresses with 0x0 top bits to 0x4, meaning present in L2 but -incoherent with L1. However, any bus addresses we were generating in -the kernel to be passed to a device had 0x0 bits. That would be a -reserved (possibly totally incoherent) value if sent to a GPU -peripheral like USB, or L1 allocating if sent to the VC (like a -firmware property request). By setting dma-ranges, all of the devices -below it get a dev->dma_pfn_offset, so that dma_alloc_coherent() and -friends return addresses with 0x4 bits and avoid cache incoherency. - -This matches the behavior in the downstream 2708 kernel (see -BUS_OFFSET in arch/arm/mach-bcm2708/include/mach/memory.h). - -Signed-off-by: Eric Anholt -Tested-by: Noralf Trønnes -Acked-by: Stephen Warren -Cc: popcornmix@gmail.com ---- - arch/arm/boot/dts/bcm2835.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 06cba29..f91db90 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -14,6 +14,7 @@ - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x7e000000 0x20000000 0x02000000>; -+ dma-ranges = <0x40000000 0x00000000 0x20000000>; - - timer@7e003000 { - compatible = "brcm,bcm2835-system-timer"; - -From fabd2cdba17ab122a41957bced0c06e993b559a8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:24:13 +0200 -Subject: [PATCH 167/216] bcm2835: Add bcm2708-fb to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add framebuffer device to Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ++++ - arch/arm/boot/dts/bcm2835.dtsi | 5 +++++ - 2 files changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index 9f4ed2f..f2ce803 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -49,3 +49,7 @@ - status = "okay"; - bus-width = <4>; - }; -+ -+&fb { -+ status = "okay"; -+}; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index f91db90..f3ab9b3 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -159,6 +159,11 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ status = "disabled"; -+ }; - }; - - clocks { - -From 81530cfc1eb8c2069f7083fa2cc56b3b7470eb29 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:24:35 +0200 -Subject: [PATCH 168/216] bcm2835: bcm2835_defconfig use FB_BCM2708 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enable the bcm2708 framebuffer driver. -Disable the simple framebuffer driver, which matches the -device handed over by u-boot. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 26b4c75..1af6069 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -72,7 +72,7 @@ CONFIG_SPI_BCM2835=y - CONFIG_GPIO_SYSFS=y - # CONFIG_HWMON is not set - CONFIG_FB=y --CONFIG_FB_SIMPLE=y -+CONFIG_FB_BCM2708=y - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y - CONFIG_USB=y - -From 9e0da80c0836b21773e84b699f2e94e50680b485 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 May 2015 11:41:11 +0100 -Subject: [PATCH 169/216] BCM2708_DT: Enable mmc and fb in the CM dtsi - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 8340c1e..815a3a4 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -25,6 +25,15 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; - -From c95de8db34841f61ef2cb38afb8b84973bd9aa6c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 19 May 2015 13:31:50 +0200 -Subject: [PATCH 170/216] BCM270x: Add vchiq device to platform file and Device - Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Prepare to turn the vchiq module into a driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 6 ++++++ - arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ - arch/arm/mach-bcm2708/include/mach/platform.h | 1 + - arch/arm/mach-bcm2709/bcm2709.c | 26 ++++++++++++++++++++++++++ - arch/arm/mach-bcm2709/include/mach/platform.h | 1 + - 5 files changed, 60 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index c5ed34b..2d9bcd8 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -114,6 +114,12 @@ - compatible = "brcm,bcm2708-fb"; - status = "disabled"; - }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ }; - }; - - clocks { -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index cde2124..81cc988 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -437,6 +437,31 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static struct resource bcm2708_vchiq_resources[] = { -+ { -+ .start = ARMCTRL_0_BELL_BASE, -+ .end = ARMCTRL_0_BELL_BASE + 16, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_DOORBELL_0, -+ .end = IRQ_ARM_DOORBELL_0, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_vchiq_device = { -+ .name = "bcm2835_vchiq", -+ .id = -1, -+ .resource = bcm2708_vchiq_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), -+ .dev = { -+ .dma_mask = &vchiq_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - #ifdef CONFIG_BCM2708_GPIO - #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" - -@@ -909,6 +934,7 @@ void __init bcm2708_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h -index bef3e5a..69674e9 100644 ---- a/arch/arm/mach-bcm2708/include/mach/platform.h -+++ b/arch/arm/mach-bcm2708/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ - #define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 95db41ff..528bf6e 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -456,6 +456,31 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static struct resource bcm2708_vchiq_resources[] = { -+ { -+ .start = ARMCTRL_0_BELL_BASE, -+ .end = ARMCTRL_0_BELL_BASE + 16, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_DOORBELL_0, -+ .end = IRQ_ARM_DOORBELL_0, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_vchiq_device = { -+ .name = "bcm2835_vchiq", -+ .id = -1, -+ .resource = bcm2708_vchiq_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), -+ .dev = { -+ .dma_mask = &vchiq_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - #ifdef CONFIG_BCM2708_GPIO - #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" - -@@ -930,6 +955,7 @@ void __init bcm2709_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -diff --git a/arch/arm/mach-bcm2709/include/mach/platform.h b/arch/arm/mach-bcm2709/include/mach/platform.h -index 5574bb5..be99733 100644 ---- a/arch/arm/mach-bcm2709/include/mach/platform.h -+++ b/arch/arm/mach-bcm2709/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ - #define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - - -From b723b4395acda96c805d6cd382d5732efa6e449c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 19 May 2015 13:32:34 +0200 -Subject: [PATCH 171/216] bcm2708: vchiq: Add Device Tree support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Turn vchiq into a driver and stop hardcoding resources. -Use devm_* functions in probe path to simplify cleanup. -A global variable is used to hold the register address. This is done -to keep this patch as small as possible. -Also make available on ARCH_BCM2835. -Based on work by Lubomir Rintel. - -Signed-off-by: Noralf Trønnes ---- - drivers/misc/vc04_services/Kconfig | 2 +- - .../interface/vchiq_arm/vchiq_2835_arm.c | 124 +++++++++------------ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 44 ++++---- - .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 7 +- - 4 files changed, 79 insertions(+), 98 deletions(-) - -diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig -index b94e6cd..b4198c2 100644 ---- a/drivers/misc/vc04_services/Kconfig -+++ b/drivers/misc/vc04_services/Kconfig -@@ -1,6 +1,6 @@ - config BCM2708_VCHIQ - tristate "Videocore VCHIQ" -- depends on MACH_BCM2708 || MACH_BCM2709 -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 - default y - help - Kernel to VideoCore communication interface for the -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 70e5086..660aad2 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -35,22 +35,17 @@ - #include - #include - #include --#include - #include - #include - #include - #include - #include -+#include - #include - #include - --#include -- --#include -- - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - --#define VCHIQ_DOORBELL_IRQ IRQ_ARM_DOORBELL_0 - #define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) - - #include "vchiq_arm.h" -@@ -60,14 +55,15 @@ - - #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) - -+#define BELL0 0x00 -+#define BELL2 0x08 -+ - typedef struct vchiq_2835_state_struct { - int inited; - VCHIQ_ARM_STATE_T arm_state; - } VCHIQ_2835_ARM_STATE_T; - --static char *g_slot_mem; --static int g_slot_mem_size; --dma_addr_t g_slot_phys; -+static void __iomem *g_regs; - static FRAGMENTS_T *g_fragments_base; - static FRAGMENTS_T *g_free_fragments; - struct semaphore g_free_fragments_sema; -@@ -86,43 +82,40 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - static void - free_pagelist(PAGELIST_T *pagelist, int actual); - --int __init --vchiq_platform_init(VCHIQ_STATE_T *state) -+int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - { -+ struct device *dev = &pdev->dev; - VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; -- int frag_mem_size; -- int err; -- int i; -+ struct resource *res; -+ void *slot_mem; -+ dma_addr_t slot_phys; -+ int slot_mem_size, frag_mem_size; -+ int err, irq, i; - - /* Allocate space for the channels in coherent memory */ -- g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); -+ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); - -- g_slot_mem = dma_alloc_coherent(NULL, g_slot_mem_size + frag_mem_size, -- &g_slot_phys, GFP_KERNEL); -- -- if (!g_slot_mem) { -- vchiq_log_error(vchiq_arm_log_level, -- "Unable to allocate channel memory"); -- err = -ENOMEM; -- goto failed_alloc; -+ slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, -+ &slot_phys, GFP_KERNEL); -+ if (!slot_mem) { -+ dev_err(dev, "could not allocate DMA memory\n"); -+ return -ENOMEM; - } - -- WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0); -+ WARN_ON(((int)slot_mem & (PAGE_SIZE - 1)) != 0); - -- vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size); -- if (!vchiq_slot_zero) { -- err = -EINVAL; -- goto failed_init_slots; -- } -+ vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); -+ if (!vchiq_slot_zero) -+ return -EINVAL; - - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = -- (int)g_slot_phys + g_slot_mem_size; -+ (int)slot_phys + slot_mem_size; - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = - MAX_FRAGMENTS; - -- g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size); -- g_slot_mem_size += frag_mem_size; -+ g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); -+ slot_mem_size += frag_mem_size; - - g_free_fragments = g_fragments_base; - for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { -@@ -132,54 +125,46 @@ vchiq_platform_init(VCHIQ_STATE_T *state) - *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; - sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); - -- if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) != -- VCHIQ_SUCCESS) { -- err = -EINVAL; -- goto failed_vchiq_init; -+ if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) -+ return -EINVAL; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ g_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(g_regs)) -+ return PTR_ERR(g_regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq <= 0) { -+ dev_err(dev, "failed to get IRQ\n"); -+ return irq; - } - -- err = request_irq(VCHIQ_DOORBELL_IRQ, vchiq_doorbell_irq, -- IRQF_IRQPOLL, "VCHIQ doorbell", -- state); -- if (err < 0) { -- vchiq_log_error(vchiq_arm_log_level, "%s: failed to register " -- "irq=%d err=%d", __func__, -- VCHIQ_DOORBELL_IRQ, err); -- goto failed_request_irq; -+ err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL, -+ "VCHIQ doorbell", state); -+ if (err) { -+ dev_err(dev, "failed to register irq=%d\n", irq); -+ return err; - } - - /* Send the base address of the slots to VideoCore */ - - dsb(); /* Ensure all writes have completed */ - -- bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys); -+ err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); -+ if (err) { -+ dev_err(dev, "mailbox write failed\n"); -+ return err; -+ } - - vchiq_log_info(vchiq_arm_log_level, -- "vchiq_init - done (slots %x, phys %x)", -- (unsigned int)vchiq_slot_zero, g_slot_phys); -+ "vchiq_init - done (slots %x, phys %pad)", -+ (unsigned int)vchiq_slot_zero, &slot_phys); - -- vchiq_call_connected_callbacks(); -+ vchiq_call_connected_callbacks(); - - return 0; -- --failed_request_irq: --failed_vchiq_init: --failed_init_slots: -- dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys); -- --failed_alloc: -- return err; --} -- --void __exit --vchiq_platform_exit(VCHIQ_STATE_T *state) --{ -- free_irq(VCHIQ_DOORBELL_IRQ, state); -- dma_free_coherent(NULL, g_slot_mem_size, -- g_slot_mem, g_slot_phys); - } - -- - VCHIQ_STATUS_T - vchiq_platform_init_state(VCHIQ_STATE_T *state) - { -@@ -213,11 +198,8 @@ remote_event_signal(REMOTE_EVENT_T *event) - - dsb(); /* data barrier operation */ - -- if (event->armed) { -- /* trigger vc interrupt */ -- -- writel(0, __io_address(ARM_0_BELL2)); -- } -+ if (event->armed) -+ writel(0, g_regs + BELL2); /* trigger vc interrupt */ - } - - int -@@ -341,7 +323,7 @@ vchiq_doorbell_irq(int irq, void *dev_id) - unsigned int status; - - /* Read (and clear) the doorbell */ -- status = readl(__io_address(ARM_0_BELL0)); -+ status = readl(g_regs + BELL0); - - if (status & 0x4) { /* Was the doorbell rung? */ - remote_event_pollall(state); -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index 0ad9656..31e2cba 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - #include "vchiq_core.h" - #include "vchiq_ioctl.h" -@@ -2790,15 +2791,7 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, - } - } - -- --/**************************************************************************** --* --* vchiq_init - called when the module is loaded. --* --***************************************************************************/ -- --static int __init --vchiq_init(void) -+static int vchiq_probe(struct platform_device *pdev) - { - int err; - void *ptr_err; -@@ -2835,7 +2828,7 @@ vchiq_init(void) - if (IS_ERR(ptr_err)) - goto failed_device_create; - -- err = vchiq_platform_init(&g_state); -+ err = vchiq_platform_init(pdev, &g_state); - if (err != 0) - goto failed_platform_init; - -@@ -2862,23 +2855,32 @@ vchiq_init(void) - return err; - } - --/**************************************************************************** --* --* vchiq_exit - called when the module is unloaded. --* --***************************************************************************/ -- --static void __exit --vchiq_exit(void) -+static int vchiq_remove(struct platform_device *pdev) - { -- vchiq_platform_exit(&g_state); - device_destroy(vchiq_class, vchiq_devid); - class_destroy(vchiq_class); - cdev_del(&vchiq_cdev); - unregister_chrdev_region(vchiq_devid, 1); -+ -+ return 0; - } - --module_init(vchiq_init); --module_exit(vchiq_exit); -+static const struct of_device_id vchiq_of_match[] = { -+ { .compatible = "brcm,bcm2835-vchiq", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, vchiq_of_match); -+ -+static struct platform_driver vchiq_driver = { -+ .driver = { -+ .name = "bcm2835_vchiq", -+ .owner = THIS_MODULE, -+ .of_match_table = vchiq_of_match, -+ }, -+ .probe = vchiq_probe, -+ .remove = vchiq_remove, -+}; -+module_platform_driver(vchiq_driver); -+ - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Broadcom Corporation"); -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -index d1e2741..9740e1a 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -@@ -36,6 +36,7 @@ - #define VCHIQ_ARM_H - - #include -+#include - #include - #include - #include "vchiq_core.h" -@@ -128,11 +129,7 @@ typedef struct vchiq_arm_state_struct { - extern int vchiq_arm_log_level; - extern int vchiq_susp_log_level; - --extern int __init --vchiq_platform_init(VCHIQ_STATE_T *state); -- --extern void __exit --vchiq_platform_exit(VCHIQ_STATE_T *state); -+int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state); - - extern VCHIQ_STATE_T * - vchiq_get_state(void); - -From a368d9389c5c346a4e5b6ee63a5b28c45184aa20 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 19 May 2015 13:32:50 +0200 -Subject: [PATCH 172/216] bcm2835: Add bcm2835-vchiq to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add vchiq to Device Tree. There are no kernel users yet, -but it's available to userspace (vcgencmd). - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index f3ab9b3..72d0354 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -164,6 +164,12 @@ - compatible = "brcm,bcm2708-fb"; - status = "disabled"; - }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ }; - }; - - clocks { - -From 0bf6760b3d81238fcfac05e88f66252192c5745d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 20 May 2015 09:29:46 +0100 -Subject: [PATCH 173/216] i2c-bcm2708: When using DT, leave the GPIO setup to - pinctrl - ---- - drivers/i2c/busses/i2c-bcm2708.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 81e9374..8773203 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -382,7 +382,8 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - goto out_clk_put; - } - -- bcm2708_i2c_init_pinmode(pdev->id); -+ if (!pdev->dev.of_node) -+ bcm2708_i2c_init_pinmode(pdev->id); - - bi = kzalloc(sizeof(*bi), GFP_KERNEL); - if (!bi) - -From aa0aca81361683205b07ecc895256795ea771528 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 May 2015 11:36:31 +0100 -Subject: [PATCH 174/216] vchiq: Change logging level for inbound data - ---- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -index 835688b..2c98da4 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -@@ -1782,7 +1782,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) - service->remoteport); - break; - case VCHIQ_MSG_DATA: -- vchiq_log_trace(vchiq_core_log_level, -+ vchiq_log_info(vchiq_core_log_level, - "%d: prs DATA@%x,%x (%d->%d)", - state->id, (unsigned int)header, size, - remoteport, localport); - -From 32477cf579fd64092395855bfacf907c7da8e3d8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 21 May 2015 13:24:35 +0200 -Subject: [PATCH 175/216] BCM270x: Add onboard sound device to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support to alsa driver. -Add device to Device Tree. -Don't add platform devices when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 4 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 7 +++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - sound/arm/Kconfig | 3 +- - sound/arm/bcm2835.c | 91 ++++++++++++++++++++++++++++++++ - 9 files changed, 118 insertions(+), 3 deletions(-) - mode change 100755 => 100644 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi - mode change 100755 => 100644 sound/arm/bcm2835.c - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 9a8fed0..6323c5b 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -53,6 +53,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index cf67ec9..e1fe6a4 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -53,6 +53,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -old mode 100755 -new mode 100644 -index 815a3a4..1c2cfcf ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -34,6 +34,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 2d9bcd8..4bf6960 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -3,6 +3,13 @@ - / { - interrupt-parent = <&intc>; - -+ /* Onboard audio */ -+ audio: audio { -+ compatible = "brcm,bcm2835-audio"; -+ brcm,pwm-channels = <8>; -+ status = "disabled"; -+ }; -+ - soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 1c865de..921add1 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -53,6 +53,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 81cc988..e451187 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -964,7 +964,7 @@ void __init bcm2708_init(void) - #endif - bcm2708_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device(&bcm2708_alsa_devices[i]); -+ bcm_register_device_dt(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 528bf6e..06c2c74 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -987,7 +987,7 @@ void __init bcm2709_init(void) - #endif - bcm2709_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device(&bcm2708_alsa_devices[i]); -+ bcm_register_device_dt(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); - -diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig -index ada7ba2..fcbe9d7 100644 ---- a/sound/arm/Kconfig -+++ b/sound/arm/Kconfig -@@ -41,7 +41,8 @@ config SND_PXA2XX_AC97 - - config SND_BCM2835 - tristate "BCM2835 ALSA driver" -- depends on (ARCH_BCM2708 || ARCH_BCM2709) && BCM2708_VCHIQ && SND -+ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) \ -+ && BCM2708_VCHIQ && SND - select SND_PCM - help - Say Y or M if you want to support BCM2835 Alsa pcm card driver -diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c -old mode 100755 -new mode 100644 -index 7ed5079..6b545e7 ---- a/sound/arm/bcm2835.c -+++ b/sound/arm/bcm2835.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - #include "bcm2835.h" - -@@ -81,6 +82,86 @@ static int snd_bcm2835_create(struct snd_card *card, - return 0; - } - -+static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ bcm2835_chip_t *chip; -+ struct snd_card *card; -+ u32 numchans; -+ int err, i; -+ -+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", -+ &numchans); -+ if (err) { -+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); -+ return err; -+ } -+ -+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { -+ numchans = MAX_SUBSTREAMS; -+ dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n", -+ numchans); -+ } -+ -+ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card); -+ if (err) { -+ dev_err(dev, "Failed to create soundcard structure\n"); -+ return err; -+ } -+ -+ snd_card_set_dev(card, dev); -+ strcpy(card->driver, "bcm2835"); -+ strcpy(card->shortname, "bcm2835 ALSA"); -+ sprintf(card->longname, "%s", card->shortname); -+ -+ err = snd_bcm2835_create(card, pdev, &chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create bcm2835 chip\n"); -+ goto err_free; -+ } -+ -+ err = snd_bcm2835_new_pcm(chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create new bcm2835 pcm device\n"); -+ goto err_free; -+ } -+ -+ err = snd_bcm2835_new_spdif_pcm(chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n"); -+ goto err_free; -+ } -+ -+ err = snd_bcm2835_new_ctl(chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create new bcm2835 ctl\n"); -+ goto err_free; -+ } -+ -+ for (i = 0; i < numchans; i++) { -+ chip->avail_substreams |= (1 << i); -+ chip->pdev[i] = pdev; -+ } -+ -+ err = snd_card_register(card); -+ if (err) { -+ dev_err(dev, "Failed to register bcm2835 ALSA card \n"); -+ goto err_free; -+ } -+ -+ g_card = card; -+ g_chip = chip; -+ platform_set_drvdata(pdev, card); -+ audio_info("bcm2835 ALSA card created with %u channels\n", numchans); -+ -+ return 0; -+ -+err_free: -+ snd_card_free(card); -+ -+ return err; -+} -+ - static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - static int dev; -@@ -88,6 +169,9 @@ static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - struct snd_card *card; - int err; - -+ if (pdev->dev.of_node) -+ return snd_bcm2835_alsa_probe_dt(pdev); -+ - if (dev >= MAX_SUBSTREAMS) - return -ENODEV; - -@@ -224,6 +308,12 @@ static int snd_bcm2835_alsa_resume(struct platform_device *pdev) - - #endif - -+static const struct of_device_id snd_bcm2835_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-audio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); -+ - static struct platform_driver bcm2835_alsa0_driver = { - .probe = snd_bcm2835_alsa_probe, - .remove = snd_bcm2835_alsa_remove, -@@ -234,6 +324,7 @@ static struct platform_driver bcm2835_alsa0_driver = { - .driver = { - .name = "bcm2835_AUD0", - .owner = THIS_MODULE, -+ .of_match_table = snd_bcm2835_of_match_table, - }, - }; - - -From a8d9f167700bc9fd113a303b4944272519fc40f0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 21 May 2015 13:25:32 +0200 -Subject: [PATCH 176/216] bcm2835: Add bcm2835-audio to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add onboard sound device to Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index f2ce803..f23835e 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -14,6 +14,12 @@ - linux,default-trigger = "heartbeat"; - }; - }; -+ -+ /* Onboard audio */ -+ audio: audio { -+ compatible = "brcm,bcm2835-audio"; -+ brcm,pwm-channels = <8>; -+ }; - }; - - &gpio { - -From ead779a26fcab730a6d4be4c7b48c62b22afd8a5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 May 2015 16:59:02 +0100 -Subject: [PATCH 177/216] config: Add CONFIG_CIFS_UPCALL - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index ff87581..6fdd9bb 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1118,6 +1118,7 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_9P_FS=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e339979..93b3de1 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1111,6 +1111,7 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_9P_FS=m - -From 2728618d457e238f4f95d96ad9303a1d816109a9 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 May 2015 16:59:13 +0100 -Subject: [PATCH 178/216] config: Add CONFIG_FB_SSD1307=m - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6fdd9bb..9daaeb7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -769,6 +769,7 @@ CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 93b3de1..dc27aeb 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -762,6 +762,7 @@ CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - -From 25b5c8e286f3a2b1779c63754b8993107bb416b0 Mon Sep 17 00:00:00 2001 +From f794a0549b3a54cbe6dcfef3b37c421dda92d13a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 179/216] Improve __copy_to_user and __copy_from_user - performance +Subject: [PATCH 71/77] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use optimised memcpy/memmove/memcmp/memset implementations. @@ -143076,7 +132661,7 @@ index cf4f3aa..9fe7780 100644 #define memset(p,v,n) \ diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h -index ce0786e..b85b93d 100644 +index 74b17d0..f4ad0a1 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -475,6 +475,7 @@ do { \ @@ -144557,356 +134142,28 @@ index 3e58d71..0622891 100644 static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From ee5567b6efdbf9cbdf4cacaabc7623c5f6d45064 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 19 May 2015 18:49:06 +0100 -Subject: [PATCH 180/216] vcsm: Add ioctl for custom cache flushing - ---- - arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h | 15 +++++++ - drivers/char/broadcom/vc_sm/vmcs_sm.c | 49 ++++++++++++++++++++++ - 2 files changed, 64 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -index 42d0eb0..334f36d 100644 ---- a/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -+++ b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -@@ -61,6 +61,8 @@ enum vmcs_sm_cmd_e { - VMCS_SM_CMD_HOST_WALK_PID_ALLOC, - VMCS_SM_CMD_HOST_WALK_PID_MAP, - -+ VMCS_SM_CMD_CLEAN_INVALID, -+ - VMCS_SM_CMD_LAST /* Do no delete */ - }; - -@@ -163,6 +165,16 @@ struct vmcs_sm_ioctl_cache { - unsigned int size; - }; - -+struct vmcs_sm_ioctl_clean_invalid { -+ /* user -> kernel */ -+ struct { -+ unsigned int cmd; -+ unsigned int handle; -+ unsigned int addr; -+ unsigned int size; -+ } s[8]; -+}; -+ - /* IOCTL numbers */ - #define VMCS_SM_IOCTL_MEM_ALLOC\ - _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_ALLOC,\ -@@ -191,6 +203,9 @@ struct vmcs_sm_ioctl_cache { - #define VMCS_SM_IOCTL_MEM_INVALID\ - _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\ - struct vmcs_sm_ioctl_cache) -+#define VMCS_SM_IOCTL_MEM_CLEAN_INVALID\ -+ _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_CLEAN_INVALID,\ -+ struct vmcs_sm_ioctl_clean_invalid) - - #define VMCS_SM_IOCTL_SIZE_USR_HDL\ - _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\ -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index da1c523..39a8971 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -2732,6 +2732,55 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - } - break; - -+ /* Flush/Invalidate the cache for a given mapping. */ -+ case VMCS_SM_CMD_CLEAN_INVALID: -+ { -+ int i; -+ struct vmcs_sm_ioctl_clean_invalid ioparam; -+ -+ /* Get parameter data. */ -+ if (copy_from_user(&ioparam, -+ (void *)arg, sizeof(ioparam)) != 0) { -+ pr_err("[%s]: failed to copy-from-user for cmd %x\n", -+ __func__, cmdnr); -+ ret = -EFAULT; -+ goto out; -+ } -+ for (i=0; ires_cached) { -+ unsigned long base = ioparam.s[i].addr & ~(PAGE_SIZE-1); -+ unsigned long end = (ioparam.s[i].addr + ioparam.s[i].size + PAGE_SIZE-1) & ~(PAGE_SIZE-1); -+ resource->res_stats[ioparam.s[i].cmd == 1 ? INVALID:FLUSH]++; -+ -+ /* L1/L2 cache flush */ -+ down_read(¤t->mm->mmap_sem); -+ vcsm_vma_cache_clean_page_range(base, end); -+ up_read(¤t->mm->mmap_sem); -+ } else if (resource == NULL) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (resource) -+ vmcs_sm_release_resource(resource, 0); -+ } -+ break; -+ } -+ } -+ } -+ break; -+ - default: - { - ret = -EINVAL; - -From 6f9e2f739661f49e2375be580025549b367444b2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 17 Mar 2015 16:07:48 +0100 -Subject: [PATCH 181/216] dts: overlay: add generic support for ads7846 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add generic support for the ADS7846 touch controller. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/ads7846-overlay.dts | 83 +++++++++++++++++++++++++++++++++++ - 2 files changed, 84 insertions(+) - create mode 100644 arch/arm/boot/dts/ads7846-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index f3558df..0e77296 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - -+dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/ads7846-overlay.dts b/arch/arm/boot/dts/ads7846-overlay.dts -new file mode 100644 -index 0000000..6a92cd1 ---- /dev/null -+++ b/arch/arm/boot/dts/ads7846-overlay.dts -@@ -0,0 +1,83 @@ -+/* -+ * Generic Device Tree overlay for the ADS7846 touch controller -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ ads7846_pins: ads7846_pins { -+ brcm,pins = <255>; /* illegal default value */ -+ brcm,function = <0>; /* in */ -+ brcm,pull = <0>; /* none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ads7846: ads7846@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ads7846_pins>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <255 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 255 0>; -+ -+ /* driver defaults */ -+ ti,x-min = /bits/ 16 <0>; -+ ti,y-min = /bits/ 16 <0>; -+ ti,x-max = /bits/ 16 <0x0FFF>; -+ ti,y-max = /bits/ 16 <0x0FFF>; -+ ti,pressure-min = /bits/ 16 <0>; -+ ti,pressure-max = /bits/ 16 <0xFFFF>; -+ ti,x-plate-ohms = /bits/ 16 <400>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ cs = <&ads7846>,"reg:0"; -+ speed = <&ads7846>,"spi-max-frequency:0"; -+ penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ -+ <&ads7846>,"interrupts:0", -+ <&ads7846>,"pendown-gpio:4"; -+ penirq_pull = <&ads7846_pins>,"brcm,pull:0"; -+ swapxy = <&ads7846>,"ti,swap-xy?"; -+ xmin = <&ads7846>,"ti,x-min;0"; -+ ymin = <&ads7846>,"ti,y-min;0"; -+ xmax = <&ads7846>,"ti,x-max;0"; -+ ymax = <&ads7846>,"ti,y-max;0"; -+ pmin = <&ads7846>,"ti,pressure-min;0"; -+ pmax = <&ads7846>,"ti,pressure-max;0"; -+ xohms = <&ads7846>,"ti,x-plate-ohms;0"; -+ }; -+}; - -From beda21eb0afb05805e46419c37f1127bf35fa775 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 24 May 2015 19:12:01 +0200 -Subject: [PATCH 182/216] bcm270x: add dtparam for audio node - -The audio node is enabled by default and can be disabled -with dtparam=audio=off in config.txt ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 6323c5b..609d004 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -126,5 +126,7 @@ - pwr_led_gpio = <&pwr_led>,"gpios:4"; - pwr_led_activelow = <&pwr_led>,"gpios:8"; - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e1fe6a4..e601194 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -116,5 +116,7 @@ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 921add1..fe282e4 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -126,5 +126,7 @@ - pwr_led_gpio = <&pwr_led>,"gpios:4"; - pwr_led_activelow = <&pwr_led>,"gpios:8"; - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; - }; - }; - -From c40ce86818e2ccd1521b5072cfa0bc102893ca7a Mon Sep 17 00:00:00 2001 +From 5787d557e062cdac5f3e19ccd60394dc6df38aab Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 27 May 2015 17:22:15 +0100 -Subject: [PATCH 183/216] bcm2835-audio: Create the platform device if the DT +Subject: [PATCH 72/77] bcm2835-audio: Create the platform device if the DT node is disabled For backwards compatibility, allow the built-in ALSA driver to be enabled either by loading the module from /etc/modules or by enabling the "/audio" node in DT. --- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ---- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ---- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ---- - arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- - 5 files changed, 16 insertions(+), 16 deletions(-) + arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- + arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- + 2 files changed, 16 insertions(+), 4 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 609d004..75df21c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -53,10 +53,6 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e601194..df12b7d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -53,10 +53,6 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index fe282e4..78bc756 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -53,10 +53,6 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e451187..06438df 100644 +index de2f93a..cfc4f13 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -963,8 +963,14 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2835_emmc_device); +@@ -898,8 +898,14 @@ void __init bcm2708_init(void) #endif bcm2708_init_led(); + bcm2708_init_uart1(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); + @@ -144921,13 +134178,13 @@ index e451187..06438df 100644 bcm_register_device_dt(&bcm2708_spi_device); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 06c2c74..ce06b7d 100644 +index 350647a..507ff52 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -986,8 +986,14 @@ void __init bcm2709_init(void) - bcm_register_device_dt(&bcm2835_emmc_device); +@@ -918,8 +918,14 @@ void __init bcm2709_init(void) #endif bcm2709_init_led(); + bcm2709_init_uart1(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); + @@ -144942,8640 +134199,10 @@ index 06c2c74..ce06b7d 100644 bcm_register_device_dt(&bcm2708_spi_device); -From 9f10489e52092f350c72745c2ac3d0afbbf4cd44 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 27 May 2015 14:39:55 +0000 -Subject: [PATCH 184/216] device-tree: spi: make spi-bcm2835 the default spi - driver and prepare for dma - -* make spi-bcm2835 the default driver for spi -* add a fallback spi-bcm2708 overlay -* add dma entries to device tree for future updates -* add default cs-gpios entry showing how to extend the number of chip-selects. - -Signed-off-by: Martin Sperl ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 10 +++++++++- - arch/arm/boot/dts/spi-bcm2708-overlay.dts | 18 ++++++++++++++++++ - 3 files changed, 28 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/spi-bcm2708-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 0e77296..9124dfb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -41,6 +41,7 @@ dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4bf6960..3f8af85 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -84,13 +84,21 @@ - }; - - spi0: spi@7e204000 { -- compatible = "brcm,bcm2708-spi"; -+ compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; - clocks = <&clk_spi>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; -+ /* the dma channels */ -+ dmas = <&dma 6>, <&dma 7>; -+ dma-names = "tx", "rx"; -+ /* the chipselects used - <0> means native GPIO -+ * add more gpios if necessary as <&gpio 6 1> -+ * (but do not forget to make them output!) -+ */ -+ cs-gpios = <0>, <0>; - }; - - i2c0: i2c@7e205000 { -diff --git a/arch/arm/boot/dts/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/spi-bcm2708-overlay.dts -new file mode 100644 -index 0000000..e378ef1 ---- /dev/null -+++ b/arch/arm/boot/dts/spi-bcm2708-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2708-spi"; -+ }; -+ }; -+}; - -From 8c5dd3fb2ef21f3dc20a7c999fd2659354afa975 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 23 May 2015 23:30:36 +0200 -Subject: [PATCH 185/216] BCM270x: Move power module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make the power module available on ARCH_BCM2835 by moving it. -The module turns on USB power making it possible to boot -ARCH_BCM2835 directly with the VC bootloader. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/include/mach/arm_power.h | 62 -------- - arch/arm/mach-bcm2708/include/mach/power.h | 26 ---- - arch/arm/mach-bcm2708/power.c | 201 ------------------------- - arch/arm/mach-bcm2709/Makefile | 2 +- - arch/arm/mach-bcm2709/include/mach/arm_power.h | 62 -------- - arch/arm/mach-bcm2709/include/mach/power.h | 26 ---- - arch/arm/mach-bcm2709/power.c | 199 ------------------------ - drivers/soc/Kconfig | 1 + - drivers/soc/Makefile | 1 + - drivers/soc/bcm2835/Kconfig | 9 ++ - drivers/soc/bcm2835/Makefile | 1 + - drivers/soc/bcm2835/bcm2708-power.c | 200 ++++++++++++++++++++++++ - include/soc/bcm2835/power.h | 61 ++++++++ - 14 files changed, 275 insertions(+), 578 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/arm_power.h - delete mode 100644 arch/arm/mach-bcm2708/include/mach/power.h - delete mode 100644 arch/arm/mach-bcm2708/power.c - delete mode 100644 arch/arm/mach-bcm2709/include/mach/arm_power.h - delete mode 100644 arch/arm/mach-bcm2709/include/mach/power.h - delete mode 100644 arch/arm/mach-bcm2709/power.c - create mode 100644 drivers/soc/bcm2835/Kconfig - create mode 100644 drivers/soc/bcm2835/Makefile - create mode 100644 drivers/soc/bcm2835/bcm2708-power.c - create mode 100644 include/soc/bcm2835/power.h - -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index c1e7d41..5552ae8 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o power.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/include/mach/arm_power.h b/arch/arm/mach-bcm2708/include/mach/arm_power.h -deleted file mode 100644 -index d3bf245..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/arm_power.h -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 _ARM_POWER_H --#define _ARM_POWER_H -- --/* Use meaningful names on each side */ --#ifdef __VIDEOCORE__ --#define PREFIX(x) ARM_##x --#else --#define PREFIX(x) BCM_##x --#endif -- --enum { -- PREFIX(POWER_SDCARD_BIT), -- PREFIX(POWER_UART_BIT), -- PREFIX(POWER_MINIUART_BIT), -- PREFIX(POWER_USB_BIT), -- PREFIX(POWER_I2C0_BIT), -- PREFIX(POWER_I2C1_BIT), -- PREFIX(POWER_I2C2_BIT), -- PREFIX(POWER_SPI_BIT), -- PREFIX(POWER_CCP2TX_BIT), -- PREFIX(POWER_DSI_BIT), -- -- PREFIX(POWER_MAX) --}; -- --enum { -- PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -- PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -- PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -- PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -- PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -- PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -- PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -- PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -- PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -- PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -- -- PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -- PREFIX(POWER_NONE) = 0 --}; -- --#endif -diff --git a/arch/arm/mach-bcm2708/include/mach/power.h b/arch/arm/mach-bcm2708/include/mach/power.h -deleted file mode 100644 -index 52b3b02..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/power.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#ifndef _MACH_BCM2708_POWER_H --#define _MACH_BCM2708_POWER_H -- --#include --#include -- --typedef unsigned int BCM_POWER_HANDLE_T; -- --extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); --extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); --extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -- --#endif -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -deleted file mode 100644 -index 796837f..0000000 ---- a/arch/arm/mach-bcm2708/power.c -+++ /dev/null -@@ -1,201 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#include --#include --#include --#include --#include --#include -- --#define DRIVER_NAME "bcm2708_power" -- --#define BCM_POWER_MAXCLIENTS 4 --#define BCM_POWER_NOCLIENT (1<<31) -- --/* Some drivers expect there devices to be permanently powered */ -- --#ifdef CONFIG_USB --#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) --#endif -- --#if 1 --#define DPRINTK printk --#else --#define DPRINTK if (0) printk --#endif -- --struct state_struct { -- uint32_t global_request; -- uint32_t client_request[BCM_POWER_MAXCLIENTS]; -- struct semaphore client_mutex; -- struct semaphore mutex; --} g_state; -- --int bcm_power_open(BCM_POWER_HANDLE_T *handle) --{ -- BCM_POWER_HANDLE_T i; -- int ret = -EBUSY; -- -- down(&g_state.client_mutex); -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -- g_state.client_request[i] = BCM_POWER_NONE; -- *handle = i; -- ret = 0; -- break; -- } -- } -- -- up(&g_state.client_mutex); -- -- DPRINTK("bcm_power_open() -> %d\n", *handle); -- -- return ret; --} --EXPORT_SYMBOL_GPL(bcm_power_open); -- --int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) --{ -- int rc = 0; -- -- DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -- -- if ((handle < BCM_POWER_MAXCLIENTS) && -- (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -- if (down_interruptible(&g_state.mutex) != 0) { -- DPRINTK("bcm_power_request -> interrupted\n"); -- return -EINTR; -- } -- -- if (request != g_state.client_request[handle]) { -- uint32_t others_request = 0; -- uint32_t global_request; -- BCM_POWER_HANDLE_T i; -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (i != handle) -- others_request |= -- g_state.client_request[i]; -- } -- others_request &= ~BCM_POWER_NOCLIENT; -- -- global_request = request | others_request; -- if (global_request != g_state.global_request) { -- uint32_t actual; -- -- /* Send a request to VideoCore */ -- 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); -- DPRINTK -- ("bcm_mailbox_read -> %08x, %d\n", -- actual, rc); -- actual >>= 4; -- } else { -- rc = 0; -- actual = global_request; -- } -- -- 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", -- __func__, -- g_state.global_request, -- global_request, actual, request, others_request); -- /* A failure */ -- BUG_ON((others_request & actual) -- != others_request); -- request &= actual; -- rc = -EIO; -- } -- -- g_state.global_request = actual; -- g_state.client_request[handle] = -- request; -- } -- } -- } -- up(&g_state.mutex); -- } else { -- rc = -EINVAL; -- } -- DPRINTK("bcm_power_request -> %d\n", rc); -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_request); -- --int bcm_power_close(BCM_POWER_HANDLE_T handle) --{ -- int rc; -- -- DPRINTK("bcm_power_close(%d)\n", handle); -- -- rc = bcm_power_request(handle, BCM_POWER_NONE); -- if (rc == 0) -- g_state.client_request[handle] = BCM_POWER_NOCLIENT; -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_close); -- --static int __init bcm_power_init(void) --{ --#if defined(BCM_POWER_ALWAYS_ON) -- BCM_POWER_HANDLE_T always_on_handle; --#endif -- int rc = 0; -- 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; -- -- sema_init(&g_state.client_mutex, 1); -- sema_init(&g_state.mutex, 1); -- -- g_state.global_request = 0; -- --#if defined(BCM_POWER_ALWAYS_ON) -- if (BCM_POWER_ALWAYS_ON) { -- bcm_power_open(&always_on_handle); -- bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -- } --#endif -- -- return rc; --} -- --static void __exit bcm_power_exit(void) --{ -- bcm_mailbox_write(MBOX_CHAN_POWER, 0); --} -- --/* -- * Load after the mailbox driver is initialized (arch_initcall), -- * but before depending drivers (module_init). -- */ --subsys_initcall(bcm_power_init); --module_exit(bcm_power_exit); -- --MODULE_AUTHOR("Phil Elwell"); --MODULE_DESCRIPTION("Interface to BCM2708 power management"); --MODULE_LICENSE("GPL"); -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index 77b8429..706116f 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o power.o -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/include/mach/arm_power.h b/arch/arm/mach-bcm2709/include/mach/arm_power.h -deleted file mode 100644 -index d3bf245..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/arm_power.h -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 _ARM_POWER_H --#define _ARM_POWER_H -- --/* Use meaningful names on each side */ --#ifdef __VIDEOCORE__ --#define PREFIX(x) ARM_##x --#else --#define PREFIX(x) BCM_##x --#endif -- --enum { -- PREFIX(POWER_SDCARD_BIT), -- PREFIX(POWER_UART_BIT), -- PREFIX(POWER_MINIUART_BIT), -- PREFIX(POWER_USB_BIT), -- PREFIX(POWER_I2C0_BIT), -- PREFIX(POWER_I2C1_BIT), -- PREFIX(POWER_I2C2_BIT), -- PREFIX(POWER_SPI_BIT), -- PREFIX(POWER_CCP2TX_BIT), -- PREFIX(POWER_DSI_BIT), -- -- PREFIX(POWER_MAX) --}; -- --enum { -- PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -- PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -- PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -- PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -- PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -- PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -- PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -- PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -- PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -- PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -- -- PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -- PREFIX(POWER_NONE) = 0 --}; -- --#endif -diff --git a/arch/arm/mach-bcm2709/include/mach/power.h b/arch/arm/mach-bcm2709/include/mach/power.h -deleted file mode 100644 -index 52b3b02..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/power.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#ifndef _MACH_BCM2708_POWER_H --#define _MACH_BCM2708_POWER_H -- --#include --#include -- --typedef unsigned int BCM_POWER_HANDLE_T; -- --extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); --extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); --extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -- --#endif -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -deleted file mode 100644 -index 960e472..0000000 ---- a/arch/arm/mach-bcm2709/power.c -+++ /dev/null -@@ -1,199 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#include --#include --#include --#include --#include --#include -- --#define DRIVER_NAME "bcm2708_power" -- --#define BCM_POWER_MAXCLIENTS 4 --#define BCM_POWER_NOCLIENT (1<<31) -- --/* Some drivers expect there devices to be permanently powered */ --#ifdef CONFIG_USB --#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) --#endif -- --#if 1 --#define DPRINTK printk --#else --#define DPRINTK if (0) printk --#endif -- --struct state_struct { -- uint32_t global_request; -- uint32_t client_request[BCM_POWER_MAXCLIENTS]; -- struct semaphore client_mutex; -- struct semaphore mutex; --} g_state; -- --int bcm_power_open(BCM_POWER_HANDLE_T *handle) --{ -- BCM_POWER_HANDLE_T i; -- int ret = -EBUSY; -- -- down(&g_state.client_mutex); -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -- g_state.client_request[i] = BCM_POWER_NONE; -- *handle = i; -- ret = 0; -- break; -- } -- } -- -- up(&g_state.client_mutex); -- -- DPRINTK("bcm_power_open() -> %d\n", *handle); -- -- return ret; --} --EXPORT_SYMBOL_GPL(bcm_power_open); -- --int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) --{ -- int rc = 0; -- -- DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -- -- if ((handle < BCM_POWER_MAXCLIENTS) && -- (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -- if (down_interruptible(&g_state.mutex) != 0) { -- DPRINTK("bcm_power_request -> interrupted\n"); -- return -EINTR; -- } -- -- if (request != g_state.client_request[handle]) { -- uint32_t others_request = 0; -- uint32_t global_request; -- BCM_POWER_HANDLE_T i; -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (i != handle) -- others_request |= -- g_state.client_request[i]; -- } -- others_request &= ~BCM_POWER_NOCLIENT; -- -- global_request = request | others_request; -- if (global_request != g_state.global_request) { -- uint32_t actual; -- -- /* Send a request to VideoCore */ -- 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); -- DPRINTK -- ("bcm_mailbox_read -> %08x, %d\n", -- actual, rc); -- actual >>= 4; -- } else { -- rc = 0; -- actual = global_request; -- } -- -- 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", -- __func__, -- g_state.global_request, -- global_request, actual, request, others_request); -- /* A failure */ -- BUG_ON((others_request & actual) -- != others_request); -- request &= actual; -- rc = -EIO; -- } -- -- g_state.global_request = actual; -- g_state.client_request[handle] = -- request; -- } -- } -- } -- up(&g_state.mutex); -- } else { -- rc = -EINVAL; -- } -- DPRINTK("bcm_power_request -> %d\n", rc); -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_request); -- --int bcm_power_close(BCM_POWER_HANDLE_T handle) --{ -- int rc; -- -- DPRINTK("bcm_power_close(%d)\n", handle); -- -- rc = bcm_power_request(handle, BCM_POWER_NONE); -- if (rc == 0) -- g_state.client_request[handle] = BCM_POWER_NOCLIENT; -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_close); -- --static int __init bcm_power_init(void) --{ --#if defined(BCM_POWER_ALWAYS_ON) -- BCM_POWER_HANDLE_T always_on_handle; --#endif -- int rc = 0; -- 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; -- -- sema_init(&g_state.client_mutex, 1); -- sema_init(&g_state.mutex, 1); -- -- g_state.global_request = 0; --#if defined(BCM_POWER_ALWAYS_ON) -- if (BCM_POWER_ALWAYS_ON) { -- bcm_power_open(&always_on_handle); -- bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -- } --#endif -- -- return rc; --} -- --static void __exit bcm_power_exit(void) --{ -- bcm_mailbox_write(MBOX_CHAN_POWER, 0); --} -- --/* -- * Load after the mailbox driver is initialized (arch_initcall), -- * but before depending drivers (module_init). -- */ --subsys_initcall(bcm_power_init); --module_exit(bcm_power_exit); -- --MODULE_AUTHOR("Phil Elwell"); --MODULE_DESCRIPTION("Interface to BCM2708 power management"); --MODULE_LICENSE("GPL"); -diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig -index 76d6bd4..aed58f4 100644 ---- a/drivers/soc/Kconfig -+++ b/drivers/soc/Kconfig -@@ -1,5 +1,6 @@ - menu "SOC (System On Chip) specific Drivers" - -+source "drivers/soc/bcm2835/Kconfig" - source "drivers/soc/qcom/Kconfig" - source "drivers/soc/ti/Kconfig" - source "drivers/soc/versatile/Kconfig" -diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile -index 063113d..897de0c5 100644 ---- a/drivers/soc/Makefile -+++ b/drivers/soc/Makefile -@@ -2,6 +2,7 @@ - # Makefile for the Linux Kernel SOC specific device drivers. - # - -+obj-y += bcm2835/ - obj-$(CONFIG_ARCH_QCOM) += qcom/ - obj-$(CONFIG_ARCH_TEGRA) += tegra/ - obj-$(CONFIG_SOC_TI) += ti/ -diff --git a/drivers/soc/bcm2835/Kconfig b/drivers/soc/bcm2835/Kconfig -new file mode 100644 -index 0000000..c2980f3 ---- /dev/null -+++ b/drivers/soc/bcm2835/Kconfig -@@ -0,0 +1,9 @@ -+# -+# BCM2835 Soc drivers -+# -+config BCM2708_POWER -+ tristate "BCM2708 legacy power driver" -+ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX -+ default y -+ help -+ Turns on USB power and provides an API for controlling power. -diff --git a/drivers/soc/bcm2835/Makefile b/drivers/soc/bcm2835/Makefile -new file mode 100644 -index 0000000..3614ad9 ---- /dev/null -+++ b/drivers/soc/bcm2835/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_BCM2708_POWER) += bcm2708-power.o -diff --git a/drivers/soc/bcm2835/bcm2708-power.c b/drivers/soc/bcm2835/bcm2708-power.c -new file mode 100644 -index 0000000..e7931a9 ---- /dev/null -+++ b/drivers/soc/bcm2835/bcm2708-power.c -@@ -0,0 +1,200 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/power.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_power" -+ -+#define BCM_POWER_MAXCLIENTS 4 -+#define BCM_POWER_NOCLIENT (1<<31) -+ -+/* Some drivers expect there devices to be permanently powered */ -+ -+#ifdef CONFIG_USB -+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) -+#endif -+ -+#if 1 -+#define DPRINTK printk -+#else -+#define DPRINTK if (0) printk -+#endif -+ -+struct state_struct { -+ uint32_t global_request; -+ uint32_t client_request[BCM_POWER_MAXCLIENTS]; -+ struct semaphore client_mutex; -+ struct semaphore mutex; -+} g_state; -+ -+int bcm_power_open(BCM_POWER_HANDLE_T *handle) -+{ -+ BCM_POWER_HANDLE_T i; -+ int ret = -EBUSY; -+ -+ down(&g_state.client_mutex); -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -+ g_state.client_request[i] = BCM_POWER_NONE; -+ *handle = i; -+ ret = 0; -+ break; -+ } -+ } -+ -+ up(&g_state.client_mutex); -+ -+ DPRINTK("bcm_power_open() -> %d\n", *handle); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(bcm_power_open); -+ -+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) -+{ -+ int rc = 0; -+ -+ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -+ -+ if ((handle < BCM_POWER_MAXCLIENTS) && -+ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -+ if (down_interruptible(&g_state.mutex) != 0) { -+ DPRINTK("bcm_power_request -> interrupted\n"); -+ return -EINTR; -+ } -+ -+ if (request != g_state.client_request[handle]) { -+ uint32_t others_request = 0; -+ uint32_t global_request; -+ BCM_POWER_HANDLE_T i; -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (i != handle) -+ others_request |= -+ g_state.client_request[i]; -+ } -+ others_request &= ~BCM_POWER_NOCLIENT; -+ -+ global_request = request | others_request; -+ if (global_request != g_state.global_request) { -+ uint32_t actual; -+ -+ /* Send a request to VideoCore */ -+ 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); -+ DPRINTK -+ ("bcm_mailbox_read -> %08x, %d\n", -+ actual, rc); -+ actual >>= 4; -+ } else { -+ rc = 0; -+ actual = global_request; -+ } -+ -+ 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", -+ __func__, -+ g_state.global_request, -+ global_request, actual, request, others_request); -+ /* A failure */ -+ BUG_ON((others_request & actual) -+ != others_request); -+ request &= actual; -+ rc = -EIO; -+ } -+ -+ g_state.global_request = actual; -+ g_state.client_request[handle] = -+ request; -+ } -+ } -+ } -+ up(&g_state.mutex); -+ } else { -+ rc = -EINVAL; -+ } -+ DPRINTK("bcm_power_request -> %d\n", rc); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_request); -+ -+int bcm_power_close(BCM_POWER_HANDLE_T handle) -+{ -+ int rc; -+ -+ DPRINTK("bcm_power_close(%d)\n", handle); -+ -+ rc = bcm_power_request(handle, BCM_POWER_NONE); -+ if (rc == 0) -+ g_state.client_request[handle] = BCM_POWER_NOCLIENT; -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_close); -+ -+static int __init bcm_power_init(void) -+{ -+#if defined(BCM_POWER_ALWAYS_ON) -+ BCM_POWER_HANDLE_T always_on_handle; -+#endif -+ int rc = 0; -+ 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; -+ -+ sema_init(&g_state.client_mutex, 1); -+ sema_init(&g_state.mutex, 1); -+ -+ g_state.global_request = 0; -+ -+#if defined(BCM_POWER_ALWAYS_ON) -+ if (BCM_POWER_ALWAYS_ON) { -+ bcm_power_open(&always_on_handle); -+ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -+ } -+#endif -+ -+ return rc; -+} -+ -+static void __exit bcm_power_exit(void) -+{ -+ bcm_mailbox_write(MBOX_CHAN_POWER, 0); -+} -+ -+/* -+ * Load after the mailbox driver is initialized (arch_initcall), -+ * but before depending drivers (module_init). -+ */ -+subsys_initcall(bcm_power_init); -+module_exit(bcm_power_exit); -+ -+MODULE_AUTHOR("Phil Elwell"); -+MODULE_DESCRIPTION("Interface to BCM2708 power management"); -+MODULE_LICENSE("GPL"); -diff --git a/include/soc/bcm2835/power.h b/include/soc/bcm2835/power.h -new file mode 100644 -index 0000000..bf22b26 ---- /dev/null -+++ b/include/soc/bcm2835/power.h -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#ifndef _BCM2708_POWER_H -+#define _BCM2708_POWER_H -+ -+#include -+ -+/* Use meaningful names on each side */ -+#ifdef __VIDEOCORE__ -+#define PREFIX(x) ARM_##x -+#else -+#define PREFIX(x) BCM_##x -+#endif -+ -+enum { -+ PREFIX(POWER_SDCARD_BIT), -+ PREFIX(POWER_UART_BIT), -+ PREFIX(POWER_MINIUART_BIT), -+ PREFIX(POWER_USB_BIT), -+ PREFIX(POWER_I2C0_BIT), -+ PREFIX(POWER_I2C1_BIT), -+ PREFIX(POWER_I2C2_BIT), -+ PREFIX(POWER_SPI_BIT), -+ PREFIX(POWER_CCP2TX_BIT), -+ PREFIX(POWER_DSI_BIT), -+ -+ PREFIX(POWER_MAX) -+}; -+ -+enum { -+ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -+ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -+ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -+ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -+ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -+ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -+ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -+ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -+ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -+ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -+ -+ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -+ PREFIX(POWER_NONE) = 0 -+}; -+ -+typedef unsigned int BCM_POWER_HANDLE_T; -+ -+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); -+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); -+extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -+ -+#endif - -From 7ea54e2541e0445c98c3b5bb4b0e80af76c5c197 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 23 May 2015 23:31:40 +0200 -Subject: [PATCH 186/216] bcm2835: Use empty bootargs in Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The VideoCore bootloader concatenates the bootargs property together -with /boot/cmdline.txt and includes it's own set of options. -Set bootargs to an empty string to behave like BCM270x. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 72d0354..40fc759 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -6,7 +6,7 @@ - interrupt-parent = <&intc>; - - chosen { -- bootargs = "earlyprintk console=ttyAMA0"; -+ bootargs = ""; - }; - - soc { - -From b340f9126d88eafd83e2ae6e0b593bea562f92f5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 187/216] scripts: Add mkknlimg and knlinfo scripts from tools - repo - -The Raspberry Pi firmware looks for a trailer on the kernel image to -determine whether it was compiled with Device Tree support enabled. -If the firmware finds a kernel without this trailer, or which has a -trailer indicating that it isn't DT-capable, it disables DT support -and reverts to using ATAGs. - -The mkknlimg utility adds that trailer, having first analysed the -image to look for signs of DT support and the kernel version string. - -knlinfo displays the contents of the trailer in the given kernel image. ---- - scripts/knlinfo | 167 +++++++++++++++++++++++++++++++++++ - scripts/mkknlimg | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 427 insertions(+) - create mode 100755 scripts/knlinfo - create mode 100755 scripts/mkknlimg - -diff --git a/scripts/knlinfo b/scripts/knlinfo -new file mode 100755 -index 0000000..9c9b42e3 ---- /dev/null -+++ b/scripts/knlinfo -@@ -0,0 +1,167 @@ -+#!/usr/bin/env perl -+# ---------------------------------------------------------------------- -+# knlinfo by Phil Elwell for Raspberry Pi -+# -+# (c) 2014,2015 Raspberry Pi (Trading) Limited -+# -+# Licensed under the terms of the GNU General Public License. -+# ---------------------------------------------------------------------- -+ -+use strict; -+use integer; -+ -+use Fcntl ":seek"; -+ -+my $trailer_magic = 'RPTL'; -+ -+my %atom_formats = -+( -+ 'DTOK' => \&format_bool, -+ 'KVer' => \&format_string, -+); -+ -+if (@ARGV != 1) -+{ -+ print ("Usage: knlinfo \n"); -+ exit(1); -+} -+ -+my $kernel_file = $ARGV[0]; -+ -+ -+my ($atoms, $pos) = read_trailer($kernel_file); -+ -+exit(1) if (!$atoms); -+ -+printf("Kernel trailer found at %d/0x%x:\n", $pos, $pos); -+ -+foreach my $atom (@$atoms) -+{ -+ printf(" %s: %s\n", $atom->[0], format_atom($atom)); -+} -+ -+exit(0); -+ -+sub read_trailer -+{ -+ my ($kernel_file) = @_; -+ my $fh; -+ -+ if (!open($fh, '<', $kernel_file)) -+ { -+ print ("* Failed to open '$kernel_file'\n"); -+ return undef; -+ } -+ -+ if (!seek($fh, -12, SEEK_END)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ -+ my $last_bytes; -+ sysread($fh, $last_bytes, 12); -+ -+ my ($trailer_len, $data_len, $magic) = unpack('VVa4', $last_bytes); -+ -+ if (($magic ne $trailer_magic) || ($data_len != 4)) -+ { -+ print ("* no trailer\n"); -+ return undef; -+ } -+ if (!seek($fh, -12, SEEK_END)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ -+ $trailer_len -= 12; -+ -+ while ($trailer_len > 0) -+ { -+ if ($trailer_len < 8) -+ { -+ print ("* truncated atom header in trailer\n"); -+ return undef; -+ } -+ if (!seek($fh, -8, SEEK_CUR)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ $trailer_len -= 8; -+ -+ my $atom_hdr; -+ sysread($fh, $atom_hdr, 8); -+ my ($atom_len, $atom_type) = unpack('Va4', $atom_hdr); -+ -+ if ($trailer_len < $atom_len) -+ { -+ print ("* truncated atom data in trailer\n"); -+ return undef; -+ } -+ -+ my $rounded_len = (($atom_len + 3) & ~3); -+ if (!seek($fh, -(8 + $rounded_len), SEEK_CUR)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ $trailer_len -= $rounded_len; -+ -+ my $atom_data; -+ sysread($fh, $atom_data, $atom_len); -+ -+ if (!seek($fh, -$atom_len, SEEK_CUR)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ -+ push @$atoms, [ $atom_type, $atom_data ]; -+ } -+ -+ if (($$atoms[-1][0] eq "\x00\x00\x00\x00") && -+ ($$atoms[-1][1] eq "")) -+ { -+ pop @$atoms; -+ } -+ else -+ { -+ print ("* end marker missing from trailer\n"); -+ } -+ -+ return ($atoms, tell($fh)); -+} -+ -+sub format_atom -+{ -+ my ($atom) = @_; -+ -+ my $format_func = $atom_formats{$atom->[0]} || \&format_hex; -+ return $format_func->($atom->[1]); -+} -+ -+sub format_bool -+{ -+ my ($data) = @_; -+ return unpack('V', $data) ? 'true' : 'false'; -+} -+ -+sub format_int -+{ -+ my ($data) = @_; -+ return unpack('V', $data); -+} -+ -+sub format_string -+{ -+ my ($data) = @_; -+ return '"'.$data.'"'; -+} -+ -+sub format_hex -+{ -+ my ($data) = @_; -+ return unpack('H*', $data); -+} -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -new file mode 100755 -index 0000000..ac829d0 ---- /dev/null -+++ b/scripts/mkknlimg -@@ -0,0 +1,260 @@ -+#!/usr/bin/env perl -+# ---------------------------------------------------------------------- -+# mkknlimg by Phil Elwell for Raspberry Pi -+# based on extract-ikconfig Dick Streefland -+# -+# (c) 2009,2010 Dick Streefland -+# (c) 2014,2015 Raspberry Pi (Trading) Limited -+# -+# Licensed under the terms of the GNU General Public License. -+# ---------------------------------------------------------------------- -+ -+use strict; -+use warnings; -+use integer; -+ -+my $trailer_magic = 'RPTL'; -+ -+my $tmpfile1 = "/tmp/mkknlimg_$$.1"; -+my $tmpfile2 = "/tmp/mkknlimg_$$.2"; -+ -+my $dtok = 0; -+ -+while (@ARGV && ($ARGV[0] =~ /^-/)) -+{ -+ my $arg = shift(@ARGV); -+ if ($arg eq '--dtok') -+ { -+ $dtok = 1; -+ } -+ else -+ { -+ print ("* Unknown option '$arg'\n"); -+ usage(); -+ } -+} -+ -+usage() if (@ARGV != 2); -+ -+my $kernel_file = $ARGV[0]; -+my $out_file = $ARGV[1]; -+ -+if (! -r $kernel_file) -+{ -+ print ("* File '$kernel_file' not found\n"); -+ usage(); -+} -+ -+my @wanted_config_lines = -+( -+ 'CONFIG_BCM2708_DT' -+); -+ -+my @wanted_strings = -+( -+ 'bcm2708_fb', -+ 'brcm,bcm2708-pinctrl', -+ 'brcm,bcm2835-gpio', -+ 'of_find_property' -+); -+ -+my $res = try_extract($kernel_file, $tmpfile1); -+$res = try_decompress('\037\213\010', 'xy', 'gunzip', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\3757zXZ\000', 'abcde', 'unxz --single-stream', -1, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('BZh', 'xy', 'bunzip2', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\135\0\0\0', 'xxx', 'unlzma', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\211\114\132', 'xy', 'lzop -d', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\002\041\114\030', 'xy', 'lz4 -d', 1, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+ -+my $append_trailer; -+my $trailer; -+my $kver = '?'; -+ -+$append_trailer = $dtok; -+ -+if ($res) -+{ -+ $kver = $res->{''} || '?'; -+ print("Version: $kver\n"); -+ -+ $append_trailer = $dtok; -+ if (!$dtok) -+ { -+ if (config_bool($res, 'bcm2708_fb')) -+ { -+ $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); -+ $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); -+ $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); -+ $append_trailer = 1; -+ } -+ else -+ { -+ print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n"); -+ } -+ } -+} -+elsif (!$dtok) -+{ -+ print ("* Is this a valid kernel? In pass-through mode.\n"); -+} -+ -+if ($append_trailer) -+{ -+ printf("DT: %s\n", $dtok ? "y" : "n"); -+ -+ my @atoms; -+ -+ push @atoms, [ $trailer_magic, pack('V', 0) ]; -+ push @atoms, [ 'KVer', $kver ]; -+ push @atoms, [ 'DTOK', pack('V', $dtok) ]; -+ -+ $trailer = pack_trailer(\@atoms); -+ $atoms[0]->[1] = pack('V', length($trailer)); -+ -+ $trailer = pack_trailer(\@atoms); -+} -+ -+my $ofh; -+my $total_len = 0; -+ -+if ($out_file eq $kernel_file) -+{ -+ die "* Failed to open '$out_file' for append\n" -+ if (!open($ofh, '>>', $out_file)); -+ $total_len = tell($ofh); -+} -+else -+{ -+ die "* Failed to open '$kernel_file'\n" -+ if (!open(my $ifh, '<', $kernel_file)); -+ die "* Failed to create '$out_file'\n" -+ if (!open($ofh, '>', $out_file)); -+ -+ my $copybuf; -+ while (1) -+ { -+ my $bytes = sysread($ifh, $copybuf, 64*1024); -+ last if (!$bytes); -+ syswrite($ofh, $copybuf, $bytes); -+ $total_len += $bytes; -+ } -+ close($ifh); -+} -+ -+if ($trailer) -+{ -+ # Pad to word-alignment -+ syswrite($ofh, "\x000\x000\x000", (-$total_len & 0x3)); -+ syswrite($ofh, $trailer); -+} -+ -+close($ofh); -+ -+exit($trailer ? 0 : 1); -+ -+END { -+ unlink($tmpfile1) if ($tmpfile1); -+ unlink($tmpfile2) if ($tmpfile2); -+} -+ -+ -+sub usage -+{ -+ print ("Usage: mkknlimg [--dtok] \n"); -+ exit(1); -+} -+ -+sub try_extract -+{ -+ my ($knl, $tmp) = @_; -+ -+ my $ver = `strings "$knl" | grep -a -E "^Linux version [1-9]"`; -+ -+ return undef if (!$ver); -+ -+ chomp($ver); -+ -+ my $res = { ''=>$ver }; -+ my $string_pattern = '^('.join('|', @wanted_strings).')$'; -+ -+ my @matches = `strings \"$knl\" | grep -E \"$string_pattern\"`; -+ foreach my $match (@matches) -+ { -+ chomp($match); -+ $res->{$match} = 1; -+ } -+ -+ my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$'; -+ my $cf1 = 'IKCFG_ST\037\213\010'; -+ my $cf2 = '0123456789'; -+ -+ my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`; -+ if ($pos) -+ { -+ $pos =~ s/:.*[\r\n]*$//s; -+ $pos += 8; -+ my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8); -+ if (($err == 0) || ($err == 2)) -+ { -+ if (open(my $fh, '<', $tmp)) -+ { -+ while (my $line = <$fh>) -+ { -+ chomp($line); -+ $res->{$1} = $2 if ($line =~ /$config_pattern/); -+ } -+ -+ close($fh); -+ } -+ } -+ } -+ -+ return $res; -+} -+ -+ -+sub try_decompress -+{ -+ my ($magic, $subst, $zcat, $idx, $knl, $tmp1, $tmp2) = @_; -+ -+ my $pos = `tr "$magic\n$subst" "\n$subst=" < "$knl" | grep -abo "^$subst"`; -+ if ($pos) -+ { -+ chomp($pos); -+ $pos = (split(/[\r\n]+/, $pos))[$idx]; -+ return undef if (!defined($pos)); -+ $pos =~ s/:.*[\r\n]*$//s; -+ my $cmd = "tail -c+$pos \"$knl\" | $zcat > $tmp2 2> /dev/null"; -+ my $err = (system($cmd) >> 8); -+ return undef if (($err != 0) && ($err != 2)); -+ -+ return try_extract($tmp2, $tmp1); -+ } -+ -+ return undef; -+} -+ -+sub pack_trailer -+{ -+ my ($atoms) = @_; -+ my $trailer = pack('VV', 0, 0); -+ for (my $i = $#$atoms; $i>=0; $i--) -+ { -+ my $atom = $atoms->[$i]; -+ $trailer .= pack('a*x!4Va4', $atom->[1], length($atom->[1]), $atom->[0]); -+ } -+ return $trailer; -+} -+ -+sub config_bool -+{ -+ my ($configs, $wanted) = @_; -+ my $val = $configs->{$wanted} || 'n'; -+ return (($val eq 'y') || ($val eq '1')); -+} - -From 2ab7f22fc98a7e6f66c3924d0eff9a721b159029 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 May 2015 18:35:44 +0100 -Subject: [PATCH 188/216] scripts/mkknlimg: Add support for ARCH_BCM2835 - -Add a new trailer field indicating whether this is an ARCH_BCM2835 -build, as opposed to MACH_BCM2708/9. If the loader finds this flag -is set it changes the default base dtb file name from bcm270x... -to bcm283y... - -Also update knlinfo to show the status of the field. ---- - scripts/knlinfo | 1 + - scripts/mkknlimg | 25 ++++++++++++++++++++----- - 2 files changed, 21 insertions(+), 5 deletions(-) - -diff --git a/scripts/knlinfo b/scripts/knlinfo -index 9c9b42e3..a0e8663 100755 ---- a/scripts/knlinfo -+++ b/scripts/knlinfo -@@ -18,6 +18,7 @@ my %atom_formats = - ( - 'DTOK' => \&format_bool, - 'KVer' => \&format_string, -+ '283x' => \&format_bool, - ); - - if (@ARGV != 1) -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -index ac829d0..3dff948 100755 ---- a/scripts/mkknlimg -+++ b/scripts/mkknlimg -@@ -1,7 +1,7 @@ - #!/usr/bin/env perl - # ---------------------------------------------------------------------- - # mkknlimg by Phil Elwell for Raspberry Pi --# based on extract-ikconfig Dick Streefland -+# based on extract-ikconfig by Dick Streefland - # - # (c) 2009,2010 Dick Streefland - # (c) 2014,2015 Raspberry Pi (Trading) Limited -@@ -19,6 +19,7 @@ my $tmpfile1 = "/tmp/mkknlimg_$$.1"; - my $tmpfile2 = "/tmp/mkknlimg_$$.2"; - - my $dtok = 0; -+my $is_283x = 0; - - while (@ARGV && ($ARGV[0] =~ /^-/)) - { -@@ -27,6 +28,10 @@ while (@ARGV && ($ARGV[0] =~ /^-/)) - { - $dtok = 1; - } -+ elsif ($arg eq '--283x') -+ { -+ $is_283x = 1; -+ } - else - { - print ("* Unknown option '$arg'\n"); -@@ -47,15 +52,18 @@ if (! -r $kernel_file) - - my @wanted_config_lines = - ( -- 'CONFIG_BCM2708_DT' -+ 'CONFIG_BCM2708_DT', -+ 'CONFIG_ARCH_BCM2835' - ); - - my @wanted_strings = - ( - 'bcm2708_fb', -+ 'brcm,bcm2835-mmc', -+ 'brcm,bcm2835-sdhost', - 'brcm,bcm2708-pinctrl', - 'brcm,bcm2835-gpio', -- 'of_find_property' -+ 'brcm,bcm2835-pm-wdt' - ); - - my $res = try_extract($kernel_file, $tmpfile1); -@@ -86,11 +94,16 @@ if ($res) - $append_trailer = $dtok; - if (!$dtok) - { -- if (config_bool($res, 'bcm2708_fb')) -+ if (config_bool($res, 'bcm2708_fb') || -+ config_bool($res, 'brcm,bcm2835-mmc') || -+ config_bool($res, 'brcm,bcm2835-sdhost')) - { - $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); -+ $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); - $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); - $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); -+ $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); -+ $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt'); - $append_trailer = 1; - } - else -@@ -107,12 +120,14 @@ elsif (!$dtok) - if ($append_trailer) - { - printf("DT: %s\n", $dtok ? "y" : "n"); -+ printf("283x: %s\n", $is_283x ? "y" : "n"); - - my @atoms; - - push @atoms, [ $trailer_magic, pack('V', 0) ]; - push @atoms, [ 'KVer', $kver ]; - push @atoms, [ 'DTOK', pack('V', $dtok) ]; -+ push @atoms, [ '283x', pack('V', $is_283x) ]; - - $trailer = pack_trailer(\@atoms); - $atoms[0]->[1] = pack('V', length($trailer)); -@@ -166,7 +181,7 @@ END { - - sub usage - { -- print ("Usage: mkknlimg [--dtok] \n"); -+ print ("Usage: mkknlimg [--dtok] [--283x] \n"); - exit(1); - } - - -From 73bb23f8980890aad84dc6b852f0aac91ab71981 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 10 Mar 2015 18:35:18 +0100 -Subject: [PATCH 189/216] config: add KEYBOARD_GPIO - ---- - arch/arm/configs/bcm2709_defconfig | 3 ++- - arch/arm/configs/bcmrpi_defconfig | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 9daaeb7..5ce9a01 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -520,7 +520,8 @@ 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_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m - # CONFIG_INPUT_MOUSE is not set - CONFIG_INPUT_JOYSTICK=y - CONFIG_JOYSTICK_IFORCE=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index dc27aeb..da443da 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -513,7 +513,8 @@ 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_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m - # CONFIG_INPUT_MOUSE is not set - CONFIG_INPUT_JOYSTICK=y - CONFIG_JOYSTICK_IFORCE=m - -From d7d347201d595ccc495da617ab583fdb3e282829 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 10 Mar 2015 18:35:59 +0100 -Subject: [PATCH 190/216] dts: overlay: add support for tinylcd.com 3.5" - display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for 3.5" display by tinylcd.com - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/tinylcd35-overlay.dts | 216 ++++++++++++++++++++++++++++++++ - 2 files changed, 217 insertions(+) - create mode 100644 arch/arm/boot/dts/tinylcd35-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 9124dfb..25ea8eb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -38,6 +38,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -diff --git a/arch/arm/boot/dts/tinylcd35-overlay.dts b/arch/arm/boot/dts/tinylcd35-overlay.dts -new file mode 100644 -index 0000000..f7102c8 ---- /dev/null -+++ b/arch/arm/boot/dts/tinylcd35-overlay.dts -@@ -0,0 +1,216 @@ -+/* -+ * tinylcd35-overlay.dts -+ * -+ * ------------------------------------------------- -+ * www.tinlylcd.com -+ * ------------------------------------------------- -+ * Device---Driver-----BUS GPIO's -+ * display tinylcd35 spi0.0 25 24 18 -+ * touch ads7846 spi0.1 5 -+ * rtc ds1307 i2c1-0068 -+ * rtc pcf8563 i2c1-0051 -+ * keypad gpio-keys --------- 17 22 27 23 28 -+ * -+ * -+ * TinyLCD.com 3.5 inch TFT -+ * -+ * Version 001 -+ * 5/3/2015 -- Noralf Trønnes Initial Device tree framework -+ * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ tinylcd35_pins: tinylcd35_pins { -+ brcm,pins = <25 24 18>; -+ brcm,function = <1>; /* out */ -+ }; -+ tinylcd35_ts_pins: tinylcd35_ts_pins { -+ brcm,pins = <5>; -+ brcm,function = <0>; /* in */ -+ }; -+ keypad_pins: keypad_pins { -+ brcm,pins = <4 17 22 23 27>; -+ brcm,function = <0>; /* in */ -+ brcm,pull = <1>; /* down */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tinylcd35: tinylcd35@0{ -+ compatible = "neosec,tinylcd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&tinylcd35_pins>, -+ <&tinylcd35_ts_pins>; -+ -+ spi-max-frequency = <48000000>; -+ rotate = <270>; -+ fps = <20>; -+ bgr; -+ buswidth = <8>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ -+ init = <0x10000B0 0x80 -+ 0x10000C0 0x0A 0x0A -+ 0x10000C1 0x01 0x01 -+ 0x10000C2 0x33 -+ 0x10000C5 0x00 0x42 0x80 -+ 0x10000B1 0xD0 0x11 -+ 0x10000B4 0x02 -+ 0x10000B6 0x00 0x22 0x3B -+ 0x10000B7 0x07 -+ 0x1000036 0x58 -+ 0x10000F0 0x36 0xA5 0xD3 -+ 0x10000E5 0x80 -+ 0x10000E5 0x01 -+ 0x10000B3 0x00 -+ 0x10000E5 0x00 -+ 0x10000F0 0x36 0xA5 0x53 -+ 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 -+ 0x100003A 0x55 -+ 0x1000011 -+ 0x2000001 -+ 0x1000029>; -+ }; -+ -+ tinylcd35_ts: tinylcd35_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ status = "disabled"; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <5 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 5 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ -+ /* RTC */ -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pcf8563: pcf8563@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* -+ * Values for input event code is found under the -+ * 'Keys and buttons' heading in include/uapi/linux/input.h -+ */ -+ fragment@5 { -+ target-path = "/soc"; -+ __overlay__ { -+ keypad: keypad { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&keypad_pins>; -+ status = "disabled"; -+ autorepeat; -+ -+ button@17 { -+ label = "GPIO KEY_UP"; -+ linux,code = <103>; -+ gpios = <&gpio 17 0>; -+ }; -+ button@22 { -+ label = "GPIO KEY_DOWN"; -+ linux,code = <108>; -+ gpios = <&gpio 22 0>; -+ }; -+ button@27 { -+ label = "GPIO KEY_LEFT"; -+ linux,code = <105>; -+ gpios = <&gpio 27 0>; -+ }; -+ button@23 { -+ label = "GPIO KEY_RIGHT"; -+ linux,code = <106>; -+ gpios = <&gpio 23 0>; -+ }; -+ button@4 { -+ label = "GPIO KEY_ENTER"; -+ linux,code = <28>; -+ gpios = <&gpio 4 0>; -+ }; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&tinylcd35>,"spi-max-frequency:0"; -+ rotate = <&tinylcd35>,"rotate:0"; -+ fps = <&tinylcd35>,"fps:0"; -+ debug = <&tinylcd35>,"debug:0"; -+ touch = <&tinylcd35_ts>,"status"; -+ touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", -+ <&tinylcd35_ts>,"interrupts:0", -+ <&tinylcd35_ts>,"pendown-gpio:4"; -+ xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; -+ rtc-pcf = <&i2c1>,"status", -+ <&pcf8563>,"status"; -+ rtc-ds = <&i2c1>,"status", -+ <&ds1307>,"status"; -+ keypad = <&keypad>,"status"; -+ }; -+}; - -From 4b843d5be018d8d392a4be34a7fdfe3640e3c2a7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 29 May 2015 14:16:47 +0100 -Subject: [PATCH 191/216] BCM270X_DT: Move the overlays into a subdirectory, - adding the README - ---- - arch/arm/boot/dts/Makefile | 31 +- - arch/arm/boot/dts/ads7846-overlay.dts | 83 ---- - arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts | 23 - - arch/arm/boot/dts/ds1307-rtc-overlay.dts | 22 - - arch/arm/boot/dts/enc28j60-overlay.dts | 29 -- - arch/arm/boot/dts/hifiberry-amp-overlay.dts | 39 -- - arch/arm/boot/dts/hifiberry-dac-overlay.dts | 34 -- - arch/arm/boot/dts/hifiberry-dacplus-overlay.dts | 39 -- - arch/arm/boot/dts/hifiberry-digi-overlay.dts | 39 -- - arch/arm/boot/dts/hy28a-overlay.dts | 87 ---- - arch/arm/boot/dts/hy28b-overlay.dts | 142 ------- - arch/arm/boot/dts/i2c-rtc-overlay.dts | 43 -- - arch/arm/boot/dts/iqaudio-dac-overlay.dts | 39 -- - arch/arm/boot/dts/iqaudio-dacplus-overlay.dts | 39 -- - arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 --- - arch/arm/boot/dts/mmc-overlay.dts | 19 - - arch/arm/boot/dts/mz61581-overlay.dts | 109 ----- - arch/arm/boot/dts/overlays/Makefile | 51 +++ - arch/arm/boot/dts/overlays/README | 470 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 ++++ - .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + - arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts | 22 + - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 29 ++ - .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ - .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 ++++ - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 +++++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 49 +++ - arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ - .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 +++ - arch/arm/boot/dts/overlays/mmc-overlay.dts | 19 + - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 109 +++++ - arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts | 22 + - arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts | 22 + - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 94 +++++ - .../dts/overlays/pitft28-resistive-overlay.dts | 115 +++++ - arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 ++++ - arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 75 ++++ - arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 18 + - arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts | 18 + - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 ++++++++++ - arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ - .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ - arch/arm/boot/dts/pcf2127-rtc-overlay.dts | 22 - - arch/arm/boot/dts/pcf8523-rtc-overlay.dts | 22 - - arch/arm/boot/dts/piscreen-overlay.dts | 94 ----- - arch/arm/boot/dts/pitft28-resistive-overlay.dts | 115 ----- - arch/arm/boot/dts/pps-gpio-overlay.dts | 34 -- - arch/arm/boot/dts/rpi-dac-overlay.dts | 34 -- - arch/arm/boot/dts/rpi-display-overlay.dts | 82 ---- - arch/arm/boot/dts/rpi-proto-overlay.dts | 39 -- - arch/arm/boot/dts/sdhost-overlay.dts | 75 ---- - arch/arm/boot/dts/spi-bcm2708-overlay.dts | 18 - - arch/arm/boot/dts/spi-bcm2835-overlay.dts | 18 - - arch/arm/boot/dts/tinylcd35-overlay.dts | 216 ---------- - arch/arm/boot/dts/w1-gpio-overlay.dts | 39 -- - arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 41 -- - 63 files changed, 2220 insertions(+), 1722 deletions(-) - delete mode 100644 arch/arm/boot/dts/ads7846-overlay.dts - delete mode 100644 arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts - delete mode 100644 arch/arm/boot/dts/ds1307-rtc-overlay.dts - delete mode 100755 arch/arm/boot/dts/enc28j60-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-amp-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-dac-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-dacplus-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-digi-overlay.dts - delete mode 100644 arch/arm/boot/dts/hy28a-overlay.dts - delete mode 100644 arch/arm/boot/dts/hy28b-overlay.dts - delete mode 100644 arch/arm/boot/dts/i2c-rtc-overlay.dts - delete mode 100644 arch/arm/boot/dts/iqaudio-dac-overlay.dts - delete mode 100644 arch/arm/boot/dts/iqaudio-dacplus-overlay.dts - delete mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts - delete mode 100644 arch/arm/boot/dts/mmc-overlay.dts - delete mode 100644 arch/arm/boot/dts/mz61581-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/Makefile - create mode 100644 arch/arm/boot/dts/overlays/README - create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts - delete mode 100644 arch/arm/boot/dts/pcf2127-rtc-overlay.dts - delete mode 100644 arch/arm/boot/dts/pcf8523-rtc-overlay.dts - delete mode 100644 arch/arm/boot/dts/piscreen-overlay.dts - delete mode 100644 arch/arm/boot/dts/pitft28-resistive-overlay.dts - delete mode 100644 arch/arm/boot/dts/pps-gpio-overlay.dts - delete mode 100644 arch/arm/boot/dts/rpi-dac-overlay.dts - delete mode 100644 arch/arm/boot/dts/rpi-display-overlay.dts - delete mode 100644 arch/arm/boot/dts/rpi-proto-overlay.dts - delete mode 100644 arch/arm/boot/dts/sdhost-overlay.dts - delete mode 100644 arch/arm/boot/dts/spi-bcm2708-overlay.dts - delete mode 100644 arch/arm/boot/dts/spi-bcm2835-overlay.dts - delete mode 100644 arch/arm/boot/dts/tinylcd35-overlay.dts - delete mode 100644 arch/arm/boot/dts/w1-gpio-overlay.dts - delete mode 100644 arch/arm/boot/dts/w1-gpio-pullup-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 25ea8eb..ea93e1d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -13,36 +13,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - --dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb -+subdir-$(RPI_DT_OVERLAYS) += overlays - - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -diff --git a/arch/arm/boot/dts/ads7846-overlay.dts b/arch/arm/boot/dts/ads7846-overlay.dts -deleted file mode 100644 -index 6a92cd1..0000000 ---- a/arch/arm/boot/dts/ads7846-overlay.dts -+++ /dev/null -@@ -1,83 +0,0 @@ --/* -- * Generic Device Tree overlay for the ADS7846 touch controller -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- ads7846_pins: ads7846_pins { -- brcm,pins = <255>; /* illegal default value */ -- brcm,function = <0>; /* in */ -- brcm,pull = <0>; /* none */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- ads7846: ads7846@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- pinctrl-names = "default"; -- pinctrl-0 = <&ads7846_pins>; -- -- spi-max-frequency = <2000000>; -- interrupts = <255 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 255 0>; -- -- /* driver defaults */ -- ti,x-min = /bits/ 16 <0>; -- ti,y-min = /bits/ 16 <0>; -- ti,x-max = /bits/ 16 <0x0FFF>; -- ti,y-max = /bits/ 16 <0x0FFF>; -- ti,pressure-min = /bits/ 16 <0>; -- ti,pressure-max = /bits/ 16 <0xFFFF>; -- ti,x-plate-ohms = /bits/ 16 <400>; -- }; -- }; -- }; -- __overrides__ { -- cs = <&ads7846>,"reg:0"; -- speed = <&ads7846>,"spi-max-frequency:0"; -- penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ -- <&ads7846>,"interrupts:0", -- <&ads7846>,"pendown-gpio:4"; -- penirq_pull = <&ads7846_pins>,"brcm,pull:0"; -- swapxy = <&ads7846>,"ti,swap-xy?"; -- xmin = <&ads7846>,"ti,x-min;0"; -- ymin = <&ads7846>,"ti,y-min;0"; -- xmax = <&ads7846>,"ti,x-max;0"; -- ymax = <&ads7846>,"ti,y-max;0"; -- pmin = <&ads7846>,"ti,pressure-min;0"; -- pmax = <&ads7846>,"ti,pressure-max;0"; -- xohms = <&ads7846>,"ti,x-plate-ohms;0"; -- }; --}; -diff --git a/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -deleted file mode 100644 -index b830bf2..0000000 ---- a/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -+++ /dev/null -@@ -1,23 +0,0 @@ --// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- bmp085@77 { -- compatible = "bosch,bmp085"; -- reg = <0x77>; -- default-oversampling = <3>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/ds1307-rtc-overlay.dts -deleted file mode 100644 -index 7d27044..0000000 ---- a/arch/arm/boot/dts/ds1307-rtc-overlay.dts -+++ /dev/null -@@ -1,22 +0,0 @@ --// Definitions for DS1307 Real Time Clock --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- ds1307@68 { -- compatible = "maxim,ds1307"; -- reg = <0x68>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/enc28j60-overlay.dts b/arch/arm/boot/dts/enc28j60-overlay.dts -deleted file mode 100755 -index aa9b645..0000000 ---- a/arch/arm/boot/dts/enc28j60-overlay.dts -+++ /dev/null -@@ -1,29 +0,0 @@ --// Overlay for the Microchip ENC28J60 Ethernet Controller --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- enc28j60@0{ -- compatible = "microchip,enc28j60"; -- reg = <0>; /* CE0 */ -- spi-max-frequency = <12000000>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/hifiberry-amp-overlay.dts -deleted file mode 100644 -index 2c81448..0000000 ---- a/arch/arm/boot/dts/hifiberry-amp-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for HiFiBerry Amp/Amp+ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-amp"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- tas5713@1b { -- #sound-dai-cells = <0>; -- compatible = "ti,tas5713"; -- reg = <0x1b>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/hifiberry-dac-overlay.dts -deleted file mode 100644 -index 5e7633a..0000000 ---- a/arch/arm/boot/dts/hifiberry-dac-overlay.dts -+++ /dev/null -@@ -1,34 +0,0 @@ --// Definitions for HiFiBerry DAC --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target-path = "/"; -- __overlay__ { -- pcm5102a-codec { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5102a"; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -deleted file mode 100644 -index deb9c625..0000000 ---- a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for HiFiBerry DAC+ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-dacplus"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcm5122@4d { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5122"; -- reg = <0x4d>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/hifiberry-digi-overlay.dts -deleted file mode 100644 -index d0e0d8a..0000000 ---- a/arch/arm/boot/dts/hifiberry-digi-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for HiFiBerry Digi --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-digi"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- wm8804@3b { -- #sound-dai-cells = <0>; -- compatible = "wlf,wm8804"; -- reg = <0x3b>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hy28a-overlay.dts b/arch/arm/boot/dts/hy28a-overlay.dts -deleted file mode 100644 -index 3cd3083..0000000 ---- a/arch/arm/boot/dts/hy28a-overlay.dts -+++ /dev/null -@@ -1,87 +0,0 @@ --/* -- * Device Tree overlay for HY28A display -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- hy28a_pins: hy28a_pins { -- brcm,pins = <17 25 18>; -- brcm,function = <0 1 1>; /* in out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- hy28a: hy28a@0{ -- compatible = "ilitek,ili9320"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&hy28a_pins>; -- -- spi-max-frequency = <32000000>; -- spi-cpol; -- spi-cpha; -- rotate = <270>; -- bgr; -- fps = <50>; -- buswidth = <8>; -- startbyte = <0x70>; -- reset-gpios = <&gpio 25 0>; -- led-gpios = <&gpio 18 1>; -- debug = <0>; -- }; -- -- hy28a_ts: hy28a-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <17 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 17 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&hy28a>,"spi-max-frequency:0"; -- rotate = <&hy28a>,"rotate:0"; -- fps = <&hy28a>,"fps:0"; -- debug = <&hy28a>,"debug:0"; -- xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; -- resetgpio = <&hy28a>,"reset-gpios:4", -- <&hy28a_pins>, "brcm,pins:1"; -- ledgpio = <&hy28a>,"led-gpios:4", -- <&hy28a_pins>, "brcm,pins:2"; -- }; --}; -diff --git a/arch/arm/boot/dts/hy28b-overlay.dts b/arch/arm/boot/dts/hy28b-overlay.dts -deleted file mode 100644 -index f774c4a..0000000 ---- a/arch/arm/boot/dts/hy28b-overlay.dts -+++ /dev/null -@@ -1,142 +0,0 @@ --/* -- * Device Tree overlay for HY28b display shield by Texy -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- hy28b_pins: hy28b_pins { -- brcm,pins = <17 25 18>; -- brcm,function = <0 1 1>; /* in out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- hy28b: hy28b@0{ -- compatible = "ilitek,ili9325"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&hy28b_pins>; -- -- spi-max-frequency = <48000000>; -- spi-cpol; -- spi-cpha; -- rotate = <270>; -- bgr; -- fps = <50>; -- buswidth = <8>; -- startbyte = <0x70>; -- reset-gpios = <&gpio 25 0>; -- led-gpios = <&gpio 18 1>; -- -- gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -- -- init = <0x10000e7 0x0010 -- 0x1000000 0x0001 -- 0x1000001 0x0100 -- 0x1000002 0x0700 -- 0x1000003 0x1030 -- 0x1000004 0x0000 -- 0x1000008 0x0207 -- 0x1000009 0x0000 -- 0x100000a 0x0000 -- 0x100000c 0x0001 -- 0x100000d 0x0000 -- 0x100000f 0x0000 -- 0x1000010 0x0000 -- 0x1000011 0x0007 -- 0x1000012 0x0000 -- 0x1000013 0x0000 -- 0x2000032 -- 0x1000010 0x1590 -- 0x1000011 0x0227 -- 0x2000032 -- 0x1000012 0x009c -- 0x2000032 -- 0x1000013 0x1900 -- 0x1000029 0x0023 -- 0x100002b 0x000e -- 0x2000032 -- 0x1000020 0x0000 -- 0x1000021 0x0000 -- 0x2000032 -- 0x1000050 0x0000 -- 0x1000051 0x00ef -- 0x1000052 0x0000 -- 0x1000053 0x013f -- 0x1000060 0xa700 -- 0x1000061 0x0001 -- 0x100006a 0x0000 -- 0x1000080 0x0000 -- 0x1000081 0x0000 -- 0x1000082 0x0000 -- 0x1000083 0x0000 -- 0x1000084 0x0000 -- 0x1000085 0x0000 -- 0x1000090 0x0010 -- 0x1000092 0x0000 -- 0x1000093 0x0003 -- 0x1000095 0x0110 -- 0x1000097 0x0000 -- 0x1000098 0x0000 -- 0x1000007 0x0133 -- 0x1000020 0x0000 -- 0x1000021 0x0000 -- 0x2000064>; -- debug = <0>; -- }; -- -- hy28b_ts: hy28b-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <17 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 17 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&hy28b>,"spi-max-frequency:0"; -- rotate = <&hy28b>,"rotate:0"; -- fps = <&hy28b>,"fps:0"; -- debug = <&hy28b>,"debug:0"; -- xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; -- resetgpio = <&hy28b>,"reset-gpios:4", -- <&hy28b_pins>, "brcm,pins:1"; -- ledgpio = <&hy28b>,"led-gpios:4", -- <&hy28b_pins>, "brcm,pins:2"; -- }; --}; -diff --git a/arch/arm/boot/dts/i2c-rtc-overlay.dts b/arch/arm/boot/dts/i2c-rtc-overlay.dts -deleted file mode 100644 -index 5d5abb1..0000000 ---- a/arch/arm/boot/dts/i2c-rtc-overlay.dts -+++ /dev/null -@@ -1,43 +0,0 @@ --// Definitions for several I2C based Real Time Clocks --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -- reg = <0x68>; -- status = "disable"; -- }; -- ds3231: ds3231@68 { -- compatible = "maxim,ds3231"; -- reg = <0x68>; -- status = "disable"; -- }; -- pcf2127: pcf2127@51 { -- compatible = "nxp,pcf2127"; -- reg = <0x51>; -- status = "disable"; -- }; -- pcf8523: pcf8523@68 { -- compatible = "nxp,pcf8523"; -- reg = <0x68>; -- status = "disable"; -- }; -- }; -- }; -- __overrides__ { -- ds1307 = <&ds1307>,"status"; -- ds3231 = <&ds3231>,"status"; -- pcf2127 = <&pcf2127>,"status"; -- pcf8523 = <&pcf8523>,"status"; -- }; --}; -diff --git a/arch/arm/boot/dts/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/iqaudio-dac-overlay.dts -deleted file mode 100644 -index ea8173e..0000000 ---- a/arch/arm/boot/dts/iqaudio-dac-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for IQaudIO DAC --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "iqaudio,iqaudio-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcm5122@4c { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5122"; -- reg = <0x4c>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -deleted file mode 100644 -index 735d8ab..0000000 ---- a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for IQaudIO DAC+ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "iqaudio,iqaudio-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcm5122@4c { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5122"; -- reg = <0x4c>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/lirc-rpi-overlay.dts b/arch/arm/boot/dts/lirc-rpi-overlay.dts -deleted file mode 100644 -index 7d5d82b..0000000 ---- a/arch/arm/boot/dts/lirc-rpi-overlay.dts -+++ /dev/null -@@ -1,57 +0,0 @@ --// Definitions for lirc-rpi module --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- lirc_rpi: lirc_rpi { -- compatible = "rpi,lirc-rpi"; -- pinctrl-names = "default"; -- pinctrl-0 = <&lirc_pins>; -- status = "okay"; -- -- // Override autodetection of IR receiver circuit -- // (0 = active high, 1 = active low, -1 = no override ) -- rpi,sense = <0xffffffff>; -- -- // Software carrier -- // (0 = off, 1 = on) -- rpi,softcarrier = <1>; -- -- // Invert output -- // (0 = off, 1 = on) -- rpi,invert = <0>; -- -- // Enable debugging messages -- // (0 = off, 1 = on) -- rpi,debug = <0>; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- lirc_pins: lirc_pins { -- brcm,pins = <17 18>; -- brcm,function = <1 0>; // out in -- brcm,pull = <0 1>; // off down -- }; -- }; -- }; -- -- __overrides__ { -- gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; -- gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; -- gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; -- -- sense = <&lirc_rpi>,"rpi,sense:0"; -- softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; -- invert = <&lirc_rpi>,"rpi,invert:0"; -- debug = <&lirc_rpi>,"rpi,debug:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/mmc-overlay.dts b/arch/arm/boot/dts/mmc-overlay.dts -deleted file mode 100644 -index 0a37cf4..0000000 ---- a/arch/arm/boot/dts/mmc-overlay.dts -+++ /dev/null -@@ -1,19 +0,0 @@ --/dts-v1/; --/plugin/; -- --/{ -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&mmc>; -- -- __overlay__ { -- brcm,overclock-50 = <0>; -- }; -- }; -- -- __overrides__ { -- overclock_50 = <&mmc>,"brcm,overclock-50:0"; -- force_pio = <&mmc>,"brcm,force-pio?"; -- }; --}; -diff --git a/arch/arm/boot/dts/mz61581-overlay.dts b/arch/arm/boot/dts/mz61581-overlay.dts -deleted file mode 100644 -index c06fe12..0000000 ---- a/arch/arm/boot/dts/mz61581-overlay.dts -+++ /dev/null -@@ -1,109 +0,0 @@ --/* -- * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- mz61581_pins: mz61581_pins { -- brcm,pins = <4 15 18 25>; -- brcm,function = <0 1 1 1>; /* in out out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- mz61581: mz61581@0{ -- compatible = "samsung,s6d02a1"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&mz61581_pins>; -- -- spi-max-frequency = <128000000>; -- spi-cpol; -- spi-cpha; -- -- width = <320>; -- height = <480>; -- rotate = <270>; -- bgr; -- fps = <30>; -- buswidth = <8>; -- -- reset-gpios = <&gpio 15 0>; -- dc-gpios = <&gpio 25 0>; -- led-gpios = <&gpio 18 0>; -- -- init = <0x10000b0 00 -- 0x1000011 -- 0x20000ff -- 0x10000b3 0x02 0x00 0x00 0x00 -- 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 -- 0x10000c1 0x08 0x16 0x08 0x08 -- 0x10000c4 0x11 0x07 0x03 0x03 -- 0x10000c6 0x00 -- 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 -- 0x1000035 0x00 -- 0x1000036 0xa0 -- 0x100003a 0x55 -- 0x1000044 0x00 0x01 -- 0x10000d0 0x07 0x07 0x1d 0x03 -- 0x10000d1 0x03 0x30 0x10 -- 0x10000d2 0x03 0x14 0x04 -- 0x1000029 -- 0x100002c>; -- -- /* This is a workaround to make sure the init sequence slows down and doesn't fail */ -- debug = <3>; -- }; -- -- mz61581_ts: mz61581_ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <4 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 4 0>; -- -- ti,x-plate-ohms = /bits/ 16 <60>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&mz61581>, "spi-max-frequency:0"; -- rotate = <&mz61581>, "rotate:0"; -- fps = <&mz61581>, "fps:0"; -- debug = <&mz61581>, "debug:0"; -- xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; -- }; --}; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -new file mode 100644 -index 0000000..d64e6b4 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,51 @@ -+ifeq ($(CONFIG_OF),y) -+ -+# Overlays for the Raspberry Pi platform -+ -+ifeq ($(CONFIG_BCM2708_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ifeq ($(CONFIG_BCM2709_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ -+dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+ -+targets += dtbs dtbs_install -+targets += $(dtb-y) -+ -+endif -+ -+always := $(dtb-y) -+clean-files := *.dtb -+ -+# Enable fixups to support overlays on BCM2708 platforms -+ifeq ($(RPI_DT_OVERLAYS),y) -+ DTC_FLAGS ?= -@ -+endif -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -new file mode 100644 -index 0000000..c260612 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,470 @@ -+Introduction -+============ -+ -+This directory contains Device Tree overlays. Device Tree makes it possible -+to support many hardware configurations with a single kernel and without the -+need to explicitly load or blacklist kernel modules. Note that this isn't a -+"pure" Device Tree configuration (c.f. MACH_BCM2835) - some on-board devices -+are still configured by the board support code, but the intention is to -+eventually reach that goal. -+ -+On Raspberry Pi, Device Tree usage is controlled from /boot/config.txt. By -+default, the Raspberry Pi kernel boots with device tree enabled. You can -+completely disable DT usage (for now) by adding: -+ -+ device_tree= -+ -+to your config.txt, which should cause your Pi to revert to the old way of -+doing things after a reboot. -+ -+In /boot you will find a .dtb for each base platform. This describes the -+hardware that is part of the Raspberry Pi board. The loader (start.elf and its -+siblings) selects the .dtb file appropriate for the platform by name, and reads -+it into memory. At this point, all of the optional interfaces (i2c, i2s, spi) -+are disabled, but they can be enabled using Device Tree parameters: -+ -+ dtparam=i2c=on,i2s=on,spi=on -+ -+However, this shouldn't be necessary in many use cases because loading an -+overlay that requires one of those interfaces will cause it to be enabled -+automatically, and it is advisable to only enable interfaces if they are -+needed. -+ -+Configuring additional, optional hardware is done using Device Tree overlays -+(see below). -+ -+raspi-config -+============ -+ -+The Advanced Options section of the raspi-config utility can enable and disable -+Device Tree use, as well as toggling the I2C and SPI interfaces. Note that it -+is possible to both enable an interface and blacklist the driver, if for some -+reason you should want to defer the loading. -+ -+Modules -+======= -+ -+As well as describing the hardware, Device Tree also gives enough information -+to allow suitable driver modules to be located and loaded, with the corollary -+that unneeded modules are not loaded. As a result it should be possible to -+remove lines from /etc/modules, and /etc/modprobe.d/raspi-blacklist.conf can -+have its contents deleted (or commented out). -+ -+Using Overlays -+============== -+ -+Overlays are loaded using the "dtoverlay" directive. As an example, consider the -+popular lirc-rpi module, the Linux Infrared Remote Control driver. In the -+pre-DT world this would be loaded from /etc/modules, with an explicit -+"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, -+this becomes a line in config.txt: -+ -+ dtoverlay=lirc-rpi -+ -+This causes the file /boot/overlays/lirc-rpi-overlay.dtb to be loaded. By -+default it will use GPIOs 17 (out) and 18 (in), but this can be modified using -+DT parameters: -+ -+ dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 -+ -+Parameters always have default values, although in some cases (e.g. "w1-gpio") -+it is necessary to provided multiple overlays in order to get the desired -+behaviour. See the list of overlays below for a description of the parameters and their defaults. -+ -+The Overlay and Parameter Reference -+=================================== -+ -+Name: -+Info: Configures the base Raspberry Pi hardware -+Load: -+Params: -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") -+ -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") -+ -+ i2c An alias for i2c_arm -+ -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") -+ -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") -+ -+ i2c_baudrate An alias for i2c_arm_baudrate -+ -+ i2s Set to "on" to enable the i2s interface -+ (default "off") -+ -+ spi Set to "on" to enable the spi interfaces -+ (default "off") -+ -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") -+ -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) -+ -+ pwr_led_trigger -+ pwr_led_activelow -+ pwr_led_gpio -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. -+ -+ N.B. It is recommended to only enable those interfaces that are needed. -+ Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc -+ interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) -+ Note also that i2c, i2c_arm and i2c_vc are aliases for the physical -+ interfaces i2c0 and i2c1. Use of the numeric variants is still possible -+ but deprecated because the ARM/VC assignments differ between board -+ revisions. The same board-specific mapping applies to i2c_baudrate, -+ and the other i2c baudrate parameters. -+ -+ -+Name: ads7846 -+Info: ADS7846 Touch controller -+Load: dtoverlay=ads7846,= -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) -+ -+ penirq is required and usually xohms (60-100) has to be set as well. -+ Apart from that, pmax (255) and swapxy are also common. -+ The rest of the calibration can be done with xinput-calibrator. -+ See: github.com/notro/fbtft/wiki/FBTFT-on-Raspian -+ Device Tree binding document: -+ www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt -+ -+ -+Name: bmp085_i2c-sensor -+Info: Configures the BMP085/BMP180 digital barometric pressure and temperature -+ sensors from Bosch Sensortec -+Load: dtoverlay=bmp085_i2c-sensor -+Params: -+ -+ -+[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+Name: enc28j60 -+Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) -+Load: dtoverlay=enc28j60,= -+Params: int_pin GPIO used for INT (default 25) -+ -+ speed SPI bus speed (default 12000000) -+ -+ -+Name: hifiberry-amp -+Info: Configures the HifiBerry Amp and Amp+ audio cards -+Load: dtoverlay=hifiberry-amp -+Params: -+ -+ -+Name: hifiberry-dac -+Info: Configures the HifiBerry DAC audio card -+Load: dtoverlay=hifiberry-dac -+Params: -+ -+ -+Name: hifiberry-dacplus -+Info: Configures the HifiBerry DAC+ audio card -+Load: dtoverlay=hifiberry-dacplus -+Params: -+ -+ -+Name: hifiberry-digi -+Info: Configures the HifiBerry Digi audio card -+Load: dtoverlay=hifiberry-digi -+Params: -+ -+ -+Name: hy28a -+Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics -+ Default values match Texy's display shield -+Load: dtoverlay=hy28a,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ resetgpio GPIO used to reset controller -+ -+ ledgpio GPIO used to control backlight -+ -+ -+Name: hy28b -+Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics -+ Default values match Texy's display shield -+Load: dtoverlay=hy28b,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ resetgpio GPIO used to reset controller -+ -+ ledgpio GPIO used to control backlight -+ -+ -+Name: i2c-rtc -+Info: Adds support for a number of I2C Real Time Clock devices -+Load: dtoverlay=i2c-rtc, -+Params: ds1307 Select the DS1307 device -+ -+ ds3231 Select the DS3231 device -+ -+ pcf2127 Select the PCF2127 device -+ -+ pcf8523 Select the PCF8523 device -+ -+ pcf8563 Select the PCF8563 device -+ -+ -+Name: iqaudio-dac -+Info: Configures the IQaudio DAC audio card -+Load: dtoverlay=iqaudio-dac -+Params: -+ -+ -+Name: iqaudio-dacplus -+Info: Configures the IQaudio DAC+ audio card -+Load: dtoverlay=iqaudio-dacplus -+Params: -+ -+ -+Name: lirc-rpi -+Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) -+ Consult the module documentation for more details. -+Load: dtoverlay=lirc-rpi,=,... -+Params: gpio_out_pin GPIO for output (default "17") -+ -+ gpio_in_pin GPIO for input (default "18") -+ -+ gpio_in_pull Pull up/down/off on the input pin -+ (default "down") -+ -+ sense Override the IR receive auto-detection logic: -+ "1" = force active high -+ "0" = force active low -+ "-1" = use auto-detection -+ (default "-1") -+ -+ softcarrier Turn the software carrier "on" or "off" -+ (default "on") -+ -+ invert "on" = invert the output pin (default "off") -+ -+ debug "on" = enable additional debug messages -+ (default "off") -+ -+ -+Name: mmc -+Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock -+Load: dtoverlay=mmc,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support -+ -+ -+Name: mz61581 -+Info: MZ61581 display by Tontec -+Load: dtoverlay=mz61581,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ -+[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+[ The pcf8523-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+Name: piscreen -+Info: PiScreen display by OzzMaker.com -+Load: dtoverlay=piscreen,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ -+Name: pitft28-resistive -+Info: Adafruit PiTFT 2.8" resistive touch screen -+Load: dtoverlay=pitft28-resistive,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ -+Name: pps-gpio -+Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). -+Load: dtoverlay=pps-gpio,= -+Params: gpiopin Input GPIO (default "18") -+ -+ -+Name: rpi-dac -+Info: Configures the RPi DAC audio card -+Load: dtoverlay=rpi-dac -+Params: -+ -+ -+Name: rpi-display -+Info: RPi-Display - 2.8" Touch Display by Watterott -+Load: dtoverlay=rpi-display,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ -+Name: rpi-proto -+Info: Configures the RPi Proto audio card -+Load: dtoverlay=rpi-proto -+Params: -+ -+ -+Name: sdhost -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock -+Load: dtoverlay=sdhost,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support -+ -+ -+Name: spi-bcm2708 -+Info: Selects the bcm2708-spi SPI driver -+Load: dtoverlay=spi-bcm2708 -+Params: -+ -+ -+Name: spi-bcm2835 -+Info: Selects the bcm2835-spi SPI driver -+Load: dtoverlay=spi-bcm2835 -+Params: -+ -+ -+Name: tinylcd35 -+Info: 3.5" Color TFT Display by www.tinlylcd.com -+ Options: Touch, RTC, keypad -+Load: dtoverlay=tinylcd35,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ touch Enable touch panel -+ -+ touchgpio Touch controller IRQ GPIO -+ -+ xohms Touchpanel: Resistance of X-plate in ohms -+ -+ rtc-pcf PCF8563 Real Time Clock -+ -+ rtc-ds DS1307 Real Time Clock -+ -+ keypad Enable keypad -+ -+ Examples: -+ Display with touchpanel, PCF8563 RTC and keypad: -+ dtoverlay=tinylcd35,touch,rtc-pcf,keypad -+ Old touch display: -+ dtoverlay=tinylcd35,touch,touchgpio=3 -+ -+ -+Name: w1-gpio -+Info: Configures the w1-gpio Onewire interface module. -+ Use this overlay if you *don't* need a GPIO to drive an external pullup. -+Load: dtoverlay=w1-gpio,= -+Params: gpiopin GPIO for I/O (default "4") -+ -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature -+ -+ -+Name: w1-gpio-pullup -+Info: Configures the w1-gpio Onewire interface module. -+ Use this overlay if you *do* need a GPIO to drive an external pullup. -+Load: dtoverlay=w1-gpio-pullup,=,... -+Params: gpiopin GPIO for I/O (default "4") -+ -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature -+ -+ extpullup GPIO for external pullup (default "5") -+ -+ -+Troubleshooting -+=============== -+ -+If you are experiencing problems that you think are DT-related, enable DT -+diagnostic output by adding this to /boot/config.txt: -+ -+ dtdebug=on -+ -+and rebooting. Then run: -+ -+ sudo vcdbg log msg -+ -+and look for relevant messages. -+ -+Further reading -+=============== -+ -+This is only meant to be a quick introduction to the subject of Device Tree on -+Raspberry Pi. There is a more complete explanation here: -+ -+http://www.raspberrypi.org/documentation/configuration/device-tree.md -diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -new file mode 100644 -index 0000000..6a92cd1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -0,0 +1,83 @@ -+/* -+ * Generic Device Tree overlay for the ADS7846 touch controller -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ ads7846_pins: ads7846_pins { -+ brcm,pins = <255>; /* illegal default value */ -+ brcm,function = <0>; /* in */ -+ brcm,pull = <0>; /* none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ads7846: ads7846@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ads7846_pins>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <255 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 255 0>; -+ -+ /* driver defaults */ -+ ti,x-min = /bits/ 16 <0>; -+ ti,y-min = /bits/ 16 <0>; -+ ti,x-max = /bits/ 16 <0x0FFF>; -+ ti,y-max = /bits/ 16 <0x0FFF>; -+ ti,pressure-min = /bits/ 16 <0>; -+ ti,pressure-max = /bits/ 16 <0xFFFF>; -+ ti,x-plate-ohms = /bits/ 16 <400>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ cs = <&ads7846>,"reg:0"; -+ speed = <&ads7846>,"spi-max-frequency:0"; -+ penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ -+ <&ads7846>,"interrupts:0", -+ <&ads7846>,"pendown-gpio:4"; -+ penirq_pull = <&ads7846_pins>,"brcm,pull:0"; -+ swapxy = <&ads7846>,"ti,swap-xy?"; -+ xmin = <&ads7846>,"ti,x-min;0"; -+ ymin = <&ads7846>,"ti,y-min;0"; -+ xmax = <&ads7846>,"ti,x-max;0"; -+ ymax = <&ads7846>,"ti,y-max;0"; -+ pmin = <&ads7846>,"ti,pressure-min;0"; -+ pmax = <&ads7846>,"ti,pressure-max;0"; -+ xohms = <&ads7846>,"ti,x-plate-ohms;0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -new file mode 100644 -index 0000000..b830bf2 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -@@ -0,0 +1,23 @@ -+// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ bmp085@77 { -+ compatible = "bosch,bmp085"; -+ reg = <0x77>; -+ default-oversampling = <3>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts -new file mode 100644 -index 0000000..7d27044 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for DS1307 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -new file mode 100644 -index 0000000..aa9b645 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -0,0 +1,29 @@ -+// Overlay for the Microchip ENC28J60 Ethernet Controller -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ enc28j60@0{ -+ compatible = "microchip,enc28j60"; -+ reg = <0>; /* CE0 */ -+ spi-max-frequency = <12000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts -new file mode 100644 -index 0000000..2c81448 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Amp/Amp+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-amp"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ tas5713@1b { -+ #sound-dai-cells = <0>; -+ compatible = "ti,tas5713"; -+ reg = <0x1b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts -new file mode 100644 -index 0000000..5e7633a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for HiFiBerry DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm5102a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5102a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -new file mode 100644 -index 0000000..deb9c625 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dacplus"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts -new file mode 100644 -index 0000000..d0e0d8a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Digi -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-digi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8804@3b { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8804"; -+ reg = <0x3b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -new file mode 100644 -index 0000000..3cd3083 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -0,0 +1,87 @@ -+/* -+ * Device Tree overlay for HY28A display -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28a_pins: hy28a_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28a: hy28a@0{ -+ compatible = "ilitek,ili9320"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28a_pins>; -+ -+ spi-max-frequency = <32000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ hy28a_ts: hy28a-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28a>,"spi-max-frequency:0"; -+ rotate = <&hy28a>,"rotate:0"; -+ fps = <&hy28a>,"fps:0"; -+ debug = <&hy28a>,"debug:0"; -+ xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28a>,"reset-gpios:4", -+ <&hy28a_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28a>,"led-gpios:4", -+ <&hy28a_pins>, "brcm,pins:2"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -new file mode 100644 -index 0000000..f774c4a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -0,0 +1,142 @@ -+/* -+ * Device Tree overlay for HY28b display shield by Texy -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28b_pins: hy28b_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28b: hy28b@0{ -+ compatible = "ilitek,ili9325"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28b_pins>; -+ -+ spi-max-frequency = <48000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ -+ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -+ -+ init = <0x10000e7 0x0010 -+ 0x1000000 0x0001 -+ 0x1000001 0x0100 -+ 0x1000002 0x0700 -+ 0x1000003 0x1030 -+ 0x1000004 0x0000 -+ 0x1000008 0x0207 -+ 0x1000009 0x0000 -+ 0x100000a 0x0000 -+ 0x100000c 0x0001 -+ 0x100000d 0x0000 -+ 0x100000f 0x0000 -+ 0x1000010 0x0000 -+ 0x1000011 0x0007 -+ 0x1000012 0x0000 -+ 0x1000013 0x0000 -+ 0x2000032 -+ 0x1000010 0x1590 -+ 0x1000011 0x0227 -+ 0x2000032 -+ 0x1000012 0x009c -+ 0x2000032 -+ 0x1000013 0x1900 -+ 0x1000029 0x0023 -+ 0x100002b 0x000e -+ 0x2000032 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000032 -+ 0x1000050 0x0000 -+ 0x1000051 0x00ef -+ 0x1000052 0x0000 -+ 0x1000053 0x013f -+ 0x1000060 0xa700 -+ 0x1000061 0x0001 -+ 0x100006a 0x0000 -+ 0x1000080 0x0000 -+ 0x1000081 0x0000 -+ 0x1000082 0x0000 -+ 0x1000083 0x0000 -+ 0x1000084 0x0000 -+ 0x1000085 0x0000 -+ 0x1000090 0x0010 -+ 0x1000092 0x0000 -+ 0x1000093 0x0003 -+ 0x1000095 0x0110 -+ 0x1000097 0x0000 -+ 0x1000098 0x0000 -+ 0x1000007 0x0133 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000064>; -+ debug = <0>; -+ }; -+ -+ hy28b_ts: hy28b-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28b>,"spi-max-frequency:0"; -+ rotate = <&hy28b>,"rotate:0"; -+ fps = <&hy28b>,"fps:0"; -+ debug = <&hy28b>,"debug:0"; -+ xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28b>,"reset-gpios:4", -+ <&hy28b_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28b>,"led-gpios:4", -+ <&hy28b_pins>, "brcm,pins:2"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -new file mode 100644 -index 0000000..6bccfdc ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -0,0 +1,49 @@ -+// Definitions for several I2C based Real Time Clocks -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ ds3231: ds3231@68 { -+ compatible = "maxim,ds3231"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ pcf2127: pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "disable"; -+ }; -+ pcf8523: pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ pcf8563: pcf8563@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ status = "disable"; -+ }; -+ }; -+ }; -+ __overrides__ { -+ ds1307 = <&ds1307>,"status"; -+ ds3231 = <&ds3231>,"status"; -+ pcf2127 = <&pcf2127>,"status"; -+ pcf8523 = <&pcf8523>,"status"; -+ pcf8563 = <&pcf8563>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts -new file mode 100644 -index 0000000..ea8173e ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -new file mode 100644 -index 0000000..735d8ab ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts -new file mode 100644 -index 0000000..7d5d82b ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts -@@ -0,0 +1,57 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ lirc_rpi: lirc_rpi { -+ compatible = "rpi,lirc-rpi"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lirc_pins>; -+ status = "okay"; -+ -+ // Override autodetection of IR receiver circuit -+ // (0 = active high, 1 = active low, -1 = no override ) -+ rpi,sense = <0xffffffff>; -+ -+ // Software carrier -+ // (0 = off, 1 = on) -+ rpi,softcarrier = <1>; -+ -+ // Invert output -+ // (0 = off, 1 = on) -+ rpi,invert = <0>; -+ -+ // Enable debugging messages -+ // (0 = off, 1 = on) -+ rpi,debug = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lirc_pins: lirc_pins { -+ brcm,pins = <17 18>; -+ brcm,function = <1 0>; // out in -+ brcm,pull = <0 1>; // off down -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; -+ gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; -+ gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; -+ -+ sense = <&lirc_rpi>,"rpi,sense:0"; -+ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; -+ invert = <&lirc_rpi>,"rpi,invert:0"; -+ debug = <&lirc_rpi>,"rpi,debug:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts -new file mode 100644 -index 0000000..0a37cf4 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -0,0 +1,19 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&mmc>; -+ -+ __overlay__ { -+ brcm,overclock-50 = <0>; -+ }; -+ }; -+ -+ __overrides__ { -+ overclock_50 = <&mmc>,"brcm,overclock-50:0"; -+ force_pio = <&mmc>,"brcm,force-pio?"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -new file mode 100644 -index 0000000..c06fe12 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -0,0 +1,109 @@ -+/* -+ * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ mz61581_pins: mz61581_pins { -+ brcm,pins = <4 15 18 25>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mz61581: mz61581@0{ -+ compatible = "samsung,s6d02a1"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mz61581_pins>; -+ -+ spi-max-frequency = <128000000>; -+ spi-cpol; -+ spi-cpha; -+ -+ width = <320>; -+ height = <480>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ -+ reset-gpios = <&gpio 15 0>; -+ dc-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 0>; -+ -+ init = <0x10000b0 00 -+ 0x1000011 -+ 0x20000ff -+ 0x10000b3 0x02 0x00 0x00 0x00 -+ 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 -+ 0x10000c1 0x08 0x16 0x08 0x08 -+ 0x10000c4 0x11 0x07 0x03 0x03 -+ 0x10000c6 0x00 -+ 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 -+ 0x1000035 0x00 -+ 0x1000036 0xa0 -+ 0x100003a 0x55 -+ 0x1000044 0x00 0x01 -+ 0x10000d0 0x07 0x07 0x1d 0x03 -+ 0x10000d1 0x03 0x30 0x10 -+ 0x10000d2 0x03 0x14 0x04 -+ 0x1000029 -+ 0x100002c>; -+ -+ /* This is a workaround to make sure the init sequence slows down and doesn't fail */ -+ debug = <3>; -+ }; -+ -+ mz61581_ts: mz61581_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <4 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 4 0>; -+ -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&mz61581>, "spi-max-frequency:0"; -+ rotate = <&mz61581>, "rotate:0"; -+ fps = <&mz61581>, "fps:0"; -+ debug = <&mz61581>, "debug:0"; -+ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts b/arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts -new file mode 100644 -index 0000000..01fc81d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF2127 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts -new file mode 100644 -index 0000000..0071f62 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF8523 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -new file mode 100644 -index 0000000..b7fd7ea ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -0,0 +1,94 @@ -+/* -+ * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen_pins: piscreen_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen: piscreen@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen_pins>; -+ -+ spi-max-frequency = <24000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c2 0x44 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 -+ 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x1000011 -+ 0x1000029>; -+ }; -+ -+ piscreen-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen>,"spi-max-frequency:0"; -+ rotate = <&piscreen>,"rotate:0"; -+ fps = <&piscreen>,"fps:0"; -+ debug = <&piscreen>,"debug:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -new file mode 100644 -index 0000000..d506eae ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -0,0 +1,115 @@ -+/* -+ * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pitft_pins: pitft_pins { -+ brcm,pins = <24 25>; -+ brcm,function = <0 1>; /* in out */ -+ brcm,pull = <2 0>; /* pullup none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pitft: pitft@0{ -+ compatible = "ilitek,ili9340"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pitft_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <90>; -+ fps = <25>; -+ bgr; -+ buswidth = <8>; -+ dc-gpios = <&gpio 25 0>; -+ debug = <0>; -+ }; -+ -+ pitft_ts@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stmpe610"; -+ reg = <1>; -+ -+ spi-max-frequency = <500000>; -+ irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ -+ interrupts = <24 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ interrupt-controller; -+ -+ stmpe_touchscreen { -+ compatible = "st,stmpe-ts"; -+ st,sample-time = <4>; -+ st,mod-12b = <1>; -+ st,ref-sel = <0>; -+ st,adc-freq = <2>; -+ st,ave-ctrl = <3>; -+ st,touch-det-delay = <4>; -+ st,settling = <2>; -+ st,fraction-z = <7>; -+ st,i-drive = <0>; -+ }; -+ -+ stmpe_gpio: stmpe_gpio { -+ #gpio-cells = <2>; -+ compatible = "st,stmpe-gpio"; -+ /* -+ * only GPIO2 is wired/available -+ * and it is wired to the backlight -+ */ -+ st,norequest-mask = <0x7b>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/soc"; -+ __overlay__ { -+ backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&stmpe_gpio 2 0>; -+ default-on; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&pitft>,"spi-max-frequency:0"; -+ rotate = <&pitft>,"rotate:0"; -+ fps = <&pitft>,"fps:0"; -+ debug = <&pitft>,"debug:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts -new file mode 100644 -index 0000000..40bf0e1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts -@@ -0,0 +1,34 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ pps: pps { -+ compatible = "pps-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pps_pins>; -+ gpios = <&gpio 18 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pps_pins: pps_pins { -+ brcm,pins = <18>; -+ brcm,function = <0>; // in -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&pps>,"gpios:4", -+ <&pps_pins>,"brcm,pins:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts -new file mode 100644 -index 0000000..7fc6ac9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for RPi DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm1794a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm1794a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -new file mode 100644 -index 0000000..a8fa974 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -0,0 +1,82 @@ -+/* -+ * Device Tree overlay for rpi-display by Watterott -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ rpi_display_pins: rpi_display_pins { -+ brcm,pins = <18 23 24 25>; -+ brcm,function = <1 1 1 0>; /* out out out in */ -+ brcm,pull = <0 0 0 2>; /* - - - up */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rpidisplay: rpi-display@0{ -+ compatible = "ilitek,ili9341"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rpi_display_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ reset-gpios = <&gpio 23 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ rpidisplay_ts: rpi-display-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <25 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 25 0>; -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&rpidisplay>,"spi-max-frequency:0"; -+ rotate = <&rpidisplay>,"rotate:0"; -+ fps = <&rpidisplay>,"fps:0"; -+ debug = <&rpidisplay>,"debug:0"; -+ xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts -new file mode 100644 -index 0000000..2029930 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for Rpi-Proto -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-proto"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8731@1a { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8731"; -+ reg = <0x1a>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -new file mode 100644 -index 0000000..b2653e9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -0,0 +1,75 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sdhost: sdhost@7e202000 { -+ compatible = "brcm,bcm2835-sdhost"; -+ reg = <0x7e202000 0x100>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ interrupts = <2 24>; -+ clocks = <&clk_sdhost>; -+ dmas = <&dma 13>, -+ <&dma 13>; -+ dma-names = "tx", "rx"; -+ brcm,delay-after-stop = <0>; -+ brcm,overclock-50 = <0>; -+ status = "okay"; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_sdhost: clock@3 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mmc>; -+ __overlay__ { -+ /* Find a way to disable the other driver */ -+ compatible = ""; -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/__overrides__"; -+ __overlay__ { -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+ }; -+ -+ __overrides__ { -+ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; -+ force_pio = <&sdhost>,"brcm,force-pio?"; -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts -new file mode 100644 -index 0000000..e378ef1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2708-spi"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts -new file mode 100644 -index 0000000..fc1e39b ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2835-spi"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -new file mode 100644 -index 0000000..f7102c8 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -0,0 +1,216 @@ -+/* -+ * tinylcd35-overlay.dts -+ * -+ * ------------------------------------------------- -+ * www.tinlylcd.com -+ * ------------------------------------------------- -+ * Device---Driver-----BUS GPIO's -+ * display tinylcd35 spi0.0 25 24 18 -+ * touch ads7846 spi0.1 5 -+ * rtc ds1307 i2c1-0068 -+ * rtc pcf8563 i2c1-0051 -+ * keypad gpio-keys --------- 17 22 27 23 28 -+ * -+ * -+ * TinyLCD.com 3.5 inch TFT -+ * -+ * Version 001 -+ * 5/3/2015 -- Noralf Trønnes Initial Device tree framework -+ * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ tinylcd35_pins: tinylcd35_pins { -+ brcm,pins = <25 24 18>; -+ brcm,function = <1>; /* out */ -+ }; -+ tinylcd35_ts_pins: tinylcd35_ts_pins { -+ brcm,pins = <5>; -+ brcm,function = <0>; /* in */ -+ }; -+ keypad_pins: keypad_pins { -+ brcm,pins = <4 17 22 23 27>; -+ brcm,function = <0>; /* in */ -+ brcm,pull = <1>; /* down */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tinylcd35: tinylcd35@0{ -+ compatible = "neosec,tinylcd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&tinylcd35_pins>, -+ <&tinylcd35_ts_pins>; -+ -+ spi-max-frequency = <48000000>; -+ rotate = <270>; -+ fps = <20>; -+ bgr; -+ buswidth = <8>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ -+ init = <0x10000B0 0x80 -+ 0x10000C0 0x0A 0x0A -+ 0x10000C1 0x01 0x01 -+ 0x10000C2 0x33 -+ 0x10000C5 0x00 0x42 0x80 -+ 0x10000B1 0xD0 0x11 -+ 0x10000B4 0x02 -+ 0x10000B6 0x00 0x22 0x3B -+ 0x10000B7 0x07 -+ 0x1000036 0x58 -+ 0x10000F0 0x36 0xA5 0xD3 -+ 0x10000E5 0x80 -+ 0x10000E5 0x01 -+ 0x10000B3 0x00 -+ 0x10000E5 0x00 -+ 0x10000F0 0x36 0xA5 0x53 -+ 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 -+ 0x100003A 0x55 -+ 0x1000011 -+ 0x2000001 -+ 0x1000029>; -+ }; -+ -+ tinylcd35_ts: tinylcd35_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ status = "disabled"; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <5 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 5 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ -+ /* RTC */ -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pcf8563: pcf8563@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* -+ * Values for input event code is found under the -+ * 'Keys and buttons' heading in include/uapi/linux/input.h -+ */ -+ fragment@5 { -+ target-path = "/soc"; -+ __overlay__ { -+ keypad: keypad { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&keypad_pins>; -+ status = "disabled"; -+ autorepeat; -+ -+ button@17 { -+ label = "GPIO KEY_UP"; -+ linux,code = <103>; -+ gpios = <&gpio 17 0>; -+ }; -+ button@22 { -+ label = "GPIO KEY_DOWN"; -+ linux,code = <108>; -+ gpios = <&gpio 22 0>; -+ }; -+ button@27 { -+ label = "GPIO KEY_LEFT"; -+ linux,code = <105>; -+ gpios = <&gpio 27 0>; -+ }; -+ button@23 { -+ label = "GPIO KEY_RIGHT"; -+ linux,code = <106>; -+ gpios = <&gpio 23 0>; -+ }; -+ button@4 { -+ label = "GPIO KEY_ENTER"; -+ linux,code = <28>; -+ gpios = <&gpio 4 0>; -+ }; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&tinylcd35>,"spi-max-frequency:0"; -+ rotate = <&tinylcd35>,"rotate:0"; -+ fps = <&tinylcd35>,"fps:0"; -+ debug = <&tinylcd35>,"debug:0"; -+ touch = <&tinylcd35_ts>,"status"; -+ touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", -+ <&tinylcd35_ts>,"interrupts:0", -+ <&tinylcd35_ts>,"pendown-gpio:4"; -+ xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; -+ rtc-pcf = <&i2c1>,"status", -+ <&pcf8563>,"status"; -+ rtc-ds = <&i2c1>,"status", -+ <&ds1307>,"status"; -+ keypad = <&keypad>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -new file mode 100644 -index 0000000..29a3b48 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for w1-gpio module (without external pullup) -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>; -+ rpi,parasitic-power = <0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4>; -+ brcm,function = <0>; // in (initially) -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -new file mode 100644 -index 0000000..66a98f6 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -@@ -0,0 +1,41 @@ -+// Definitions for w1-gpio module (with external pullup) -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>, <&gpio 5 1>; -+ rpi,parasitic-power = <0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4 5>; -+ brcm,function = <0 1>; // in out -+ brcm,pull = <0 0>; // off off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ extpullup = <&w1>,"gpios:16", -+ <&w1_pins>,"brcm,pins:4"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/pcf2127-rtc-overlay.dts b/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -deleted file mode 100644 -index 01fc81d..0000000 ---- a/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -+++ /dev/null -@@ -1,22 +0,0 @@ --// Definitions for PCF2127 Real Time Clock --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcf2127@51 { -- compatible = "nxp,pcf2127"; -- reg = <0x51>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -deleted file mode 100644 -index 0071f62..0000000 ---- a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -+++ /dev/null -@@ -1,22 +0,0 @@ --// Definitions for PCF8523 Real Time Clock --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcf8523@68 { -- compatible = "nxp,pcf8523"; -- reg = <0x68>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/piscreen-overlay.dts b/arch/arm/boot/dts/piscreen-overlay.dts -deleted file mode 100644 -index b7fd7ea..0000000 ---- a/arch/arm/boot/dts/piscreen-overlay.dts -+++ /dev/null -@@ -1,94 +0,0 @@ --/* -- * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- piscreen_pins: piscreen_pins { -- brcm,pins = <17 25 24 22>; -- brcm,function = <0 1 1 1>; /* in out out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- piscreen: piscreen@0{ -- compatible = "ilitek,ili9486"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&piscreen_pins>; -- -- spi-max-frequency = <24000000>; -- rotate = <270>; -- bgr; -- fps = <30>; -- buswidth = <8>; -- regwidth = <16>; -- reset-gpios = <&gpio 25 0>; -- dc-gpios = <&gpio 24 0>; -- led-gpios = <&gpio 22 1>; -- debug = <0>; -- -- init = <0x10000b0 0x00 -- 0x1000011 -- 0x20000ff -- 0x100003a 0x55 -- 0x1000036 0x28 -- 0x10000c2 0x44 -- 0x10000c5 0x00 0x00 0x00 0x00 -- 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 -- 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -- 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -- 0x1000011 -- 0x1000029>; -- }; -- -- piscreen-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <17 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 17 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&piscreen>,"spi-max-frequency:0"; -- rotate = <&piscreen>,"rotate:0"; -- fps = <&piscreen>,"fps:0"; -- debug = <&piscreen>,"debug:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/pitft28-resistive-overlay.dts -deleted file mode 100644 -index d506eae..0000000 ---- a/arch/arm/boot/dts/pitft28-resistive-overlay.dts -+++ /dev/null -@@ -1,115 +0,0 @@ --/* -- * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- pitft_pins: pitft_pins { -- brcm,pins = <24 25>; -- brcm,function = <0 1>; /* in out */ -- brcm,pull = <2 0>; /* pullup none */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- pitft: pitft@0{ -- compatible = "ilitek,ili9340"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&pitft_pins>; -- -- spi-max-frequency = <32000000>; -- rotate = <90>; -- fps = <25>; -- bgr; -- buswidth = <8>; -- dc-gpios = <&gpio 25 0>; -- debug = <0>; -- }; -- -- pitft_ts@1 { -- #address-cells = <1>; -- #size-cells = <0>; -- compatible = "st,stmpe610"; -- reg = <1>; -- -- spi-max-frequency = <500000>; -- irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ -- interrupts = <24 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- interrupt-controller; -- -- stmpe_touchscreen { -- compatible = "st,stmpe-ts"; -- st,sample-time = <4>; -- st,mod-12b = <1>; -- st,ref-sel = <0>; -- st,adc-freq = <2>; -- st,ave-ctrl = <3>; -- st,touch-det-delay = <4>; -- st,settling = <2>; -- st,fraction-z = <7>; -- st,i-drive = <0>; -- }; -- -- stmpe_gpio: stmpe_gpio { -- #gpio-cells = <2>; -- compatible = "st,stmpe-gpio"; -- /* -- * only GPIO2 is wired/available -- * and it is wired to the backlight -- */ -- st,norequest-mask = <0x7b>; -- }; -- }; -- }; -- }; -- -- fragment@3 { -- target-path = "/soc"; -- __overlay__ { -- backlight { -- compatible = "gpio-backlight"; -- gpios = <&stmpe_gpio 2 0>; -- default-on; -- }; -- }; -- }; -- -- __overrides__ { -- speed = <&pitft>,"spi-max-frequency:0"; -- rotate = <&pitft>,"rotate:0"; -- fps = <&pitft>,"fps:0"; -- debug = <&pitft>,"debug:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/pps-gpio-overlay.dts b/arch/arm/boot/dts/pps-gpio-overlay.dts -deleted file mode 100644 -index 40bf0e1..0000000 ---- a/arch/arm/boot/dts/pps-gpio-overlay.dts -+++ /dev/null -@@ -1,34 +0,0 @@ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- pps: pps { -- compatible = "pps-gpio"; -- pinctrl-names = "default"; -- pinctrl-0 = <&pps_pins>; -- gpios = <&gpio 18 0>; -- status = "okay"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- pps_pins: pps_pins { -- brcm,pins = <18>; -- brcm,function = <0>; // in -- brcm,pull = <0>; // off -- }; -- }; -- }; -- -- __overrides__ { -- gpiopin = <&pps>,"gpios:4", -- <&pps_pins>,"brcm,pins:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/rpi-dac-overlay.dts b/arch/arm/boot/dts/rpi-dac-overlay.dts -deleted file mode 100644 -index 7fc6ac9..0000000 ---- a/arch/arm/boot/dts/rpi-dac-overlay.dts -+++ /dev/null -@@ -1,34 +0,0 @@ --// Definitions for RPi DAC --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "rpi,rpi-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target-path = "/"; -- __overlay__ { -- pcm1794a-codec { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm1794a"; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/rpi-display-overlay.dts b/arch/arm/boot/dts/rpi-display-overlay.dts -deleted file mode 100644 -index a8fa974..0000000 ---- a/arch/arm/boot/dts/rpi-display-overlay.dts -+++ /dev/null -@@ -1,82 +0,0 @@ --/* -- * Device Tree overlay for rpi-display by Watterott -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- rpi_display_pins: rpi_display_pins { -- brcm,pins = <18 23 24 25>; -- brcm,function = <1 1 1 0>; /* out out out in */ -- brcm,pull = <0 0 0 2>; /* - - - up */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- rpidisplay: rpi-display@0{ -- compatible = "ilitek,ili9341"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&rpi_display_pins>; -- -- spi-max-frequency = <32000000>; -- rotate = <270>; -- bgr; -- fps = <30>; -- buswidth = <8>; -- reset-gpios = <&gpio 23 0>; -- dc-gpios = <&gpio 24 0>; -- led-gpios = <&gpio 18 1>; -- debug = <0>; -- }; -- -- rpidisplay_ts: rpi-display-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <25 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 25 0>; -- ti,x-plate-ohms = /bits/ 16 <60>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&rpidisplay>,"spi-max-frequency:0"; -- rotate = <&rpidisplay>,"rotate:0"; -- fps = <&rpidisplay>,"fps:0"; -- debug = <&rpidisplay>,"debug:0"; -- xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -- }; --}; -diff --git a/arch/arm/boot/dts/rpi-proto-overlay.dts b/arch/arm/boot/dts/rpi-proto-overlay.dts -deleted file mode 100644 -index 2029930..0000000 ---- a/arch/arm/boot/dts/rpi-proto-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for Rpi-Proto --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "rpi,rpi-proto"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- wm8731@1a { -- #sound-dai-cells = <0>; -- compatible = "wlf,wm8731"; -- reg = <0x1a>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/sdhost-overlay.dts b/arch/arm/boot/dts/sdhost-overlay.dts -deleted file mode 100644 -index b2653e9..0000000 ---- a/arch/arm/boot/dts/sdhost-overlay.dts -+++ /dev/null -@@ -1,75 +0,0 @@ --/dts-v1/; --/plugin/; -- --/{ -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&soc>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <1>; -- -- sdhost: sdhost@7e202000 { -- compatible = "brcm,bcm2835-sdhost"; -- reg = <0x7e202000 0x100>; -- pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_pins>; -- interrupts = <2 24>; -- clocks = <&clk_sdhost>; -- dmas = <&dma 13>, -- <&dma 13>; -- dma-names = "tx", "rx"; -- brcm,delay-after-stop = <0>; -- brcm,overclock-50 = <0>; -- status = "okay"; -- }; -- -- clocks { -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_sdhost: clock@3 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "sdhost"; -- clock-frequency = <250000000>; -- }; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- sdhost_pins: sdhost_pins { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <4>; /* alt0 */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&mmc>; -- __overlay__ { -- /* Find a way to disable the other driver */ -- compatible = ""; -- status = "disabled"; -- }; -- }; -- -- fragment@3 { -- target-path = "/__overrides__"; -- __overlay__ { -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -- }; -- }; -- -- __overrides__ { -- delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -- overclock_50 = <&sdhost>,"brcm,overclock-50:0"; -- force_pio = <&sdhost>,"brcm,force-pio?"; -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/spi-bcm2708-overlay.dts -deleted file mode 100644 -index e378ef1..0000000 ---- a/arch/arm/boot/dts/spi-bcm2708-overlay.dts -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- * Device tree overlay for spi-bcm2835 -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -- /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- compatible = "brcm,bcm2708-spi"; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/spi-bcm2835-overlay.dts -deleted file mode 100644 -index fc1e39b..0000000 ---- a/arch/arm/boot/dts/spi-bcm2835-overlay.dts -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- * Device tree overlay for spi-bcm2835 -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -- /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- compatible = "brcm,bcm2835-spi"; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/tinylcd35-overlay.dts b/arch/arm/boot/dts/tinylcd35-overlay.dts -deleted file mode 100644 -index f7102c8..0000000 ---- a/arch/arm/boot/dts/tinylcd35-overlay.dts -+++ /dev/null -@@ -1,216 +0,0 @@ --/* -- * tinylcd35-overlay.dts -- * -- * ------------------------------------------------- -- * www.tinlylcd.com -- * ------------------------------------------------- -- * Device---Driver-----BUS GPIO's -- * display tinylcd35 spi0.0 25 24 18 -- * touch ads7846 spi0.1 5 -- * rtc ds1307 i2c1-0068 -- * rtc pcf8563 i2c1-0051 -- * keypad gpio-keys --------- 17 22 27 23 28 -- * -- * -- * TinyLCD.com 3.5 inch TFT -- * -- * Version 001 -- * 5/3/2015 -- Noralf Trønnes Initial Device tree framework -- * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- tinylcd35_pins: tinylcd35_pins { -- brcm,pins = <25 24 18>; -- brcm,function = <1>; /* out */ -- }; -- tinylcd35_ts_pins: tinylcd35_ts_pins { -- brcm,pins = <5>; -- brcm,function = <0>; /* in */ -- }; -- keypad_pins: keypad_pins { -- brcm,pins = <4 17 22 23 27>; -- brcm,function = <0>; /* in */ -- brcm,pull = <1>; /* down */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- tinylcd35: tinylcd35@0{ -- compatible = "neosec,tinylcd"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&tinylcd35_pins>, -- <&tinylcd35_ts_pins>; -- -- spi-max-frequency = <48000000>; -- rotate = <270>; -- fps = <20>; -- bgr; -- buswidth = <8>; -- reset-gpios = <&gpio 25 0>; -- dc-gpios = <&gpio 24 0>; -- led-gpios = <&gpio 18 1>; -- debug = <0>; -- -- init = <0x10000B0 0x80 -- 0x10000C0 0x0A 0x0A -- 0x10000C1 0x01 0x01 -- 0x10000C2 0x33 -- 0x10000C5 0x00 0x42 0x80 -- 0x10000B1 0xD0 0x11 -- 0x10000B4 0x02 -- 0x10000B6 0x00 0x22 0x3B -- 0x10000B7 0x07 -- 0x1000036 0x58 -- 0x10000F0 0x36 0xA5 0xD3 -- 0x10000E5 0x80 -- 0x10000E5 0x01 -- 0x10000B3 0x00 -- 0x10000E5 0x00 -- 0x10000F0 0x36 0xA5 0x53 -- 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 -- 0x100003A 0x55 -- 0x1000011 -- 0x2000001 -- 0x1000029>; -- }; -- -- tinylcd35_ts: tinylcd35_ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- status = "disabled"; -- -- spi-max-frequency = <2000000>; -- interrupts = <5 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 5 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- -- /* RTC */ -- -- fragment@3 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- -- pcf8563: pcf8563@51 { -- compatible = "nxp,pcf8563"; -- reg = <0x51>; -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@4 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- -- ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -- reg = <0x68>; -- status = "disabled"; -- }; -- }; -- }; -- -- /* -- * Values for input event code is found under the -- * 'Keys and buttons' heading in include/uapi/linux/input.h -- */ -- fragment@5 { -- target-path = "/soc"; -- __overlay__ { -- keypad: keypad { -- compatible = "gpio-keys"; -- #address-cells = <1>; -- #size-cells = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&keypad_pins>; -- status = "disabled"; -- autorepeat; -- -- button@17 { -- label = "GPIO KEY_UP"; -- linux,code = <103>; -- gpios = <&gpio 17 0>; -- }; -- button@22 { -- label = "GPIO KEY_DOWN"; -- linux,code = <108>; -- gpios = <&gpio 22 0>; -- }; -- button@27 { -- label = "GPIO KEY_LEFT"; -- linux,code = <105>; -- gpios = <&gpio 27 0>; -- }; -- button@23 { -- label = "GPIO KEY_RIGHT"; -- linux,code = <106>; -- gpios = <&gpio 23 0>; -- }; -- button@4 { -- label = "GPIO KEY_ENTER"; -- linux,code = <28>; -- gpios = <&gpio 4 0>; -- }; -- }; -- }; -- }; -- -- __overrides__ { -- speed = <&tinylcd35>,"spi-max-frequency:0"; -- rotate = <&tinylcd35>,"rotate:0"; -- fps = <&tinylcd35>,"fps:0"; -- debug = <&tinylcd35>,"debug:0"; -- touch = <&tinylcd35_ts>,"status"; -- touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", -- <&tinylcd35_ts>,"interrupts:0", -- <&tinylcd35_ts>,"pendown-gpio:4"; -- xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; -- rtc-pcf = <&i2c1>,"status", -- <&pcf8563>,"status"; -- rtc-ds = <&i2c1>,"status", -- <&ds1307>,"status"; -- keypad = <&keypad>,"status"; -- }; --}; -diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts -deleted file mode 100644 -index 29a3b48..0000000 ---- a/arch/arm/boot/dts/w1-gpio-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for w1-gpio module (without external pullup) --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- -- w1: onewire@0 { -- compatible = "w1-gpio"; -- pinctrl-names = "default"; -- pinctrl-0 = <&w1_pins>; -- gpios = <&gpio 4 0>; -- rpi,parasitic-power = <0>; -- status = "okay"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- w1_pins: w1_pins { -- brcm,pins = <4>; -- brcm,function = <0>; // in (initially) -- brcm,pull = <0>; // off -- }; -- }; -- }; -- -- __overrides__ { -- gpiopin = <&w1>,"gpios:4", -- <&w1_pins>,"brcm,pins:0"; -- pullup = <&w1>,"rpi,parasitic-power:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -deleted file mode 100644 -index 66a98f6..0000000 ---- a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -+++ /dev/null -@@ -1,41 +0,0 @@ --// Definitions for w1-gpio module (with external pullup) --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- -- w1: onewire@0 { -- compatible = "w1-gpio"; -- pinctrl-names = "default"; -- pinctrl-0 = <&w1_pins>; -- gpios = <&gpio 4 0>, <&gpio 5 1>; -- rpi,parasitic-power = <0>; -- status = "okay"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- w1_pins: w1_pins { -- brcm,pins = <4 5>; -- brcm,function = <0 1>; // in out -- brcm,pull = <0 0>; // off off -- }; -- }; -- }; -- -- __overrides__ { -- gpiopin = <&w1>,"gpios:4", -- <&w1_pins>,"brcm,pins:0"; -- extpullup = <&w1>,"gpios:16", -- <&w1_pins>,"brcm,pins:4"; -- pullup = <&w1>,"rpi,parasitic-power:0"; -- }; --}; - -From 9c2920928cae9f7d35cb3c0e4f677b7f266a7ae3 Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Fri, 3 Apr 2015 12:40:10 +0000 -Subject: [PATCH 192/216] Swap X Y axis of ads7846 touchscreen controller for - PiScreen TFT - ---- - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -index b7fd7ea..be1e2ec 100644 ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -80,6 +80,7 @@ - interrupts = <17 2>; /* high-to-low edge triggered */ - interrupt-parent = <&gpio>; - pendown-gpio = <&gpio 17 0>; -+ ti,swap-xy; - ti,x-plate-ohms = /bits/ 16 <100>; - ti,pressure-max = /bits/ 16 <255>; - }; - -From a4d119709c817d2bf6caea401b8266f55ad861c2 Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Wed, 8 Apr 2015 01:13:47 +0000 -Subject: [PATCH 193/216] Added optional parameter to set resistance of touch - plate(x-plate-ohms) - ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 3 ++- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index c260612..9d4f283 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -329,6 +329,8 @@ Params: speed Display SPI bus speed - - debug Debug output level {0-7} - -+ xohms Touchpanel sensitivity (X-plate resistance) -+ - - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -index be1e2ec..ba4ad33 100644 ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -72,7 +72,7 @@ - 0x1000029>; - }; - -- piscreen-ts@1 { -+ piscreen_ts: piscreen-ts@1 { - compatible = "ti,ads7846"; - reg = <1>; - -@@ -91,5 +91,6 @@ - rotate = <&piscreen>,"rotate:0"; - fps = <&piscreen>,"fps:0"; - debug = <&piscreen>,"debug:0"; -+ xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; - }; - }; - -From df11ad948112ccee4eae40b6f4810946a8dc5019 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 28 May 2015 18:50:21 +0200 -Subject: [PATCH 194/216] BCM270x: Move vc_mem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make the vc_mem module available for ARCH_BCM2835 by moving it. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/Kconfig | 7 - - arch/arm/mach-bcm2708/Makefile | 1 - - arch/arm/mach-bcm2708/include/mach/vc_mem.h | 35 --- - arch/arm/mach-bcm2708/vc_mem.c | 431 ---------------------------- - arch/arm/mach-bcm2709/Kconfig | 7 - - arch/arm/mach-bcm2709/Makefile | 1 - - arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 --- - arch/arm/mach-bcm2709/vc_mem.c | 431 ---------------------------- - drivers/char/broadcom/Kconfig | 13 +- - drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/vc_mem.c | 423 +++++++++++++++++++++++++++ - drivers/char/broadcom/vc_sm/vmcs_sm.c | 3 +- - include/linux/broadcom/vc_mem.h | 35 +++ - 13 files changed, 472 insertions(+), 951 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/vc_mem.h - delete mode 100644 arch/arm/mach-bcm2708/vc_mem.c - delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h - delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c - create mode 100644 drivers/char/broadcom/vc_mem.c - create mode 100644 include/linux/broadcom/vc_mem.h - -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 4cfae55..68e3706 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -28,13 +28,6 @@ config BCM2708_GPIO - help - Include support for the Broadcom(R) BCM2708 gpio. - --config BCM2708_VCMEM -- bool "Videocore Memory" -- depends on MACH_BCM2708 -- default y -- help -- Helper for videocore memory access and total size allocation. -- - config BCM2708_NOL2CACHE - bool "Videocore L2 cache disable" - depends on MACH_BCM2708 -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index 5552ae8..5120994 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -4,4 +4,3 @@ - - obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o --obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h -deleted file mode 100644 -index 4a4a338..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/vc_mem.h -+++ /dev/null -@@ -1,35 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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. --*****************************************************************************/ -- --#if !defined( VC_MEM_H ) --#define VC_MEM_H -- --#include -- --#define VC_MEM_IOC_MAGIC 'v' -- --#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 ) --#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -- --#if defined( __KERNEL__ ) --#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -- --extern unsigned long mm_vc_mem_phys_addr; --extern unsigned int mm_vc_mem_size; --extern int vc_mem_get_current_size( void ); --#endif -- --#endif /* VC_MEM_H */ -diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c -deleted file mode 100644 -index 226b737..0000000 ---- a/arch/arm/mach-bcm2708/vc_mem.c -+++ /dev/null -@@ -1,431 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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 -- --#ifdef CONFIG_ARCH_KONA --#include --#elif CONFIG_ARCH_BCM2708 --#else --#include --#endif -- --#include "mach/vc_mem.h" -- --#define DRIVER_NAME "vc-mem" -- --// Device (/dev) related variables --static dev_t vc_mem_devnum = 0; --static struct class *vc_mem_class = NULL; --static struct cdev vc_mem_cdev; --static int vc_mem_inited = 0; -- --#ifdef CONFIG_DEBUG_FS --static struct dentry *vc_mem_debugfs_entry; --#endif -- --/* -- * Videocore memory addresses and size -- * -- * Drivers that wish to know the videocore memory addresses and sizes should -- * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -- * headers. This allows the other drivers to not be tied down to a a certain -- * address/size at compile time. -- * -- * In the future, the goal is to have the videocore memory virtual address and -- * size be calculated at boot time rather than at compile time. The decision of -- * where the videocore memory resides and its size would be in the hands of the -- * bootloader (and/or kernel). When that happens, the values of these variables -- * would be calculated and assigned in the init function. -- */ --// in the 2835 VC in mapped above ARM, but ARM has full access to VC space --unsigned long mm_vc_mem_phys_addr = 0x00000000; --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); -- --static uint phys_addr = 0; --static uint mem_size = 0; --static uint mem_base = 0; -- -- --/**************************************************************************** --* --* vc_mem_open --* --***************************************************************************/ -- --static int --vc_mem_open(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_release --* --***************************************************************************/ -- --static int --vc_mem_release(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_get_size --* --***************************************************************************/ -- --static void --vc_mem_get_size(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_base --* --***************************************************************************/ -- --static void --vc_mem_get_base(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_current_size --* --***************************************************************************/ -- --int --vc_mem_get_current_size(void) --{ -- return mm_vc_mem_size; --} -- --EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -- --/**************************************************************************** --* --* vc_mem_ioctl --* --***************************************************************************/ -- --static long --vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) --{ -- int rc = 0; -- -- (void) cmd; -- (void) arg; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- switch (cmd) { -- case VC_MEM_IOC_MEM_PHYS_ADDR: -- { -- pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -- __func__, (void *) mm_vc_mem_phys_addr); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -- sizeof (mm_vc_mem_phys_addr)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_SIZE: -- { -- // Get the videocore memory size first -- vc_mem_get_size(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -- mm_vc_mem_size); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_size, -- sizeof (mm_vc_mem_size)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_BASE: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -- mm_vc_mem_base); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_base, -- sizeof (mm_vc_mem_base)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_LOAD: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -- { -- return -ENOTTY; -- } -- } -- pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -- -- return rc; --} -- --/**************************************************************************** --* --* vc_mem_mmap --* --***************************************************************************/ -- --static int --vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) --{ -- int rc = 0; -- unsigned long length = vma->vm_end - vma->vm_start; -- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -- -- pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -- __func__, (long) vma->vm_start, (long) vma->vm_end, -- (long) vma->vm_pgoff); -- -- if (offset + length > mm_vc_mem_size) { -- pr_err("%s: length %ld is too big\n", __func__, length); -- return -EINVAL; -- } -- // Do not cache the memory map -- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -- -- rc = remap_pfn_range(vma, vma->vm_start, -- (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -- vma->vm_pgoff, length, vma->vm_page_prot); -- if (rc != 0) { -- pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -- } -- -- return rc; --} -- --/**************************************************************************** --* --* File Operations for the driver. --* --***************************************************************************/ -- --static const struct file_operations vc_mem_fops = { -- .owner = THIS_MODULE, -- .open = vc_mem_open, -- .release = vc_mem_release, -- .unlocked_ioctl = vc_mem_ioctl, -- .mmap = vc_mem_mmap, --}; -- --#ifdef CONFIG_DEBUG_FS --static void vc_mem_debugfs_deinit(void) --{ -- debugfs_remove_recursive(vc_mem_debugfs_entry); -- vc_mem_debugfs_entry = NULL; --} -- -- --static int vc_mem_debugfs_init( -- struct device *dev) --{ -- vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -- if (!vc_mem_debugfs_entry) { -- dev_warn(dev, "could not create debugfs entry\n"); -- return -EFAULT; -- } -- -- if (!debugfs_create_x32("vc_mem_phys_addr", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_phys_addr)) { -- dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_size", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_size)) { -- dev_warn(dev, "%s:could not create vc_mem_size entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_base", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_base)) { -- dev_warn(dev, "%s:could not create vc_mem_base entry\n", -- __func__); -- goto fail; -- } -- -- return 0; -- --fail: -- vc_mem_debugfs_deinit(); -- return -EFAULT; --} -- --#endif /* CONFIG_DEBUG_FS */ -- -- --/**************************************************************************** --* --* vc_mem_init --* --***************************************************************************/ -- --static int __init --vc_mem_init(void) --{ -- int rc = -EFAULT; -- struct device *dev; -- -- pr_debug("%s: called\n", __func__); -- -- mm_vc_mem_phys_addr = phys_addr; -- mm_vc_mem_size = mem_size; -- mm_vc_mem_base = mem_base; -- -- vc_mem_get_size(); -- -- pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -- -- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -- pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -- __func__, rc); -- goto out_err; -- } -- -- cdev_init(&vc_mem_cdev, &vc_mem_fops); -- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -- pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -- goto out_unregister; -- } -- -- vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vc_mem_class)) { -- rc = PTR_ERR(vc_mem_class); -- pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -- goto out_cdev_del; -- } -- -- dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -- DRIVER_NAME); -- if (IS_ERR(dev)) { -- rc = PTR_ERR(dev); -- pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -- goto out_class_destroy; -- } -- --#ifdef CONFIG_DEBUG_FS -- /* don't fail if the debug entries cannot be created */ -- vc_mem_debugfs_init(dev); --#endif -- -- vc_mem_inited = 1; -- return 0; -- -- device_destroy(vc_mem_class, vc_mem_devnum); -- -- out_class_destroy: -- class_destroy(vc_mem_class); -- vc_mem_class = NULL; -- -- out_cdev_del: -- cdev_del(&vc_mem_cdev); -- -- out_unregister: -- unregister_chrdev_region(vc_mem_devnum, 1); -- -- out_err: -- return -1; --} -- --/**************************************************************************** --* --* vc_mem_exit --* --***************************************************************************/ -- --static void __exit --vc_mem_exit(void) --{ -- pr_debug("%s: called\n", __func__); -- -- if (vc_mem_inited) { --#if CONFIG_DEBUG_FS -- vc_mem_debugfs_deinit(); --#endif -- device_destroy(vc_mem_class, vc_mem_devnum); -- class_destroy(vc_mem_class); -- cdev_del(&vc_mem_cdev); -- unregister_chrdev_region(vc_mem_devnum, 1); -- } --} -- --module_init(vc_mem_init); --module_exit(vc_mem_exit); --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Broadcom Corporation"); -- --module_param(phys_addr, uint, 0644); --module_param(mem_size, uint, 0644); --module_param(mem_base, uint, 0644); -diff --git a/arch/arm/mach-bcm2709/Kconfig b/arch/arm/mach-bcm2709/Kconfig -index 4fb6e1b..d61ade0 100644 ---- a/arch/arm/mach-bcm2709/Kconfig -+++ b/arch/arm/mach-bcm2709/Kconfig -@@ -25,13 +25,6 @@ config BCM2708_GPIO - help - Include support for the Broadcom(R) BCM2709 gpio. - --config BCM2708_VCMEM -- bool "Videocore Memory" -- depends on MACH_BCM2709 -- default y -- help -- Helper for videocore memory access and total size allocation. -- - config BCM2708_NOL2CACHE - bool "Videocore L2 cache disable" - depends on MACH_BCM2709 -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index 706116f..1ae8b80 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -4,4 +4,3 @@ - - obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o --obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/include/mach/vc_mem.h b/arch/arm/mach-bcm2709/include/mach/vc_mem.h -deleted file mode 100644 -index 4a4a338..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/vc_mem.h -+++ /dev/null -@@ -1,35 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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. --*****************************************************************************/ -- --#if !defined( VC_MEM_H ) --#define VC_MEM_H -- --#include -- --#define VC_MEM_IOC_MAGIC 'v' -- --#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 ) --#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -- --#if defined( __KERNEL__ ) --#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -- --extern unsigned long mm_vc_mem_phys_addr; --extern unsigned int mm_vc_mem_size; --extern int vc_mem_get_current_size( void ); --#endif -- --#endif /* VC_MEM_H */ -diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c -deleted file mode 100644 -index d2adfd1..0000000 ---- a/arch/arm/mach-bcm2709/vc_mem.c -+++ /dev/null -@@ -1,431 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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 -- --#ifdef CONFIG_ARCH_KONA --#include --#elif defined(CONFIG_ARCH_BCM2708) || defined(CONFIG_ARCH_BCM2709) --#else --#include --#endif -- --#include "mach/vc_mem.h" -- --#define DRIVER_NAME "vc-mem" -- --// Device (/dev) related variables --static dev_t vc_mem_devnum = 0; --static struct class *vc_mem_class = NULL; --static struct cdev vc_mem_cdev; --static int vc_mem_inited = 0; -- --#ifdef CONFIG_DEBUG_FS --static struct dentry *vc_mem_debugfs_entry; --#endif -- --/* -- * Videocore memory addresses and size -- * -- * Drivers that wish to know the videocore memory addresses and sizes should -- * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -- * headers. This allows the other drivers to not be tied down to a a certain -- * address/size at compile time. -- * -- * In the future, the goal is to have the videocore memory virtual address and -- * size be calculated at boot time rather than at compile time. The decision of -- * where the videocore memory resides and its size would be in the hands of the -- * bootloader (and/or kernel). When that happens, the values of these variables -- * would be calculated and assigned in the init function. -- */ --// in the 2835 VC in mapped above ARM, but ARM has full access to VC space --unsigned long mm_vc_mem_phys_addr = 0x00000000; --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); -- --static uint phys_addr = 0; --static uint mem_size = 0; --static uint mem_base = 0; -- -- --/**************************************************************************** --* --* vc_mem_open --* --***************************************************************************/ -- --static int --vc_mem_open(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_release --* --***************************************************************************/ -- --static int --vc_mem_release(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_get_size --* --***************************************************************************/ -- --static void --vc_mem_get_size(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_base --* --***************************************************************************/ -- --static void --vc_mem_get_base(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_current_size --* --***************************************************************************/ -- --int --vc_mem_get_current_size(void) --{ -- return mm_vc_mem_size; --} -- --EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -- --/**************************************************************************** --* --* vc_mem_ioctl --* --***************************************************************************/ -- --static long --vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) --{ -- int rc = 0; -- -- (void) cmd; -- (void) arg; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- switch (cmd) { -- case VC_MEM_IOC_MEM_PHYS_ADDR: -- { -- pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -- __func__, (void *) mm_vc_mem_phys_addr); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -- sizeof (mm_vc_mem_phys_addr)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_SIZE: -- { -- // Get the videocore memory size first -- vc_mem_get_size(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -- mm_vc_mem_size); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_size, -- sizeof (mm_vc_mem_size)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_BASE: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -- mm_vc_mem_base); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_base, -- sizeof (mm_vc_mem_base)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_LOAD: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -- { -- return -ENOTTY; -- } -- } -- pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -- -- return rc; --} -- --/**************************************************************************** --* --* vc_mem_mmap --* --***************************************************************************/ -- --static int --vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) --{ -- int rc = 0; -- unsigned long length = vma->vm_end - vma->vm_start; -- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -- -- pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -- __func__, (long) vma->vm_start, (long) vma->vm_end, -- (long) vma->vm_pgoff); -- -- if (offset + length > mm_vc_mem_size) { -- pr_err("%s: length %ld is too big\n", __func__, length); -- return -EINVAL; -- } -- // Do not cache the memory map -- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -- -- rc = remap_pfn_range(vma, vma->vm_start, -- (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -- vma->vm_pgoff, length, vma->vm_page_prot); -- if (rc != 0) { -- pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -- } -- -- return rc; --} -- --/**************************************************************************** --* --* File Operations for the driver. --* --***************************************************************************/ -- --static const struct file_operations vc_mem_fops = { -- .owner = THIS_MODULE, -- .open = vc_mem_open, -- .release = vc_mem_release, -- .unlocked_ioctl = vc_mem_ioctl, -- .mmap = vc_mem_mmap, --}; -- --#ifdef CONFIG_DEBUG_FS --static void vc_mem_debugfs_deinit(void) --{ -- debugfs_remove_recursive(vc_mem_debugfs_entry); -- vc_mem_debugfs_entry = NULL; --} -- -- --static int vc_mem_debugfs_init( -- struct device *dev) --{ -- vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -- if (!vc_mem_debugfs_entry) { -- dev_warn(dev, "could not create debugfs entry\n"); -- return -EFAULT; -- } -- -- if (!debugfs_create_x32("vc_mem_phys_addr", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_phys_addr)) { -- dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_size", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_size)) { -- dev_warn(dev, "%s:could not create vc_mem_size entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_base", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_base)) { -- dev_warn(dev, "%s:could not create vc_mem_base entry\n", -- __func__); -- goto fail; -- } -- -- return 0; -- --fail: -- vc_mem_debugfs_deinit(); -- return -EFAULT; --} -- --#endif /* CONFIG_DEBUG_FS */ -- -- --/**************************************************************************** --* --* vc_mem_init --* --***************************************************************************/ -- --static int __init --vc_mem_init(void) --{ -- int rc = -EFAULT; -- struct device *dev; -- -- pr_debug("%s: called\n", __func__); -- -- mm_vc_mem_phys_addr = phys_addr; -- mm_vc_mem_size = mem_size; -- mm_vc_mem_base = mem_base; -- -- vc_mem_get_size(); -- -- pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -- -- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -- pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -- __func__, rc); -- goto out_err; -- } -- -- cdev_init(&vc_mem_cdev, &vc_mem_fops); -- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -- pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -- goto out_unregister; -- } -- -- vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vc_mem_class)) { -- rc = PTR_ERR(vc_mem_class); -- pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -- goto out_cdev_del; -- } -- -- dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -- DRIVER_NAME); -- if (IS_ERR(dev)) { -- rc = PTR_ERR(dev); -- pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -- goto out_class_destroy; -- } -- --#ifdef CONFIG_DEBUG_FS -- /* don't fail if the debug entries cannot be created */ -- vc_mem_debugfs_init(dev); --#endif -- -- vc_mem_inited = 1; -- return 0; -- -- device_destroy(vc_mem_class, vc_mem_devnum); -- -- out_class_destroy: -- class_destroy(vc_mem_class); -- vc_mem_class = NULL; -- -- out_cdev_del: -- cdev_del(&vc_mem_cdev); -- -- out_unregister: -- unregister_chrdev_region(vc_mem_devnum, 1); -- -- out_err: -- return -1; --} -- --/**************************************************************************** --* --* vc_mem_exit --* --***************************************************************************/ -- --static void __exit --vc_mem_exit(void) --{ -- pr_debug("%s: called\n", __func__); -- -- if (vc_mem_inited) { --#if CONFIG_DEBUG_FS -- vc_mem_debugfs_deinit(); --#endif -- device_destroy(vc_mem_class, vc_mem_devnum); -- class_destroy(vc_mem_class); -- cdev_del(&vc_mem_cdev); -- unregister_chrdev_region(vc_mem_devnum, 1); -- } --} -- --module_init(vc_mem_init); --module_exit(vc_mem_exit); --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Broadcom Corporation"); -- --module_param(phys_addr, uint, 0644); --module_param(mem_size, uint, 0644); --module_param(mem_base, uint, 0644); -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index fd23e00..c310d9d 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -7,16 +7,27 @@ menuconfig BRCM_CHAR_DRIVERS - help - Broadcom's char drivers - -+if BRCM_CHAR_DRIVERS -+ - config BCM_VC_CMA - bool "Videocore CMA" -- depends on CMA && BRCM_CHAR_DRIVERS && BCM2708_VCHIQ -+ depends on CMA && BCM2708_VCHIQ - default n - help - Helper for videocore CMA access. - - config BCM_VC_SM - bool "VMCS Shared Memory" -+ select BCM2708_VCMEM - default n - help - Support for the VC shared memory on the Broadcom reference - design. Uses the VCHIQ stack. -+ -+config BCM2708_VCMEM -+ bool "Videocore Memory" -+ default y -+ help -+ Helper for videocore memory access and total size allocation. -+ -+endif -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 0bf7fdf..b4f8e39d 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -1,2 +1,3 @@ - obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ -+obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c -new file mode 100644 -index 0000000..fcde6b1 ---- /dev/null -+++ b/drivers/char/broadcom/vc_mem.c -@@ -0,0 +1,423 @@ -+/***************************************************************************** -+* Copyright 2010 - 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 -+ -+#define DRIVER_NAME "vc-mem" -+ -+// Device (/dev) related variables -+static dev_t vc_mem_devnum = 0; -+static struct class *vc_mem_class = NULL; -+static struct cdev vc_mem_cdev; -+static int vc_mem_inited = 0; -+ -+#ifdef CONFIG_DEBUG_FS -+static struct dentry *vc_mem_debugfs_entry; -+#endif -+ -+/* -+ * Videocore memory addresses and size -+ * -+ * Drivers that wish to know the videocore memory addresses and sizes should -+ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -+ * headers. This allows the other drivers to not be tied down to a a certain -+ * address/size at compile time. -+ * -+ * In the future, the goal is to have the videocore memory virtual address and -+ * size be calculated at boot time rather than at compile time. The decision of -+ * where the videocore memory resides and its size would be in the hands of the -+ * bootloader (and/or kernel). When that happens, the values of these variables -+ * would be calculated and assigned in the init function. -+ */ -+// in the 2835 VC in mapped above ARM, but ARM has full access to VC space -+unsigned long mm_vc_mem_phys_addr = 0x00000000; -+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); -+ -+static uint phys_addr = 0; -+static uint mem_size = 0; -+static uint mem_base = 0; -+ -+ -+/**************************************************************************** -+* -+* vc_mem_open -+* -+***************************************************************************/ -+ -+static int -+vc_mem_open(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_release -+* -+***************************************************************************/ -+ -+static int -+vc_mem_release(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_size -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_size(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_base -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_base(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_current_size -+* -+***************************************************************************/ -+ -+int -+vc_mem_get_current_size(void) -+{ -+ return mm_vc_mem_size; -+} -+ -+EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -+ -+/**************************************************************************** -+* -+* vc_mem_ioctl -+* -+***************************************************************************/ -+ -+static long -+vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int rc = 0; -+ -+ (void) cmd; -+ (void) arg; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ switch (cmd) { -+ case VC_MEM_IOC_MEM_PHYS_ADDR: -+ { -+ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -+ __func__, (void *) mm_vc_mem_phys_addr); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -+ sizeof (mm_vc_mem_phys_addr)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_SIZE: -+ { -+ // Get the videocore memory size first -+ vc_mem_get_size(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -+ mm_vc_mem_size); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_size, -+ sizeof (mm_vc_mem_size)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_BASE: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -+ mm_vc_mem_base); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_base, -+ sizeof (mm_vc_mem_base)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_LOAD: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -+ { -+ return -ENOTTY; -+ } -+ } -+ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_mmap -+* -+***************************************************************************/ -+ -+static int -+vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ int rc = 0; -+ unsigned long length = vma->vm_end - vma->vm_start; -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ -+ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -+ __func__, (long) vma->vm_start, (long) vma->vm_end, -+ (long) vma->vm_pgoff); -+ -+ if (offset + length > mm_vc_mem_size) { -+ pr_err("%s: length %ld is too big\n", __func__, length); -+ return -EINVAL; -+ } -+ // Do not cache the memory map -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ -+ rc = remap_pfn_range(vma, vma->vm_start, -+ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -+ vma->vm_pgoff, length, vma->vm_page_prot); -+ if (rc != 0) { -+ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -+ } -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* File Operations for the driver. -+* -+***************************************************************************/ -+ -+static const struct file_operations vc_mem_fops = { -+ .owner = THIS_MODULE, -+ .open = vc_mem_open, -+ .release = vc_mem_release, -+ .unlocked_ioctl = vc_mem_ioctl, -+ .mmap = vc_mem_mmap, -+}; -+ -+#ifdef CONFIG_DEBUG_FS -+static void vc_mem_debugfs_deinit(void) -+{ -+ debugfs_remove_recursive(vc_mem_debugfs_entry); -+ vc_mem_debugfs_entry = NULL; -+} -+ -+ -+static int vc_mem_debugfs_init( -+ struct device *dev) -+{ -+ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -+ if (!vc_mem_debugfs_entry) { -+ dev_warn(dev, "could not create debugfs entry\n"); -+ return -EFAULT; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_phys_addr", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_phys_addr)) { -+ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_size", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_size)) { -+ dev_warn(dev, "%s:could not create vc_mem_size entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_base", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_base)) { -+ dev_warn(dev, "%s:could not create vc_mem_base entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ vc_mem_debugfs_deinit(); -+ return -EFAULT; -+} -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -+ -+/**************************************************************************** -+* -+* vc_mem_init -+* -+***************************************************************************/ -+ -+static int __init -+vc_mem_init(void) -+{ -+ int rc = -EFAULT; -+ struct device *dev; -+ -+ pr_debug("%s: called\n", __func__); -+ -+ mm_vc_mem_phys_addr = phys_addr; -+ mm_vc_mem_size = mem_size; -+ mm_vc_mem_base = mem_base; -+ -+ vc_mem_get_size(); -+ -+ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -+ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -+ -+ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -+ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -+ __func__, rc); -+ goto out_err; -+ } -+ -+ cdev_init(&vc_mem_cdev, &vc_mem_fops); -+ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -+ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -+ goto out_unregister; -+ } -+ -+ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vc_mem_class)) { -+ rc = PTR_ERR(vc_mem_class); -+ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -+ goto out_cdev_del; -+ } -+ -+ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -+ DRIVER_NAME); -+ if (IS_ERR(dev)) { -+ rc = PTR_ERR(dev); -+ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -+ goto out_class_destroy; -+ } -+ -+#ifdef CONFIG_DEBUG_FS -+ /* don't fail if the debug entries cannot be created */ -+ vc_mem_debugfs_init(dev); -+#endif -+ -+ vc_mem_inited = 1; -+ return 0; -+ -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ -+ out_class_destroy: -+ class_destroy(vc_mem_class); -+ vc_mem_class = NULL; -+ -+ out_cdev_del: -+ cdev_del(&vc_mem_cdev); -+ -+ out_unregister: -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ -+ out_err: -+ return -1; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_exit -+* -+***************************************************************************/ -+ -+static void __exit -+vc_mem_exit(void) -+{ -+ pr_debug("%s: called\n", __func__); -+ -+ if (vc_mem_inited) { -+#if CONFIG_DEBUG_FS -+ vc_mem_debugfs_deinit(); -+#endif -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ class_destroy(vc_mem_class); -+ cdev_del(&vc_mem_cdev); -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ } -+} -+ -+module_init(vc_mem_init); -+module_exit(vc_mem_exit); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Broadcom Corporation"); -+ -+module_param(phys_addr, uint, 0644); -+module_param(mem_size, uint, 0644); -+module_param(mem_base, uint, 0644); -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index 39a8971..0bfb42e 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -15,6 +15,7 @@ - /* ---- Include Files ----------------------------------------------------- */ - - #include -+#include - #include - #include - #include -@@ -35,8 +36,6 @@ - #include - #include - --#include -- - #include "vchiq_connected.h" - #include "vc_vchi_sm.h" - -diff --git a/include/linux/broadcom/vc_mem.h b/include/linux/broadcom/vc_mem.h -new file mode 100644 -index 0000000..20a4753 ---- /dev/null -+++ b/include/linux/broadcom/vc_mem.h -@@ -0,0 +1,35 @@ -+/***************************************************************************** -+* Copyright 2010 - 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_MEM_H -+#define _VC_MEM_H -+ -+#include -+ -+#define VC_MEM_IOC_MAGIC 'v' -+ -+#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 ) -+#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -+ -+#if defined( __KERNEL__ ) -+#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -+ -+extern unsigned long mm_vc_mem_phys_addr; -+extern unsigned int mm_vc_mem_size; -+extern int vc_mem_get_current_size( void ); -+#endif -+ -+#endif /* _VC_MEM_H */ - -From 7495f032da212d310393adf5c4d1694190e6f309 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 1 Jun 2015 20:40:11 +0200 -Subject: [PATCH 195/216] BCM270x: Add USB controller to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support to dwc_otg driver. -Add device to Device Tree. -Don't add platform devices when booting in DT mode. - -Tested on Pi1 and Pi2 with and without DT. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 8 ++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 7 +++++++ - 4 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 3f8af85..dc7df47 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -121,6 +121,14 @@ - status = "disabled"; - }; - -+ usb: usb@7e980000 { -+ compatible = "brcm,bcm2708-usb"; -+ reg = <0x7e980000 0x10000>, -+ <0x7e006000 0x1000>; -+ interrupts = <2 0>, -+ <1 9>; -+ }; -+ - leds: leds { - compatible = "gpio-leds"; - }; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 06438df..6298309 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -955,7 +955,7 @@ void __init bcm2708_init(void) - #endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device_dt(&bcm2708_fb_device); -- bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device_dt(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index ce06b7d..d8c2336 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -978,7 +978,7 @@ void __init bcm2709_init(void) - bcm_register_device(&bcm2708_systemtimer_device); - #endif - bcm_register_device_dt(&bcm2708_fb_device); -- bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device_dt(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -index dc7cd32..53307f0 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -1043,9 +1043,16 @@ static struct platform_device_id platform_ids[] = { - }; - MODULE_DEVICE_TABLE(platform, platform_ids); - -+static const struct of_device_id dwc_otg_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-usb", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, dwc_otg_of_match_table); -+ - static struct platform_driver dwc_otg_driver = { - .driver = { - .name = (char *)dwc_driver_name, -+ .of_match_table = dwc_otg_of_match_table, - }, - .id_table = platform_ids, - - -From da5345649e7ad4deb51692d4d969ba4a2f86974b Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 2 Mar 2015 17:57:30 +0000 -Subject: [PATCH 196/216] added mcp251x module to list of modules to get - compiled as well as the corresponding overlay - ---- - arch/arm/boot/dts/Makefile | 2 +- - arch/arm/boot/dts/overlays/Makefile | 1 + - .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 5 ++ - arch/arm/configs/bcmrpi_defconfig | 8 +++ - 5 files changed, 84 insertions(+), 1 deletion(-) - create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index ea93e1d..d5b6a82 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1,9 +1,9 @@ - ifeq ($(CONFIG_OF),y) - - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb --dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb -+dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb - - # Raspberry Pi - ifeq ($(CONFIG_BCM2708_DT),y) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d64e6b4..d18a1f2 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -22,6 +22,7 @@ dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -new file mode 100755 -index 0000000..398d59c ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -0,0 +1,69 @@ -+/* -+ * Device tree overlay for mcp251x/can0 on spi0.0 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* disable spi-dev for spi0.0 */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ spidev@0{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ can0_pins: can0_pins { -+ brcm,pins = <25>; -+ brcm,function = <0>; /* input */ -+ }; -+ }; -+ }; -+ -+ /* the clock/oscillator of the can-controller */ -+ fragment@2 { -+ target-path = "/clocks"; -+ __overlay__ { -+ /* external oscillator of mcp2515 on SPI0.0 */ -+ can0_osc: can0_osc { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <16000000>; -+ }; -+ }; -+ }; -+ -+ /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ can0: mcp2515@0 { -+ reg = <0>; -+ compatible = "microchip,mcp2515"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&can0_pins>; -+ spi-max-frequency = <10000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 0x2>; -+ clocks = <&can0_osc>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ oscillator = <&can0_osc>,"clock-frequency:0"; -+ spimaxfrequency = <&can0>,"spi-max-frequency:0"; -+ interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 5ce9a01..2a1a15a 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -344,7 +344,12 @@ CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m - CONFIG_YAM=m - CONFIG_CAN=m -+CONFIG_CAN_RAW=m -+CONFIG_CAN_BCM=m -+CONFIG_CAN_GW=m - CONFIG_CAN_VCAN=m -+CONFIG_CAN_DEV=m -+CONFIG_CAN_CALC_BITTIMING=y - CONFIG_CAN_MCP251X=m - CONFIG_IRDA=m - CONFIG_IRLAN=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index da443da..a2d7291 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -335,6 +335,14 @@ CONFIG_6PACK=m - CONFIG_BPQETHER=m - CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m -+CONFIG_CAN=m -+CONFIG_CAN_RAW=m -+CONFIG_CAN_BCM=m -+CONFIG_CAN_GW=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_DEV=m -+CONFIG_CAN_CALC_BITTIMING=y -+CONFIG_CAN_MCP251X=m - CONFIG_YAM=m - CONFIG_CAN=m - CONFIG_CAN_VCAN=m - -From 8e999dc420b342d1304fc2bcd755ab6a36d6896c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 13:55:05 +0200 -Subject: [PATCH 197/216] BCM270x: Move thermal sensor to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support to bcm2835-thermal driver. -Add thermal sensor device to Device Tree. -Don't add platform device when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 4 ++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - drivers/thermal/bcm2835-thermal.c | 8 +++++++- - 4 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index dc7df47..fcb5828 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -143,6 +143,10 @@ - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; - }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ }; - }; - - clocks { -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6298309..e141c0b 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -984,7 +984,7 @@ void __init bcm2708_init(void) - } - - bcm_register_device(&bcm2835_hwmon_device); -- bcm_register_device(&bcm2835_thermal_device); -+ bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) - bcm_register_device_dt(&bcm2708_i2s_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index d8c2336..6dadb80 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -1007,7 +1007,7 @@ void __init bcm2709_init(void) - } - - bcm_register_device(&bcm2835_hwmon_device); -- bcm_register_device(&bcm2835_thermal_device); -+ bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) - bcm_register_device_dt(&bcm2708_i2s_device); -diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c -index 0c556d1..3bc80f1 100644 ---- a/drivers/thermal/bcm2835-thermal.c -+++ b/drivers/thermal/bcm2835-thermal.c -@@ -167,13 +167,19 @@ static struct thermal_zone_device_ops ops = { - .get_mode = bcm2835_get_mode, - }; - --/* Thermal Driver */ -+static const struct of_device_id bcm2835_thermal_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-thermal", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); -+ - static struct platform_driver bcm2835_thermal_driver = { - .probe = bcm2835_thermal_probe, - .remove = bcm2835_thermal_remove, - .driver = { - .name = "bcm2835_thermal", - .owner = THIS_MODULE, -+ .of_match_table = bcm2835_thermal_of_match_table, - }, - }; - - -From fd724791a4d515e8069884b72f52752501ee0f92 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 13:55:22 +0200 -Subject: [PATCH 198/216] bcm2835: Add thermal sensor to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add the BCM2835 thermal sensor to Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 40fc759..efaf4df 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -170,6 +170,10 @@ - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; - }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ }; - }; - - clocks { - -From 34638ffefe49111b137c8b0927c47f9aab23215b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 15:51:24 +0200 -Subject: [PATCH 199/216] BCM270x: Enable bcm2835_wdt and bcm2835-rng -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Change the kconfig dependency to make bcm2835_wdt and bcm2835-rng -available on ARCH_BCM2708 and ARCH_BCM2709. -Enable them as loadable modules in bcmrpi_defconfig and -bcm2709_defconfig. - -There is a commit in linux-next that will move restart/pm_power_off -to bcm2835_wdt for ARCH_BCM2835. This will not affect ARCH_BCM270x -since arm_pm_restart (.restart = bcm2708_restart) and -pm_power_off (=bcm2708_power_off) is set in -arch/arm/mach-bcm270X/bcm270X.c and will take presedence. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - drivers/char/hw_random/Kconfig | 2 +- - drivers/watchdog/Kconfig | 2 +- - 4 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 2a1a15a..d08ae51 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -561,6 +561,7 @@ CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m - CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y -@@ -603,6 +604,7 @@ CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y - CONFIG_BCM2708_WDT=m -+CONFIG_BCM2835_WDT=m - CONFIG_UCB1400_CORE=m - CONFIG_MFD_STMPE=y - CONFIG_STMPE_SPI=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index a2d7291..11bbfac 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -557,6 +557,7 @@ CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m - CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y -@@ -599,6 +600,7 @@ CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y - CONFIG_BCM2708_WDT=m -+CONFIG_BCM2835_WDT=m - CONFIG_UCB1400_CORE=m - CONFIG_MFD_STMPE=y - CONFIG_STMPE_SPI=y -diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index 1c97093..0996083 100644 ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX - - config HW_RANDOM_BCM2835 - tristate "Broadcom BCM2835 Random Number Generator support" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - default HW_RANDOM - ---help--- - This driver provides kernel-side support for the Random Number -diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index ca7d6463..e010420 100644 ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -1222,7 +1222,7 @@ config BCM63XX_WDT - - config BCM2835_WDT - tristate "Broadcom BCM2835 hardware watchdog" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - select WATCHDOG_CORE - help - Watchdog driver for the built in watchdog hardware in Broadcom - -From 6779bd793d41be8d73ee771b149606e13e13e0b7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 15:51:52 +0200 -Subject: [PATCH 200/216] BCM270X_DT: Add bcm2835-pm-wdt and bcm2835-rng -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This makes it possible to use the mainline watchdog and -random generator drivers: -dtparam=watchdog=on -dtparam=random=on - -bcm2708_wdog and bcm2708-rng can still be used. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 12 ++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 4 files changed, 18 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 75df21c..52b1404 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -124,5 +124,7 @@ - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - - audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index df12b7d..876dfca 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -114,5 +114,7 @@ - act_led_trigger = <&act_led>,"linux,default-trigger"; - - audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index fcb5828..a80b1a8 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -43,6 +43,18 @@ - #interrupt-cells = <2>; - }; - -+ watchdog: watchdog@7e100000 { -+ compatible = "brcm,bcm2835-pm-wdt"; -+ reg = <0x7e100000 0x28>; -+ status = "disabled"; -+ }; -+ -+ random: rng@7e104000 { -+ compatible = "brcm,bcm2835-rng"; -+ reg = <0x7e104000 0x10>; -+ status = "disabled"; -+ }; -+ - mailbox: mailbox@7e00b800 { - compatible = "brcm,bcm2708-vcio"; - reg = <0x7e00b880 0x40>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 78bc756..b226dfb 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -124,5 +124,7 @@ - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - - audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; - -From 493b7b5c56b4afd21bd980e38deb0f9d7d06061c Mon Sep 17 00:00:00 2001 +From 070a6f51cd5f81f635cfcccd3452ee5f252a7ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 201/216] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 73/77] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -153634,3120 +134261,186 @@ index 70f2f39..f7fdacd 100644 static const char * const bcm2835_compat[] = { -From e98419e0f836f39ae77a595f0d7218ba4b0576ab Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:34:24 +0200 -Subject: [PATCH 202/216] bcm2835: Match BCM270X Device Trees -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 45 +++++++++++------ - arch/arm/boot/dts/bcm2835-rpi-b.dts | 29 +++++++---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 85 +++++++++++++++++++++++++------- - arch/arm/boot/dts/bcm2835.dtsi | 12 ++--- - 4 files changed, 122 insertions(+), 49 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index e479515..b0fb0e8 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -4,27 +4,40 @@ - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; - model = "Raspberry Pi Model B+"; -+}; -+ -+&gpio { -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; - -- leds { -- act { -- gpios = <&gpio 47 0>; -- }; -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 47 0>; -+}; - -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; -+&leds { -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; - }; - }; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - -- /* I2S interface */ -- i2s_alt0: i2s_alt0 { -- brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index bafa46f..b867224 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -5,19 +5,28 @@ - compatible = "raspberrypi,model-b", "brcm,bcm2835"; - model = "Raspberry Pi Model B"; - -- leds { -- act { -- gpios = <&gpio 16 1>; -- }; -- }; - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; -- -- /* I2S interface */ -- i2s_alt2: i2s_alt2 { -+ i2s_pins: i2s { - brcm,pins = <28 29 30 31>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 16 1>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index f23835e..466f02b 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -1,17 +1,29 @@ - /include/ "bcm2835.dtsi" - - / { -+ /* This is left here in case u-boot needs it */ - memory { - reg = <0 0x10000000>; - }; - -- leds { -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ sound = &sound; -+ }; -+ -+ leds: leds { - compatible = "gpio-leds"; - -- act { -- label = "ACT"; -- default-state = "keep"; -- linux,default-trigger = "heartbeat"; -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; - }; - }; - -@@ -19,35 +31,61 @@ - audio: audio { - compatible = "brcm,bcm2835-audio"; - brcm,pwm-channels = <8>; -+ status = "disabled"; -+ }; -+ -+ /* External sound card */ -+ sound: sound { - }; - }; - - &gpio { -- pinctrl-names = "default"; -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; - -- gpioout: gpioout { -- brcm,pins = <6>; -- brcm,function = <1>; /* GPIO out */ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; - }; - -- alt0: alt0 { -- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; -- brcm,function = <4>; /* alt0 */ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; - }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; - -- alt3: alt3 { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <7>; /* alt3 */ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; - }; - }; - - &i2c0 { -- status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; - clock-frequency = <100000>; - }; - - &i2c1 { -- status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; - clock-frequency = <100000>; - }; - -@@ -59,3 +97,16 @@ - &fb { - status = "okay"; - }; -+ -+/ { -+ __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ audio = <&audio>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index efaf4df..4b6dd65f 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -9,7 +9,7 @@ - bootargs = ""; - }; - -- soc { -+ soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; -@@ -51,12 +51,12 @@ - #interrupt-cells = <2>; - }; - -- watchdog@7e100000 { -+ watchdog: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm-wdt"; - reg = <0x7e100000 0x28>; - }; - -- rng@7e104000 { -+ random: rng@7e104000 { - compatible = "brcm,bcm2835-rng"; - reg = <0x7e104000 0x10>; - }; -@@ -90,7 +90,7 @@ - #interrupt-cells = <2>; - }; - -- uart@7e201000 { -+ uart0: uart@7e201000 { - compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; - interrupts = <2 25>; -@@ -109,7 +109,7 @@ - status = "disabled"; - }; - -- spi: spi@7e204000 { -+ spi0: spi@7e204000 { - compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; -@@ -150,7 +150,7 @@ - status = "disabled"; - }; - -- usb@7e980000 { -+ usb: usb@7e980000 { - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; - -From 3ac358b4ca8e0b71da28992689669218e0dbbacf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:35:11 +0200 -Subject: [PATCH 203/216] dts: Enable overlays on ARCH_BCM2835 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Build Device Tree overlays on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 3 +++ - arch/arm/boot/dts/overlays/Makefile | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index d5b6a82..e7ce7c4 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,9 @@ endif - ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif -+ifeq ($(CONFIG_ARCH_BCM2835),y) -+ RPI_DT_OVERLAYS=y -+endif - - subdir-$(RPI_DT_OVERLAYS) += overlays - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d18a1f2..c449c3f 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -8,6 +8,9 @@ endif - ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif -+ifeq ($(CONFIG_ARCH_BCM2835),y) -+ RPI_DT_OVERLAYS=y -+endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - -From 6c6321340ea33c79dbfb15441ad58db03ec94167 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:35:55 +0200 -Subject: [PATCH 204/216] bcm2835: Make camera and sound drivers available -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Change kconfig dependency to make SND_BCM2708_SOC_* and -VIDEO_BCM2835 available on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - drivers/media/platform/bcm2835/Kconfig | 2 +- - sound/soc/bcm/Kconfig | 14 +++++++------- - 2 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig -index 2cb1a68..99a5cbc 100644 ---- a/drivers/media/platform/bcm2835/Kconfig -+++ b/drivers/media/platform/bcm2835/Kconfig -@@ -2,7 +2,7 @@ - - config VIDEO_BCM2835 - bool "Broadcom BCM2835 camera interface driver" -- depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709) -+ depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) - ---help--- - Say Y here to enable camera host interface devices for - Broadcom BCM2835 SoC. This operates over the VCHIQ interface -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 003ae28..516ab9d 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -21,49 +21,49 @@ config SND_BCM2708_SOC_I2S - - config SND_BCM2708_SOC_HIFIBERRY_DAC - tristate "Support for HifiBerry DAC" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM5102A - help - Say Y or M if you want to add support for HifiBerry DAC. - - config SND_BCM2708_SOC_HIFIBERRY_DACPLUS - tristate "Support for HifiBerry DAC+" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM512x - help - Say Y or M if you want to add support for HifiBerry DAC+. - - config SND_BCM2708_SOC_HIFIBERRY_DIGI - tristate "Support for HifiBerry Digi" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_WM8804 - help - Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. - - config SND_BCM2708_SOC_HIFIBERRY_AMP - tristate "Support for the HifiBerry Amp" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_TAS5713 - help - Say Y or M if you want to add support for the HifiBerry Amp amplifier board. - - config SND_BCM2708_SOC_RPI_DAC - tristate "Support for RPi-DAC" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM1794A - help - Say Y or M if you want to add support for RPi-DAC. - - config SND_BCM2708_SOC_RPI_PROTO - tristate "Support for Rpi-PROTO" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_WM8731 - help - Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731). - - config SND_BCM2708_SOC_IQAUDIO_DAC - tristate "Support for IQaudIO-DAC" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM512x_I2C - help - Say Y or M if you want to add support for IQaudIO-DAC. - -From b5b5fa6e2a877089b48daaaac9b135c95c71e24f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:36:19 +0200 -Subject: [PATCH 205/216] bcm2835: Merge bcm2835_defconfig with - bcmrpi_defconfig -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These commands where used to make this commit: - -./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg - -cat << EOF > filter -CONFIG_ARCH_BCM2708 -CONFIG_BCM2708_DT -CONFIG_ARM_PATCH_PHYS_VIRT -CONFIG_PHYS_OFFSET -CONFIG_CMDLINE -CONFIG_BCM2708_WDT -CONFIG_HW_RANDOM_BCM2708 -CONFIG_I2C_BCM2708 -CONFIG_SPI_BCM2708 -CONFIG_SND_BCM2708_SOC_I2S -CONFIG_USB_DWCOTG -CONFIG_LIRC_RPI -EOF - -grep -F -v -f filter merge.cfg > filtered.cfg - -cat << EOF > added.cfg -CONFIG_WATCHDOG=y -CONFIG_BCM2835_WDT=y -CONFIG_MISC_FILESYSTEMS=y -CONFIG_SND_BCM2835_SOC_I2S=m -EOF - -ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg -ARCH=arm make oldconfig - -ARCH=arm make savedefconfig -cp defconfig arch/arm/configs/bcm2835_defconfig - -rm merge.cfg filter filtered.cfg added.cfg defconfig - -ARCH=arm make bcm2835_defconfig -ARCH=arm make oldconfig - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 1114 +++++++++++++++++++++++++++++++++++- - 1 file changed, 1097 insertions(+), 17 deletions(-) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 1af6069..2e8a95a 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -1,107 +1,1071 @@ - # CONFIG_LOCALVERSION_AUTO is not set - CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y - CONFIG_FHANDLE=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_BSD_PROCESS_ACCT=y - CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y - CONFIG_LOG_BUF_SHIFT=18 - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y -+CONFIG_MEMCG=y - CONFIG_CGROUP_PERF=y - CONFIG_CFS_BANDWIDTH=y - CONFIG_RT_GROUP_SCHED=y -+CONFIG_BLK_CGROUP=y - CONFIG_NAMESPACES=y - CONFIG_SCHED_AUTOGROUP=y --CONFIG_RELAY=y - CONFIG_BLK_DEV_INITRD=y - CONFIG_CC_OPTIMIZE_FOR_SIZE=y --CONFIG_KALLSYMS_ALL=y - CONFIG_EMBEDDED=y - # CONFIG_COMPAT_BRK is not set - CONFIG_PROFILING=y --CONFIG_OPROFILE=y -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y - CONFIG_JUMP_LABEL=y - CONFIG_CC_STACKPROTECTOR_REGULAR=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_ARCH_MULTI_V6=y - # CONFIG_ARCH_MULTI_V7 is not set - CONFIG_ARCH_BCM=y - CONFIG_ARCH_BCM2835=y --CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_PREEMPT=y - CONFIG_AEABI=y -+CONFIG_OABI_COMPAT=y - CONFIG_KSM=y - CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 - CONFIG_KEXEC=y - CONFIG_CRASH_DUMP=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y - CONFIG_VFP=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_BINFMT_MISC=m - # CONFIG_SUSPEND is not set - 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_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m -+CONFIG_INET_DIAG=m -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y - CONFIG_NETWORK_SECMARK=y - CONFIG_NETFILTER=y --CONFIG_CFG80211=y --CONFIG_MAC80211=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CT_PROTO_DCCP=m -+CONFIG_NF_CT_PROTO_UDPLITE=m -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_IRDA=m -+CONFIG_IRLAN=m -+CONFIG_IRNET=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_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_6LOWPAN=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_BT_WILINK=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_NFC_PN533=m - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - # CONFIG_STANDALONE is not set -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m - CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m - CONFIG_SCSI_CONSTANTS=y - CONFIG_SCSI_SCAN_ASYNC=y -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_MD_RAID0=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m - CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_ENC28J60=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=m - CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m - CONFIG_USB_NET_SMSC95XX=y --CONFIG_ZD1211RW=y --CONFIG_INPUT_EVDEV=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_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+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_CARDS=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_HOSTAP=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_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_RTL8192CU=m -+CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_INPUT_POLLDEV=m -+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=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_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m -+CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y - CONFIG_I2C=y --CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2835=y - CONFIG_SPI=y --CONFIG_SPI_BCM2835=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_SPIDEV=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m - CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2760=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_W1_SLAVE_BQ27000=m -+CONFIG_BATTERY_DS2760=m - # CONFIG_HWMON is not set -+CONFIG_THERMAL=y -+CONFIG_THERMAL_BCM2835=y -+CONFIG_WATCHDOG=y -+CONFIG_BCM2835_WDT=y -+CONFIG_UCB1400_CORE=m -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_LIRC=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_STK1160_AC97=y -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_FRIIO=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835=y -+CONFIG_VIDEO_BCM2835_MMAL=m -+CONFIG_RADIO_SI470X=y -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV7640=m -+CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=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_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_SOUND_PRIME=m -+CONFIG_HIDRAW=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_ELO=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_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_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y - CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_PRINTER=m - 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_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m - CONFIG_USB_DWC2=y -+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_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_F81232=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_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=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_SAFE=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_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=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_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m - CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 - CONFIG_MMC_BCM2835=y - CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2835=y --CONFIG_NEW_LEDS=y -+CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y --CONFIG_LEDS_TRIGGERS=y - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y - CONFIG_LEDS_TRIGGER_CPU=y - CONFIG_LEDS_TRIGGER_GPIO=y - CONFIG_LEDS_TRIGGER_DEFAULT_ON=y --CONFIG_LEDS_TRIGGER_TRANSIENT=y --CONFIG_LEDS_TRIGGER_CAMERA=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_ISL12057=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_RX4581=m - CONFIG_DMADEVICES=y - CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_LIRC_STAGING=y -+CONFIG_LIRC_IMON=m -+CONFIG_LIRC_SASEM=m -+CONFIG_LIRC_SERIAL=m -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - CONFIG_EXT2_FS_POSIX_ACL=y -@@ -109,18 +1073,110 @@ CONFIG_EXT3_FS=y - CONFIG_EXT3_FS_POSIX_ACL=y - 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_QFMT_V1=m -+CONFIG_QFMT_V2=m -+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_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --# CONFIG_MISC_FILESYSTEMS is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y --CONFIG_NFSD=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=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=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=y -+CONFIG_DLM=m - CONFIG_PRINTK_TIME=y - CONFIG_BOOT_PRINTK_DELAY=y - CONFIG_DYNAMIC_DEBUG=y -@@ -130,14 +1186,38 @@ CONFIG_DEBUG_INFO=y - CONFIG_UNUSED_SYMBOLS=y - CONFIG_DEBUG_MEMORY_INIT=y - CONFIG_LOCKUP_DETECTOR=y -+CONFIG_TIMER_STATS=y -+# CONFIG_DEBUG_PREEMPT is not set -+CONFIG_LATENCYTOP=y -+CONFIG_IRQSOFF_TRACER=y - CONFIG_SCHED_TRACER=y - CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_KPROBE_EVENT is not set - CONFIG_FUNCTION_PROFILER=y - CONFIG_TEST_KSTRTOX=y - CONFIG_KGDB=y - CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y - CONFIG_STRICT_DEVMEM=y - CONFIG_DEBUG_LL=y - CONFIG_EARLY_PRINTK=y -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CRYPTD=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_SHA512=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y - # CONFIG_XZ_DEC_ARM is not set - # CONFIG_XZ_DEC_ARMTHUMB is not set - -From c712b42d06623b5410a3921f71278963a9a45209 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 24 Mar 2015 16:57:04 +0000 -Subject: [PATCH 206/216] BCM270x_DT: Configure UART using DT - -See: https://github.com/raspberrypi/firmware/issues/393 ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 7 +++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 7 +++++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 27 +++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 7 +++++++ - arch/arm/mach-bcm2708/bcm2708.c | 9 +++++---- - arch/arm/mach-bcm2709/bcm2709.c | 9 +++++---- - 6 files changed, 58 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 52b1404..99ab3c9 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -16,6 +16,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -@@ -53,6 +54,10 @@ - status = "okay"; - }; - -+&uart0 { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -@@ -108,6 +113,8 @@ - - / { - __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 876dfca..e8c80cd 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -16,6 +16,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -@@ -53,6 +54,10 @@ - status = "okay"; - }; - -+&uart0 { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -@@ -102,6 +107,8 @@ - - / { - __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index a80b1a8..a09a3c7 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -84,6 +84,17 @@ - status = "disabled"; - }; - -+ uart0: uart@7e201000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x7e201000 0x1000>; -+ interrupts = <2 25>; -+ clocks = <&clk_uart0 &clk_apb_p>; -+ clock-names = "uartclk","apb_pclk"; -+ arm,primecell-periphid = <0x00241011>; // For an explanation, see -+ // https://github.com/raspberrypi/linux/commit/13731d862cf5219216533a3b0de052cee4cc5038 -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; - reg = <0x7e203000 0x20>, -@@ -188,5 +199,21 @@ - clock-output-names = "spi"; - clock-frequency = <250000000>; - }; -+ -+ clk_uart0: clock@3 { -+ compatible = "fixed-clock"; -+ reg = <3>; -+ #clock-cells = <0>; -+ clock-output-names = "uart0_pclk"; -+ clock-frequency = <3000000>; -+ }; -+ -+ clk_apb_p: clock@4 { -+ compatible = "fixed-clock"; -+ reg = <4>; -+ #clock-cells = <0>; -+ clock-output-names = "apb_pclk"; -+ clock-frequency = <126000000>; -+ }; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index b226dfb..39b6fd4 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -16,6 +16,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -@@ -53,6 +54,10 @@ - status = "okay"; - }; - -+&uart0 { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -@@ -108,6 +113,8 @@ - - / { - __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e141c0b..e17c1de 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -1020,10 +1020,11 @@ void __init bcm2708_init(void) - i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); - #endif - -- -- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -- struct amba_device *d = amba_devs[i]; -- amba_device_register(d, &iomem_resource); -+ if (!use_dt) { -+ 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; -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 6dadb80..8834a10 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -1043,10 +1043,11 @@ void __init bcm2709_init(void) - i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); - #endif - -- -- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -- struct amba_device *d = amba_devs[i]; -- amba_device_register(d, &iomem_resource); -+ if (!use_dt) { -+ 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; - -From aa05d1fe61d794be63d7e6055881e36c33cdb09c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 4 Jun 2015 16:16:08 +0100 -Subject: [PATCH 207/216] vchiq_arm: ARCH_BCM2835 compatibility - -Use virt_to_dma (not ideal, I know) to calculate the virt-to-bus -offset. This will make use of the "dma-ranges" property, if -present. ---- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 660aad2..c739083 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -46,7 +46,7 @@ - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - --#define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) -+#define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset)) - - #include "vchiq_arm.h" - #include "vchiq_2835.h" -@@ -66,7 +66,8 @@ typedef struct vchiq_2835_state_struct { - static void __iomem *g_regs; - static FRAGMENTS_T *g_fragments_base; - static FRAGMENTS_T *g_free_fragments; --struct semaphore g_free_fragments_sema; -+static struct semaphore g_free_fragments_sema; -+static unsigned long g_virt_to_bus_offset; - - extern int vchiq_arm_log_level; - -@@ -92,6 +93,8 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - int slot_mem_size, frag_mem_size; - int err, irq, i; - -+ g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); -+ - /* Allocate space for the channels in coherent memory */ - slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); - -From fa0a4bff157dddc6207cba9911a1581864cf2307 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Jun 2015 14:00:54 +0100 -Subject: [PATCH 208/216] BCM270x_DT: Enable UART in the example Compute Module - DTS as well +From 3add74da14e27d18ef276f66c55a69e6dc014216 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 16 Jun 2015 17:47:27 +0100 +Subject: [PATCH 74/77] platform: Add force_core command line setting to boot + from a different core number --- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 11 +++++++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 3 ++- - 3 files changed, 14 insertions(+), 1 deletion(-) + arch/arm/mach-bcm2709/armctrl.c | 17 ++++++++++++++++- + arch/arm/mach-bcm2709/bcm2709.c | 2 ++ + 2 files changed, 18 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 45f8244..238bd65 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -5,3 +5,14 @@ - / { - model = "Raspberry Pi Compute Module"; - }; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+/ { -+ __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 1c2cfcf..43830a6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -11,6 +11,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index a09a3c7..dc0346b 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -185,10 +185,11 @@ - clock-frequency = <250000000>; - }; - -- clk_i2c: i2c { -+ clk_i2c: clock@1 { - compatible = "fixed-clock"; - reg = <1>; - #clock-cells = <0>; -+ clock-output-names = "i2c"; - clock-frequency = <250000000>; - }; - - -From fae583caba82c37f9a1e0cff81fbaa4c3f768657 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Jun 2015 15:59:08 +0100 -Subject: [PATCH 209/216] bcm270x defconfigs: Remove spurious entries - ---- - arch/arm/configs/bcm2709_defconfig | 5 ----- - arch/arm/configs/bcmrpi_defconfig | 8 -------- - 2 files changed, 13 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d08ae51..78e1202 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -344,12 +344,7 @@ CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m - CONFIG_YAM=m - CONFIG_CAN=m --CONFIG_CAN_RAW=m --CONFIG_CAN_BCM=m --CONFIG_CAN_GW=m - CONFIG_CAN_VCAN=m --CONFIG_CAN_DEV=m --CONFIG_CAN_CALC_BITTIMING=y - CONFIG_CAN_MCP251X=m - CONFIG_IRDA=m - CONFIG_IRLAN=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 11bbfac..c6a5db2 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -335,14 +335,6 @@ CONFIG_6PACK=m - CONFIG_BPQETHER=m - CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m --CONFIG_CAN=m --CONFIG_CAN_RAW=m --CONFIG_CAN_BCM=m --CONFIG_CAN_GW=m --CONFIG_CAN_VCAN=m --CONFIG_CAN_DEV=m --CONFIG_CAN_CALC_BITTIMING=y --CONFIG_CAN_MCP251X=m - CONFIG_YAM=m - CONFIG_CAN=m - CONFIG_CAN_VCAN=m - -From 549ff9d4fee2f6dc0abdeaa552754ce2197ba331 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 May 2015 09:00:01 +0100 -Subject: [PATCH 210/216] BCM270x_DT: Add a label to the clocks node, and a few - aliases - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 2 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 2 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 5 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 99ab3c9..c9053f8 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -15,8 +15,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e8c80cd..32066c3 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -15,8 +15,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 43830a6..f38a0c2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -10,8 +10,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index dc0346b..a9f1507 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -172,7 +172,7 @@ - }; - }; - -- clocks { -+ clocks: clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 39b6fd4..a9adaf4 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -15,8 +15,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { - -From 1b8bcc8ef9b600f7ac5e4d40bd70b507ad02aa01 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 May 2015 09:01:02 +0100 -Subject: [PATCH 211/216] sdhost-overlay: Move clock declaration out of /soc - ---- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 29 +++++++++++++++------------ - 1 file changed, 16 insertions(+), 13 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index b2653e9..8fb28e9 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -24,23 +24,26 @@ - brcm,overclock-50 = <0>; - status = "okay"; - }; -+ }; -+ }; - -- clocks { -- #address-cells = <1>; -- #size-cells = <0>; -+ fragment@1 { -+ target = <&clocks>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; - -- clk_sdhost: clock@3 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "sdhost"; -- clock-frequency = <250000000>; -- }; -+ clk_sdhost: sdhost { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; - }; - }; - }; - -- fragment@1 { -+ fragment@2 { - target = <&gpio>; - __overlay__ { - sdhost_pins: sdhost_pins { -@@ -50,7 +53,7 @@ - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&mmc>; - __overlay__ { - /* Find a way to disable the other driver */ -@@ -59,7 +62,7 @@ - }; - }; - -- fragment@3 { -+ fragment@4 { - target-path = "/__overrides__"; - __overlay__ { - sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - -From 24d8164a16fb825c4bee4a8cca87f55a68f33edf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 6 Jun 2015 23:45:32 +0200 -Subject: [PATCH 212/216] BCM270X_DT: Enable 'make clean' on overlays directory -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Always add the overlays directory to subdir so it can be -cleaned with 'make clean'. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index e7ce7c4..d85583c 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -16,8 +16,6 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - RPI_DT_OVERLAYS=y - endif - --subdir-$(RPI_DT_OVERLAYS) += overlays -- - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb - # Keep at91 dtb files sorted alphabetically for each SoC -@@ -676,3 +674,5 @@ clean-files := *.dtb - ifeq ($(RPI_DT_OVERLAYS),y) - DTC_FLAGS ?= -@ - endif -+ -+subdir-y += overlays - -From 2b53c727bbb2ba40102236f127ea6e68b1148335 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 7 Jun 2015 13:35:33 +0200 -Subject: [PATCH 213/216] hwmon: Remove bcm2835-hwmon -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -bcm2835-thermal combined with the configs HWMON=y and -THERMAL_HWMON=y, gives the same functionality. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 5 - - arch/arm/mach-bcm2709/bcm2709.c | 5 - - drivers/hwmon/Kconfig | 10 -- - drivers/hwmon/Makefile | 1 - - drivers/hwmon/bcm2835-hwmon.c | 219 ---------------------------------------- - 5 files changed, 240 deletions(-) - delete mode 100644 drivers/hwmon/bcm2835-hwmon.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e17c1de..4f191d9 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -697,10 +697,6 @@ static struct platform_device bcm2708_bsc1_device = { - .resource = bcm2708_bsc1_resources, +diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c +index a366275..90805a6 100644 +--- a/arch/arm/mach-bcm2709/armctrl.c ++++ b/arch/arm/mach-bcm2709/armctrl.c +@@ -45,6 +45,8 @@ static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { + INTERRUPT_VC_ARASANSDIO }; --static struct platform_device bcm2835_hwmon_device = { -- .name = "bcm2835_hwmon", --}; -- - static struct platform_device bcm2835_thermal_device = { - .name = "bcm2835_thermal", - }; -@@ -983,7 +979,6 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2708_bsc1_device); - } - -- bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 8834a10..d61bb30 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -718,10 +718,6 @@ static struct platform_device bcm2708_bsc1_device = { - .resource = bcm2708_bsc1_resources, - }; - --static struct platform_device bcm2835_hwmon_device = { -- .name = "bcm2835_hwmon", --}; -- - static struct platform_device bcm2835_thermal_device = { - .name = "bcm2835_thermal", - }; -@@ -1006,7 +1002,6 @@ void __init bcm2709_init(void) - bcm_register_device_dt(&bcm2708_bsc1_device); - } - -- bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 8c4474d..110fade 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -1703,16 +1703,6 @@ config SENSORS_ULTRA45 - This driver provides support for the Ultra45 workstation environmental - sensors. - --config SENSORS_BCM2835 -- depends on THERMAL_BCM2835=n -- tristate "Broadcom BCM2835 HWMON Driver" -- help -- If you say yes here you get support for the hardware -- monitoring features of the BCM2835 Chip -- -- This driver can also be built as a module. If so, the module -- will be called bcm2835-hwmon. -- - if ACPI - - comment "ACPI drivers" -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index e7c60cb..6c94147 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -155,7 +155,6 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o - obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o - obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o - obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o --obj-$(CONFIG_SENSORS_BCM2835) += bcm2835-hwmon.o - - obj-$(CONFIG_PMBUS) += pmbus/ - -diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c -deleted file mode 100644 -index d14502c..0000000 ---- a/drivers/hwmon/bcm2835-hwmon.c -+++ /dev/null -@@ -1,219 +0,0 @@ --/***************************************************************************** --* 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 -- --#define MODULE_NAME "bcm2835_hwmon" -- --/*#define HWMON_DEBUG_ENABLE*/ -- --#ifdef HWMON_DEBUG_ENABLE --#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) --#else --#define print_debug(fmt,...) --#endif --#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) --#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__) -- --#define VC_TAG_GET_TEMP 0x00030006 --#define VC_TAG_GET_MAX_TEMP 0x0003000A -- --/* --- STRUCTS --- */ --struct bcm2835_hwmon_data { -- struct device *hwmon_dev; --}; -- --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the tag ID for the temperature */ -- uint32_t buffer_size; /* size of the buffer (should be 8) */ -- uint32_t request_code; /* identifies message as a request (should be 0) */ -- uint32_t id; /* extra ID field (should be 0) */ -- uint32_t val; /* returned value of the temperature */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- --typedef enum { -- TEMP, -- MAX_TEMP, --} temp_type; -- --/* --- PROTOTYPES --- */ --static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf); --static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf); -- --/* --- GLOBALS --- */ -- --static struct bcm2835_hwmon_data *bcm2835_data; --static struct platform_driver bcm2835_hwmon_driver; -- --static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0); --static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP); --static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP); -- --static struct attribute* bcm2835_attributes[] = { -- &sensor_dev_attr_name.dev_attr.attr, -- &sensor_dev_attr_temp1_input.dev_attr.attr, -- &sensor_dev_attr_temp1_max.dev_attr.attr, -- NULL, --}; -- --static struct attribute_group bcm2835_attr_group = { -- .attrs = bcm2835_attributes, --}; -- --/* --- FUNCTIONS --- */ -- --static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf) --{ -- return sprintf(buf,"bcm2835_hwmon\n"); --} -- --static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf) --{ -- struct vc_msg msg; -- int result; -- uint temp = 0; -- int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index; -- -- print_debug("IN"); -- -- /* wipe all previous message data */ -- memset(&msg, 0, sizeof msg); -- -- /* determine the message type */ -- if(index == TEMP) -- msg.tag.tag_id = VC_TAG_GET_TEMP; -- else if (index == MAX_TEMP) -- msg.tag.tag_id = VC_TAG_GET_MAX_TEMP; -- else -- { -- print_debug("Unknown temperature message!"); -- return -EINVAL; -- } -- -- msg.msg_size = sizeof msg; -- msg.tag.buffer_size = 8; -- -- /* send the message */ -- result = bcm_mailbox_property(&msg, sizeof msg); -- -- /* check if it was all ok and return the rate in milli degrees C */ -- if (result == 0 && (msg.request_code & 0x80000000)) -- temp = (uint)msg.tag.val; -- #ifdef HWMON_DEBUG_ENABLE -- else -- print_debug("Failed to get temperature!"); -- #endif -- print_debug("Got temperature as %u",temp); -- print_debug("OUT"); -- return sprintf(buf, "%u\n", temp); --} -- -- --static int bcm2835_hwmon_probe(struct platform_device *pdev) --{ -- int err; -- -- print_debug("IN"); -- print_debug("HWMON Driver has been probed!"); -- -- /* check that the device isn't null!*/ -- if(pdev == NULL) -- { -- print_debug("Platform device is empty!"); -- return -ENODEV; -- } -- -- /* allocate memory for neccessary data */ -- bcm2835_data = kzalloc(sizeof(struct bcm2835_hwmon_data),GFP_KERNEL); -- if(!bcm2835_data) -- { -- print_debug("Unable to allocate memory for hwmon data!"); -- err = -ENOMEM; -- goto kzalloc_error; -- } -- -- /* create the sysfs files */ -- if(sysfs_create_group(&pdev->dev.kobj, &bcm2835_attr_group)) -- { -- print_debug("Unable to create sysfs files!"); -- err = -EFAULT; -- goto sysfs_error; -- } -- -- /* register the hwmon device */ -- bcm2835_data->hwmon_dev = hwmon_device_register(&pdev->dev); -- if (IS_ERR(bcm2835_data->hwmon_dev)) -- { -- err = PTR_ERR(bcm2835_data->hwmon_dev); -- goto hwmon_error; -- } -- print_debug("OUT"); -- return 0; -- -- /* error goto's */ -- hwmon_error: -- sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -- -- sysfs_error: -- kfree(bcm2835_data); -- -- kzalloc_error: -- -- return err; -- --} -- --static int bcm2835_hwmon_remove(struct platform_device *pdev) --{ -- print_debug("IN"); -- hwmon_device_unregister(bcm2835_data->hwmon_dev); -- -- sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -- print_debug("OUT"); -- return 0; --} -- --/* Hwmon Driver */ --static struct platform_driver bcm2835_hwmon_driver = { -- .probe = bcm2835_hwmon_probe, -- .remove = bcm2835_hwmon_remove, -- .driver = { -- .name = "bcm2835_hwmon", -- .owner = THIS_MODULE, -- }, --}; -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Dorian Peake"); --MODULE_DESCRIPTION("HW Monitor driver for bcm2835 chip"); -- --module_platform_driver(bcm2835_hwmon_driver); - -From a4573f4e07996b61582f828189091bede1296d25 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 6 Jun 2015 22:59:28 +0200 -Subject: [PATCH 214/216] BCM270x: Make uart1 work with Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add uart1 to Device Tree. Enable it in AUXENB when it's used. -Remove old platform device. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 10 +++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/mach-bcm2708/bcm2708.c | 35 +++++++++++--------------------- - arch/arm/mach-bcm2709/bcm2709.c | 34 +++++++++++-------------------- - 7 files changed, 38 insertions(+), 45 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index c9053f8..0fa2210 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -18,6 +18,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 32066c3..3fd49d0 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -18,6 +18,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index f38a0c2..3da7d3b 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -13,6 +13,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index a9f1507..8caa234 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -134,6 +134,16 @@ - status = "disabled"; - }; - -+ uart1: uart@7e215040 { -+ compatible = "brcm,bcm2835-aux-uart", "ns16550"; -+ reg = <0x7e215040 0x40>; -+ interrupts = <1 29>; -+ clock-frequency = <500000000>; -+ reg-shift = <2>; -+ no-loopback-test; -+ status = "disabled"; -+ }; ++extern unsigned force_core; + - i2c1: i2c@7e804000 { - compatible = "brcm,bcm2708-i2c"; - reg = <0x7e804000 0x1000>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index a9adaf4..8aaaf1f 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -18,6 +18,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 4f191d9..f1706366 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -353,28 +353,6 @@ static struct platform_device bcm2708_fb_device = { - }, - }; - --static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { -- { -- .mapbase = UART1_BASE + 0x40, -- .irq = IRQ_AUX, -- .uartclk = 500000000, -- .regshift = 2, -- .iotype = UPIO_MEM, -- .flags = UPF_SHARE_IRQ | UPF_FIXED_TYPE | UPF_FIXED_PORT | -- UPF_IOREMAP | UPF_SKIP_TEST, -- .type = PORT_16550, -- }, -- {}, --}; -- --static struct platform_device bcm2708_uart1_device = { -- .name = "serial8250", -- .id = PLAT8250_DEV_PLATFORM, -- .dev = { -- .platform_data = bcm2708_uart1_platform_data, -- }, --}; -- - static struct resource bcm2708_usb_resources[] = { - [0] = { - .start = USB_BASE, -@@ -897,6 +875,17 @@ static void bcm2708_power_off(void) - } - } - -+static void __init bcm2708_init_uart1(void) -+{ -+ struct device_node *np; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); -+ if (of_device_is_available(np)) { -+ pr_info("bcm2708: Mini UART enabled\n"); -+ writel(1, __io_address(UART1_BASE + 0x4)); -+ } -+} -+ - #ifdef CONFIG_OF - static void __init bcm2708_dt_init(void) + static void armctrl_mask_irq(struct irq_data *d) { -@@ -952,13 +941,13 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); + static const unsigned int disables[4] = { +@@ -92,7 +94,13 @@ static void armctrl_unmask_irq(struct irq_data *d) + int i; + if (d->irq >= FIQ_START) { + unsigned int data; +- if (num_online_cpus() > 1) { ++ if (force_core) { ++ data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ data &= ~0xc; ++ data |= ((force_core-1) << 2); ++ writel(data, __io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ } ++ else if (num_online_cpus() > 1) { + data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING)); + data &= ~0xc; + data |= (1 << 2); +@@ -119,6 +127,13 @@ static void armctrl_unmask_irq(struct irq_data *d) + } #endif - bcm2708_init_led(); -+ bcm2708_init_uart1(); - - /* Only create the platform devices for the ALSA driver in the - absence of an enabled "audio" DT node */ + } else if (d->irq >= ARM_IRQ1_BASE && d->irq < ARM_IRQ_LOCAL_BASE) { ++ if (force_core) { ++ unsigned int data; ++ data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ data &= ~0x3; ++ data |= ((force_core-1) << 0); ++ writel(data, __io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ } + unsigned int data = (unsigned int)irq_get_chip_data(d->irq); + writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); + } else if (d->irq == INTERRUPT_ARM_LOCAL_PMU_FAST) { diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index d61bb30..ffa667e 100644 +index 507ff52..c5e51e8 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -363,27 +363,6 @@ static struct platform_device bcm2708_fb_device = { - }, - }; +@@ -96,6 +96,7 @@ static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; + static int pps_gpio_pin = -1; ++unsigned force_core; --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, -- }, -- {}, --}; -- --static struct platform_device bcm2708_uart1_device = { -- .name = "serial8250", -- .id = PLAT8250_DEV_PLATFORM, -- .dev = { -- .platform_data = bcm2708_uart1_platform_data, -- }, --}; -- - static struct resource bcm2708_usb_resources[] = { - [0] = { - .start = USB_BASE, -@@ -918,6 +897,17 @@ static void bcm2709_power_off(void) + static unsigned use_dt = 0; + +@@ -1305,6 +1306,7 @@ MACHINE_START(BCM2708, "BCM2709") + .dt_compat = bcm2709_compat, + MACHINE_END + ++module_param(force_core, uint, 0644); + module_param(boardrev, uint, 0644); + module_param(serial, uint, 0644); + module_param(uart_clock, uint, 0644); + +From a283be0c98260b1f29c8c46df7e8fb2a9cdaf5a8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 18 Jun 2015 17:46:17 +0100 +Subject: [PATCH 75/77] mach-bcm270x: Enable the building of pinctrl-bcm2835 + +--- + drivers/pinctrl/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile +index 6eadf04..ca6e1be 100644 +--- a/drivers/pinctrl/Makefile ++++ b/drivers/pinctrl/Makefile +@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o + obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o + obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o + ++obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_MACH_BCM2709) += bcm/ + obj-$(CONFIG_ARCH_BCM) += bcm/ + obj-$(CONFIG_ARCH_BERLIN) += berlin/ + obj-y += freescale/ + +From fd08db11f15960c30449a5a2cb14d3ab7fd470ea Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 18 Jun 2015 18:06:28 +0100 +Subject: [PATCH 76/77] squash: Fix inconsistency in pinctrl Makefile patch + +--- + drivers/pinctrl/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile +index ca6e1be..9119513 100644 +--- a/drivers/pinctrl/Makefile ++++ b/drivers/pinctrl/Makefile +@@ -38,7 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o + obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o + obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o + +-obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_MACH_BCM2709) += bcm/ ++obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += bcm/ + obj-$(CONFIG_ARCH_BCM) += bcm/ + obj-$(CONFIG_ARCH_BERLIN) += berlin/ + obj-y += freescale/ + +From 05376fce25aaab4f47182a5af04928bfa06f30d6 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 18 Jun 2015 19:53:58 +0100 +Subject: [PATCH 77/77] platform: squash: Remove IRQF_DISABLED + +--- + arch/arm/mach-bcm2708/armctrl.c | 2 +- + arch/arm/mach-bcm2708/bcm2708.c | 2 +- + arch/arm/mach-bcm2708/bcm2708_gpio.c | 2 +- + arch/arm/mach-bcm2709/bcm2709.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c +index 74bacb3..0429225 100644 +--- a/arch/arm/mach-bcm2708/armctrl.c ++++ b/arch/arm/mach-bcm2708/armctrl.c +@@ -305,7 +305,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + irq_set_chip(irq, &armctrl_chip); + irq_set_chip_data(irq, (void *)data); + irq_set_handler(irq, handle_level_irq); +- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - } -+static void __init bcm2709_init_uart1(void) -+{ -+ struct device_node *np; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); -+ if (of_device_is_available(np)) { -+ pr_info("bcm2709: Mini UART enabled\n"); -+ writel(1, __io_address(UART1_BASE + 0x4)); -+ } -+} -+ - #ifdef CONFIG_OF - static void __init bcm2709_dt_init(void) - { -@@ -975,13 +965,13 @@ void __init bcm2709_init(void) - #endif - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); - #endif - bcm2709_init_led(); -+ bcm2709_init_uart1(); - - /* Only create the platform devices for the ALSA driver in the - absence of an enabled "audio" DT node */ - -From 31c0f40b228b657d4c8968c32768992a3bbcefb6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 7 Jun 2015 20:42:35 +0200 -Subject: [PATCH 215/216] fixup: BCM2709: Remove unused clock implementation - ---- - arch/arm/mach-bcm2709/clock.c | 61 ------------------------------------------- - arch/arm/mach-bcm2709/clock.h | 24 ----------------- - 2 files changed, 85 deletions(-) - delete mode 100644 arch/arm/mach-bcm2709/clock.c - delete mode 100644 arch/arm/mach-bcm2709/clock.h - -diff --git a/arch/arm/mach-bcm2709/clock.c b/arch/arm/mach-bcm2709/clock.c -deleted file mode 100644 -index 4fc556e..0000000 ---- a/arch/arm/mach-bcm2709/clock.c -+++ /dev/null -@@ -1,61 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include "clock.h" -- --int clk_enable(struct clk *clk) --{ -- return 0; --} --EXPORT_SYMBOL(clk_enable); -- --void clk_disable(struct clk *clk) --{ --} --EXPORT_SYMBOL(clk_disable); -- --unsigned long clk_get_rate(struct clk *clk) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_get_rate); -- --long clk_round_rate(struct clk *clk, unsigned long rate) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_round_rate); -- --int clk_set_rate(struct clk *clk, unsigned long rate) --{ -- return -EIO; --} --EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2709/clock.h b/arch/arm/mach-bcm2709/clock.h -deleted file mode 100644 -index 5f9d725..0000000 ---- a/arch/arm/mach-bcm2709/clock.h -+++ /dev/null -@@ -1,24 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 -- */ --struct module; -- --struct clk { -- unsigned long rate; --}; - -From 6ae9c7a93909159bde1a92fd305e99443e4ac680 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 7 Jun 2015 20:42:52 +0200 -Subject: [PATCH 216/216] BCM270x: Remove bcm2708_systemtimer and - bcm2708_powerman -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These devices do not have a matching driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 50 -------------------------------------- - arch/arm/mach-bcm2709/bcm2709.c | 54 ----------------------------------------- - 2 files changed, 104 deletions(-) - + armctrl_pm_register(base, irq_start, resume_sources); diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index f1706366..00fc5d6 100644 +index cfc4f13..937c2d3 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -465,33 +465,6 @@ static struct platform_device bcm2708_gpio_device = { +@@ -1028,7 +1028,7 @@ static irqreturn_t bcm2708_timer_interrupt(int irq, void *dev_id) + + static struct irqaction bcm2708_timer_irq = { + .name = "BCM2708 Timer Tick", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2708_timer_interrupt, }; - #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, -- } -- --}; -- --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), -- }, --}; -- - #ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ - static struct resource bcm2835_emmc_resources[] = { - [0] = { -@@ -520,27 +493,6 @@ struct platform_device bcm2835_emmc_device = { +diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c +index c1e9254..e33265d 100644 +--- a/arch/arm/mach-bcm2708/bcm2708_gpio.c ++++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c +@@ -306,7 +306,7 @@ static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id) + + static struct irqaction bcm2708_gpio_irq = { + .name = "BCM2708 GPIO catchall handler", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2708_gpio_interrupt, }; - #endif /* CONFIG_MMC_BCM2835 */ --static struct resource bcm2708_powerman_resources[] = { -- [0] = { -- .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}, --}; -- -- - static struct platform_device bcm2708_alsa_devices[] = { - [0] = { - .name = "bcm2835_AUD0", -@@ -938,10 +890,8 @@ void __init bcm2708_init(void) - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; - bcm_register_device_dt(&w1_device); - #endif -- bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index ffa667e..a5cac5b 100644 +index c5e51e8..fe71c50 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -485,35 +485,6 @@ static struct platform_device bcm2708_gpio_device = { +@@ -1050,7 +1050,7 @@ static irqreturn_t bcm2709_timer_interrupt(int irq, void *dev_id) + + static struct irqaction bcm2709_timer_irq = { + .name = "BCM2709 Timer Tick", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2709_timer_interrupt, }; - #endif --#ifdef SYSTEM_TIMER --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, -- } -- --}; -- --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), -- }, --}; --#endif -- - #ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ - static struct resource bcm2835_emmc_resources[] = { - [0] = { -@@ -542,27 +513,6 @@ struct platform_device bcm2835_emmc_device = { - }; - #endif /* CONFIG_MMC_BCM2835 */ - --static struct resource bcm2708_powerman_resources[] = { -- [0] = { -- .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}, --}; -- -- - static struct platform_device bcm2708_alsa_devices[] = { - [0] = { - .name = "bcm2835_AUD0", -@@ -960,12 +910,8 @@ void __init bcm2709_init(void) - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; - bcm_register_device_dt(&w1_device); - #endif --#ifdef SYSTEM_TIMER -- bcm_register_device(&bcm2708_systemtimer_device); --#endif - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); diff --git a/projects/RPi2/linux/linux.arm.conf b/projects/RPi2/linux/linux.arm.conf index 7825e17135..d472b2287f 100644 --- a/projects/RPi2/linux/linux.arm.conf +++ b/projects/RPi2/linux/linux.arm.conf @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm 4.0.5 Kernel Configuration +# Linux/arm 4.1.0-rc8 Kernel Configuration # CONFIG_ARM=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y @@ -19,6 +19,7 @@ CONFIG_ARM_PATCH_PHYS_VIRT=y CONFIG_NEED_MACH_IO_H=y CONFIG_NEED_MACH_MEMORY_H=y CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y @@ -58,13 +59,14 @@ CONFIG_HAVE_ARCH_AUDITSYSCALL=y # CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_IRQ_DOMAIN=y CONFIG_HANDLE_DOMAIN_IRQ=y # CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y +CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_ARCH_HAS_TICK_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y @@ -103,6 +105,7 @@ CONFIG_RCU_FANOUT_LEAF=16 # CONFIG_TREE_RCU_TRACE is not set CONFIG_RCU_KTHREAD_PRIO=0 # CONFIG_RCU_NOCB_CPU is not set +# CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m CONFIG_IKCONFIG_PROC=y @@ -140,6 +143,7 @@ CONFIG_HAVE_UID16=y CONFIG_BPF=y CONFIG_EXPERT=y # CONFIG_UID16 is not set +CONFIG_MULTIUSER=y # CONFIG_SGETMASK_SYSCALL is not set # CONFIG_SYSFS_SYSCALL is not set CONFIG_SYSCTL_SYSCALL=y @@ -207,6 +211,7 @@ CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_CLONE_BACKWARDS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_OLD_SIGACTION=y @@ -286,11 +291,11 @@ CONFIG_LOCK_SPIN_ON_OWNER=y # System Type # CONFIG_MMU=y +# CONFIG_ARCH_BCM2708 is not set +CONFIG_ARCH_BCM2709=y # CONFIG_ARCH_MULTIPLATFORM is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCM2708 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_GEMINI is not set # CONFIG_ARCH_EBSA110 is not set @@ -309,7 +314,6 @@ CONFIG_MMU=y # CONFIG_ARCH_W90X900 is not set # CONFIG_ARCH_LPC32XX is not set # CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set # CONFIG_ARCH_SHMOBILE_LEGACY is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -317,7 +321,6 @@ CONFIG_MMU=y # CONFIG_ARCH_S3C64XX is not set # CONFIG_ARCH_DAVINCI is not set # CONFIG_ARCH_OMAP1 is not set -CONFIG_ARCH_BCM2709=y CONFIG_BCM2708_GPIO=y CONFIG_BCM2708_NOL2CACHE=y CONFIG_BCM2708_SPIDEV=y @@ -354,9 +357,9 @@ CONFIG_ARM_THUMB=y CONFIG_ARM_VIRT_EXT=y CONFIG_SWP_EMULATE=y # CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set # CONFIG_CPU_BPREDICT_DISABLE is not set CONFIG_KUSER_HELPERS=y +CONFIG_VDSO=y CONFIG_MIGHT_HAVE_CACHE_L2X0=y # CONFIG_CACHE_L2X0 is not set CONFIG_ARM_L1_CACHE_SHIFT_6=y @@ -445,6 +448,7 @@ CONFIG_CLEANCACHE=y CONFIG_FRONTSWAP=y CONFIG_CMA=y # CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=7 # CONFIG_ZSWAP is not set # CONFIG_ZPOOL is not set @@ -502,6 +506,7 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y # CONFIG_CPUFREQ_DT is not set # CONFIG_ARM_KIRKWOOD_CPUFREQ is not set CONFIG_ARM_BCM2835_CPUFREQ=y +# CONFIG_QORIQ_CPUFREQ is not set # # CPU Idle @@ -513,6 +518,7 @@ CONFIG_CPU_IDLE_GOV_MENU=y # # ARM CPU Idle Drivers # +# CONFIG_ARM_CPUIDLE is not set # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set # @@ -531,7 +537,6 @@ CONFIG_NEON=y # Userspace binary formats # CONFIG_BINFMT_ELF=y -CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set @@ -819,7 +824,7 @@ CONFIG_DNS_RESOLVER=y # CONFIG_VSOCKETS is not set # CONFIG_NETLINK_MMAP is not set # CONFIG_NETLINK_DIAG is not set -# CONFIG_NET_MPLS_GSO is not set +# CONFIG_MPLS is not set # CONFIG_HSR is not set # CONFIG_NET_SWITCHDEV is not set CONFIG_RPS=y @@ -847,11 +852,15 @@ CONFIG_BT_RFCOMM_TTY=y CONFIG_BT_HIDP=m CONFIG_BT_LE=y # CONFIG_BT_SELFTEST is not set +# CONFIG_BT_DEBUGFS is not set # # Bluetooth device drivers # +CONFIG_BT_INTEL=m +CONFIG_BT_BCM=m CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTUSB_BCM=y # CONFIG_BT_HCIBTSDIO is not set # CONFIG_BT_HCIUART is not set CONFIG_BT_HCIBCM203X=m @@ -942,7 +951,6 @@ CONFIG_CMA_ALIGNMENT=8 # Bus devices # # CONFIG_BRCMSTB_GISB_ARB is not set -# CONFIG_ARM_CCI is not set # CONFIG_VEXPRESS_CONFIG is not set # CONFIG_CONNECTOR is not set # CONFIG_MTD is not set @@ -974,6 +982,7 @@ CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_PMEM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_MG_DISK is not set @@ -1110,13 +1119,7 @@ CONFIG_TUN=y # Distributed Switch Architecture drivers # # CONFIG_NET_DSA_MV88E6XXX is not set -# CONFIG_NET_DSA_MV88E6060 is not set # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set -# CONFIG_NET_DSA_MV88E6131 is not set -# CONFIG_NET_DSA_MV88E6123_61_65 is not set -# CONFIG_NET_DSA_MV88E6171 is not set -# CONFIG_NET_DSA_MV88E6352 is not set -# CONFIG_NET_DSA_BCM_SF2 is not set # CONFIG_ETHERNET is not set CONFIG_PHYLIB=y @@ -1125,7 +1128,6 @@ CONFIG_PHYLIB=y # # CONFIG_AT803X_PHY is not set # CONFIG_AMD_PHY is not set -# CONFIG_AMD_XGBE_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_DAVICOM_PHY is not set # CONFIG_QSEMI_PHY is not set @@ -1430,8 +1432,8 @@ CONFIG_HW_RANDOM_BCM2708=m # CONFIG_TCG_TPM is not set CONFIG_BRCM_CHAR_DRIVERS=y CONFIG_BCM_VC_CMA=y -# CONFIG_BCM_VC_SM is not set CONFIG_BCM2708_VCMEM=y +# CONFIG_BCM_VC_SM is not set # CONFIG_XILLYBUS is not set # @@ -1548,8 +1550,9 @@ CONFIG_PINCTRL=y CONFIG_PINMUX=y CONFIG_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set -CONFIG_PINCTRL_BCM2835=y +# CONFIG_PINCTRL_AMD is not set # CONFIG_PINCTRL_SINGLE is not set +CONFIG_PINCTRL_BCM2835=y CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y CONFIG_ARCH_REQUIRE_GPIOLIB=y CONFIG_GPIOLIB=y @@ -1559,55 +1562,44 @@ CONFIG_OF_GPIO=y CONFIG_GPIO_SYSFS=y # -# Memory mapped GPIO drivers: +# Memory mapped GPIO drivers # # CONFIG_GPIO_74XX_MMIO is not set -# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_ALTERA is not set # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_EM is not set -# CONFIG_GPIO_ZEVIO is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GRGPIO is not set # CONFIG_GPIO_PL061 is not set # CONFIG_GPIO_SCH311X is not set -# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_ZEVIO is not set # -# I2C GPIO expanders: +# I2C GPIO expanders # -CONFIG_GPIO_ARIZONA=m +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_SX150X is not set -# CONFIG_GPIO_ADP5588 is not set -# CONFIG_GPIO_ADNP is not set # -# PCI GPIO expanders: +# MFD GPIO expanders # +CONFIG_GPIO_ARIZONA=m # -# SPI GPIO expanders: +# SPI GPIO expanders # +# CONFIG_GPIO_74X164 is not set # CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set # -# AC97 GPIO expanders: -# - -# -# LPC GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# - -# -# USB GPIO expanders: +# USB GPIO expanders # CONFIG_W1=m @@ -1736,6 +1728,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set # CONFIG_SENSORS_NCT7802 is not set +# CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT15 is not set @@ -1871,10 +1864,12 @@ CONFIG_MFD_CORE=y # CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77686 is not set # CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_EZX_PCAP is not set # CONFIG_MFD_VIPERBOARD is not set @@ -1890,6 +1885,7 @@ CONFIG_MFD_RTSX_USB=y # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SMSC is not set # CONFIG_ABX500_CORE is not set # CONFIG_MFD_STMPE is not set @@ -2191,7 +2187,6 @@ CONFIG_MEDIA_TUNER_FC0013=m CONFIG_MEDIA_TUNER_TDA18212=m CONFIG_MEDIA_TUNER_E4000=m CONFIG_MEDIA_TUNER_FC2580=m -CONFIG_MEDIA_TUNER_M88TS2022=m CONFIG_MEDIA_TUNER_TUA9001=m CONFIG_MEDIA_TUNER_SI2157=m CONFIG_MEDIA_TUNER_IT913X=m @@ -2448,6 +2443,7 @@ CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m # CONFIG_SND_SOC_FSL_SPDIF is not set # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_QCOM is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set CONFIG_SND_SOC_I2C_AND_SPI=m @@ -2511,6 +2507,8 @@ CONFIG_SND_SOC_WM8731=m # CONFIG_SND_SOC_WM8770 is not set # CONFIG_SND_SOC_WM8776 is not set CONFIG_SND_SOC_WM8804=m +# CONFIG_SND_SOC_WM8804_I2C is not set +# CONFIG_SND_SOC_WM8804_SPI is not set # CONFIG_SND_SOC_WM8903 is not set # CONFIG_SND_SOC_WM8962 is not set # CONFIG_SND_SOC_WM8978 is not set @@ -2551,7 +2549,6 @@ CONFIG_DRAGONRISE_FF=y CONFIG_HID_EZKEY=y # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set -# CONFIG_HID_HUION is not set # CONFIG_HID_KEYTOUCH is not set CONFIG_HID_KYE=y # CONFIG_HID_UCLOGIC is not set @@ -2780,6 +2777,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_EZUSB_FX2 is not set # CONFIG_USB_HSIC_USB3503 is not set # CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set # # USB Physical Layer drivers @@ -2854,6 +2852,7 @@ CONFIG_LEDS_GPIO=y # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set +# CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers @@ -2895,6 +2894,7 @@ CONFIG_RTC_INTF_DEV=y # I2C RTC drivers # # CONFIG_RTC_DRV_ABB5ZES3 is not set +# CONFIG_RTC_DRV_ABX80X is not set CONFIG_RTC_DRV_DS1307=m # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set @@ -2975,7 +2975,6 @@ CONFIG_DMADEVICES=y # DMA Devices # # CONFIG_AMBA_PL08X is not set -# CONFIG_DW_DMAC_CORE is not set # CONFIG_DW_DMAC is not set # CONFIG_PL330_DMA is not set CONFIG_DMA_BCM2708=y @@ -3040,6 +3039,7 @@ CONFIG_LIRC_XBOX=m # CONFIG_GS_FPGABOOT is not set # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set # CONFIG_FB_TFT is not set +# CONFIG_CHROME_PLATFORMS is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y @@ -3052,7 +3052,6 @@ CONFIG_COMMON_CLK=y # CONFIG_CLK_QORIQ is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set -# CONFIG_COMMON_CLK_QCOM is not set # # Hardware Spinlock drivers @@ -3069,9 +3068,9 @@ CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y # CONFIG_SH_TIMER_MTU2 is not set # CONFIG_SH_TIMER_TMU is not set # CONFIG_EM_TIMER_STI is not set -# CONFIG_CLKSRC_VERSATILE is not set CONFIG_MAILBOX=y CONFIG_BCM2708_MBOX=y +# CONFIG_ARM_MHU is not set # CONFIG_PL320_MBOX is not set # CONFIG_ALTERA_MBOX is not set # CONFIG_IOMMU_SUPPORT is not set @@ -3100,6 +3099,7 @@ CONFIG_EXTCON_ARIZONA=m # CONFIG_EXTCON_GPIO is not set # CONFIG_EXTCON_RT8973A is not set # CONFIG_EXTCON_SM5502 is not set +# CONFIG_EXTCON_USB_GPIO is not set # CONFIG_MEMORY is not set # CONFIG_IIO is not set # CONFIG_PWM is not set @@ -3121,6 +3121,11 @@ CONFIG_IRQCHIP=y # # CONFIG_ANDROID is not set +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set + # # File systems # @@ -3131,6 +3136,7 @@ CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT23=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set +# CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set @@ -3158,6 +3164,10 @@ CONFIG_BTRFS_FS=m # CONFIG_BTRFS_DEBUG is not set # CONFIG_BTRFS_ASSERT is not set # CONFIG_NILFS2_FS is not set +CONFIG_F2FS_FS=y +CONFIG_F2FS_STAT_FS=y +# CONFIG_F2FS_FS_XATTR is not set +CONFIG_F2FS_CHECK_FS=y CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y @@ -3245,10 +3255,6 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # CONFIG_PSTORE is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_F2FS_FS=y -CONFIG_F2FS_STAT_FS=y -# CONFIG_F2FS_FS_XATTR is not set -CONFIG_F2FS_CHECK_FS=y CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V2=y @@ -3402,6 +3408,7 @@ CONFIG_PANIC_TIMEOUT=0 # CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set # CONFIG_TIMER_STATS is not set # @@ -3429,6 +3436,7 @@ CONFIG_PANIC_TIMEOUT=0 # # RCU Debugging # +# CONFIG_PROVE_RCU is not set # CONFIG_SPARSE_RCU_POINTER is not set # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set @@ -3467,6 +3475,7 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set +# CONFIG_MEMTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set @@ -3566,7 +3575,6 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA1_ARM=m CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set @@ -3576,7 +3584,6 @@ CONFIG_CRYPTO_SHA256=y # Ciphers # CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_ARM=m # CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_BLOWFISH is not set @@ -3611,6 +3618,10 @@ CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_USER_API_RNG is not set # CONFIG_CRYPTO_HW is not set # CONFIG_ASYMMETRIC_KEY_TYPE is not set +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_AES_ARM=m # CONFIG_BINARY_PRINTF is not set # diff --git a/projects/RPi2/options b/projects/RPi2/options index e8df837a09..28b3747c9d 100644 --- a/projects/RPi2/options +++ b/projects/RPi2/options @@ -57,7 +57,7 @@ # Kernel to use. values can be: # default: default mainline kernel - LINUX="4.0" + LINUX="default" # NOOBS supported hex versions NOOBS_HEX="1040,1041" diff --git a/projects/RPi2/patches/linux/linux-01-RPi_support.patch b/projects/RPi2/patches/linux/linux-01-RPi_support.patch index c1f57bb01c..0008aa8b30 100644 --- a/projects/RPi2/patches/linux/linux-01-RPi_support.patch +++ b/projects/RPi2/patches/linux/linux-01-RPi_support.patch @@ -1,52 +1,77 @@ -From 0e7aaf92061593060fc62957aeec745534add9a4 Mon Sep 17 00:00:00 2001 +From 8e2bdce040b3459de0954cb2f212dea47549131c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 12 May 2013 12:24:19 +0100 -Subject: [PATCH 001/216] Main bcm2708 linux port +Subject: [PATCH 01/77] Main bcm2708/bcm2709 linux port +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix +Signed-off-by: Noralf Trønnes --- - arch/arm/Kconfig | 17 + + arch/arm/Kconfig | 39 ++ arch/arm/Kconfig.debug | 8 + - arch/arm/Makefile | 1 + + arch/arm/Makefile | 2 + + arch/arm/kernel/head.S | 8 + arch/arm/kernel/process.c | 10 + - arch/arm/mach-bcm2708/Kconfig | 26 + - arch/arm/mach-bcm2708/Makefile | 6 + + arch/arm/mach-bcm2708/Kconfig | 30 + + arch/arm/mach-bcm2708/Makefile | 5 + arch/arm/mach-bcm2708/Makefile.boot | 3 + - arch/arm/mach-bcm2708/armctrl.c | 208 +++++++ + arch/arm/mach-bcm2708/armctrl.c | 304 +++++++++ arch/arm/mach-bcm2708/armctrl.h | 27 + - arch/arm/mach-bcm2708/bcm2708.c | 662 +++++++++++++++++++++++ + arch/arm/mach-bcm2708/bcm2708.c | 622 ++++++++++++++++++ arch/arm/mach-bcm2708/bcm2708.h | 49 ++ - arch/arm/mach-bcm2708/clock.c | 61 +++ - arch/arm/mach-bcm2708/clock.h | 24 + - arch/arm/mach-bcm2708/dma.c | 399 ++++++++++++++ - arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++++ - arch/arm/mach-bcm2708/include/mach/arm_power.h | 62 +++ + arch/arm/mach-bcm2708/include/mach/arm_control.h | 419 ++++++++++++ arch/arm/mach-bcm2708/include/mach/clkdev.h | 7 + arch/arm/mach-bcm2708/include/mach/debug-macro.S | 22 + - arch/arm/mach-bcm2708/include/mach/dma.h | 88 +++ - arch/arm/mach-bcm2708/include/mach/entry-macro.S | 69 +++ + arch/arm/mach-bcm2708/include/mach/entry-macro.S | 69 ++ arch/arm/mach-bcm2708/include/mach/frc.h | 38 ++ arch/arm/mach-bcm2708/include/mach/hardware.h | 28 + arch/arm/mach-bcm2708/include/mach/io.h | 27 + - arch/arm/mach-bcm2708/include/mach/irqs.h | 196 +++++++ + arch/arm/mach-bcm2708/include/mach/irqs.h | 196 ++++++ arch/arm/mach-bcm2708/include/mach/memory.h | 57 ++ - arch/arm/mach-bcm2708/include/mach/platform.h | 228 ++++++++ - arch/arm/mach-bcm2708/include/mach/power.h | 26 + + arch/arm/mach-bcm2708/include/mach/platform.h | 228 +++++++ arch/arm/mach-bcm2708/include/mach/system.h | 38 ++ arch/arm/mach-bcm2708/include/mach/timex.h | 23 + arch/arm/mach-bcm2708/include/mach/uncompress.h | 84 +++ - arch/arm/mach-bcm2708/include/mach/vc_mem.h | 35 ++ - arch/arm/mach-bcm2708/include/mach/vcio.h | 165 ++++++ arch/arm/mach-bcm2708/include/mach/vmalloc.h | 20 + - arch/arm/mach-bcm2708/power.c | 197 +++++++ - arch/arm/mach-bcm2708/vc_mem.c | 431 +++++++++++++++ - arch/arm/mach-bcm2708/vcio.c | 474 ++++++++++++++++ + arch/arm/mach-bcm2709/Kconfig | 42 ++ + arch/arm/mach-bcm2709/Makefile | 6 + + arch/arm/mach-bcm2709/Makefile.boot | 3 + + arch/arm/mach-bcm2709/armctrl.c | 361 ++++++++++ + arch/arm/mach-bcm2709/armctrl.h | 27 + + arch/arm/mach-bcm2709/bcm2708_gpio.c | 426 ++++++++++++ + arch/arm/mach-bcm2709/bcm2709.c | 801 +++++++++++++++++++++++ + arch/arm/mach-bcm2709/bcm2709.h | 49 ++ + arch/arm/mach-bcm2709/delay.S | 21 + + arch/arm/mach-bcm2709/include/mach/arm_control.h | 493 ++++++++++++++ + arch/arm/mach-bcm2709/include/mach/barriers.h | 3 + + arch/arm/mach-bcm2709/include/mach/clkdev.h | 7 + + arch/arm/mach-bcm2709/include/mach/debug-macro.S | 22 + + arch/arm/mach-bcm2709/include/mach/entry-macro.S | 123 ++++ + arch/arm/mach-bcm2709/include/mach/frc.h | 38 ++ + arch/arm/mach-bcm2709/include/mach/gpio.h | 17 + + arch/arm/mach-bcm2709/include/mach/hardware.h | 28 + + arch/arm/mach-bcm2709/include/mach/io.h | 27 + + arch/arm/mach-bcm2709/include/mach/irqs.h | 225 +++++++ + arch/arm/mach-bcm2709/include/mach/memory.h | 57 ++ + arch/arm/mach-bcm2709/include/mach/platform.h | 225 +++++++ + arch/arm/mach-bcm2709/include/mach/system.h | 38 ++ + arch/arm/mach-bcm2709/include/mach/timex.h | 23 + + arch/arm/mach-bcm2709/include/mach/uncompress.h | 84 +++ + arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 + + arch/arm/mach-bcm2709/include/mach/vc_support.h | 69 ++ + arch/arm/mach-bcm2709/include/mach/vmalloc.h | 20 + + arch/arm/mach-bcm2709/vc_mem.c | 431 ++++++++++++ + arch/arm/mach-bcm2709/vc_support.c | 318 +++++++++ arch/arm/mm/Kconfig | 2 +- arch/arm/mm/proc-v6.S | 15 +- - arch/arm/tools/mach-types | 1 + + arch/arm/mm/proc-v7.S | 1 + + arch/arm/tools/mach-types | 2 + + drivers/clocksource/arm_arch_timer.c | 36 + drivers/tty/serial/amba-pl011.c | 2 +- include/linux/mmc/host.h | 1 + - 41 files changed, 4251 insertions(+), 5 deletions(-) + 62 files changed, 6436 insertions(+), 5 deletions(-) create mode 100644 arch/arm/mach-bcm2708/Kconfig create mode 100644 arch/arm/mach-bcm2708/Makefile create mode 100644 arch/arm/mach-bcm2708/Makefile.boot @@ -54,14 +79,9 @@ Signed-off-by: popcornmix create mode 100644 arch/arm/mach-bcm2708/armctrl.h create mode 100644 arch/arm/mach-bcm2708/bcm2708.c create mode 100644 arch/arm/mach-bcm2708/bcm2708.h - create mode 100644 arch/arm/mach-bcm2708/clock.c - create mode 100644 arch/arm/mach-bcm2708/clock.h - create mode 100644 arch/arm/mach-bcm2708/dma.c create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_control.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/arm_power.h create mode 100644 arch/arm/mach-bcm2708/include/mach/clkdev.h create mode 100644 arch/arm/mach-bcm2708/include/mach/debug-macro.S - create mode 100644 arch/arm/mach-bcm2708/include/mach/dma.h create mode 100644 arch/arm/mach-bcm2708/include/mach/entry-macro.S create mode 100644 arch/arm/mach-bcm2708/include/mach/frc.h create mode 100644 arch/arm/mach-bcm2708/include/mach/hardware.h @@ -69,57 +89,102 @@ Signed-off-by: popcornmix create mode 100644 arch/arm/mach-bcm2708/include/mach/irqs.h create mode 100644 arch/arm/mach-bcm2708/include/mach/memory.h create mode 100644 arch/arm/mach-bcm2708/include/mach/platform.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/power.h create mode 100644 arch/arm/mach-bcm2708/include/mach/system.h create mode 100644 arch/arm/mach-bcm2708/include/mach/timex.h create mode 100644 arch/arm/mach-bcm2708/include/mach/uncompress.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_mem.h - create mode 100644 arch/arm/mach-bcm2708/include/mach/vcio.h create mode 100644 arch/arm/mach-bcm2708/include/mach/vmalloc.h - create mode 100644 arch/arm/mach-bcm2708/power.c - create mode 100644 arch/arm/mach-bcm2708/vc_mem.c - create mode 100644 arch/arm/mach-bcm2708/vcio.c + create mode 100644 arch/arm/mach-bcm2709/Kconfig + create mode 100644 arch/arm/mach-bcm2709/Makefile + create mode 100644 arch/arm/mach-bcm2709/Makefile.boot + create mode 100644 arch/arm/mach-bcm2709/armctrl.c + create mode 100644 arch/arm/mach-bcm2709/armctrl.h + create mode 100644 arch/arm/mach-bcm2709/bcm2708_gpio.c + create mode 100644 arch/arm/mach-bcm2709/bcm2709.c + create mode 100644 arch/arm/mach-bcm2709/bcm2709.h + create mode 100644 arch/arm/mach-bcm2709/delay.S + create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_control.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/clkdev.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/debug-macro.S + create mode 100644 arch/arm/mach-bcm2709/include/mach/entry-macro.S + create mode 100644 arch/arm/mach-bcm2709/include/mach/frc.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/gpio.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/hardware.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/io.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/irqs.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/memory.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/platform.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/system.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/timex.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/uncompress.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h + create mode 100755 arch/arm/mach-bcm2709/include/mach/vc_support.h + create mode 100644 arch/arm/mach-bcm2709/include/mach/vmalloc.h + create mode 100644 arch/arm/mach-bcm2709/vc_mem.c + create mode 100644 arch/arm/mach-bcm2709/vc_support.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index cf4c0c9..6876ae8 100644 +index 45df48b..bd9b2f3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -369,6 +369,22 @@ config ARCH_AT91 - This enables support for systems based on Atmel - AT91RM9200, AT91SAM9 and SAMA5 processors. +@@ -314,6 +314,42 @@ choice + default ARCH_VERSATILE if !MMU + default ARCH_MULTIPLATFORM if MMU +config ARCH_BCM2708 + bool "Broadcom BCM2708 family" + select CPU_V6 + select ARM_AMBA -+ select HAVE_CLK + select HAVE_SCHED_CLOCK + select NEED_MACH_GPIO_H + select NEED_MACH_MEMORY_H -+ select CLKDEV_LOOKUP ++ select COMMON_CLK ++ select ARCH_HAS_CPUFREQ + select GENERIC_CLOCKEVENTS + select ARM_ERRATA_411920 + select MACH_BCM2708 + select VC4 ++ select FIQ + help + This enables support for Broadcom BCM2708 boards. + - config ARCH_CLPS711X - bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" - select ARCH_REQUIRE_GPIOLIB -@@ -967,6 +983,7 @@ source "arch/arm/plat-versatile/Kconfig" - source "arch/arm/mach-vt8500/Kconfig" - - source "arch/arm/mach-w90x900/Kconfig" ++config ARCH_BCM2709 ++ bool "Broadcom BCM2709 family" ++ select ARCH_HAS_BARRIERS if SMP ++ select CPU_V7 ++ select HAVE_SMP ++ select ARM_AMBA ++ select MIGHT_HAVE_CACHE_L2X0 ++ select HAVE_SCHED_CLOCK ++ select NEED_MACH_MEMORY_H ++ select NEED_MACH_IO_H ++ select COMMON_CLK ++ select ARCH_HAS_CPUFREQ ++ select GENERIC_CLOCKEVENTS ++ select MACH_BCM2709 ++ select VC4 ++ select FIQ ++ help ++ This enables support for Broadcom BCM2709 boards. ++ + config ARCH_MULTIPLATFORM + bool "Allow multiple platforms to be selected" + depends on MMU +@@ -823,6 +859,9 @@ config ARCH_VIRT + # Kconfigs may be included either alphabetically (according to the + # plat- suffix) or along side the corresponding mach-* source. + # +source "arch/arm/mach-bcm2708/Kconfig" ++source "arch/arm/mach-bcm2709/Kconfig" ++ + source "arch/arm/mach-mvebu/Kconfig" - source "arch/arm/mach-zynq/Kconfig" - + source "arch/arm/mach-alpine/Kconfig" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug -index 970de75..eaadbe8 100644 +index 0c12ffb..18db6c4 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug -@@ -1209,6 +1209,14 @@ choice +@@ -1197,6 +1197,14 @@ choice options; the platform specific options are deprecated and will be soon removed. @@ -135,22 +200,42 @@ index 970de75..eaadbe8 100644 config DEBUG_AT91_UART diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index eb7bb51..27c0f92 100644 +index 985227c..e5df9a5 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile -@@ -146,6 +146,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 +@@ -142,6 +142,8 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 + + # Machine directory name. This list is sorted alphanumerically + # by CONFIG_* macro name. ++machine-$(CONFIG_ARCH_BCM2708) += bcm2708 ++machine-$(CONFIG_ARCH_BCM2709) += bcm2709 + machine-$(CONFIG_ARCH_ALPINE) += alpine machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AXXIA) += axxia - machine-$(CONFIG_ARCH_BCM) += bcm -+machine-$(CONFIG_ARCH_BCM2708) += bcm2708 - machine-$(CONFIG_ARCH_BERLIN) += berlin - machine-$(CONFIG_ARCH_CLPS711X) += clps711x - machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx +diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S +index 3637973..380430a 100644 +--- a/arch/arm/kernel/head.S ++++ b/arch/arm/kernel/head.S +@@ -680,6 +680,14 @@ ARM_BE8(rev16 ip, ip) + ldrcc r7, [r4], #4 @ use branch for delay slot + bcc 1b + ret lr ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop ++ nop + #endif + ENDPROC(__fixup_a_pv_table) + diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c -index 2bf1a16..2915516 100644 +index f192a2a..f638dae 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c -@@ -172,6 +172,16 @@ void arch_cpu_idle_dead(void) +@@ -98,6 +98,16 @@ void arch_cpu_idle_dead(void) } #endif @@ -164,15 +249,15 @@ index 2bf1a16..2915516 100644 + +__setup("reboot=", reboot_setup); + - /* - * Called by kexec, immediately prior to machine_kexec(). - * + void __show_regs(struct pt_regs *regs) + { + unsigned long flags; diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig new file mode 100644 -index 0000000..1f11478 +index 0000000..4955422 --- /dev/null +++ b/arch/arm/mach-bcm2708/Kconfig -@@ -0,0 +1,26 @@ +@@ -0,0 +1,30 @@ +menu "Broadcom BCM2708 Implementations" + depends on ARCH_BCM2708 + @@ -184,12 +269,16 @@ index 0000000..1f11478 + help + Include support for the Broadcom(R) BCM2708 platform. + -+config BCM2708_VCMEM -+ bool "Videocore Memory" ++config BCM2708_DT ++ bool "BCM2708 Device Tree support" + depends on MACH_BCM2708 -+ default y -+ help -+ Helper for videocore memory access and total size allocation. ++ default n ++ select USE_OF ++ select ARCH_REQUIRE_GPIOLIB ++ select PINCTRL ++ select PINCTRL_BCM2835 ++ help ++ Enable Device Tree support for BCM2708 + +config BCM2708_NOL2CACHE + bool "Videocore L2 cache disable" @@ -201,16 +290,15 @@ index 0000000..1f11478 +endmenu diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile new file mode 100644 -index 0000000..c76f39bc +index 0000000..e7d5a29 --- /dev/null +++ b/arch/arm/mach-bcm2708/Makefile -@@ -0,0 +1,6 @@ +@@ -0,0 +1,5 @@ +# +# Makefile for the linux kernel. +# + -+obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o ++obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o diff --git a/arch/arm/mach-bcm2708/Makefile.boot b/arch/arm/mach-bcm2708/Makefile.boot new file mode 100644 index 0000000..67039c3 @@ -222,10 +310,10 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c new file mode 100644 -index 0000000..ef1c8d5 +index 0000000..cd252fa --- /dev/null +++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -0,0 +1,208 @@ +@@ -0,0 +1,304 @@ +/* + * linux/arch/arm/mach-bcm2708/armctrl.c + * @@ -251,6 +339,8 @@ index 0000000..ef1c8d5 +#include +#include +#include ++#include ++#include + +#include +#include @@ -297,6 +387,99 @@ index 0000000..ef1c8d5 + writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); +} + ++#ifdef CONFIG_OF ++ ++#define NR_IRQS_BANK0 21 ++#define NR_BANKS 3 ++#define IRQS_PER_BANK 32 ++ ++/* from drivers/irqchip/irq-bcm2835.c */ ++static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, ++ const u32 *intspec, unsigned int intsize, ++ unsigned long *out_hwirq, unsigned int *out_type) ++{ ++ if (WARN_ON(intsize != 2)) ++ return -EINVAL; ++ ++ if (WARN_ON(intspec[0] >= NR_BANKS)) ++ return -EINVAL; ++ ++ if (WARN_ON(intspec[1] >= IRQS_PER_BANK)) ++ return -EINVAL; ++ ++ if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0)) ++ return -EINVAL; ++ ++ if (intspec[0] == 0) ++ *out_hwirq = ARM_IRQ0_BASE + intspec[1]; ++ else if (intspec[0] == 1) ++ *out_hwirq = ARM_IRQ1_BASE + intspec[1]; ++ else ++ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; ++ ++ /* reverse remap_irqs[] */ ++ switch (*out_hwirq) { ++ case INTERRUPT_VC_JPEG: ++ *out_hwirq = INTERRUPT_JPEG; ++ break; ++ case INTERRUPT_VC_USB: ++ *out_hwirq = INTERRUPT_USB; ++ break; ++ case INTERRUPT_VC_3D: ++ *out_hwirq = INTERRUPT_3D; ++ break; ++ case INTERRUPT_VC_DMA2: ++ *out_hwirq = INTERRUPT_DMA2; ++ break; ++ case INTERRUPT_VC_DMA3: ++ *out_hwirq = INTERRUPT_DMA3; ++ break; ++ case INTERRUPT_VC_I2C: ++ *out_hwirq = INTERRUPT_I2C; ++ break; ++ case INTERRUPT_VC_SPI: ++ *out_hwirq = INTERRUPT_SPI; ++ break; ++ case INTERRUPT_VC_I2SPCM: ++ *out_hwirq = INTERRUPT_I2SPCM; ++ break; ++ case INTERRUPT_VC_SDIO: ++ *out_hwirq = INTERRUPT_SDIO; ++ break; ++ case INTERRUPT_VC_UART: ++ *out_hwirq = INTERRUPT_UART; ++ break; ++ case INTERRUPT_VC_ARASANSDIO: ++ *out_hwirq = INTERRUPT_ARASANSDIO; ++ break; ++ } ++ ++ *out_type = IRQ_TYPE_NONE; ++ return 0; ++} ++ ++static struct irq_domain_ops armctrl_ops = { ++ .xlate = armctrl_xlate ++}; ++ ++void __init armctrl_dt_init(void) ++{ ++ struct device_node *np; ++ struct irq_domain *domain; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic"); ++ if (!np) ++ return; ++ ++ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS, ++ IRQ_ARMCTRL_START, 0, ++ &armctrl_ops, NULL); ++ WARN_ON(!domain); ++} ++#else ++void __init armctrl_dt_init(void) { } ++#endif /* CONFIG_OF */ ++ +#if defined(CONFIG_PM) + +/* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ @@ -432,6 +615,7 @@ index 0000000..ef1c8d5 + } + + armctrl_pm_register(base, irq_start, resume_sources); ++ armctrl_dt_init(); + return 0; +} diff --git a/arch/arm/mach-bcm2708/armctrl.h b/arch/arm/mach-bcm2708/armctrl.h @@ -469,10 +653,10 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c new file mode 100644 -index 0000000..9b4e709 +index 0000000..d6659b0 --- /dev/null +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -0,0 +1,662 @@ +@@ -0,0 +1,622 @@ +/* + * linux/arch/arm/mach-bcm2708/bcm2708.c + * @@ -502,10 +686,14 @@ index 0000000..9b4e709 +#include +#include +#include ++#include ++#include +#include +#include +#include +#include ++#include ++#include + +#include +#include @@ -523,15 +711,12 @@ index 0000000..9b4e709 +#include + +#include -+#include -+#include +#include + +#include + +#include "bcm2708.h" +#include "armctrl.h" -+#include "clock.h" + +#ifdef CONFIG_BCM_VC_CMA +#include @@ -552,11 +737,13 @@ index 0000000..9b4e709 + +/* command line parameters */ +static unsigned boardrev, serial; -+static unsigned uart_clock; ++static unsigned uart_clock = UART0_CLOCK; +static unsigned disk_led_gpio = 16; +static unsigned disk_led_active_low = 1; +static unsigned reboot_part = 0; + ++static unsigned use_dt = 0; ++ +static void __init bcm2708_init_led(void); + +void __init bcm2708_init_irq(void) @@ -662,44 +849,40 @@ index 0000000..9b4e709 + } +} + ++struct clk __init *bcm2708_clk_register(const char *name, unsigned long fixed_rate) ++{ ++ struct clk *clk; + -+/* -+ * These are fixed clocks. -+ */ -+static struct clk ref24_clk = { -+ .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */ -+}; ++ clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, ++ fixed_rate); ++ if (IS_ERR(clk)) ++ pr_err("%s not registered\n", name); + -+static struct clk osc_clk = { -+#ifdef CONFIG_ARCH_BCM2708_CHIPIT -+ .rate = 27000000, -+#else -+ .rate = 500000000, /* ARM clock is set from the VideoCore booter */ -+#endif -+}; ++ return clk; ++} + -+/* warning - the USB needs a clock > 34MHz */ ++void __init bcm2708_register_clkdev(struct clk *clk, const char *name) ++{ ++ int ret; + -+#ifdef CONFIG_MMC_BCM2708 -+static struct clk sdhost_clk = { -+#ifdef CONFIG_ARCH_BCM2708_CHIPIT -+ .rate = 4000000, /* 4MHz */ -+#else -+ .rate = 250000000, /* 250MHz */ -+#endif -+}; -+#endif ++ ret = clk_register_clkdev(clk, NULL, name); ++ if (ret) ++ pr_err("%s alias not registered\n", name); ++} + -+static struct clk_lookup lookups[] = { -+ { /* UART0 */ -+ .dev_id = "dev:f1", -+ .clk = &ref24_clk, -+ }, -+ { /* USB */ -+ .dev_id = "bcm2708_usb", -+ .clk = &osc_clk, -+ } -+}; ++void __init bcm2708_init_clocks(void) ++{ ++ struct clk *clk; ++ ++ clk = bcm2708_clk_register("uart0_clk", uart_clock); ++ bcm2708_register_clkdev(clk, "dev:f1"); ++ ++ clk = bcm2708_clk_register("sdhost_clk", 250000000); ++ bcm2708_register_clkdev(clk, "mmc-bcm2835.0"); ++ bcm2708_register_clkdev(clk, "bcm2708_spi.0"); ++ bcm2708_register_clkdev(clk, "bcm2708_i2c.0"); ++ bcm2708_register_clkdev(clk, "bcm2708_i2c.1"); ++} + +#define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ } +#define UART0_DMA { 15, 14 } @@ -710,21 +893,6 @@ index 0000000..9b4e709 + &uart0_device, +}; + -+static struct resource bcm2708_dmaman_resources[] = { -+ { -+ .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), -+}; -+ +static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_fb_device = { @@ -738,38 +906,17 @@ index 0000000..9b4e709 + }, +}; + -+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, -+ }, -+ {}, -+}; -+ -+static struct platform_device bcm2708_uart1_device = { -+ .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, -+ }, ++ .start = USB_BASE, ++ .end = USB_BASE + SZ_128K - 1, ++ .flags = IORESOURCE_MEM, ++ }, + [1] = { -+ .start = IRQ_USB, -+ .end = IRQ_USB, -+ .flags = IORESOURCE_IRQ, -+ }, ++ .start = IRQ_USB, ++ .end = IRQ_USB, ++ .flags = IORESOURCE_IRQ, ++ }, +}; + +static u64 usb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); @@ -786,17 +933,21 @@ index 0000000..9b4e709 +}; + +static struct resource bcm2708_vcio_resources[] = { -+ [0] = { /* mailbox/semaphore/doorbell access */ -+ .start = MCORE_BASE, -+ .end = MCORE_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, ++ { ++ .start = ARMCTRL_0_MAIL0_BASE, ++ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_MAILBOX, ++ .end = IRQ_ARM_MAILBOX, ++ .flags = IORESOURCE_IRQ, ++ }, +}; + +static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_vcio_device = { -+ .name = BCM_VCIO_DRIVER_NAME, ++ .name = "bcm2708_vcio", + .id = -1, /* only one VideoCore I/O area */ + .resource = bcm2708_vcio_resources, + .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), @@ -806,53 +957,6 @@ index 0000000..9b4e709 + }, +}; + -+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, -+ } -+ -+}; -+ -+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), -+ }, -+}; -+ -+static struct resource bcm2708_powerman_resources[] = { -+ [0] = { -+ .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}, -+}; -+ +int __init bcm_register_device(struct platform_device *pdev) +{ + int ret; @@ -865,6 +969,16 @@ index 0000000..9b4e709 + return ret; +} + ++/* ++ * Use these macros for platform and i2c devices that are present in the ++ * Device Tree. This way the devices are only added on non-DT systems. ++ */ ++#define bcm_register_device_dt(pdev) \ ++ if (!use_dt) bcm_register_device(pdev) ++ ++#define i2c_register_board_info_dt(busnum, info, n) \ ++ if (!use_dt) i2c_register_board_info(busnum, info, n) ++ +int calc_rsts(int partition) +{ + return PM_PASSWORD | @@ -930,6 +1044,35 @@ index 0000000..9b4e709 + } +} + ++static void __init bcm2708_init_uart1(void) ++{ ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); ++ if (of_device_is_available(np)) { ++ pr_info("bcm2708: Mini UART enabled\n"); ++ writel(1, __io_address(UART1_BASE + 0x4)); ++ } ++} ++ ++#ifdef CONFIG_OF ++static void __init bcm2708_dt_init(void) ++{ ++ int ret; ++ ++ of_clk_init(NULL); ++ ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++ if (ret) { ++ pr_err("of_platform_populate failed: %d\n", ret); ++ /* Proceed as if CONFIG_OF was not defined */ ++ } else { ++ use_dt = 1; ++ } ++} ++#else ++static void __init bcm2708_dt_init(void) { } ++#endif /* CONFIG_OF */ ++ +void __init bcm2708_init(void) +{ + int i; @@ -940,25 +1083,24 @@ index 0000000..9b4e709 + printk("bcm2708.uart_clock = %d\n", uart_clock); + pm_power_off = bcm2708_power_off; + -+ if (uart_clock) -+ lookups[0].clk->rate = uart_clock; ++ bcm2708_init_clocks(); ++ bcm2708_dt_init(); + -+ for (i = 0; i < ARRAY_SIZE(lookups); i++) -+ clkdev_add(&lookups[i]); -+ -+ bcm_register_device(&bcm2708_dmaman_device); + bcm_register_device(&bcm2708_vcio_device); -+ bcm_register_device(&bcm2708_systemtimer_device); -+ bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device(&bcm2708_uart1_device); -+ bcm_register_device(&bcm2708_powerman_device); ++#ifdef CONFIG_BCM2708_GPIO ++ bcm_register_device_dt(&bcm2708_gpio_device); ++#endif ++ bcm_register_device_dt(&bcm2708_fb_device); ++ bcm_register_device_dt(&bcm2708_usb_device); + + bcm2708_init_led(); ++ bcm2708_init_uart1(); + -+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -+ struct amba_device *d = amba_devs[i]; -+ amba_device_register(d, &iomem_resource); ++ if (!use_dt) { ++ 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; @@ -1041,10 +1183,6 @@ index 0000000..9b4e709 + bcm2708_clocksource_init(); + + /* -+ * Initialise to a known state (all timers off) -+ */ -+ writel(0, __io_address(ARM_T_CONTROL)); -+ /* + * Make irqs happen for the system timer + */ + setup_irq(IRQ_TIMER3, &bcm2708_timer_irq); @@ -1091,9 +1229,9 @@ index 0000000..9b4e709 + +static void __init bcm2708_init_led(void) +{ -+ bcm2708_leds[0].gpio = disk_led_gpio; -+ bcm2708_leds[0].active_low = disk_led_active_low; -+ platform_device_register(&bcm2708_led_device); ++ bcm2708_leds[0].gpio = disk_led_gpio; ++ bcm2708_leds[0].active_low = disk_led_active_low; ++ bcm_register_device_dt(&bcm2708_led_device); +} +#else +static inline void bcm2708_init_led(void) @@ -1118,6 +1256,11 @@ index 0000000..9b4e709 +#endif +} + ++static const char * const bcm2708_compat[] = { ++ "brcm,bcm2708", ++ NULL ++}; ++ +MACHINE_START(BCM2708, "BCM2708") + /* Maintainer: Broadcom Europe Ltd. */ + .map_io = bcm2708_map_io, @@ -1127,6 +1270,7 @@ index 0000000..9b4e709 + .init_early = bcm2708_init_early, + .reserve = board_reserve, + .restart = bcm2708_restart, ++ .dt_compat = bcm2708_compat, +MACHINE_END + +module_param(boardrev, uint, 0644); @@ -1190,508 +1334,6 @@ index 0000000..e339a93 +} + +#endif -diff --git a/arch/arm/mach-bcm2708/clock.c b/arch/arm/mach-bcm2708/clock.c -new file mode 100644 -index 0000000..4fc556e ---- /dev/null -+++ b/arch/arm/mach-bcm2708/clock.c -@@ -0,0 +1,61 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "clock.h" -+ -+int clk_enable(struct clk *clk) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(clk_enable); -+ -+void clk_disable(struct clk *clk) -+{ -+} -+EXPORT_SYMBOL(clk_disable); -+ -+unsigned long clk_get_rate(struct clk *clk) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_get_rate); -+ -+long clk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_round_rate); -+ -+int clk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ return -EIO; -+} -+EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2708/clock.h b/arch/arm/mach-bcm2708/clock.h -new file mode 100644 -index 0000000..5f9d725 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/clock.h -@@ -0,0 +1,24 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 -+ */ -+struct module; -+ -+struct clk { -+ unsigned long rate; -+}; -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -new file mode 100644 -index 0000000..51d147a ---- /dev/null -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -0,0 +1,399 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/dma.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/*****************************************************************************\ -+ * * -+ * Configuration * -+ * * -+\*****************************************************************************/ -+ -+#define CACHE_LINE_MASK 31 -+#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME -+#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -+ -+/* valid only for channels 0 - 14, 15 has its own base address */ -+#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ -+#define BCM2708_DMA_CHANIO(dma_base, n) \ -+ ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -+ -+ -+/*****************************************************************************\ -+ * * -+ * DMA Auxilliary Functions * -+ * * -+\*****************************************************************************/ -+ -+/* A DMA buffer on an arbitrary boundary may separate a cache line into a -+ section inside the DMA buffer and another section outside it. -+ Even if we flush DMA buffers from the cache there is always the chance that -+ during a DMA someone will access the part of a cache line that is outside -+ the DMA buffer - which will then bring in unwelcome data. -+ Without being able to dictate our own buffer pools we must insist that -+ DMA buffers consist of a whole number of cache lines. -+*/ -+ -+extern int -+bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) -+{ -+ int i; -+ -+ for (i = 0; i < sg_len; i++) { -+ if (sg_ptr[i].offset & CACHE_LINE_MASK || -+ sg_ptr[i].length & CACHE_LINE_MASK) -+ return 0; -+ } -+ -+ return 1; -+} -+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -+ -+extern void -+bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) -+{ -+ dsb(); /* ARM data synchronization (push) operation */ -+ -+ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -+ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); -+} -+ -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ /* ugly busy wait only option for now */ -+ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -+ cpu_relax(); -+} -+ -+EXPORT_SYMBOL_GPL(bcm_dma_start); -+ -+/* Complete an ongoing DMA (assuming its results are to be ignored) -+ Does nothing if there is no DMA in progress. -+ This routine waits for the current AXI transfer to complete before -+ terminating the current DMA. If the current transfer is hung on a DREQ used -+ by an uncooperative peripheral the AXI transfer may never complete. In this -+ case the routine times out and return a non-zero error code. -+ Use of this routine doesn't guarantee that the ongoing or aborted DMA -+ does not produce an interrupt. -+*/ -+extern int -+bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ unsigned long int cs; -+ int rc = 0; -+ -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (BCM2708_DMA_ACTIVE & cs) { -+ long int timeout = 10000; -+ -+ /* write 0 to the active bit - pause the DMA */ -+ writel(0, dma_chan_base + BCM2708_DMA_CS); -+ -+ /* wait for any current AXI transfer to complete */ -+ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -+ /* we'll un-pause when we set of our next DMA */ -+ rc = -ETIMEDOUT; -+ -+ } else if (BCM2708_DMA_ACTIVE & cs) { -+ /* terminate the control block chain */ -+ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -+ -+ /* abort the whole DMA */ -+ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -+ dma_chan_base + BCM2708_DMA_CS); -+ } -+ } -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_abort); -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Device Methods * -+ * * -+\*****************************************************************************/ -+ -+struct vc_dmaman { -+ void __iomem *dma_base; -+ u32 chan_available; /* bitmap of available channels */ -+ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ -+}; -+ -+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -+ u32 chans_available) -+{ -+ dmaman->dma_base = dma_base; -+ dmaman->chan_available = chans_available; -+ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -+} -+ -+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) -+{ -+ u32 chans; -+ int feature; -+ -+ chans = dmaman->chan_available; -+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -+ /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) -+ chans &= dmaman->has_feature[feature]; -+ -+ if (chans) { -+ int chan = 0; -+ /* return the ordinal of the first channel in the bitmap */ -+ while (chans != 0 && (chans & 1) == 0) { -+ chans >>= 1; -+ chan++; -+ } -+ /* claim the channel */ -+ dmaman->chan_available &= ~(1 << chan); -+ return chan; -+ } else -+ return -ENOMEM; -+} -+ -+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) -+{ -+ if (chan < 0) -+ return -EINVAL; -+ else if ((1 << chan) & dmaman->chan_available) -+ return -EIDRM; -+ else { -+ dmaman->chan_available |= (1 << chan); -+ return 0; -+ } -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA IRQs * -+ * * -+\*****************************************************************************/ -+ -+static unsigned char bcm_dma_irqs[] = { -+ IRQ_DMA0, -+ IRQ_DMA1, -+ IRQ_DMA2, -+ IRQ_DMA3, -+ IRQ_DMA4, -+ IRQ_DMA5, -+ IRQ_DMA6, -+ IRQ_DMA7, -+ IRQ_DMA8, -+ IRQ_DMA9, -+ IRQ_DMA10, -+ IRQ_DMA11, -+ IRQ_DMA12 -+}; -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Monitor * -+ * * -+\*****************************************************************************/ -+ -+static struct device *dmaman_dev; /* we assume there's only one! */ -+ -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq) -+{ -+ if (!dmaman_dev) -+ return -ENODEV; -+ else { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ if (rc >= 0) { -+ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -+ rc); -+ *out_dma_irq = bcm_dma_irqs[rc]; -+ } -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -+ -+extern int bcm_dma_chan_free(int channel) -+{ -+ if (dmaman_dev) { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_free(dmaman, channel); -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -+ -+static int dev_dmaman_register(const char *dev_name, struct device *dev) -+{ -+ int rc = dmaman_dev ? -EINVAL : 0; -+ dmaman_dev = dev; -+ return rc; -+} -+ -+static void dev_dmaman_deregister(const char *dev_name, struct device *dev) -+{ -+ dmaman_dev = NULL; -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA Device * -+ * * -+\*****************************************************************************/ -+ -+static int dmachans = -1; /* module parameter */ -+ -+static int bcm_dmaman_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_dmaman *dmaman; -+ struct resource *dma_res = NULL; -+ void __iomem *dma_base = NULL; -+ int have_dma_region = 0; -+ -+ dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -+ if (NULL == dmaman) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "DMA management memory\n"); -+ ret = -ENOMEM; -+ } else { -+ -+ dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (dma_res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ } else if (!request_mem_region(dma_res->start, -+ resource_size(dma_res), -+ DRIVER_NAME)) { -+ dev_err(&pdev->dev, "cannot obtain DMA region\n"); -+ ret = -EBUSY; -+ } else { -+ have_dma_region = 1; -+ dma_base = ioremap(dma_res->start, -+ resource_size(dma_res)); -+ if (!dma_base) { -+ dev_err(&pdev->dev, "cannot map DMA region\n"); -+ ret = -ENOMEM; -+ } else { -+ /* use module parameter if one was provided */ -+ if (dmachans > 0) -+ vc_dmaman_init(dmaman, dma_base, -+ dmachans); -+ else -+ vc_dmaman_init(dmaman, dma_base, -+ DEFAULT_DMACHAN_BITMAP); -+ -+ platform_set_drvdata(pdev, dmaman); -+ dev_dmaman_register(DRIVER_NAME, &pdev->dev); -+ -+ printk(KERN_INFO DRIVER_NAME ": DMA manager " -+ "at %p\n", dma_base); -+ } -+ } -+ } -+ if (ret != 0) { -+ if (dma_base) -+ iounmap(dma_base); -+ if (dma_res && have_dma_region) -+ release_mem_region(dma_res->start, -+ resource_size(dma_res)); -+ if (dmaman) -+ kfree(dmaman); -+ } -+ return ret; -+} -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -+ kfree(dmaman); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_dmaman_driver = { -+ .probe = bcm_dmaman_probe, -+ .remove = bcm_dmaman_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+/*****************************************************************************\ -+ * * -+ * Driver init/exit * -+ * * -+\*****************************************************************************/ -+ -+static int __init bcm_dmaman_drv_init(void) -+{ -+ int ret; -+ -+ ret = platform_driver_register(&bcm_dmaman_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_dmaman_drv_exit(void) -+{ -+ platform_driver_unregister(&bcm_dmaman_driver); -+} -+ -+module_init(bcm_dmaman_drv_init); -+module_exit(bcm_dmaman_drv_exit); -+ -+module_param(dmachans, int, 0644); -+ -+MODULE_AUTHOR("Gray Girling "); -+MODULE_DESCRIPTION("DMA channel manager driver"); -+MODULE_LICENSE("GPL"); -+ -+MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); diff --git a/arch/arm/mach-bcm2708/include/mach/arm_control.h b/arch/arm/mach-bcm2708/include/mach/arm_control.h new file mode 100644 index 0000000..a82bb92b @@ -2117,74 +1759,6 @@ index 0000000..a82bb92b +#define AJBTDO HW_REGISTER_RW(AJB_BASE+0x0c) + +#endif -diff --git a/arch/arm/mach-bcm2708/include/mach/arm_power.h b/arch/arm/mach-bcm2708/include/mach/arm_power.h -new file mode 100644 -index 0000000..d3bf245 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/arm_power.h -@@ -0,0 +1,62 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _ARM_POWER_H -+#define _ARM_POWER_H -+ -+/* Use meaningful names on each side */ -+#ifdef __VIDEOCORE__ -+#define PREFIX(x) ARM_##x -+#else -+#define PREFIX(x) BCM_##x -+#endif -+ -+enum { -+ PREFIX(POWER_SDCARD_BIT), -+ PREFIX(POWER_UART_BIT), -+ PREFIX(POWER_MINIUART_BIT), -+ PREFIX(POWER_USB_BIT), -+ PREFIX(POWER_I2C0_BIT), -+ PREFIX(POWER_I2C1_BIT), -+ PREFIX(POWER_I2C2_BIT), -+ PREFIX(POWER_SPI_BIT), -+ PREFIX(POWER_CCP2TX_BIT), -+ PREFIX(POWER_DSI_BIT), -+ -+ PREFIX(POWER_MAX) -+}; -+ -+enum { -+ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -+ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -+ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -+ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -+ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -+ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -+ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -+ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -+ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -+ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -+ -+ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -+ PREFIX(POWER_NONE) = 0 -+}; -+ -+#endif diff --git a/arch/arm/mach-bcm2708/include/mach/clkdev.h b/arch/arm/mach-bcm2708/include/mach/clkdev.h new file mode 100644 index 0000000..04b37a8 @@ -2226,100 +1800,6 @@ index 0000000..b24304a + .endm + +#include -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -new file mode 100644 -index 0000000..f2568d4 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -0,0 +1,88 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/dma.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+ -+#ifndef _MACH_BCM2708_DMA_H -+#define _MACH_BCM2708_DMA_H -+ -+#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -+ -+/* DMA CS Control and Status bits */ -+#define BCM2708_DMA_ACTIVE (1 << 0) -+#define BCM2708_DMA_INT (1 << 2) -+#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ -+#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ -+#define BCM2708_DMA_ERR (1 << 8) -+#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ -+#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -+ -+/* DMA control block "info" field bits */ -+#define BCM2708_DMA_INT_EN (1 << 0) -+#define BCM2708_DMA_TDMODE (1 << 1) -+#define BCM2708_DMA_WAIT_RESP (1 << 3) -+#define BCM2708_DMA_D_INC (1 << 4) -+#define BCM2708_DMA_D_WIDTH (1 << 5) -+#define BCM2708_DMA_D_DREQ (1 << 6) -+#define BCM2708_DMA_S_INC (1 << 8) -+#define BCM2708_DMA_S_WIDTH (1 << 9) -+#define BCM2708_DMA_S_DREQ (1 << 10) -+ -+#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) -+#define BCM2708_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -+ -+#define BCM2708_DMA_DREQ_EMMC 11 -+#define BCM2708_DMA_DREQ_SDHOST 13 -+ -+#define BCM2708_DMA_CS 0x00 /* Control and Status */ -+#define BCM2708_DMA_ADDR 0x04 -+/* the current control block appears in the following registers - read only */ -+#define BCM2708_DMA_INFO 0x08 -+#define BCM2708_DMA_SOURCE_AD 0x0c -+#define BCM2708_DMA_DEST_AD 0x10 -+#define BCM2708_DMA_NEXTCB 0x1C -+#define BCM2708_DMA_DEBUG 0x20 -+ -+#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) -+#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -+ -+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -+ -+struct bcm2708_dma_cb { -+ unsigned long info; -+ unsigned long src; -+ unsigned long dst; -+ unsigned long length; -+ unsigned long stride; -+ unsigned long next; -+ unsigned long pad[2]; -+}; -+ -+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); -+extern void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block); -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -+ -+/* When listing features we can ask for when allocating DMA channels give -+ those with higher priority smaller ordinal numbers */ -+#define BCM_DMA_FEATURE_FAST_ORD 0 -+#define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_FAST (1< -+#include -+ -+typedef unsigned int BCM_POWER_HANDLE_T; -+ -+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); -+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); -+extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -+ -+#endif diff --git a/arch/arm/mach-bcm2708/include/mach/system.h b/arch/arm/mach-bcm2708/include/mach/system.h new file mode 100644 index 0000000..2d0b821 @@ -3200,218 +2648,6 @@ index 0000000..d634813 + * nothing to do + */ +#define arch_decomp_wdog() -diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h -new file mode 100644 -index 0000000..4a4a338 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/vc_mem.h -@@ -0,0 +1,35 @@ -+/***************************************************************************** -+* Copyright 2010 - 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. -+*****************************************************************************/ -+ -+#if !defined( VC_MEM_H ) -+#define VC_MEM_H -+ -+#include -+ -+#define VC_MEM_IOC_MAGIC 'v' -+ -+#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 ) -+#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -+ -+#if defined( __KERNEL__ ) -+#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -+ -+extern unsigned long mm_vc_mem_phys_addr; -+extern unsigned int mm_vc_mem_size; -+extern int vc_mem_get_current_size( void ); -+#endif -+ -+#endif /* VC_MEM_H */ -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -new file mode 100644 -index 0000000..8e11d67e ---- /dev/null -+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h -@@ -0,0 +1,165 @@ -+/* -+ * arch/arm/mach-bcm2708/include/mach/vcio.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _MACH_BCM2708_VCIO_H -+#define _MACH_BCM2708_VCIO_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); -+extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); -+extern int /*rc*/ bcm_mailbox_property(void *data, int size); -+ -+#include -+ -+/* -+ * The major device number. We can't rely on dynamic -+ * registration any more, because ioctls need to know -+ * it. -+ */ -+#define MAJOR_NUM 100 -+ -+/* -+ * Set the message of the device driver -+ */ -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+/* -+ * _IOWR means that we're creating an ioctl command -+ * number for passing information from a user process -+ * to the kernel module and from the kernel module to user process -+ * -+ * The first arguments, MAJOR_NUM, is the major device -+ * number we're using. -+ * -+ * The second argument is the number of the command -+ * (there could be several with different meanings). -+ * -+ * The third argument is the type we want to get from -+ * the process to the kernel. -+ */ -+ -+/* -+ * The name of the device file -+ */ -+#define DEVICE_FILE_NAME "vcio" -+ -+#endif diff --git a/arch/arm/mach-bcm2708/include/mach/vmalloc.h b/arch/arm/mach-bcm2708/include/mach/vmalloc.h new file mode 100644 index 0000000..502c617 @@ -3438,1370 +2674,12 @@ index 0000000..502c617 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define VMALLOC_END (0xe8000000) -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -new file mode 100644 -index 0000000..2696be9 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/power.c -@@ -0,0 +1,197 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/power.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_power" -+ -+#define BCM_POWER_MAXCLIENTS 4 -+#define BCM_POWER_NOCLIENT (1<<31) -+ -+/* Some drivers expect there devices to be permanently powered */ -+ -+#ifdef CONFIG_USB -+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) -+#endif -+ -+#if 1 -+#define DPRINTK printk -+#else -+#define DPRINTK if (0) printk -+#endif -+ -+struct state_struct { -+ uint32_t global_request; -+ uint32_t client_request[BCM_POWER_MAXCLIENTS]; -+ struct semaphore client_mutex; -+ struct semaphore mutex; -+} g_state; -+ -+int bcm_power_open(BCM_POWER_HANDLE_T *handle) -+{ -+ BCM_POWER_HANDLE_T i; -+ int ret = -EBUSY; -+ -+ down(&g_state.client_mutex); -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -+ g_state.client_request[i] = BCM_POWER_NONE; -+ *handle = i; -+ ret = 0; -+ break; -+ } -+ } -+ -+ up(&g_state.client_mutex); -+ -+ DPRINTK("bcm_power_open() -> %d\n", *handle); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(bcm_power_open); -+ -+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) -+{ -+ int rc = 0; -+ -+ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -+ -+ if ((handle < BCM_POWER_MAXCLIENTS) && -+ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -+ if (down_interruptible(&g_state.mutex) != 0) { -+ DPRINTK("bcm_power_request -> interrupted\n"); -+ return -EINTR; -+ } -+ -+ if (request != g_state.client_request[handle]) { -+ uint32_t others_request = 0; -+ uint32_t global_request; -+ BCM_POWER_HANDLE_T i; -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (i != handle) -+ others_request |= -+ g_state.client_request[i]; -+ } -+ others_request &= ~BCM_POWER_NOCLIENT; -+ -+ global_request = request | others_request; -+ if (global_request != g_state.global_request) { -+ uint32_t actual; -+ -+ /* Send a request to VideoCore */ -+ 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); -+ DPRINTK -+ ("bcm_mailbox_read -> %08x, %d\n", -+ actual, rc); -+ actual >>= 4; -+ } else { -+ rc = 0; -+ actual = global_request; -+ } -+ -+ 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", -+ __func__, -+ g_state.global_request, -+ global_request, actual, request, others_request); -+ /* A failure */ -+ BUG_ON((others_request & actual) -+ != others_request); -+ request &= actual; -+ rc = -EIO; -+ } -+ -+ g_state.global_request = actual; -+ g_state.client_request[handle] = -+ request; -+ } -+ } -+ } -+ up(&g_state.mutex); -+ } else { -+ rc = -EINVAL; -+ } -+ DPRINTK("bcm_power_request -> %d\n", rc); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_request); -+ -+int bcm_power_close(BCM_POWER_HANDLE_T handle) -+{ -+ int rc; -+ -+ DPRINTK("bcm_power_close(%d)\n", handle); -+ -+ rc = bcm_power_request(handle, BCM_POWER_NONE); -+ if (rc == 0) -+ g_state.client_request[handle] = BCM_POWER_NOCLIENT; -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_close); -+ -+static int __init bcm_power_init(void) -+{ -+#if defined(BCM_POWER_ALWAYS_ON) -+ BCM_POWER_HANDLE_T always_on_handle; -+#endif -+ int rc = 0; -+ 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; -+ -+ sema_init(&g_state.client_mutex, 1); -+ sema_init(&g_state.mutex, 1); -+ -+ g_state.global_request = 0; -+ -+#if defined(BCM_POWER_ALWAYS_ON) -+ if (BCM_POWER_ALWAYS_ON) { -+ bcm_power_open(&always_on_handle); -+ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -+ } -+#endif -+ -+ return rc; -+} -+ -+static void __exit bcm_power_exit(void) -+{ -+ bcm_mailbox_write(MBOX_CHAN_POWER, 0); -+} -+ -+arch_initcall(bcm_power_init); /* Initialize early */ -+module_exit(bcm_power_exit); -+ -+MODULE_AUTHOR("Phil Elwell"); -+MODULE_DESCRIPTION("Interface to BCM2708 power management"); -+MODULE_LICENSE("GPL"); -diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c -new file mode 100644 -index 0000000..2982af7 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/vc_mem.c -@@ -0,0 +1,431 @@ -+/***************************************************************************** -+* Copyright 2010 - 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 -+ -+#ifdef CONFIG_ARCH_KONA -+#include -+#elif CONFIG_ARCH_BCM2708 -+#else -+#include -+#endif -+ -+#include "mach/vc_mem.h" -+#include -+ -+#define DRIVER_NAME "vc-mem" -+ -+// Device (/dev) related variables -+static dev_t vc_mem_devnum = 0; -+static struct class *vc_mem_class = NULL; -+static struct cdev vc_mem_cdev; -+static int vc_mem_inited = 0; -+ -+#ifdef CONFIG_DEBUG_FS -+static struct dentry *vc_mem_debugfs_entry; -+#endif -+ -+/* -+ * Videocore memory addresses and size -+ * -+ * Drivers that wish to know the videocore memory addresses and sizes should -+ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -+ * headers. This allows the other drivers to not be tied down to a a certain -+ * address/size at compile time. -+ * -+ * In the future, the goal is to have the videocore memory virtual address and -+ * size be calculated at boot time rather than at compile time. The decision of -+ * where the videocore memory resides and its size would be in the hands of the -+ * bootloader (and/or kernel). When that happens, the values of these variables -+ * would be calculated and assigned in the init function. -+ */ -+// in the 2835 VC in mapped above ARM, but ARM has full access to VC space -+unsigned long mm_vc_mem_phys_addr = 0x00000000; -+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); -+ -+static uint phys_addr = 0; -+static uint mem_size = 0; -+static uint mem_base = 0; -+ -+ -+/**************************************************************************** -+* -+* vc_mem_open -+* -+***************************************************************************/ -+ -+static int -+vc_mem_open(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_release -+* -+***************************************************************************/ -+ -+static int -+vc_mem_release(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_size -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_size(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_base -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_base(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_current_size -+* -+***************************************************************************/ -+ -+int -+vc_mem_get_current_size(void) -+{ -+ return mm_vc_mem_size; -+} -+ -+EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -+ -+/**************************************************************************** -+* -+* vc_mem_ioctl -+* -+***************************************************************************/ -+ -+static long -+vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int rc = 0; -+ -+ (void) cmd; -+ (void) arg; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ switch (cmd) { -+ case VC_MEM_IOC_MEM_PHYS_ADDR: -+ { -+ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -+ __func__, (void *) mm_vc_mem_phys_addr); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -+ sizeof (mm_vc_mem_phys_addr)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_SIZE: -+ { -+ // Get the videocore memory size first -+ vc_mem_get_size(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -+ mm_vc_mem_size); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_size, -+ sizeof (mm_vc_mem_size)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_BASE: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -+ mm_vc_mem_base); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_base, -+ sizeof (mm_vc_mem_base)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_LOAD: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -+ { -+ return -ENOTTY; -+ } -+ } -+ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_mmap -+* -+***************************************************************************/ -+ -+static int -+vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ int rc = 0; -+ unsigned long length = vma->vm_end - vma->vm_start; -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ -+ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -+ __func__, (long) vma->vm_start, (long) vma->vm_end, -+ (long) vma->vm_pgoff); -+ -+ if (offset + length > mm_vc_mem_size) { -+ pr_err("%s: length %ld is too big\n", __func__, length); -+ return -EINVAL; -+ } -+ // Do not cache the memory map -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ -+ rc = remap_pfn_range(vma, vma->vm_start, -+ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -+ vma->vm_pgoff, length, vma->vm_page_prot); -+ if (rc != 0) { -+ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -+ } -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* File Operations for the driver. -+* -+***************************************************************************/ -+ -+static const struct file_operations vc_mem_fops = { -+ .owner = THIS_MODULE, -+ .open = vc_mem_open, -+ .release = vc_mem_release, -+ .unlocked_ioctl = vc_mem_ioctl, -+ .mmap = vc_mem_mmap, -+}; -+ -+#ifdef CONFIG_DEBUG_FS -+static void vc_mem_debugfs_deinit(void) -+{ -+ debugfs_remove_recursive(vc_mem_debugfs_entry); -+ vc_mem_debugfs_entry = NULL; -+} -+ -+ -+static int vc_mem_debugfs_init( -+ struct device *dev) -+{ -+ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -+ if (!vc_mem_debugfs_entry) { -+ dev_warn(dev, "could not create debugfs entry\n"); -+ return -EFAULT; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_phys_addr", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_phys_addr)) { -+ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_size", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_size)) { -+ dev_warn(dev, "%s:could not create vc_mem_size entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_base", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_base)) { -+ dev_warn(dev, "%s:could not create vc_mem_base entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ vc_mem_debugfs_deinit(); -+ return -EFAULT; -+} -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -+ -+/**************************************************************************** -+* -+* vc_mem_init -+* -+***************************************************************************/ -+ -+static int __init -+vc_mem_init(void) -+{ -+ int rc = -EFAULT; -+ struct device *dev; -+ -+ pr_debug("%s: called\n", __func__); -+ -+ mm_vc_mem_phys_addr = phys_addr; -+ mm_vc_mem_size = mem_size; -+ mm_vc_mem_base = mem_base; -+ -+ vc_mem_get_size(); -+ -+ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -+ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -+ -+ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -+ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -+ __func__, rc); -+ goto out_err; -+ } -+ -+ cdev_init(&vc_mem_cdev, &vc_mem_fops); -+ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -+ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -+ goto out_unregister; -+ } -+ -+ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vc_mem_class)) { -+ rc = PTR_ERR(vc_mem_class); -+ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -+ goto out_cdev_del; -+ } -+ -+ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -+ DRIVER_NAME); -+ if (IS_ERR(dev)) { -+ rc = PTR_ERR(dev); -+ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -+ goto out_class_destroy; -+ } -+ -+#ifdef CONFIG_DEBUG_FS -+ /* don't fail if the debug entries cannot be created */ -+ vc_mem_debugfs_init(dev); -+#endif -+ -+ vc_mem_inited = 1; -+ return 0; -+ -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ -+ out_class_destroy: -+ class_destroy(vc_mem_class); -+ vc_mem_class = NULL; -+ -+ out_cdev_del: -+ cdev_del(&vc_mem_cdev); -+ -+ out_unregister: -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ -+ out_err: -+ return -1; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_exit -+* -+***************************************************************************/ -+ -+static void __exit -+vc_mem_exit(void) -+{ -+ pr_debug("%s: called\n", __func__); -+ -+ if (vc_mem_inited) { -+#if CONFIG_DEBUG_FS -+ vc_mem_debugfs_deinit(); -+#endif -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ class_destroy(vc_mem_class); -+ cdev_del(&vc_mem_cdev); -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ } -+} -+ -+module_init(vc_mem_init); -+module_exit(vc_mem_exit); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Broadcom Corporation"); -+ -+module_param(phys_addr, uint, 0644); -+module_param(mem_size, uint, 0644); -+module_param(mem_base, uint, 0644); -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -new file mode 100644 -index 0000000..5e43e85 ---- /dev/null -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -0,0 +1,474 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -+#define SUPPORT_SYSRQ -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+ -+ -+#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* offsets from a mail box base address */ -+#define MAIL_WRT 0x00 /* write - and next 4 words */ -+#define MAIL_RD 0x00 /* read - and next 4 words */ -+#define MAIL_POL 0x10 /* read without popping the fifo */ -+#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL_STA 0x18 /* status */ -+#define MAIL_CNF 0x1C /* configuration */ -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+struct vc_mailbox { -+ struct device *dev; /* parent device */ -+ void __iomem *status; -+ void __iomem *config; -+ void __iomem *read; -+ void __iomem *write; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -+ uint32_t addr_mbox) -+{ -+ int i; -+ -+ mbox_out->dev = dev; -+ mbox_out->status = __io_address(addr_mbox + MAIL_STA); -+ mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -+ mbox_out->read = __io_address(addr_mbox + MAIL_RD); -+ /* Write to the other mailbox */ -+ mbox_out->write = -+ __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -+ MAIL_WRT); -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->write); -+ rc = 0; -+ } -+ return rc; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ rc = 0; -+ } -+ return rc; -+} -+ -+static irqreturn_t mbox_irq(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -+ int status = readl(mbox->status); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->read); -+ int chan = MBOX_CHAN(msg); -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ /* Overflow */ -+ printk(KERN_ERR DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ printk(KERN_ERR DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->status); -+ } -+ return ret; -+} -+ -+static struct irqaction mbox_irqaction = { -+ .name = "ARM Mailbox IRQ", -+ .flags = IRQF_DISABLED | IRQF_IRQPOLL, -+ .handler = mbox_irq, -+}; -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox Methods -+ * -------------------------------------------------------------------- */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_write(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_read(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static void dev_mbox_register(const char *dev_name, struct device *dev) -+{ -+ mbox_dev = dev; -+} -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)src < TASK_SIZE) -+ { -+ return copy_from_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)dst < TASK_SIZE) -+ { -+ return copy_to_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) { -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ } -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* ---------------------------------------------------------------------- -+ * Platform Device for Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static int Device_Open = 0; -+ -+/* -+ * This is called whenever a process attempts to open the device file -+ */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* -+ * We don't want to talk to two processes at the same time -+ */ -+ if (Device_Open) -+ return -EBUSY; -+ -+ Device_Open++; -+ /* -+ * Initialize the message -+ */ -+ try_module_get(THIS_MODULE); -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* -+ * We're now ready for our next caller -+ */ -+ Device_Open--; -+ -+ module_put(THIS_MODULE); -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -+ unsigned int ioctl_num, /* number and param for ioctl */ -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ /* -+ * Switch according to the ioctl called -+ */ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ break; -+ default: -+ printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_mailbox *mailbox; -+ -+ mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -+ if (NULL == mailbox) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "mailbox memory\n"); -+ ret = -ENOMEM; -+ } else { -+ struct resource *res; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ kfree(mailbox); -+ } else { -+ /* should be based on the registers from res really */ -+ mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -+ -+ platform_set_drvdata(pdev, mailbox); -+ dev_mbox_register(DRIVER_NAME, &pdev->dev); -+ -+ mbox_irqaction.dev_id = mailbox; -+ setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -+ printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -+ __io_address(ARM_0_MAIL0_RD)); -+ } -+ } -+ -+ if (ret == 0) { -+ /* -+ * Register the character device -+ */ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ -+ /* -+ * Negative values signify an error -+ */ -+ if (ret < 0) { -+ printk(KERN_ERR DRIVER_NAME -+ "Failed registering the character device %d\n", ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(mailbox); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ int ret; -+ -+ printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -+ -+ ret = platform_driver_register(&bcm_mbox_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bcm-mbox"); -diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig -index 9b4f29e5..0c5d4ac 100644 ---- a/arch/arm/mm/Kconfig -+++ b/arch/arm/mm/Kconfig -@@ -358,7 +358,7 @@ config CPU_PJ4B - - # ARMv6 - config CPU_V6 -- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) -+ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708) - select CPU_32v6 - select CPU_ABRT_EV6 - select CPU_CACHE_V6 -diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S -index d0390f4..a042de8 100644 ---- a/arch/arm/mm/proc-v6.S -+++ b/arch/arm/mm/proc-v6.S -@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset) - * - * IRQs are already disabled. - */ -+ -+/* See jira SW-5991 for details of this workaround */ - ENTRY(cpu_v6_do_idle) -- mov r1, #0 -- mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode -- mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt -+ .align 5 -+ mov r1, #2 -+1: subs r1, #1 -+ nop -+ mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode -+ mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt -+ nop -+ nop -+ nop -+ bne 1b - ret lr - - ENTRY(cpu_v6_dcache_clean_area) -diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types -index a10297d..c9ddd87 100644 ---- a/arch/arm/tools/mach-types -+++ b/arch/arm/tools/mach-types -@@ -522,6 +522,7 @@ torbreck MACH_TORBRECK TORBRECK 3090 - prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 - paz00 MACH_PAZ00 PAZ00 3128 - acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 -+bcm2708 MACH_BCM2708 BCM2708 3138 - ag5evm MACH_AG5EVM AG5EVM 3189 - ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 - wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 8d94c19..16ca535 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -84,7 +84,7 @@ struct vendor_data { - - static unsigned int get_fifosize_arm(struct amba_device *dev) - { -- return amba_rev(dev) < 3 ? 16 : 32; -+ return 16; //TODO: fix: amba_rev(dev) < 3 ? 16 : 32; - } - - static struct vendor_data vendor_arm = { -diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index 0c8cbe5..c3b84a2 100644 ---- a/include/linux/mmc/host.h -+++ b/include/linux/mmc/host.h -@@ -291,6 +291,7 @@ struct mmc_host { - MMC_CAP2_HS400_1_2V) - #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) - #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) -+#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ - - mmc_pm_flag_t pm_caps; /* supported pm features */ - - -From 6763b931593e5ce8e1b5e45de482527d61390f56 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 7 May 2013 14:32:27 +0100 -Subject: [PATCH 002/216] Add 2709 platform for Raspberry Pi 2 - ---- - arch/arm/Kconfig | 21 + - arch/arm/Makefile | 1 + - arch/arm/kernel/head.S | 8 + - arch/arm/mach-bcm2709/Kconfig | 49 + - arch/arm/mach-bcm2709/Makefile | 7 + - arch/arm/mach-bcm2709/Makefile.boot | 3 + - arch/arm/mach-bcm2709/armctrl.c | 361 +++++++ - arch/arm/mach-bcm2709/armctrl.h | 27 + - arch/arm/mach-bcm2709/bcm2708_gpio.c | 426 ++++++++ - arch/arm/mach-bcm2709/bcm2709.c | 1263 ++++++++++++++++++++++ - arch/arm/mach-bcm2709/bcm2709.h | 49 + - arch/arm/mach-bcm2709/clock.c | 61 ++ - arch/arm/mach-bcm2709/clock.h | 24 + - arch/arm/mach-bcm2709/delay.S | 21 + - arch/arm/mach-bcm2709/dma.c | 409 +++++++ - arch/arm/mach-bcm2709/include/mach/arm_control.h | 493 +++++++++ - arch/arm/mach-bcm2709/include/mach/arm_power.h | 62 ++ - arch/arm/mach-bcm2709/include/mach/barriers.h | 3 + - arch/arm/mach-bcm2709/include/mach/clkdev.h | 7 + - arch/arm/mach-bcm2709/include/mach/debug-macro.S | 22 + - arch/arm/mach-bcm2709/include/mach/dma.h | 94 ++ - arch/arm/mach-bcm2709/include/mach/entry-macro.S | 123 +++ - arch/arm/mach-bcm2709/include/mach/frc.h | 38 + - arch/arm/mach-bcm2709/include/mach/gpio.h | 17 + - arch/arm/mach-bcm2709/include/mach/hardware.h | 28 + - arch/arm/mach-bcm2709/include/mach/io.h | 27 + - arch/arm/mach-bcm2709/include/mach/irqs.h | 225 ++++ - arch/arm/mach-bcm2709/include/mach/memory.h | 57 + - arch/arm/mach-bcm2709/include/mach/platform.h | 225 ++++ - arch/arm/mach-bcm2709/include/mach/power.h | 26 + - arch/arm/mach-bcm2709/include/mach/system.h | 38 + - arch/arm/mach-bcm2709/include/mach/timex.h | 23 + - arch/arm/mach-bcm2709/include/mach/uncompress.h | 84 ++ - arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 + - arch/arm/mach-bcm2709/include/mach/vc_support.h | 69 ++ - arch/arm/mach-bcm2709/include/mach/vcio.h | 165 +++ - arch/arm/mach-bcm2709/include/mach/vmalloc.h | 20 + - arch/arm/mach-bcm2709/power.c | 195 ++++ - arch/arm/mach-bcm2709/vc_mem.c | 431 ++++++++ - arch/arm/mach-bcm2709/vc_support.c | 318 ++++++ - arch/arm/mach-bcm2709/vcio.c | 474 ++++++++ - arch/arm/mm/proc-v7.S | 1 + - arch/arm/tools/mach-types | 1 + - drivers/clocksource/arm_arch_timer.c | 36 + - 44 files changed, 6067 insertions(+) - create mode 100644 arch/arm/mach-bcm2709/Kconfig - create mode 100644 arch/arm/mach-bcm2709/Makefile - create mode 100644 arch/arm/mach-bcm2709/Makefile.boot - create mode 100644 arch/arm/mach-bcm2709/armctrl.c - create mode 100644 arch/arm/mach-bcm2709/armctrl.h - create mode 100644 arch/arm/mach-bcm2709/bcm2708_gpio.c - create mode 100644 arch/arm/mach-bcm2709/bcm2709.c - create mode 100644 arch/arm/mach-bcm2709/bcm2709.h - create mode 100644 arch/arm/mach-bcm2709/clock.c - create mode 100644 arch/arm/mach-bcm2709/clock.h - create mode 100644 arch/arm/mach-bcm2709/delay.S - create mode 100644 arch/arm/mach-bcm2709/dma.c - create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_control.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/arm_power.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/barriers.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/clkdev.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/debug-macro.S - create mode 100644 arch/arm/mach-bcm2709/include/mach/dma.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/entry-macro.S - create mode 100644 arch/arm/mach-bcm2709/include/mach/frc.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/gpio.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/hardware.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/io.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/irqs.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/memory.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/platform.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/power.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/system.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/timex.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/uncompress.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h - create mode 100755 arch/arm/mach-bcm2709/include/mach/vc_support.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/vcio.h - create mode 100644 arch/arm/mach-bcm2709/include/mach/vmalloc.h - create mode 100644 arch/arm/mach-bcm2709/power.c - create mode 100644 arch/arm/mach-bcm2709/vc_mem.c - create mode 100755 arch/arm/mach-bcm2709/vc_support.c - create mode 100644 arch/arm/mach-bcm2709/vcio.c - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 6876ae8..4018fea 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -793,6 +793,26 @@ config ARCH_OMAP1 - help - Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx) - -+config ARCH_BCM2709 -+ bool "Broadcom BCM2709 family" -+ select ARCH_HAS_BARRIERS if SMP -+ select CPU_V7 -+ select HAVE_SMP -+ select ARM_AMBA -+ select MIGHT_HAVE_CACHE_L2X0 -+ select HAVE_SCHED_CLOCK -+ select NEED_MACH_MEMORY_H -+ select NEED_MACH_IO_H -+ select COMMON_CLK -+ select ARCH_HAS_CPUFREQ -+ select GENERIC_CLOCKEVENTS -+ select MACH_BCM2709 -+ select VC4 -+ select FIQ -+# select ZONE_DMA -+ help -+ This enables support for Broadcom BCM2709 boards. -+ - endchoice - - menu "Multiple platform selection" -@@ -984,6 +1004,7 @@ source "arch/arm/mach-vt8500/Kconfig" - - source "arch/arm/mach-w90x900/Kconfig" - source "arch/arm/mach-bcm2708/Kconfig" -+source "arch/arm/mach-bcm2709/Kconfig" - - source "arch/arm/mach-zynq/Kconfig" - -diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index 27c0f92..21ba7f3 100644 ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -147,6 +147,7 @@ machine-$(CONFIG_ARCH_AT91) += at91 - machine-$(CONFIG_ARCH_AXXIA) += axxia - machine-$(CONFIG_ARCH_BCM) += bcm - machine-$(CONFIG_ARCH_BCM2708) += bcm2708 -+machine-$(CONFIG_ARCH_BCM2709) += bcm2709 - machine-$(CONFIG_ARCH_BERLIN) += berlin - machine-$(CONFIG_ARCH_CLPS711X) += clps711x - machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx -diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S -index 0196327..e4d6030 100644 ---- a/arch/arm/kernel/head.S -+++ b/arch/arm/kernel/head.S -@@ -680,6 +680,14 @@ ARM_BE8(rev16 ip, ip) - ldrcc r7, [r4], #4 @ use branch for delay slot - bcc 1b - ret lr -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop -+ nop - #endif - ENDPROC(__fixup_a_pv_table) - diff --git a/arch/arm/mach-bcm2709/Kconfig b/arch/arm/mach-bcm2709/Kconfig new file mode 100644 -index 0000000..4fb6e1b +index 0000000..d61ade0 --- /dev/null +++ b/arch/arm/mach-bcm2709/Kconfig -@@ -0,0 +1,49 @@ +@@ -0,0 +1,42 @@ +menu "Broadcom BCM2709 Implementations" + depends on ARCH_BCM2709 + @@ -4829,13 +2707,6 @@ index 0000000..4fb6e1b + help + Include support for the Broadcom(R) BCM2709 gpio. + -+config BCM2708_VCMEM -+ bool "Videocore Memory" -+ depends on MACH_BCM2709 -+ default y -+ help -+ Helper for videocore memory access and total size allocation. -+ +config BCM2708_NOL2CACHE + bool "Videocore L2 cache disable" + depends on MACH_BCM2709 @@ -4853,17 +2724,16 @@ index 0000000..4fb6e1b +endmenu diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile new file mode 100644 -index 0000000..2a803bb +index 0000000..1ae8b80 --- /dev/null +++ b/arch/arm/mach-bcm2709/Makefile -@@ -0,0 +1,7 @@ +@@ -0,0 +1,6 @@ +# +# Makefile for the linux kernel. +# + -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o dma.o ++obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o +obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o -+obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o diff --git a/arch/arm/mach-bcm2709/Makefile.boot b/arch/arm/mach-bcm2709/Makefile.boot new file mode 100644 index 0000000..67039c3 @@ -4875,7 +2745,7 @@ index 0000000..67039c3 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c new file mode 100644 -index 0000000..2815b64 +index 0000000..2fcfab9 --- /dev/null +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -0,0 +1,361 @@ @@ -5230,7 +3100,7 @@ index 0000000..2815b64 + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); + } else { + irq_set_chip_and_handler(irq, &armctrl_chip, handle_level_irq); -+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + irq_set_chip_data(irq, (void *)data); + } @@ -5275,7 +3145,7 @@ index 0000000..0aa916e +#endif diff --git a/arch/arm/mach-bcm2709/bcm2708_gpio.c b/arch/arm/mach-bcm2709/bcm2708_gpio.c new file mode 100644 -index 0000000..c1e9254 +index 0000000..e33265d --- /dev/null +++ b/arch/arm/mach-bcm2709/bcm2708_gpio.c @@ -0,0 +1,426 @@ @@ -5587,7 +3457,7 @@ index 0000000..c1e9254 + +static struct irqaction bcm2708_gpio_irq = { + .name = "BCM2708 GPIO catchall handler", -+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2708_gpio_interrupt, +}; + @@ -5707,10 +3577,10 @@ index 0000000..c1e9254 +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c new file mode 100644 -index 0000000..f8679bb +index 0000000..19d0601 --- /dev/null +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -0,0 +1,1263 @@ +@@ -0,0 +1,801 @@ +/* + * linux/arch/arm/mach-bcm2709/bcm2709.c + * @@ -5747,9 +3617,7 @@ index 0000000..f8679bb +#include +#include +#include -+#include +#include -+#include + +#include +#include @@ -5768,8 +3636,6 @@ index 0000000..f8679bb +#include + +#include -+#include -+#include +#include + +#include @@ -5795,19 +3661,12 @@ index 0000000..f8679bb + */ +#define DMA_MASK_BITS_COMMON 32 + -+// use GPIO 4 for the one-wire GPIO pin, if enabled -+#define W1_GPIO 4 -+// ensure one-wire GPIO pullup is disabled by default -+#define W1_PULLUP -1 -+ +/* command line parameters */ +static unsigned boardrev, serial; +static unsigned uart_clock = UART0_CLOCK; +static unsigned disk_led_gpio = 16; +static unsigned disk_led_active_low = 1; +static unsigned reboot_part = 0; -+static unsigned w1_gpio_pin = W1_GPIO; -+static unsigned w1_gpio_pullup = W1_PULLUP; + +static unsigned use_dt = 0; + @@ -5953,6 +3812,7 @@ index 0000000..f8679bb + bcm2709_register_clkdev(clk, "dev:f1"); + + clk = bcm2709_clk_register("sdhost_clk", 250000000); ++ bcm2709_register_clkdev(clk, "mmc-bcm2835.0"); + bcm2709_register_clkdev(clk, "bcm2708_spi.0"); + bcm2709_register_clkdev(clk, "bcm2708_i2c.0"); + bcm2709_register_clkdev(clk, "bcm2708_i2c.1"); @@ -5967,35 +3827,6 @@ index 0000000..f8679bb + &uart0_device, +}; + -+static struct resource bcm2708_dmaman_resources[] = { -+ { -+ .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), -+}; -+ -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+static struct w1_gpio_platform_data w1_gpio_pdata = { -+ .pin = W1_GPIO, -+ .ext_pullup_enable_pin = W1_PULLUP, -+ .is_open_drain = 0, -+}; -+ -+static struct platform_device w1_device = { -+ .name = "w1-gpio", -+ .id = -1, -+ .dev.platform_data = &w1_gpio_pdata, -+}; -+#endif -+ +static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_fb_device = { @@ -6009,27 +3840,6 @@ index 0000000..f8679bb + }, +}; + -+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, -+ }, -+ {}, -+}; -+ -+static struct platform_device bcm2708_uart1_device = { -+ .name = "serial8250", -+ .id = PLAT8250_DEV_PLATFORM, -+ .dev = { -+ .platform_data = bcm2708_uart1_platform_data, -+ }, -+}; -+ +static struct resource bcm2708_usb_resources[] = { + [0] = { + .start = USB_BASE, @@ -6078,17 +3888,21 @@ index 0000000..f8679bb +}; + +static struct resource bcm2708_vcio_resources[] = { -+ [0] = { /* mailbox/semaphore/doorbell access */ -+ .start = MCORE_BASE, -+ .end = MCORE_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, ++ { ++ .start = ARMCTRL_0_MAIL0_BASE, ++ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_MAILBOX, ++ .end = IRQ_ARM_MAILBOX, ++ .flags = IORESOURCE_IRQ, ++ }, +}; + +static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + +static struct platform_device bcm2708_vcio_device = { -+ .name = BCM_VCIO_DRIVER_NAME, ++ .name = "bcm2708_vcio", + .id = -1, /* only one VideoCore I/O area */ + .resource = bcm2708_vcio_resources, + .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), @@ -6098,360 +3912,6 @@ index 0000000..f8679bb + }, +}; + -+#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, -+ }, -+}; -+ -+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 SYSTEM_TIMER -+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, -+ } -+ -+}; -+ -+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), -+ }, -+}; -+#endif -+ -+#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ -+static struct resource bcm2835_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, -+ }, -+ [1] = { -+ .start = IRQ_ARASANSDIO, -+ .end = IRQ_ARASANSDIO, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 bcm2835_emmc_dmamask = 0xffffffffUL; -+ -+struct platform_device bcm2835_emmc_device = { -+ .name = "mmc-bcm2835", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2835_emmc_resources), -+ .resource = bcm2835_emmc_resources, -+ .dev = { -+ .dma_mask = &bcm2835_emmc_dmamask, -+ .coherent_dma_mask = 0xffffffffUL}, -+}; -+#endif /* CONFIG_MMC_BCM2835 */ -+ -+static struct resource bcm2708_powerman_resources[] = { -+ [0] = { -+ .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}, -+}; -+ -+ -+static struct platform_device bcm2708_alsa_devices[] = { -+ [0] = { -+ .name = "bcm2835_AUD0", -+ .id = 0, /* first audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [1] = { -+ .name = "bcm2835_AUD1", -+ .id = 1, /* second audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [2] = { -+ .name = "bcm2835_AUD2", -+ .id = 2, /* third audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [3] = { -+ .name = "bcm2835_AUD3", -+ .id = 3, /* forth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [4] = { -+ .name = "bcm2835_AUD4", -+ .id = 4, /* fifth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [5] = { -+ .name = "bcm2835_AUD5", -+ .id = 5, /* sixth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [6] = { -+ .name = "bcm2835_AUD6", -+ .id = 6, /* seventh audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+ [7] = { -+ .name = "bcm2835_AUD7", -+ .id = 7, /* eighth audio device */ -+ .resource = 0, -+ .num_resources = 0, -+ }, -+}; -+ -+static struct resource bcm2708_spi_resources[] = { -+ { -+ .start = SPI0_BASE, -+ .end = SPI0_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_SPI, -+ .end = IRQ_SPI, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+ -+static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+static struct platform_device bcm2708_spi_device = { -+ .name = "bcm2708_spi", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_spi_resources), -+ .resource = bcm2708_spi_resources, -+ .dev = { -+ .dma_mask = &bcm2708_spi_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)}, -+}; -+ -+#ifdef CONFIG_BCM2708_SPIDEV -+static struct spi_board_info bcm2708_spi_devices[] = { -+#ifdef CONFIG_SPI_SPIDEV -+ { -+ .modalias = "spidev", -+ .max_speed_hz = 500000, -+ .bus_num = 0, -+ .chip_select = 0, -+ .mode = SPI_MODE_0, -+ }, { -+ .modalias = "spidev", -+ .max_speed_hz = 500000, -+ .bus_num = 0, -+ .chip_select = 1, -+ .mode = SPI_MODE_0, -+ } -+#endif -+}; -+#endif -+ -+static struct resource bcm2708_bsc0_resources[] = { -+ { -+ .start = BSC0_BASE, -+ .end = BSC0_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc0_device = { -+ .name = "bcm2708_i2c", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), -+ .resource = bcm2708_bsc0_resources, -+}; -+ -+ -+static struct resource bcm2708_bsc1_resources[] = { -+ { -+ .start = BSC1_BASE, -+ .end = BSC1_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc1_device = { -+ .name = "bcm2708_i2c", -+ .id = 1, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), -+ .resource = bcm2708_bsc1_resources, -+}; -+ -+static struct platform_device bcm2835_hwmon_device = { -+ .name = "bcm2835_hwmon", -+}; -+ -+static struct platform_device bcm2835_thermal_device = { -+ .name = "bcm2835_thermal", -+}; -+ -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+static struct resource bcm2708_i2s_resources[] = { -+ { -+ .start = I2S_BASE, -+ .end = I2S_BASE + 0x20, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = PCM_CLOCK_BASE, -+ .end = PCM_CLOCK_BASE + 0x02, -+ .flags = IORESOURCE_MEM, -+ } -+}; -+ -+static struct platform_device bcm2708_i2s_device = { -+ .name = "bcm2708-i2s", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), -+ .resource = bcm2708_i2s_resources, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+static struct platform_device snd_hifiberry_dac_device = { -+ .name = "snd-hifiberry-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm5102a_codec_device = { -+ .name = "pcm5102a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+static struct platform_device snd_rpi_hifiberry_dacplus_device = { -+ .name = "snd-rpi-hifiberry-dacplus", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4d) -+ }, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+static struct platform_device snd_hifiberry_digi_device = { -+ .name = "snd-hifiberry-digi", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("wm8804", 0x3b) -+ }, -+}; -+ -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+static struct platform_device snd_hifiberry_amp_device = { -+ .name = "snd-hifiberry-amp", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("tas5713", 0x1b) -+ }, -+}; -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+static struct platform_device snd_rpi_dac_device = { -+ .name = "snd-rpi-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm1794a_codec_device = { -+ .name = "pcm1794a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ -+ -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+static struct platform_device snd_rpi_iqaudio_dac_device = { -+ .name = "snd-rpi-iqaudio-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+// Use the actual device name rather than generic driver name -+static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4c) -+ }, -+}; -+#endif -+ +int __init bcm_register_device(struct platform_device *pdev) +{ + int ret; @@ -6539,6 +3999,17 @@ index 0000000..f8679bb + } +} + ++static void __init bcm2709_init_uart1(void) ++{ ++ struct device_node *np; ++ ++ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); ++ if (of_device_is_available(np)) { ++ pr_info("bcm2709: Mini UART enabled\n"); ++ writel(1, __io_address(UART1_BASE + 0x4)); ++ } ++} ++ +#ifdef CONFIG_OF +static void __init bcm2709_dt_init(void) +{ @@ -6570,85 +4041,24 @@ index 0000000..f8679bb + bcm2709_init_clocks(); + bcm2709_dt_init(); + -+ bcm_register_device(&bcm2708_dmaman_device); + bcm_register_device(&bcm2708_vcio_device); +#ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); +#endif -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+ w1_gpio_pdata.pin = w1_gpio_pin; -+ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -+ bcm_register_device_dt(&w1_device); -+#endif -+#ifdef SYSTEM_TIMER -+ bcm_register_device(&bcm2708_systemtimer_device); -+#endif -+ bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device(&bcm2708_uart1_device); -+ bcm_register_device(&bcm2708_powerman_device); ++ bcm_register_device_dt(&bcm2708_fb_device); ++ bcm_register_device_dt(&bcm2708_usb_device); + -+#ifdef CONFIG_MMC_BCM2835 -+ bcm_register_device(&bcm2835_emmc_device); -+#endif -+ bcm2709_init_led(); -+ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); ++ bcm2708_init_led(); ++ bcm2708_init_uart1(); + -+ bcm_register_device_dt(&bcm2708_spi_device); -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ -+ bcm_register_device(&bcm2835_hwmon_device); -+ bcm_register_device(&bcm2835_thermal_device); -+ -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+ bcm_register_device_dt(&bcm2708_i2s_device); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_dac_device); -+ bcm_register_device_dt(&snd_pcm5102a_codec_device); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_digi_device); -+ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_amp_device); -+ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_dac_device); -+ bcm_register_device_dt(&snd_pcm1794a_codec_device); -+#endif -+ -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); -+#endif -+ -+ -+ for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -+ struct amba_device *d = amba_devs[i]; -+ amba_device_register(d, &iomem_resource); ++ if (!use_dt) { ++ 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; -+ -+#ifdef CONFIG_BCM2708_SPIDEV -+ if (!use_dt) -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); -+#endif +} + +#ifdef SYSTEM_TIMER @@ -6972,8 +4382,6 @@ index 0000000..f8679bb +module_param(disk_led_gpio, uint, 0644); +module_param(disk_led_active_low, uint, 0644); +module_param(reboot_part, uint, 0644); -+module_param(w1_gpio_pin, uint, 0644); -+module_param(w1_gpio_pullup, uint, 0644); diff --git a/arch/arm/mach-bcm2709/bcm2709.h b/arch/arm/mach-bcm2709/bcm2709.h new file mode 100644 index 0000000..e339a93 @@ -7029,103 +4437,6 @@ index 0000000..e339a93 +} + +#endif -diff --git a/arch/arm/mach-bcm2709/clock.c b/arch/arm/mach-bcm2709/clock.c -new file mode 100644 -index 0000000..4fc556e ---- /dev/null -+++ b/arch/arm/mach-bcm2709/clock.c -@@ -0,0 +1,61 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "clock.h" -+ -+int clk_enable(struct clk *clk) -+{ -+ return 0; -+} -+EXPORT_SYMBOL(clk_enable); -+ -+void clk_disable(struct clk *clk) -+{ -+} -+EXPORT_SYMBOL(clk_disable); -+ -+unsigned long clk_get_rate(struct clk *clk) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_get_rate); -+ -+long clk_round_rate(struct clk *clk, unsigned long rate) -+{ -+ return clk->rate; -+} -+EXPORT_SYMBOL(clk_round_rate); -+ -+int clk_set_rate(struct clk *clk, unsigned long rate) -+{ -+ return -EIO; -+} -+EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2709/clock.h b/arch/arm/mach-bcm2709/clock.h -new file mode 100644 -index 0000000..5f9d725 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/clock.h -@@ -0,0 +1,24 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/clock.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 -+ */ -+struct module; -+ -+struct clk { -+ unsigned long rate; -+}; diff --git a/arch/arm/mach-bcm2709/delay.S b/arch/arm/mach-bcm2709/delay.S new file mode 100644 index 0000000..06f4780 @@ -7153,421 +4464,6 @@ index 0000000..06f4780 + bhi bcm2708_delay + mov pc, lr +ENDPROC(bcm2708_delay) -diff --git a/arch/arm/mach-bcm2709/dma.c b/arch/arm/mach-bcm2709/dma.c -new file mode 100644 -index 0000000..a5e58d1 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/dma.c -@@ -0,0 +1,409 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/dma.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/*****************************************************************************\ -+ * * -+ * Configuration * -+ * * -+\*****************************************************************************/ -+ -+#define CACHE_LINE_MASK 31 -+#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME -+#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -+ -+/* valid only for channels 0 - 14, 15 has its own base address */ -+#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ -+#define BCM2708_DMA_CHANIO(dma_base, n) \ -+ ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -+ -+ -+/*****************************************************************************\ -+ * * -+ * DMA Auxilliary Functions * -+ * * -+\*****************************************************************************/ -+ -+/* A DMA buffer on an arbitrary boundary may separate a cache line into a -+ section inside the DMA buffer and another section outside it. -+ Even if we flush DMA buffers from the cache there is always the chance that -+ during a DMA someone will access the part of a cache line that is outside -+ the DMA buffer - which will then bring in unwelcome data. -+ Without being able to dictate our own buffer pools we must insist that -+ DMA buffers consist of a whole number of cache lines. -+*/ -+ -+extern int -+bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) -+{ -+ int i; -+ -+ for (i = 0; i < sg_len; i++) { -+ if (sg_ptr[i].offset & CACHE_LINE_MASK || -+ sg_ptr[i].length & CACHE_LINE_MASK) -+ return 0; -+ } -+ -+ return 1; -+} -+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -+ -+extern void -+bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) -+{ -+ dsb(); /* ARM data synchronization (push) operation */ -+ -+ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -+ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); -+} -+ -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ /* ugly busy wait only option for now */ -+ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -+ cpu_relax(); -+} -+ -+EXPORT_SYMBOL_GPL(bcm_dma_start); -+ -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ -+/* Complete an ongoing DMA (assuming its results are to be ignored) -+ Does nothing if there is no DMA in progress. -+ This routine waits for the current AXI transfer to complete before -+ terminating the current DMA. If the current transfer is hung on a DREQ used -+ by an uncooperative peripheral the AXI transfer may never complete. In this -+ case the routine times out and return a non-zero error code. -+ Use of this routine doesn't guarantee that the ongoing or aborted DMA -+ does not produce an interrupt. -+*/ -+extern int -+bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ unsigned long int cs; -+ int rc = 0; -+ -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (BCM2708_DMA_ACTIVE & cs) { -+ long int timeout = 10000; -+ -+ /* write 0 to the active bit - pause the DMA */ -+ writel(0, dma_chan_base + BCM2708_DMA_CS); -+ -+ /* wait for any current AXI transfer to complete */ -+ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -+ /* we'll un-pause when we set of our next DMA */ -+ rc = -ETIMEDOUT; -+ -+ } else if (BCM2708_DMA_ACTIVE & cs) { -+ /* terminate the control block chain */ -+ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -+ -+ /* abort the whole DMA */ -+ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -+ dma_chan_base + BCM2708_DMA_CS); -+ } -+ } -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_abort); -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Device Methods * -+ * * -+\*****************************************************************************/ -+ -+struct vc_dmaman { -+ void __iomem *dma_base; -+ u32 chan_available; /* bitmap of available channels */ -+ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ -+}; -+ -+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -+ u32 chans_available) -+{ -+ dmaman->dma_base = dma_base; -+ dmaman->chan_available = chans_available; -+ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ -+} -+ -+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) -+{ -+ u32 chans; -+ int feature; -+ -+ chans = dmaman->chan_available; -+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -+ /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) -+ chans &= dmaman->has_feature[feature]; -+ -+ if (chans) { -+ int chan = 0; -+ /* return the ordinal of the first channel in the bitmap */ -+ while (chans != 0 && (chans & 1) == 0) { -+ chans >>= 1; -+ chan++; -+ } -+ /* claim the channel */ -+ dmaman->chan_available &= ~(1 << chan); -+ return chan; -+ } else -+ return -ENOMEM; -+} -+ -+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) -+{ -+ if (chan < 0) -+ return -EINVAL; -+ else if ((1 << chan) & dmaman->chan_available) -+ return -EIDRM; -+ else { -+ dmaman->chan_available |= (1 << chan); -+ return 0; -+ } -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA IRQs * -+ * * -+\*****************************************************************************/ -+ -+static unsigned char bcm_dma_irqs[] = { -+ IRQ_DMA0, -+ IRQ_DMA1, -+ IRQ_DMA2, -+ IRQ_DMA3, -+ IRQ_DMA4, -+ IRQ_DMA5, -+ IRQ_DMA6, -+ IRQ_DMA7, -+ IRQ_DMA8, -+ IRQ_DMA9, -+ IRQ_DMA10, -+ IRQ_DMA11, -+ IRQ_DMA12 -+}; -+ -+ -+/***************************************************************************** \ -+ * * -+ * DMA Manager Monitor * -+ * * -+\*****************************************************************************/ -+ -+static struct device *dmaman_dev; /* we assume there's only one! */ -+ -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq) -+{ -+ if (!dmaman_dev) -+ return -ENODEV; -+ else { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ if (rc >= 0) { -+ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -+ rc); -+ *out_dma_irq = bcm_dma_irqs[rc]; -+ } -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -+ -+extern int bcm_dma_chan_free(int channel) -+{ -+ if (dmaman_dev) { -+ struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -+ int rc; -+ -+ device_lock(dmaman_dev); -+ rc = vc_dmaman_chan_free(dmaman, channel); -+ device_unlock(dmaman_dev); -+ -+ return rc; -+ } else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -+ -+static int dev_dmaman_register(const char *dev_name, struct device *dev) -+{ -+ int rc = dmaman_dev ? -EINVAL : 0; -+ dmaman_dev = dev; -+ return rc; -+} -+ -+static void dev_dmaman_deregister(const char *dev_name, struct device *dev) -+{ -+ dmaman_dev = NULL; -+} -+ -+/*****************************************************************************\ -+ * * -+ * DMA Device * -+ * * -+\*****************************************************************************/ -+ -+static int dmachans = -1; /* module parameter */ -+ -+static int bcm_dmaman_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_dmaman *dmaman; -+ struct resource *dma_res = NULL; -+ void __iomem *dma_base = NULL; -+ int have_dma_region = 0; -+ -+ dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -+ if (NULL == dmaman) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "DMA management memory\n"); -+ ret = -ENOMEM; -+ } else { -+ -+ dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (dma_res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ } else if (!request_mem_region(dma_res->start, -+ resource_size(dma_res), -+ DRIVER_NAME)) { -+ dev_err(&pdev->dev, "cannot obtain DMA region\n"); -+ ret = -EBUSY; -+ } else { -+ have_dma_region = 1; -+ dma_base = ioremap(dma_res->start, -+ resource_size(dma_res)); -+ if (!dma_base) { -+ dev_err(&pdev->dev, "cannot map DMA region\n"); -+ ret = -ENOMEM; -+ } else { -+ /* use module parameter if one was provided */ -+ if (dmachans > 0) -+ vc_dmaman_init(dmaman, dma_base, -+ dmachans); -+ else -+ vc_dmaman_init(dmaman, dma_base, -+ DEFAULT_DMACHAN_BITMAP); -+ -+ platform_set_drvdata(pdev, dmaman); -+ dev_dmaman_register(DRIVER_NAME, &pdev->dev); -+ -+ printk(KERN_INFO DRIVER_NAME ": DMA manager " -+ "at %p\n", dma_base); -+ } -+ } -+ } -+ if (ret != 0) { -+ if (dma_base) -+ iounmap(dma_base); -+ if (dma_res && have_dma_region) -+ release_mem_region(dma_res->start, -+ resource_size(dma_res)); -+ if (dmaman) -+ kfree(dmaman); -+ } -+ return ret; -+} -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -+ kfree(dmaman); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_dmaman_driver = { -+ .probe = bcm_dmaman_probe, -+ .remove = bcm_dmaman_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+/*****************************************************************************\ -+ * * -+ * Driver init/exit * -+ * * -+\*****************************************************************************/ -+ -+static int __init bcm_dmaman_drv_init(void) -+{ -+ int ret; -+ -+ ret = platform_driver_register(&bcm_dmaman_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_dmaman_drv_exit(void) -+{ -+ platform_driver_unregister(&bcm_dmaman_driver); -+} -+ -+module_init(bcm_dmaman_drv_init); -+module_exit(bcm_dmaman_drv_exit); -+ -+module_param(dmachans, int, 0644); -+ -+MODULE_AUTHOR("Gray Girling "); -+MODULE_DESCRIPTION("DMA channel manager driver"); -+MODULE_LICENSE("GPL"); -+ -+MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); diff --git a/arch/arm/mach-bcm2709/include/mach/arm_control.h b/arch/arm/mach-bcm2709/include/mach/arm_control.h new file mode 100644 index 0000000..e346caf @@ -8067,74 +4963,6 @@ index 0000000..e346caf +#define ARM_LOCAL_MAILBOX3_CLR3 HW_REGISTER_RW(ARM_LOCAL_BASE+0x0FC) + +#endif -diff --git a/arch/arm/mach-bcm2709/include/mach/arm_power.h b/arch/arm/mach-bcm2709/include/mach/arm_power.h -new file mode 100644 -index 0000000..d3bf245 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/include/mach/arm_power.h -@@ -0,0 +1,62 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _ARM_POWER_H -+#define _ARM_POWER_H -+ -+/* Use meaningful names on each side */ -+#ifdef __VIDEOCORE__ -+#define PREFIX(x) ARM_##x -+#else -+#define PREFIX(x) BCM_##x -+#endif -+ -+enum { -+ PREFIX(POWER_SDCARD_BIT), -+ PREFIX(POWER_UART_BIT), -+ PREFIX(POWER_MINIUART_BIT), -+ PREFIX(POWER_USB_BIT), -+ PREFIX(POWER_I2C0_BIT), -+ PREFIX(POWER_I2C1_BIT), -+ PREFIX(POWER_I2C2_BIT), -+ PREFIX(POWER_SPI_BIT), -+ PREFIX(POWER_CCP2TX_BIT), -+ PREFIX(POWER_DSI_BIT), -+ -+ PREFIX(POWER_MAX) -+}; -+ -+enum { -+ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -+ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -+ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -+ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -+ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -+ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -+ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -+ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -+ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -+ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -+ -+ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -+ PREFIX(POWER_NONE) = 0 -+}; -+ -+#endif diff --git a/arch/arm/mach-bcm2709/include/mach/barriers.h b/arch/arm/mach-bcm2709/include/mach/barriers.h new file mode 100644 index 0000000..723cdad @@ -8185,106 +5013,6 @@ index 0000000..b24304a + .endm + +#include -diff --git a/arch/arm/mach-bcm2709/include/mach/dma.h b/arch/arm/mach-bcm2709/include/mach/dma.h -new file mode 100644 -index 0000000..d03e7b5 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/include/mach/dma.h -@@ -0,0 +1,94 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/include/mach/dma.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+ -+#ifndef _MACH_BCM2708_DMA_H -+#define _MACH_BCM2708_DMA_H -+ -+#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -+ -+/* DMA CS Control and Status bits */ -+#define BCM2708_DMA_ACTIVE (1 << 0) -+#define BCM2708_DMA_INT (1 << 2) -+#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ -+#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ -+#define BCM2708_DMA_ERR (1 << 8) -+#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ -+#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -+ -+/* DMA control block "info" field bits */ -+#define BCM2708_DMA_INT_EN (1 << 0) -+#define BCM2708_DMA_TDMODE (1 << 1) -+#define BCM2708_DMA_WAIT_RESP (1 << 3) -+#define BCM2708_DMA_D_INC (1 << 4) -+#define BCM2708_DMA_D_WIDTH (1 << 5) -+#define BCM2708_DMA_D_DREQ (1 << 6) -+#define BCM2708_DMA_S_INC (1 << 8) -+#define BCM2708_DMA_S_WIDTH (1 << 9) -+#define BCM2708_DMA_S_DREQ (1 << 10) -+ -+#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) -+#define BCM2708_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -+ -+#define BCM2708_DMA_DREQ_EMMC 11 -+#define BCM2708_DMA_DREQ_SDHOST 13 -+ -+#define BCM2708_DMA_CS 0x00 /* Control and Status */ -+#define BCM2708_DMA_ADDR 0x04 -+/* the current control block appears in the following registers - read only */ -+#define BCM2708_DMA_INFO 0x08 -+#define BCM2708_DMA_SOURCE_AD 0x0c -+#define BCM2708_DMA_DEST_AD 0x10 -+#define BCM2708_DMA_NEXTCB 0x1C -+#define BCM2708_DMA_DEBUG 0x20 -+ -+#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) -+#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -+ -+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -+ -+struct bcm2708_dma_cb { -+ unsigned long info; -+ unsigned long src; -+ unsigned long dst; -+ unsigned long length; -+ unsigned long stride; -+ unsigned long next; -+ unsigned long pad[2]; -+}; -+struct scatterlist; -+ -+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); -+extern void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block); -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); -+extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -+ -+/* When listing features we can ask for when allocating DMA channels give -+ those with higher priority smaller ordinal numbers */ -+#define BCM_DMA_FEATURE_FAST_ORD 0 -+#define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_NORMAL_ORD 2 -+#define BCM_DMA_FEATURE_LITE_ORD 3 -+#define BCM_DMA_FEATURE_FAST (1< -+#include -+ -+typedef unsigned int BCM_POWER_HANDLE_T; -+ -+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); -+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); -+extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -+ -+#endif diff --git a/arch/arm/mach-bcm2709/include/mach/system.h b/arch/arm/mach-bcm2709/include/mach/system.h new file mode 100644 index 0000000..2d0b821 @@ -9384,177 +6080,6 @@ index 0000000..70e809f + unsigned int r0, unsigned int r1, unsigned int r2, unsigned int r3, unsigned int r4, unsigned int r5); + +#endif -diff --git a/arch/arm/mach-bcm2709/include/mach/vcio.h b/arch/arm/mach-bcm2709/include/mach/vcio.h -new file mode 100644 -index 0000000..8e11d67e ---- /dev/null -+++ b/arch/arm/mach-bcm2709/include/mach/vcio.h -@@ -0,0 +1,165 @@ -+/* -+ * arch/arm/mach-bcm2708/include/mach/vcio.h -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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 _MACH_BCM2708_VCIO_H -+#define _MACH_BCM2708_VCIO_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); -+extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); -+extern int /*rc*/ bcm_mailbox_property(void *data, int size); -+ -+#include -+ -+/* -+ * The major device number. We can't rely on dynamic -+ * registration any more, because ioctls need to know -+ * it. -+ */ -+#define MAJOR_NUM 100 -+ -+/* -+ * Set the message of the device driver -+ */ -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+/* -+ * _IOWR means that we're creating an ioctl command -+ * number for passing information from a user process -+ * to the kernel module and from the kernel module to user process -+ * -+ * The first arguments, MAJOR_NUM, is the major device -+ * number we're using. -+ * -+ * The second argument is the number of the command -+ * (there could be several with different meanings). -+ * -+ * The third argument is the type we want to get from -+ * the process to the kernel. -+ */ -+ -+/* -+ * The name of the device file -+ */ -+#define DEVICE_FILE_NAME "vcio" -+ -+#endif diff --git a/arch/arm/mach-bcm2709/include/mach/vmalloc.h b/arch/arm/mach-bcm2709/include/mach/vmalloc.h new file mode 100644 index 0000000..6aa6826 @@ -9581,210 +6106,9 @@ index 0000000..6aa6826 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define VMALLOC_END (0xff000000) -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -new file mode 100644 -index 0000000..3421057 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/power.c -@@ -0,0 +1,195 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/power.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_power" -+ -+#define BCM_POWER_MAXCLIENTS 4 -+#define BCM_POWER_NOCLIENT (1<<31) -+ -+/* Some drivers expect there devices to be permanently powered */ -+#ifdef CONFIG_USB -+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) -+#endif -+ -+#if 1 -+#define DPRINTK printk -+#else -+#define DPRINTK if (0) printk -+#endif -+ -+struct state_struct { -+ uint32_t global_request; -+ uint32_t client_request[BCM_POWER_MAXCLIENTS]; -+ struct semaphore client_mutex; -+ struct semaphore mutex; -+} g_state; -+ -+int bcm_power_open(BCM_POWER_HANDLE_T *handle) -+{ -+ BCM_POWER_HANDLE_T i; -+ int ret = -EBUSY; -+ -+ down(&g_state.client_mutex); -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -+ g_state.client_request[i] = BCM_POWER_NONE; -+ *handle = i; -+ ret = 0; -+ break; -+ } -+ } -+ -+ up(&g_state.client_mutex); -+ -+ DPRINTK("bcm_power_open() -> %d\n", *handle); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(bcm_power_open); -+ -+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) -+{ -+ int rc = 0; -+ -+ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -+ -+ if ((handle < BCM_POWER_MAXCLIENTS) && -+ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -+ if (down_interruptible(&g_state.mutex) != 0) { -+ DPRINTK("bcm_power_request -> interrupted\n"); -+ return -EINTR; -+ } -+ -+ if (request != g_state.client_request[handle]) { -+ uint32_t others_request = 0; -+ uint32_t global_request; -+ BCM_POWER_HANDLE_T i; -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (i != handle) -+ others_request |= -+ g_state.client_request[i]; -+ } -+ others_request &= ~BCM_POWER_NOCLIENT; -+ -+ global_request = request | others_request; -+ if (global_request != g_state.global_request) { -+ uint32_t actual; -+ -+ /* Send a request to VideoCore */ -+ 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); -+ DPRINTK -+ ("bcm_mailbox_read -> %08x, %d\n", -+ actual, rc); -+ actual >>= 4; -+ } else { -+ rc = 0; -+ actual = global_request; -+ } -+ -+ 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", -+ __func__, -+ g_state.global_request, -+ global_request, actual, request, others_request); -+ /* A failure */ -+ BUG_ON((others_request & actual) -+ != others_request); -+ request &= actual; -+ rc = -EIO; -+ } -+ -+ g_state.global_request = actual; -+ g_state.client_request[handle] = -+ request; -+ } -+ } -+ } -+ up(&g_state.mutex); -+ } else { -+ rc = -EINVAL; -+ } -+ DPRINTK("bcm_power_request -> %d\n", rc); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_request); -+ -+int bcm_power_close(BCM_POWER_HANDLE_T handle) -+{ -+ int rc; -+ -+ DPRINTK("bcm_power_close(%d)\n", handle); -+ -+ rc = bcm_power_request(handle, BCM_POWER_NONE); -+ if (rc == 0) -+ g_state.client_request[handle] = BCM_POWER_NOCLIENT; -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_close); -+ -+static int __init bcm_power_init(void) -+{ -+#if defined(BCM_POWER_ALWAYS_ON) -+ BCM_POWER_HANDLE_T always_on_handle; -+#endif -+ int rc = 0; -+ 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; -+ -+ sema_init(&g_state.client_mutex, 1); -+ sema_init(&g_state.mutex, 1); -+ -+ g_state.global_request = 0; -+#if defined(BCM_POWER_ALWAYS_ON) -+ if (BCM_POWER_ALWAYS_ON) { -+ bcm_power_open(&always_on_handle); -+ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -+ } -+#endif -+ -+ return rc; -+} -+ -+static void __exit bcm_power_exit(void) -+{ -+ bcm_mailbox_write(MBOX_CHAN_POWER, 0); -+} -+ -+arch_initcall(bcm_power_init); /* Initialize early */ -+module_exit(bcm_power_exit); -+ -+MODULE_AUTHOR("Phil Elwell"); -+MODULE_DESCRIPTION("Interface to BCM2708 power management"); -+MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c new file mode 100644 -index 0000000..ac578db +index 0000000..d2adfd1 --- /dev/null +++ b/arch/arm/mach-bcm2709/vc_mem.c @@ -0,0 +1,431 @@ @@ -9812,6 +6136,7 @@ index 0000000..ac578db +#include +#include +#include ++#include + +#ifdef CONFIG_ARCH_KONA +#include @@ -9821,7 +6146,6 @@ index 0000000..ac578db +#endif + +#include "mach/vc_mem.h" -+#include + +#define DRIVER_NAME "vc-mem" + @@ -10220,8 +6544,8 @@ index 0000000..ac578db +module_param(mem_size, uint, 0644); +module_param(mem_base, uint, 0644); diff --git a/arch/arm/mach-bcm2709/vc_support.c b/arch/arm/mach-bcm2709/vc_support.c -new file mode 100755 -index 0000000..0bc41c4 +new file mode 100644 +index 0000000..c4dc7d6 --- /dev/null +++ b/arch/arm/mach-bcm2709/vc_support.c @@ -0,0 +1,318 @@ @@ -10233,7 +6557,7 @@ index 0000000..0bc41c4 + */ + +#include -+#include ++#include + +#ifdef ECLIPSE_IGNORE + @@ -10543,491 +6867,51 @@ index 0000000..0bc41c4 + return 1; + } +} -diff --git a/arch/arm/mach-bcm2709/vcio.c b/arch/arm/mach-bcm2709/vcio.c -new file mode 100644 -index 0000000..5e43e85 ---- /dev/null -+++ b/arch/arm/mach-bcm2709/vcio.c -@@ -0,0 +1,474 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -+#define SUPPORT_SYSRQ -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+ -+ -+#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* offsets from a mail box base address */ -+#define MAIL_WRT 0x00 /* write - and next 4 words */ -+#define MAIL_RD 0x00 /* read - and next 4 words */ -+#define MAIL_POL 0x10 /* read without popping the fifo */ -+#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL_STA 0x18 /* status */ -+#define MAIL_CNF 0x1C /* configuration */ -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+struct vc_mailbox { -+ struct device *dev; /* parent device */ -+ void __iomem *status; -+ void __iomem *config; -+ void __iomem *read; -+ void __iomem *write; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -+ uint32_t addr_mbox) -+{ -+ int i; -+ -+ mbox_out->dev = dev; -+ mbox_out->status = __io_address(addr_mbox + MAIL_STA); -+ mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -+ mbox_out->read = __io_address(addr_mbox + MAIL_RD); -+ /* Write to the other mailbox */ -+ mbox_out->write = -+ __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -+ MAIL_WRT); -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->write); -+ rc = 0; -+ } -+ return rc; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ if (mbox->magic != MBOX_MAGIC) -+ rc = -EINVAL; -+ else { -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ rc = 0; -+ } -+ return rc; -+} -+ -+static irqreturn_t mbox_irq(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -+ int status = readl(mbox->status); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->read); -+ int chan = MBOX_CHAN(msg); -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ /* Overflow */ -+ printk(KERN_ERR DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ printk(KERN_ERR DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->status); -+ } -+ return ret; -+} -+ -+static struct irqaction mbox_irqaction = { -+ .name = "ARM Mailbox IRQ", -+ .flags = IRQF_DISABLED | IRQF_IRQPOLL, -+ .handler = mbox_irq, -+}; -+ -+/* ---------------------------------------------------------------------- -+ * Mailbox Methods -+ * -------------------------------------------------------------------- */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ int rc; -+ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_write(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (mbox_dev) -+ return dev_mbox_read(mbox_dev, chan, data28); -+ else -+ return -ENODEV; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static void dev_mbox_register(const char *dev_name, struct device *dev) -+{ -+ mbox_dev = dev; -+} -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)src < TASK_SIZE) -+ { -+ return copy_from_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ( (uint32_t)dst < TASK_SIZE) -+ { -+ return copy_to_user(dst, src, size); -+ } -+ else -+ { -+ memcpy( dst, src, size ); -+ return 0; -+ } -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) { -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ } -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* ---------------------------------------------------------------------- -+ * Platform Device for Mailbox -+ * -------------------------------------------------------------------- */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static int Device_Open = 0; -+ -+/* -+ * This is called whenever a process attempts to open the device file -+ */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* -+ * We don't want to talk to two processes at the same time -+ */ -+ if (Device_Open) -+ return -EBUSY; -+ -+ Device_Open++; -+ /* -+ * Initialize the message -+ */ -+ try_module_get(THIS_MODULE); -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* -+ * We're now ready for our next caller -+ */ -+ Device_Open--; -+ -+ module_put(THIS_MODULE); -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -+ unsigned int ioctl_num, /* number and param for ioctl */ -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ /* -+ * Switch according to the ioctl called -+ */ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ break; -+ default: -+ printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ struct vc_mailbox *mailbox; -+ -+ mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -+ if (NULL == mailbox) { -+ printk(KERN_ERR DRIVER_NAME ": failed to allocate " -+ "mailbox memory\n"); -+ ret = -ENOMEM; -+ } else { -+ struct resource *res; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (res == NULL) { -+ printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -+ "resource\n"); -+ ret = -ENODEV; -+ kfree(mailbox); -+ } else { -+ /* should be based on the registers from res really */ -+ mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -+ -+ platform_set_drvdata(pdev, mailbox); -+ dev_mbox_register(DRIVER_NAME, &pdev->dev); -+ -+ mbox_irqaction.dev_id = mailbox; -+ setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -+ printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -+ __io_address(ARM_0_MAIL0_RD)); -+ } -+ } -+ -+ if (ret == 0) { -+ /* -+ * Register the character device -+ */ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ -+ /* -+ * Negative values signify an error -+ */ -+ if (ret < 0) { -+ printk(KERN_ERR DRIVER_NAME -+ "Failed registering the character device %d\n", ret); -+ return ret; -+ } -+ } -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ kfree(mailbox); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ int ret; -+ -+ printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -+ -+ ret = platform_driver_register(&bcm_mbox_driver); -+ if (ret != 0) { -+ printk(KERN_ERR DRIVER_NAME ": failed to register " -+ "on platform\n"); -+ } -+ -+ return ret; -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -+MODULE_ALIAS("platform:bcm-mbox"); +diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig +index b4f92b9..bb263d8 100644 +--- a/arch/arm/mm/Kconfig ++++ b/arch/arm/mm/Kconfig +@@ -358,7 +358,7 @@ config CPU_PJ4B + + # ARMv6 + config CPU_V6 +- bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX) ++ bool "Support ARM V6 processor" if (!ARCH_MULTIPLATFORM || ARCH_MULTI_V6) && (ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || MACH_BCM2708) + select CPU_32v6 + select CPU_ABRT_EV6 + select CPU_CACHE_V6 +diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S +index 06d890a..30d96e8 100644 +--- a/arch/arm/mm/proc-v6.S ++++ b/arch/arm/mm/proc-v6.S +@@ -73,10 +73,19 @@ ENDPROC(cpu_v6_reset) + * + * IRQs are already disabled. + */ ++ ++/* See jira SW-5991 for details of this workaround */ + ENTRY(cpu_v6_do_idle) +- mov r1, #0 +- mcr p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode +- mcr p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ .align 5 ++ mov r1, #2 ++1: subs r1, #1 ++ nop ++ mcreq p15, 0, r1, c7, c10, 4 @ DWB - WFI may enter a low-power mode ++ mcreq p15, 0, r1, c7, c0, 4 @ wait for interrupt ++ nop ++ nop ++ nop ++ bne 1b + ret lr + + ENTRY(cpu_v6_dcache_clean_area) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S -index 8b4ee5e..80fa74b 100644 +index 3d1054f..7615bbf 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S -@@ -441,6 +441,7 @@ __v7_setup: +@@ -456,6 +456,7 @@ __v7_setup: orr r0, r0, r6 @ set them THUMB( orr r0, r0, #1 << 30 ) @ Thumb exceptions ret lr @ return to head.S:__ret @@ -11036,25 +6920,26 @@ index 8b4ee5e..80fa74b 100644 .align 2 diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types -index c9ddd87..bfc397c 100644 +index 2ed1b8a..b52d949 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types -@@ -523,6 +523,7 @@ prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 +@@ -522,6 +522,8 @@ torbreck MACH_TORBRECK TORBRECK 3090 + prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 paz00 MACH_PAZ00 PAZ00 3128 acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 - bcm2708 MACH_BCM2708 BCM2708 3138 ++bcm2708 MACH_BCM2708 BCM2708 3138 +bcm2709 MACH_BCM2709 BCM2709 3139 ag5evm MACH_AG5EVM AG5EVM 3189 ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c -index a3025e7..4a2a601 100644 +index 0aa135d..89dbcb9 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c -@@ -804,3 +804,39 @@ static void __init arch_timer_mem_init(struct device_node *np) +@@ -882,3 +882,39 @@ void __init acpi_generic_timer_init(void) + acpi_table_parse(ACPI_SIG_GTDT, arch_timer_acpi_init); } - CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", - arch_timer_mem_init); + #endif + +int __init dc4_arch_timer_init(void) +{ @@ -11091,11 +6976,396 @@ index a3025e7..4a2a601 100644 + arch_timer_common_init(); + return 0; +} +diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c +index 763eb20..ad45801 100644 +--- a/drivers/tty/serial/amba-pl011.c ++++ b/drivers/tty/serial/amba-pl011.c +@@ -85,7 +85,7 @@ struct vendor_data { + + static unsigned int get_fifosize_arm(struct amba_device *dev) + { +- return amba_rev(dev) < 3 ? 16 : 32; ++ return 16; //TODO: fix: amba_rev(dev) < 3 ? 16 : 32; + } + + static struct vendor_data vendor_arm = { +diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h +index b5bedae..b0258e8 100644 +--- a/include/linux/mmc/host.h ++++ b/include/linux/mmc/host.h +@@ -285,6 +285,7 @@ struct mmc_host { + MMC_CAP2_HS400_1_2V) + #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) + #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) ++#define MMC_CAP2_FORCE_MULTIBLOCK (1 << 31) /* Always use multiblock transfers */ + + mmc_pm_flag_t pm_caps; /* supported pm features */ + -From ade70caa2a108d3a2257a32ce6873758ae968f97 Mon Sep 17 00:00:00 2001 +From aa090a771afa15310eb10d3209c190441f3ecefd Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 16 Jun 2015 23:48:09 +0100 +Subject: [PATCH 02/77] power: Add power driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: popcornmix + +BCM270x: power: Change initcall level to subsys + +Load ordering of modules are determined by the initcall used. +If it's the same initcall level, makefile ordering decides. +Now that the mailbox driver is being moved, it's no longer +placed before the power driver by the linker. +So use a later initcall level to let the mailbox driver +load first. + +Signed-off-by: Noralf Trønnes + +BCM270x: Move power module + +Make the power module available on ARCH_BCM2835 by moving it. +The module turns on USB power making it possible to boot +ARCH_BCM2835 directly with the VC bootloader. + +Signed-off-by: Noralf Trønnes +--- + drivers/soc/Kconfig | 1 + + drivers/soc/Makefile | 1 + + drivers/soc/bcm2835/Kconfig | 9 ++ + drivers/soc/bcm2835/Makefile | 1 + + drivers/soc/bcm2835/bcm2708-power.c | 200 ++++++++++++++++++++++++++++++++++++ + include/soc/bcm2835/power.h | 61 +++++++++++ + 6 files changed, 273 insertions(+) + create mode 100644 drivers/soc/bcm2835/Kconfig + create mode 100644 drivers/soc/bcm2835/Makefile + create mode 100644 drivers/soc/bcm2835/bcm2708-power.c + create mode 100644 include/soc/bcm2835/power.h + +diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig +index d8bde82..595c9cd 100644 +--- a/drivers/soc/Kconfig ++++ b/drivers/soc/Kconfig +@@ -1,5 +1,6 @@ + menu "SOC (System On Chip) specific Drivers" + ++source "drivers/soc/bcm2835/Kconfig" + source "drivers/soc/mediatek/Kconfig" + source "drivers/soc/qcom/Kconfig" + source "drivers/soc/ti/Kconfig" +diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile +index 70042b2..9ad449c 100644 +--- a/drivers/soc/Makefile ++++ b/drivers/soc/Makefile +@@ -2,6 +2,7 @@ + # Makefile for the Linux Kernel SOC specific device drivers. + # + ++obj-y += bcm2835/ + obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ + obj-$(CONFIG_ARCH_QCOM) += qcom/ + obj-$(CONFIG_ARCH_TEGRA) += tegra/ +diff --git a/drivers/soc/bcm2835/Kconfig b/drivers/soc/bcm2835/Kconfig +new file mode 100644 +index 0000000..c2980f3 +--- /dev/null ++++ b/drivers/soc/bcm2835/Kconfig +@@ -0,0 +1,9 @@ ++# ++# BCM2835 Soc drivers ++# ++config BCM2708_POWER ++ tristate "BCM2708 legacy power driver" ++ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX ++ default y ++ help ++ Turns on USB power and provides an API for controlling power. +diff --git a/drivers/soc/bcm2835/Makefile b/drivers/soc/bcm2835/Makefile +new file mode 100644 +index 0000000..3614ad9 +--- /dev/null ++++ b/drivers/soc/bcm2835/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_BCM2708_POWER) += bcm2708-power.o +diff --git a/drivers/soc/bcm2835/bcm2708-power.c b/drivers/soc/bcm2835/bcm2708-power.c +new file mode 100644 +index 0000000..e7931a9 +--- /dev/null ++++ b/drivers/soc/bcm2835/bcm2708-power.c +@@ -0,0 +1,200 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/power.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "bcm2708_power" ++ ++#define BCM_POWER_MAXCLIENTS 4 ++#define BCM_POWER_NOCLIENT (1<<31) ++ ++/* Some drivers expect there devices to be permanently powered */ ++ ++#ifdef CONFIG_USB ++#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) ++#endif ++ ++#if 1 ++#define DPRINTK printk ++#else ++#define DPRINTK if (0) printk ++#endif ++ ++struct state_struct { ++ uint32_t global_request; ++ uint32_t client_request[BCM_POWER_MAXCLIENTS]; ++ struct semaphore client_mutex; ++ struct semaphore mutex; ++} g_state; ++ ++int bcm_power_open(BCM_POWER_HANDLE_T *handle) ++{ ++ BCM_POWER_HANDLE_T i; ++ int ret = -EBUSY; ++ ++ down(&g_state.client_mutex); ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { ++ g_state.client_request[i] = BCM_POWER_NONE; ++ *handle = i; ++ ret = 0; ++ break; ++ } ++ } ++ ++ up(&g_state.client_mutex); ++ ++ DPRINTK("bcm_power_open() -> %d\n", *handle); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(bcm_power_open); ++ ++int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) ++{ ++ int rc = 0; ++ ++ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); ++ ++ if ((handle < BCM_POWER_MAXCLIENTS) && ++ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { ++ if (down_interruptible(&g_state.mutex) != 0) { ++ DPRINTK("bcm_power_request -> interrupted\n"); ++ return -EINTR; ++ } ++ ++ if (request != g_state.client_request[handle]) { ++ uint32_t others_request = 0; ++ uint32_t global_request; ++ BCM_POWER_HANDLE_T i; ++ ++ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { ++ if (i != handle) ++ others_request |= ++ g_state.client_request[i]; ++ } ++ others_request &= ~BCM_POWER_NOCLIENT; ++ ++ global_request = request | others_request; ++ if (global_request != g_state.global_request) { ++ uint32_t actual; ++ ++ /* Send a request to VideoCore */ ++ 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); ++ DPRINTK ++ ("bcm_mailbox_read -> %08x, %d\n", ++ actual, rc); ++ actual >>= 4; ++ } else { ++ rc = 0; ++ actual = global_request; ++ } ++ ++ 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", ++ __func__, ++ g_state.global_request, ++ global_request, actual, request, others_request); ++ /* A failure */ ++ BUG_ON((others_request & actual) ++ != others_request); ++ request &= actual; ++ rc = -EIO; ++ } ++ ++ g_state.global_request = actual; ++ g_state.client_request[handle] = ++ request; ++ } ++ } ++ } ++ up(&g_state.mutex); ++ } else { ++ rc = -EINVAL; ++ } ++ DPRINTK("bcm_power_request -> %d\n", rc); ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_request); ++ ++int bcm_power_close(BCM_POWER_HANDLE_T handle) ++{ ++ int rc; ++ ++ DPRINTK("bcm_power_close(%d)\n", handle); ++ ++ rc = bcm_power_request(handle, BCM_POWER_NONE); ++ if (rc == 0) ++ g_state.client_request[handle] = BCM_POWER_NOCLIENT; ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_power_close); ++ ++static int __init bcm_power_init(void) ++{ ++#if defined(BCM_POWER_ALWAYS_ON) ++ BCM_POWER_HANDLE_T always_on_handle; ++#endif ++ int rc = 0; ++ 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; ++ ++ sema_init(&g_state.client_mutex, 1); ++ sema_init(&g_state.mutex, 1); ++ ++ g_state.global_request = 0; ++ ++#if defined(BCM_POWER_ALWAYS_ON) ++ if (BCM_POWER_ALWAYS_ON) { ++ bcm_power_open(&always_on_handle); ++ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); ++ } ++#endif ++ ++ return rc; ++} ++ ++static void __exit bcm_power_exit(void) ++{ ++ bcm_mailbox_write(MBOX_CHAN_POWER, 0); ++} ++ ++/* ++ * Load after the mailbox driver is initialized (arch_initcall), ++ * but before depending drivers (module_init). ++ */ ++subsys_initcall(bcm_power_init); ++module_exit(bcm_power_exit); ++ ++MODULE_AUTHOR("Phil Elwell"); ++MODULE_DESCRIPTION("Interface to BCM2708 power management"); ++MODULE_LICENSE("GPL"); +diff --git a/include/soc/bcm2835/power.h b/include/soc/bcm2835/power.h +new file mode 100644 +index 0000000..bf22b26 +--- /dev/null ++++ b/include/soc/bcm2835/power.h +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for controlling the power to ++ * VideoCore subsystems. ++ */ ++ ++#ifndef _BCM2708_POWER_H ++#define _BCM2708_POWER_H ++ ++#include ++ ++/* Use meaningful names on each side */ ++#ifdef __VIDEOCORE__ ++#define PREFIX(x) ARM_##x ++#else ++#define PREFIX(x) BCM_##x ++#endif ++ ++enum { ++ PREFIX(POWER_SDCARD_BIT), ++ PREFIX(POWER_UART_BIT), ++ PREFIX(POWER_MINIUART_BIT), ++ PREFIX(POWER_USB_BIT), ++ PREFIX(POWER_I2C0_BIT), ++ PREFIX(POWER_I2C1_BIT), ++ PREFIX(POWER_I2C2_BIT), ++ PREFIX(POWER_SPI_BIT), ++ PREFIX(POWER_CCP2TX_BIT), ++ PREFIX(POWER_DSI_BIT), ++ ++ PREFIX(POWER_MAX) ++}; ++ ++enum { ++ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), ++ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), ++ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), ++ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), ++ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), ++ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), ++ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), ++ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), ++ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), ++ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), ++ ++ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, ++ PREFIX(POWER_NONE) = 0 ++}; ++ ++typedef unsigned int BCM_POWER_HANDLE_T; ++ ++extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); ++extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); ++extern int bcm_power_close(BCM_POWER_HANDLE_T handle); ++ ++#endif + +From 9409d45ef7d82d4f0677ea1a16bb6e87d41ed8de Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 8 Oct 2014 18:50:05 +0100 -Subject: [PATCH 003/216] Add bcm2708_gpio driver +Subject: [PATCH 03/77] Add bcm2708_gpio driver Signed-off-by: popcornmix @@ -11130,22 +7400,23 @@ Issue: linux #760 --- arch/arm/mach-bcm2708/Kconfig | 8 + arch/arm/mach-bcm2708/Makefile | 1 + - arch/arm/mach-bcm2708/bcm2708.c | 28 ++ + arch/arm/mach-bcm2708/bcm2708.c | 25 ++ arch/arm/mach-bcm2708/bcm2708_gpio.c | 426 ++++++++++++++++++++++++++++++ arch/arm/mach-bcm2708/include/mach/gpio.h | 17 ++ + arch/arm/mach-bcm2709/bcm2709.c | 25 ++ include/linux/platform_data/bcm2708.h | 23 ++ - 6 files changed, 503 insertions(+) + 7 files changed, 525 insertions(+) create mode 100644 arch/arm/mach-bcm2708/bcm2708_gpio.c create mode 100644 arch/arm/mach-bcm2708/include/mach/gpio.h create mode 100644 include/linux/platform_data/bcm2708.h diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 1f11478..9355841 100644 +index 4955422..4cbda0c 100644 --- a/arch/arm/mach-bcm2708/Kconfig +++ b/arch/arm/mach-bcm2708/Kconfig -@@ -9,6 +9,14 @@ config MACH_BCM2708 +@@ -20,6 +20,14 @@ config BCM2708_DT help - Include support for the Broadcom(R) BCM2708 platform. + Enable Device Tree support for BCM2708 +config BCM2708_GPIO + bool "BCM2708 gpio support" @@ -11155,24 +7426,23 @@ index 1f11478..9355841 100644 + help + Include support for the Broadcom(R) BCM2708 gpio. + - config BCM2708_VCMEM - bool "Videocore Memory" + config BCM2708_NOL2CACHE + bool "Videocore L2 cache disable" depends on MACH_BCM2708 diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index c76f39bc..a722f3f 100644 +index e7d5a29..5120994 100644 --- a/arch/arm/mach-bcm2708/Makefile +++ b/arch/arm/mach-bcm2708/Makefile -@@ -3,4 +3,5 @@ +@@ -3,3 +3,4 @@ # - obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o + obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o +obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 9b4e709..7503649 100644 +index d6659b0..c606853 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -331,6 +331,31 @@ static struct platform_device bcm2708_vcio_device = { +@@ -298,6 +298,31 @@ static struct platform_device bcm2708_vcio_device = { }, }; @@ -11201,19 +7471,9 @@ index 9b4e709..7503649 100644 +}; +#endif + - static struct resource bcm2708_systemtimer_resources[] = { - [0] = { /* system timer access */ - .start = ST_BASE, -@@ -473,6 +498,9 @@ void __init bcm2708_init(void) - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_vcio_device); -+#ifdef CONFIG_BCM2708_GPIO -+ bcm_register_device(&bcm2708_gpio_device); -+#endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c new file mode 100644 index 0000000..c1e9254 @@ -11669,6 +7929,42 @@ index 0000000..7965a97 +#define irq_to_gpio(x) ((x) - GPIO_IRQ_START) + +#endif +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 19d0601..6060a0d 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -329,6 +329,31 @@ static struct platform_device bcm2708_vcio_device = { + }, + }; + ++#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, ++ }, ++}; ++ ++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 ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; diff --git a/include/linux/platform_data/bcm2708.h b/include/linux/platform_data/bcm2708.h new file mode 100644 index 0000000..fb69624 @@ -11699,10 +7995,647 @@ index 0000000..fb69624 + +#endif -From 2ca472651d3e308f62709f5e2536eaba99944b11 Mon Sep 17 00:00:00 2001 +From 4b9ec02bb6738a9c29f6308c55cbcab58c2c88a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= +Date: Fri, 1 May 2015 19:11:03 +0200 +Subject: [PATCH 04/77] mailbox: bcm2708: Add bcm2708-vcio +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: popcornmix + +Copy the arch vcio.c driver to drivers/mailbox. +This is done to make it available on ARCH_BCM2835. + +Signed-off-by: Noralf Trønnes + +mailbox: bcm2708-vcio: Allocation does not need to be atomic + +No need to do atomic allocation in a context that can sleep. + +Signed-off-by: Noralf Trønnes + +mailbox: bcm2708-vcio: Check the correct status register before writing + +With the VC reader blocked and the ARM writing, MAIL0_STA reads +empty permanently while MAIL1_STA goes from empty (0x40000000) +to non-empty (0x00000001-0x00000007) to full (0x80000008). + +Suggested-by: Phil Elwell +Signed-off-by: Noralf Trønnes +--- + drivers/mailbox/Kconfig | 6 + + drivers/mailbox/Makefile | 2 + + drivers/mailbox/bcm2708-vcio.c | 427 ++++++++++++++++++++++++++ + include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++ + 4 files changed, 561 insertions(+) + create mode 100644 drivers/mailbox/bcm2708-vcio.c + create mode 100644 include/linux/platform_data/mailbox-bcm2708.h + +diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig +index 84b0a2d..7f19cb4 100644 +--- a/drivers/mailbox/Kconfig ++++ b/drivers/mailbox/Kconfig +@@ -7,6 +7,12 @@ menuconfig MAILBOX + + if MAILBOX + ++config BCM2708_MBOX ++ bool "Broadcom BCM2708 Mailbox (vcio)" ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 ++ help ++ Broadcom BCM2708 Mailbox (vcio) ++ + config ARM_MHU + tristate "ARM MHU Mailbox" + depends on ARM_AMBA +diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile +index b18201e..cecfad3 100644 +--- a/drivers/mailbox/Makefile ++++ b/drivers/mailbox/Makefile +@@ -2,6 +2,8 @@ + + obj-$(CONFIG_MAILBOX) += mailbox.o + ++obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o ++ + obj-$(CONFIG_ARM_MHU) += arm_mhu.o + + obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o +diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c +new file mode 100644 +index 0000000..d91672b +--- /dev/null ++++ b/drivers/mailbox/bcm2708-vcio.c +@@ -0,0 +1,427 @@ ++/* ++ * linux/arch/arm/mach-bcm2708/vcio.c ++ * ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This device provides a shared mechanism for writing to the mailboxes, ++ * semaphores, doorbells etc. that are shared between the ARM and the ++ * VideoCore processor ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "bcm2708_vcio" ++#define DEVICE_FILE_NAME "vcio" ++ ++/* offsets from a mail box base address */ ++#define MAIL0_RD 0x00 /* read - and next 4 words */ ++#define MAIL0_POL 0x10 /* read without popping the fifo */ ++#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ ++#define MAIL0_STA 0x18 /* status */ ++#define MAIL0_CNF 0x1C /* configuration */ ++#define MAIL1_WRT 0x20 /* write - and next 4 words */ ++#define MAIL1_STA 0x38 /* status */ ++ ++/* On MACH_BCM270x these come through (arm_control.h ) */ ++#ifndef ARM_MS_EMPTY ++#define ARM_MS_EMPTY BIT(30) ++#define ARM_MS_FULL BIT(31) ++ ++#define ARM_MC_IHAVEDATAIRQEN BIT(0) ++#endif ++ ++#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) ++#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) ++#define MBOX_CHAN(msg) ((msg) & 0xf) ++#define MBOX_DATA28(msg) ((msg) & ~0xf) ++#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) ++ ++#define MBOX_MAGIC 0xd0d0c0de ++ ++#define MAJOR_NUM 100 ++#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) ++ ++static struct class *vcio_class; ++ ++struct vc_mailbox { ++ void __iomem *regs; ++ uint32_t msg[MBOX_CHAN_COUNT]; ++ struct semaphore sema[MBOX_CHAN_COUNT]; ++ uint32_t magic; ++}; ++ ++static void mbox_init(struct vc_mailbox *mbox_out) ++{ ++ int i; ++ ++ for (i = 0; i < MBOX_CHAN_COUNT; i++) { ++ mbox_out->msg[i] = 0; ++ sema_init(&mbox_out->sema[i], 0); ++ } ++ ++ /* Enable the interrupt on data reception */ ++ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); ++ ++ mbox_out->magic = MBOX_MAGIC; ++} ++ ++static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) ++{ ++ if (mbox->magic != MBOX_MAGIC) ++ return -EINVAL; ++ ++ /* wait for the mailbox FIFO to have some space in it */ ++ while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) ++ cpu_relax(); ++ ++ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); ++ ++ return 0; ++} ++ ++static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) ++{ ++ if (mbox->magic != MBOX_MAGIC) ++ return -EINVAL; ++ ++ down(&mbox->sema[chan]); ++ *data28 = MBOX_DATA28(mbox->msg[chan]); ++ mbox->msg[chan] = 0; ++ ++ return 0; ++} ++ ++static irqreturn_t mbox_irq_handler(int irq, void *dev_id) ++{ ++ /* wait for the mailbox FIFO to have some data in it */ ++ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; ++ int status = readl(mbox->regs + MAIL0_STA); ++ int ret = IRQ_NONE; ++ ++ while (!(status & ARM_MS_EMPTY)) { ++ uint32_t msg = readl(mbox->regs + MAIL0_RD); ++ int chan = MBOX_CHAN(msg); ++ ++ if (chan < MBOX_CHAN_COUNT) { ++ if (mbox->msg[chan]) { ++ pr_err(DRIVER_NAME ++ ": mbox chan %d overflow - drop %08x\n", ++ chan, msg); ++ } else { ++ mbox->msg[chan] = (msg | 0xf); ++ up(&mbox->sema[chan]); ++ } ++ } else { ++ pr_err(DRIVER_NAME ++ ": invalid channel selector (msg %08x)\n", msg); ++ } ++ ret = IRQ_HANDLED; ++ status = readl(mbox->regs + MAIL0_STA); ++ } ++ return ret; ++} ++ ++/* Mailbox Methods */ ++ ++static struct device *mbox_dev; /* we assume there's only one! */ ++ ++static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) ++{ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ int rc; ++ ++ device_lock(dev); ++ rc = mbox_write(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) ++{ ++ struct vc_mailbox *mailbox = dev_get_drvdata(dev); ++ int rc; ++ ++ device_lock(dev); ++ rc = mbox_read(mailbox, chan, data28); ++ device_unlock(dev); ++ ++ return rc; ++} ++ ++extern int bcm_mailbox_write(unsigned chan, uint32_t data28) ++{ ++ if (!mbox_dev) ++ return -ENODEV; ++ ++ return dev_mbox_write(mbox_dev, chan, data28); ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_write); ++ ++extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) ++{ ++ if (!mbox_dev) ++ return -ENODEV; ++ ++ return dev_mbox_read(mbox_dev, chan, data28); ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_read); ++ ++static int mbox_copy_from_user(void *dst, const void *src, int size) ++{ ++ if ((uint32_t)src < TASK_SIZE) ++ return copy_from_user(dst, src, size); ++ ++ memcpy(dst, src, size); ++ ++ return 0; ++} ++ ++static int mbox_copy_to_user(void *dst, const void *src, int size) ++{ ++ if ((uint32_t)dst < TASK_SIZE) ++ return copy_to_user(dst, src, size); ++ ++ memcpy(dst, src, size); ++ ++ return 0; ++} ++ ++static DEFINE_MUTEX(mailbox_lock); ++extern int bcm_mailbox_property(void *data, int size) ++{ ++ uint32_t success; ++ dma_addr_t mem_bus; /* the memory address accessed from videocore */ ++ void *mem_kern; /* the memory address accessed from driver */ ++ int s = 0; ++ ++ mutex_lock(&mailbox_lock); ++ /* allocate some memory for the messages communicating with GPU */ ++ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, ++ GFP_KERNEL); ++ if (mem_kern) { ++ /* create the message */ ++ mbox_copy_from_user(mem_kern, data, size); ++ ++ /* send the message */ ++ wmb(); ++ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); ++ if (s == 0) ++ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); ++ if (s == 0) { ++ /* copy the response */ ++ rmb(); ++ mbox_copy_to_user(data, mem_kern, size); ++ } ++ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); ++ } else { ++ s = -ENOMEM; ++ } ++ if (s != 0) ++ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); ++ ++ mutex_unlock(&mailbox_lock); ++ return s; ++} ++EXPORT_SYMBOL_GPL(bcm_mailbox_property); ++ ++/* Platform Device for Mailbox */ ++ ++/* ++ * Is the device open right now? Used to prevent ++ * concurent access into the same device ++ */ ++static bool device_is_open; ++ ++/* This is called whenever a process attempts to open the device file */ ++static int device_open(struct inode *inode, struct file *file) ++{ ++ /* We don't want to talk to two processes at the same time */ ++ if (device_is_open) ++ return -EBUSY; ++ ++ device_is_open = true; ++ try_module_get(THIS_MODULE); ++ ++ return 0; ++} ++ ++static int device_release(struct inode *inode, struct file *file) ++{ ++ /* We're now ready for our next caller */ ++ device_is_open = false; ++ ++ module_put(THIS_MODULE); ++ ++ return 0; ++} ++ ++/* ++ * This function is called whenever a process tries to do an ioctl on our ++ * device file. We get two extra parameters (additional to the inode and file ++ * structures, which all device functions get): the number of the ioctl called ++ * and the parameter given to the ioctl function. ++ * ++ * If the ioctl is write or read/write (meaning output is returned to the ++ * calling process), the ioctl call returns the output of this function. ++ * ++ */ ++static long device_ioctl(struct file *file, unsigned int ioctl_num, ++ unsigned long ioctl_param) ++{ ++ unsigned size; ++ ++ switch (ioctl_num) { ++ case IOCTL_MBOX_PROPERTY: ++ /* ++ * Receive a pointer to a message (in user space) and set that ++ * to be the device's message. Get the parameter given to ++ * ioctl by the process. ++ */ ++ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); ++ return bcm_mailbox_property((void *)ioctl_param, size); ++ default: ++ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++/* Module Declarations */ ++ ++/* ++ * This structure will hold the functions to be called ++ * when a process does something to the device we ++ * created. Since a pointer to this structure is kept in ++ * the devices table, it can't be local to ++ * init_module. NULL is for unimplemented functios. ++ */ ++const struct file_operations fops = { ++ .unlocked_ioctl = device_ioctl, ++ .open = device_open, ++ .release = device_release, /* a.k.a. close */ ++}; ++ ++static int bcm_vcio_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device *vdev; ++ struct vc_mailbox *mailbox; ++ struct resource *res; ++ int irq, ret; ++ ++ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); ++ if (!mailbox) ++ return -ENOMEM; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ mailbox->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(mailbox->regs)) ++ return PTR_ERR(mailbox->regs); ++ ++ irq = platform_get_irq(pdev, 0); ++ ret = devm_request_irq(dev, irq, mbox_irq_handler, ++ IRQF_IRQPOLL, ++ dev_name(dev), mailbox); ++ if (ret) { ++ dev_err(dev, "Interrupt request failed %d\n", ret); ++ return ret; ++ } ++ ++ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); ++ if (ret < 0) { ++ pr_err("Character device registration failed %d\n", ret); ++ return ret; ++ } ++ ++ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); ++ if (IS_ERR(vcio_class)) { ++ ret = PTR_ERR(vcio_class); ++ pr_err("Class creation failed %d\n", ret); ++ goto err_class; ++ } ++ ++ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, ++ "vcio"); ++ if (IS_ERR(vdev)) { ++ ret = PTR_ERR(vdev); ++ pr_err("Device creation failed %d\n", ret); ++ goto err_dev; ++ } ++ ++ mbox_init(mailbox); ++ platform_set_drvdata(pdev, mailbox); ++ mbox_dev = dev; ++ ++ dev_info(dev, "mailbox at %p\n", mailbox->regs); ++ ++ return 0; ++ ++err_dev: ++ class_destroy(vcio_class); ++err_class: ++ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); ++ ++ return ret; ++} ++ ++static int bcm_vcio_remove(struct platform_device *pdev) ++{ ++ mbox_dev = NULL; ++ platform_set_drvdata(pdev, NULL); ++ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); ++ class_destroy(vcio_class); ++ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_vcio_of_match_table[] = { ++ { .compatible = "brcm,bcm2708-vcio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); ++ ++static struct platform_driver bcm_mbox_driver = { ++ .probe = bcm_vcio_probe, ++ .remove = bcm_vcio_remove, ++ ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_vcio_of_match_table, ++ }, ++}; ++ ++static int __init bcm_mbox_init(void) ++{ ++ return platform_driver_register(&bcm_mbox_driver); ++} ++ ++static void __exit bcm_mbox_exit(void) ++{ ++ platform_driver_unregister(&bcm_mbox_driver); ++} ++ ++arch_initcall(bcm_mbox_init); /* Initialize early */ ++module_exit(bcm_mbox_exit); ++ ++MODULE_AUTHOR("Gray Girling"); ++MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); ++MODULE_LICENSE("GPL"); +diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h +new file mode 100644 +index 0000000..cc284ed +--- /dev/null ++++ b/include/linux/platform_data/mailbox-bcm2708.h +@@ -0,0 +1,126 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * ++ * 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. ++ */ ++#ifndef _PLAT_MAILBOX_BCM2708_H ++#define _PLAT_MAILBOX_BCM2708_H ++ ++/* Routines to handle I/O via the VideoCore "ARM control" registers ++ * (semaphores, doorbells, mailboxes) ++ */ ++ ++/* Constants shared with the ARM identifying separate mailbox channels */ ++#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ ++#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ ++#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ ++#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ ++#define MBOX_CHAN_COUNT 9 ++ ++enum { ++ VCMSG_PROCESS_REQUEST = 0x00000000 ++}; ++ ++enum { ++ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, ++ VCMSG_REQUEST_FAILED = 0x80000001 ++}; ++ ++/* Mailbox property tags */ ++enum { ++ VCMSG_PROPERTY_END = 0x00000000, ++ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, ++ VCMSG_GET_BOARD_MODEL = 0x00010001, ++ VCMSG_GET_BOARD_REVISION = 0x00010002, ++ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, ++ VCMSG_GET_BOARD_SERIAL = 0x00010004, ++ VCMSG_GET_ARM_MEMORY = 0x00010005, ++ VCMSG_GET_VC_MEMORY = 0x00010006, ++ VCMSG_GET_CLOCKS = 0x00010007, ++ VCMSG_GET_COMMAND_LINE = 0x00050001, ++ VCMSG_GET_DMA_CHANNELS = 0x00060001, ++ VCMSG_GET_POWER_STATE = 0x00020001, ++ VCMSG_GET_TIMING = 0x00020002, ++ VCMSG_SET_POWER_STATE = 0x00028001, ++ VCMSG_GET_CLOCK_STATE = 0x00030001, ++ VCMSG_SET_CLOCK_STATE = 0x00038001, ++ VCMSG_GET_CLOCK_RATE = 0x00030002, ++ VCMSG_SET_CLOCK_RATE = 0x00038002, ++ VCMSG_GET_VOLTAGE = 0x00030003, ++ VCMSG_SET_VOLTAGE = 0x00038003, ++ VCMSG_GET_MAX_CLOCK = 0x00030004, ++ VCMSG_GET_MAX_VOLTAGE = 0x00030005, ++ VCMSG_GET_TEMPERATURE = 0x00030006, ++ VCMSG_GET_MIN_CLOCK = 0x00030007, ++ VCMSG_GET_MIN_VOLTAGE = 0x00030008, ++ VCMSG_GET_TURBO = 0x00030009, ++ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, ++ VCMSG_GET_STC = 0x0003000b, ++ VCMSG_SET_TURBO = 0x00038009, ++ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, ++ VCMSG_SET_LOCK_MEM = 0x0003000d, ++ VCMSG_SET_UNLOCK_MEM = 0x0003000e, ++ VCMSG_SET_RELEASE_MEM = 0x0003000f, ++ VCMSG_SET_EXECUTE_CODE = 0x00030010, ++ VCMSG_SET_EXECUTE_QPU = 0x00030011, ++ VCMSG_SET_ENABLE_QPU = 0x00030012, ++ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, ++ VCMSG_GET_EDID_BLOCK = 0x00030020, ++ VCMSG_GET_CUSTOMER_OTP = 0x00030021, ++ VCMSG_SET_CUSTOMER_OTP = 0x00038021, ++ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, ++ VCMSG_SET_RELEASE_BUFFER = 0x00048001, ++ VCMSG_SET_BLANK_SCREEN = 0x00040002, ++ VCMSG_TST_BLANK_SCREEN = 0x00044002, ++ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, ++ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, ++ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, ++ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, ++ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, ++ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, ++ VCMSG_GET_DEPTH = 0x00040005, ++ VCMSG_TST_DEPTH = 0x00044005, ++ VCMSG_SET_DEPTH = 0x00048005, ++ VCMSG_GET_PIXEL_ORDER = 0x00040006, ++ VCMSG_TST_PIXEL_ORDER = 0x00044006, ++ VCMSG_SET_PIXEL_ORDER = 0x00048006, ++ VCMSG_GET_ALPHA_MODE = 0x00040007, ++ VCMSG_TST_ALPHA_MODE = 0x00044007, ++ VCMSG_SET_ALPHA_MODE = 0x00048007, ++ VCMSG_GET_PITCH = 0x00040008, ++ VCMSG_TST_PITCH = 0x00044008, ++ VCMSG_SET_PITCH = 0x00048008, ++ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, ++ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, ++ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, ++ VCMSG_GET_OVERSCAN = 0x0004000a, ++ VCMSG_TST_OVERSCAN = 0x0004400a, ++ VCMSG_SET_OVERSCAN = 0x0004800a, ++ VCMSG_GET_PALETTE = 0x0004000b, ++ VCMSG_TST_PALETTE = 0x0004400b, ++ VCMSG_SET_PALETTE = 0x0004800b, ++ VCMSG_GET_LAYER = 0x0004000c, ++ VCMSG_TST_LAYER = 0x0004400c, ++ VCMSG_SET_LAYER = 0x0004800c, ++ VCMSG_GET_TRANSFORM = 0x0004000d, ++ VCMSG_TST_TRANSFORM = 0x0004400d, ++ VCMSG_SET_TRANSFORM = 0x0004800d, ++ VCMSG_TST_VSYNC = 0x0004400e, ++ VCMSG_SET_VSYNC = 0x0004800e, ++ VCMSG_SET_CURSOR_INFO = 0x00008010, ++ VCMSG_SET_CURSOR_STATE = 0x00008011, ++}; ++ ++int bcm_mailbox_read(unsigned chan, uint32_t *data28); ++int bcm_mailbox_write(unsigned chan, uint32_t data28); ++int bcm_mailbox_property(void *data, int size); ++ ++#endif + +From c921ec1cd21e8a8eb4e453834a205e9da5dff30a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:46:17 +0100 -Subject: [PATCH 004/216] Add dwc_otg driver +Subject: [PATCH 05/77] Add dwc_otg driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix @@ -12117,16 +9050,38 @@ in the middle of a transaction. Make the effects less severe. Also get rid of the useless return value. squash: dwc_otg: Allow to build without SMP + +usb: core: make overcurrent messages more prominent + +Hub overcurrent messages are more serious than "debug". Increase loglevel. + +usb: dwc_otg: Don't use dma_to_virt() + +Commit 6ce0d20 changes dma_to_virt() which breaks this driver. +Open code the old dma_to_virt() implementation to work around this. + +Limit the use of __bus_to_virt() to cases where transfer_buffer_length +is set and transfer_buffer is not set. This is done to increase the +chance that this driver will also work on ARCH_BCM2835. + +transfer_buffer should not be NULL if the length is set, but the +comment in the code indicates that there are situations where this +might happen. drivers/usb/isp1760/isp1760-hcd.c also has a similar +comment pointing to a possible: 'usb storage / SCSI bug'. + +Signed-off-by: Noralf Trønnes + +dwc_otg: Fix crash when fiq_enable=0 --- - arch/arm/Kconfig | 1 + arch/arm/include/asm/irqflags.h | 16 +- arch/arm/kernel/fiqasm.S | 4 + arch/arm/mach-bcm2708/armctrl.c | 19 +- - arch/arm/mach-bcm2708/bcm2708.c | 15 +- + arch/arm/mach-bcm2708/bcm2708.c | 11 + arch/arm/mach-bcm2708/include/mach/irqs.h | 153 +- arch/arm/mach-bcm2709/armctrl.c | 10 +- drivers/usb/Makefile | 1 + drivers/usb/core/generic.c | 1 + + drivers/usb/core/hub.c | 2 +- drivers/usb/core/message.c | 79 + drivers/usb/core/otg_whitelist.h | 114 +- drivers/usb/gadget/file_storage.c | 3676 ++++++++++ @@ -12169,7 +9124,7 @@ squash: dwc_otg: Allow to build without SMP drivers/usb/host/dwc_otg/dwc_otg_cil_intr.c | 1594 +++++ drivers/usb/host/dwc_otg/dwc_otg_core_if.h | 705 ++ drivers/usb/host/dwc_otg/dwc_otg_dbg.h | 117 + - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1749 +++++ + drivers/usb/host/dwc_otg/dwc_otg_driver.c | 1756 +++++ drivers/usb/host/dwc_otg/dwc_otg_driver.h | 86 + drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c | 1346 ++++ drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.h | 367 + @@ -12179,7 +9134,7 @@ squash: dwc_otg: Allow to build without SMP drivers/usb/host/dwc_otg/dwc_otg_hcd_ddma.c | 1132 ++++ drivers/usb/host/dwc_otg/dwc_otg_hcd_if.h | 417 ++ drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c | 2713 ++++++++ - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 994 +++ + drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 995 +++ drivers/usb/host/dwc_otg/dwc_otg_hcd_queue.c | 957 +++ drivers/usb/host/dwc_otg/dwc_otg_os_dep.h | 188 + drivers/usb/host/dwc_otg/dwc_otg_pcd.c | 2712 ++++++++ @@ -12192,7 +9147,7 @@ squash: dwc_otg: Allow to build without SMP drivers/usb/host/dwc_otg/test/dwc_otg_test.pm | 337 + drivers/usb/host/dwc_otg/test/test_mod_param.pl | 133 + drivers/usb/host/dwc_otg/test/test_sysfs.pl | 193 + - 74 files changed, 60026 insertions(+), 97 deletions(-) + 74 files changed, 60032 insertions(+), 96 deletions(-) create mode 100644 drivers/usb/gadget/file_storage.c create mode 100644 drivers/usb/host/dwc_common_port/Makefile create mode 100644 drivers/usb/host/dwc_common_port/Makefile.fbsd @@ -12255,18 +9210,6 @@ squash: dwc_otg: Allow to build without SMP create mode 100644 drivers/usb/host/dwc_otg/test/test_mod_param.pl create mode 100644 drivers/usb/host/dwc_otg/test/test_sysfs.pl -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 4018fea..ee1bb5e 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -382,6 +382,7 @@ config ARCH_BCM2708 - select ARM_ERRATA_411920 - select MACH_BCM2708 - select VC4 -+ select FIQ - help - This enables support for Broadcom BCM2708 boards. - diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h index 3b763d6..5770408 100644 --- a/arch/arm/include/asm/irqflags.h @@ -12310,10 +9253,10 @@ index 8dd26e1..eef4847 100644 + mov pc, r8 +ENDPROC(__FIQ_Branch) diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index ef1c8d5..96fa9b9 100644 +index cd252fa..74bacb3 100644 --- a/arch/arm/mach-bcm2708/armctrl.c +++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -52,8 +52,12 @@ static void armctrl_mask_irq(struct irq_data *d) +@@ -54,8 +54,12 @@ static void armctrl_mask_irq(struct irq_data *d) 0 }; @@ -12328,7 +9271,7 @@ index ef1c8d5..96fa9b9 100644 } static void armctrl_unmask_irq(struct irq_data *d) -@@ -65,8 +69,14 @@ static void armctrl_unmask_irq(struct irq_data *d) +@@ -67,8 +71,14 @@ static void armctrl_unmask_irq(struct irq_data *d) 0 }; @@ -12344,38 +9287,37 @@ index ef1c8d5..96fa9b9 100644 + } } - #if defined(CONFIG_PM) -@@ -204,5 +214,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + #ifdef CONFIG_OF +@@ -299,6 +309,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, } armctrl_pm_register(base, irq_start, resume_sources); + init_FIQ(FIQ_START); + armctrl_dt_init(); return 0; } diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 7503649..d9db081 100644 +index c606853..4455f34 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -291,12 +291,23 @@ static struct resource bcm2708_usb_resources[] = { - .flags = IORESOURCE_MEM, - }, +@@ -254,12 +254,23 @@ static struct resource bcm2708_usb_resources[] = { + .flags = IORESOURCE_MEM, + }, [1] = { -- .start = IRQ_USB, -- .end = IRQ_USB, + .start = MPHI_BASE, + .end = MPHI_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, -+ }, ++ }, + [2] = { -+ .start = IRQ_HOSTPORT, -+ .end = IRQ_HOSTPORT, - .flags = IORESOURCE_IRQ, - }, ++ .start = IRQ_HOSTPORT, ++ .end = IRQ_HOSTPORT, ++ .flags = IORESOURCE_IRQ, ++ }, + [3] = { -+ .start = IRQ_USB, -+ .end = IRQ_USB, -+ .flags = IORESOURCE_IRQ, -+ }, + .start = IRQ_USB, + .end = IRQ_USB, + .flags = IORESOURCE_IRQ, + }, }; + @@ -12553,7 +9495,7 @@ index 3a88a1a..45152ed 100644 #define SPARE_ALLOC_IRQS 64 #define BCM2708_ALLOC_IRQS (HARD_IRQS+FIQ_IRQS+GPIO_IRQS+SPARE_ALLOC_IRQS) diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c -index 2815b64..fc6cb8b 100644 +index 2fcfab9..a366275 100644 --- a/arch/arm/mach-bcm2709/armctrl.c +++ b/arch/arm/mach-bcm2709/armctrl.c @@ -91,7 +91,15 @@ static void armctrl_unmask_irq(struct irq_data *d) @@ -12574,12 +9516,12 @@ index 2815b64..fc6cb8b 100644 } else if (d->irq >= IRQ_ARM_LOCAL_CNTPSIRQ && d->irq < IRQ_ARM_LOCAL_CNTPSIRQ + 4) { #if 1 diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile -index 2f1e2aa..887ca56 100644 +index d8926c6..0607af9 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile -@@ -6,6 +6,7 @@ - +@@ -7,6 +7,7 @@ obj-$(CONFIG_USB) += core/ + obj-$(CONFIG_USB_SUPPORT) += phy/ +obj-$(CONFIG_USB_DWCOTG) += host/ obj-$(CONFIG_USB_DWC3) += dwc3/ @@ -12597,6 +9539,19 @@ index 358ca8d..abaac7c 100644 } return i; } +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 3b71516..8324c14 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4922,7 +4922,7 @@ static void port_event(struct usb_hub *hub, int port1) + if (portchange & USB_PORT_STAT_C_OVERCURRENT) { + u16 status = 0, unused; + +- dev_dbg(&port_dev->dev, "over-current change\n"); ++ dev_notice(&port_dev->dev, "over-current change\n"); + usb_clear_port_feature(hdev, port1, + USB_PORT_FEAT_C_OVER_CURRENT); + msleep(100); /* Cool down */ diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f368d20..2f6e3fe 100644 --- a/drivers/usb/core/message.c @@ -16527,7 +13482,7 @@ index 0000000..a896d73 +} +module_exit(fsg_cleanup); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig -index 5ad60e4..fb5b986 100644 +index 197a6a3..5496cd0 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -738,6 +738,19 @@ config USB_HWA_HCD @@ -44589,10 +41544,10 @@ index 0000000..ccc24e0 +#endif diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c new file mode 100644 -index 0000000..dc7cd32 +index 0000000..53307f0 --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -0,0 +1,1749 @@ +@@ -0,0 +1,1756 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.c $ + * $Revision: #92 $ @@ -45638,9 +42593,16 @@ index 0000000..dc7cd32 +}; +MODULE_DEVICE_TABLE(platform, platform_ids); + ++static const struct of_device_id dwc_otg_of_match_table[] = { ++ { .compatible = "brcm,bcm2708-usb", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, dwc_otg_of_match_table); ++ +static struct platform_driver dwc_otg_driver = { + .driver = { + .name = (char *)dwc_driver_name, ++ .of_match_table = dwc_otg_of_match_table, + }, + .id_table = platform_ids, + @@ -48247,7 +45209,7 @@ index 0000000..ffa8d21 +END(_dwc_otg_fiq_stub) diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c new file mode 100644 -index 0000000..6c53d2c +index 0000000..4d7c7bb --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd.c @@ -0,0 +1,4252 @@ @@ -50273,7 +47235,7 @@ index 0000000..6c53d2c + * we hold off on bulk retransmissions to reduce NAK interrupt overhead for full-speed + * cheeky devices that just hold off using NAKs + */ -+ if (nak_holdoff && qh->do_split) { ++ if (fiq_enable && nak_holdoff && qh->do_split) { + if (qh->nak_frame != 0xffff) { + uint16_t next_frame = dwc_frame_num_inc(qh->nak_frame, (qh->ep_type == UE_BULK) ? nak_holdoff : 8); + uint16_t frame = dwc_otg_hcd_get_frame_number(hcd); @@ -57653,10 +54615,10 @@ index 0000000..8a31562 +#endif /* DWC_DEVICE_ONLY */ diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c new file mode 100644 -index 0000000..1d28459 +index 0000000..0f4ebcd --- /dev/null +++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -0,0 +1,994 @@ +@@ -0,0 +1,995 @@ + +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_linux.c $ @@ -58195,9 +55157,9 @@ index 0000000..1d28459 + * IRQ line, and calls hcd_start method. + */ +#ifdef PLATFORM_INTERFACE -+ retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED | IRQF_DISABLED); ++ retval = usb_add_hcd(hcd, platform_get_irq(_dev, fiq_enable ? 0 : 1), IRQF_SHARED); +#else -+ retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED | IRQF_DISABLED); ++ retval = usb_add_hcd(hcd, _dev->irq, IRQF_SHARED); +#endif + if (retval < 0) { + goto error2; @@ -58425,16 +55387,17 @@ index 0000000..1d28459 + !(usb_pipein(urb->pipe)))); + + buf = urb->transfer_buffer; -+ if (hcd->self.uses_dma) { ++ if (hcd->self.uses_dma && !buf && urb->transfer_buffer_length) { + /* + * Calculate virtual address from physical address, + * because some class driver may not fill transfer_buffer. + * In Buffer DMA mode virual address is used, + * when handling non DWORD aligned buffers. + */ -+ //buf = phys_to_virt(urb->transfer_dma); -+ // DMA addresses are bus addresses not physical addresses! -+ buf = dma_to_virt(&urb->dev->dev, urb->transfer_dma); ++ buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma); ++ dev_warn_once(&urb->dev->dev, ++ "USB transfer_buffer was NULL, will use __bus_to_virt(%pad)=%p\n", ++ &urb->transfer_dma, buf); + } + + if (!(urb->transfer_flags & URB_NO_INTERRUPT)) @@ -72943,24 +69906,24 @@ index 0000000..cdc9963 +test_main(); +0; -From 0876a9278a3227e3f8924b6e04c1af6c18d4e1e7 Mon Sep 17 00:00:00 2001 +From 560486db654a651cebb107628426d1705ef4cc20 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 1 May 2013 19:54:32 +0100 -Subject: [PATCH 005/216] bcm2708 watchdog driver +Subject: [PATCH 06/77] bcm2708 watchdog driver Signed-off-by: popcornmix --- - drivers/watchdog/Kconfig | 6 + + drivers/watchdog/Kconfig | 8 +- drivers/watchdog/Makefile | 1 + drivers/watchdog/bcm2708_wdog.c | 382 ++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 389 insertions(+) + 3 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 drivers/watchdog/bcm2708_wdog.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index 16f2023..ca7d6463 100644 +index e5e7c55..b9c1ed5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig -@@ -452,6 +452,12 @@ config RETU_WATCHDOG +@@ -451,6 +451,12 @@ config RETU_WATCHDOG To compile this driver as a module, choose M here: the module will be called retu_wdt. @@ -72973,6 +69936,15 @@ index 16f2023..ca7d6463 100644 config MOXART_WDT tristate "MOXART watchdog" depends on ARCH_MOXART +@@ -1216,7 +1222,7 @@ config BCM63XX_WDT + + config BCM2835_WDT + tristate "Broadcom BCM2835 hardware watchdog" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + select WATCHDOG_CORE + help + Watchdog driver for the built in watchdog hardware in Broadcom diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 5c19294..aac60bd 100644 --- a/drivers/watchdog/Makefile @@ -73374,10 +70346,13 @@ index 0000000..8a27d68 +MODULE_ALIAS_MISCDEV(TEMP_MINOR); +MODULE_LICENSE("GPL"); -From e32648d3db67d9954ee0a8bc13ab3f81345c50af Mon Sep 17 00:00:00 2001 +From 7014dbd386a6ce510bd6b9fa3a3fcfc2bd89d237 Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Wed, 1 May 2013 19:55:09 +0100 -Subject: [PATCH 006/216] bcm2708 framebuffer driver +Date: Wed, 17 Jun 2015 17:06:34 +0100 +Subject: [PATCH 07/77] bcm2708 framebuffer driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix @@ -73423,55 +70398,40 @@ transfers, busy-waiting is still likely to be faster. Signed-off-by: Luke Diamand bcm2708: Make ioctl logging quieter + +video: fbdev: bcm2708_fb: Don't panic on error + +No need to panic the kernel if the video driver fails. +Just print a message and return an error. + +Signed-off-by: Noralf Trønnes + +fbdev: bcm2708_fb: Add ARCH_BCM2835 support + +Add Device Tree support. +Pass the device to dma_alloc_coherent() in order to get the +correct bus address on ARCH_BCM2835. +Use the new DMA legacy API header file. +Including is not necessary. + +Signed-off-by: Noralf Trønnes + +BCM270x_DT: Add bcm2708-fb device + +Add bcm2708-fb to Device Tree and don't add the +platform device when booting in DT mode. + +Signed-off-by: Noralf Trønnes --- - arch/arm/mach-bcm2708/dma.c | 8 + - arch/arm/mach-bcm2708/include/mach/dma.h | 2 + drivers/video/fbdev/Kconfig | 14 + drivers/video/fbdev/Makefile | 1 + - drivers/video/fbdev/bcm2708_fb.c | 818 ++++++++++ + drivers/video/fbdev/bcm2708_fb.c | 824 ++++++++++ drivers/video/logo/logo_linux_clut224.ppm | 2483 ++++++++++------------------- - 6 files changed, 1724 insertions(+), 1602 deletions(-) + 4 files changed, 1720 insertions(+), 1602 deletions(-) create mode 100644 drivers/video/fbdev/bcm2708_fb.c -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -index 51d147a..1da2413 100644 ---- a/arch/arm/mach-bcm2708/dma.c -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -83,6 +83,14 @@ extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) - - EXPORT_SYMBOL_GPL(bcm_dma_start); - -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ - /* Complete an ongoing DMA (assuming its results are to be ignored) - Does nothing if there is no DMA in progress. - This routine waits for the current AXI transfer to complete before -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index f2568d4..a4aac4c 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -64,11 +64,13 @@ struct bcm2708_dma_cb { - unsigned long next; - unsigned long pad[2]; - }; -+struct scatterlist; - - extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); - extern void bcm_dma_start(void __iomem *dma_chan_base, - dma_addr_t control_block); - extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); - extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); - - /* When listing features we can ask for when allocating DMA channels give diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig -index b3dd417..b3768b4 100644 +index 1094623..42e6c3b 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -224,6 +224,20 @@ config FB_TILEBLITTING @@ -73480,7 +70440,7 @@ index b3dd417..b3768b4 100644 +config FB_BCM2708 + tristate "BCM2708 framebuffer support" -+ depends on FB && ARM ++ depends on FB && ARM && BCM2708_MBOX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT @@ -73509,10 +70469,10 @@ index 1979aff..57181ad 100644 obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c new file mode 100644 -index 0000000..9179291 +index 0000000..f6ac7da --- /dev/null +++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -0,0 +1,818 @@ +@@ -0,0 +1,824 @@ +/* + * linux/drivers/video/bcm2708_fb.c + * @@ -73539,16 +70499,13 @@ index 0000000..9179291 +#include +#include +#include ++#include ++#include +#include +#include +#include +#include +#include -+ -+#include -+#include -+#include -+ +#include +#include +#include @@ -73840,8 +70797,8 @@ index 0000000..9179291 + /* the console may currently be locked */ + console_trylock(); + console_unlock(); -+ -+ BUG(); /* what can we do here */ ++ pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); ++ return -EIO; + } + } + print_debug @@ -74143,7 +71100,7 @@ index 0000000..9179291 + void *mem; + + mem = -+ dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, ++ dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, + GFP_KERNEL); + + if (NULL == mem) { @@ -74192,7 +71149,9 @@ index 0000000..9179291 + */ + + fb_set_var(&fb->fb, &fb->fb.var); -+ bcm2708_fb_set_par(&fb->fb); ++ ret = bcm2708_fb_set_par(&fb->fb); ++ if (ret) ++ return ret; + + print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", fbwidth, + fbheight, fbdepth, fbswap); @@ -74296,12 +71255,19 @@ index 0000000..9179291 + return 0; +} + ++static const struct of_device_id bcm2708_fb_of_match_table[] = { ++ { .compatible = "brcm,bcm2708-fb", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_fb_of_match_table); ++ +static struct platform_driver bcm2708_fb_driver = { + .probe = bcm2708_fb_probe, + .remove = bcm2708_fb_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_fb_of_match_table, + }, +}; + @@ -76822,10 +73788,10 @@ index 3c14e43..7626beb6a 100644 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 -From 31a44367b5b2a156b2a45d34a1e6b65c55fe8c96 Mon Sep 17 00:00:00 2001 +From 5efe288a95d60bd10a162be79442d04b6f1d4079 Mon Sep 17 00:00:00 2001 From: Florian Meier Date: Fri, 22 Nov 2013 14:22:53 +0100 -Subject: [PATCH 007/216] dmaengine: Add support for BCM2708 +Subject: [PATCH 08/77] dmaengine: Add support for BCM2708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -76874,116 +73840,277 @@ Add Device Tree support to the non ARCH_BCM2835 case. Use the same driver name regardless of architecture. Signed-off-by: Noralf Trønnes + +BCM270x_DT: add bcm2835-dma entry + +Add Device Tree entry for bcm2835-dma. +The entry doesn't contain any resources since they are handled +by the arch/arm/mach-bcm270x/dma.c driver. +In non-DT mode, don't add the device in the board file. + +Signed-off-by: Noralf Trønnes + +bcm2708-dmaengine: Add debug options + +BCM270x: Add memory and irq resources to dmaengine device and DT + +Prepare for merging of the legacy DMA API arch driver dma.c +with bcm2708-dmaengine by adding memory and irq resources both +to platform file device and Device Tree node. +Don't use BCM_DMAMAN_DRIVER_NAME so we don't have to include mach/dma.h + +Signed-off-by: Noralf Trønnes + +dmaengine: bcm2708: Merge with arch dma.c driver and disable dma.c + +Merge the legacy DMA API driver with bcm2708-dmaengine. +This is done so we can use bcm2708_fb on ARCH_BCM2835 (mailbox +driver is also needed). + +Changes to the dma.c code: +- Use BIT() macro. +- Cutdown some comments to one line. +- Add mutex to vc_dmaman and use this, since the dev lock is locked + during probing of the engine part. +- Add global g_dmaman variable since drvdata is used by the engine part. +- Restructure for readability: + vc_dmaman_chan_alloc() + vc_dmaman_chan_free() + bcm_dma_chan_free() +- Restructure bcm_dma_chan_alloc() to simplify error handling. +- Use device irq resources instead of hardcoded bcm_dma_irqs table. +- Remove dev_dmaman_register() and code it directly. +- Remove dev_dmaman_deregister() and code it directly. +- Simplify bcm_dmaman_probe() using devm_* functions. +- Get dmachans from DT if available. +- Keep 'dma.dmachans' module argument name for backwards compatibility. + +Make it available on ARCH_BCM2835 as well. + +Signed-off-by: Noralf Trønnes + +dmaengine: bcm2708: set residue_granularity field + +bcm2708-dmaengine supports residue reporting at burst level +but didn't report this via the residue_granularity field. + +Without this field set properly we get playback issues with I2S cards. --- - arch/arm/mach-bcm2708/bcm2708.c | 6 + - arch/arm/mach-bcm2708/dma.c | 2 + - arch/arm/mach-bcm2708/include/mach/dma.h | 6 +- - arch/arm/mach-bcm2709/bcm2709.c | 6 + - drivers/dma/Kconfig | 6 + - drivers/dma/Makefile | 1 + - drivers/dma/bcm2708-dmaengine.c | 989 +++++++++++++++++++++++++++++++ - 7 files changed, 1015 insertions(+), 1 deletion(-) + arch/arm/mach-bcm2708/bcm2708.c | 68 ++ + arch/arm/mach-bcm2709/bcm2709.c | 68 ++ + drivers/dma/Kconfig | 13 +- + drivers/dma/Makefile | 1 + + drivers/dma/bcm2708-dmaengine.c | 1298 +++++++++++++++++++++++++++++ + include/linux/platform_data/dma-bcm2708.h | 127 +++ + 6 files changed, 1574 insertions(+), 1 deletion(-) create mode 100644 drivers/dma/bcm2708-dmaengine.c + create mode 100644 include/linux/platform_data/dma-bcm2708.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index d9db081..5d8657b 100644 +index 4455f34..6b0b6c4 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -250,6 +250,11 @@ static struct platform_device bcm2708_dmaman_device = { - .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), +@@ -234,6 +234,73 @@ static struct amba_device *amba_devs[] __initdata = { + &uart0_device, }; ++static struct resource bcm2708_dmaengine_resources[] = { ++ { ++ .start = DMA_BASE, ++ .end = DMA_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_DMA0, ++ .end = IRQ_DMA0, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA1, ++ .end = IRQ_DMA1, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA2, ++ .end = IRQ_DMA2, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA3, ++ .end = IRQ_DMA3, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA4, ++ .end = IRQ_DMA4, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA5, ++ .end = IRQ_DMA5, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA6, ++ .end = IRQ_DMA6, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA7, ++ .end = IRQ_DMA7, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA8, ++ .end = IRQ_DMA8, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA9, ++ .end = IRQ_DMA9, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA10, ++ .end = IRQ_DMA10, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA11, ++ .end = IRQ_DMA11, ++ .flags = IORESOURCE_IRQ, ++ }, { ++ .start = IRQ_DMA12, ++ .end = IRQ_DMA12, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ +static struct platform_device bcm2708_dmaengine_device = { + .name = "bcm2708-dmaengine", + .id = -1, ++ .resource = bcm2708_dmaengine_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), +}; + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); static struct platform_device bcm2708_fb_device = { -@@ -508,6 +513,7 @@ void __init bcm2708_init(void) - clkdev_add(&lookups[i]); +@@ -463,6 +530,7 @@ void __init bcm2708_init(void) + bcm2708_init_clocks(); + bcm2708_dt_init(); - bcm_register_device(&bcm2708_dmaman_device); -+ bcm_register_device(&bcm2708_dmaengine_device); ++ bcm_register_device_dt(&bcm2708_dmaengine_device); bcm_register_device(&bcm2708_vcio_device); #ifdef CONFIG_BCM2708_GPIO - bcm_register_device(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -index 1da2413..a5e58d1 100644 ---- a/arch/arm/mach-bcm2708/dma.c -+++ b/arch/arm/mach-bcm2708/dma.c -@@ -156,6 +156,8 @@ static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, - dmaman->chan_available = chans_available; - dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ - dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ - } - - static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index a4aac4c..d03e7b5 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -77,9 +77,13 @@ extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); - those with higher priority smaller ordinal numbers */ - #define BCM_DMA_FEATURE_FAST_ORD 0 - #define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_NORMAL_ORD 2 -+#define BCM_DMA_FEATURE_LITE_ORD 3 - #define BCM_DMA_FEATURE_FAST (1< +#include +#include ++#include +#include +#include +#include +#include -+ -+#ifndef CONFIG_ARCH_BCM2835 -+ -+/* dma manager */ -+#include -+ -+//#define DMA_COMPLETE DMA_SUCCESS -+ -+#endif -+ +#include +#include + +#include "virt-dma.h" + ++static unsigned dma_debug; ++ ++/* ++ * Legacy DMA API ++ */ ++ ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++ ++#define CACHE_LINE_MASK 31 ++#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ ++ ++/* valid only for channels 0 - 14, 15 has its own base address */ ++#define BCM2708_DMA_CHAN(n) ((n) << 8) /* base address */ ++#define BCM2708_DMA_CHANIO(dma_base, n) \ ++ ((void __iomem *)((char *)(dma_base) + BCM2708_DMA_CHAN(n))) ++ ++struct vc_dmaman { ++ void __iomem *dma_base; ++ u32 chan_available; /* bitmap of available channels */ ++ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ ++ struct mutex lock; ++}; ++ ++static struct device *dmaman_dev; /* we assume there's only one! */ ++static struct vc_dmaman *g_dmaman; /* DMA manager */ ++static int dmachans = -1; /* module parameter */ ++ ++/* DMA Auxiliary Functions */ ++ ++/* A DMA buffer on an arbitrary boundary may separate a cache line into a ++ section inside the DMA buffer and another section outside it. ++ Even if we flush DMA buffers from the cache there is always the chance that ++ during a DMA someone will access the part of a cache line that is outside ++ the DMA buffer - which will then bring in unwelcome data. ++ Without being able to dictate our own buffer pools we must insist that ++ DMA buffers consist of a whole number of cache lines. ++*/ ++extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) ++{ ++ int i; ++ ++ for (i = 0; i < sg_len; i++) { ++ if (sg_ptr[i].offset & CACHE_LINE_MASK || ++ sg_ptr[i].length & CACHE_LINE_MASK) ++ return 0; ++ } ++ ++ return 1; ++} ++EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); ++ ++extern void bcm_dma_start(void __iomem *dma_chan_base, ++ dma_addr_t control_block) ++{ ++ dsb(); /* ARM data synchronization (push) operation */ ++ ++ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); ++ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); ++} ++EXPORT_SYMBOL_GPL(bcm_dma_start); ++ ++extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ /* ugly busy wait only option for now */ ++ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) ++ cpu_relax(); ++} ++EXPORT_SYMBOL_GPL(bcm_dma_wait_idle); ++ ++extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) ++{ ++ dsb(); ++ ++ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_is_busy); ++ ++/* Complete an ongoing DMA (assuming its results are to be ignored) ++ Does nothing if there is no DMA in progress. ++ This routine waits for the current AXI transfer to complete before ++ terminating the current DMA. If the current transfer is hung on a DREQ used ++ by an uncooperative peripheral the AXI transfer may never complete. In this ++ case the routine times out and return a non-zero error code. ++ Use of this routine doesn't guarantee that the ongoing or aborted DMA ++ does not produce an interrupt. ++*/ ++extern int bcm_dma_abort(void __iomem *dma_chan_base) ++{ ++ unsigned long int cs; ++ int rc = 0; ++ ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (BCM2708_DMA_ACTIVE & cs) { ++ long int timeout = 10000; ++ ++ /* write 0 to the active bit - pause the DMA */ ++ writel(0, dma_chan_base + BCM2708_DMA_CS); ++ ++ /* wait for any current AXI transfer to complete */ ++ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) ++ cs = readl(dma_chan_base + BCM2708_DMA_CS); ++ ++ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { ++ /* we'll un-pause when we set of our next DMA */ ++ rc = -ETIMEDOUT; ++ ++ } else if (BCM2708_DMA_ACTIVE & cs) { ++ /* terminate the control block chain */ ++ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); ++ ++ /* abort the whole DMA */ ++ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, ++ dma_chan_base + BCM2708_DMA_CS); ++ } ++ } ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_abort); ++ ++ /* DMA Manager Device Methods */ ++ ++static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, ++ u32 chans_available) ++{ ++ dmaman->dma_base = dma_base; ++ dmaman->chan_available = chans_available; ++ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* 2 & 3 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* 0 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* 1 to 7 */ ++ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* 8 to 14 */ ++} ++ ++static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, ++ unsigned preferred_feature_set) ++{ ++ u32 chans; ++ int chan = 0; ++ int feature; ++ ++ chans = dmaman->chan_available; ++ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) ++ /* select the subset of available channels with the desired ++ feature so long as some of the candidate channels have that ++ feature */ ++ if ((preferred_feature_set & (1 << feature)) && ++ (chans & dmaman->has_feature[feature])) ++ chans &= dmaman->has_feature[feature]; ++ ++ if (!chans) ++ return -ENOENT; ++ ++ /* return the ordinal of the first channel in the bitmap */ ++ while (chans != 0 && (chans & 1) == 0) { ++ chans >>= 1; ++ chan++; ++ } ++ /* claim the channel */ ++ dmaman->chan_available &= ~(1 << chan); ++ ++ return chan; ++} ++ ++static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) ++{ ++ if (chan < 0) ++ return -EINVAL; ++ ++ if ((1 << chan) & dmaman->chan_available) ++ return -EIDRM; ++ ++ dmaman->chan_available |= (1 << chan); ++ ++ return 0; ++} ++ ++/* DMA Manager Monitor */ ++ ++extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, int *out_dma_irq) ++{ ++ struct vc_dmaman *dmaman = g_dmaman; ++ struct platform_device *pdev = to_platform_device(dmaman_dev); ++ struct resource *r; ++ int chan; ++ ++ if (!dmaman_dev) ++ return -ENODEV; ++ ++ mutex_lock(&dmaman->lock); ++ chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); ++ if (chan < 0) ++ goto out; ++ ++ r = platform_get_resource(pdev, IORESOURCE_IRQ, (unsigned int)chan); ++ if (!r) { ++ dev_err(dmaman_dev, "failed to get irq for DMA channel %d\n", ++ chan); ++ vc_dmaman_chan_free(dmaman, chan); ++ chan = -ENOENT; ++ goto out; ++ } ++ ++ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, chan); ++ *out_dma_irq = r->start; ++ dev_dbg(dmaman_dev, ++ "Legacy API allocated channel=%d, base=%p, irq=%i\n", ++ chan, *out_dma_base, *out_dma_irq); ++ ++out: ++ mutex_unlock(&dmaman->lock); ++ ++ return chan; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); ++ ++extern int bcm_dma_chan_free(int channel) ++{ ++ struct vc_dmaman *dmaman = g_dmaman; ++ int rc; ++ ++ if (!dmaman_dev) ++ return -ENODEV; ++ ++ mutex_lock(&dmaman->lock); ++ rc = vc_dmaman_chan_free(dmaman, channel); ++ mutex_unlock(&dmaman->lock); ++ ++ return rc; ++} ++EXPORT_SYMBOL_GPL(bcm_dma_chan_free); ++ ++static int bcm_dmaman_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct vc_dmaman *dmaman; ++ struct resource *r; ++ void __iomem *dma_base; ++ uint32_t val; ++ ++ if (!of_property_read_u32(dev->of_node, ++ "brcm,dma-channel-mask", &val)) ++ dmachans = val; ++ else if (dmachans == -1) ++ dmachans = DEFAULT_DMACHAN_BITMAP; ++ ++ dmaman = devm_kzalloc(dev, sizeof(*dmaman), GFP_KERNEL); ++ if (!dmaman) ++ return -ENOMEM; ++ ++ mutex_init(&dmaman->lock); ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ dma_base = devm_ioremap_resource(dev, r); ++ if (IS_ERR(dma_base)) ++ return PTR_ERR(dma_base); ++ ++ vc_dmaman_init(dmaman, dma_base, dmachans); ++ g_dmaman = dmaman; ++ dmaman_dev = dev; ++ ++ dev_info(dev, "DMA legacy API manager at %p, dmachans=0x%x\n", ++ dma_base, dmachans); ++ ++ return 0; ++} ++ ++static int bcm_dmaman_remove(struct platform_device *pdev) ++{ ++ dmaman_dev = NULL; ++ ++ return 0; ++} ++ ++#else /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++static int bcm_dmaman_remove(struct platform_device *pdev) ++{ ++ return 0; ++} ++ ++#endif /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++/* ++ * DMA engine ++ */ + +struct bcm2835_dmadev { + struct dma_device ddev; @@ -77602,7 +75008,10 @@ index 0000000..6150b8f + } + + /* Common part */ -+ control_block->info |= BCM2835_DMA_WAITS(SDHCI_BCM_DMA_WAITS); ++ u32 waits = SDHCI_BCM_DMA_WAITS; ++ if ((dma_debug >> 0) & 0x1f) ++ waits = (dma_debug >> 0) & 0x1f; ++ control_block->info |= BCM2835_DMA_WAITS(waits); + control_block->info |= BCM2835_DMA_WAIT_RESP; + + /* Enable */ @@ -77707,7 +75116,7 @@ index 0000000..6150b8f + return 0; +} + -+#ifdef CONFIG_ARCH_BCM2835 ++#ifndef CONFIG_DMA_BCM2708_LEGACY +static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) +{ + struct bcm2835_chan *c; @@ -77785,7 +75194,7 @@ index 0000000..6150b8f +static int bcm2835_dma_probe(struct platform_device *pdev) +{ + struct bcm2835_dmadev *od; -+#ifdef CONFIG_ARCH_BCM2835 ++#ifndef CONFIG_DMA_BCM2708_LEGACY + struct resource *res; + void __iomem *base; + uint32_t chans_available; @@ -77798,10 +75207,7 @@ index 0000000..6150b8f + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + -+ /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */ -+ /* hence the difference between probing */ -+ -+#ifndef CONFIG_ARCH_BCM2835 ++#ifdef CONFIG_DMA_BCM2708_LEGACY + + rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (rc) @@ -77813,6 +75219,10 @@ index 0000000..6150b8f + if (!od) + return -ENOMEM; + ++ rc = bcm_dmaman_probe(pdev); ++ if (rc) ++ return rc; ++ + pdev->dev.dma_parms = &od->dma_parms; + dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); + @@ -77831,6 +75241,7 @@ index 0000000..6150b8f + od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); ++ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + od->ddev.dev = &pdev->dev; + INIT_LIST_HEAD(&od->ddev.channels); + spin_lock_init(&od->lock); @@ -77899,6 +75310,7 @@ index 0000000..6150b8f + od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); ++ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + od->ddev.dev = &pdev->dev; + INIT_LIST_HEAD(&od->ddev.channels); + spin_lock_init(&od->lock); @@ -77954,6 +75366,7 @@ index 0000000..6150b8f + } + + dev_info(&pdev->dev, "Load BCM2835 DMA engine driver\n"); ++ dev_info(&pdev->dev, "dma_debug:%x\n", dma_debug); + + return 0; + @@ -77968,6 +75381,7 @@ index 0000000..6150b8f + + dma_async_device_unregister(&od->ddev); + bcm2835_dma_free(od); ++ bcm_dmaman_remove(pdev); + + return 0; +} @@ -77982,18 +75396,173 @@ index 0000000..6150b8f + }, +}; + -+module_platform_driver(bcm2835_dma_driver); ++static int bcm2835_init(void) ++{ ++ return platform_driver_register(&bcm2835_dma_driver); ++} + ++static void bcm2835_exit(void) ++{ ++ platform_driver_unregister(&bcm2835_dma_driver); ++} ++ ++/* ++ * Load after serial driver (arch_initcall) so we see the messages if it fails, ++ * but before drivers (module_init) that need a DMA channel. ++ */ ++subsys_initcall(bcm2835_init); ++module_exit(bcm2835_exit); ++ ++module_param(dma_debug, uint, 0644); ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++/* Keep backward compatibility: dma.dmachans= */ ++#undef MODULE_PARAM_PREFIX ++#define MODULE_PARAM_PREFIX "dma." ++module_param(dmachans, int, 0644); ++#endif +MODULE_ALIAS("platform:bcm2835-dma"); +MODULE_DESCRIPTION("BCM2835 DMA engine driver"); +MODULE_AUTHOR("Florian Meier "); +MODULE_AUTHOR("Gellert Weisz "); +MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/platform_data/dma-bcm2708.h b/include/linux/platform_data/dma-bcm2708.h +new file mode 100644 +index 0000000..2310e34 +--- /dev/null ++++ b/include/linux/platform_data/dma-bcm2708.h +@@ -0,0 +1,127 @@ ++/* ++ * Copyright (C) 2010 Broadcom ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef _PLAT_BCM2708_DMA_H ++#define _PLAT_BCM2708_DMA_H ++ ++/* DMA CS Control and Status bits */ ++#define BCM2708_DMA_ACTIVE BIT(0) ++#define BCM2708_DMA_INT BIT(2) ++#define BCM2708_DMA_ISPAUSED BIT(4) /* Pause requested or not active */ ++#define BCM2708_DMA_ISHELD BIT(5) /* Is held by DREQ flow control */ ++#define BCM2708_DMA_ERR BIT(8) ++#define BCM2708_DMA_ABORT BIT(30) /* stop current CB, go to next, WO */ ++#define BCM2708_DMA_RESET BIT(31) /* WO, self clearing */ ++ ++/* DMA control block "info" field bits */ ++#define BCM2708_DMA_INT_EN BIT(0) ++#define BCM2708_DMA_TDMODE BIT(1) ++#define BCM2708_DMA_WAIT_RESP BIT(3) ++#define BCM2708_DMA_D_INC BIT(4) ++#define BCM2708_DMA_D_WIDTH BIT(5) ++#define BCM2708_DMA_D_DREQ BIT(6) ++#define BCM2708_DMA_S_INC BIT(8) ++#define BCM2708_DMA_S_WIDTH BIT(9) ++#define BCM2708_DMA_S_DREQ BIT(10) ++ ++#define BCM2708_DMA_BURST(x) (((x) & 0xf) << 12) ++#define BCM2708_DMA_PER_MAP(x) ((x) << 16) ++#define BCM2708_DMA_WAITS(x) (((x) & 0x1f) << 21) ++ ++#define BCM2708_DMA_DREQ_EMMC 11 ++#define BCM2708_DMA_DREQ_SDHOST 13 ++ ++#define BCM2708_DMA_CS 0x00 /* Control and Status */ ++#define BCM2708_DMA_ADDR 0x04 ++/* the current control block appears in the following registers - read only */ ++#define BCM2708_DMA_INFO 0x08 ++#define BCM2708_DMA_SOURCE_AD 0x0c ++#define BCM2708_DMA_DEST_AD 0x10 ++#define BCM2708_DMA_NEXTCB 0x1C ++#define BCM2708_DMA_DEBUG 0x20 ++ ++#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4) + BCM2708_DMA_CS) ++#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4) + BCM2708_DMA_ADDR) ++ ++#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) ++ ++/* When listing features we can ask for when allocating DMA channels give ++ those with higher priority smaller ordinal numbers */ ++#define BCM_DMA_FEATURE_FAST_ORD 0 ++#define BCM_DMA_FEATURE_BULK_ORD 1 ++#define BCM_DMA_FEATURE_NORMAL_ORD 2 ++#define BCM_DMA_FEATURE_LITE_ORD 3 ++#define BCM_DMA_FEATURE_FAST BIT(BCM_DMA_FEATURE_FAST_ORD) ++#define BCM_DMA_FEATURE_BULK BIT(BCM_DMA_FEATURE_BULK_ORD) ++#define BCM_DMA_FEATURE_NORMAL BIT(BCM_DMA_FEATURE_NORMAL_ORD) ++#define BCM_DMA_FEATURE_LITE BIT(BCM_DMA_FEATURE_LITE_ORD) ++#define BCM_DMA_FEATURE_COUNT 4 ++ ++struct bcm2708_dma_cb { ++ unsigned long info; ++ unsigned long src; ++ unsigned long dst; ++ unsigned long length; ++ unsigned long stride; ++ unsigned long next; ++ unsigned long pad[2]; ++}; ++ ++struct scatterlist; ++ ++#ifdef CONFIG_DMA_BCM2708_LEGACY ++ ++int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); ++void bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block); ++void bcm_dma_wait_idle(void __iomem *dma_chan_base); ++bool bcm_dma_is_busy(void __iomem *dma_chan_base); ++int bcm_dma_abort(void __iomem *dma_chan_base); ++ ++/* return channel no or -ve error */ ++int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, int *out_dma_irq); ++int bcm_dma_chan_free(int channel); ++ ++#else /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++static inline int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, ++ int sg_len) ++{ ++ return 0; ++} ++ ++static inline void bcm_dma_start(void __iomem *dma_chan_base, ++ dma_addr_t control_block) { } ++ ++static inline void bcm_dma_wait_idle(void __iomem *dma_chan_base) { } ++ ++static inline bool bcm_dma_is_busy(void __iomem *dma_chan_base) ++{ ++ return false; ++} ++ ++static inline int bcm_dma_abort(void __iomem *dma_chan_base) ++{ ++ return -EINVAL; ++} ++ ++static inline int bcm_dma_chan_alloc(unsigned preferred_feature_set, ++ void __iomem **out_dma_base, ++ int *out_dma_irq) ++{ ++ return -EINVAL; ++} ++ ++static inline int bcm_dma_chan_free(int channel) ++{ ++ return -EINVAL; ++} ++ ++#endif /* CONFIG_DMA_BCM2708_LEGACY */ ++ ++#endif /* _PLAT_BCM2708_DMA_H */ -From 7ec18e818133424bf20d58993fa6822dd241e096 Mon Sep 17 00:00:00 2001 +From be30ad8849aa9fd6ffbe6f8198a5af4bb62c465f Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 15 Aug 2014 16:35:06 +0100 -Subject: [PATCH 008/216] MMC: added alternative MMC driver +Subject: [PATCH 09/77] MMC: added alternative MMC driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -78019,23 +75588,61 @@ Probe error handling is broken in several places. Simplify error handling by using device managed functions. Replace pr_{err,info} with dev_{err,info}. +Signed-off-by: Noralf Trønnes + +bcm2835-mmc: Add locks when accessing sdhost registers + +bcm2835-mmc: Add range of debug options for slowing things down + +bcm2835-mmc: Add option to disable some delays + +bcm2835-mmc: Add option to disable MMC_QUIRK_BLK_NO_CMD23 + +bcm2835-mmc: Default to disabling MMC_QUIRK_BLK_NO_CMD23 + +bcm2835-mmc: Adding overclocking option + +Allow a different clock speed to be substitued for a requested 50MHz. +This option is exposed using the "overclock_50" DT parameter. +Note that the mmc interface is restricted to EVEN integer divisions of +250MHz, and the highest sensible option is 63 (250/4 = 62.5), the +next being 125 (250/2) which is much too high. + +Use at your own risk. + +bcm2835-mmc: Round up the overclock, so 62 works for 62.5Mhz + +Also only warn once for each overclock setting. + +mmc: bcm2835-mmc: Make available on ARCH_BCM2835 + +Make the bcm2835-mmc driver available for use on ARCH_BCM2835. + +Signed-off-by: Noralf Trønnes + +BCM270x_DT: add bcm2835-mmc entry + +Add Device Tree entry for bcm2835-mmc. +In non-DT mode, don't add the device in the board file. + Signed-off-by: Noralf Trønnes --- arch/arm/mach-bcm2708/bcm2708.c | 31 + - drivers/mmc/core/quirks.c | 4 + + arch/arm/mach-bcm2709/bcm2709.c | 35 +- + drivers/mmc/core/quirks.c | 6 + drivers/mmc/host/Kconfig | 29 + drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-mmc.c | 1506 +++++++++++++++++++++++++++++++++++++++ - 5 files changed, 1571 insertions(+) + drivers/mmc/host/bcm2835-mmc.c | 1558 +++++++++++++++++++++++++++++++++++++++ + 6 files changed, 1658 insertions(+), 2 deletions(-) create mode 100644 drivers/mmc/host/bcm2835-mmc.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5d8657b..d1308ed 100644 +index 6b0b6c4..5b10802 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -399,6 +399,34 @@ static struct platform_device bcm2708_systemtimer_device = { - }, +@@ -401,6 +401,34 @@ static struct platform_device bcm2708_gpio_device = { }; + #endif +#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ +static struct resource bcm2835_emmc_resources[] = { @@ -78065,35 +75672,97 @@ index 5d8657b..d1308ed 100644 +}; +#endif /* CONFIG_MMC_BCM2835 */ + - static struct resource bcm2708_powerman_resources[] = { - [0] = { - .start = PM_BASE, -@@ -524,6 +552,9 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -538,6 +566,9 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); +#ifdef CONFIG_MMC_BCM2835 -+ bcm_register_device(&bcm2835_emmc_device); ++ bcm_register_device_dt(&bcm2835_emmc_device); +#endif bcm2708_init_led(); + bcm2708_init_uart1(); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 86ebfbe..54c5444 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -421,6 +421,34 @@ static struct platform_device bcm2708_gpio_device = { + }; + #endif + ++#ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ ++static struct resource bcm2835_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, ++ }, ++ [1] = { ++ .start = IRQ_ARASANSDIO, ++ .end = IRQ_ARASANSDIO, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 bcm2835_emmc_dmamask = 0xffffffffUL; ++ ++struct platform_device bcm2835_emmc_device = { ++ .name = "mmc-bcm2835", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2835_emmc_resources), ++ .resource = bcm2835_emmc_resources, ++ .dev = { ++ .dma_mask = &bcm2835_emmc_dmamask, ++ .coherent_dma_mask = 0xffffffffUL}, ++}; ++#endif /* CONFIG_MMC_BCM2835 */ ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -558,8 +586,11 @@ void __init bcm2709_init(void) + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); + +- bcm2708_init_led(); +- bcm2708_init_uart1(); ++#ifdef CONFIG_MMC_BCM2835 ++ bcm_register_device_dt(&bcm2835_emmc_device); ++#endif ++ bcm2709_init_led(); ++ bcm2709_init_uart1(); + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index dd1d1e0..f472082 100644 +index dd1d1e0..bc3bbad 100644 --- a/drivers/mmc/core/quirks.c +++ b/drivers/mmc/core/quirks.c -@@ -95,5 +95,9 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) +@@ -71,6 +71,7 @@ static const struct mmc_fixup mmc_fixup_methods[] = { + + void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) + { ++ extern unsigned mmc_debug; + const struct mmc_fixup *f; + u64 rev = cid_rev_card(card); + +@@ -95,5 +96,10 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) f->vendor_fixup(card, f->data); } } + /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. + * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). + */ ++ if (mmc_debug & (1<<13)) + card->quirks |= MMC_QUIRK_BLK_NO_CMD23; } EXPORT_SYMBOL(mmc_fixup_device); diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 61ac63a..7c093a6 100644 +index b1f837e..0ef7417 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -4,6 +4,35 @@ @@ -78102,7 +75771,7 @@ index 61ac63a..7c093a6 100644 +config MMC_BCM2835 + tristate "MMC support on BCM2835" -+ depends on (MACH_BCM2708 || MACH_BCM2709) ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 + help + This selects the MMC Interface on BCM2835. + @@ -78133,7 +75802,7 @@ index 61ac63a..7c093a6 100644 tristate "ARM AMBA Multimedia Card Interface support" depends on ARM_AMBA diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 6a7cfe0..9d41de9 100644 +index e3ab5b9..f1ee1f7 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o @@ -78146,10 +75815,10 @@ index 6a7cfe0..9d41de9 100644 obj-$(CONFIG_MMC_OMAP) += omap.o diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c new file mode 100644 -index 0000000..eef0d351 +index 0000000..b7c4883 --- /dev/null +++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -0,0 +1,1506 @@ +@@ -0,0 +1,1558 @@ +/* + * BCM2835 MMC host driver. + * @@ -78223,6 +75892,9 @@ index 0000000..eef0d351 +#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) + + ++unsigned mmc_debug; ++unsigned mmc_debug2; ++ +struct bcm2835_host { + spinlock_t lock; + @@ -78280,22 +75952,38 @@ index 0000000..eef0d351 +#define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ +#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ +#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ ++ ++ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ ++ u32 max_overclock; /* Highest reported */ +}; + + -+static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) ++static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg, int from) +{ ++ unsigned delay; ++ lockdep_assert_held_once(&host->lock); + writel(val, host->ioaddr + reg); + udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); ++ ++ delay = ((mmc_debug >> 16) & 0xf) << ((mmc_debug >> 20) & 0xf); ++ if (delay && !((1<lock); + writel(val, host->ioaddr + reg); ++ ++ delay = ((mmc_debug >> 24) & 0xf) << ((mmc_debug >> 28) & 0xf); ++ if (delay) ++ udelay(delay); +} + +static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) +{ ++ lockdep_assert_held_once(&host->lock); + return readl(host->ioaddr + reg); +} + @@ -78311,7 +75999,7 @@ index 0000000..eef0d351 + if (reg == SDHCI_TRANSFER_MODE) + host->shadow = newval; + else -+ bcm2835_mmc_writel(host, newval, reg & ~3); ++ bcm2835_mmc_writel(host, newval, reg & ~3, 0); + +} + @@ -78323,7 +76011,7 @@ index 0000000..eef0d351 + u32 mask = 0xff << byte_shift; + u32 newval = (oldval & ~mask) | (val << byte_shift); + -+ bcm2835_mmc_writel(host, newval, reg & ~3); ++ bcm2835_mmc_writel(host, newval, reg & ~3, 1); +} + + @@ -78355,7 +76043,7 @@ index 0000000..eef0d351 + ier &= ~clear; + /* change which requests generate IRQs - makes no difference to + the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ -+ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE, 2); +} + + @@ -78407,7 +76095,9 @@ index 0000000..eef0d351 +static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) +{ + unsigned long timeout; ++ unsigned long flags; + ++ spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); + + if (mask & SDHCI_RESET_ALL) @@ -78425,19 +76115,23 @@ index 0000000..eef0d351 + return; + } + timeout--; ++ spin_unlock_irqrestore(&host->lock, flags); + mdelay(1); ++ spin_lock_irqsave(&host->lock, flags); + } + + if (100-timeout > 10 && 100-timeout > host->max_delay) { + host->max_delay = 100-timeout; + pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); + } ++ spin_unlock_irqrestore(&host->lock, flags); +} + +static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); + +static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) +{ ++ unsigned long flags; + if (soft) + bcm2835_mmc_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); + else @@ -78449,8 +76143,10 @@ index 0000000..eef0d351 + SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | + SDHCI_INT_RESPONSE; + -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ spin_lock_irqsave(&host->lock, flags); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 3); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 3); ++ spin_unlock_irqrestore(&host->lock, flags); + + if (soft) { + /* force clock reconfiguration */ @@ -78649,11 +76345,14 @@ index 0000000..eef0d351 + dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); + } + if (desc) { ++ unsigned long flags; ++ spin_lock_irqsave(&host->lock, flags); + bcm2835_mmc_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | + SDHCI_INT_SPACE_AVAIL); + host->tx_desc = desc; + desc->callback = bcm2835_mmc_dma_complete; + desc->callback_param = host; ++ spin_unlock_irqrestore(&host->lock, flags); + dmaengine_submit(desc); + dma_async_issue_pending(dma_chan); + } @@ -78672,8 +76371,8 @@ index 0000000..eef0d351 + else + host->ier = (host->ier & ~dma_irqs) | pio_irqs; + -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 4); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 4); +} + + @@ -78755,7 +76454,7 @@ index 0000000..eef0d351 + mode |= SDHCI_TRNS_AUTO_CMD12; + else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { + mode |= SDHCI_TRNS_AUTO_CMD23; -+ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); ++ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2, 5); + } + } + @@ -78818,7 +76517,7 @@ index 0000000..eef0d351 + + bcm2835_mmc_prepare_data(host, cmd); + -+ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT); ++ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT, 6); + + bcm2835_mmc_set_transfer_mode(host, cmd); + @@ -78975,8 +76674,8 @@ index 0000000..eef0d351 + else + host->ier &= ~SDHCI_INT_CARD_INT; + -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 7); ++ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 7); + mmiowb(); + } +} @@ -79123,7 +76822,7 @@ index 0000000..eef0d351 + /* Clear selected interrupts. */ + mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | + SDHCI_INT_BUS_POWER); -+ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS); ++ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS, 8); + + + if (intmask & SDHCI_INT_CMD_MASK) @@ -79153,7 +76852,7 @@ index 0000000..eef0d351 + + if (intmask) { + unexpected |= intmask; -+ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS); ++ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS, 9); + } + + if (result == IRQ_NONE) @@ -79211,7 +76910,10 @@ index 0000000..eef0d351 + int real_div = div, clk_mul = 1; + u16 clk = 0; + unsigned long timeout; ++ unsigned int input_clock = clock; + ++ if (host->overclock_50 && (clock == 50000000)) ++ clock = host->overclock_50 * 1000000 + 999999; + + host->mmc->actual_clock = 0; + @@ -79235,7 +76937,14 @@ index 0000000..eef0d351 + div >>= 1; + + if (real_div) -+ host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; ++ clock = (host->max_clk * clk_mul) / real_div; ++ host->mmc->actual_clock = clock; ++ ++ if ((clock > input_clock) && (clock > host->max_overclock)) { ++ pr_warn("%s: Overclocking to %dHz\n", ++ mmc_hostname(host->mmc), clock); ++ host->max_overclock = clock; ++ } + + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; + clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) @@ -79302,6 +77011,9 @@ index 0000000..eef0d351 + u8 ctrl; + u16 clk, ctrl_2; + ++ pr_debug("bcm2835_mmc_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", ++ ios->clock, ios->power_mode, ios->bus_width, ++ ios->timing, ios->signal_voltage, ios->drv_type); + + spin_lock_irqsave(&host->lock, flags); + @@ -79395,8 +77107,10 @@ index 0000000..eef0d351 + (mrq->data && (mrq->data->error || + (mrq->data->stop && mrq->data->stop->error))))) { + ++ spin_unlock_irqrestore(&host->lock, flags); + bcm2835_mmc_reset(host, SDHCI_RESET_CMD); + bcm2835_mmc_reset(host, SDHCI_RESET_DATA); ++ spin_lock_irqsave(&host->lock, flags); + } + + host->mrq = NULL; @@ -79411,7 +77125,7 @@ index 0000000..eef0d351 + + + -+int bcm2835_mmc_add_host(struct bcm2835_host *host) ++static int bcm2835_mmc_add_host(struct bcm2835_host *host) +{ + struct mmc_host *mmc = host->mmc; + struct device *dev = mmc->parent; @@ -79439,8 +77153,7 @@ index 0000000..eef0d351 + + host->flags = SDHCI_AUTO_CMD23; + -+ spin_lock_init(&host->lock); -+ ++ dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); +#ifdef FORCE_PIO + dev_info(dev, "Forcing PIO mode\n"); + host->have_dma = false; @@ -79568,10 +77281,16 @@ index 0000000..eef0d351 + goto err; + } + -+ if (node) ++ if (node) { + mmc_of_parse(mmc); -+ else ++ ++ /* Read any custom properties */ ++ of_property_read_u32(node, ++ "brcm,overclock-50", ++ &host->overclock_50); ++ } else { + mmc->caps |= MMC_CAP_4_BIT_DATA; ++ } + + ret = bcm2835_mmc_add_host(host); + if (ret) @@ -79652,15 +77371,1790 @@ index 0000000..eef0d351 +}; +module_platform_driver(bcm2835_mmc_driver); + ++module_param(mmc_debug, uint, 0644); ++module_param(mmc_debug2, uint, 0644); +MODULE_ALIAS("platform:mmc-bcm2835"); +MODULE_DESCRIPTION("BCM2835 SDHCI driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gellert Weisz"); -From 97f9d94720b108ba3e793621d4a500cc593fc775 Mon Sep 17 00:00:00 2001 +From 81cff325dce6ba8765e23e542a219d3c9103a70b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 25 Mar 2015 17:49:47 +0000 +Subject: [PATCH 10/77] Adding bcm2835-sdhost driver, and an overlay to enable + it + +BCM2835 has two SD card interfaces. This driver uses the other one. + +bcm2835-sdhost: Error handling fix, and code clarification + +bcm2835-sdhost: Adding overclocking option + +Allow a different clock speed to be substitued for a requested 50MHz. +This option is exposed using the "overclock_50" DT parameter. +Note that the sdhost interface is restricted to integer divisions of +core_freq, and the highest sensible option for a core_freq of 250MHz +is 84 (250/3 = 83.3MHz), the next being 125 (250/2) which is much too +high. + +Use at your own risk. + +bcm2835-sdhost: Round up the overclock, so 62 works for 62.5Mhz + +Also only warn once for each overclock setting. +--- + drivers/mmc/host/Kconfig | 10 + + drivers/mmc/host/Makefile | 1 + + drivers/mmc/host/bcm2835-sdhost.c | 1702 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 1713 insertions(+) + create mode 100644 drivers/mmc/host/bcm2835-sdhost.c + +diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +index 0ef7417..1af139a 100644 +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER + + If unsure, say 2 here. + ++config MMC_BCM2835_SDHOST ++ tristate "Support for the SDHost controller on BCM2708/9" ++ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 ++ help ++ This selects the SDHost controller on BCM2835/6. ++ ++ If you have a controller with this interface, say Y or M here. ++ ++ If unsure, say N. ++ + config MMC_ARMMMCI + tristate "ARM AMBA Multimedia Card Interface support" + depends on ARM_AMBA +diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile +index f1ee1f7..8c656a5 100644 +--- a/drivers/mmc/host/Makefile ++++ b/drivers/mmc/host/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o + obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o + obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o + obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o ++obj-$(CONFIG_MMC_BCM2835_SDHOST) += bcm2835-sdhost.o + obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o + obj-$(CONFIG_MMC_WBSD) += wbsd.o + obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c +new file mode 100644 +index 0000000..eef8a24 +--- /dev/null ++++ b/drivers/mmc/host/bcm2835-sdhost.c +@@ -0,0 +1,1702 @@ ++/* ++ * BCM2835 SD host driver. ++ * ++ * Author: Phil Elwell ++ * Copyright 2015 ++ * ++ * Based on ++ * mmc-bcm2835.c by Gellert Weisz ++ * which is, in turn, based on ++ * sdhci-bcm2708.c by Broadcom ++ * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko ++ * sdhci.c and sdhci-pci.c by Pierre Ossman ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#define SAFE_READ_THRESHOLD 4 ++#define SAFE_WRITE_THRESHOLD 4 ++#define ALLOW_DMA 1 ++#define ALLOW_CMD23 0 ++#define ALLOW_FAST 1 ++#define USE_BLOCK_IRQ 1 ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRIVER_NAME "sdhost-bcm2835" ++ ++#define SDCMD 0x00 /* Command to SD card - 16 R/W */ ++#define SDARG 0x04 /* Argument to SD card - 32 R/W */ ++#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */ ++#define SDCDIV 0x0c /* Start value for clock divider - 11 R/W */ ++#define SDRSP0 0x10 /* SD card response (31:0) - 32 R */ ++#define SDRSP1 0x14 /* SD card response (63:32) - 32 R */ ++#define SDRSP2 0x18 /* SD card response (95:64) - 32 R */ ++#define SDRSP3 0x1c /* SD card response (127:96) - 32 R */ ++#define SDHSTS 0x20 /* SD host status - 11 R */ ++#define SDVDD 0x30 /* SD card power control - 1 R/W */ ++#define SDEDM 0x34 /* Emergency Debug Mode - 13 R/W */ ++#define SDHCFG 0x38 /* Host configuration - 2 R/W */ ++#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */ ++#define SDDATA 0x40 /* Data to/from SD card - 32 R/W */ ++#define SDHBLC 0x50 /* Host block count (SDIO/SDHC) - 9 R/W */ ++ ++#define SDCMD_NEW_FLAG 0x8000 ++#define SDCMD_FAIL_FLAG 0x4000 ++#define SDCMD_BUSYWAIT 0x800 ++#define SDCMD_NO_RESPONSE 0x400 ++#define SDCMD_LONG_RESPONSE 0x200 ++#define SDCMD_WRITE_CMD 0x80 ++#define SDCMD_READ_CMD 0x40 ++#define SDCMD_CMD_MASK 0x3f ++ ++#define SDCDIV_MAX_CDIV 0x7ff ++ ++#define SDHSTS_BUSY_IRPT 0x400 ++#define SDHSTS_BLOCK_IRPT 0x200 ++#define SDHSTS_SDIO_IRPT 0x100 ++#define SDHSTS_REW_TIME_OUT 0x80 ++#define SDHSTS_CMD_TIME_OUT 0x40 ++#define SDHSTS_CRC16_ERROR 0x20 ++#define SDHSTS_CRC7_ERROR 0x10 ++#define SDHSTS_FIFO_ERROR 0x08 ++/* Reserved */ ++/* Reserved */ ++#define SDHSTS_DATA_FLAG 0x01 ++ ++#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) ++#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) ++/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ ++ ++#define SDHCFG_BUSY_IRPT_EN (1<<10) ++#define SDHCFG_BLOCK_IRPT_EN (1<<8) ++#define SDHCFG_SDIO_IRPT_EN (1<<5) ++#define SDHCFG_DATA_IRPT_EN (1<<4) ++#define SDHCFG_SLOW_CARD (1<<3) ++#define SDHCFG_WIDE_EXT_BUS (1<<2) ++#define SDHCFG_WIDE_INT_BUS (1<<1) ++#define SDHCFG_REL_CMD_LINE (1<<0) ++ ++#define SDEDM_FORCE_DATA_MODE (1<<19) ++#define SDEDM_CLOCK_PULSE (1<<20) ++#define SDEDM_BYPASS (1<<21) ++ ++#define SDEDM_WRITE_THRESHOLD_SHIFT 9 ++#define SDEDM_READ_THRESHOLD_SHIFT 14 ++#define SDEDM_THRESHOLD_MASK 0x1f ++ ++/* the inclusive limit in bytes under which PIO will be used instead of DMA */ ++#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER ++#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER ++#else ++#define PIO_DMA_BARRIER 0 ++#endif ++ ++#define MIN_FREQ 400000 ++#define TIMEOUT_VAL 0xE ++#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) ++ ++#ifndef BCM2708_PERI_BASE ++ #define BCM2708_PERI_BASE 0x20000000 ++#endif ++ ++/* FIXME: Needs IOMMU support */ ++#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) ++ ++ ++struct bcm2835_host { ++ spinlock_t lock; ++ ++ void __iomem *ioaddr; ++ u32 phys_addr; ++ ++ struct mmc_host *mmc; ++ ++ u32 timeout; ++ ++ int clock; /* Current clock speed */ ++ ++ bool slow_card; /* Force 11-bit divisor */ ++ ++ unsigned int max_clk; /* Max possible freq */ ++ unsigned int timeout_clk; /* Timeout freq (KHz) */ ++ ++ struct tasklet_struct finish_tasklet; /* Tasklet structures */ ++ ++ struct timer_list timer; /* Timer for timeouts */ ++ ++ struct sg_mapping_iter sg_miter; /* SG state for PIO */ ++ unsigned int blocks; /* remaining PIO blocks */ ++ ++ int irq; /* Device IRQ */ ++ ++ ++ /* cached registers */ ++ u32 hcfg; ++ u32 cdiv; ++ ++ struct mmc_request *mrq; /* Current request */ ++ struct mmc_command *cmd; /* Current command */ ++ struct mmc_data *data; /* Current data request */ ++ unsigned int data_complete:1; /* Data finished before cmd */ ++ ++ unsigned int flush_fifo:1; /* Drain the fifo when finishing */ ++ ++ unsigned int use_busy:1; /* Wait for busy interrupt */ ++ ++ u32 thread_isr; ++ ++ /*DMA part*/ ++ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ ++ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ ++ ++ bool allow_dma; ++ bool have_dma; ++ bool use_dma; ++ /*end of DMA part*/ ++ ++ int max_delay; /* maximum length of time spent waiting */ ++ struct timeval stop_time; /* when the last stop was issued */ ++ u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ ++ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ ++ u32 max_overclock; /* Highest reported */ ++}; ++ ++ ++static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) ++{ ++ writel(val, host->ioaddr + reg); ++} ++ ++static inline u32 bcm2835_sdhost_read(struct bcm2835_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg) ++{ ++ return readl_relaxed(host->ioaddr + reg); ++} ++ ++static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) ++{ ++ pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", ++ mmc_hostname(host->mmc)); ++ ++ pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", ++ bcm2835_sdhost_read(host, SDCMD)); ++ pr_info(DRIVER_NAME ": SDARG 0x%08x\n", ++ bcm2835_sdhost_read(host, SDARG)); ++ pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", ++ bcm2835_sdhost_read(host, SDTOUT)); ++ pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", ++ bcm2835_sdhost_read(host, SDCDIV)); ++ pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP0)); ++ pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP1)); ++ pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP2)); ++ pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", ++ bcm2835_sdhost_read(host, SDRSP3)); ++ pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHSTS)); ++ pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", ++ bcm2835_sdhost_read(host, SDVDD)); ++ pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", ++ bcm2835_sdhost_read(host, SDEDM)); ++ pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHCFG)); ++ pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHBCT)); ++ pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", ++ bcm2835_sdhost_read(host, SDHBLC)); ++ ++ pr_debug(DRIVER_NAME ": ===========================================\n"); ++} ++ ++ ++static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) ++{ ++ bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); ++} ++ ++ ++static void bcm2835_sdhost_reset(struct bcm2835_host *host) ++{ ++ u32 temp; ++ ++ pr_debug("bcm2835_sdhost_reset\n"); ++ ++ bcm2835_sdhost_set_power(host, false); ++ ++ bcm2835_sdhost_write(host, 0, SDCMD); ++ bcm2835_sdhost_write(host, 0, SDARG); ++ bcm2835_sdhost_write(host, 0xf00000, SDTOUT); ++ bcm2835_sdhost_write(host, 0, SDCDIV); ++ bcm2835_sdhost_write(host, 0x7f8, SDHSTS); /* Write 1s to clear */ ++ bcm2835_sdhost_write(host, 0, SDHCFG); ++ bcm2835_sdhost_write(host, 0, SDHBCT); ++ bcm2835_sdhost_write(host, 0, SDHBLC); ++ ++ /* Limit fifo usage due to silicon bug */ ++ temp = bcm2835_sdhost_read(host, SDEDM); ++ temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); ++ mmiowb(); ++} ++ ++static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); ++ ++static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) ++{ ++ pr_debug("bcm2835_sdhost_init(%d)\n", soft); ++ ++ /* Set interrupt enables */ ++ host->hcfg = SDHCFG_BUSY_IRPT_EN; ++ ++ bcm2835_sdhost_reset(host); ++ ++ if (soft) { ++ /* force clock reconfiguration */ ++ host->clock = 0; ++ bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); ++ } ++} ++ ++static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) ++{ ++ bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); ++ ++ if (!write_complete) { ++ /* Request an IRQ for the last block */ ++ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { ++ /* The write has now completed. Disable the interrupt ++ and clear the status flag */ ++ host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); ++ write_complete = true; ++ } ++ } ++ ++ return write_complete; ++} ++ ++static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) ++{ ++ int timediff; ++#ifdef DEBUG ++ static struct timeval start_time; ++ static int max_stall_time = 0; ++ static int total_stall_time = 0; ++ struct timeval before, after; ++ ++ do_gettimeofday(&before); ++ if (max_stall_time == 0) ++ start_time = before; ++#endif ++ ++ timediff = 0; ++ ++ while (1) { ++ u32 edm = bcm2835_sdhost_read(host, SDEDM); ++ if ((edm & 0xf) == 1) ++ break; ++ timediff++; ++ if (timediff > 5000000) { ++#ifdef DEBUG ++ do_gettimeofday(&after); ++ timediff = (after.tv_sec - before.tv_sec)*1000000 + ++ (after.tv_usec - before.tv_usec); ++ ++ pr_err(" wait_write_complete - still waiting after %dus\n", ++ timediff); ++#else ++ pr_err(" wait_write_complete - still waiting after %d retries\n", ++ timediff); ++#endif ++ bcm2835_sdhost_dumpregs(host); ++ host->data->error = -ETIMEDOUT; ++ return; ++ } ++ } ++ ++#ifdef DEBUG ++ do_gettimeofday(&after); ++ timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); ++ ++ total_stall_time += timediff; ++ if (timediff > max_stall_time) ++ max_stall_time = timediff; ++ ++ if ((after.tv_sec - start_time.tv_sec) > 10) { ++ pr_debug(" wait_write_complete - max wait %dus, total %dus\n", ++ max_stall_time, total_stall_time); ++ start_time = after; ++ max_stall_time = 0; ++ total_stall_time = 0; ++ } ++#endif ++} ++ ++static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); ++ ++static void bcm2835_sdhost_dma_complete(void *param) ++{ ++ struct bcm2835_host *host = param; ++ struct dma_chan *dma_chan; ++ unsigned long flags; ++ u32 dir_data; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host->data) { ++ bool write_complete; ++ if (USE_BLOCK_IRQ) ++ write_complete = bcm2835_sdhost_is_write_complete(host); ++ else { ++ bcm2835_sdhost_wait_write_complete(host); ++ write_complete = true; ++ } ++ pr_debug("dma_complete() - write_complete=%d\n", ++ write_complete); ++ ++ if (write_complete || (host->data->flags & MMC_DATA_READ)) ++ { ++ if (write_complete) { ++ dma_chan = host->dma_chan_tx; ++ dir_data = DMA_TO_DEVICE; ++ } else { ++ dma_chan = host->dma_chan_rx; ++ dir_data = DMA_FROM_DEVICE; ++ } ++ ++ dma_unmap_sg(dma_chan->device->dev, ++ host->data->sg, host->data->sg_len, ++ dir_data); ++ ++ bcm2835_sdhost_finish_data(host); ++ } ++ } ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) ++{ ++ unsigned long flags; ++ size_t blksize, len; ++ u32 *buf; ++ ++ blksize = host->data->blksz; ++ ++ local_irq_save(flags); ++ ++ while (blksize) { ++ if (!sg_miter_next(&host->sg_miter)) ++ BUG(); ++ ++ len = min(host->sg_miter.length, blksize); ++ BUG_ON(len % 4); ++ ++ blksize -= len; ++ host->sg_miter.consumed = len; ++ ++ buf = (u32 *)host->sg_miter.addr; ++ ++ while (len) { ++ while (1) { ++ u32 hsts; ++ hsts = bcm2835_sdhost_read(host, SDHSTS); ++ if (hsts & SDHSTS_DATA_FLAG) ++ break; ++ ++ if (hsts & SDHSTS_ERROR_MASK) { ++ pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", ++ mmc_hostname(host->mmc), ++ hsts, ++ bcm2835_sdhost_read(host, SDHBCT), ++ blksize + len); ++ if (hsts & SDHSTS_REW_TIME_OUT) ++ host->data->error = -ETIMEDOUT; ++ else if (hsts & (SDHSTS_CRC16_ERROR || ++ SDHSTS_CRC7_ERROR)) ++ host->data->error = -EILSEQ; ++ else { ++ pr_err("%s: unexpected data error\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ } ++ } ++ } ++ ++ *(buf++) = bcm2835_sdhost_read(host, SDDATA); ++ len -= 4; ++ } ++ } ++ ++ sg_miter_stop(&host->sg_miter); ++ ++ local_irq_restore(flags); ++} ++ ++static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) ++{ ++ unsigned long flags; ++ size_t blksize, len; ++ u32 *buf; ++ ++ blksize = host->data->blksz; ++ ++ local_irq_save(flags); ++ ++ while (blksize) { ++ if (!sg_miter_next(&host->sg_miter)) ++ BUG(); ++ ++ len = min(host->sg_miter.length, blksize); ++ BUG_ON(len % 4); ++ ++ blksize -= len; ++ host->sg_miter.consumed = len; ++ ++ buf = host->sg_miter.addr; ++ ++ while (len) { ++ while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) ++ continue; ++ bcm2835_sdhost_write(host, *(buf++), SDDATA); ++ len -= 4; ++ } ++ } ++ ++ sg_miter_stop(&host->sg_miter); ++ ++ local_irq_restore(flags); ++} ++ ++ ++static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) ++{ ++ BUG_ON(!host->data); ++ ++ if (host->data->flags & MMC_DATA_READ) ++ bcm2835_sdhost_read_block_pio(host); ++ else ++ bcm2835_sdhost_write_block_pio(host); ++} ++ ++ ++static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) ++{ ++ u32 len, dir_data, dir_slave; ++ struct dma_async_tx_descriptor *desc = NULL; ++ struct dma_chan *dma_chan; ++ ++ pr_debug("bcm2835_sdhost_transfer_dma()\n"); ++ ++ WARN_ON(!host->data); ++ ++ if (!host->data) ++ return; ++ ++ if (host->data->flags & MMC_DATA_READ) { ++ dma_chan = host->dma_chan_rx; ++ dir_data = DMA_FROM_DEVICE; ++ dir_slave = DMA_DEV_TO_MEM; ++ } else { ++ dma_chan = host->dma_chan_tx; ++ dir_data = DMA_TO_DEVICE; ++ dir_slave = DMA_MEM_TO_DEV; ++ } ++ ++ BUG_ON(!dma_chan->device); ++ BUG_ON(!dma_chan->device->dev); ++ BUG_ON(!host->data->sg); ++ ++ len = dma_map_sg(dma_chan->device->dev, host->data->sg, ++ host->data->sg_len, dir_data); ++ if (len > 0) { ++ desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, ++ len, dir_slave, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ } else { ++ dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); ++ } ++ if (desc) { ++ desc->callback = bcm2835_sdhost_dma_complete; ++ desc->callback_param = host; ++ dmaengine_submit(desc); ++ dma_async_issue_pending(dma_chan); ++ } ++ ++} ++ ++ ++static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) ++{ ++ u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | ++ SDHCFG_BUSY_IRPT_EN; ++ if (host->use_dma) ++ host->hcfg = (host->hcfg & ~all_irqs) | ++ SDHCFG_BUSY_IRPT_EN; ++ else ++ host->hcfg = (host->hcfg & ~all_irqs) | ++ SDHCFG_DATA_IRPT_EN | ++ SDHCFG_BUSY_IRPT_EN; ++ ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++} ++ ++ ++static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) ++{ ++ struct mmc_data *data = cmd->data; ++ ++ WARN_ON(host->data); ++ ++ if (!data) ++ return; ++ ++ /* Sanity checks */ ++ BUG_ON(data->blksz * data->blocks > 524288); ++ BUG_ON(data->blksz > host->mmc->max_blk_size); ++ BUG_ON(data->blocks > 65535); ++ ++ host->data = data; ++ host->data_complete = 0; ++ host->flush_fifo = 0; ++ host->data->bytes_xfered = 0; ++ ++ if (!host->use_dma) { ++ int flags; ++ ++ flags = SG_MITER_ATOMIC; ++ if (data->flags & MMC_DATA_READ) ++ flags |= SG_MITER_TO_SG; ++ else ++ flags |= SG_MITER_FROM_SG; ++ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); ++ host->blocks = data->blocks; ++ } ++ ++ host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; ++ ++ bcm2835_sdhost_set_transfer_irqs(host); ++ ++ bcm2835_sdhost_write(host, data->blksz, SDHBCT); ++ if (host->use_dma) ++ bcm2835_sdhost_write(host, data->blocks, SDHBLC); ++ ++ BUG_ON(!host->data); ++} ++ ++ ++void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) ++{ ++ u32 sdcmd; ++ unsigned long timeout; ++ ++ WARN_ON(host->cmd); ++ ++ if (1) { ++ pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", ++ cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); ++ if (cmd->data) ++ pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ } ++ ++ /* Wait max 10 ms */ ++ timeout = 1000; ++ ++ while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { ++ if (timeout == 0) { ++ pr_err("%s: Previous command never completed.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ cmd->error = -EIO; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ timeout--; ++ udelay(10); ++ } ++ ++ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { ++ host->max_delay = (1000-timeout)/100; ++ pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); ++ } ++ ++ timeout = jiffies; ++#ifdef CONFIG_ARCH_BCM2835 ++ if (!cmd->data && cmd->busy_timeout > 9000) ++ timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; ++ else ++#endif ++ timeout += 10 * HZ; ++ mod_timer(&host->timer, timeout); ++ ++ host->cmd = cmd; ++ ++ bcm2835_sdhost_prepare_data(host, cmd); ++ ++ bcm2835_sdhost_write(host, cmd->arg, SDARG); ++ ++ if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { ++ pr_err("%s: Unsupported response type!\n", ++ mmc_hostname(host->mmc)); ++ cmd->error = -EINVAL; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ ++ sdcmd = cmd->opcode & SDCMD_CMD_MASK; ++ ++ if (!(cmd->flags & MMC_RSP_PRESENT)) ++ sdcmd |= SDCMD_NO_RESPONSE; ++ else { ++ if (cmd->flags & MMC_RSP_136) ++ sdcmd |= SDCMD_LONG_RESPONSE; ++ if (cmd->flags & MMC_RSP_BUSY) { ++ sdcmd |= SDCMD_BUSYWAIT; ++ host->use_busy = 1; ++ } ++ } ++ ++ if (cmd->data) { ++ if (host->delay_after_stop) { ++ struct timeval now; ++ int time_since_stop; ++ do_gettimeofday(&now); ++ time_since_stop = (now.tv_sec - host->stop_time.tv_sec); ++ if (time_since_stop < 2) { ++ /* Possibly less than one second */ ++ time_since_stop = time_since_stop * 1000000 + ++ (now.tv_usec - host->stop_time.tv_usec); ++ if (time_since_stop < host->delay_after_stop) ++ udelay(host->delay_after_stop - ++ time_since_stop); ++ } ++ } ++ ++ if (cmd->data->flags & MMC_DATA_WRITE) ++ sdcmd |= SDCMD_WRITE_CMD; ++ if (cmd->data->flags & MMC_DATA_READ) ++ sdcmd |= SDCMD_READ_CMD; ++ } ++ ++ bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); ++} ++ ++ ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); ++static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); ++ ++static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) ++{ ++ struct mmc_data *data; ++ ++ data = host->data; ++ BUG_ON(!data); ++ ++ pr_debug("finish_data(error %d, stop %d, sbc %d)\n", ++ data->error, data->stop ? 1 : 0, ++ host->mrq->sbc ? 1 : 0); ++ ++ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ ++ if (data->error) { ++ data->bytes_xfered = 0; ++ } else ++ data->bytes_xfered = data->blksz * data->blocks; ++ ++ host->data_complete = 1; ++ ++ if (host->cmd) { ++ /* ++ * Data managed to finish before the ++ * command completed. Make sure we do ++ * things in the proper order. ++ */ ++ pr_debug("Finished early - HSTS %x\n", ++ bcm2835_sdhost_read(host, SDHSTS)); ++ } ++ else ++ bcm2835_sdhost_transfer_complete(host); ++} ++ ++ ++static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) ++{ ++ struct mmc_data *data; ++ ++ BUG_ON(host->cmd); ++ BUG_ON(!host->data); ++ BUG_ON(!host->data_complete); ++ ++ data = host->data; ++ host->data = NULL; ++ ++ pr_debug("transfer_complete(error %d, stop %d)\n", ++ data->error, data->stop ? 1 : 0); ++ ++ if (data->error) ++ /* ++ * The controller needs a reset of internal state machines ++ * upon error conditions. ++ */ ++ bcm2835_sdhost_reset(host); ++ ++ /* ++ * Need to send CMD12 if - ++ * a) open-ended multiblock transfer (no CMD23) ++ * b) error in multiblock transfer ++ */ ++ if (data->stop && ++ (data->error || ++ !host->mrq->sbc)) { ++ host->flush_fifo = 1; ++ bcm2835_sdhost_send_command(host, data->stop); ++ if (host->delay_after_stop) ++ do_gettimeofday(&host->stop_time); ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host); ++ } else { ++ tasklet_schedule(&host->finish_tasklet); ++ } ++} ++ ++static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) ++{ ++ u32 sdcmd; ++ int timeout = 1000; ++#ifdef DEBUG ++ struct timeval before, after; ++ int timediff = 0; ++#endif ++ ++ pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); ++ ++ BUG_ON(!host->cmd || !host->mrq); ++ ++#ifdef DEBUG ++ do_gettimeofday(&before); ++#endif ++ for (sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ (sdcmd & SDCMD_NEW_FLAG) && timeout; ++ timeout--) { ++ if (host->flush_fifo) { ++ while (bcm2835_sdhost_read(host, SDHSTS) & ++ SDHSTS_DATA_FLAG) ++ (void)bcm2835_sdhost_read(host, SDDATA); ++ } ++ udelay(10); ++ sdcmd = bcm2835_sdhost_read(host, SDCMD); ++ } ++#ifdef DEBUG ++ do_gettimeofday(&after); ++ timediff = (after.tv_sec - before.tv_sec)*1000000 + ++ (after.tv_usec - before.tv_usec); ++ ++ pr_debug(" finish_command - waited %dus\n", timediff); ++#endif ++ ++ if (timeout == 0) { ++ pr_err("%s: Command never completed.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ ++ if (host->flush_fifo) { ++ for (timeout = 100; ++ (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; ++ timeout--) { ++ (void)bcm2835_sdhost_read(host, SDDATA); ++ } ++ host->flush_fifo = 0; ++ if (timeout == 0) { ++ pr_err("%s: FIFO never drained.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ } ++ ++ /* Check for errors */ ++ if (sdcmd & SDCMD_FAIL_FLAG) ++ { ++ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); ++ ++ pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", ++ mmc_hostname(host->mmc), sdcmd, sdhsts, ++ bcm2835_sdhost_read(host, SDEDM)); ++ ++ if (sdhsts & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else ++ { ++ pr_err("%s: unexpected command error\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ host->cmd->error = -EIO; ++ } ++ tasklet_schedule(&host->finish_tasklet); ++ return; ++ } ++ ++ if (host->cmd->flags & MMC_RSP_PRESENT) { ++ if (host->cmd->flags & MMC_RSP_136) { ++ int i; ++ for (i = 0; i < 4; i++) ++ host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); ++ pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", ++ host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); ++ } else { ++ host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); ++ pr_debug("bcm2835_sdhost_finish_command: %08x\n", ++ host->cmd->resp[0]); ++ } ++ } ++ ++ host->cmd->error = 0; ++ ++ if (host->cmd == host->mrq->sbc) { ++ /* Finished CMD23, now send actual command. */ ++ host->cmd = NULL; ++ bcm2835_sdhost_send_command(host, host->mrq->cmd); ++ ++ if (host->cmd->data && host->use_dma) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_transfer_dma(host); ++ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host); ++ } else if (host->cmd == host->mrq->stop) ++ /* Finished CMD12 */ ++ tasklet_schedule(&host->finish_tasklet); ++ else { ++ /* Processed actual command. */ ++ host->cmd = NULL; ++ if (!host->data) ++ tasklet_schedule(&host->finish_tasklet); ++ else if (host->data_complete) ++ bcm2835_sdhost_transfer_complete(host); ++ } ++} ++ ++static void bcm2835_sdhost_timeout_timer(unsigned long data) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ host = (struct bcm2835_host *)data; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (host->mrq) { ++ pr_err("%s: Timeout waiting for hardware interrupt.\n", ++ mmc_hostname(host->mmc)); ++ bcm2835_sdhost_dumpregs(host); ++ ++ if (host->data) { ++ host->data->error = -ETIMEDOUT; ++ bcm2835_sdhost_finish_data(host); ++ } else { ++ if (host->cmd) ++ host->cmd->error = -ETIMEDOUT; ++ else ++ host->mrq->cmd->error = -ETIMEDOUT; ++ ++ pr_debug("timeout_timer tasklet_schedule\n"); ++ tasklet_schedule(&host->finish_tasklet); ++ } ++ } ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) ++{ ++ if (enable) ++ host->hcfg |= SDHCFG_SDIO_IRPT_EN; ++ else ++ host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ mmiowb(); ++} ++ ++static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) ++{ ++ struct bcm2835_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ ++ pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); ++ spin_lock_irqsave(&host->lock, flags); ++ bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) ++{ ++ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ ++ if (!host->cmd) { ++ pr_err("%s: Got command busy interrupt 0x%08x even " ++ "though no command operation was in progress.\n", ++ mmc_hostname(host->mmc), (unsigned)intmask); ++ bcm2835_sdhost_dumpregs(host); ++ return 0; ++ } ++ ++ if (!host->use_busy) { ++ pr_err("%s: Got command busy interrupt 0x%08x even " ++ "though not expecting one.\n", ++ mmc_hostname(host->mmc), (unsigned)intmask); ++ bcm2835_sdhost_dumpregs(host); ++ return 0; ++ } ++ host->use_busy = 0; ++ ++ if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | ++ SDHSTS_FIFO_ERROR)) ++ host->cmd->error = -EILSEQ; ++ ++ if (host->cmd->error) ++ tasklet_schedule(&host->finish_tasklet); ++ else ++ bcm2835_sdhost_finish_command(host); ++ ++ return handled; ++} ++ ++static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) ++{ ++ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ ++ /* There are no dedicated data/space available interrupt ++ status bits, so it is necessary to use the single shared ++ data/space available FIFO status bits. It is therefore not ++ an error to get here when there is no data transfer in ++ progress. */ ++ if (!host->data) ++ return 0; ++ ++ // XXX FIFO_ERROR ++ if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && ++ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) ++ != MMC_BUS_TEST_R)) ++ host->cmd->error = -EILSEQ; ++ ++ /* Use the block interrupt for writes after the first block */ ++ if (host->data->flags & MMC_DATA_WRITE) { ++ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); ++ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ if (host->data->error) ++ bcm2835_sdhost_finish_data(host); ++ else ++ bcm2835_sdhost_transfer_pio(host); ++ } else { ++ if (!host->data->error) { ++ bcm2835_sdhost_transfer_pio(host); ++ host->blocks--; ++ } ++ if ((host->blocks == 0) || host->data->error) ++ bcm2835_sdhost_finish_data(host); ++ } ++ ++ return handled; ++} ++ ++static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) ++{ ++ struct dma_chan *dma_chan; ++ u32 dir_data; ++ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | ++ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); ++ ++ if (!host->data) { ++ pr_err("%s: Got block interrupt 0x%08x even " ++ "though no data operation was in progress.\n", ++ mmc_hostname(host->mmc), (unsigned)intmask); ++ bcm2835_sdhost_dumpregs(host); ++ return handled; ++ } ++ ++ if (intmask & SDHSTS_CMD_TIME_OUT) ++ host->cmd->error = -ETIMEDOUT; ++ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && ++ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) ++ != MMC_BUS_TEST_R)) ++ host->cmd->error = -EILSEQ; ++ ++ if (!host->use_dma) { ++ BUG_ON(!host->blocks); ++ host->blocks--; ++ if ((host->blocks == 0) || host->data->error) ++ bcm2835_sdhost_finish_data(host); ++ else ++ bcm2835_sdhost_transfer_pio(host); ++ } else if (host->data->flags & MMC_DATA_WRITE) { ++ dma_chan = host->dma_chan_tx; ++ dir_data = DMA_TO_DEVICE; ++ dma_unmap_sg(dma_chan->device->dev, ++ host->data->sg, host->data->sg_len, ++ dir_data); ++ ++ bcm2835_sdhost_finish_data(host); ++ } ++ ++ return handled; ++} ++ ++ ++static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) ++{ ++ irqreturn_t result = IRQ_NONE; ++ struct bcm2835_host *host = dev_id; ++ u32 unexpected = 0, early = 0; ++ int loops = 0; ++#ifndef CONFIG_ARCH_BCM2835 ++ int cardint = 0; ++#endif ++ spin_lock(&host->lock); ++ ++ for (loops = 0; loops < 1; loops++) { ++ u32 intmask, handled; ++ ++ intmask = bcm2835_sdhost_read(host, SDHSTS); ++ handled = intmask & (SDHSTS_BUSY_IRPT | ++ SDHSTS_BLOCK_IRPT | ++ SDHSTS_SDIO_IRPT | ++ SDHSTS_DATA_FLAG); ++ if ((handled == SDHSTS_DATA_FLAG) && // XXX ++ (loops == 0) && !host->data) { ++ pr_err("%s: sdhost_irq data interrupt 0x%08x even " ++ "though no data operation was in progress.\n", ++ mmc_hostname(host->mmc), ++ (unsigned)intmask); ++ ++ bcm2835_sdhost_dumpregs(host); ++ } ++ ++ if (!handled) ++ break; ++ ++ if (loops) ++ early |= handled; ++ ++ result = IRQ_HANDLED; ++ ++ /* Clear all interrupts and notifications */ ++ bcm2835_sdhost_write(host, intmask, SDHSTS); ++ ++ if (intmask & SDHSTS_BUSY_IRPT) ++ handled |= bcm2835_sdhost_busy_irq(host, intmask); ++ ++ /* There is no true data interrupt status bit, so it is ++ necessary to qualify the data flag with the interrupt ++ enable bit */ ++ if ((intmask & SDHSTS_DATA_FLAG) && ++ (host->hcfg & SDHCFG_DATA_IRPT_EN)) ++ handled |= bcm2835_sdhost_data_irq(host, intmask); ++ ++ if (intmask & SDHSTS_BLOCK_IRPT) ++ handled |= bcm2835_sdhost_block_irq(host, intmask); ++ ++ if (intmask & SDHSTS_SDIO_IRPT) { ++#ifndef CONFIG_ARCH_BCM2835 ++ cardint = 1; ++#else ++ bcm2835_sdhost_enable_sdio_irq_nolock(host, false); ++ host->thread_isr |= SDHSTS_SDIO_IRPT; ++ result = IRQ_WAKE_THREAD; ++#endif ++ } ++ ++ unexpected |= (intmask & ~handled); ++ } ++ ++ mmiowb(); ++ ++ spin_unlock(&host->lock); ++ ++ if (early) ++ pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); ++ ++ if (unexpected) { ++ pr_err("%s: Unexpected interrupt 0x%08x.\n", ++ mmc_hostname(host->mmc), unexpected); ++ bcm2835_sdhost_dumpregs(host); ++ } ++ ++#ifndef CONFIG_ARCH_BCM2835 ++ if (cardint) ++ mmc_signal_sdio_irq(host->mmc); ++#endif ++ ++ return result; ++} ++ ++#ifdef CONFIG_ARCH_BCM2835 ++static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) ++{ ++ struct bcm2835_host *host = dev_id; ++ unsigned long flags; ++ u32 isr; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ isr = host->thread_isr; ++ host->thread_isr = 0; ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (isr & SDHSTS_SDIO_IRPT) { ++ sdio_run_irqs(host->mmc); ++ ++/* Is this necessary? Why re-enable an interrupt which is enabled? ++ spin_lock_irqsave(&host->lock, flags); ++ if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) ++ bcm2835_sdhost_enable_sdio_irq_nolock(host, true); ++ spin_unlock_irqrestore(&host->lock, flags); ++*/ ++ } ++ ++ return isr ? IRQ_HANDLED : IRQ_NONE; ++} ++#endif ++ ++ ++ ++void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) ++{ ++ int div = 0; /* Initialized for compiler warning */ ++ unsigned int input_clock = clock; ++ ++ if (host->overclock_50 && (clock == 50000000)) ++ clock = host->overclock_50 * 1000000 + 999999; ++ ++ /* The SDCDIV register has 11 bits, and holds (div - 2). ++ But in data mode the max is 50MHz wihout a minimum, and only the ++ bottom 3 bits are used. Since the switch over is automatic (unless ++ we have marked the card as slow...), chosen values have to make ++ sense in both modes. ++ Ident mode must be 100-400KHz, so can range check the requested ++ clock. CMD15 must be used to return to data mode, so this can be ++ monitored. ++ ++ clock 250MHz -> 0->125MHz, 1->83.3MHz, 2->62.5MHz, 3->50.0MHz ++ 4->41.7MHz, 5->35.7MHz, 6->31.3MHz, 7->27.8MHz ++ ++ 623->400KHz/27.8MHz ++ reset value (507)->491159/50MHz ++ ++ BUT, the 3-bit clock divisor in data mode is too small if the ++ core clock is higher than 250MHz, so instead use the SLOW_CARD ++ configuration bit to force the use of the ident clock divisor ++ at all times. ++ */ ++ ++ host->mmc->actual_clock = 0; ++ ++ if (clock < 100000) { ++ /* Can't stop the clock, but make it as slow as possible ++ * to show willing ++ */ ++ host->cdiv = SDCDIV_MAX_CDIV; ++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); ++ return; ++ } ++ ++ div = host->max_clk / clock; ++ if (div < 2) ++ div = 2; ++ if ((host->max_clk / div) > clock) ++ div++; ++ div -= 2; ++ ++ if (div > SDCDIV_MAX_CDIV) ++ div = SDCDIV_MAX_CDIV; ++ ++ clock = host->max_clk / (div + 2); ++ host->mmc->actual_clock = clock; ++ ++ if ((clock > input_clock) && (clock > host->max_overclock)) { ++ pr_warn("%s: Overclocking to %dHz\n", ++ mmc_hostname(host->mmc), clock); ++ host->max_overclock = clock; ++ } ++ ++ host->cdiv = div; ++ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); ++ ++ pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", ++ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); ++} ++ ++static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ ++ if (1) { ++ struct mmc_command *cmd = mrq->cmd; ++ const char *src = "cmd"; ++ BUG_ON(!cmd); ++ pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", ++ src, cmd->opcode, cmd->arg, cmd->flags); ++ if (cmd->data) ++ pr_debug("bcm2835_sdhost_request: %s %d*%d\n", ++ (cmd->data->flags & MMC_DATA_READ) ? ++ "read" : "write", cmd->data->blocks, ++ cmd->data->blksz); ++ } ++ ++ if (mrq->data && !is_power_of_2(mrq->data->blksz)) { ++ pr_err("%s: Unsupported block size (%d bytes)\n", ++ mmc_hostname(mmc), mrq->data->blksz); ++ mrq->cmd->error = -EINVAL; ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ ++ host = mmc_priv(mmc); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ WARN_ON(host->mrq != NULL); ++ ++ host->mrq = mrq; ++ ++ if (mrq->sbc) ++ bcm2835_sdhost_send_command(host, mrq->sbc); ++ else ++ bcm2835_sdhost_send_command(host, mrq->cmd); ++ ++ mmiowb(); ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (!mrq->sbc && mrq->cmd->data && host->use_dma) ++ /* DMA transfer starts now, PIO starts after irq */ ++ bcm2835_sdhost_transfer_dma(host); ++ ++ if (!host->use_busy) ++ bcm2835_sdhost_finish_command(host); ++} ++ ++ ++static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ ++ struct bcm2835_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ ++ pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", ++ ios->clock, ios->power_mode, ios->bus_width, ++ ios->timing, ios->signal_voltage, ios->drv_type); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ if (!ios->clock || ios->clock != host->clock) { ++ bcm2835_sdhost_set_clock(host, ios->clock); ++ host->clock = ios->clock; ++ } ++ ++ /* set bus width */ ++ host->hcfg &= ~SDHCFG_WIDE_EXT_BUS; ++ if (ios->bus_width == MMC_BUS_WIDTH_4) ++ host->hcfg |= SDHCFG_WIDE_EXT_BUS; ++ ++ host->hcfg |= SDHCFG_WIDE_INT_BUS; ++ ++ /* Disable clever clock switching, to cope with fast core clocks */ ++ host->hcfg |= SDHCFG_SLOW_CARD; ++ ++ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); ++ ++ mmiowb(); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++} ++ ++static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, ++ unsigned int direction, ++ u32 blk_pos, int blk_size) ++{ ++ /* There is a bug in the host controller hardware that makes ++ reading the final sector of the card as part of a multiple read ++ problematic. Detect that case and shorten the read accordingly. ++ */ ++ /* csd.capacity is in weird units - convert to sectors */ ++ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); ++ ++ if ((direction == MMC_DATA_READ) && ++ ((blk_pos + blk_size) == card_sectors)) ++ blk_size--; ++ ++ return blk_size; ++} ++ ++ ++static struct mmc_host_ops bcm2835_sdhost_ops = { ++ .request = bcm2835_sdhost_request, ++ .set_ios = bcm2835_sdhost_set_ios, ++ .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, ++ .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, ++}; ++ ++ ++static void bcm2835_sdhost_tasklet_finish(unsigned long param) ++{ ++ struct bcm2835_host *host; ++ unsigned long flags; ++ struct mmc_request *mrq; ++ ++ host = (struct bcm2835_host *)param; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ ++ /* ++ * If this tasklet gets rescheduled while running, it will ++ * be run again afterwards but without any active request. ++ */ ++ if (!host->mrq) { ++ spin_unlock_irqrestore(&host->lock, flags); ++ return; ++ } ++ ++ del_timer(&host->timer); ++ ++ mrq = host->mrq; ++ ++ /* ++ * The controller needs a reset of internal state machines ++ * upon error conditions. ++ */ ++ if (((mrq->cmd && mrq->cmd->error) || ++ (mrq->data && (mrq->data->error || ++ (mrq->data->stop && mrq->data->stop->error))))) { ++ ++ bcm2835_sdhost_reset(host); ++ } ++ ++ host->mrq = NULL; ++ host->cmd = NULL; ++ host->data = NULL; ++ ++ mmiowb(); ++ ++ spin_unlock_irqrestore(&host->lock, flags); ++ mmc_request_done(host->mmc, mrq); ++} ++ ++ ++ ++int bcm2835_sdhost_add_host(struct bcm2835_host *host) ++{ ++ struct mmc_host *mmc; ++ struct dma_slave_config cfg; ++ int ret; ++ ++ mmc = host->mmc; ++ ++ bcm2835_sdhost_reset(host); ++ ++ mmc->f_max = host->max_clk; ++ mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; ++ ++ /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ ++ host->timeout_clk = mmc->f_max / 1000; ++#ifdef CONFIG_ARCH_BCM2835 ++ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; ++#endif ++ /* host controller capabilities */ ++ mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | ++ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | ++ MMC_CAP_NEEDS_POLL | ++ (ALLOW_CMD23 * MMC_CAP_CMD23); ++ ++ spin_lock_init(&host->lock); ++ ++ if (host->allow_dma) { ++ if (!host->dma_chan_tx || !host->dma_chan_rx || ++ IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { ++ pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); ++ host->have_dma = false; ++ } else { ++ pr_info("DMA channels allocated for the SDHost driver"); ++ host->have_dma = true; ++ ++ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ cfg.slave_id = 13; /* DREQ channel */ ++ ++ cfg.direction = DMA_MEM_TO_DEV; ++ cfg.src_addr = 0; ++ cfg.dst_addr = host->phys_addr + SDDATA; ++ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); ++ ++ cfg.direction = DMA_DEV_TO_MEM; ++ cfg.src_addr = host->phys_addr + SDDATA; ++ cfg.dst_addr = 0; ++ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); ++ } ++ } else { ++ pr_info("Forcing PIO mode\n"); ++ host->have_dma = false; ++ } ++ ++ mmc->max_segs = 128; ++ mmc->max_req_size = 524288; ++ mmc->max_seg_size = mmc->max_req_size; ++ mmc->max_blk_size = 512; ++ mmc->max_blk_count = 65535; ++ ++ /* report supported voltage ranges */ ++ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; ++ ++ tasklet_init(&host->finish_tasklet, ++ bcm2835_sdhost_tasklet_finish, (unsigned long)host); ++ ++ setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); ++ ++ bcm2835_sdhost_init(host, 0); ++#ifndef CONFIG_ARCH_BCM2835 ++ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, ++ mmc_hostname(mmc), host); ++#else ++ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, ++ IRQF_SHARED, mmc_hostname(mmc), host); ++#endif ++ if (ret) { ++ pr_err("%s: Failed to request IRQ %d: %d\n", ++ mmc_hostname(mmc), host->irq, ret); ++ goto untasklet; ++ } ++ ++ mmiowb(); ++ mmc_add_host(mmc); ++ ++ pr_info("Load BCM2835 SDHost driver\n"); ++ if (host->delay_after_stop) ++ pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", ++ host->delay_after_stop); ++ ++ return 0; ++ ++untasklet: ++ tasklet_kill(&host->finish_tasklet); ++ ++ return ret; ++} ++ ++static int bcm2835_sdhost_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *node = dev->of_node; ++ struct clk *clk; ++ struct resource *iomem; ++ struct bcm2835_host *host; ++ struct mmc_host *mmc; ++ int ret; ++ ++ pr_debug("bcm2835_sdhost_probe\n"); ++ mmc = mmc_alloc_host(sizeof(*host), dev); ++ if (!mmc) ++ return -ENOMEM; ++ ++ mmc->ops = &bcm2835_sdhost_ops; ++ host = mmc_priv(mmc); ++ host->mmc = mmc; ++ host->timeout = msecs_to_jiffies(1000); ++ spin_lock_init(&host->lock); ++ ++ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ host->ioaddr = devm_ioremap_resource(dev, iomem); ++ if (IS_ERR(host->ioaddr)) { ++ ret = PTR_ERR(host->ioaddr); ++ goto err; ++ } ++ ++ host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT; ++ pr_debug(" - ioaddr %lx, iomem->start %lx, phys_addr %lx\n", ++ (unsigned long)host->ioaddr, ++ (unsigned long)iomem->start, ++ (unsigned long)host->phys_addr); ++ ++ host->allow_dma = ALLOW_DMA; ++ ++ if (node) { ++ /* Read any custom properties */ ++ of_property_read_u32(node, ++ "brcm,delay-after-stop", ++ &host->delay_after_stop); ++ of_property_read_u32(node, ++ "brcm,overclock-50", ++ &host->overclock_50); ++ host->allow_dma = ALLOW_DMA && ++ !of_property_read_bool(node, "brcm,force-pio"); ++ } ++ ++ if (host->allow_dma) { ++ if (node) { ++ host->dma_chan_tx = ++ dma_request_slave_channel(dev, "tx"); ++ host->dma_chan_rx = ++ dma_request_slave_channel(dev, "rx"); ++ } else { ++ dma_cap_mask_t mask; ++ ++ dma_cap_zero(mask); ++ /* we don't care about the channel, any would work */ ++ dma_cap_set(DMA_SLAVE, mask); ++ host->dma_chan_tx = ++ dma_request_channel(mask, NULL, NULL); ++ host->dma_chan_rx = ++ dma_request_channel(mask, NULL, NULL); ++ } ++ } ++ ++ clk = devm_clk_get(dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(dev, "could not get clk\n"); ++ ret = PTR_ERR(clk); ++ goto err; ++ } ++ ++ host->max_clk = clk_get_rate(clk); ++ ++ host->irq = platform_get_irq(pdev, 0); ++ if (host->irq <= 0) { ++ dev_err(dev, "get IRQ failed\n"); ++ ret = -EINVAL; ++ goto err; ++ } ++ ++ pr_debug(" - max_clk %lx, irq %d\n", ++ (unsigned long)host->max_clk, ++ (int)host->irq); ++ ++ if (node) ++ mmc_of_parse(mmc); ++ else ++ mmc->caps |= MMC_CAP_4_BIT_DATA; ++ ++ ret = bcm2835_sdhost_add_host(host); ++ if (ret) ++ goto err; ++ ++ platform_set_drvdata(pdev, host); ++ ++ pr_debug("bcm2835_sdhost_probe -> OK\n"); ++ ++ return 0; ++ ++err: ++ pr_debug("bcm2835_sdhost_probe -> err %d\n", ret); ++ mmc_free_host(mmc); ++ ++ return ret; ++} ++ ++static int bcm2835_sdhost_remove(struct platform_device *pdev) ++{ ++ struct bcm2835_host *host = platform_get_drvdata(pdev); ++ ++ pr_debug("bcm2835_sdhost_remove\n"); ++ ++ mmc_remove_host(host->mmc); ++ ++ bcm2835_sdhost_set_power(host, false); ++ ++ free_irq(host->irq, host); ++ ++ del_timer_sync(&host->timer); ++ ++ tasklet_kill(&host->finish_tasklet); ++ ++ mmc_free_host(host->mmc); ++ platform_set_drvdata(pdev, NULL); ++ ++ pr_debug("bcm2835_sdhost_remove - OK\n"); ++ return 0; ++} ++ ++ ++static const struct of_device_id bcm2835_sdhost_match[] = { ++ { .compatible = "brcm,bcm2835-sdhost" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); ++ ++ ++ ++static struct platform_driver bcm2835_sdhost_driver = { ++ .probe = bcm2835_sdhost_probe, ++ .remove = bcm2835_sdhost_remove, ++ .driver = { ++ .name = DRIVER_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2835_sdhost_match, ++ }, ++}; ++module_platform_driver(bcm2835_sdhost_driver); ++ ++MODULE_ALIAS("platform:sdhost-bcm2835"); ++MODULE_DESCRIPTION("BCM2835 SDHost driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Phil Elwell"); + +From 34fb9ba0190b9f9e18e6c136c64af8dcea23376d Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:31:47 +0100 -Subject: [PATCH 009/216] cma: Add vc_cma driver to enable use of CMA +Subject: [PATCH 11/77] cma: Add vc_cma driver to enable use of CMA Signed-off-by: popcornmix @@ -80985,12 +80479,15 @@ index 0000000..5325832 + +#endif /* VC_CMA_H */ -From 6bafd180b5b7672ebbaea3878e78511d309007a0 Mon Sep 17 00:00:00 2001 +From 0e6896e85bf10d584b555ecae4b55f066a774b54 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 26 Mar 2012 22:15:50 +0100 -Subject: [PATCH 010/216] bcm2708: alsa sound driver +Subject: [PATCH 12/77] bcm2708: alsa sound driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit - Signed-off-by: popcornmix +Signed-off-by: popcornmix alsa: add mmap support and some cleanups to bcm2835 ALSA driver @@ -81014,33 +80511,41 @@ snd-bcm2708: Fix dmesg spam for non-error case alsa: Ensure mutexes are released through error paths alsa: Make interrupted close paths quieter + +BCM270x: Add onboard sound device to Device Tree + +Add Device Tree support to alsa driver. +Add device to Device Tree. +Don't add platform devices when booting in DT mode. + +Signed-off-by: Noralf Trønnes --- - arch/arm/mach-bcm2708/bcm2708.c | 54 +++ - sound/arm/Kconfig | 7 + + arch/arm/mach-bcm2708/bcm2708.c | 53 +++ + arch/arm/mach-bcm2709/bcm2709.c | 53 +++ + sound/arm/Kconfig | 8 + sound/arm/Makefile | 5 + sound/arm/bcm2835-ctl.c | 323 +++++++++++++ sound/arm/bcm2835-pcm.c | 557 +++++++++++++++++++++++ sound/arm/bcm2835-vchiq.c | 902 +++++++++++++++++++++++++++++++++++++ - sound/arm/bcm2835.c | 420 +++++++++++++++++ + sound/arm/bcm2835.c | 511 +++++++++++++++++++++ sound/arm/bcm2835.h | 167 +++++++ sound/arm/vc_vchi_audioserv_defs.h | 116 +++++ - 9 files changed, 2551 insertions(+) + 10 files changed, 2695 insertions(+) create mode 100755 sound/arm/bcm2835-ctl.c create mode 100755 sound/arm/bcm2835-pcm.c create mode 100755 sound/arm/bcm2835-vchiq.c - create mode 100755 sound/arm/bcm2835.c + create mode 100644 sound/arm/bcm2835.c create mode 100755 sound/arm/bcm2835.h create mode 100644 sound/arm/vc_vchi_audioserv_defs.h diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index d1308ed..f54e3e9b 100644 +index 5b10802..06271df 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -447,6 +447,58 @@ struct platform_device bcm2708_powerman_device = { - .coherent_dma_mask = 0xffffffffUL}, +@@ -429,6 +429,57 @@ struct platform_device bcm2835_emmc_device = { }; + #endif /* CONFIG_MMC_BCM2835 */ -+ +static struct platform_device bcm2708_alsa_devices[] = { + [0] = { + .name = "bcm2835_AUD0", @@ -81095,26 +80600,98 @@ index d1308ed..f54e3e9b 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -556,6 +608,8 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2835_emmc_device); +@@ -571,6 +622,8 @@ void __init bcm2708_init(void) #endif bcm2708_init_led(); + bcm2708_init_uart1(); + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -+ bcm_register_device(&bcm2708_alsa_devices[i]); ++ bcm_register_device_dt(&bcm2708_alsa_devices[i]); - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 54c5444..0f875ff 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -449,6 +449,57 @@ struct platform_device bcm2835_emmc_device = { + }; + #endif /* CONFIG_MMC_BCM2835 */ + ++static struct platform_device bcm2708_alsa_devices[] = { ++ [0] = { ++ .name = "bcm2835_AUD0", ++ .id = 0, /* first audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [1] = { ++ .name = "bcm2835_AUD1", ++ .id = 1, /* second audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [2] = { ++ .name = "bcm2835_AUD2", ++ .id = 2, /* third audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [3] = { ++ .name = "bcm2835_AUD3", ++ .id = 3, /* forth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [4] = { ++ .name = "bcm2835_AUD4", ++ .id = 4, /* fifth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [5] = { ++ .name = "bcm2835_AUD5", ++ .id = 5, /* sixth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [6] = { ++ .name = "bcm2835_AUD6", ++ .id = 6, /* seventh audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++ [7] = { ++ .name = "bcm2835_AUD7", ++ .id = 7, /* eighth audio device */ ++ .resource = 0, ++ .num_resources = 0, ++ }, ++}; ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -591,6 +642,8 @@ void __init bcm2709_init(void) + #endif + bcm2709_init_led(); + bcm2709_init_uart1(); ++ for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) ++ bcm_register_device_dt(&bcm2708_alsa_devices[i]); + + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig -index 885683a..ada7ba2 100644 +index 885683a..fcbe9d7 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig -@@ -39,5 +39,12 @@ config SND_PXA2XX_AC97 +@@ -39,5 +39,13 @@ 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 || ARCH_BCM2709) && BCM2708_VCHIQ && SND ++ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) \ ++ && BCM2708_VCHIQ && SND + select SND_PCM + help + Say Y or M if you want to support BCM2835 Alsa pcm card driver @@ -82935,11 +82512,11 @@ index 0000000..3de3094 +module_param(force_bulk, bool, 0444); +MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c -new file mode 100755 -index 0000000..7ed5079 +new file mode 100644 +index 0000000..6b545e7 --- /dev/null +++ b/sound/arm/bcm2835.c -@@ -0,0 +1,420 @@ +@@ -0,0 +1,511 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -82959,6 +82536,7 @@ index 0000000..7ed5079 +#include +#include +#include ++#include + +#include "bcm2835.h" + @@ -83023,6 +82601,86 @@ index 0000000..7ed5079 + return 0; +} + ++static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ bcm2835_chip_t *chip; ++ struct snd_card *card; ++ u32 numchans; ++ int err, i; ++ ++ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", ++ &numchans); ++ if (err) { ++ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); ++ return err; ++ } ++ ++ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { ++ numchans = MAX_SUBSTREAMS; ++ dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n", ++ numchans); ++ } ++ ++ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card); ++ if (err) { ++ dev_err(dev, "Failed to create soundcard structure\n"); ++ return err; ++ } ++ ++ snd_card_set_dev(card, dev); ++ strcpy(card->driver, "bcm2835"); ++ strcpy(card->shortname, "bcm2835 ALSA"); ++ sprintf(card->longname, "%s", card->shortname); ++ ++ err = snd_bcm2835_create(card, pdev, &chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create bcm2835 chip\n"); ++ goto err_free; ++ } ++ ++ err = snd_bcm2835_new_pcm(chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create new bcm2835 pcm device\n"); ++ goto err_free; ++ } ++ ++ err = snd_bcm2835_new_spdif_pcm(chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n"); ++ goto err_free; ++ } ++ ++ err = snd_bcm2835_new_ctl(chip); ++ if (err < 0) { ++ dev_err(dev, "Failed to create new bcm2835 ctl\n"); ++ goto err_free; ++ } ++ ++ for (i = 0; i < numchans; i++) { ++ chip->avail_substreams |= (1 << i); ++ chip->pdev[i] = pdev; ++ } ++ ++ err = snd_card_register(card); ++ if (err) { ++ dev_err(dev, "Failed to register bcm2835 ALSA card \n"); ++ goto err_free; ++ } ++ ++ g_card = card; ++ g_chip = chip; ++ platform_set_drvdata(pdev, card); ++ audio_info("bcm2835 ALSA card created with %u channels\n", numchans); ++ ++ return 0; ++ ++err_free: ++ snd_card_free(card); ++ ++ return err; ++} ++ +static int snd_bcm2835_alsa_probe(struct platform_device *pdev) +{ + static int dev; @@ -83030,6 +82688,9 @@ index 0000000..7ed5079 + struct snd_card *card; + int err; + ++ if (pdev->dev.of_node) ++ return snd_bcm2835_alsa_probe_dt(pdev); ++ + if (dev >= MAX_SUBSTREAMS) + return -ENODEV; + @@ -83166,6 +82827,12 @@ index 0000000..7ed5079 + +#endif + ++static const struct of_device_id snd_bcm2835_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-audio", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); ++ +static struct platform_driver bcm2835_alsa0_driver = { + .probe = snd_bcm2835_alsa_probe, + .remove = snd_bcm2835_alsa_remove, @@ -83176,6 +82843,7 @@ index 0000000..7ed5079 + .driver = { + .name = "bcm2835_AUD0", + .owner = THIS_MODULE, ++ .of_match_table = snd_bcm2835_of_match_table, + }, +}; + @@ -83656,10 +83324,13 @@ index 0000000..af3e6eb + +#endif // _VC_AUDIO_DEFS_H_ -From ddf7318165c6faf5bc73597105a2eed9fece4225 Mon Sep 17 00:00:00 2001 +From b2b5ab24c875e79e1fbb55ae76dc5a914fe301d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 2 Jul 2013 23:42:01 +0100 -Subject: [PATCH 011/216] bcm2708 vchiq driver +Subject: [PATCH 13/77] bcm2708 vchiq driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit Signed-off-by: popcornmix @@ -83727,7 +83398,30 @@ vchiq: Fix wrong condition check The log level is checked from within the log call. Remove the check in the call. Signed-off-by: Pranith Kumar + +BCM270x: Add vchiq device to platform file and Device Tree + +Prepare to turn the vchiq module into a driver. + +Signed-off-by: Noralf Trønnes + +bcm2708: vchiq: Add Device Tree support + +Turn vchiq into a driver and stop hardcoding resources. +Use devm_* functions in probe path to simplify cleanup. +A global variable is used to hold the register address. This is done +to keep this patch as small as possible. +Also make available on ARCH_BCM2835. +Based on work by Lubomir Rintel. + +Signed-off-by: Noralf Trønnes + +vchiq: Change logging level for inbound data --- + arch/arm/mach-bcm2708/bcm2708.c | 26 + + arch/arm/mach-bcm2708/include/mach/platform.h | 2 + + arch/arm/mach-bcm2709/bcm2709.c | 26 + + arch/arm/mach-bcm2709/include/mach/platform.h | 2 + drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/vc04_services/Kconfig | 9 + @@ -83741,9 +83435,9 @@ Signed-off-by: Pranith Kumar .../misc/vc04_services/interface/vchi/vchi_mh.h | 42 + .../misc/vc04_services/interface/vchiq_arm/vchiq.h | 40 + .../vc04_services/interface/vchiq_arm/vchiq_2835.h | 42 + - .../interface/vchiq_arm/vchiq_2835_arm.c | 562 +++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2884 ++++++++++++++ - .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 223 ++ + .../interface/vchiq_arm/vchiq_2835_arm.c | 547 +++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 2886 ++++++++++++++ + .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 220 ++ .../interface/vchiq_arm/vchiq_build_info.h | 37 + .../vc04_services/interface/vchiq_arm/vchiq_cfg.h | 69 + .../interface/vchiq_arm/vchiq_connected.c | 120 + @@ -83763,7 +83457,7 @@ Signed-off-by: Pranith Kumar .../vc04_services/interface/vchiq_arm/vchiq_util.c | 152 + .../vc04_services/interface/vchiq_arm/vchiq_util.h | 81 + .../interface/vchiq_arm/vchiq_version.c | 59 + - 35 files changed, 12770 insertions(+) + 39 files changed, 12810 insertions(+) create mode 100644 drivers/misc/vc04_services/Kconfig create mode 100644 drivers/misc/vc04_services/Makefile create mode 100644 drivers/misc/vc04_services/interface/vchi/connections/connection.h @@ -83798,6 +83492,120 @@ Signed-off-by: Pranith Kumar create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_util.h create mode 100644 drivers/misc/vc04_services/interface/vchiq_arm/vchiq_version.c +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 06271df..86011af 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -376,6 +376,31 @@ static struct platform_device bcm2708_vcio_device = { + }, + }; + ++static struct resource bcm2708_vchiq_resources[] = { ++ { ++ .start = ARMCTRL_0_BELL_BASE, ++ .end = ARMCTRL_0_BELL_BASE + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_DOORBELL_0, ++ .end = IRQ_ARM_DOORBELL_0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_vchiq_device = { ++ .name = "bcm2835_vchiq", ++ .id = -1, ++ .resource = bcm2708_vchiq_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), ++ .dev = { ++ .dma_mask = &vchiq_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ + #ifdef CONFIG_BCM2708_GPIO + #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" + +@@ -611,6 +636,7 @@ void __init bcm2708_init(void) + + bcm_register_device_dt(&bcm2708_dmaengine_device); + bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_vchiq_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif +diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h +index 2e7e1bb..69674e9 100644 +--- a/arch/arm/mach-bcm2708/include/mach/platform.h ++++ b/arch/arm/mach-bcm2708/include/mach/platform.h +@@ -81,6 +81,8 @@ + #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ + #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ + #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ ++#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ ++#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ + + + /* +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 0f875ff..bc1ee1c 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -396,6 +396,31 @@ static struct platform_device bcm2708_vcio_device = { + }, + }; + ++static struct resource bcm2708_vchiq_resources[] = { ++ { ++ .start = ARMCTRL_0_BELL_BASE, ++ .end = ARMCTRL_0_BELL_BASE + 16, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_ARM_DOORBELL_0, ++ .end = IRQ_ARM_DOORBELL_0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++ ++static struct platform_device bcm2708_vchiq_device = { ++ .name = "bcm2835_vchiq", ++ .id = -1, ++ .resource = bcm2708_vchiq_resources, ++ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), ++ .dev = { ++ .dma_mask = &vchiq_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), ++ }, ++}; ++ + #ifdef CONFIG_BCM2708_GPIO + #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" + +@@ -631,6 +656,7 @@ void __init bcm2709_init(void) + + bcm_register_device_dt(&bcm2708_dmaengine_device); + bcm_register_device(&bcm2708_vcio_device); ++ bcm_register_device_dt(&bcm2708_vchiq_device); + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif +diff --git a/arch/arm/mach-bcm2709/include/mach/platform.h b/arch/arm/mach-bcm2709/include/mach/platform.h +index 7157f38..be99733 100644 +--- a/arch/arm/mach-bcm2709/include/mach/platform.h ++++ b/arch/arm/mach-bcm2709/include/mach/platform.h +@@ -81,6 +81,8 @@ + #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ + #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ + #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ ++#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ ++#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ + + + /* diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 006242c..4e6f46c3 100644 --- a/drivers/misc/Kconfig @@ -83824,13 +83632,13 @@ index 7d5c4cd..43d2ac9 100644 obj-$(CONFIG_ECHO) += echo/ diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig new file mode 100644 -index 0000000..b94e6cd +index 0000000..c5ba283 --- /dev/null +++ b/drivers/misc/vc04_services/Kconfig @@ -0,0 +1,9 @@ +config BCM2708_VCHIQ + tristate "Videocore VCHIQ" -+ depends on MACH_BCM2708 || MACH_BCM2709 ++ depends on (MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX + default y + help + Kernel to VideoCore communication interface for the @@ -85417,10 +85225,10 @@ index 0000000..7ea5c64 +#endif /* VCHIQ_2835_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c new file mode 100644 -index 0000000..8ec88bb +index 0000000..c739083 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -0,0 +1,562 @@ +@@ -0,0 +1,547 @@ +/** + * Copyright (c) 2010-2012 Broadcom. All rights reserved. + * @@ -85458,23 +85266,18 @@ index 0000000..8ec88bb +#include +#include +#include -+#include +#include +#include +#include +#include ++#include ++#include +#include +#include + -+#include -+ -+#include -+#include -+ +#define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) + -+#define VCHIQ_DOORBELL_IRQ IRQ_ARM_DOORBELL_0 -+#define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) ++#define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset)) + +#include "vchiq_arm.h" +#include "vchiq_2835.h" @@ -85483,17 +85286,19 @@ index 0000000..8ec88bb + +#define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) + ++#define BELL0 0x00 ++#define BELL2 0x08 ++ +typedef struct vchiq_2835_state_struct { + int inited; + VCHIQ_ARM_STATE_T arm_state; +} VCHIQ_2835_ARM_STATE_T; + -+static char *g_slot_mem; -+static int g_slot_mem_size; -+dma_addr_t g_slot_phys; ++static void __iomem *g_regs; +static FRAGMENTS_T *g_fragments_base; +static FRAGMENTS_T *g_free_fragments; -+struct semaphore g_free_fragments_sema; ++static struct semaphore g_free_fragments_sema; ++static unsigned long g_virt_to_bus_offset; + +extern int vchiq_arm_log_level; + @@ -85509,43 +85314,42 @@ index 0000000..8ec88bb +static void +free_pagelist(PAGELIST_T *pagelist, int actual); + -+int __init -+vchiq_platform_init(VCHIQ_STATE_T *state) ++int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) +{ ++ struct device *dev = &pdev->dev; + VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; -+ int frag_mem_size; -+ int err; -+ int i; ++ struct resource *res; ++ void *slot_mem; ++ dma_addr_t slot_phys; ++ int slot_mem_size, frag_mem_size; ++ int err, irq, i; ++ ++ g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); + + /* Allocate space for the channels in coherent memory */ -+ g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); ++ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); + frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); + -+ g_slot_mem = dma_alloc_coherent(NULL, g_slot_mem_size + frag_mem_size, -+ &g_slot_phys, GFP_KERNEL); -+ -+ if (!g_slot_mem) { -+ vchiq_log_error(vchiq_arm_log_level, -+ "Unable to allocate channel memory"); -+ err = -ENOMEM; -+ goto failed_alloc; ++ slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, ++ &slot_phys, GFP_KERNEL); ++ if (!slot_mem) { ++ dev_err(dev, "could not allocate DMA memory\n"); ++ return -ENOMEM; + } + -+ WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0); ++ WARN_ON(((int)slot_mem & (PAGE_SIZE - 1)) != 0); + -+ vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size); -+ if (!vchiq_slot_zero) { -+ err = -EINVAL; -+ goto failed_init_slots; -+ } ++ vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); ++ if (!vchiq_slot_zero) ++ return -EINVAL; + + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = -+ (int)g_slot_phys + g_slot_mem_size; ++ (int)slot_phys + slot_mem_size; + vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = + MAX_FRAGMENTS; + -+ g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size); -+ g_slot_mem_size += frag_mem_size; ++ g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); ++ slot_mem_size += frag_mem_size; + + g_free_fragments = g_fragments_base; + for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { @@ -85555,54 +85359,46 @@ index 0000000..8ec88bb + *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; + sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); + -+ if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) != -+ VCHIQ_SUCCESS) { -+ err = -EINVAL; -+ goto failed_vchiq_init; ++ if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) ++ return -EINVAL; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ g_regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(g_regs)) ++ return PTR_ERR(g_regs); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(dev, "failed to get IRQ\n"); ++ return irq; + } + -+ err = request_irq(VCHIQ_DOORBELL_IRQ, vchiq_doorbell_irq, -+ IRQF_IRQPOLL, "VCHIQ doorbell", -+ state); -+ if (err < 0) { -+ vchiq_log_error(vchiq_arm_log_level, "%s: failed to register " -+ "irq=%d err=%d", __func__, -+ VCHIQ_DOORBELL_IRQ, err); -+ goto failed_request_irq; ++ err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL, ++ "VCHIQ doorbell", state); ++ if (err) { ++ dev_err(dev, "failed to register irq=%d\n", irq); ++ return err; + } + + /* Send the base address of the slots to VideoCore */ + + dsb(); /* Ensure all writes have completed */ + -+ bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys); ++ err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); ++ if (err) { ++ dev_err(dev, "mailbox write failed\n"); ++ return err; ++ } + + vchiq_log_info(vchiq_arm_log_level, -+ "vchiq_init - done (slots %x, phys %x)", -+ (unsigned int)vchiq_slot_zero, g_slot_phys); ++ "vchiq_init - done (slots %x, phys %pad)", ++ (unsigned int)vchiq_slot_zero, &slot_phys); + -+ vchiq_call_connected_callbacks(); ++ vchiq_call_connected_callbacks(); + + return 0; -+ -+failed_request_irq: -+failed_vchiq_init: -+failed_init_slots: -+ dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys); -+ -+failed_alloc: -+ return err; +} + -+void __exit -+vchiq_platform_exit(VCHIQ_STATE_T *state) -+{ -+ free_irq(VCHIQ_DOORBELL_IRQ, state); -+ dma_free_coherent(NULL, g_slot_mem_size, -+ g_slot_mem, g_slot_phys); -+} -+ -+ +VCHIQ_STATUS_T +vchiq_platform_init_state(VCHIQ_STATE_T *state) +{ @@ -85636,11 +85432,8 @@ index 0000000..8ec88bb + + dsb(); /* data barrier operation */ + -+ if (event->armed) { -+ /* trigger vc interrupt */ -+ -+ writel(0, __io_address(ARM_0_BELL2)); -+ } ++ if (event->armed) ++ writel(0, g_regs + BELL2); /* trigger vc interrupt */ +} + +int @@ -85764,7 +85557,7 @@ index 0000000..8ec88bb + unsigned int status; + + /* Read (and clear) the doorbell */ -+ status = readl(__io_address(ARM_0_BELL0)); ++ status = readl(g_regs + BELL0); + + if (status & 0x4) { /* Was the doorbell rung? */ + remote_event_pollall(state); @@ -85985,10 +85778,10 @@ index 0000000..8ec88bb +} diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c new file mode 100644 -index 0000000..0ad9656 +index 0000000..31e2cba --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -0,0 +1,2884 @@ +@@ -0,0 +1,2886 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -86036,6 +85829,7 @@ index 0000000..0ad9656 +#include +#include +#include ++#include + +#include "vchiq_core.h" +#include "vchiq_ioctl.h" @@ -88781,15 +88575,7 @@ index 0000000..0ad9656 + } +} + -+ -+/**************************************************************************** -+* -+* vchiq_init - called when the module is loaded. -+* -+***************************************************************************/ -+ -+static int __init -+vchiq_init(void) ++static int vchiq_probe(struct platform_device *pdev) +{ + int err; + void *ptr_err; @@ -88826,7 +88612,7 @@ index 0000000..0ad9656 + if (IS_ERR(ptr_err)) + goto failed_device_create; + -+ err = vchiq_platform_init(&g_state); ++ err = vchiq_platform_init(pdev, &g_state); + if (err != 0) + goto failed_platform_init; + @@ -88853,32 +88639,41 @@ index 0000000..0ad9656 + return err; +} + -+/**************************************************************************** -+* -+* vchiq_exit - called when the module is unloaded. -+* -+***************************************************************************/ -+ -+static void __exit -+vchiq_exit(void) ++static int vchiq_remove(struct platform_device *pdev) +{ -+ vchiq_platform_exit(&g_state); + device_destroy(vchiq_class, vchiq_devid); + class_destroy(vchiq_class); + cdev_del(&vchiq_cdev); + unregister_chrdev_region(vchiq_devid, 1); ++ ++ return 0; +} + -+module_init(vchiq_init); -+module_exit(vchiq_exit); ++static const struct of_device_id vchiq_of_match[] = { ++ { .compatible = "brcm,bcm2835-vchiq", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, vchiq_of_match); ++ ++static struct platform_driver vchiq_driver = { ++ .driver = { ++ .name = "bcm2835_vchiq", ++ .owner = THIS_MODULE, ++ .of_match_table = vchiq_of_match, ++ }, ++ .probe = vchiq_probe, ++ .remove = vchiq_remove, ++}; ++module_platform_driver(vchiq_driver); ++ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Broadcom Corporation"); diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h new file mode 100644 -index 0000000..d1e2741 +index 0000000..9740e1a --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -@@ -0,0 +1,223 @@ +@@ -0,0 +1,220 @@ +/** + * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved. + * Copyright (c) 2010-2012 Broadcom. All rights reserved. @@ -88917,6 +88712,7 @@ index 0000000..d1e2741 +#define VCHIQ_ARM_H + +#include ++#include +#include +#include +#include "vchiq_core.h" @@ -89009,11 +88805,7 @@ index 0000000..d1e2741 +extern int vchiq_arm_log_level; +extern int vchiq_susp_log_level; + -+extern int __init -+vchiq_platform_init(VCHIQ_STATE_T *state); -+ -+extern void __exit -+vchiq_platform_exit(VCHIQ_STATE_T *state); ++int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state); + +extern VCHIQ_STATE_T * +vchiq_get_state(void); @@ -89404,7 +89196,7 @@ index 0000000..863b3e3 +#endif /* VCHIQ_CONNECTED_H */ diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c new file mode 100644 -index 0000000..835688b +index 0000000..2c98da4 --- /dev/null +++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -0,0 +1,3934 @@ @@ -91192,7 +90984,7 @@ index 0000000..835688b + service->remoteport); + break; + case VCHIQ_MSG_DATA: -+ vchiq_log_trace(vchiq_core_log_level, ++ vchiq_log_info(vchiq_core_log_level, + "%d: prs DATA@%x,%x (%d->%d)", + state->id, (unsigned int)header, size, + remoteport, localport); @@ -96789,10 +96581,1019 @@ index 0000000..b6bfa21 + return vchiq_build_time; +} -From 859a7d70416a46048ab89165367891de2104ef6f Mon Sep 17 00:00:00 2001 +From 6290b45c0e5fa71d2131718d1b5770e7849aedeb Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 17 Jun 2015 16:07:06 +0100 +Subject: [PATCH 14/77] vc_mem: Add vc_mem driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: popcornmix + +BCM270x: Move vc_mem + +Make the vc_mem module available for ARCH_BCM2835 by moving it. + +Signed-off-by: Noralf Trønnes +--- + arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 --- + arch/arm/mach-bcm2709/vc_mem.c | 431 ---------------------------- + drivers/char/broadcom/Kconfig | 12 +- + drivers/char/broadcom/Makefile | 1 + + drivers/char/broadcom/vc_mem.c | 423 +++++++++++++++++++++++++++ + include/linux/broadcom/vc_mem.h | 35 +++ + 6 files changed, 470 insertions(+), 467 deletions(-) + delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h + delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c + create mode 100644 drivers/char/broadcom/vc_mem.c + create mode 100644 include/linux/broadcom/vc_mem.h + +diff --git a/arch/arm/mach-bcm2709/include/mach/vc_mem.h b/arch/arm/mach-bcm2709/include/mach/vc_mem.h +deleted file mode 100644 +index 4a4a338..0000000 +--- a/arch/arm/mach-bcm2709/include/mach/vc_mem.h ++++ /dev/null +@@ -1,35 +0,0 @@ +-/***************************************************************************** +-* Copyright 2010 - 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. +-*****************************************************************************/ +- +-#if !defined( VC_MEM_H ) +-#define VC_MEM_H +- +-#include +- +-#define VC_MEM_IOC_MAGIC 'v' +- +-#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 ) +-#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) +- +-#if defined( __KERNEL__ ) +-#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF +- +-extern unsigned long mm_vc_mem_phys_addr; +-extern unsigned int mm_vc_mem_size; +-extern int vc_mem_get_current_size( void ); +-#endif +- +-#endif /* VC_MEM_H */ +diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c +deleted file mode 100644 +index d2adfd1..0000000 +--- a/arch/arm/mach-bcm2709/vc_mem.c ++++ /dev/null +@@ -1,431 +0,0 @@ +-/***************************************************************************** +-* Copyright 2010 - 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 +- +-#ifdef CONFIG_ARCH_KONA +-#include +-#elif defined(CONFIG_ARCH_BCM2708) || defined(CONFIG_ARCH_BCM2709) +-#else +-#include +-#endif +- +-#include "mach/vc_mem.h" +- +-#define DRIVER_NAME "vc-mem" +- +-// Device (/dev) related variables +-static dev_t vc_mem_devnum = 0; +-static struct class *vc_mem_class = NULL; +-static struct cdev vc_mem_cdev; +-static int vc_mem_inited = 0; +- +-#ifdef CONFIG_DEBUG_FS +-static struct dentry *vc_mem_debugfs_entry; +-#endif +- +-/* +- * Videocore memory addresses and size +- * +- * Drivers that wish to know the videocore memory addresses and sizes should +- * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in +- * headers. This allows the other drivers to not be tied down to a a certain +- * address/size at compile time. +- * +- * In the future, the goal is to have the videocore memory virtual address and +- * size be calculated at boot time rather than at compile time. The decision of +- * where the videocore memory resides and its size would be in the hands of the +- * bootloader (and/or kernel). When that happens, the values of these variables +- * would be calculated and assigned in the init function. +- */ +-// in the 2835 VC in mapped above ARM, but ARM has full access to VC space +-unsigned long mm_vc_mem_phys_addr = 0x00000000; +-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); +- +-static uint phys_addr = 0; +-static uint mem_size = 0; +-static uint mem_base = 0; +- +- +-/**************************************************************************** +-* +-* vc_mem_open +-* +-***************************************************************************/ +- +-static int +-vc_mem_open(struct inode *inode, struct file *file) +-{ +- (void) inode; +- (void) file; +- +- pr_debug("%s: called file = 0x%p\n", __func__, file); +- +- return 0; +-} +- +-/**************************************************************************** +-* +-* vc_mem_release +-* +-***************************************************************************/ +- +-static int +-vc_mem_release(struct inode *inode, struct file *file) +-{ +- (void) inode; +- (void) file; +- +- pr_debug("%s: called file = 0x%p\n", __func__, file); +- +- return 0; +-} +- +-/**************************************************************************** +-* +-* vc_mem_get_size +-* +-***************************************************************************/ +- +-static void +-vc_mem_get_size(void) +-{ +-} +- +-/**************************************************************************** +-* +-* vc_mem_get_base +-* +-***************************************************************************/ +- +-static void +-vc_mem_get_base(void) +-{ +-} +- +-/**************************************************************************** +-* +-* vc_mem_get_current_size +-* +-***************************************************************************/ +- +-int +-vc_mem_get_current_size(void) +-{ +- return mm_vc_mem_size; +-} +- +-EXPORT_SYMBOL_GPL(vc_mem_get_current_size); +- +-/**************************************************************************** +-* +-* vc_mem_ioctl +-* +-***************************************************************************/ +- +-static long +-vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +-{ +- int rc = 0; +- +- (void) cmd; +- (void) arg; +- +- pr_debug("%s: called file = 0x%p\n", __func__, file); +- +- switch (cmd) { +- case VC_MEM_IOC_MEM_PHYS_ADDR: +- { +- pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", +- __func__, (void *) mm_vc_mem_phys_addr); +- +- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, +- sizeof (mm_vc_mem_phys_addr)) != 0) { +- rc = -EFAULT; +- } +- break; +- } +- case VC_MEM_IOC_MEM_SIZE: +- { +- // Get the videocore memory size first +- vc_mem_get_size(); +- +- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, +- mm_vc_mem_size); +- +- if (copy_to_user((void *) arg, &mm_vc_mem_size, +- sizeof (mm_vc_mem_size)) != 0) { +- rc = -EFAULT; +- } +- break; +- } +- case VC_MEM_IOC_MEM_BASE: +- { +- // Get the videocore memory base +- vc_mem_get_base(); +- +- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, +- mm_vc_mem_base); +- +- if (copy_to_user((void *) arg, &mm_vc_mem_base, +- sizeof (mm_vc_mem_base)) != 0) { +- rc = -EFAULT; +- } +- break; +- } +- case VC_MEM_IOC_MEM_LOAD: +- { +- // Get the videocore memory base +- vc_mem_get_base(); +- +- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: +- { +- return -ENOTTY; +- } +- } +- pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); +- +- return rc; +-} +- +-/**************************************************************************** +-* +-* vc_mem_mmap +-* +-***************************************************************************/ +- +-static int +-vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) +-{ +- int rc = 0; +- unsigned long length = vma->vm_end - vma->vm_start; +- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; +- +- pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", +- __func__, (long) vma->vm_start, (long) vma->vm_end, +- (long) vma->vm_pgoff); +- +- if (offset + length > mm_vc_mem_size) { +- pr_err("%s: length %ld is too big\n", __func__, length); +- return -EINVAL; +- } +- // Do not cache the memory map +- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +- +- rc = remap_pfn_range(vma, vma->vm_start, +- (mm_vc_mem_phys_addr >> PAGE_SHIFT) + +- vma->vm_pgoff, length, vma->vm_page_prot); +- if (rc != 0) { +- pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); +- } +- +- return rc; +-} +- +-/**************************************************************************** +-* +-* File Operations for the driver. +-* +-***************************************************************************/ +- +-static const struct file_operations vc_mem_fops = { +- .owner = THIS_MODULE, +- .open = vc_mem_open, +- .release = vc_mem_release, +- .unlocked_ioctl = vc_mem_ioctl, +- .mmap = vc_mem_mmap, +-}; +- +-#ifdef CONFIG_DEBUG_FS +-static void vc_mem_debugfs_deinit(void) +-{ +- debugfs_remove_recursive(vc_mem_debugfs_entry); +- vc_mem_debugfs_entry = NULL; +-} +- +- +-static int vc_mem_debugfs_init( +- struct device *dev) +-{ +- vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); +- if (!vc_mem_debugfs_entry) { +- dev_warn(dev, "could not create debugfs entry\n"); +- return -EFAULT; +- } +- +- if (!debugfs_create_x32("vc_mem_phys_addr", +- 0444, +- vc_mem_debugfs_entry, +- (u32 *)&mm_vc_mem_phys_addr)) { +- dev_warn(dev, "%s:could not create vc_mem_phys entry\n", +- __func__); +- goto fail; +- } +- +- if (!debugfs_create_x32("vc_mem_size", +- 0444, +- vc_mem_debugfs_entry, +- (u32 *)&mm_vc_mem_size)) { +- dev_warn(dev, "%s:could not create vc_mem_size entry\n", +- __func__); +- goto fail; +- } +- +- if (!debugfs_create_x32("vc_mem_base", +- 0444, +- vc_mem_debugfs_entry, +- (u32 *)&mm_vc_mem_base)) { +- dev_warn(dev, "%s:could not create vc_mem_base entry\n", +- __func__); +- goto fail; +- } +- +- return 0; +- +-fail: +- vc_mem_debugfs_deinit(); +- return -EFAULT; +-} +- +-#endif /* CONFIG_DEBUG_FS */ +- +- +-/**************************************************************************** +-* +-* vc_mem_init +-* +-***************************************************************************/ +- +-static int __init +-vc_mem_init(void) +-{ +- int rc = -EFAULT; +- struct device *dev; +- +- pr_debug("%s: called\n", __func__); +- +- mm_vc_mem_phys_addr = phys_addr; +- mm_vc_mem_size = mem_size; +- mm_vc_mem_base = mem_base; +- +- vc_mem_get_size(); +- +- pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", +- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); +- +- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { +- pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", +- __func__, rc); +- goto out_err; +- } +- +- cdev_init(&vc_mem_cdev, &vc_mem_fops); +- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { +- pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); +- goto out_unregister; +- } +- +- vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); +- if (IS_ERR(vc_mem_class)) { +- rc = PTR_ERR(vc_mem_class); +- pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); +- goto out_cdev_del; +- } +- +- dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, +- DRIVER_NAME); +- if (IS_ERR(dev)) { +- rc = PTR_ERR(dev); +- pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); +- goto out_class_destroy; +- } +- +-#ifdef CONFIG_DEBUG_FS +- /* don't fail if the debug entries cannot be created */ +- vc_mem_debugfs_init(dev); +-#endif +- +- vc_mem_inited = 1; +- return 0; +- +- device_destroy(vc_mem_class, vc_mem_devnum); +- +- out_class_destroy: +- class_destroy(vc_mem_class); +- vc_mem_class = NULL; +- +- out_cdev_del: +- cdev_del(&vc_mem_cdev); +- +- out_unregister: +- unregister_chrdev_region(vc_mem_devnum, 1); +- +- out_err: +- return -1; +-} +- +-/**************************************************************************** +-* +-* vc_mem_exit +-* +-***************************************************************************/ +- +-static void __exit +-vc_mem_exit(void) +-{ +- pr_debug("%s: called\n", __func__); +- +- if (vc_mem_inited) { +-#if CONFIG_DEBUG_FS +- vc_mem_debugfs_deinit(); +-#endif +- device_destroy(vc_mem_class, vc_mem_devnum); +- class_destroy(vc_mem_class); +- cdev_del(&vc_mem_cdev); +- unregister_chrdev_region(vc_mem_devnum, 1); +- } +-} +- +-module_init(vc_mem_init); +-module_exit(vc_mem_exit); +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Broadcom Corporation"); +- +-module_param(phys_addr, uint, 0644); +-module_param(mem_size, uint, 0644); +-module_param(mem_base, uint, 0644); +diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig +index 2d8bd6e..7037928 100644 +--- a/drivers/char/broadcom/Kconfig ++++ b/drivers/char/broadcom/Kconfig +@@ -7,9 +7,19 @@ menuconfig BRCM_CHAR_DRIVERS + help + Broadcom's char drivers + ++if BRCM_CHAR_DRIVERS ++ + config BCM_VC_CMA + bool "Videocore CMA" +- depends on CMA && BRCM_CHAR_DRIVERS && BCM2708_VCHIQ ++ depends on CMA && BCM2708_VCHIQ + default n + help + Helper for videocore CMA access. ++ ++config BCM2708_VCMEM ++ bool "Videocore Memory" ++ default y ++ help ++ Helper for videocore memory access and total size allocation. ++ ++endif +diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile +index 13c5bca..fce918c 100644 +--- a/drivers/char/broadcom/Makefile ++++ b/drivers/char/broadcom/Makefile +@@ -1 +1,2 @@ + obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ ++obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o +diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c +new file mode 100644 +index 0000000..fcde6b1 +--- /dev/null ++++ b/drivers/char/broadcom/vc_mem.c +@@ -0,0 +1,423 @@ ++/***************************************************************************** ++* Copyright 2010 - 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 ++ ++#define DRIVER_NAME "vc-mem" ++ ++// Device (/dev) related variables ++static dev_t vc_mem_devnum = 0; ++static struct class *vc_mem_class = NULL; ++static struct cdev vc_mem_cdev; ++static int vc_mem_inited = 0; ++ ++#ifdef CONFIG_DEBUG_FS ++static struct dentry *vc_mem_debugfs_entry; ++#endif ++ ++/* ++ * Videocore memory addresses and size ++ * ++ * Drivers that wish to know the videocore memory addresses and sizes should ++ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in ++ * headers. This allows the other drivers to not be tied down to a a certain ++ * address/size at compile time. ++ * ++ * In the future, the goal is to have the videocore memory virtual address and ++ * size be calculated at boot time rather than at compile time. The decision of ++ * where the videocore memory resides and its size would be in the hands of the ++ * bootloader (and/or kernel). When that happens, the values of these variables ++ * would be calculated and assigned in the init function. ++ */ ++// in the 2835 VC in mapped above ARM, but ARM has full access to VC space ++unsigned long mm_vc_mem_phys_addr = 0x00000000; ++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); ++ ++static uint phys_addr = 0; ++static uint mem_size = 0; ++static uint mem_base = 0; ++ ++ ++/**************************************************************************** ++* ++* vc_mem_open ++* ++***************************************************************************/ ++ ++static int ++vc_mem_open(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_release ++* ++***************************************************************************/ ++ ++static int ++vc_mem_release(struct inode *inode, struct file *file) ++{ ++ (void) inode; ++ (void) file; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ return 0; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_size ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_size(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_base ++* ++***************************************************************************/ ++ ++static void ++vc_mem_get_base(void) ++{ ++} ++ ++/**************************************************************************** ++* ++* vc_mem_get_current_size ++* ++***************************************************************************/ ++ ++int ++vc_mem_get_current_size(void) ++{ ++ return mm_vc_mem_size; ++} ++ ++EXPORT_SYMBOL_GPL(vc_mem_get_current_size); ++ ++/**************************************************************************** ++* ++* vc_mem_ioctl ++* ++***************************************************************************/ ++ ++static long ++vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ int rc = 0; ++ ++ (void) cmd; ++ (void) arg; ++ ++ pr_debug("%s: called file = 0x%p\n", __func__, file); ++ ++ switch (cmd) { ++ case VC_MEM_IOC_MEM_PHYS_ADDR: ++ { ++ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", ++ __func__, (void *) mm_vc_mem_phys_addr); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, ++ sizeof (mm_vc_mem_phys_addr)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_SIZE: ++ { ++ // Get the videocore memory size first ++ vc_mem_get_size(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, ++ mm_vc_mem_size); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_size, ++ sizeof (mm_vc_mem_size)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_BASE: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, ++ mm_vc_mem_base); ++ ++ if (copy_to_user((void *) arg, &mm_vc_mem_base, ++ sizeof (mm_vc_mem_base)) != 0) { ++ rc = -EFAULT; ++ } ++ break; ++ } ++ case VC_MEM_IOC_MEM_LOAD: ++ { ++ // Get the videocore memory base ++ vc_mem_get_base(); ++ ++ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: ++ { ++ return -ENOTTY; ++ } ++ } ++ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_mmap ++* ++***************************************************************************/ ++ ++static int ++vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ int rc = 0; ++ unsigned long length = vma->vm_end - vma->vm_start; ++ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ ++ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", ++ __func__, (long) vma->vm_start, (long) vma->vm_end, ++ (long) vma->vm_pgoff); ++ ++ if (offset + length > mm_vc_mem_size) { ++ pr_err("%s: length %ld is too big\n", __func__, length); ++ return -EINVAL; ++ } ++ // Do not cache the memory map ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ rc = remap_pfn_range(vma, vma->vm_start, ++ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + ++ vma->vm_pgoff, length, vma->vm_page_prot); ++ if (rc != 0) { ++ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); ++ } ++ ++ return rc; ++} ++ ++/**************************************************************************** ++* ++* File Operations for the driver. ++* ++***************************************************************************/ ++ ++static const struct file_operations vc_mem_fops = { ++ .owner = THIS_MODULE, ++ .open = vc_mem_open, ++ .release = vc_mem_release, ++ .unlocked_ioctl = vc_mem_ioctl, ++ .mmap = vc_mem_mmap, ++}; ++ ++#ifdef CONFIG_DEBUG_FS ++static void vc_mem_debugfs_deinit(void) ++{ ++ debugfs_remove_recursive(vc_mem_debugfs_entry); ++ vc_mem_debugfs_entry = NULL; ++} ++ ++ ++static int vc_mem_debugfs_init( ++ struct device *dev) ++{ ++ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); ++ if (!vc_mem_debugfs_entry) { ++ dev_warn(dev, "could not create debugfs entry\n"); ++ return -EFAULT; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_phys_addr", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_phys_addr)) { ++ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_size", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_size)) { ++ dev_warn(dev, "%s:could not create vc_mem_size entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ if (!debugfs_create_x32("vc_mem_base", ++ 0444, ++ vc_mem_debugfs_entry, ++ (u32 *)&mm_vc_mem_base)) { ++ dev_warn(dev, "%s:could not create vc_mem_base entry\n", ++ __func__); ++ goto fail; ++ } ++ ++ return 0; ++ ++fail: ++ vc_mem_debugfs_deinit(); ++ return -EFAULT; ++} ++ ++#endif /* CONFIG_DEBUG_FS */ ++ ++ ++/**************************************************************************** ++* ++* vc_mem_init ++* ++***************************************************************************/ ++ ++static int __init ++vc_mem_init(void) ++{ ++ int rc = -EFAULT; ++ struct device *dev; ++ ++ pr_debug("%s: called\n", __func__); ++ ++ mm_vc_mem_phys_addr = phys_addr; ++ mm_vc_mem_size = mem_size; ++ mm_vc_mem_base = mem_base; ++ ++ vc_mem_get_size(); ++ ++ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", ++ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); ++ ++ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { ++ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", ++ __func__, rc); ++ goto out_err; ++ } ++ ++ cdev_init(&vc_mem_cdev, &vc_mem_fops); ++ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { ++ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); ++ goto out_unregister; ++ } ++ ++ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); ++ if (IS_ERR(vc_mem_class)) { ++ rc = PTR_ERR(vc_mem_class); ++ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); ++ goto out_cdev_del; ++ } ++ ++ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, ++ DRIVER_NAME); ++ if (IS_ERR(dev)) { ++ rc = PTR_ERR(dev); ++ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); ++ goto out_class_destroy; ++ } ++ ++#ifdef CONFIG_DEBUG_FS ++ /* don't fail if the debug entries cannot be created */ ++ vc_mem_debugfs_init(dev); ++#endif ++ ++ vc_mem_inited = 1; ++ return 0; ++ ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ ++ out_class_destroy: ++ class_destroy(vc_mem_class); ++ vc_mem_class = NULL; ++ ++ out_cdev_del: ++ cdev_del(&vc_mem_cdev); ++ ++ out_unregister: ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ ++ out_err: ++ return -1; ++} ++ ++/**************************************************************************** ++* ++* vc_mem_exit ++* ++***************************************************************************/ ++ ++static void __exit ++vc_mem_exit(void) ++{ ++ pr_debug("%s: called\n", __func__); ++ ++ if (vc_mem_inited) { ++#if CONFIG_DEBUG_FS ++ vc_mem_debugfs_deinit(); ++#endif ++ device_destroy(vc_mem_class, vc_mem_devnum); ++ class_destroy(vc_mem_class); ++ cdev_del(&vc_mem_cdev); ++ unregister_chrdev_region(vc_mem_devnum, 1); ++ } ++} ++ ++module_init(vc_mem_init); ++module_exit(vc_mem_exit); ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Broadcom Corporation"); ++ ++module_param(phys_addr, uint, 0644); ++module_param(mem_size, uint, 0644); ++module_param(mem_base, uint, 0644); +diff --git a/include/linux/broadcom/vc_mem.h b/include/linux/broadcom/vc_mem.h +new file mode 100644 +index 0000000..20a4753 +--- /dev/null ++++ b/include/linux/broadcom/vc_mem.h +@@ -0,0 +1,35 @@ ++/***************************************************************************** ++* Copyright 2010 - 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_MEM_H ++#define _VC_MEM_H ++ ++#include ++ ++#define VC_MEM_IOC_MAGIC 'v' ++ ++#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 ) ++#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) ++ ++#if defined( __KERNEL__ ) ++#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF ++ ++extern unsigned long mm_vc_mem_phys_addr; ++extern unsigned int mm_vc_mem_size; ++extern int vc_mem_get_current_size( void ); ++#endif ++ ++#endif /* _VC_MEM_H */ + +From e9ebded52208b6164753a82d268cd80e833e2737 Mon Sep 17 00:00:00 2001 From: Tim Gover Date: Tue, 22 Jul 2014 15:41:04 +0100 -Subject: [PATCH 012/216] vcsm: VideoCore shared memory service for BCM2835 +Subject: [PATCH 15/77] vcsm: VideoCore shared memory service for BCM2835 Add experimental support for the VideoCore shared memory service. This allows user processes to allocate memory from VideoCore's @@ -96823,17 +97624,19 @@ On building the bcm_vc_sm as a module we get the following error: v7_dma_flush_range and do_munmap are undefined in vc-sm.ko. Fix by making it not an option to build as module + +vcsm: Add ioctl for custom cache flushing --- arch/arm/mach-bcm2708/include/mach/vc_sm_defs.h | 181 ++ arch/arm/mach-bcm2708/include/mach/vc_sm_knl.h | 55 + arch/arm/mach-bcm2708/include/mach/vc_vchi_sm.h | 82 + - arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h | 233 ++ - drivers/char/broadcom/Kconfig | 7 + + arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h | 248 ++ + drivers/char/broadcom/Kconfig | 9 + drivers/char/broadcom/Makefile | 1 + drivers/char/broadcom/vc_sm/Makefile | 21 + drivers/char/broadcom/vc_sm/vc_vchi_sm.c | 492 +++ - drivers/char/broadcom/vc_sm/vmcs_sm.c | 3163 ++++++++++++++++++++ - 9 files changed, 4235 insertions(+) + drivers/char/broadcom/vc_sm/vmcs_sm.c | 3211 ++++++++++++++++++++ + 9 files changed, 4300 insertions(+) create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_sm_defs.h create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_sm_knl.h create mode 100644 arch/arm/mach-bcm2708/include/mach/vc_vchi_sm.h @@ -97180,10 +97983,10 @@ index 0000000..5e279f5 +#endif /* __VC_VCHI_SM_H__INCLUDED__ */ diff --git a/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h new file mode 100644 -index 0000000..42d0eb0 +index 0000000..334f36d --- /dev/null +++ b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -@@ -0,0 +1,233 @@ +@@ -0,0 +1,248 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -97247,6 +98050,8 @@ index 0000000..42d0eb0 + VMCS_SM_CMD_HOST_WALK_PID_ALLOC, + VMCS_SM_CMD_HOST_WALK_PID_MAP, + ++ VMCS_SM_CMD_CLEAN_INVALID, ++ + VMCS_SM_CMD_LAST /* Do no delete */ +}; + @@ -97349,6 +98154,16 @@ index 0000000..42d0eb0 + unsigned int size; +}; + ++struct vmcs_sm_ioctl_clean_invalid { ++ /* user -> kernel */ ++ struct { ++ unsigned int cmd; ++ unsigned int handle; ++ unsigned int addr; ++ unsigned int size; ++ } s[8]; ++}; ++ +/* IOCTL numbers */ +#define VMCS_SM_IOCTL_MEM_ALLOC\ + _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_ALLOC,\ @@ -97377,6 +98192,9 @@ index 0000000..42d0eb0 +#define VMCS_SM_IOCTL_MEM_INVALID\ + _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\ + struct vmcs_sm_ioctl_cache) ++#define VMCS_SM_IOCTL_MEM_CLEAN_INVALID\ ++ _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_CLEAN_INVALID,\ ++ struct vmcs_sm_ioctl_clean_invalid) + +#define VMCS_SM_IOCTL_SIZE_USR_HDL\ + _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\ @@ -97418,26 +98236,29 @@ index 0000000..42d0eb0 + +#endif /* __VMCS_SM_IOCTL_H__INCLUDED__ */ diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index 2d8bd6e..fd23e00 100644 +index 7037928..75fa1cb 100644 --- a/drivers/char/broadcom/Kconfig +++ b/drivers/char/broadcom/Kconfig -@@ -13,3 +13,10 @@ config BCM_VC_CMA - default n - help - Helper for videocore CMA access. +@@ -23,3 +23,12 @@ config BCM2708_VCMEM + Helper for videocore memory access and total size allocation. + + endif + +config BCM_VC_SM + bool "VMCS Shared Memory" ++ depends on BCM2708_VCHIQ ++ select BCM2708_VCMEM + default n + help + Support for the VC shared memory on the Broadcom reference + design. Uses the VCHIQ stack. diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 13c5bca..0bf7fdf 100644 +index fce918c..de8feb9 100644 --- a/drivers/char/broadcom/Makefile +++ b/drivers/char/broadcom/Makefile -@@ -1 +1,2 @@ +@@ -1,2 +1,3 @@ obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ + obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o +obj-$(CONFIG_BCM_VC_SM) += vc_sm/ diff --git a/drivers/char/broadcom/vc_sm/Makefile b/drivers/char/broadcom/vc_sm/Makefile new file mode 100644 @@ -97966,10 +98787,10 @@ index 0000000..7c6ba1a +} diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c new file mode 100644 -index 0000000..da1c523 +index 0000000..0bfb42e --- /dev/null +++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -0,0 +1,3163 @@ +@@ -0,0 +1,3211 @@ +/***************************************************************************** +* Copyright 2011-2012 Broadcom Corporation. All rights reserved. +* @@ -97987,6 +98808,7 @@ index 0000000..da1c523 +/* ---- Include Files ----------------------------------------------------- */ + +#include ++#include +#include +#include +#include @@ -98007,8 +98829,6 @@ index 0000000..da1c523 +#include +#include + -+#include -+ +#include "vchiq_connected.h" +#include "vc_vchi_sm.h" + @@ -100704,6 +101524,55 @@ index 0000000..da1c523 + } + break; + ++ /* Flush/Invalidate the cache for a given mapping. */ ++ case VMCS_SM_CMD_CLEAN_INVALID: ++ { ++ int i; ++ struct vmcs_sm_ioctl_clean_invalid ioparam; ++ ++ /* Get parameter data. */ ++ if (copy_from_user(&ioparam, ++ (void *)arg, sizeof(ioparam)) != 0) { ++ pr_err("[%s]: failed to copy-from-user for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ goto out; ++ } ++ for (i=0; ires_cached) { ++ unsigned long base = ioparam.s[i].addr & ~(PAGE_SIZE-1); ++ unsigned long end = (ioparam.s[i].addr + ioparam.s[i].size + PAGE_SIZE-1) & ~(PAGE_SIZE-1); ++ resource->res_stats[ioparam.s[i].cmd == 1 ? INVALID:FLUSH]++; ++ ++ /* L1/L2 cache flush */ ++ down_read(¤t->mm->mmap_sem); ++ vcsm_vma_cache_clean_page_range(base, end); ++ up_read(¤t->mm->mmap_sem); ++ } else if (resource == NULL) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (resource) ++ vmcs_sm_release_resource(resource, 0); ++ } ++ break; ++ } ++ } ++ } ++ break; ++ + default: + { + ret = -EINVAL; @@ -101134,23 +102003,32 @@ index 0000000..da1c523 +MODULE_DESCRIPTION("VideoCore SharedMemory Driver"); +MODULE_LICENSE("GPL v2"); -From 103cb0411fad640ec86640f3fda90a3da782aa68 Mon Sep 17 00:00:00 2001 +From 7f769de038003dcf3f6eff180e2e295888789dc2 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:51:55 +0100 -Subject: [PATCH 013/216] Add hwrng (hardware random number generator) driver +Subject: [PATCH 16/77] Add hwrng (hardware random number generator) driver --- - drivers/char/hw_random/Kconfig | 11 ++++ + drivers/char/hw_random/Kconfig | 13 +++- drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/bcm2708-rng.c | 118 +++++++++++++++++++++++++++++++++++ - 3 files changed, 130 insertions(+) + 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100755 drivers/char/hw_random/bcm2708-rng.c diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index de57b38..1c97093 100644 +index f48cf11..70f9613 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig -@@ -320,6 +320,17 @@ config HW_RANDOM_TPM +@@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX + + config HW_RANDOM_BCM2835 + tristate "Broadcom BCM2835 Random Number Generator support" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the Random Number +@@ -333,6 +333,17 @@ config HW_RANDOM_TPM If unsure, say Y. @@ -101169,16 +102047,17 @@ index de57b38..1c97093 100644 tristate "Qualcomm SoCs Random Number Generator support" depends on HW_RANDOM && ARCH_QCOM diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile -index 0b4cd57..78b019c 100644 +index 055bb01..36be864 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile -@@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o - obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o - obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o - obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o +@@ -4,6 +4,7 @@ + + obj-$(CONFIG_HW_RANDOM) += rng-core.o + rng-core-y := core.o +obj-$(CONFIG_HW_RANDOM_BCM2708) += bcm2708-rng.o - obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o - obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o + obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o + obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o + obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o diff --git a/drivers/char/hw_random/bcm2708-rng.c b/drivers/char/hw_random/bcm2708-rng.c new file mode 100755 index 0000000..340f004 @@ -101304,10 +102183,10 @@ index 0000000..340f004 +MODULE_DESCRIPTION("BCM2708 H/W Random Number Generator (RNG) driver"); +MODULE_LICENSE("GPL and additional rights"); -From 4e3072cbb7ce07057d091188fc1a3897e3169007 Mon Sep 17 00:00:00 2001 +From 68990b28334ea63cdc56bfe9663025dade9d7822 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sat, 16 Jun 2012 12:15:55 +0200 -Subject: [PATCH 014/216] lirc: added support for RaspberryPi GPIO +Subject: [PATCH 17/77] lirc: added support for RaspberryPi GPIO lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others See: https://github.com/raspberrypi/linux/issues/525 @@ -101344,11 +102223,19 @@ read_current_timer isn't guaranteed to return values in microseconds, and indeed it doesn't on a Pi2. Issue: linux#827 + +lirc-rpi: Add device tree support, and a suitable overlay + +The overlay supports DT parameters that match the old module +parameters, except that gpio_in_pull should be set using the +strings "up", "down" or "off". + +lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode --- drivers/staging/media/lirc/Kconfig | 6 + drivers/staging/media/lirc/Makefile | 1 + - drivers/staging/media/lirc/lirc_rpi.c | 667 ++++++++++++++++++++++++++++++++++ - 3 files changed, 674 insertions(+) + drivers/staging/media/lirc/lirc_rpi.c | 765 ++++++++++++++++++++++++++++++++++ + 3 files changed, 772 insertions(+) create mode 100644 drivers/staging/media/lirc/lirc_rpi.c diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig @@ -101382,10 +102269,10 @@ index 5430adf..9e53cd0 100644 obj-$(CONFIG_LIRC_SIR) += lirc_sir.o diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c new file mode 100644 -index 0000000..8aa452d +index 0000000..24563ec --- /dev/null +++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -0,0 +1,667 @@ +@@ -0,0 +1,765 @@ +/* + * lirc_rpi.c + * @@ -101429,6 +102316,7 @@ index 0000000..8aa452d +#include +#include +#include ++#include + +#include + @@ -101691,32 +102579,117 @@ index 0000000..8aa452d + return 0; +} + ++static inline int read_bool_property(const struct device_node *np, ++ const char *propname, ++ bool *out_value) ++{ ++ u32 value = 0; ++ int err = of_property_read_u32(np, propname, &value); ++ if (err == 0) ++ *out_value = (value != 0); ++ return err; ++} ++ ++static void read_pin_settings(struct device_node *node) ++{ ++ u32 pin; ++ int index; ++ ++ for (index = 0; ++ of_property_read_u32_index( ++ node, ++ "brcm,pins", ++ index, ++ &pin) == 0; ++ index++) { ++ u32 function; ++ int err; ++ err = of_property_read_u32_index( ++ node, ++ "brcm,function", ++ index, ++ &function); ++ if (err == 0) { ++ if (function == 1) /* Output */ ++ gpio_out_pin = pin; ++ else if (function == 0) /* Input */ ++ gpio_in_pin = pin; ++ } ++ } ++} ++ +static int init_port(void) +{ + int i, nlow, nhigh, ret; ++ struct device_node *node; ++ ++ node = lirc_rpi_dev->dev.of_node; + + gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); + -+ if (!gpiochip) ++ /* ++ * Because of the lack of a setpull function, only support ++ * pinctrl-bcm2835 if using device tree. ++ */ ++ if (!gpiochip && node) ++ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); ++ ++ if (!gpiochip) { ++ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); + return -ENODEV; -+ -+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_out_pin); -+ ret = -ENODEV; -+ goto exit_init_port; + } + -+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_in_pin); -+ ret = -ENODEV; -+ goto exit_gpio_free_out_pin; ++ if (node) { ++ struct device_node *pins_node; ++ ++ pins_node = of_parse_phandle(node, "pinctrl-0", 0); ++ if (!pins_node) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": pinctrl settings not found!\n"); ++ ret = -EINVAL; ++ goto exit_init_port; ++ } ++ ++ read_pin_settings(pins_node); ++ ++ of_property_read_u32(node, "rpi,sense", &sense); ++ ++ read_bool_property(node, "rpi,softcarrier", &softcarrier); ++ ++ read_bool_property(node, "rpi,invert", &invert); ++ ++ read_bool_property(node, "rpi,debug", &debug); ++ ++ } ++ else ++ { ++ if (gpio_in_pin >= BCM2708_NR_GPIOS || ++ gpio_out_pin >= BCM2708_NR_GPIOS) { ++ ret = -EINVAL; ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": invalid GPIO pin(s) specified!\n"); ++ goto exit_init_port; ++ } ++ ++ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { ++ printk(KERN_ALERT LIRC_DRIVER_NAME ++ ": cant claim gpio pin %d\n", gpio_out_pin); ++ ret = -ENODEV; ++ goto exit_init_port; ++ } ++ ++ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { ++ printk(KERN_ALERT LIRC_DRIVER_NAME ++ ": cant claim gpio pin %d\n", gpio_in_pin); ++ ret = -ENODEV; ++ goto exit_gpio_free_out_pin; ++ } ++ ++ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); ++ gpiochip->direction_input(gpiochip, gpio_in_pin); ++ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); + } + -+ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); -+ gpiochip->direction_input(gpiochip, gpio_in_pin); -+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); + gpiochip->set(gpiochip, gpio_out_pin, invert); + + irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); @@ -101910,15 +102883,23 @@ index 0000000..8aa452d + .owner = THIS_MODULE, +}; + ++static const struct of_device_id lirc_rpi_of_match[] = { ++ { .compatible = "rpi,lirc-rpi", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, lirc_rpi_of_match); ++ +static struct platform_driver lirc_rpi_driver = { + .driver = { + .name = LIRC_DRIVER_NAME, + .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(lirc_rpi_of_match), + }, +}; + +static int __init lirc_rpi_init(void) +{ ++ struct device_node *node; + int result; + + /* Init read buffer. */ @@ -101933,15 +102914,26 @@ index 0000000..8aa452d + goto exit_buffer_free; + } + -+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); -+ if (!lirc_rpi_dev) { -+ result = -ENOMEM; -+ goto exit_driver_unregister; -+ } ++ node = of_find_compatible_node(NULL, NULL, ++ lirc_rpi_of_match[0].compatible); + -+ result = platform_device_add(lirc_rpi_dev); -+ if (result) -+ goto exit_device_put; ++ if (node) { ++ /* DT-enabled */ ++ lirc_rpi_dev = of_find_device_by_node(node); ++ WARN_ON(lirc_rpi_dev->dev.of_node != node); ++ of_node_put(node); ++ } ++ else { ++ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); ++ if (!lirc_rpi_dev) { ++ result = -ENOMEM; ++ goto exit_driver_unregister; ++ } ++ ++ result = platform_device_add(lirc_rpi_dev); ++ if (result) ++ goto exit_device_put; ++ } + + return 0; + @@ -101973,13 +102965,6 @@ index 0000000..8aa452d + if (result) + return result; + -+ if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) { -+ result = -EINVAL; -+ printk(KERN_ERR LIRC_DRIVER_NAME -+ ": invalid GPIO pin(s) specified!\n"); -+ goto exit_rpi; -+ } -+ + result = init_port(); + if (result < 0) + goto exit_rpi; @@ -102054,40 +103039,29 @@ index 0000000..8aa452d +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Enable debugging messages"); -From 123948742379f19e1c2764020d8c523d445550bf Mon Sep 17 00:00:00 2001 +From b359d4ff9144f1ee3f333eee7b49bab1c6d92c1f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 3 Jul 2013 00:49:20 +0100 -Subject: [PATCH 015/216] Add cpufreq driver +Subject: [PATCH 18/77] Add cpufreq driver +Signed-off-by: popcornmix --- - arch/arm/Kconfig | 1 + - drivers/cpufreq/Kconfig.arm | 8 ++ + drivers/cpufreq/Kconfig.arm | 9 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/bcm2835-cpufreq.c | 224 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 234 insertions(+) - create mode 100755 drivers/cpufreq/bcm2835-cpufreq.c + 3 files changed, 234 insertions(+) + create mode 100644 drivers/cpufreq/bcm2835-cpufreq.c -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index ee1bb5e..9fcd395 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -378,6 +378,7 @@ config ARCH_BCM2708 - select NEED_MACH_GPIO_H - select NEED_MACH_MEMORY_H - select CLKDEV_LOOKUP -+ select ARCH_HAS_CPUFREQ - select GENERIC_CLOCKEVENTS - select ARM_ERRATA_411920 - select MACH_BCM2708 diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm -index 1b06fc4..0b90de8 100644 +index 4f3dbc8..a1039f0 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm -@@ -249,6 +249,14 @@ config ARM_SPEAR_CPUFREQ +@@ -258,6 +258,15 @@ config ARM_SPEAR_CPUFREQ help This adds the CPUFreq driver support for SPEAr SOCs. +config ARM_BCM2835_CPUFREQ ++ depends on BCM2708_MBOX + bool "BCM2835 Driver" + default y + help @@ -102099,10 +103073,10 @@ index 1b06fc4..0b90de8 100644 bool "TEGRA CPUFreq support" depends on ARCH_TEGRA diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 82a1821..50b1954 100644 +index cdce92a..c420f3f 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile -@@ -76,6 +76,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o +@@ -77,6 +77,7 @@ obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o obj-$(CONFIG_ARM_SA1100_CPUFREQ) += sa1100-cpufreq.o obj-$(CONFIG_ARM_SA1110_CPUFREQ) += sa1110-cpufreq.o obj-$(CONFIG_ARM_SPEAR_CPUFREQ) += spear-cpufreq.o @@ -102111,8 +103085,8 @@ index 82a1821..50b1954 100644 obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c -new file mode 100755 -index 0000000..447ca09 +new file mode 100644 +index 0000000..6735da9 --- /dev/null +++ b/drivers/cpufreq/bcm2835-cpufreq.c @@ -0,0 +1,224 @@ @@ -102144,7 +103118,7 @@ index 0000000..447ca09 +#include +#include +#include -+#include ++#include + +/* ---------- DEFINES ---------- */ +/*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ @@ -102341,36 +103315,39 @@ index 0000000..447ca09 +module_init(bcm2835_cpufreq_module_init); +module_exit(bcm2835_cpufreq_module_exit); -From f563316302e117df98e91a8e1366dae653094f04 Mon Sep 17 00:00:00 2001 +From 37e551cc949ea14042539b089e08df475bab0f59 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 26 Mar 2013 19:24:24 +0000 -Subject: [PATCH 016/216] Added hwmon/thermal driver for reporting core +Subject: [PATCH 19/77] Added hwmon/thermal driver for reporting core temperature. Thanks Dorian +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +BCM270x: Move thermal sensor to Device Tree + +Add Device Tree support to bcm2835-thermal driver. +Add thermal sensor device to Device Tree. +Don't add platform device when booting in DT mode. + +Signed-off-by: Noralf Trønnes --- - arch/arm/mach-bcm2708/bcm2708.c | 11 ++ - drivers/hwmon/Kconfig | 10 ++ - drivers/hwmon/Makefile | 1 + - drivers/hwmon/bcm2835-hwmon.c | 219 ++++++++++++++++++++++++++++++++++++++ - drivers/thermal/Kconfig | 6 ++ + arch/arm/mach-bcm2708/bcm2708.c | 6 ++ + arch/arm/mach-bcm2709/bcm2709.c | 6 ++ + drivers/thermal/Kconfig | 7 ++ drivers/thermal/Makefile | 1 + - drivers/thermal/bcm2835-thermal.c | 184 ++++++++++++++++++++++++++++++++ - 7 files changed, 432 insertions(+) - create mode 100644 drivers/hwmon/bcm2835-hwmon.c + drivers/thermal/bcm2835-thermal.c | 190 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 210 insertions(+) create mode 100644 drivers/thermal/bcm2835-thermal.c diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index f54e3e9b..bae8ba5 100644 +index 86011af..f2d9b03 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -499,6 +499,14 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -505,6 +505,10 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; -+static struct platform_device bcm2835_hwmon_device = { -+ .name = "bcm2835_hwmon", -+}; -+ +static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", +}; @@ -102378,283 +103355,49 @@ index f54e3e9b..bae8ba5 100644 int __init bcm_register_device(struct platform_device *pdev) { int ret; -@@ -611,6 +619,9 @@ void __init bcm2708_init(void) +@@ -651,6 +655,8 @@ void __init bcm2708_init(void) for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device(&bcm2708_alsa_devices[i]); + bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ bcm_register_device(&bcm2835_hwmon_device); -+ bcm_register_device(&bcm2835_thermal_device); ++ bcm_register_device_dt(&bcm2835_thermal_device); + - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 110fade..8c4474d 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -1703,6 +1703,16 @@ config SENSORS_ULTRA45 - This driver provides support for the Ultra45 workstation environmental - sensors. + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index bc1ee1c..9631bdb 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -525,6 +525,10 @@ static struct platform_device bcm2708_alsa_devices[] = { + }, + }; -+config SENSORS_BCM2835 -+ depends on THERMAL_BCM2835=n -+ tristate "Broadcom BCM2835 HWMON Driver" -+ help -+ If you say yes here you get support for the hardware -+ monitoring features of the BCM2835 Chip ++static struct platform_device bcm2835_thermal_device = { ++ .name = "bcm2835_thermal", ++}; + -+ This driver can also be built as a module. If so, the module -+ will be called bcm2835-hwmon. -+ - if ACPI + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -671,6 +675,8 @@ void __init bcm2709_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device_dt(&bcm2708_alsa_devices[i]); - comment "ACPI drivers" -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index 6c94147..e7c60cb 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -155,6 +155,7 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o - obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o - obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o - obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o -+obj-$(CONFIG_SENSORS_BCM2835) += bcm2835-hwmon.o - - obj-$(CONFIG_PMBUS) += pmbus/ - -diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c -new file mode 100644 -index 0000000..5bbed45 ---- /dev/null -+++ b/drivers/hwmon/bcm2835-hwmon.c -@@ -0,0 +1,219 @@ -+/***************************************************************************** -+* 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. -+*****************************************************************************/ ++ bcm_register_device_dt(&bcm2835_thermal_device); + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MODULE_NAME "bcm2835_hwmon" -+ -+/*#define HWMON_DEBUG_ENABLE*/ -+ -+#ifdef HWMON_DEBUG_ENABLE -+#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) -+#else -+#define print_debug(fmt,...) -+#endif -+#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) -+#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__) -+ -+#define VC_TAG_GET_TEMP 0x00030006 -+#define VC_TAG_GET_MAX_TEMP 0x0003000A -+ -+/* --- STRUCTS --- */ -+struct bcm2835_hwmon_data { -+ struct device *hwmon_dev; -+}; -+ -+/* tag part of the message */ -+struct vc_msg_tag { -+ uint32_t tag_id; /* the tag ID for the temperature */ -+ uint32_t buffer_size; /* size of the buffer (should be 8) */ -+ uint32_t request_code; /* identifies message as a request (should be 0) */ -+ uint32_t id; /* extra ID field (should be 0) */ -+ uint32_t val; /* returned value of the temperature */ -+}; -+ -+/* message structure to be sent to videocore */ -+struct vc_msg { -+ uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -+ uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -+ struct vc_msg_tag tag; /* the tag structure above to make */ -+ uint32_t end_tag; /* an end identifier, should be set to NULL */ -+}; -+ -+typedef enum { -+ TEMP, -+ MAX_TEMP, -+} temp_type; -+ -+/* --- PROTOTYPES --- */ -+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf); -+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf); -+ -+/* --- GLOBALS --- */ -+ -+static struct bcm2835_hwmon_data *bcm2835_data; -+static struct platform_driver bcm2835_hwmon_driver; -+ -+static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0); -+static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP); -+static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP); -+ -+static struct attribute* bcm2835_attributes[] = { -+ &sensor_dev_attr_name.dev_attr.attr, -+ &sensor_dev_attr_temp1_input.dev_attr.attr, -+ &sensor_dev_attr_temp1_max.dev_attr.attr, -+ NULL, -+}; -+ -+static struct attribute_group bcm2835_attr_group = { -+ .attrs = bcm2835_attributes, -+}; -+ -+/* --- FUNCTIONS --- */ -+ -+static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf,"bcm2835_hwmon\n"); -+} -+ -+static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct vc_msg msg; -+ int result; -+ uint temp = 0; -+ int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index; -+ -+ print_debug("IN"); -+ -+ /* wipe all previous message data */ -+ memset(&msg, 0, sizeof msg); -+ -+ /* determine the message type */ -+ if(index == TEMP) -+ msg.tag.tag_id = VC_TAG_GET_TEMP; -+ else if (index == MAX_TEMP) -+ msg.tag.tag_id = VC_TAG_GET_MAX_TEMP; -+ else -+ { -+ print_debug("Unknown temperature message!"); -+ return -EINVAL; -+ } -+ -+ msg.msg_size = sizeof msg; -+ msg.tag.buffer_size = 8; -+ -+ /* send the message */ -+ result = bcm_mailbox_property(&msg, sizeof msg); -+ -+ /* check if it was all ok and return the rate in milli degrees C */ -+ if (result == 0 && (msg.request_code & 0x80000000)) -+ temp = (uint)msg.tag.val; -+ #ifdef HWMON_DEBUG_ENABLE -+ else -+ print_debug("Failed to get temperature!"); -+ #endif -+ print_debug("Got temperature as %u",temp); -+ print_debug("OUT"); -+ return sprintf(buf, "%u\n", temp); -+} -+ -+ -+static int bcm2835_hwmon_probe(struct platform_device *pdev) -+{ -+ int err; -+ -+ print_debug("IN"); -+ print_debug("HWMON Driver has been probed!"); -+ -+ /* check that the device isn't null!*/ -+ if(pdev == NULL) -+ { -+ print_debug("Platform device is empty!"); -+ return -ENODEV; -+ } -+ -+ /* allocate memory for neccessary data */ -+ bcm2835_data = kzalloc(sizeof(struct bcm2835_hwmon_data),GFP_KERNEL); -+ if(!bcm2835_data) -+ { -+ print_debug("Unable to allocate memory for hwmon data!"); -+ err = -ENOMEM; -+ goto kzalloc_error; -+ } -+ -+ /* create the sysfs files */ -+ if(sysfs_create_group(&pdev->dev.kobj, &bcm2835_attr_group)) -+ { -+ print_debug("Unable to create sysfs files!"); -+ err = -EFAULT; -+ goto sysfs_error; -+ } -+ -+ /* register the hwmon device */ -+ bcm2835_data->hwmon_dev = hwmon_device_register(&pdev->dev); -+ if (IS_ERR(bcm2835_data->hwmon_dev)) -+ { -+ err = PTR_ERR(bcm2835_data->hwmon_dev); -+ goto hwmon_error; -+ } -+ print_debug("OUT"); -+ return 0; -+ -+ /* error goto's */ -+ hwmon_error: -+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -+ -+ sysfs_error: -+ kfree(bcm2835_data); -+ -+ kzalloc_error: -+ -+ return err; -+ -+} -+ -+static int bcm2835_hwmon_remove(struct platform_device *pdev) -+{ -+ print_debug("IN"); -+ hwmon_device_unregister(bcm2835_data->hwmon_dev); -+ -+ sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -+ print_debug("OUT"); -+ return 0; -+} -+ -+/* Hwmon Driver */ -+static struct platform_driver bcm2835_hwmon_driver = { -+ .probe = bcm2835_hwmon_probe, -+ .remove = bcm2835_hwmon_remove, -+ .driver = { -+ .name = "bcm2835_hwmon", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Dorian Peake"); -+MODULE_DESCRIPTION("HW Monitor driver for bcm2835 chip"); -+ -+module_platform_driver(bcm2835_hwmon_driver); + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig -index af40db0..4584b1e 100644 +index af40db0..ddc77ad 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig -@@ -238,6 +238,12 @@ config INTEL_POWERCLAMP +@@ -238,6 +238,13 @@ config INTEL_POWERCLAMP enforce idle time which results in more package C-state residency. The user interface is exposed via generic thermal framework. +config THERMAL_BCM2835 ++ depends on BCM2708_MBOX + tristate "BCM2835 Thermal Driver" + help + This will enable temperature monitoring for the Broadcom BCM2835 @@ -102677,10 +103420,10 @@ index fa0dc48..453d4d9 100644 obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c new file mode 100644 -index 0000000..85fceb5 +index 0000000..3bc80f1 --- /dev/null +++ b/drivers/thermal/bcm2835-thermal.c -@@ -0,0 +1,184 @@ +@@ -0,0 +1,190 @@ +/***************************************************************************** +* Copyright 2011 Broadcom Corporation. All rights reserved. +* @@ -102698,10 +103441,10 @@ index 0000000..85fceb5 +#include +#include +#include ++#include +#include +#include +#include -+#include +#include + + @@ -102850,13 +103593,19 @@ index 0000000..85fceb5 + .get_mode = bcm2835_get_mode, +}; + -+/* Thermal Driver */ ++static const struct of_device_id bcm2835_thermal_of_match_table[] = { ++ { .compatible = "brcm,bcm2835-thermal", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); ++ +static struct platform_driver bcm2835_thermal_driver = { + .probe = bcm2835_thermal_probe, + .remove = bcm2835_thermal_remove, + .driver = { + .name = "bcm2835_thermal", + .owner = THIS_MODULE, ++ .of_match_table = bcm2835_thermal_of_match_table, + }, +}; + @@ -102866,49 +103615,58 @@ index 0000000..85fceb5 + +module_platform_driver(bcm2835_thermal_driver); -From bb1c2fec8850e0e017e3b80f51df5dc850627555 Mon Sep 17 00:00:00 2001 +From 4d5da3fa21e1d94e38644bf9a5493bb677854e42 Mon Sep 17 00:00:00 2001 From: popcornmix -Date: Mon, 4 Nov 2013 18:56:10 +0000 -Subject: [PATCH 017/216] Add Chris Boot's i2c and spi drivers. +Date: Wed, 17 Jun 2015 15:41:33 +0100 +Subject: [PATCH 20/77] Add Chris Boot's spi driver. -i2c-bcm2708: fixed baudrate +spi: bcm2708: add device tree support -Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock). -In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits. -This resulted in incorrect setting of CDIV and higher baudrate than intended. -Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz -After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz -The correct baudrate is shown in the log after the cdiv > 0xffff correction. +Add DT support to driver and add to .dtsi file. +Setup pins and spidev in .dts file. +SPI is disabled by default. -Perform I2C combined transactions when possible +Signed-off-by: Noralf Tronnes -Perform I2C combined transactions whenever possible, within the -restrictions of the Broadcomm Serial Controller. +BCM2708: don't register SPI controller when using DT -Disable DONE interrupt during TA poll +The device for the SPI controller is in the Device Tree. +Only register the device when not using DT. -Prevent interrupt from being triggered if poll is missed and transfer -starts and finishes. +Signed-off-by: Noralf Tronnes -i2c: Make combined transactions optional and disabled by default +spi: bcm2835: make driver available on ARCH_BCM2708 + +Make this driver available on ARCH_BCM2708 + +Signed-off-by: Noralf Tronnes + +bcm2708: Remove the prohibition on mixing SPIDEV and DT + +spi-bcm2708: Prepare for Common Clock Framework migration + +As part of migrating to use the Common Clock Framework, replace clk_enable() +with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). +This does not affect behaviour under the current clock implementation. + +Also add a missing clk_disable_unprepare() in the probe error path. + +Signed-off-by: Noralf Tronnes --- - arch/arm/mach-bcm2708/Kconfig | 7 + - arch/arm/mach-bcm2708/bcm2708.c | 104 ++++++- - drivers/i2c/busses/Kconfig | 19 ++ - drivers/i2c/busses/Makefile | 2 + - drivers/i2c/busses/i2c-bcm2708.c | 449 ++++++++++++++++++++++++++++ - drivers/spi/Kconfig | 8 + - drivers/spi/Makefile | 1 + - drivers/spi/spi-bcm2708.c | 626 +++++++++++++++++++++++++++++++++++++++ - 8 files changed, 1214 insertions(+), 2 deletions(-) - create mode 100644 drivers/i2c/busses/i2c-bcm2708.c + arch/arm/mach-bcm2708/Kconfig | 7 + + arch/arm/mach-bcm2708/bcm2708.c | 53 ++++ + arch/arm/mach-bcm2709/bcm2709.c | 53 ++++ + drivers/spi/Kconfig | 10 +- + drivers/spi/Makefile | 1 + + drivers/spi/spi-bcm2708.c | 635 ++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 758 insertions(+), 1 deletion(-) create mode 100644 drivers/spi/spi-bcm2708.c diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 9355841..e151ed4 100644 +index 4cbda0c..68e3706 100644 --- a/arch/arm/mach-bcm2708/Kconfig +++ b/arch/arm/mach-bcm2708/Kconfig -@@ -31,4 +31,11 @@ config BCM2708_NOL2CACHE +@@ -35,4 +35,11 @@ config BCM2708_NOL2CACHE help Do not allow ARM to use GPU's L2 cache. Requires disable_l2cache in config.txt. @@ -102921,50 +103679,18 @@ index 9355841..e151ed4 100644 + Binds spidev driver to the SPI0 master endmenu diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index bae8ba5..752dd46 100644 +index f2d9b03..e3aa6fc 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -31,6 +31,7 @@ - #include +@@ -34,6 +34,7 @@ #include #include + #include +#include + #include #include - #include -@@ -205,7 +206,6 @@ static struct clk osc_clk = { - - /* warning - the USB needs a clock > 34MHz */ - --#ifdef CONFIG_MMC_BCM2708 - static struct clk sdhost_clk = { - #ifdef CONFIG_ARCH_BCM2708_CHIPIT - .rate = 4000000, /* 4MHz */ -@@ -213,7 +213,6 @@ static struct clk sdhost_clk = { - .rate = 250000000, /* 250MHz */ - #endif - }; --#endif - - static struct clk_lookup lookups[] = { - { /* UART0 */ -@@ -223,6 +222,15 @@ static struct clk_lookup lookups[] = { - { /* USB */ - .dev_id = "bcm2708_usb", - .clk = &osc_clk, -+ }, { /* SPI */ -+ .dev_id = "bcm2708_spi.0", -+ .clk = &sdhost_clk, -+ }, { /* BSC0 */ -+ .dev_id = "bcm2708_i2c.0", -+ .clk = &sdhost_clk, -+ }, { /* BSC1 */ -+ .dev_id = "bcm2708_i2c.1", -+ .clk = &sdhost_clk, - } - }; - -@@ -499,6 +507,89 @@ static struct platform_device bcm2708_alsa_devices[] = { +@@ -505,6 +506,50 @@ static struct platform_device bcm2708_alsa_devices[] = { }, }; @@ -103012,580 +103738,136 @@ index bae8ba5..752dd46 100644 +}; +#endif + -+static struct resource bcm2708_bsc0_resources[] = { -+ { -+ .start = BSC0_BASE, -+ .end = BSC0_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc0_device = { -+ .name = "bcm2708_i2c", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), -+ .resource = bcm2708_bsc0_resources, -+}; -+ -+ -+static struct resource bcm2708_bsc1_resources[] = { -+ { -+ .start = BSC1_BASE, -+ .end = BSC1_BASE + SZ_256 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = INTERRUPT_I2C, -+ .end = INTERRUPT_I2C, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static struct platform_device bcm2708_bsc1_device = { -+ .name = "bcm2708_i2c", -+ .id = 1, -+ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), -+ .resource = bcm2708_bsc1_resources, -+}; -+ - static struct platform_device bcm2835_hwmon_device = { - .name = "bcm2835_hwmon", + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", }; -@@ -619,6 +710,10 @@ void __init bcm2708_init(void) +@@ -655,6 +700,8 @@ void __init bcm2708_init(void) for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device(&bcm2708_alsa_devices[i]); + bcm_register_device_dt(&bcm2708_alsa_devices[i]); -+ bcm_register_device(&bcm2708_spi_device); -+ bcm_register_device(&bcm2708_bsc0_device); -+ bcm_register_device(&bcm2708_bsc1_device); ++ bcm_register_device_dt(&bcm2708_spi_device); + - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); + bcm_register_device_dt(&bcm2835_thermal_device); -@@ -628,6 +723,11 @@ void __init bcm2708_init(void) + if (!use_dt) { +@@ -665,6 +712,12 @@ void __init bcm2708_init(void) } system_rev = boardrev; system_serial_low = serial; + +#ifdef CONFIG_BCM2708_SPIDEV -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); ++ if (!use_dt) ++ spi_register_board_info(bcm2708_spi_devices, ++ ARRAY_SIZE(bcm2708_spi_devices)); +#endif } static void timer_set_mode(enum clock_event_mode mode, -diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 22da9c2..00c7baa 100644 ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" - comment "PC SMBus host controller drivers" - depends on PCI +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 9631bdb..5fb99b6 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include -+config I2C_BCM2708 -+ tristate "BCM2708 BSC" -+ depends on MACH_BCM2708 -+ help -+ Enabling this option will add BSC (Broadcom Serial Controller) -+ support for the BCM2708. BSC is a Broadcom proprietary bus compatible -+ with I2C/TWI/SMBus. -+ -+config I2C_BCM2708_BAUDRATE -+ prompt "BCM2708 I2C baudrate" -+ depends on I2C_BCM2708 -+ int -+ default 100000 -+ help -+ Set the I2C baudrate. This will alter the default value. A -+ different baudrate can be set by using a module parameter as well. If -+ no parameter is provided when loading, this is the value that will be -+ used. -+ - config I2C_ALI1535 - tristate "ALI 1535" - depends on PCI -diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile -index 3638feb..4905fae 100644 ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -2,6 +2,8 @@ - # Makefile for the i2c bus drivers. - # + #include +@@ -525,6 +526,50 @@ static struct platform_device bcm2708_alsa_devices[] = { + }, + }; -+obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o -+ - # ACPI drivers - obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -new file mode 100644 -index 0000000..7d385a3 ---- /dev/null -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -0,0 +1,449 @@ -+/* -+ * Driver for Broadcom BCM2708 BSC Controllers -+ * -+ * Copyright (C) 2012 Chris Boot & Frank Buss -+ * -+ * This driver is inspired by: -+ * i2c-ocores.c, by Peter Korsgaard -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* BSC register offsets */ -+#define BSC_C 0x00 -+#define BSC_S 0x04 -+#define BSC_DLEN 0x08 -+#define BSC_A 0x0c -+#define BSC_FIFO 0x10 -+#define BSC_DIV 0x14 -+#define BSC_DEL 0x18 -+#define BSC_CLKT 0x1c -+ -+/* Bitfields in BSC_C */ -+#define BSC_C_I2CEN 0x00008000 -+#define BSC_C_INTR 0x00000400 -+#define BSC_C_INTT 0x00000200 -+#define BSC_C_INTD 0x00000100 -+#define BSC_C_ST 0x00000080 -+#define BSC_C_CLEAR_1 0x00000020 -+#define BSC_C_CLEAR_2 0x00000010 -+#define BSC_C_READ 0x00000001 -+ -+/* Bitfields in BSC_S */ -+#define BSC_S_CLKT 0x00000200 -+#define BSC_S_ERR 0x00000100 -+#define BSC_S_RXF 0x00000080 -+#define BSC_S_TXE 0x00000040 -+#define BSC_S_RXD 0x00000020 -+#define BSC_S_TXD 0x00000010 -+#define BSC_S_RXR 0x00000008 -+#define BSC_S_TXW 0x00000004 -+#define BSC_S_DONE 0x00000002 -+#define BSC_S_TA 0x00000001 -+ -+#define I2C_TIMEOUT_MS 150 -+ -+#define DRV_NAME "bcm2708_i2c" -+ -+static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; -+module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+MODULE_PARM_DESC(baudrate, "The I2C baudrate"); -+ -+static bool combined = false; -+module_param(combined, bool, 0644); -+MODULE_PARM_DESC(combined, "Use combined transactions"); -+ -+struct bcm2708_i2c { -+ struct i2c_adapter adapter; -+ -+ spinlock_t lock; -+ void __iomem *base; -+ int irq; -+ struct clk *clk; -+ -+ struct completion done; -+ -+ struct i2c_msg *msg; -+ int pos; -+ int nmsgs; -+ bool error; -+}; -+ -+/* -+ * This function sets the ALT mode on the I2C pins so that we can use them with -+ * the BSC hardware. -+ * -+ * FIXME: This is a hack. Use pinmux / pinctrl. -+ */ -+static void bcm2708_i2c_init_pinmode(int id) -+{ -+#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) -+#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) -+ -+ int pin; -+ u32 *gpio = ioremap(GPIO_BASE, SZ_16K); -+ -+ BUG_ON(id != 0 && id != 1); -+ /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */ -+ for (pin = id*2+0; pin <= id*2+1; pin++) { -+printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); -+ INP_GPIO(pin); /* set mode to GPIO input first */ -+ SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */ -+ } -+ -+ iounmap(gpio); -+ -+#undef INP_GPIO -+#undef SET_GPIO_ALT -+} -+ -+static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) -+{ -+ return readl(bi->base + reg); -+} -+ -+static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val) -+{ -+ writel(val, bi->base + reg); -+} -+ -+static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi) -+{ -+ bcm2708_wr(bi, BSC_C, 0); -+ bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE); -+} -+ -+static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi) -+{ -+ while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len)) -+ bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO); -+} -+ -+static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) -+{ -+ while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len)) -+ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); -+} -+ -+static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) -+{ -+ unsigned long bus_hz; -+ u32 cdiv, s; -+ u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; -+ -+ bus_hz = clk_get_rate(bi->clk); -+ cdiv = bus_hz / baudrate; -+ if (cdiv > 0xffff) -+ cdiv = 0xffff; -+ -+ if (bi->msg->flags & I2C_M_RD) -+ c |= BSC_C_INTR | BSC_C_READ; -+ else -+ c |= BSC_C_INTT; -+ -+ bcm2708_wr(bi, BSC_DIV, cdiv); -+ bcm2708_wr(bi, BSC_A, bi->msg->addr); -+ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); -+ if (combined) ++static struct resource bcm2708_spi_resources[] = { + { -+ /* Do the next two messages meet combined transaction criteria? -+ - Current message is a write, next message is a read -+ - Both messages to same slave address -+ - Write message can fit inside FIFO (16 bytes or less) */ -+ if ( (bi->nmsgs > 1) && -+ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && -+ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { -+ /* Fill FIFO with entire write message (16 byte FIFO) */ -+ while (bi->pos < bi->msg->len) -+ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); -+ /* Start write transfer (no interrupts, don't clear FIFO) */ -+ bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); -+ /* poll for transfer start bit (should only take 1-20 polls) */ -+ do { -+ s = bcm2708_rd(bi, BSC_S); -+ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE))); -+ /* Send next read message before the write transfer finishes. */ -+ bi->nmsgs--; -+ bi->msg++; -+ bi->pos = 0; -+ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); -+ c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ; -+ } ++ .start = SPI0_BASE, ++ .end = SPI0_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = IRQ_SPI, ++ .end = IRQ_SPI, ++ .flags = IORESOURCE_IRQ, + } -+ bcm2708_wr(bi, BSC_C, c); -+} -+ -+static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) -+{ -+ struct bcm2708_i2c *bi = dev_id; -+ bool handled = true; -+ u32 s; -+ -+ spin_lock(&bi->lock); -+ -+ /* we may see camera interrupts on the "other" I2C channel -+ Just return if we've not sent anything */ -+ if (!bi->nmsgs || !bi->msg ) -+ goto early_exit; -+ -+ s = bcm2708_rd(bi, BSC_S); -+ -+ if (s & (BSC_S_CLKT | BSC_S_ERR)) { -+ bcm2708_bsc_reset(bi); -+ bi->error = true; -+ -+ /* wake up our bh */ -+ complete(&bi->done); -+ } else if (s & BSC_S_DONE) { -+ bi->nmsgs--; -+ -+ if (bi->msg->flags & I2C_M_RD) -+ bcm2708_bsc_fifo_drain(bi); -+ -+ bcm2708_bsc_reset(bi); -+ -+ if (bi->nmsgs) { -+ /* advance to next message */ -+ bi->msg++; -+ bi->pos = 0; -+ bcm2708_bsc_setup(bi); -+ } else { -+ /* wake up our bh */ -+ complete(&bi->done); -+ } -+ } else if (s & BSC_S_TXW) { -+ bcm2708_bsc_fifo_fill(bi); -+ } else if (s & BSC_S_RXR) { -+ bcm2708_bsc_fifo_drain(bi); -+ } else { -+ handled = false; -+ } -+ -+early_exit: -+ spin_unlock(&bi->lock); -+ -+ return handled ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, -+ struct i2c_msg *msgs, int num) -+{ -+ struct bcm2708_i2c *bi = adap->algo_data; -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&bi->lock, flags); -+ -+ reinit_completion(&bi->done); -+ bi->msg = msgs; -+ bi->pos = 0; -+ bi->nmsgs = num; -+ bi->error = false; -+ -+ bcm2708_bsc_setup(bi); -+ -+ /* unlockig _after_ the setup to avoid races with the interrupt routine */ -+ spin_unlock_irqrestore(&bi->lock, flags); -+ -+ ret = wait_for_completion_timeout(&bi->done, -+ msecs_to_jiffies(I2C_TIMEOUT_MS)); -+ if (ret == 0) { -+ dev_err(&adap->dev, "transfer timed out\n"); -+ spin_lock_irqsave(&bi->lock, flags); -+ bcm2708_bsc_reset(bi); -+ spin_unlock_irqrestore(&bi->lock, flags); -+ return -ETIMEDOUT; -+ } -+ -+ return bi->error ? -EIO : num; -+} -+ -+static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) -+{ -+ return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL; -+} -+ -+static struct i2c_algorithm bcm2708_i2c_algorithm = { -+ .master_xfer = bcm2708_i2c_master_xfer, -+ .functionality = bcm2708_i2c_functionality, +}; + -+static int bcm2708_i2c_probe(struct platform_device *pdev) -+{ -+ struct resource *regs; -+ int irq, err = -ENOMEM; -+ struct clk *clk; -+ struct bcm2708_i2c *bi; -+ struct i2c_adapter *adap; -+ unsigned long bus_hz; -+ u32 cdiv; + -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) { -+ dev_err(&pdev->dev, "could not get IO memory\n"); -+ return -ENXIO; -+ } -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_err(&pdev->dev, "could not get IRQ\n"); -+ return irq; -+ } -+ -+ clk = clk_get(&pdev->dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk)); -+ return PTR_ERR(clk); -+ } -+ -+ bcm2708_i2c_init_pinmode(pdev->id); -+ -+ bi = kzalloc(sizeof(*bi), GFP_KERNEL); -+ if (!bi) -+ goto out_clk_put; -+ -+ platform_set_drvdata(pdev, bi); -+ -+ adap = &bi->adapter; -+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC; -+ adap->algo = &bcm2708_i2c_algorithm; -+ adap->algo_data = bi; -+ adap->dev.parent = &pdev->dev; -+ adap->nr = pdev->id; -+ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ -+ switch (pdev->id) { -+ case 0: -+ adap->class = I2C_CLASS_HWMON; -+ break; -+ case 1: -+ adap->class = I2C_CLASS_DDC; -+ break; -+ default: -+ dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); -+ err = -ENXIO; -+ goto out_free_bi; -+ } -+ -+ spin_lock_init(&bi->lock); -+ init_completion(&bi->done); -+ -+ bi->base = ioremap(regs->start, resource_size(regs)); -+ if (!bi->base) { -+ dev_err(&pdev->dev, "could not remap memory\n"); -+ goto out_free_bi; -+ } -+ -+ bi->irq = irq; -+ bi->clk = clk; -+ -+ err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED, -+ dev_name(&pdev->dev), bi); -+ if (err) { -+ dev_err(&pdev->dev, "could not request IRQ: %d\n", err); -+ goto out_iounmap; -+ } -+ -+ bcm2708_bsc_reset(bi); -+ -+ err = i2c_add_numbered_adapter(adap); -+ if (err < 0) { -+ dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err); -+ goto out_free_irq; -+ } -+ -+ bus_hz = clk_get_rate(bi->clk); -+ cdiv = bus_hz / baudrate; -+ if (cdiv > 0xffff) { -+ cdiv = 0xffff; -+ baudrate = bus_hz / cdiv; -+ } -+ -+ dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", -+ pdev->id, (unsigned long)regs->start, irq, baudrate); -+ -+ return 0; -+ -+out_free_irq: -+ free_irq(bi->irq, bi); -+out_iounmap: -+ iounmap(bi->base); -+out_free_bi: -+ kfree(bi); -+out_clk_put: -+ clk_put(clk); -+ return err; -+} -+ -+static int bcm2708_i2c_remove(struct platform_device *pdev) -+{ -+ struct bcm2708_i2c *bi = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ i2c_del_adapter(&bi->adapter); -+ free_irq(bi->irq, bi); -+ iounmap(bi->base); -+ clk_disable(bi->clk); -+ clk_put(bi->clk); -+ kfree(bi); -+ -+ return 0; -+} -+ -+static struct platform_driver bcm2708_i2c_driver = { -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = bcm2708_i2c_probe, -+ .remove = bcm2708_i2c_remove, ++static u64 bcm2708_spi_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); ++static struct platform_device bcm2708_spi_device = { ++ .name = "bcm2708_spi", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_spi_resources), ++ .resource = bcm2708_spi_resources, ++ .dev = { ++ .dma_mask = &bcm2708_spi_dmamask, ++ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON)}, +}; + -+// module_platform_driver(bcm2708_i2c_driver); ++#ifdef CONFIG_BCM2708_SPIDEV ++static struct spi_board_info bcm2708_spi_devices[] = { ++#ifdef CONFIG_SPI_SPIDEV ++ { ++ .modalias = "spidev", ++ .max_speed_hz = 500000, ++ .bus_num = 0, ++ .chip_select = 0, ++ .mode = SPI_MODE_0, ++ }, { ++ .modalias = "spidev", ++ .max_speed_hz = 500000, ++ .bus_num = 0, ++ .chip_select = 1, ++ .mode = SPI_MODE_0, ++ } ++#endif ++}; ++#endif + + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; +@@ -675,6 +720,8 @@ void __init bcm2709_init(void) + for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) + bcm_register_device_dt(&bcm2708_alsa_devices[i]); + ++ bcm_register_device_dt(&bcm2708_spi_device); + -+static int __init bcm2708_i2c_init(void) -+{ -+ return platform_driver_register(&bcm2708_i2c_driver); -+} + bcm_register_device_dt(&bcm2835_thermal_device); + + if (!use_dt) { +@@ -685,6 +732,12 @@ void __init bcm2709_init(void) + } + system_rev = boardrev; + system_serial_low = serial; + -+static void __exit bcm2708_i2c_exit(void) -+{ -+ platform_driver_unregister(&bcm2708_i2c_driver); -+} -+ -+module_init(bcm2708_i2c_init); -+module_exit(bcm2708_i2c_exit); -+ -+ -+ -+MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708"); -+MODULE_AUTHOR("Chris Boot "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS("platform:" DRV_NAME); ++#ifdef CONFIG_BCM2708_SPIDEV ++ if (!use_dt) ++ spi_register_board_info(bcm2708_spi_devices, ++ ARRAY_SIZE(bcm2708_spi_devices)); ++#endif + } + + #ifdef SYSTEM_TIMER diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index ab8dfbe..9628e75 100644 +index 72b0590..ea5e5de 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -86,6 +86,14 @@ config SPI_BCM2835 +@@ -77,7 +77,7 @@ config SPI_ATMEL + + config SPI_BCM2835 + tristate "BCM2835 SPI controller" +- depends on ARCH_BCM2835 || COMPILE_TEST ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST + depends on GPIOLIB + help + This selects a driver for the Broadcom BCM2835 SPI master. +@@ -87,6 +87,14 @@ config SPI_BCM2835 is for the regular SPI controller. Slave mode operation is not also not supported. +config SPI_BCM2708 + tristate "BCM2708 SPI controller driver (SPI0)" -+ depends on MACH_BCM2708 ++ depends on MACH_BCM2708 || MACH_BCM2709 + help + This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This + driver is not compatible with the "Universal SPI Master" or the SPI slave @@ -103608,10 +103890,10 @@ index d8cbf65..0dcd03d 100644 obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c new file mode 100644 -index 0000000..b04a57d +index 0000000..041b5e2 --- /dev/null +++ b/drivers/spi/spi-bcm2708.c -@@ -0,0 +1,626 @@ +@@ -0,0 +1,635 @@ +/* + * Driver for Broadcom BCM2708 SPI Controllers + * @@ -104126,6 +104408,7 @@ index 0000000..b04a57d + master->setup = bcm2708_spi_setup; + master->transfer = bcm2708_spi_transfer; + master->cleanup = bcm2708_spi_cleanup; ++ master->dev.of_node = pdev->dev.of_node; + platform_set_drvdata(pdev, master); + + bs = spi_master_get_devdata(master); @@ -104159,7 +104442,7 @@ index 0000000..b04a57d + } + + /* initialise the hardware */ -+ clk_enable(clk); ++ clk_prepare_enable(clk); + bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX); + + err = spi_register_master(master); @@ -104175,6 +104458,7 @@ index 0000000..b04a57d + +out_free_irq: + free_irq(bs->irq, master); ++ clk_disable_unprepare(bs->clk); +out_workqueue: + destroy_workqueue(bs->workq); +out_iounmap: @@ -104199,7 +104483,7 @@ index 0000000..b04a57d + + flush_work(&bs->work); + -+ clk_disable(bs->clk); ++ clk_disable_unprepare(bs->clk); + clk_put(bs->clk); + free_irq(bs->irq, master); + iounmap(bs->base); @@ -104209,10 +104493,17 @@ index 0000000..b04a57d + return 0; +} + ++static const struct of_device_id bcm2708_spi_match[] = { ++ { .compatible = "brcm,bcm2708-spi", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_spi_match); ++ +static struct platform_driver bcm2708_spi_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, ++ .of_match_table = bcm2708_spi_match, + }, + .probe = bcm2708_spi_probe, + .remove = bcm2708_spi_remove, @@ -104239,10 +104530,814 @@ index 0000000..b04a57d +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRV_NAME); -From 530db15891390005623b20a03dda6ef6871607bc Mon Sep 17 00:00:00 2001 +From 75d6625177ee7e4746baf70b60380069d58231ba Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 17 Jun 2015 15:44:08 +0100 +Subject: [PATCH 21/77] Add Chris Boot's i2c driver + +i2c-bcm2708: fixed baudrate + +Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock). +In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits. +This resulted in incorrect setting of CDIV and higher baudrate than intended. +Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz +After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz +The correct baudrate is shown in the log after the cdiv > 0xffff correction. + +Perform I2C combined transactions when possible + +Perform I2C combined transactions whenever possible, within the +restrictions of the Broadcomm Serial Controller. + +Disable DONE interrupt during TA poll + +Prevent interrupt from being triggered if poll is missed and transfer +starts and finishes. + +i2c: Make combined transactions optional and disabled by default + +i2c: bcm2708: add device tree support + +Add DT support to driver and add to .dtsi file. +Setup pins in .dts file. +i2c is disabled by default. + +Signed-off-by: Noralf Tronnes + +bcm2708: don't register i2c controllers when using DT + +The devices for the i2c controllers are in the Device Tree. +Only register devices when not using DT. + +Signed-off-by: Noralf Tronnes + +I2C: Only register the I2C device for the current board revision + +i2c_bcm2708: Fix clock reference counting + +Fix grabbing lock from atomic context in i2c driver + +2 main changes: +- check for timeouts in the bcm2708_bsc_setup function as indicated by this comment: + /* poll for transfer start bit (should only take 1-20 polls) */ + This implies that the setup function can now fail so account for this everywhere it's called +- Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock. + +i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl +--- + arch/arm/mach-bcm2708/bcm2708.c | 51 ++++ + arch/arm/mach-bcm2709/bcm2709.c | 51 ++++ + drivers/i2c/busses/Kconfig | 21 +- + drivers/i2c/busses/Makefile | 2 + + drivers/i2c/busses/i2c-bcm2708.c | 522 +++++++++++++++++++++++++++++++++++++++ + 5 files changed, 646 insertions(+), 1 deletion(-) + create mode 100644 drivers/i2c/busses/i2c-bcm2708.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index e3aa6fc..efb3544 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -83,6 +83,7 @@ static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static bool vc_i2c_override = false; + + static unsigned use_dt = 0; + +@@ -550,6 +551,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { + }; + #endif + ++static struct resource bcm2708_bsc0_resources[] = { ++ { ++ .start = BSC0_BASE, ++ .end = BSC0_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc0_device = { ++ .name = "bcm2708_i2c", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), ++ .resource = bcm2708_bsc0_resources, ++}; ++ ++ ++static struct resource bcm2708_bsc1_resources[] = { ++ { ++ .start = BSC1_BASE, ++ .end = BSC1_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc1_device = { ++ .name = "bcm2708_i2c", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), ++ .resource = bcm2708_bsc1_resources, ++}; ++ + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; +@@ -702,6 +742,15 @@ void __init bcm2708_init(void) + + bcm_register_device_dt(&bcm2708_spi_device); + ++ if (vc_i2c_override) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ } else { ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } ++ + bcm_register_device_dt(&bcm2835_thermal_device); + + if (!use_dt) { +@@ -893,3 +942,5 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(vc_i2c_override, bool, 0644); ++MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 5fb99b6..8017c50 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -85,6 +85,7 @@ static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static bool vc_i2c_override = false; + + static unsigned use_dt = 0; + +@@ -570,6 +571,45 @@ static struct spi_board_info bcm2708_spi_devices[] = { + }; + #endif + ++static struct resource bcm2708_bsc0_resources[] = { ++ { ++ .start = BSC0_BASE, ++ .end = BSC0_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc0_device = { ++ .name = "bcm2708_i2c", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources), ++ .resource = bcm2708_bsc0_resources, ++}; ++ ++ ++static struct resource bcm2708_bsc1_resources[] = { ++ { ++ .start = BSC1_BASE, ++ .end = BSC1_BASE + SZ_256 - 1, ++ .flags = IORESOURCE_MEM, ++ }, { ++ .start = INTERRUPT_I2C, ++ .end = INTERRUPT_I2C, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static struct platform_device bcm2708_bsc1_device = { ++ .name = "bcm2708_i2c", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources), ++ .resource = bcm2708_bsc1_resources, ++}; ++ + static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; +@@ -722,6 +762,15 @@ void __init bcm2709_init(void) + + bcm_register_device_dt(&bcm2708_spi_device); + ++ if (vc_i2c_override) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { ++ bcm_register_device_dt(&bcm2708_bsc0_device); ++ } else { ++ bcm_register_device_dt(&bcm2708_bsc1_device); ++ } ++ + bcm_register_device_dt(&bcm2835_thermal_device); + + if (!use_dt) { +@@ -1061,3 +1110,5 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(vc_i2c_override, bool, 0644); ++MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 2255af2..5b0c772 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -8,6 +8,25 @@ menu "I2C Hardware Bus support" + comment "PC SMBus host controller drivers" + depends on PCI + ++config I2C_BCM2708 ++ tristate "BCM2708 BSC" ++ depends on MACH_BCM2708 || MACH_BCM2709 ++ help ++ Enabling this option will add BSC (Broadcom Serial Controller) ++ support for the BCM2708. BSC is a Broadcom proprietary bus compatible ++ with I2C/TWI/SMBus. ++ ++config I2C_BCM2708_BAUDRATE ++ prompt "BCM2708 I2C baudrate" ++ depends on I2C_BCM2708 ++ int ++ default 100000 ++ help ++ Set the I2C baudrate. This will alter the default value. A ++ different baudrate can be set by using a module parameter as well. If ++ no parameter is provided when loading, this is the value that will be ++ used. ++ + config I2C_ALI1535 + tristate "ALI 1535" + depends on PCI +@@ -362,7 +381,7 @@ config I2C_AXXIA + + config I2C_BCM2835 + tristate "Broadcom BCM2835 I2C controller" +- depends on ARCH_BCM2835 ++ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 + help + If you say yes to this option, support will be included for the + BCM2835 I2C controller. +diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile +index cdf941d..e0176d7 100644 +--- a/drivers/i2c/busses/Makefile ++++ b/drivers/i2c/busses/Makefile +@@ -2,6 +2,8 @@ + # Makefile for the i2c bus drivers. + # + ++obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o ++ + # ACPI drivers + obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o + +diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c +new file mode 100644 +index 0000000..8773203 +--- /dev/null ++++ b/drivers/i2c/busses/i2c-bcm2708.c +@@ -0,0 +1,522 @@ ++/* ++ * Driver for Broadcom BCM2708 BSC Controllers ++ * ++ * Copyright (C) 2012 Chris Boot & Frank Buss ++ * ++ * This driver is inspired by: ++ * i2c-ocores.c, by Peter Korsgaard ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* BSC register offsets */ ++#define BSC_C 0x00 ++#define BSC_S 0x04 ++#define BSC_DLEN 0x08 ++#define BSC_A 0x0c ++#define BSC_FIFO 0x10 ++#define BSC_DIV 0x14 ++#define BSC_DEL 0x18 ++#define BSC_CLKT 0x1c ++ ++/* Bitfields in BSC_C */ ++#define BSC_C_I2CEN 0x00008000 ++#define BSC_C_INTR 0x00000400 ++#define BSC_C_INTT 0x00000200 ++#define BSC_C_INTD 0x00000100 ++#define BSC_C_ST 0x00000080 ++#define BSC_C_CLEAR_1 0x00000020 ++#define BSC_C_CLEAR_2 0x00000010 ++#define BSC_C_READ 0x00000001 ++ ++/* Bitfields in BSC_S */ ++#define BSC_S_CLKT 0x00000200 ++#define BSC_S_ERR 0x00000100 ++#define BSC_S_RXF 0x00000080 ++#define BSC_S_TXE 0x00000040 ++#define BSC_S_RXD 0x00000020 ++#define BSC_S_TXD 0x00000010 ++#define BSC_S_RXR 0x00000008 ++#define BSC_S_TXW 0x00000004 ++#define BSC_S_DONE 0x00000002 ++#define BSC_S_TA 0x00000001 ++ ++#define I2C_TIMEOUT_MS 150 ++#define I2C_WAIT_LOOP_COUNT 40 ++ ++#define DRV_NAME "bcm2708_i2c" ++ ++static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE; ++module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); ++MODULE_PARM_DESC(baudrate, "The I2C baudrate"); ++ ++static bool combined = false; ++module_param(combined, bool, 0644); ++MODULE_PARM_DESC(combined, "Use combined transactions"); ++ ++struct bcm2708_i2c { ++ struct i2c_adapter adapter; ++ ++ spinlock_t lock; ++ void __iomem *base; ++ int irq; ++ struct clk *clk; ++ u32 cdiv; ++ ++ struct completion done; ++ ++ struct i2c_msg *msg; ++ int pos; ++ int nmsgs; ++ bool error; ++}; ++ ++/* ++ * This function sets the ALT mode on the I2C pins so that we can use them with ++ * the BSC hardware. ++ * ++ * FIXME: This is a hack. Use pinmux / pinctrl. ++ */ ++static void bcm2708_i2c_init_pinmode(int id) ++{ ++#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)) ++#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3)) ++ ++ int pin; ++ u32 *gpio = ioremap(GPIO_BASE, SZ_16K); ++ ++ BUG_ON(id != 0 && id != 1); ++ /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */ ++ for (pin = id*2+0; pin <= id*2+1; pin++) { ++ printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); ++ INP_GPIO(pin); /* set mode to GPIO input first */ ++ SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */ ++ } ++ ++ iounmap(gpio); ++ ++#undef INP_GPIO ++#undef SET_GPIO_ALT ++} ++ ++static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg) ++{ ++ return readl(bi->base + reg); ++} ++ ++static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val) ++{ ++ writel(val, bi->base + reg); ++} ++ ++static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi) ++{ ++ bcm2708_wr(bi, BSC_C, 0); ++ bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE); ++} ++ ++static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi) ++{ ++ while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len)) ++ bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO); ++} ++ ++static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) ++{ ++ while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len)) ++ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); ++} ++ ++static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) ++{ ++ u32 cdiv, s; ++ u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; ++ int wait_loops = I2C_WAIT_LOOP_COUNT; ++ ++ /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked. ++ * Use the value that we cached in the probe. ++ */ ++ cdiv = bi->cdiv; ++ ++ if (bi->msg->flags & I2C_M_RD) ++ c |= BSC_C_INTR | BSC_C_READ; ++ else ++ c |= BSC_C_INTT; ++ ++ bcm2708_wr(bi, BSC_DIV, cdiv); ++ bcm2708_wr(bi, BSC_A, bi->msg->addr); ++ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); ++ if (combined) ++ { ++ /* Do the next two messages meet combined transaction criteria? ++ - Current message is a write, next message is a read ++ - Both messages to same slave address ++ - Write message can fit inside FIFO (16 bytes or less) */ ++ if ( (bi->nmsgs > 1) && ++ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && ++ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { ++ /* Fill FIFO with entire write message (16 byte FIFO) */ ++ while (bi->pos < bi->msg->len) { ++ bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); ++ } ++ /* Start write transfer (no interrupts, don't clear FIFO) */ ++ bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); ++ ++ /* poll for transfer start bit (should only take 1-20 polls) */ ++ do { ++ s = bcm2708_rd(bi, BSC_S); ++ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0); ++ ++ /* did we time out or some error occured? */ ++ if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) { ++ return -1; ++ } ++ ++ /* Send next read message before the write transfer finishes. */ ++ bi->nmsgs--; ++ bi->msg++; ++ bi->pos = 0; ++ bcm2708_wr(bi, BSC_DLEN, bi->msg->len); ++ c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ; ++ } ++ } ++ bcm2708_wr(bi, BSC_C, c); ++ ++ return 0; ++} ++ ++static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) ++{ ++ struct bcm2708_i2c *bi = dev_id; ++ bool handled = true; ++ u32 s; ++ int ret; ++ ++ spin_lock(&bi->lock); ++ ++ /* we may see camera interrupts on the "other" I2C channel ++ Just return if we've not sent anything */ ++ if (!bi->nmsgs || !bi->msg) { ++ goto early_exit; ++ } ++ ++ s = bcm2708_rd(bi, BSC_S); ++ ++ if (s & (BSC_S_CLKT | BSC_S_ERR)) { ++ bcm2708_bsc_reset(bi); ++ bi->error = true; ++ ++ bi->msg = 0; /* to inform the that all work is done */ ++ bi->nmsgs = 0; ++ /* wake up our bh */ ++ complete(&bi->done); ++ } else if (s & BSC_S_DONE) { ++ bi->nmsgs--; ++ ++ if (bi->msg->flags & I2C_M_RD) { ++ bcm2708_bsc_fifo_drain(bi); ++ } ++ ++ bcm2708_bsc_reset(bi); ++ ++ if (bi->nmsgs) { ++ /* advance to next message */ ++ bi->msg++; ++ bi->pos = 0; ++ ret = bcm2708_bsc_setup(bi); ++ if (ret < 0) { ++ bcm2708_bsc_reset(bi); ++ bi->error = true; ++ bi->msg = 0; /* to inform the that all work is done */ ++ bi->nmsgs = 0; ++ /* wake up our bh */ ++ complete(&bi->done); ++ goto early_exit; ++ } ++ } else { ++ bi->msg = 0; /* to inform the that all work is done */ ++ bi->nmsgs = 0; ++ /* wake up our bh */ ++ complete(&bi->done); ++ } ++ } else if (s & BSC_S_TXW) { ++ bcm2708_bsc_fifo_fill(bi); ++ } else if (s & BSC_S_RXR) { ++ bcm2708_bsc_fifo_drain(bi); ++ } else { ++ handled = false; ++ } ++ ++early_exit: ++ spin_unlock(&bi->lock); ++ ++ return handled ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, ++ struct i2c_msg *msgs, int num) ++{ ++ struct bcm2708_i2c *bi = adap->algo_data; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&bi->lock, flags); ++ ++ reinit_completion(&bi->done); ++ bi->msg = msgs; ++ bi->pos = 0; ++ bi->nmsgs = num; ++ bi->error = false; ++ ++ ret = bcm2708_bsc_setup(bi); ++ ++ spin_unlock_irqrestore(&bi->lock, flags); ++ ++ /* check the result of the setup */ ++ if (ret < 0) ++ { ++ dev_err(&adap->dev, "transfer setup timed out\n"); ++ goto error_timeout; ++ } ++ ++ ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); ++ if (ret == 0) { ++ dev_err(&adap->dev, "transfer timed out\n"); ++ goto error_timeout; ++ } ++ ++ ret = bi->error ? -EIO : num; ++ return ret; ++ ++error_timeout: ++ spin_lock_irqsave(&bi->lock, flags); ++ bcm2708_bsc_reset(bi); ++ bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */ ++ bi->nmsgs = 0; ++ spin_unlock_irqrestore(&bi->lock, flags); ++ return -ETIMEDOUT; ++} ++ ++static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL; ++} ++ ++static struct i2c_algorithm bcm2708_i2c_algorithm = { ++ .master_xfer = bcm2708_i2c_master_xfer, ++ .functionality = bcm2708_i2c_functionality, ++}; ++ ++static int bcm2708_i2c_probe(struct platform_device *pdev) ++{ ++ struct resource *regs; ++ int irq, err = -ENOMEM; ++ struct clk *clk; ++ struct bcm2708_i2c *bi; ++ struct i2c_adapter *adap; ++ unsigned long bus_hz; ++ u32 cdiv; ++ ++ if (pdev->dev.of_node) { ++ u32 bus_clk_rate; ++ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); ++ if (pdev->id < 0) { ++ dev_err(&pdev->dev, "alias is missing\n"); ++ return -EINVAL; ++ } ++ if (!of_property_read_u32(pdev->dev.of_node, ++ "clock-frequency", &bus_clk_rate)) ++ baudrate = bus_clk_rate; ++ else ++ dev_warn(&pdev->dev, ++ "Could not read clock-frequency property\n"); ++ } ++ ++ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!regs) { ++ dev_err(&pdev->dev, "could not get IO memory\n"); ++ return -ENXIO; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(&pdev->dev, "could not get IRQ\n"); ++ return irq; ++ } ++ ++ clk = clk_get(&pdev->dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk)); ++ return PTR_ERR(clk); ++ } ++ ++ err = clk_prepare_enable(clk); ++ if (err) { ++ dev_err(&pdev->dev, "could not enable clk: %d\n", err); ++ goto out_clk_put; ++ } ++ ++ if (!pdev->dev.of_node) ++ bcm2708_i2c_init_pinmode(pdev->id); ++ ++ bi = kzalloc(sizeof(*bi), GFP_KERNEL); ++ if (!bi) ++ goto out_clk_disable; ++ ++ platform_set_drvdata(pdev, bi); ++ ++ adap = &bi->adapter; ++ adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC; ++ adap->algo = &bcm2708_i2c_algorithm; ++ adap->algo_data = bi; ++ adap->dev.parent = &pdev->dev; ++ adap->nr = pdev->id; ++ strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); ++ adap->dev.of_node = pdev->dev.of_node; ++ ++ switch (pdev->id) { ++ case 0: ++ adap->class = I2C_CLASS_HWMON; ++ break; ++ case 1: ++ adap->class = I2C_CLASS_DDC; ++ break; ++ default: ++ dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n"); ++ err = -ENXIO; ++ goto out_free_bi; ++ } ++ ++ spin_lock_init(&bi->lock); ++ init_completion(&bi->done); ++ ++ bi->base = ioremap(regs->start, resource_size(regs)); ++ if (!bi->base) { ++ dev_err(&pdev->dev, "could not remap memory\n"); ++ goto out_free_bi; ++ } ++ ++ bi->irq = irq; ++ bi->clk = clk; ++ ++ err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED, ++ dev_name(&pdev->dev), bi); ++ if (err) { ++ dev_err(&pdev->dev, "could not request IRQ: %d\n", err); ++ goto out_iounmap; ++ } ++ ++ bcm2708_bsc_reset(bi); ++ ++ err = i2c_add_numbered_adapter(adap); ++ if (err < 0) { ++ dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err); ++ goto out_free_irq; ++ } ++ ++ bus_hz = clk_get_rate(bi->clk); ++ cdiv = bus_hz / baudrate; ++ if (cdiv > 0xffff) { ++ cdiv = 0xffff; ++ baudrate = bus_hz / cdiv; ++ } ++ bi->cdiv = cdiv; ++ ++ dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", ++ pdev->id, (unsigned long)regs->start, irq, baudrate); ++ ++ return 0; ++ ++out_free_irq: ++ free_irq(bi->irq, bi); ++out_iounmap: ++ iounmap(bi->base); ++out_free_bi: ++ kfree(bi); ++out_clk_disable: ++ clk_disable_unprepare(clk); ++out_clk_put: ++ clk_put(clk); ++ return err; ++} ++ ++static int bcm2708_i2c_remove(struct platform_device *pdev) ++{ ++ struct bcm2708_i2c *bi = platform_get_drvdata(pdev); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ i2c_del_adapter(&bi->adapter); ++ free_irq(bi->irq, bi); ++ iounmap(bi->base); ++ clk_disable_unprepare(bi->clk); ++ clk_put(bi->clk); ++ kfree(bi); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm2708_i2c_of_match[] = { ++ { .compatible = "brcm,bcm2708-i2c" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); ++ ++static struct platform_driver bcm2708_i2c_driver = { ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2708_i2c_of_match, ++ }, ++ .probe = bcm2708_i2c_probe, ++ .remove = bcm2708_i2c_remove, ++}; ++ ++// module_platform_driver(bcm2708_i2c_driver); ++ ++ ++static int __init bcm2708_i2c_init(void) ++{ ++ return platform_driver_register(&bcm2708_i2c_driver); ++} ++ ++static void __exit bcm2708_i2c_exit(void) ++{ ++ platform_driver_unregister(&bcm2708_i2c_driver); ++} ++ ++module_init(bcm2708_i2c_init); ++module_exit(bcm2708_i2c_exit); ++ ++ ++ ++MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708"); ++MODULE_AUTHOR("Chris Boot "); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform:" DRV_NAME); + +From 87711afd62feac0850e063b279057c91fe0aabbf Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 30 Jan 2013 12:45:18 +0000 -Subject: [PATCH 018/216] bcm2835: add v4l2 camera device +Subject: [PATCH 22/77] bcm2835: add v4l2 camera device - Supports raw YUV capture, preview, JPEG and H264. - Uses videobuf2 for data transfer, using dma_buf. @@ -104582,7 +105677,7 @@ index 0000000..c585a8f + +$ v4l2-ctl --list-formats diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig -index d9b872b..2da9264 100644 +index 421f531..34ad311 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -11,6 +11,8 @@ menuconfig V4L_PLATFORM_DRIVERS @@ -104595,7 +105690,7 @@ index d9b872b..2da9264 100644 config VIDEO_VIA_CAMERA diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile -index 3ec1547..d8d5927 100644 +index 8f85561..7b15c24 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -2,6 +2,8 @@ @@ -104609,7 +105704,7 @@ index 3ec1547..d8d5927 100644 diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig new file mode 100644 -index 0000000..2cb1a68 +index 0000000..99a5cbc --- /dev/null +++ b/drivers/media/platform/bcm2835/Kconfig @@ -0,0 +1,25 @@ @@ -104617,7 +105712,7 @@ index 0000000..2cb1a68 + +config VIDEO_BCM2835 + bool "Broadcom BCM2835 camera interface driver" -+ depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709) ++ depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) + ---help--- + Say Y here to enable camera host interface devices for + Broadcom BCM2835 SoC. This operates over the VCHIQ interface @@ -111569,6942 +112664,10 @@ index 0000000..9d1d11e + +#endif /* MMAL_VCHIQ_H */ -From 47303896a0462c49e8bf3e5ef31e744d891a30a4 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 6 Jul 2014 12:07:25 +0200 -Subject: [PATCH 019/216] spi-bcm2708: Prepare for Common Clock Framework - migration - -As part of migrating to use the Common Clock Framework, replace clk_enable() -with clk_prepare_enable() and clk_disable() with clk_disable_unprepare(). -This does not affect behaviour under the current clock implementation. - -Also add a missing clk_disable_unprepare() in the probe error path. - -Signed-off-by: Noralf Tronnes ---- - drivers/spi/spi-bcm2708.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index b04a57d..349d21f 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -545,7 +545,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - } - - /* initialise the hardware */ -- clk_enable(clk); -+ clk_prepare_enable(clk); - bcm2708_wr(bs, SPI_CS, SPI_CS_REN | SPI_CS_CLEAR_RX | SPI_CS_CLEAR_TX); - - err = spi_register_master(master); -@@ -561,6 +561,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - - out_free_irq: - free_irq(bs->irq, master); -+ clk_disable_unprepare(bs->clk); - out_workqueue: - destroy_workqueue(bs->workq); - out_iounmap: -@@ -585,7 +586,7 @@ static int bcm2708_spi_remove(struct platform_device *pdev) - - flush_work(&bs->work); - -- clk_disable(bs->clk); -+ clk_disable_unprepare(bs->clk); - clk_put(bs->clk); - free_irq(bs->irq, master); - iounmap(bs->base); - -From d8d78e0bb5731d6fb3f1f813dc795e98be064870 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 6 Jul 2014 12:09:30 +0200 -Subject: [PATCH 020/216] BCM2708: Migrate to the Common Clock Framework - -As part of moving towards using Device Tree, the Common Clock Framework -has to be used instead of the BCM2708 clock implementation. - -Selecting COMMON_CLK removes the need to set CLKDEV_LOOKUP and HAVE_CLK explicitly. - -CONFIG_ARCH_BCM2708_CHIPIT #ifdef's are removed. They are no longer in use. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/Kconfig | 3 +- - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/bcm2708.c | 79 +++++++++++++++++------------------------ - arch/arm/mach-bcm2708/clock.c | 61 ------------------------------- - arch/arm/mach-bcm2708/clock.h | 24 ------------- - 5 files changed, 34 insertions(+), 135 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/clock.c - delete mode 100644 arch/arm/mach-bcm2708/clock.h - -diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig -index 9fcd395..c495965 100644 ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -373,11 +373,10 @@ config ARCH_BCM2708 - bool "Broadcom BCM2708 family" - select CPU_V6 - select ARM_AMBA -- select HAVE_CLK - select HAVE_SCHED_CLOCK - select NEED_MACH_GPIO_H - select NEED_MACH_MEMORY_H -- select CLKDEV_LOOKUP -+ select COMMON_CLK - select ARCH_HAS_CPUFREQ - select GENERIC_CLOCKEVENTS - select ARM_ERRATA_411920 -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index a722f3f..21e3521 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += clock.o bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o dma.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 752dd46..080e260 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -27,6 +27,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -57,7 +59,6 @@ - - #include "bcm2708.h" - #include "armctrl.h" --#include "clock.h" - - #ifdef CONFIG_BCM_VC_CMA - #include -@@ -78,7 +79,7 @@ - - /* command line parameters */ - static unsigned boardrev, serial; --static unsigned uart_clock; -+static unsigned uart_clock = UART0_CLOCK; - static unsigned disk_led_gpio = 16; - static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; -@@ -188,51 +189,39 @@ static void __init bcm2708_clocksource_init(void) - } - } - -+struct clk __init *bcm2708_clk_register(const char *name, unsigned long fixed_rate) -+{ -+ struct clk *clk; - --/* -- * These are fixed clocks. -- */ --static struct clk ref24_clk = { -- .rate = UART0_CLOCK, /* The UART is clocked at 3MHz via APB_CLK */ --}; -+ clk = clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, -+ fixed_rate); -+ if (IS_ERR(clk)) -+ pr_err("%s not registered\n", name); - --static struct clk osc_clk = { --#ifdef CONFIG_ARCH_BCM2708_CHIPIT -- .rate = 27000000, --#else -- .rate = 500000000, /* ARM clock is set from the VideoCore booter */ --#endif --}; -+ return clk; -+} - --/* warning - the USB needs a clock > 34MHz */ -+void __init bcm2708_register_clkdev(struct clk *clk, const char *name) -+{ -+ int ret; - --static struct clk sdhost_clk = { --#ifdef CONFIG_ARCH_BCM2708_CHIPIT -- .rate = 4000000, /* 4MHz */ --#else -- .rate = 250000000, /* 250MHz */ --#endif --}; -+ ret = clk_register_clkdev(clk, NULL, name); -+ if (ret) -+ pr_err("%s alias not registered\n", name); -+} - --static struct clk_lookup lookups[] = { -- { /* UART0 */ -- .dev_id = "dev:f1", -- .clk = &ref24_clk, -- }, -- { /* USB */ -- .dev_id = "bcm2708_usb", -- .clk = &osc_clk, -- }, { /* SPI */ -- .dev_id = "bcm2708_spi.0", -- .clk = &sdhost_clk, -- }, { /* BSC0 */ -- .dev_id = "bcm2708_i2c.0", -- .clk = &sdhost_clk, -- }, { /* BSC1 */ -- .dev_id = "bcm2708_i2c.1", -- .clk = &sdhost_clk, -- } --}; -+void __init bcm2708_init_clocks(void) -+{ -+ struct clk *clk; -+ -+ clk = bcm2708_clk_register("uart0_clk", uart_clock); -+ bcm2708_register_clkdev(clk, "dev:f1"); -+ -+ clk = bcm2708_clk_register("sdhost_clk", 250000000); -+ bcm2708_register_clkdev(clk, "bcm2708_spi.0"); -+ bcm2708_register_clkdev(clk, "bcm2708_i2c.0"); -+ bcm2708_register_clkdev(clk, "bcm2708_i2c.1"); -+} - - #define UART0_IRQ { IRQ_UART, 0 /*NO_IRQ*/ } - #define UART0_DMA { 15, 14 } -@@ -685,11 +674,7 @@ void __init bcm2708_init(void) - printk("bcm2708.uart_clock = %d\n", uart_clock); - pm_power_off = bcm2708_power_off; - -- if (uart_clock) -- lookups[0].clk->rate = uart_clock; -- -- for (i = 0; i < ARRAY_SIZE(lookups); i++) -- clkdev_add(&lookups[i]); -+ bcm2708_init_clocks(); - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_dmaengine_device); -diff --git a/arch/arm/mach-bcm2708/clock.c b/arch/arm/mach-bcm2708/clock.c -deleted file mode 100644 -index 4fc556e..0000000 ---- a/arch/arm/mach-bcm2708/clock.c -+++ /dev/null -@@ -1,61 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include "clock.h" -- --int clk_enable(struct clk *clk) --{ -- return 0; --} --EXPORT_SYMBOL(clk_enable); -- --void clk_disable(struct clk *clk) --{ --} --EXPORT_SYMBOL(clk_disable); -- --unsigned long clk_get_rate(struct clk *clk) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_get_rate); -- --long clk_round_rate(struct clk *clk, unsigned long rate) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_round_rate); -- --int clk_set_rate(struct clk *clk, unsigned long rate) --{ -- return -EIO; --} --EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2708/clock.h b/arch/arm/mach-bcm2708/clock.h -deleted file mode 100644 -index 5f9d725..0000000 ---- a/arch/arm/mach-bcm2708/clock.h -+++ /dev/null -@@ -1,24 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 -- */ --struct module; -- --struct clk { -- unsigned long rate; --}; - -From 5f8aad35cdb010ca9fc0c58cca2a5a11fce879ec Mon Sep 17 00:00:00 2001 -From: notro -Date: Wed, 9 Jul 2014 14:46:08 +0200 -Subject: [PATCH 021/216] BCM2708: Add core Device Tree support - -Add the bare minimum needed to boot BCM2708 from a Device Tree. - -Signed-off-by: Noralf Tronnes - -BCM2708: DT: change 'axi' nodename to 'soc' - -Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835. -The VC4 bootloader fills in certain properties in the 'axi' subtree, -but since this is part of an upstreaming effort, the name is changed. - -Signed-off-by: Noralf Tronnes notro@tronnes.org - -BCM2708_DT: Correct length of the peripheral space ---- - arch/arm/boot/dts/Makefile | 21 ++++ - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 81 +++++++++++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 81 +++++++++++++++ - arch/arm/boot/dts/bcm2708.dtsi | 86 ++++++++++++++++ - arch/arm/boot/dts/bcm2709.dtsi | 165 +++++++++++++++++++++++++++++++ - arch/arm/mach-bcm2708/Kconfig | 8 ++ - arch/arm/mach-bcm2708/bcm2708.c | 45 ++++++++- - 7 files changed, 484 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts - create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts - create mode 100644 arch/arm/boot/dts/bcm2708.dtsi - create mode 100644 arch/arm/boot/dts/bcm2709.dtsi - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 992ea0b..25fbf52 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1,5 +1,17 @@ - ifeq ($(CONFIG_OF),y) - -+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb -+dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb -+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb -+ -+# Raspberry Pi -+ifeq ($(CONFIG_BCM2708_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ifeq ($(CONFIG_BCM2709_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb - # Keep at91 dtb files sorted alphabetically for each SoC -@@ -645,7 +657,16 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ - mt6592-evb.dtb \ - mt8127-moose.dtb \ - mt8135-evbp1.dtb -+ -+targets += dtbs dtbs_install -+targets += $(dtb-y) -+ - endif - - always := $(dtb-y) - clean-files := *.dtb -+ -+# Enable fixups to support overlays on BCM2708 platforms -+ifeq ($(RPI_DT_OVERLAYS),y) -+ DTC_FLAGS ?= -@ -+endif -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -new file mode 100644 -index 0000000..983c23f ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+ -+/include/ "bcm2708.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ model = "Raspberry Pi Model B+"; -+ -+ aliases { -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ sound = &sound; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -new file mode 100644 -index 0000000..d8c6d15 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -0,0 +1,81 @@ -+/dts-v1/; -+ -+/include/ "bcm2708.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ model = "Raspberry Pi Model B"; -+ -+ aliases { -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ sound = &sound; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ -+&gpio { -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; -+ }; -+ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; -+ }; -+ -+ i2s_pins: i2s { -+ brcm,pins = <28 29 30 31>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; -+ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+}; -+ -+&i2c0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2c1 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; -+ clock-frequency = <100000>; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -new file mode 100644 -index 0000000..96b7311 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -0,0 +1,86 @@ -+/include/ "skeleton.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ model = "BCM2708"; -+ -+ interrupt-parent = <&intc>; -+ -+ chosen { -+ /* No padding required - the boot loader can do that. */ -+ bootargs = ""; -+ }; -+ -+ soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x7e000000 0x20000000 0x01000000>; -+ -+ intc: interrupt-controller { -+ compatible = "brcm,bcm2708-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio: gpio { -+ compatible = "brcm,bcm2835-gpio"; -+ reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ i2s: i2s@7e203000 { -+ compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; -+ -+ //dmas = <&dma 2>, -+ // <&dma 3>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@7e204000 { -+ compatible = "brcm,bcm2708-spi"; -+ reg = <0x7e204000 0x1000>; -+ interrupts = <2 22>; -+ clocks = <&clk_spi>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@7e205000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e205000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@7e804000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e804000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ }; -+ -+ clocks { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -new file mode 100644 -index 0000000..15c7e65 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -0,0 +1,165 @@ -+/include/ "skeleton.dtsi" -+ -+/ { -+ compatible = "brcm,bcm2709"; -+ model = "BCM2709"; -+ -+ interrupt-parent = <&intc>; -+ -+ chosen { -+ /* No padding required - the boot loader can do that. */ -+ bootargs = ""; -+ }; -+ -+ soc: soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0x7e000000 0x3f000000 0x01000000>; -+ -+ intc: interrupt-controller { -+ compatible = "brcm,bcm2708-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio: gpio { -+ compatible = "brcm,bcm2835-gpio"; -+ reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ i2s: i2s@7e203000 { -+ compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; -+ -+ //dmas = <&dma 2>, -+ // <&dma 3>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@7e204000 { -+ compatible = "brcm,bcm2708-spi"; -+ reg = <0x7e204000 0x1000>; -+ interrupts = <2 22>; -+ clocks = <&clk_spi>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@7e205000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e205000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@7e804000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e804000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ leds: leds { -+ compatible = "gpio-leds"; -+ -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ }; -+ }; -+ -+ arm-pmu { -+ compatible = "arm,cortex-a7-pmu"; -+ interrupts = <3 9>; -+ }; -+ }; -+ -+ clocks { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_i2c: i2c { -+ compatible = "fixed-clock"; -+ reg = <1>; -+ #clock-cells = <0>; -+ clock-frequency = <250000000>; -+ }; -+ -+ clk_spi: clock@2 { -+ compatible = "fixed-clock"; -+ reg = <2>; -+ #clock-cells = <0>; -+ clock-output-names = "spi"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ -+ timer { -+ compatible = "arm,armv7-timer"; -+ clock-frequency = <19200000>; -+ interrupts = <3 0>, // PHYS_SECURE_PPI -+ <3 1>, // PHYS_NONSECURE_PPI -+ <3 3>, // VIRT_PPI -+ <3 2>; // HYP_PPI -+ always-on; -+ }; -+ -+ cpus: cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ v7_cpu0: cpu@0 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf00>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu1: cpu@1 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf01>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu2: cpu@2 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf02>; -+ clock-frequency = <800000000>; -+ }; -+ -+ v7_cpu3: cpu@3 { -+ device_type = "cpu"; -+ compatible = "arm,cortex-a7"; -+ reg = <0xf03>; -+ clock-frequency = <800000000>; -+ }; -+ }; -+ -+ __overrides__ { -+ arm_freq = <&v7_cpu0>, "clock-frequency:0", -+ <&v7_cpu1>, "clock-frequency:0", -+ <&v7_cpu2>, "clock-frequency:0", -+ <&v7_cpu3>, "clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index e151ed4..182e7ba 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -9,6 +9,14 @@ config MACH_BCM2708 - help - Include support for the Broadcom(R) BCM2708 platform. - -+config BCM2708_DT -+ bool "BCM2708 Device Tree support" -+ depends on MACH_BCM2708 -+ default n -+ select USE_OF -+ help -+ Enable Device Tree support for BCM2708 -+ - config BCM2708_GPIO - bool "BCM2708 gpio support" - depends on MACH_BCM2708 -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 080e260..496cbcd 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -33,7 +33,9 @@ - #include - #include - #include -+#include - #include -+#include - - #include - #include -@@ -84,6 +86,8 @@ static unsigned disk_led_gpio = 16; - static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - -+static unsigned use_dt = 0; -+ - static void __init bcm2708_init_led(void); - - void __init bcm2708_init_irq(void) -@@ -599,6 +603,16 @@ int __init bcm_register_device(struct platform_device *pdev) - return ret; - } - -+/* -+ * Use these macros for platform and i2c devices that are present in the -+ * Device Tree. This way the devices are only added on non-DT systems. -+ */ -+#define bcm_register_device_dt(pdev) \ -+ if (!use_dt) bcm_register_device(pdev) -+ -+#define i2c_register_board_info_dt(busnum, info, n) \ -+ if (!use_dt) i2c_register_board_info(busnum, info, n) -+ - int calc_rsts(int partition) - { - return PM_PASSWORD | -@@ -664,6 +678,24 @@ static void bcm2708_power_off(void) - } - } - -+#ifdef CONFIG_OF -+static void __init bcm2708_dt_init(void) -+{ -+ int ret; -+ -+ of_clk_init(NULL); -+ ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -+ if (ret) { -+ pr_err("of_platform_populate failed: %d\n", ret); -+ /* Proceed as if CONFIG_OF was not defined */ -+ } else { -+ use_dt = 1; -+ } -+} -+#else -+static void __init bcm2708_dt_init(void) { } -+#endif /* CONFIG_OF */ -+ - void __init bcm2708_init(void) - { - int i; -@@ -675,6 +707,7 @@ void __init bcm2708_init(void) - pm_power_off = bcm2708_power_off; - - bcm2708_init_clocks(); -+ bcm2708_dt_init(); - - bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device(&bcm2708_dmaengine_device); -@@ -842,9 +875,9 @@ static struct platform_device bcm2708_led_device = { - - static void __init bcm2708_init_led(void) - { -- bcm2708_leds[0].gpio = disk_led_gpio; -- bcm2708_leds[0].active_low = disk_led_active_low; -- platform_device_register(&bcm2708_led_device); -+ bcm2708_leds[0].gpio = disk_led_gpio; -+ bcm2708_leds[0].active_low = disk_led_active_low; -+ bcm_register_device_dt(&bcm2708_led_device); - } - #else - static inline void bcm2708_init_led(void) -@@ -869,6 +902,11 @@ static void __init board_reserve(void) - #endif - } - -+static const char * const bcm2708_compat[] = { -+ "brcm,bcm2708", -+ NULL -+}; -+ - MACHINE_START(BCM2708, "BCM2708") - /* Maintainer: Broadcom Europe Ltd. */ - .map_io = bcm2708_map_io, -@@ -878,6 +916,7 @@ MACHINE_START(BCM2708, "BCM2708") - .init_early = bcm2708_init_early, - .reserve = board_reserve, - .restart = bcm2708_restart, -+ .dt_compat = bcm2708_compat, - MACHINE_END - - module_param(boardrev, uint, 0644); - -From 55bd100cb5e042a279b944a4ff3c0f00c51ed64c Mon Sep 17 00:00:00 2001 -From: Siarhei Siamashka -Date: Mon, 17 Jun 2013 13:32:11 +0300 -Subject: [PATCH 022/216] fbdev: add FBIOCOPYAREA ioctl - -Based on the patch authored by Ali Gholami Rudi at - https://lkml.org/lkml/2009/7/13/153 - -Provide an ioctl for userspace applications, but only if this operation -is hardware accelerated (otherwide it does not make any sense). - -Signed-off-by: Siarhei Siamashka ---- - drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++ - include/uapi/linux/fb.h | 5 +++++ - 2 files changed, 35 insertions(+) - -diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c -index 0705d88..771992a 100644 ---- a/drivers/video/fbdev/core/fbmem.c -+++ b/drivers/video/fbdev/core/fbmem.c -@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) - } - EXPORT_SYMBOL(fb_blank); - -+static int fb_copyarea_user(struct fb_info *info, -+ struct fb_copyarea *copy) -+{ -+ int ret = 0; -+ if (!lock_fb_info(info)) -+ return -ENODEV; -+ if (copy->dx + copy->width > info->var.xres || -+ copy->sx + copy->width > info->var.xres || -+ copy->dy + copy->height > info->var.yres || -+ copy->sy + copy->height > info->var.yres) { -+ ret = -EINVAL; -+ goto out; -+ } -+ info->fbops->fb_copyarea(info, copy); -+out: -+ unlock_fb_info(info); -+ return ret; -+} -+ - static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - unsigned long arg) - { -@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - struct fb_cmap cmap_from; - struct fb_cmap_user cmap; - struct fb_event event; -+ struct fb_copyarea copy; - void __user *argp = (void __user *)arg; - long ret = 0; - -@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, - unlock_fb_info(info); - console_unlock(); - break; -+ case FBIOCOPYAREA: -+ if (info->flags & FBINFO_HWACCEL_COPYAREA) { -+ /* only provide this ioctl if it is accelerated */ -+ if (copy_from_user(©, argp, sizeof(copy))) -+ return -EFAULT; -+ ret = fb_copyarea_user(info, ©); -+ break; -+ } -+ /* fall through */ - default: - if (!lock_fb_info(info)) - return -ENODEV; -@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, - case FBIOPAN_DISPLAY: - case FBIOGET_CON2FBMAP: - case FBIOPUT_CON2FBMAP: -+ case FBIOCOPYAREA: - arg = (unsigned long) compat_ptr(arg); - case FBIOBLANK: - ret = do_fb_ioctl(info, cmd, arg); -diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h -index fb795c3..fa72af0 100644 ---- a/include/uapi/linux/fb.h -+++ b/include/uapi/linux/fb.h -@@ -34,6 +34,11 @@ - #define FBIOPUT_MODEINFO 0x4617 - #define FBIOGET_DISPINFO 0x4618 - #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) -+/* -+ * HACK: use 'z' in order not to clash with any other ioctl numbers which might -+ * be concurrently added to the mainline kernel -+ */ -+#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea) - - #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ - #define FB_TYPE_PLANES 1 /* Non interleaved planes */ - -From ee44a85f3a6b76509c3de7ee16164e8d32eecc24 Mon Sep 17 00:00:00 2001 -From: Harm Hanemaaijer -Date: Thu, 20 Jun 2013 20:21:39 +0200 -Subject: [PATCH 025/216] Speed up console framebuffer imageblit function - -Especially on platforms with a slower CPU but a relatively high -framebuffer fill bandwidth, like current ARM devices, the existing -console monochrome imageblit function used to draw console text is -suboptimal for common pixel depths such as 16bpp and 32bpp. The existing -code is quite general and can deal with several pixel depths. By creating -special case functions for 16bpp and 32bpp, by far the most common pixel -formats used on modern systems, a significant speed-up is attained -which can be readily felt on ARM-based devices like the Raspberry Pi -and the Allwinner platform, but should help any platform using the -fb layer. - -The special case functions allow constant folding, eliminating a number -of instructions including divide operations, and allow the use of an -unrolled loop, eliminating instructions with a variable shift size, -reducing source memory access instructions, and eliminating excessive -branching. These unrolled loops also allow much better code optimization -by the C compiler. The code that selects which optimized variant is used -is also simplified, eliminating integer divide instructions. - -The speed-up, measured by timing 'cat file.txt' in the console, varies -between 40% and 70%, when testing on the Raspberry Pi and Allwinner -ARM-based platforms, depending on font size and the pixel depth, with -the greater benefit for 32bpp. - -Signed-off-by: Harm Hanemaaijer ---- - drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++-- - 1 file changed, 147 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c -index a2bb276..436494f 100644 ---- a/drivers/video/fbdev/core/cfbimgblt.c -+++ b/drivers/video/fbdev/core/cfbimgblt.c -@@ -28,6 +28,11 @@ - * - * Also need to add code to deal with cards endians that are different than - * the native cpu endians. I also need to deal with MSB position in the word. -+ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013: -+ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are -+ * significantly faster than the previous implementation. -+ * - Simplify the fast/slow_imageblit selection code, avoiding integer -+ * divides. - */ - #include - #include -@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * - } - } - -+/* -+ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded -+ * into the code, main loop unrolled. -+ */ -+ -+static inline void fast_imageblit16(const struct fb_image *image, -+ struct fb_info *p, u8 __iomem * dst1, -+ u32 fgcolor, u32 bgcolor) -+{ -+ u32 fgx = fgcolor, bgx = bgcolor; -+ u32 spitch = (image->width + 7) / 8; -+ u32 end_mask, eorx; -+ const char *s = image->data, *src; -+ u32 __iomem *dst; -+ const u32 *tab = NULL; -+ int i, j, k; -+ -+ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; -+ -+ fgx <<= 16; -+ bgx <<= 16; -+ fgx |= fgcolor; -+ bgx |= bgcolor; -+ -+ eorx = fgx ^ bgx; -+ k = image->width / 2; -+ -+ for (i = image->height; i--;) { -+ dst = (u32 __iomem *) dst1; -+ src = s; -+ -+ j = k; -+ while (j >= 4) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 6) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 4) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 2) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[bits & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ src++; -+ j -= 4; -+ } -+ if (j != 0) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 6) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ if (j >= 2) { -+ end_mask = tab[(bits >> 4) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ if (j == 3) { -+ end_mask = tab[(bits >> 2) & 3]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst); -+ } -+ } -+ } -+ dst1 += p->fix.line_length; -+ s += spitch; -+ } -+} -+ -+/* -+ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded -+ * into the code, main loop unrolled. -+ */ -+ -+static inline void fast_imageblit32(const struct fb_image *image, -+ struct fb_info *p, u8 __iomem * dst1, -+ u32 fgcolor, u32 bgcolor) -+{ -+ u32 fgx = fgcolor, bgx = bgcolor; -+ u32 spitch = (image->width + 7) / 8; -+ u32 end_mask, eorx; -+ const char *s = image->data, *src; -+ u32 __iomem *dst; -+ const u32 *tab = NULL; -+ int i, j, k; -+ -+ tab = cfb_tab32; -+ -+ eorx = fgx ^ bgx; -+ k = image->width; -+ -+ for (i = image->height; i--;) { -+ dst = (u32 __iomem *) dst1; -+ src = s; -+ -+ j = k; -+ while (j >= 8) { -+ u8 bits = *src; -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 6) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 5) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 4) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 3) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 2) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[(bits >> 1) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ end_mask = tab[bits & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ src++; -+ j -= 8; -+ } -+ if (j != 0) { -+ u32 bits = (u32) * src; -+ while (j > 1) { -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); -+ bits <<= 1; -+ j--; -+ } -+ end_mask = tab[(bits >> 7) & 1]; -+ FB_WRITEL((end_mask & eorx) ^ bgx, dst); -+ } -+ dst1 += p->fix.line_length; -+ s += spitch; -+ } -+} -+ - void cfb_imageblit(struct fb_info *p, const struct fb_image *image) - { - u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; -@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) - bgcolor = image->bg_color; - } - -- if (32 % bpp == 0 && !start_index && !pitch_index && -- ((width & (32/bpp-1)) == 0) && -- bpp >= 8 && bpp <= 32) -- fast_imageblit(image, p, dst1, fgcolor, bgcolor); -- else -+ if (!start_index && !pitch_index) { -+ if (bpp == 32) -+ fast_imageblit32(image, p, dst1, fgcolor, -+ bgcolor); -+ else if (bpp == 16 && (width & 1) == 0) -+ fast_imageblit16(image, p, dst1, fgcolor, -+ bgcolor); -+ else if (bpp == 8 && (width & 3) == 0) -+ fast_imageblit(image, p, dst1, fgcolor, -+ bgcolor); -+ else -+ slow_imageblit(image, p, dst1, fgcolor, -+ bgcolor, -+ start_index, pitch_index); -+ } else - slow_imageblit(image, p, dst1, fgcolor, bgcolor, - start_index, pitch_index); - } else - -From 12b6956e3ba31498771d282025fc4a44b6648559 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 26 Mar 2013 17:26:38 +0000 -Subject: [PATCH 026/216] Allow mac address to be set in smsc95xx - -Signed-off-by: popcornmix ---- - drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 56 insertions(+) - -diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index 26423ad..e29a323 100644 ---- a/drivers/net/usb/smsc95xx.c -+++ b/drivers/net/usb/smsc95xx.c -@@ -59,6 +59,7 @@ - #define SUSPEND_SUSPEND3 (0x08) - #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ - SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) -+#define MAC_ADDR_LEN (6) - - struct smsc95xx_priv { - u32 mac_cr; -@@ -74,6 +75,10 @@ static bool turbo_mode = true; - module_param(turbo_mode, bool, 0644); - MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); - -+static char *macaddr = ":"; -+module_param(macaddr, charp, 0); -+MODULE_PARM_DESC(macaddr, "MAC address"); -+ - static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, - u32 *data, int in_pm) - { -@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) - return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); - } - -+/* Check the macaddr module parameter for a MAC address */ -+static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) -+{ -+ int i, j, got_num, num; -+ u8 mtbl[MAC_ADDR_LEN]; -+ -+ if (macaddr[0] == ':') -+ return 0; -+ -+ i = 0; -+ j = 0; -+ num = 0; -+ got_num = 0; -+ while (j < MAC_ADDR_LEN) { -+ if (macaddr[i] && macaddr[i] != ':') { -+ got_num++; -+ if ('0' <= macaddr[i] && macaddr[i] <= '9') -+ num = num * 16 + macaddr[i] - '0'; -+ else if ('A' <= macaddr[i] && macaddr[i] <= 'F') -+ num = num * 16 + 10 + macaddr[i] - 'A'; -+ else if ('a' <= macaddr[i] && macaddr[i] <= 'f') -+ num = num * 16 + 10 + macaddr[i] - 'a'; -+ else -+ break; -+ i++; -+ } else if (got_num == 2) { -+ mtbl[j++] = (u8) num; -+ num = 0; -+ got_num = 0; -+ i++; -+ } else { -+ break; -+ } -+ } -+ -+ if (j == MAC_ADDR_LEN) { -+ netif_dbg(dev, ifup, dev->net, "Overriding MAC address with: " -+ "%02x:%02x:%02x:%02x:%02x:%02x\n", mtbl[0], mtbl[1], mtbl[2], -+ mtbl[3], mtbl[4], mtbl[5]); -+ for (i = 0; i < MAC_ADDR_LEN; i++) -+ dev_mac[i] = mtbl[i]; -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ - static void smsc95xx_init_mac_address(struct usbnet *dev) - { -+ /* Check module parameters */ -+ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr)) -+ return; -+ - /* try reading mac address from EEPROM */ - if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, - dev->net->dev_addr) == 0) { - -From 03ecfd1c727358b884730a06b05d072ef28ebffd Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 8 May 2013 11:46:50 +0100 -Subject: [PATCH 027/216] enabling the realtime clock 1-wire chip DS1307 and - 1-wire on GPIO4 (as a module) - -1-wire: Add support for configuring pin for w1-gpio kernel module -See: https://github.com/raspberrypi/linux/pull/457 - -Add bitbanging pullups, use them for w1-gpio - -Allows parasite power to work, uses module option pullup=1 - -bcm2708: Ensure 1-wire pullup is disabled by default, and expose as module parameter - -Signed-off-by: Alex J Lennon - -w1-gpio: Add gpiopin module parameter and correctly free up gpio pull-up pin, if set - -Signed-off-by: Alex J Lennon ---- - arch/arm/mach-bcm2708/bcm2708.c | 29 ++++++++++++++++++++++ - drivers/w1/masters/w1-gpio.c | 55 +++++++++++++++++++++++++++++++++++++---- - drivers/w1/w1.h | 6 +++++ - drivers/w1/w1_int.c | 14 +++++++++++ - drivers/w1/w1_io.c | 18 +++++++++++--- - 5 files changed, 114 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 496cbcd..5873f8b 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -79,12 +80,19 @@ - */ - #define DMA_MASK_BITS_COMMON 32 - -+// use GPIO 4 for the one-wire GPIO pin, if enabled -+#define W1_GPIO 4 -+// ensure one-wire GPIO pullup is disabled by default -+#define W1_PULLUP -1 -+ - /* command line parameters */ - static unsigned boardrev, serial; - static unsigned uart_clock = UART0_CLOCK; - static unsigned disk_led_gpio = 16; - static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; -+static unsigned w1_gpio_pin = W1_GPIO; -+static unsigned w1_gpio_pullup = W1_PULLUP; - - static unsigned use_dt = 0; - -@@ -256,6 +264,20 @@ static struct platform_device bcm2708_dmaengine_device = { - .id = -1, - }; - -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+static struct w1_gpio_platform_data w1_gpio_pdata = { -+ .pin = W1_GPIO, -+ .ext_pullup_enable_pin = W1_PULLUP, -+ .is_open_drain = 0, -+}; -+ -+static struct platform_device w1_device = { -+ .name = "w1-gpio", -+ .id = -1, -+ .dev.platform_data = &w1_gpio_pdata, -+}; -+#endif -+ - static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_fb_device = { -@@ -715,6 +737,11 @@ void __init bcm2708_init(void) - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device(&bcm2708_gpio_device); - #endif -+#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -+ w1_gpio_pdata.pin = w1_gpio_pin; -+ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -+ bcm_register_device_dt(&w1_device); -+#endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); -@@ -925,3 +952,5 @@ module_param(uart_clock, uint, 0644); - module_param(disk_led_gpio, uint, 0644); - module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); -+module_param(w1_gpio_pin, uint, 0644); -+module_param(w1_gpio_pullup, uint, 0644); -diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c -index b99a932..3ad15cc 100644 ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -23,6 +23,15 @@ - #include "../w1.h" - #include "../w1_int.h" - -+static int w1_gpio_pullup = -1; -+static int w1_gpio_pullup_orig = -1; -+module_param_named(pullup, w1_gpio_pullup, int, 0); -+MODULE_PARM_DESC(pullup, "GPIO pin pullup number"); -+static int w1_gpio_pin = -1; -+static int w1_gpio_pin_orig = -1; -+module_param_named(gpiopin, w1_gpio_pin, int, 0); -+MODULE_PARM_DESC(gpiopin, "GPIO pin number"); -+ - static u8 w1_gpio_set_pullup(void *data, int delay) - { - struct w1_gpio_platform_data *pdata = data; -@@ -67,6 +76,16 @@ static u8 w1_gpio_read_bit(void *data) - return gpio_get_value(pdata->pin) ? 1 : 0; - } - -+static void w1_gpio_bitbang_pullup(void *data, u8 on) -+{ -+ struct w1_gpio_platform_data *pdata = data; -+ -+ if (on) -+ gpio_direction_output(pdata->pin, 1); -+ else -+ gpio_direction_input(pdata->pin); -+} -+ - #if defined(CONFIG_OF) - static struct of_device_id w1_gpio_dt_ids[] = { - { .compatible = "w1-gpio" }, -@@ -113,13 +132,15 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - static int w1_gpio_probe(struct platform_device *pdev) - { - struct w1_bus_master *master; -- struct w1_gpio_platform_data *pdata; -+ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; - int err; - -- if (of_have_populated_dt()) { -- err = w1_gpio_probe_dt(pdev); -- if (err < 0) -- return err; -+ if(pdata == NULL) { -+ if (of_have_populated_dt()) { -+ err = w1_gpio_probe_dt(pdev); -+ if (err < 0) -+ return err; -+ } - } - - pdata = dev_get_platdata(&pdev->dev); -@@ -136,6 +157,19 @@ static int w1_gpio_probe(struct platform_device *pdev) - return -ENOMEM; - } - -+ w1_gpio_pin_orig = pdata->pin; -+ w1_gpio_pullup_orig = pdata->ext_pullup_enable_pin; -+ -+ if(gpio_is_valid(w1_gpio_pin)) { -+ pdata->pin = w1_gpio_pin; -+ pdata->ext_pullup_enable_pin = -1; -+ } -+ if(gpio_is_valid(w1_gpio_pullup)) { -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup; -+ } -+ -+ dev_info(&pdev->dev, "gpio pin %d, gpio pullup pin %d\n", pdata->pin, pdata->ext_pullup_enable_pin); -+ - err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); - if (err) { - dev_err(&pdev->dev, "gpio_request (pin) failed\n"); -@@ -165,6 +199,14 @@ static int w1_gpio_probe(struct platform_device *pdev) - master->set_pullup = w1_gpio_set_pullup; - } - -+ if (gpio_is_valid(w1_gpio_pullup)) { -+ if (pdata->is_open_drain) -+ printk(KERN_ERR "w1-gpio 'pullup' option " -+ "doesn't work with open drain GPIO\n"); -+ else -+ master->bitbang_pullup = w1_gpio_bitbang_pullup; -+ } -+ - err = w1_add_master_device(master); - if (err) { - dev_err(&pdev->dev, "w1_add_master device failed\n"); -@@ -195,6 +237,9 @@ static int w1_gpio_remove(struct platform_device *pdev) - - w1_remove_master_device(master); - -+ pdata->pin = w1_gpio_pin_orig; -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_orig; -+ - return 0; - } - -diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h -index 56a49ba..881d728 100644 ---- a/drivers/w1/w1.h -+++ b/drivers/w1/w1.h -@@ -171,6 +171,12 @@ struct w1_bus_master - - u8 (*set_pullup)(void *, int); - -+ /** -+ * Turns the pullup on/off in bitbanging mode, takes an on/off argument. -+ * @return -1=Error, 0=completed -+ */ -+ void (*bitbang_pullup) (void *, u8); -+ - void (*search)(void *, struct w1_master *, - u8, w1_slave_found_callback); - }; -diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c -index 47249a3..a4b4a8d 100644 ---- a/drivers/w1/w1_int.c -+++ b/drivers/w1/w1_int.c -@@ -123,6 +123,20 @@ int w1_add_master_device(struct w1_bus_master *master) - return(-EINVAL); - } - -+ /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup -+ * and takes care of timing itself */ -+ if (!master->write_byte && !master->touch_bit && master->set_pullup) { -+ printk(KERN_ERR "w1_add_master_device: set_pullup requires " -+ "write_byte or touch_bit, disabling\n"); -+ master->set_pullup = NULL; -+ } -+ -+ if (master->set_pullup && master->bitbang_pullup) { -+ printk(KERN_ERR "w1_add_master_device: set_pullup should not " -+ "be set when bitbang_pullup is used, disabling\n"); -+ master->set_pullup = NULL; -+ } -+ - /* Lock until the device is added (or not) to w1_masters. */ - mutex_lock(&w1_mlock); - /* Search for the first available id (starting at 1). */ -diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c -index 2820924..fd0550f 100644 ---- a/drivers/w1/w1_io.c -+++ b/drivers/w1/w1_io.c -@@ -134,10 +134,22 @@ static void w1_pre_write(struct w1_master *dev) - static void w1_post_write(struct w1_master *dev) - { - if (dev->pullup_duration) { -- if (dev->enable_pullup && dev->bus_master->set_pullup) -- dev->bus_master->set_pullup(dev->bus_master->data, 0); -- else -+ if (dev->enable_pullup) { -+ if (dev->bus_master->set_pullup) { -+ dev->bus_master->set_pullup(dev-> -+ bus_master->data, -+ 0); -+ } else if (dev->bus_master->bitbang_pullup) { -+ dev->bus_master-> -+ bitbang_pullup(dev->bus_master->data, 1); -+ msleep(dev->pullup_duration); -+ dev->bus_master-> -+ bitbang_pullup(dev->bus_master->data, 0); -+ } -+ } else { - msleep(dev->pullup_duration); -+ } -+ - dev->pullup_duration = 0; - } - } - -From 4624b823abd044524b26cb4d7111564f141e540f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Dec 2013 22:16:19 +0000 -Subject: [PATCH 029/216] config: Enable CONFIG_MEMCG, but leave it disabled - (due to memory cost). Enable with cgroup_enable=memory. - ---- - kernel/cgroup.c | 23 +++++++++++++++++++++++ - mm/memcontrol.c | 1 + - 2 files changed, 24 insertions(+) - -diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index 29a7b2c..54fd2f0 100644 ---- a/kernel/cgroup.c -+++ b/kernel/cgroup.c -@@ -5393,6 +5393,29 @@ static int __init cgroup_disable(char *str) - } - __setup("cgroup_disable=", cgroup_disable); - -+static int __init cgroup_enable(char *str) -+{ -+ struct cgroup_subsys *ss; -+ char *token; -+ int i; -+ -+ while ((token = strsep(&str, ",")) != NULL) { -+ if (!*token) -+ continue; -+ -+ for_each_subsys(ss, i) { -+ if (!strcmp(token, ss->name)) { -+ ss->disabled = 0; -+ printk(KERN_INFO "Enabling %s control group" -+ " subsystem\n", ss->name); -+ break; -+ } -+ } -+ } -+ return 1; -+} -+__setup("cgroup_enable=", cgroup_enable); -+ - static int __init cgroup_set_legacy_files_on_dfl(char *str) - { - printk("cgroup: using legacy files on the default hierarchy\n"); -diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index b34ef4a..c2aa348 100644 ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5391,6 +5391,7 @@ struct cgroup_subsys memory_cgrp_subsys = { - .dfl_cftypes = memory_files, - .legacy_cftypes = mem_cgroup_legacy_files, - .early_init = 0, -+ .disabled = 1, - }; - - /** - -From 14913d5804e6cc14027404667dbacd69267fd032 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 14:33:38 +0100 -Subject: [PATCH 030/216] ASoC: Add support for BCM2708 - -This driver adds support for digital audio (I2S) -for the BCM2708 SoC that is used by the -Raspberry Pi. External audio codecs can be -connected to the Raspberry Pi via P5 header. - -It relies on cyclic DMA engine support for BCM2708. - -Signed-off-by: Florian Meier - -ASoC: BCM2708: Add 24 bit support - -This adds 24 bit support to the I2S driver of the BCM2708. -Besides enabling the 24 bit flags, it includes two bug fixes: - -MMAP is not supported. Claiming this leads to strange issues -when the format of driver and file do not match. - -The datasheet states that the width extension bit should be set -for widths greater than 24, but greater or equal would be correct. -This follows from the definition of the width field. - -Signed-off-by: Florian Meier - -bcm2708-i2s: Update bclk_ratio to more correct values - -Move GPIO setup to hw_params. - -This is used to stop the I2S driver from breaking -the GPIO setup for other uses of the PCM interface - -Configure GPIOs for I2S based on revision/card settings - -With RPi model B+, assignment of the I2S GPIO pins has changed. -This patch uses the board revision to auto-detect the GPIOs used -for I2S. It also allows sound card drivers to set the GPIOs that -should be used. This is especially important with the Compute -Module. - -bcm2708-i2s: Avoid leak from iomap when accessing gpio - -bcm2708: Eliminate i2s debugfs directory error - -Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') -to avoid the name clash when registering debugfs entries. ---- - sound/soc/bcm/Kconfig | 11 + - sound/soc/bcm/Makefile | 4 + - sound/soc/bcm/bcm2708-i2s.c | 1009 +++++++++++++++++++++++++++++++++++++++++++ - sound/soc/bcm/bcm2708-i2s.h | 35 ++ - 4 files changed, 1059 insertions(+) - create mode 100644 sound/soc/bcm/bcm2708-i2s.c - create mode 100644 sound/soc/bcm/bcm2708-i2s.h - -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 6a834e1..8642296 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -7,3 +7,14 @@ config SND_BCM2835_SOC_I2S - Say Y or M if you want to add support for codecs attached to - the BCM2835 I2S interface. You will also need - to select the audio interfaces to support below. -+ -+config SND_BCM2708_SOC_I2S -+ tristate "SoC Audio support for the Broadcom BCM2708 I2S module" -+ depends on MACH_BCM2708 || MACH_BCM2709 -+ select REGMAP_MMIO -+ select SND_SOC_DMAENGINE_PCM -+ select SND_SOC_GENERIC_DMAENGINE_PCM -+ help -+ Say Y or M if you want to add support for codecs attached to -+ the BCM2708 I2S interface. You will also need -+ to select the audio interfaces to support below. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index bc816b7..f8bbe1f 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -3,3 +3,7 @@ snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o - - obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o - -+# BCM2708 Platform Support -+snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o -+ -+obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o -diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c -new file mode 100644 -index 0000000..a3b65dc ---- /dev/null -+++ b/sound/soc/bcm/bcm2708-i2s.c -@@ -0,0 +1,1009 @@ -+/* -+ * ALSA SoC I2S Audio Layer for Broadcom BCM2708 SoC -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * Based on -+ * Raspberry Pi PCM I2S ALSA Driver -+ * Copyright (c) by Phil Poole 2013 -+ * -+ * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor -+ * Vladimir Barinov, -+ * Copyright (C) 2007 MontaVista Software, Inc., -+ * -+ * OMAP ALSA SoC DAI driver using McBSP port -+ * Copyright (C) 2008 Nokia Corporation -+ * Contact: Jarkko Nikula -+ * Peter Ujfalusi -+ * -+ * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver -+ * Author: Timur Tabi -+ * Copyright 2007-2010 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * 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. -+ */ -+ -+#include "bcm2708-i2s.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+/* Clock registers */ -+#define BCM2708_CLK_PCMCTL_REG 0x00 -+#define BCM2708_CLK_PCMDIV_REG 0x04 -+ -+/* Clock register settings */ -+#define BCM2708_CLK_PASSWD (0x5a000000) -+#define BCM2708_CLK_PASSWD_MASK (0xff000000) -+#define BCM2708_CLK_MASH(v) ((v) << 9) -+#define BCM2708_CLK_FLIP BIT(8) -+#define BCM2708_CLK_BUSY BIT(7) -+#define BCM2708_CLK_KILL BIT(5) -+#define BCM2708_CLK_ENAB BIT(4) -+#define BCM2708_CLK_SRC(v) (v) -+ -+#define BCM2708_CLK_SHIFT (12) -+#define BCM2708_CLK_DIVI(v) ((v) << BCM2708_CLK_SHIFT) -+#define BCM2708_CLK_DIVF(v) (v) -+#define BCM2708_CLK_DIVF_MASK (0xFFF) -+ -+enum { -+ BCM2708_CLK_MASH_0 = 0, -+ BCM2708_CLK_MASH_1, -+ BCM2708_CLK_MASH_2, -+ BCM2708_CLK_MASH_3, -+}; -+ -+enum { -+ BCM2708_CLK_SRC_GND = 0, -+ BCM2708_CLK_SRC_OSC, -+ BCM2708_CLK_SRC_DBG0, -+ BCM2708_CLK_SRC_DBG1, -+ BCM2708_CLK_SRC_PLLA, -+ BCM2708_CLK_SRC_PLLC, -+ BCM2708_CLK_SRC_PLLD, -+ BCM2708_CLK_SRC_HDMI, -+}; -+ -+/* Most clocks are not useable (freq = 0) */ -+static const unsigned int bcm2708_clk_freq[BCM2708_CLK_SRC_HDMI+1] = { -+ [BCM2708_CLK_SRC_GND] = 0, -+ [BCM2708_CLK_SRC_OSC] = 19200000, -+ [BCM2708_CLK_SRC_DBG0] = 0, -+ [BCM2708_CLK_SRC_DBG1] = 0, -+ [BCM2708_CLK_SRC_PLLA] = 0, -+ [BCM2708_CLK_SRC_PLLC] = 0, -+ [BCM2708_CLK_SRC_PLLD] = 500000000, -+ [BCM2708_CLK_SRC_HDMI] = 0, -+}; -+ -+/* I2S registers */ -+#define BCM2708_I2S_CS_A_REG 0x00 -+#define BCM2708_I2S_FIFO_A_REG 0x04 -+#define BCM2708_I2S_MODE_A_REG 0x08 -+#define BCM2708_I2S_RXC_A_REG 0x0c -+#define BCM2708_I2S_TXC_A_REG 0x10 -+#define BCM2708_I2S_DREQ_A_REG 0x14 -+#define BCM2708_I2S_INTEN_A_REG 0x18 -+#define BCM2708_I2S_INTSTC_A_REG 0x1c -+#define BCM2708_I2S_GRAY_REG 0x20 -+ -+/* I2S register settings */ -+#define BCM2708_I2S_STBY BIT(25) -+#define BCM2708_I2S_SYNC BIT(24) -+#define BCM2708_I2S_RXSEX BIT(23) -+#define BCM2708_I2S_RXF BIT(22) -+#define BCM2708_I2S_TXE BIT(21) -+#define BCM2708_I2S_RXD BIT(20) -+#define BCM2708_I2S_TXD BIT(19) -+#define BCM2708_I2S_RXR BIT(18) -+#define BCM2708_I2S_TXW BIT(17) -+#define BCM2708_I2S_CS_RXERR BIT(16) -+#define BCM2708_I2S_CS_TXERR BIT(15) -+#define BCM2708_I2S_RXSYNC BIT(14) -+#define BCM2708_I2S_TXSYNC BIT(13) -+#define BCM2708_I2S_DMAEN BIT(9) -+#define BCM2708_I2S_RXTHR(v) ((v) << 7) -+#define BCM2708_I2S_TXTHR(v) ((v) << 5) -+#define BCM2708_I2S_RXCLR BIT(4) -+#define BCM2708_I2S_TXCLR BIT(3) -+#define BCM2708_I2S_TXON BIT(2) -+#define BCM2708_I2S_RXON BIT(1) -+#define BCM2708_I2S_EN (1) -+ -+#define BCM2708_I2S_CLKDIS BIT(28) -+#define BCM2708_I2S_PDMN BIT(27) -+#define BCM2708_I2S_PDME BIT(26) -+#define BCM2708_I2S_FRXP BIT(25) -+#define BCM2708_I2S_FTXP BIT(24) -+#define BCM2708_I2S_CLKM BIT(23) -+#define BCM2708_I2S_CLKI BIT(22) -+#define BCM2708_I2S_FSM BIT(21) -+#define BCM2708_I2S_FSI BIT(20) -+#define BCM2708_I2S_FLEN(v) ((v) << 10) -+#define BCM2708_I2S_FSLEN(v) (v) -+ -+#define BCM2708_I2S_CHWEX BIT(15) -+#define BCM2708_I2S_CHEN BIT(14) -+#define BCM2708_I2S_CHPOS(v) ((v) << 4) -+#define BCM2708_I2S_CHWID(v) (v) -+#define BCM2708_I2S_CH1(v) ((v) << 16) -+#define BCM2708_I2S_CH2(v) (v) -+ -+#define BCM2708_I2S_TX_PANIC(v) ((v) << 24) -+#define BCM2708_I2S_RX_PANIC(v) ((v) << 16) -+#define BCM2708_I2S_TX(v) ((v) << 8) -+#define BCM2708_I2S_RX(v) (v) -+ -+#define BCM2708_I2S_INT_RXERR BIT(3) -+#define BCM2708_I2S_INT_TXERR BIT(2) -+#define BCM2708_I2S_INT_RXR BIT(1) -+#define BCM2708_I2S_INT_TXW BIT(0) -+ -+/* I2S DMA interface */ -+#define BCM2708_I2S_FIFO_PHYSICAL_ADDR 0x7E203004 -+#define BCM2708_DMA_DREQ_PCM_TX 2 -+#define BCM2708_DMA_DREQ_PCM_RX 3 -+ -+/* I2S pin configuration */ -+static int bcm2708_i2s_gpio=BCM2708_I2S_GPIO_AUTO; -+ -+/* General device struct */ -+struct bcm2708_i2s_dev { -+ struct device *dev; -+ struct snd_dmaengine_dai_dma_data dma_data[2]; -+ unsigned int fmt; -+ unsigned int bclk_ratio; -+ -+ struct regmap *i2s_regmap; -+ struct regmap *clk_regmap; -+}; -+ -+void bcm2708_i2s_set_gpio(int gpio) { -+ bcm2708_i2s_gpio=gpio; -+} -+EXPORT_SYMBOL(bcm2708_i2s_set_gpio); -+ -+ -+static void bcm2708_i2s_start_clock(struct bcm2708_i2s_dev *dev) -+{ -+ /* Start the clock if in master mode */ -+ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; -+ -+ switch (master) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ case SND_SOC_DAIFMT_CBS_CFM: -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, -+ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); -+ break; -+ default: -+ break; -+ } -+} -+ -+static void bcm2708_i2s_stop_clock(struct bcm2708_i2s_dev *dev) -+{ -+ uint32_t clkreg; -+ int timeout = 1000; -+ -+ /* Stop clock */ -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, -+ BCM2708_CLK_PASSWD); -+ -+ /* Wait for the BUSY flag going down */ -+ while (--timeout) { -+ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); -+ if (!(clkreg & BCM2708_CLK_BUSY)) -+ break; -+ } -+ -+ if (!timeout) { -+ /* KILL the clock */ -+ dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n"); -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD_MASK, -+ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD); -+ } -+} -+ -+static void bcm2708_i2s_clear_fifos(struct bcm2708_i2s_dev *dev, -+ bool tx, bool rx) -+{ -+ int timeout = 1000; -+ uint32_t syncval; -+ uint32_t csreg; -+ uint32_t i2s_active_state; -+ uint32_t clkreg; -+ uint32_t clk_active_state; -+ uint32_t off; -+ uint32_t clr; -+ -+ off = tx ? BCM2708_I2S_TXON : 0; -+ off |= rx ? BCM2708_I2S_RXON : 0; -+ -+ clr = tx ? BCM2708_I2S_TXCLR : 0; -+ clr |= rx ? BCM2708_I2S_RXCLR : 0; -+ -+ /* Backup the current state */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); -+ i2s_active_state = csreg & (BCM2708_I2S_RXON | BCM2708_I2S_TXON); -+ -+ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); -+ clk_active_state = clkreg & BCM2708_CLK_ENAB; -+ -+ /* Start clock if not running */ -+ if (!clk_active_state) { -+ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, -+ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, -+ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); -+ } -+ -+ /* Stop I2S module */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, off, 0); -+ -+ /* -+ * Clear the FIFOs -+ * Requires at least 2 PCM clock cycles to take effect -+ */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, clr, clr); -+ -+ /* Wait for 2 PCM clock cycles */ -+ -+ /* -+ * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back -+ * FIXME: This does not seem to work for slave mode! -+ */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &syncval); -+ syncval &= BCM2708_I2S_SYNC; -+ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_SYNC, ~syncval); -+ -+ /* Wait for the SYNC flag changing it's state */ -+ while (--timeout) { -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); -+ if ((csreg & BCM2708_I2S_SYNC) != syncval) -+ break; -+ } -+ -+ if (!timeout) -+ dev_err(dev->dev, "I2S SYNC error!\n"); -+ -+ /* Stop clock if it was not running before */ -+ if (!clk_active_state) -+ bcm2708_i2s_stop_clock(dev); -+ -+ /* Restore I2S state */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_RXON | BCM2708_I2S_TXON, i2s_active_state); -+} -+ -+static int bcm2708_i2s_set_dai_fmt(struct snd_soc_dai *dai, -+ unsigned int fmt) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ dev->fmt = fmt; -+ return 0; -+} -+ -+static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, -+ unsigned int ratio) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ dev->bclk_ratio = ratio; -+ return 0; -+} -+ -+ -+static int bcm2708_i2s_set_function(unsigned offset, int function) -+{ -+ #define GPIOFSEL(x) (0x00+(x)*4) -+ void __iomem *gpio = __io_address(GPIO_BASE); -+ unsigned alt = function <= 3 ? function + 4: function == 4 ? 3 : 2; -+ unsigned gpiodir; -+ unsigned gpio_bank = offset / 10; -+ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3; -+ -+ if (offset >= BCM2708_NR_GPIOS) -+ return -EINVAL; -+ -+ gpiodir = readl(gpio + GPIOFSEL(gpio_bank)); -+ gpiodir &= ~(7 << gpio_field_offset); -+ gpiodir |= alt << gpio_field_offset; -+ writel(gpiodir, gpio + GPIOFSEL(gpio_bank)); -+ return 0; -+} -+ -+static void bcm2708_i2s_setup_gpio(void) -+{ -+ /* -+ * This is the common way to handle the GPIO pins for -+ * the Raspberry Pi. -+ * TODO Better way would be to handle -+ * this in the device tree! -+ */ -+ int pin,pinconfig,startpin,alt; -+ -+ /* SPI is on different GPIOs on different boards */ -+ /* for Raspberry Pi B+, this is pin GPIO18-21, for original on 28-31 */ -+ if (bcm2708_i2s_gpio==BCM2708_I2S_GPIO_AUTO) { -+ if ((system_rev & 0xffffff) >= 0x10) { -+ /* Model B+ */ -+ pinconfig=BCM2708_I2S_GPIO_PIN18; -+ } else { -+ /* original */ -+ pinconfig=BCM2708_I2S_GPIO_PIN28; -+ } -+ } else { -+ pinconfig=bcm2708_i2s_gpio; -+ } -+ -+ if (pinconfig==BCM2708_I2S_GPIO_PIN18) { -+ startpin=18; -+ alt=BCM2708_I2S_GPIO_PIN18_ALT; -+ } else if (pinconfig==BCM2708_I2S_GPIO_PIN28) { -+ startpin=28; -+ alt=BCM2708_I2S_GPIO_PIN28_ALT; -+ } else { -+ printk(KERN_INFO "Can't configure I2S GPIOs, unknown pin mode for I2S: %i\n",pinconfig); -+ return; -+ } -+ -+ /* configure I2S pins to correct ALT mode */ -+ for (pin = startpin; pin <= startpin+3; pin++) { -+ bcm2708_i2s_set_function(pin, alt); -+ } -+} -+ -+static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ unsigned int sampling_rate = params_rate(params); -+ unsigned int data_length, data_delay, bclk_ratio; -+ unsigned int ch1pos, ch2pos, mode, format; -+ unsigned int mash = BCM2708_CLK_MASH_1; -+ unsigned int divi, divf, target_frequency; -+ int clk_src = -1; -+ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; -+ bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS -+ || master == SND_SOC_DAIFMT_CBS_CFM); -+ -+ bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS -+ || master == SND_SOC_DAIFMT_CBM_CFS); -+ uint32_t csreg; -+ -+ /* -+ * If a stream is already enabled, -+ * the registers are already set properly. -+ */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); -+ -+ if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) -+ return 0; -+ -+ -+ bcm2708_i2s_setup_gpio(); -+ -+ /* -+ * Adjust the data length according to the format. -+ * We prefill the half frame length with an integer -+ * divider of 2400 as explained at the clock settings. -+ * Maybe it is overwritten there, if the Integer mode -+ * does not apply. -+ */ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ data_length = 16; -+ bclk_ratio = 50; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ data_length = 24; -+ bclk_ratio = 50; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ data_length = 32; -+ bclk_ratio = 100; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* If bclk_ratio already set, use that one. */ -+ if (dev->bclk_ratio) -+ bclk_ratio = dev->bclk_ratio; -+ -+ /* -+ * Clock Settings -+ * -+ * The target frequency of the bit clock is -+ * sampling rate * frame length -+ * -+ * Integer mode: -+ * Sampling rates that are multiples of 8000 kHz -+ * can be driven by the oscillator of 19.2 MHz -+ * with an integer divider as long as the frame length -+ * is an integer divider of 19200000/8000=2400 as set up above. -+ * This is no longer possible if the sampling rate -+ * is too high (e.g. 192 kHz), because the oscillator is too slow. -+ * -+ * MASH mode: -+ * For all other sampling rates, it is not possible to -+ * have an integer divider. Approximate the clock -+ * with the MASH module that induces a slight frequency -+ * variance. To minimize that it is best to have the fastest -+ * clock here. That is PLLD with 500 MHz. -+ */ -+ target_frequency = sampling_rate * bclk_ratio; -+ clk_src = BCM2708_CLK_SRC_OSC; -+ mash = BCM2708_CLK_MASH_0; -+ -+ if (bcm2708_clk_freq[clk_src] % target_frequency == 0 -+ && bit_master && frame_master) { -+ divi = bcm2708_clk_freq[clk_src] / target_frequency; -+ divf = 0; -+ } else { -+ uint64_t dividend; -+ -+ if (!dev->bclk_ratio) { -+ /* -+ * Overwrite bclk_ratio, because the -+ * above trick is not needed or can -+ * not be used. -+ */ -+ bclk_ratio = 2 * data_length; -+ } -+ -+ target_frequency = sampling_rate * bclk_ratio; -+ -+ clk_src = BCM2708_CLK_SRC_PLLD; -+ mash = BCM2708_CLK_MASH_1; -+ -+ dividend = bcm2708_clk_freq[clk_src]; -+ dividend <<= BCM2708_CLK_SHIFT; -+ do_div(dividend, target_frequency); -+ divi = dividend >> BCM2708_CLK_SHIFT; -+ divf = dividend & BCM2708_CLK_DIVF_MASK; -+ } -+ -+ /* Clock should only be set up here if CPU is clock master */ -+ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) || -+ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) { -+ /* Set clock divider */ -+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD -+ | BCM2708_CLK_DIVI(divi) -+ | BCM2708_CLK_DIVF(divf)); -+ -+ /* Setup clock, but don't start it yet */ -+ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD -+ | BCM2708_CLK_MASH(mash) -+ | BCM2708_CLK_SRC(clk_src)); -+ } -+ -+ /* Setup the frame format */ -+ format = BCM2708_I2S_CHEN; -+ -+ if (data_length >= 24) -+ format |= BCM2708_I2S_CHWEX; -+ -+ format |= BCM2708_I2S_CHWID((data_length-8)&0xf); -+ -+ switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { -+ case SND_SOC_DAIFMT_I2S: -+ data_delay = 1; -+ break; -+ default: -+ /* -+ * TODO -+ * Others are possible but are not implemented at the moment. -+ */ -+ dev_err(dev->dev, "%s:bad format\n", __func__); -+ return -EINVAL; -+ } -+ -+ ch1pos = data_delay; -+ ch2pos = bclk_ratio / 2 + data_delay; -+ -+ switch (params_channels(params)) { -+ case 2: -+ format = BCM2708_I2S_CH1(format) | BCM2708_I2S_CH2(format); -+ format |= BCM2708_I2S_CH1(BCM2708_I2S_CHPOS(ch1pos)); -+ format |= BCM2708_I2S_CH2(BCM2708_I2S_CHPOS(ch2pos)); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ /* -+ * Set format for both streams. -+ * We cannot set another frame length -+ * (and therefore word length) anyway, -+ * so the format will be the same. -+ */ -+ regmap_write(dev->i2s_regmap, BCM2708_I2S_RXC_A_REG, format); -+ regmap_write(dev->i2s_regmap, BCM2708_I2S_TXC_A_REG, format); -+ -+ /* Setup the I2S mode */ -+ mode = 0; -+ -+ if (data_length <= 16) { -+ /* -+ * Use frame packed mode (2 channels per 32 bit word) -+ * We cannot set another frame length in the second stream -+ * (and therefore word length) anyway, -+ * so the format will be the same. -+ */ -+ mode |= BCM2708_I2S_FTXP | BCM2708_I2S_FRXP; -+ } -+ -+ mode |= BCM2708_I2S_FLEN(bclk_ratio - 1); -+ mode |= BCM2708_I2S_FSLEN(bclk_ratio / 2); -+ -+ /* Master or slave? */ -+ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { -+ case SND_SOC_DAIFMT_CBS_CFS: -+ /* CPU is master */ -+ break; -+ case SND_SOC_DAIFMT_CBM_CFS: -+ /* -+ * CODEC is bit clock master -+ * CPU is frame master -+ */ -+ mode |= BCM2708_I2S_CLKM; -+ break; -+ case SND_SOC_DAIFMT_CBS_CFM: -+ /* -+ * CODEC is frame master -+ * CPU is bit clock master -+ */ -+ mode |= BCM2708_I2S_FSM; -+ break; -+ case SND_SOC_DAIFMT_CBM_CFM: -+ /* CODEC is master */ -+ mode |= BCM2708_I2S_CLKM; -+ mode |= BCM2708_I2S_FSM; -+ break; -+ default: -+ dev_err(dev->dev, "%s:bad master\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* -+ * Invert clocks? -+ * -+ * The BCM approach seems to be inverted to the classical I2S approach. -+ */ -+ switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { -+ case SND_SOC_DAIFMT_NB_NF: -+ /* None. Therefore, both for BCM */ -+ mode |= BCM2708_I2S_CLKI; -+ mode |= BCM2708_I2S_FSI; -+ break; -+ case SND_SOC_DAIFMT_IB_IF: -+ /* Both. Therefore, none for BCM */ -+ break; -+ case SND_SOC_DAIFMT_NB_IF: -+ /* -+ * Invert only frame sync. Therefore, -+ * invert only bit clock for BCM -+ */ -+ mode |= BCM2708_I2S_CLKI; -+ break; -+ case SND_SOC_DAIFMT_IB_NF: -+ /* -+ * Invert only bit clock. Therefore, -+ * invert only frame sync for BCM -+ */ -+ mode |= BCM2708_I2S_FSI; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_write(dev->i2s_regmap, BCM2708_I2S_MODE_A_REG, mode); -+ -+ /* Setup the DMA parameters */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_RXTHR(1) -+ | BCM2708_I2S_TXTHR(1) -+ | BCM2708_I2S_DMAEN, 0xffffffff); -+ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_DREQ_A_REG, -+ BCM2708_I2S_TX_PANIC(0x10) -+ | BCM2708_I2S_RX_PANIC(0x30) -+ | BCM2708_I2S_TX(0x30) -+ | BCM2708_I2S_RX(0x20), 0xffffffff); -+ -+ /* Clear FIFOs */ -+ bcm2708_i2s_clear_fifos(dev, true, true); -+ -+ return 0; -+} -+ -+static int bcm2708_i2s_prepare(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ uint32_t cs_reg; -+ -+ bcm2708_i2s_start_clock(dev); -+ -+ /* -+ * Clear both FIFOs if the one that should be started -+ * is not empty at the moment. This should only happen -+ * after overrun. Otherwise, hw_params would have cleared -+ * the FIFO. -+ */ -+ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &cs_reg); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK -+ && !(cs_reg & BCM2708_I2S_TXE)) -+ bcm2708_i2s_clear_fifos(dev, true, false); -+ else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE -+ && (cs_reg & BCM2708_I2S_RXD)) -+ bcm2708_i2s_clear_fifos(dev, false, true); -+ -+ return 0; -+} -+ -+static void bcm2708_i2s_stop(struct bcm2708_i2s_dev *dev, -+ struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ uint32_t mask; -+ -+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -+ mask = BCM2708_I2S_RXON; -+ else -+ mask = BCM2708_I2S_TXON; -+ -+ regmap_update_bits(dev->i2s_regmap, -+ BCM2708_I2S_CS_A_REG, mask, 0); -+ -+ /* Stop also the clock when not SND_SOC_DAIFMT_CONT */ -+ if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT)) -+ bcm2708_i2s_stop_clock(dev); -+} -+ -+static int bcm2708_i2s_trigger(struct snd_pcm_substream *substream, int cmd, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ uint32_t mask; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ case SNDRV_PCM_TRIGGER_RESUME: -+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: -+ bcm2708_i2s_start_clock(dev); -+ -+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) -+ mask = BCM2708_I2S_RXON; -+ else -+ mask = BCM2708_I2S_TXON; -+ -+ regmap_update_bits(dev->i2s_regmap, -+ BCM2708_I2S_CS_A_REG, mask, mask); -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ case SNDRV_PCM_TRIGGER_SUSPEND: -+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -+ bcm2708_i2s_stop(dev, substream, dai); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int bcm2708_i2s_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ if (dai->active) -+ return 0; -+ -+ /* Should this still be running stop it */ -+ bcm2708_i2s_stop_clock(dev); -+ -+ /* Enable PCM block */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_EN, BCM2708_I2S_EN); -+ -+ /* -+ * Disable STBY. -+ * Requires at least 4 PCM clock cycles to take effect. -+ */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_STBY, BCM2708_I2S_STBY); -+ -+ return 0; -+} -+ -+static void bcm2708_i2s_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ bcm2708_i2s_stop(dev, substream, dai); -+ -+ /* If both streams are stopped, disable module and clock */ -+ if (dai->active) -+ return; -+ -+ /* Disable the module */ -+ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, -+ BCM2708_I2S_EN, 0); -+ -+ /* -+ * Stopping clock is necessary, because stop does -+ * not stop the clock when SND_SOC_DAIFMT_CONT -+ */ -+ bcm2708_i2s_stop_clock(dev); -+} -+ -+static const struct snd_soc_dai_ops bcm2708_i2s_dai_ops = { -+ .startup = bcm2708_i2s_startup, -+ .shutdown = bcm2708_i2s_shutdown, -+ .prepare = bcm2708_i2s_prepare, -+ .trigger = bcm2708_i2s_trigger, -+ .hw_params = bcm2708_i2s_hw_params, -+ .set_fmt = bcm2708_i2s_set_dai_fmt, -+ .set_bclk_ratio = bcm2708_i2s_set_dai_bclk_ratio -+}; -+ -+static int bcm2708_i2s_dai_probe(struct snd_soc_dai *dai) -+{ -+ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); -+ -+ dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; -+ dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; -+ -+ return 0; -+} -+ -+static struct snd_soc_dai_driver bcm2708_i2s_dai = { -+ .name = "bcm2708-i2s", -+ .probe = bcm2708_i2s_dai_probe, -+ .playback = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE -+ | SNDRV_PCM_FMTBIT_S24_LE -+ | SNDRV_PCM_FMTBIT_S32_LE -+ }, -+ .capture = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE -+ | SNDRV_PCM_FMTBIT_S24_LE -+ | SNDRV_PCM_FMTBIT_S32_LE -+ }, -+ .ops = &bcm2708_i2s_dai_ops, -+ .symmetric_rates = 1 -+}; -+ -+static bool bcm2708_i2s_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case BCM2708_I2S_CS_A_REG: -+ case BCM2708_I2S_FIFO_A_REG: -+ case BCM2708_I2S_INTSTC_A_REG: -+ case BCM2708_I2S_GRAY_REG: -+ return true; -+ default: -+ return false; -+ }; -+} -+ -+static bool bcm2708_i2s_precious_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case BCM2708_I2S_FIFO_A_REG: -+ return true; -+ default: -+ return false; -+ }; -+} -+ -+static bool bcm2708_clk_volatile_reg(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case BCM2708_CLK_PCMCTL_REG: -+ return true; -+ default: -+ return false; -+ }; -+} -+ -+static const struct regmap_config bcm2708_regmap_config[] = { -+ { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = BCM2708_I2S_GRAY_REG, -+ .precious_reg = bcm2708_i2s_precious_reg, -+ .volatile_reg = bcm2708_i2s_volatile_reg, -+ .cache_type = REGCACHE_RBTREE, -+ .name = "i2s", -+ }, -+ { -+ .reg_bits = 32, -+ .reg_stride = 4, -+ .val_bits = 32, -+ .max_register = BCM2708_CLK_PCMDIV_REG, -+ .volatile_reg = bcm2708_clk_volatile_reg, -+ .cache_type = REGCACHE_RBTREE, -+ .name = "clk", -+ }, -+}; -+ -+static const struct snd_soc_component_driver bcm2708_i2s_component = { -+ .name = "bcm2708-i2s-comp", -+}; -+ -+static const struct snd_pcm_hardware bcm2708_pcm_hardware = { -+ .info = SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_JOINT_DUPLEX, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE, -+ .period_bytes_min = 32, -+ .period_bytes_max = 64 * PAGE_SIZE, -+ .periods_min = 2, -+ .periods_max = 255, -+ .buffer_bytes_max = 128 * PAGE_SIZE, -+}; -+ -+static const struct snd_dmaengine_pcm_config bcm2708_dmaengine_pcm_config = { -+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, -+ .pcm_hardware = &bcm2708_pcm_hardware, -+ .prealloc_buffer_size = 256 * PAGE_SIZE, -+}; -+ -+ -+static int bcm2708_i2s_probe(struct platform_device *pdev) -+{ -+ struct bcm2708_i2s_dev *dev; -+ int i; -+ int ret; -+ struct regmap *regmap[2]; -+ struct resource *mem[2]; -+ -+ /* Request both ioareas */ -+ for (i = 0; i <= 1; i++) { -+ void __iomem *base; -+ -+ mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); -+ base = devm_ioremap_resource(&pdev->dev, mem[i]); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, -+ &bcm2708_regmap_config[i]); -+ if (IS_ERR(regmap[i])) { -+ dev_err(&pdev->dev, "I2S probe: regmap init failed\n"); -+ return PTR_ERR(regmap[i]); -+ } -+ } -+ -+ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), -+ GFP_KERNEL); -+ if (IS_ERR(dev)) -+ return PTR_ERR(dev); -+ -+ dev->i2s_regmap = regmap[0]; -+ dev->clk_regmap = regmap[1]; -+ -+ /* Set the DMA address */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = -+ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; -+ -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = -+ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; -+ -+ /* Set the DREQ */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].slave_id = -+ BCM2708_DMA_DREQ_PCM_TX; -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].slave_id = -+ BCM2708_DMA_DREQ_PCM_RX; -+ -+ /* Set the bus width */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = -+ DMA_SLAVE_BUSWIDTH_4_BYTES; -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = -+ DMA_SLAVE_BUSWIDTH_4_BYTES; -+ -+ /* Set burst */ -+ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; -+ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; -+ -+ /* BCLK ratio - use default */ -+ dev->bclk_ratio = 0; -+ -+ /* Store the pdev */ -+ dev->dev = &pdev->dev; -+ dev_set_drvdata(&pdev->dev, dev); -+ -+ ret = snd_soc_register_component(&pdev->dev, -+ &bcm2708_i2s_component, &bcm2708_i2s_dai, 1); -+ -+ if (ret) { -+ dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ ret = snd_dmaengine_pcm_register(&pdev->dev, -+ &bcm2708_dmaengine_pcm_config, -+ SND_DMAENGINE_PCM_FLAG_COMPAT); -+ if (ret) { -+ dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); -+ snd_soc_unregister_component(&pdev->dev); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int bcm2708_i2s_remove(struct platform_device *pdev) -+{ -+ snd_dmaengine_pcm_unregister(&pdev->dev); -+ snd_soc_unregister_component(&pdev->dev); -+ return 0; -+} -+ -+static const struct of_device_id bcm2708_i2s_of_match[] = { -+ { .compatible = "brcm,bcm2708-i2s", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match); -+ -+static struct platform_driver bcm2708_i2s_driver = { -+ .probe = bcm2708_i2s_probe, -+ .remove = bcm2708_i2s_remove, -+ .driver = { -+ .name = "bcm2708-i2s", -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2708_i2s_of_match, -+ }, -+}; -+ -+module_platform_driver(bcm2708_i2s_driver); -+ -+MODULE_ALIAS("platform:bcm2708-i2s"); -+MODULE_DESCRIPTION("BCM2708 I2S interface"); -+MODULE_AUTHOR("Florian Meier "); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/bcm/bcm2708-i2s.h b/sound/soc/bcm/bcm2708-i2s.h -new file mode 100644 -index 0000000..6fdcbc1 ---- /dev/null -+++ b/sound/soc/bcm/bcm2708-i2s.h -@@ -0,0 +1,35 @@ -+/* -+ * I2S configuration for sound cards. -+ * -+ * Copyright (c) 2014 Daniel Matuschek -+ * -+ * 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 BCM2708_I2S_H -+#define BCM2708_I2S_H -+ -+/* I2S pin assignment */ -+#define BCM2708_I2S_GPIO_AUTO 0 -+#define BCM2708_I2S_GPIO_PIN18 1 -+#define BCM2708_I2S_GPIO_PIN28 2 -+ -+/* Alt mode to enable I2S */ -+#define BCM2708_I2S_GPIO_PIN18_ALT 0 -+#define BCM2708_I2S_GPIO_PIN28_ALT 2 -+ -+extern void bcm2708_i2s_set_gpio(int gpio); -+ -+#endif - -From 95f9b87c32e716eb0276c9d6d1228db5a9e38a0e Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 14:59:51 +0100 -Subject: [PATCH 031/216] ASoC: Add support for PCM5102A codec - -Some definitions to support the PCM5102A codec -by Texas Instruments. - -Signed-off-by: Florian Meier ---- - sound/soc/codecs/Kconfig | 4 +++ - sound/soc/codecs/Makefile | 2 ++ - sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 69 insertions(+) - create mode 100644 sound/soc/codecs/pcm5102a.c - -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index ea9f0e3..bc39bbc 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -82,6 +82,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_I2C if I2C - select SND_SOC_PCM512x_SPI if SPI_MASTER - select SND_SOC_RT286 if I2C -+ select SND_SOC_PCM5102A if I2C - select SND_SOC_RT5631 if I2C - select SND_SOC_RT5640 if I2C - select SND_SOC_RT5645 if I2C -@@ -506,6 +507,9 @@ config SND_SOC_RT286 - tristate - depends on I2C - -+config SND_SOC_PCM5102A -+ tristate -+ - config SND_SOC_RT5631 - tristate "Realtek ALC5631/RT5631 CODEC" - depends on I2C -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 69b8666..905ef6f 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -77,6 +77,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o - snd-soc-rt286-objs := rt286.o -+snd-soc-pcm5102a-objs := pcm5102a.o - snd-soc-rt5631-objs := rt5631.o - snd-soc-rt5640-objs := rt5640.o - snd-soc-rt5645-objs := rt5645.o -@@ -259,6 +260,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o -+obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o - obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o - obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o - obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o -diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c -new file mode 100644 -index 0000000..126f1e9 ---- /dev/null -+++ b/sound/soc/codecs/pcm5102a.c -@@ -0,0 +1,63 @@ -+/* -+ * Driver for the PCM5102A codec -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include -+ -+static struct snd_soc_dai_driver pcm5102a_dai = { -+ .name = "pcm5102a-hifi", -+ .playback = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE | -+ SNDRV_PCM_FMTBIT_S32_LE -+ }, -+}; -+ -+static struct snd_soc_codec_driver soc_codec_dev_pcm5102a; -+ -+static int pcm5102a_probe(struct platform_device *pdev) -+{ -+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a, -+ &pcm5102a_dai, 1); -+} -+ -+static int pcm5102a_remove(struct platform_device *pdev) -+{ -+ snd_soc_unregister_codec(&pdev->dev); -+ return 0; -+} -+ -+static struct platform_driver pcm5102a_codec_driver = { -+ .probe = pcm5102a_probe, -+ .remove = pcm5102a_remove, -+ .driver = { -+ .name = "pcm5102a-codec", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(pcm5102a_codec_driver); -+ -+MODULE_DESCRIPTION("ASoC PCM5102A codec driver"); -+MODULE_AUTHOR("Florian Meier "); -+MODULE_LICENSE("GPL v2"); - -From b8442f0526d6de697deec639e36023a92a2d178a Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 19:04:54 +0100 -Subject: [PATCH 032/216] BCM2708: Add I2S support to board file - -Adds the required initializations for I2S -to the board file of mach-bcm2708. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5873f8b..7f4ebf4 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -613,6 +613,28 @@ static struct platform_device bcm2835_thermal_device = { - .name = "bcm2835_thermal", - }; - -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+static struct resource bcm2708_i2s_resources[] = { -+ { -+ .start = I2S_BASE, -+ .end = I2S_BASE + 0x20, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = PCM_CLOCK_BASE, -+ .end = PCM_CLOCK_BASE + 0x02, -+ .flags = IORESOURCE_MEM, -+ } -+}; -+ -+static struct platform_device bcm2708_i2s_device = { -+ .name = "bcm2708-i2s", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), -+ .resource = bcm2708_i2s_resources, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -762,6 +784,10 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); - -+#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -+ bcm_register_device_dt(&bcm2708_i2s_device); -+#endif -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - -From 40cf34f896f3ac88ad775464619175b5167ddacb Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 19:19:08 +0100 -Subject: [PATCH 033/216] ASoC: Add support for HifiBerry DAC - -This adds a machine driver for the HifiBerry DAC. -It is a sound card that can -be stacked onto the Raspberry Pi. - -Signed-off-by: Florian Meier ---- - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 5 +++ - sound/soc/bcm/hifiberry_dac.c | 100 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 112 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_dac.c - -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 8642296..a92adb2 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -18,3 +18,10 @@ config SND_BCM2708_SOC_I2S - Say Y or M if you want to add support for codecs attached to - the BCM2708 I2S interface. You will also need - to select the audio interfaces to support below. -+ -+config SND_BCM2708_SOC_HIFIBERRY_DAC -+ tristate "Support for HifiBerry DAC" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM5102A -+ help -+ Say Y or M if you want to add support for HifiBerry DAC. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index f8bbe1f..be90a49cb 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -7,3 +7,8 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o - snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o - - obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o -+ -+# BCM2708 Machine Support -+snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+ -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c -new file mode 100644 -index 0000000..4b70b45 ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_dac.c -@@ -0,0 +1,100 @@ -+/* -+ * ASoC Driver for HifiBerry DAC -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_hifiberry_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ unsigned int sample_bits = -+ snd_pcm_format_physical_width(params_format(params)); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_dac_ops = { -+ .hw_params = snd_rpi_hifiberry_dac_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = { -+{ -+ .name = "HifiBerry DAC", -+ .stream_name = "HifiBerry DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm5102a-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm5102a-codec", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_dac_ops, -+ .init = snd_rpi_hifiberry_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_dac = { -+ .name = "snd_rpi_hifiberry_dac", -+ .dai_link = snd_rpi_hifiberry_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), -+}; -+ -+static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_dac.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); -+} -+ -+static struct platform_driver snd_rpi_hifiberry_dac_driver = { -+ .driver = { -+ .name = "snd-hifiberry-dac", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_dac_probe, -+ .remove = snd_rpi_hifiberry_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_hifiberry_dac_driver); -+ -+MODULE_AUTHOR("Florian Meier "); -+MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); -+MODULE_LICENSE("GPL v2"); - -From c2ef063e2adb0e41654dc580ae959a86cde6f6f5 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 22 Nov 2013 19:21:34 +0100 -Subject: [PATCH 034/216] BCM2708: Add HifiBerry DAC to board file - -This adds the initalization of the HifiBerry DAC -to the mach-bcm2708 board file. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 7f4ebf4..94ce8fc 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -635,6 +635,20 @@ static struct platform_device bcm2708_i2s_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+static struct platform_device snd_hifiberry_dac_device = { -+ .name = "snd-hifiberry-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm5102a_codec_device = { -+ .name = "pcm5102a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -788,6 +802,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2708_i2s_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_dac_device); -+ bcm_register_device_dt(&snd_pcm5102a_codec_device); -+#endif -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - -From 1de129c2113a6fb145e654260b683e6c7e30bb51 Mon Sep 17 00:00:00 2001 -From: Florian Meier -Date: Fri, 6 Dec 2013 20:50:28 +0100 -Subject: [PATCH 035/216] ASoC: BCM2708: Add support for RPi-DAC - -This adds a machine driver for the RPi-DAC. - -Signed-off-by: Florian Meier ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ - sound/soc/codecs/Kconfig | 4 ++ - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ - 7 files changed, 193 insertions(+) - create mode 100644 sound/soc/bcm/rpi-dac.c - create mode 100644 sound/soc/codecs/pcm1794a.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 94ce8fc..fb955755 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -649,6 +649,20 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+static struct platform_device snd_rpi_dac_device = { -+ .name = "snd-rpi-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct platform_device snd_pcm1794a_codec_device = { -+ .name = "pcm1794a-codec", -+ .id = -1, -+ .num_resources = 0, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -807,6 +821,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_dac_device); -+ bcm_register_device_dt(&snd_pcm1794a_codec_device); -+#endif -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index a92adb2..64c61ac 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -25,3 +25,10 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC - select SND_SOC_PCM5102A - help - Say Y or M if you want to add support for HifiBerry DAC. -+ -+config SND_BCM2708_SOC_RPI_DAC -+ tristate "Support for RPi-DAC" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM1794A -+ help -+ Say Y or M if you want to add support for RPi-DAC. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index be90a49cb..ccc9809 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -10,5 +10,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - - # BCM2708 Machine Support - snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+snd-soc-rpi-dac-objs := rpi-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o -diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c -new file mode 100644 -index 0000000..6d6e0ba ---- /dev/null -+++ b/sound/soc/bcm/rpi-dac.c -@@ -0,0 +1,97 @@ -+/* -+ * ASoC Driver for RPi-DAC. -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_rpi_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ return 0; -+} -+ -+static int snd_rpi_rpi_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_rpi_dac_ops = { -+ .hw_params = snd_rpi_rpi_dac_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = { -+{ -+ .name = "RPi-DAC", -+ .stream_name = "RPi-DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm1794a-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm1794a-codec", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_rpi_dac_ops, -+ .init = snd_rpi_rpi_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_rpi_dac = { -+ .name = "snd_rpi_rpi_dac", -+ .dai_link = snd_rpi_rpi_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), -+}; -+ -+static int snd_rpi_rpi_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_rpi_dac.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_rpi_dac); -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_rpi_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_rpi_dac); -+} -+ -+static struct platform_driver snd_rpi_rpi_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-dac", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_rpi_dac_probe, -+ .remove = snd_rpi_rpi_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_rpi_dac_driver); -+ -+MODULE_AUTHOR("Florian Meier "); -+MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index bc39bbc..8682bcf 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -83,6 +83,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_PCM512x_SPI if SPI_MASTER - select SND_SOC_RT286 if I2C - select SND_SOC_PCM5102A if I2C -+ select SND_SOC_PCM1794A if I2C - select SND_SOC_RT5631 if I2C - select SND_SOC_RT5640 if I2C - select SND_SOC_RT5645 if I2C -@@ -507,6 +508,9 @@ config SND_SOC_RT286 - tristate - depends on I2C - -+config SND_SOC_PCM1794A -+ tristate -+ - config SND_SOC_PCM5102A - tristate - -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index 905ef6f..c9bceba 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -77,6 +77,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o - snd-soc-pcm512x-spi-objs := pcm512x-spi.o - snd-soc-rl6231-objs := rl6231.o - snd-soc-rt286-objs := rt286.o -+snd-soc-pcm1794a-objs := pcm1794a.o - snd-soc-pcm5102a-objs := pcm5102a.o - snd-soc-rt5631-objs := rt5631.o - snd-soc-rt5640-objs := rt5640.o -@@ -260,6 +261,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o - obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o - obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o - obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o -+obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o - obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o - obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o - obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o -diff --git a/sound/soc/codecs/pcm1794a.c b/sound/soc/codecs/pcm1794a.c -new file mode 100644 -index 0000000..b4eaa44 ---- /dev/null -+++ b/sound/soc/codecs/pcm1794a.c -@@ -0,0 +1,62 @@ -+/* -+ * Driver for the PCM1794A codec -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+ -+#include -+#include -+#include -+ -+#include -+ -+static struct snd_soc_dai_driver pcm1794a_dai = { -+ .name = "pcm1794a-hifi", -+ .playback = { -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE | -+ SNDRV_PCM_FMTBIT_S24_LE -+ }, -+}; -+ -+static struct snd_soc_codec_driver soc_codec_dev_pcm1794a; -+ -+static int pcm1794a_probe(struct platform_device *pdev) -+{ -+ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm1794a, -+ &pcm1794a_dai, 1); -+} -+ -+static int pcm1794a_remove(struct platform_device *pdev) -+{ -+ snd_soc_unregister_codec(&pdev->dev); -+ return 0; -+} -+ -+static struct platform_driver pcm1794a_codec_driver = { -+ .probe = pcm1794a_probe, -+ .remove = pcm1794a_remove, -+ .driver = { -+ .name = "pcm1794a-codec", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+module_platform_driver(pcm1794a_codec_driver); -+ -+MODULE_DESCRIPTION("ASoC PCM1794A codec driver"); -+MODULE_AUTHOR("Florian Meier "); -+MODULE_LICENSE("GPL v2"); - -From 11dea4325311685b8d38b791b519e74a561476ca Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Wed, 15 Jan 2014 21:41:23 +0100 -Subject: [PATCH 036/216] ASoC: wm8804: Implement MCLK configuration options, - add 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs - for most sample rates. At 192kHz only 128xfs is supported. The existing - driver selects 128xfs automatically for some lower samples rates. By using an - additional mclk_div divider, it is now possible to control the behaviour. - This allows using 256xfs PLL frequency on all sample rates up to 96kHz. It - should allow lower jitter and better signal quality. The behavior has to be - controlled by the sound card driver, because some sample frequency share the - same setting. e.g. 192kHz and 96kHz use 24.576MHz master clock. The only - difference is the MCLK divider. - -This also added support for 32bit data. - -Signed-off-by: Daniel Matuschek ---- - sound/soc/codecs/wm8804.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index b2b0e68..ba2a0f8 100644 ---- a/sound/soc/codecs/wm8804.c -+++ b/sound/soc/codecs/wm8804.c -@@ -278,6 +278,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream, - blen = 0x1; - break; - case 24: -+ case 32: - blen = 0x2; - break; - default: -@@ -621,7 +622,7 @@ static const struct snd_soc_dai_ops wm8804_dai_ops = { - }; - - #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ -- SNDRV_PCM_FMTBIT_S24_LE) -+ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) - - #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ - -From 84aed3cc8e8d60407b60cd132fe7a673024fb1a4 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Wed, 15 Jan 2014 21:42:08 +0100 -Subject: [PATCH 037/216] ASoC: BCM:Add support for HiFiBerry Digi. Driver is - based on the patched WM8804 driver. - -Signed-off-by: Daniel Matuschek ---- - sound/soc/bcm/Kconfig | 7 ++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_digi.c | 153 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 162 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_digi.c - -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 64c61ac..d4a00fc 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC - help - Say Y or M if you want to add support for HifiBerry DAC. - -+config SND_BCM2708_SOC_HIFIBERRY_DIGI -+ tristate "Support for HifiBerry Digi" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_WM8804 -+ help -+ Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. -+ - config SND_BCM2708_SOC_RPI_DAC - tristate "Support for RPi-DAC" - depends on SND_BCM2708_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index ccc9809..826df7d 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -10,7 +10,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - - # BCM2708 Machine Support - snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-rpi-dac-objs := rpi-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -new file mode 100644 -index 0000000..446ecdd ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -0,0 +1,153 @@ -+/* -+ * ASoC Driver for HifiBerry Digi -+ * -+ * Author: Daniel Matuschek -+ * based on the HifiBerry DAC driver by Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/wm8804.h" -+ -+static int samplerate=44100; -+ -+static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ /* enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *codec_dai = rtd->codec_dai; -+ struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ int sysclk = 27000000; /* This is fixed on this board */ -+ -+ long mclk_freq=0; -+ int mclk_div=1; -+ -+ int ret; -+ -+ samplerate = params_rate(params); -+ -+ switch (samplerate) { -+ case 44100: -+ case 48000: -+ case 88200: -+ case 96000: -+ mclk_freq=samplerate*256; -+ mclk_div=WM8804_MCLKDIV_256FS; -+ break; -+ case 176400: -+ case 192000: -+ mclk_freq=samplerate*128; -+ mclk_div=WM8804_MCLKDIV_128FS; -+ break; -+ default: -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK, unsupported samplerate\n"); -+ } -+ -+ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); -+ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); -+ -+ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, -+ sysclk, SND_SOC_CLOCK_OUT); -+ if (ret < 0) { -+ dev_err(codec->dev, -+ "Failed to set WM8804 SYSCLK: %d\n", ret); -+ return ret; -+ } -+ -+ /* Enable TX output */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); -+ -+ /* Power on */ -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai,64); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = { -+ .hw_params = snd_rpi_hifiberry_digi_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { -+{ -+ .name = "HifiBerry Digi", -+ .stream_name = "HifiBerry Digi HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "wm8804-spdif", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "wm8804.1-003b", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBM_CFM, -+ .ops = &snd_rpi_hifiberry_digi_ops, -+ .init = snd_rpi_hifiberry_digi_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_digi = { -+ .name = "snd_rpi_hifiberry_digi", -+ .dai_link = snd_rpi_hifiberry_digi_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), -+}; -+ -+static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_digi.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); -+ if (ret) -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); -+} -+ -+static struct platform_driver snd_rpi_hifiberry_digi_driver = { -+ .driver = { -+ .name = "snd-hifiberry-digi", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_digi_probe, -+ .remove = snd_rpi_hifiberry_digi_remove, -+}; -+ -+module_platform_driver(snd_rpi_hifiberry_digi_driver); -+ -+MODULE_AUTHOR("Daniel Matuschek "); -+MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); -+MODULE_LICENSE("GPL v2"); - -From 4d5dd3c3d6019cf233add726cbe3aac6e543c540 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Thu, 16 Jan 2014 07:26:08 +0100 -Subject: [PATCH 038/216] BCM2708: Added support for HiFiBerry Digi board Board - initalization by I2C - -Signed-off-by: Daniel Matuschek ---- - arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index fb955755..0ad5343 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -649,6 +649,21 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+static struct platform_device snd_hifiberry_digi_device = { -+ .name = "snd-hifiberry-digi", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("wm8804", 0x3b) -+ }, -+}; -+ -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - static struct platform_device snd_rpi_dac_device = { - .name = "snd-rpi-dac", -@@ -821,6 +836,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_digi_device); -+ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - bcm_register_device_dt(&snd_rpi_dac_device); - bcm_register_device_dt(&snd_pcm1794a_codec_device); - -From 963fd96f5747dd0c693a87cbb23bc1239d3bda72 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Thu, 16 Jan 2014 07:36:35 +0100 -Subject: [PATCH 039/216] ASoC: wm8804: Set idle_bias_off to false Idle bias - has been change to remove warning on driver startup - -Signed-off-by: Daniel Matuschek ---- - sound/soc/codecs/wm8804.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c -index ba2a0f8..91974f9 100644 ---- a/sound/soc/codecs/wm8804.c -+++ b/sound/soc/codecs/wm8804.c -@@ -653,7 +653,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { - .probe = wm8804_probe, - .remove = wm8804_remove, - .set_bias_level = wm8804_set_bias_level, -- .idle_bias_off = true, -+ .idle_bias_off = false, - - .controls = wm8804_snd_controls, - .num_controls = ARRAY_SIZE(wm8804_snd_controls), - -From f5995e9c2cc2d801d5b05e3f4be0bdafb184943a Mon Sep 17 00:00:00 2001 -From: Gordon Garrity -Date: Sat, 8 Mar 2014 16:56:57 +0000 -Subject: [PATCH 040/216] Add IQaudIO Sound Card support for Raspberry Pi - ---- - arch/arm/mach-bcm2708/bcm2708.c | 22 ++++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/iqaudio-dac.c | 111 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 142 insertions(+) - create mode 100644 sound/soc/bcm/iqaudio-dac.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 0ad5343..a812b51 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -678,6 +678,22 @@ static struct platform_device snd_pcm1794a_codec_device = { - }; - #endif - -+ -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+static struct platform_device snd_rpi_iqaudio_dac_device = { -+ .name = "snd-rpi-iqaudio-dac", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+// Use the actual device name rather than generic driver name -+static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4c) -+ }, -+}; -+#endif -+ - int __init bcm_register_device(struct platform_device *pdev) - { - int ret; -@@ -846,6 +862,12 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm1794a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) -+ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); -+#endif -+ -+ - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index d4a00fc..faa89ef 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -39,3 +39,10 @@ config SND_BCM2708_SOC_RPI_DAC - select SND_SOC_PCM1794A - help - Say Y or M if you want to add support for RPi-DAC. -+ -+config SND_BCM2708_SOC_IQAUDIO_DAC -+ tristate "Support for IQaudIO-DAC" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM512x_I2C -+ help -+ Say Y or M if you want to add support for IQaudIO-DAC. -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index 826df7d..d597fb0 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -12,7 +12,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - snd-soc-hifiberry-dac-objs := hifiberry_dac.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-rpi-dac-objs := rpi-dac.o -+snd-soc-iqaudio-dac-objs := iqaudio-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -new file mode 100644 -index 0000000..8d0e2ae ---- /dev/null -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -0,0 +1,111 @@ -+/* -+ * ASoC Driver for IQaudIO DAC -+ * -+ * Author: Florian Meier -+ * Copyright 2013 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) -+{ -+// NOT USED struct snd_soc_codec *codec = rtd->codec; -+ -+ return 0; -+} -+ -+static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+// NOT USED struct snd_soc_dai *codec_dai = rtd->codec_dai; -+// NOT USED struct snd_soc_codec *codec = rtd->codec; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ unsigned int sample_bits = -+ snd_pcm_format_physical_width(params_format(params)); -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = { -+ .hw_params = snd_rpi_iqaudio_dac_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { -+{ -+ .name = "IQaudIO DAC", -+ .stream_name = "IQaudIO DAC HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm512x-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm512x.1-004c", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_iqaudio_dac_ops, -+ .init = snd_rpi_iqaudio_dac_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_iqaudio_dac = { -+ .name = "IQaudIODAC", -+ .dai_link = snd_rpi_iqaudio_dac_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), -+}; -+ -+static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_iqaudio_dac.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_iqaudio_dac); -+} -+ -+static const struct of_device_id iqaudio_of_match[] = { -+ { .compatible = "iqaudio,iqaudio-dac", }, -+ {}, -+}; -+ -+static struct platform_driver snd_rpi_iqaudio_dac_driver = { -+ .driver = { -+ .name = "snd-rpi-iqaudio-dac", -+ .owner = THIS_MODULE, -+ .of_match_table = iqaudio_of_match, -+ }, -+ .probe = snd_rpi_iqaudio_dac_probe, -+ .remove = snd_rpi_iqaudio_dac_remove, -+}; -+ -+module_platform_driver(snd_rpi_iqaudio_dac_driver); -+ -+MODULE_AUTHOR("Florian Meier "); -+MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); -+MODULE_LICENSE("GPL v2"); - -From 5d1809ba161ed01404974ad13403d23a008bd181 Mon Sep 17 00:00:00 2001 -From: Howard Mitchell -Date: Mon, 2 Mar 2015 17:28:02 +0000 -Subject: [PATCH 041/216] Set a limit of 0dB on Digital Volume Control - -The main volume control in the PCM512x DAC has a range up to -+24dB. This is dangerously loud and can potentially cause massive -clipping in the output stages. Therefore this sets a sensible -limit of 0dB for this control. ---- - sound/soc/bcm/iqaudio-dac.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index 8d0e2ae..aff7377 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -25,7 +25,13 @@ - - static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) - { --// NOT USED struct snd_soc_codec *codec = rtd->codec; -+ int ret; -+ struct snd_soc_card *card = rtd->card; -+ struct snd_soc_codec *codec = rtd->codec; -+ -+ ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); -+ if (ret < 0) -+ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); - - return 0; - } - -From 8dbd2bddafe5d604e9f03a702d5ae50c0dd791e6 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 18 Jun 2014 13:42:01 +0100 -Subject: [PATCH 042/216] vmstat: Workaround for issue where dirty page count - goes negative - -See: -https://github.com/raspberrypi/linux/issues/617 -http://www.spinics.net/lists/linux-mm/msg72236.html ---- - include/linux/vmstat.h | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h -index 82e7db7..f87d16d 100644 ---- a/include/linux/vmstat.h -+++ b/include/linux/vmstat.h -@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) - static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) - { - atomic_long_dec(&zone->vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) -+ atomic_long_set(&zone->vm_stat[item], 0); - atomic_long_dec(&vm_stat[item]); -+ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) -+ atomic_long_set(&vm_stat[item], 0); - } - - static inline void __inc_zone_page_state(struct page *page, - -From 15bf30debd62320326c6a474f69eabbf3b43029e Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 13 Apr 2015 18:55:53 +0100 -Subject: [PATCH 043/216] BCM2708: armctrl: Add IRQ Device Tree support - -Add Device Tree IRQ support for BCM2708. -Usage is the same as for irq-bcm2835. -See binding document: brcm,bcm2835-armctrl-ic.txt - -A bank 3 is added to handle GPIO interrupts. This is done because -armctrl also handles GPIO interrupts. - -Signed-off-by: Noralf Tronnes - -BCM2708: armctrl: remove irq bank 3 - -irq bank 3 was needed by the pinctrl-bcm2708 and bcm2708_gpio -combination. It is no longer required. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/armctrl.c | 96 +++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 96 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c -index 96fa9b9..74bacb3 100644 ---- a/arch/arm/mach-bcm2708/armctrl.c -+++ b/arch/arm/mach-bcm2708/armctrl.c -@@ -23,6 +23,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -79,6 +81,99 @@ static void armctrl_unmask_irq(struct irq_data *d) - } - } - -+#ifdef CONFIG_OF -+ -+#define NR_IRQS_BANK0 21 -+#define NR_BANKS 3 -+#define IRQS_PER_BANK 32 -+ -+/* from drivers/irqchip/irq-bcm2835.c */ -+static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, -+ const u32 *intspec, unsigned int intsize, -+ unsigned long *out_hwirq, unsigned int *out_type) -+{ -+ if (WARN_ON(intsize != 2)) -+ return -EINVAL; -+ -+ if (WARN_ON(intspec[0] >= NR_BANKS)) -+ return -EINVAL; -+ -+ if (WARN_ON(intspec[1] >= IRQS_PER_BANK)) -+ return -EINVAL; -+ -+ if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0)) -+ return -EINVAL; -+ -+ if (intspec[0] == 0) -+ *out_hwirq = ARM_IRQ0_BASE + intspec[1]; -+ else if (intspec[0] == 1) -+ *out_hwirq = ARM_IRQ1_BASE + intspec[1]; -+ else -+ *out_hwirq = ARM_IRQ2_BASE + intspec[1]; -+ -+ /* reverse remap_irqs[] */ -+ switch (*out_hwirq) { -+ case INTERRUPT_VC_JPEG: -+ *out_hwirq = INTERRUPT_JPEG; -+ break; -+ case INTERRUPT_VC_USB: -+ *out_hwirq = INTERRUPT_USB; -+ break; -+ case INTERRUPT_VC_3D: -+ *out_hwirq = INTERRUPT_3D; -+ break; -+ case INTERRUPT_VC_DMA2: -+ *out_hwirq = INTERRUPT_DMA2; -+ break; -+ case INTERRUPT_VC_DMA3: -+ *out_hwirq = INTERRUPT_DMA3; -+ break; -+ case INTERRUPT_VC_I2C: -+ *out_hwirq = INTERRUPT_I2C; -+ break; -+ case INTERRUPT_VC_SPI: -+ *out_hwirq = INTERRUPT_SPI; -+ break; -+ case INTERRUPT_VC_I2SPCM: -+ *out_hwirq = INTERRUPT_I2SPCM; -+ break; -+ case INTERRUPT_VC_SDIO: -+ *out_hwirq = INTERRUPT_SDIO; -+ break; -+ case INTERRUPT_VC_UART: -+ *out_hwirq = INTERRUPT_UART; -+ break; -+ case INTERRUPT_VC_ARASANSDIO: -+ *out_hwirq = INTERRUPT_ARASANSDIO; -+ break; -+ } -+ -+ *out_type = IRQ_TYPE_NONE; -+ return 0; -+} -+ -+static struct irq_domain_ops armctrl_ops = { -+ .xlate = armctrl_xlate -+}; -+ -+void __init armctrl_dt_init(void) -+{ -+ struct device_node *np; -+ struct irq_domain *domain; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2708-armctrl-ic"); -+ if (!np) -+ return; -+ -+ domain = irq_domain_add_legacy(np, BCM2708_ALLOC_IRQS, -+ IRQ_ARMCTRL_START, 0, -+ &armctrl_ops, NULL); -+ WARN_ON(!domain); -+} -+#else -+void __init armctrl_dt_init(void) { } -+#endif /* CONFIG_OF */ -+ - #if defined(CONFIG_PM) - - /* for kernels 3.xx use the new syscore_ops apis but for older kernels use the sys dev class */ -@@ -215,5 +310,6 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, - - armctrl_pm_register(base, irq_start, resume_sources); - init_FIQ(FIQ_START); -+ armctrl_dt_init(); - return 0; - } - -From e85c6248222486f0aca8f09ea4bf7ad463b15487 Mon Sep 17 00:00:00 2001 -From: notro -Date: Thu, 10 Jul 2014 13:59:47 +0200 -Subject: [PATCH 044/216] BCM2708: use pinctrl-bcm2835 - -Use pinctrl-bcm2835 instead of the pinctrl-bcm2708 and bcm2708_gpio -combination. - -Signed-off-by: Noralf Tronnes ---- - arch/arm/mach-bcm2708/Kconfig | 3 +++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - drivers/pinctrl/pinctrl-bcm2835.c | 2 +- - 3 files changed, 5 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 182e7ba..4cfae55 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -14,6 +14,9 @@ config BCM2708_DT - depends on MACH_BCM2708 - default n - select USE_OF -+ select ARCH_REQUIRE_GPIOLIB -+ select PINCTRL -+ select PINCTRL_BCM2835 - help - Enable Device Tree support for BCM2708 - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a812b51..a207ad8 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -816,7 +816,7 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO -- bcm_register_device(&bcm2708_gpio_device); -+ bcm_register_device_dt(&bcm2708_gpio_device); - #endif - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index 9aa8a3f..9d1149e 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { - .get = bcm2835_gpio_get, - .set = bcm2835_gpio_set, - .to_irq = bcm2835_gpio_to_irq, -- .base = -1, -+ .base = 0, - .ngpio = BCM2835_NUM_GPIOS, - .can_sleep = false, - }; - -From d00f2dcc5c02b51e10e6516e12570db41509ffe5 Mon Sep 17 00:00:00 2001 -From: notro -Date: Sun, 27 Jul 2014 20:12:58 +0200 -Subject: [PATCH 045/216] spi: bcm2708: add device tree support - -Add DT support to driver and add to .dtsi file. -Setup pins and spidev in .dts file. -SPI is disabled by default. - -Signed-off-by: Noralf Tronnes - -BCM2708: don't register SPI controller when using DT - -The device for the SPI controller is in the Device Tree. -Only register the device when not using DT. - -Signed-off-by: Noralf Tronnes - -spi: bcm2835: make driver available on ARCH_BCM2708 - -Make this driver available on ARCH_BCM2708 - -Signed-off-by: Noralf Tronnes - -bcm2708: Remove the prohibition on mixing SPIDEV and DT ---- - arch/arm/boot/dts/bcm2708.dtsi | 8 ++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 7 ++++--- - drivers/spi/Kconfig | 4 ++-- - drivers/spi/spi-bcm2708.c | 8 ++++++++ - 4 files changed, 22 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 96b7311..93f009a 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -82,5 +82,13 @@ - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; -+ -+ clk_spi: clock@2 { -+ compatible = "fixed-clock"; -+ reg = <2>; -+ #clock-cells = <0>; -+ clock-output-names = "spi"; -+ clock-frequency = <250000000>; -+ }; - }; - }; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a207ad8..e366bb4 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -836,7 +836,7 @@ void __init bcm2708_init(void) - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device(&bcm2708_alsa_devices[i]); - -- bcm_register_device(&bcm2708_spi_device); -+ bcm_register_device_dt(&bcm2708_spi_device); - bcm_register_device(&bcm2708_bsc0_device); - bcm_register_device(&bcm2708_bsc1_device); - -@@ -876,8 +876,9 @@ void __init bcm2708_init(void) - system_serial_low = serial; - - #ifdef CONFIG_BCM2708_SPIDEV -- spi_register_board_info(bcm2708_spi_devices, -- ARRAY_SIZE(bcm2708_spi_devices)); -+ if (!use_dt) -+ spi_register_board_info(bcm2708_spi_devices, -+ ARRAY_SIZE(bcm2708_spi_devices)); - #endif - } - -diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig -index 9628e75..113bf64 100644 ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -77,7 +77,7 @@ config SPI_ATMEL - - config SPI_BCM2835 - tristate "BCM2835 SPI controller" -- depends on ARCH_BCM2835 || COMPILE_TEST -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 || COMPILE_TEST - help - This selects a driver for the Broadcom BCM2835 SPI master. - -@@ -88,7 +88,7 @@ config SPI_BCM2835 - - config SPI_BCM2708 - tristate "BCM2708 SPI controller driver (SPI0)" -- depends on MACH_BCM2708 -+ depends on MACH_BCM2708 || MACH_BCM2709 - help - This selects a driver for the Broadcom BCM2708 SPI master (SPI0). This - driver is not compatible with the "Universal SPI Master" or the SPI slave -diff --git a/drivers/spi/spi-bcm2708.c b/drivers/spi/spi-bcm2708.c -index 349d21f..041b5e2 100644 ---- a/drivers/spi/spi-bcm2708.c -+++ b/drivers/spi/spi-bcm2708.c -@@ -512,6 +512,7 @@ static int bcm2708_spi_probe(struct platform_device *pdev) - master->setup = bcm2708_spi_setup; - master->transfer = bcm2708_spi_transfer; - master->cleanup = bcm2708_spi_cleanup; -+ master->dev.of_node = pdev->dev.of_node; - platform_set_drvdata(pdev, master); - - bs = spi_master_get_devdata(master); -@@ -596,10 +597,17 @@ static int bcm2708_spi_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm2708_spi_match[] = { -+ { .compatible = "brcm,bcm2708-spi", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_spi_match); -+ - static struct platform_driver bcm2708_spi_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_spi_match, - }, - .probe = bcm2708_spi_probe, - .remove = bcm2708_spi_remove, - -From 13cf0c2ef8f80ef3e128343e2d07cd3d31eb9860 Mon Sep 17 00:00:00 2001 -From: notro -Date: Tue, 29 Jul 2014 11:04:49 +0200 -Subject: [PATCH 046/216] i2c: bcm2708: add device tree support - -Add DT support to driver and add to .dtsi file. -Setup pins in .dts file. -i2c is disabled by default. - -Signed-off-by: Noralf Tronnes - -bcm2708: don't register i2c controllers when using DT - -The devices for the i2c controllers are in the Device Tree. -Only register devices when not using DT. - -Signed-off-by: Noralf Tronnes - -i2c: bcm2835: make driver available on ARCH_BCM2708 - -Make this driver available on ARCH_BCM2708 - -Signed-off-by: Noralf Tronnes ---- - arch/arm/boot/dts/bcm2708.dtsi | 7 +++++++ - arch/arm/mach-bcm2708/bcm2708.c | 4 ++-- - drivers/i2c/busses/Kconfig | 4 ++-- - drivers/i2c/busses/i2c-bcm2708.c | 24 ++++++++++++++++++++++++ - 4 files changed, 35 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 93f009a..0a916a4 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -83,6 +83,13 @@ - #address-cells = <1>; - #size-cells = <0>; - -+ clk_i2c: i2c { -+ compatible = "fixed-clock"; -+ reg = <1>; -+ #clock-cells = <0>; -+ clock-frequency = <250000000>; -+ }; -+ - clk_spi: clock@2 { - compatible = "fixed-clock"; - reg = <2>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e366bb4..a81200e 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -837,8 +837,8 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); -- bcm_register_device(&bcm2708_bsc0_device); -- bcm_register_device(&bcm2708_bsc1_device); -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); - - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); -diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig -index 00c7baa..92009dc 100644 ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -10,7 +10,7 @@ comment "PC SMBus host controller drivers" - - config I2C_BCM2708 - tristate "BCM2708 BSC" -- depends on MACH_BCM2708 -+ depends on MACH_BCM2708 || MACH_BCM2709 - help - Enabling this option will add BSC (Broadcom Serial Controller) - support for the BCM2708. BSC is a Broadcom proprietary bus compatible -@@ -381,7 +381,7 @@ config I2C_AXXIA - - config I2C_BCM2835 - tristate "Broadcom BCM2835 I2C controller" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - help - If you say yes to this option, support will be included for the - BCM2835 I2C controller. -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 7d385a3..526129b 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -303,6 +304,21 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - unsigned long bus_hz; - u32 cdiv; - -+ if (pdev->dev.of_node) { -+ u32 bus_clk_rate; -+ pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c"); -+ if (pdev->id < 0) { -+ dev_err(&pdev->dev, "alias is missing\n"); -+ return -EINVAL; -+ } -+ if (!of_property_read_u32(pdev->dev.of_node, -+ "clock-frequency", &bus_clk_rate)) -+ baudrate = bus_clk_rate; -+ else -+ dev_warn(&pdev->dev, -+ "Could not read clock-frequency property\n"); -+ } -+ - regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!regs) { - dev_err(&pdev->dev, "could not get IO memory\n"); -@@ -336,6 +352,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - adap->dev.parent = &pdev->dev; - adap->nr = pdev->id; - strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name)); -+ adap->dev.of_node = pdev->dev.of_node; - - switch (pdev->id) { - case 0: -@@ -416,10 +433,17 @@ static int bcm2708_i2c_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm2708_i2c_of_match[] = { -+ { .compatible = "brcm,bcm2708-i2c" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match); -+ - static struct platform_driver bcm2708_i2c_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_i2c_of_match, - }, - .probe = bcm2708_i2c_probe, - .remove = bcm2708_i2c_remove, - -From b36757e9c2eb66112c0cebce20ac608f1f94cbe4 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 14 Jul 2014 22:02:09 +0100 -Subject: [PATCH 047/216] hid: Reduce default mouse polling interval to 60Hz - -Reduces overhead when using X ---- - drivers/hid/usbhid/hid-core.c | 10 +++++++--- - 1 file changed, 7 insertions(+), 3 deletions(-) - -diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c -index bfbe1be..a738b25 100644 ---- a/drivers/hid/usbhid/hid-core.c -+++ b/drivers/hid/usbhid/hid-core.c -@@ -49,7 +49,7 @@ - * Module parameters. - */ - --static unsigned int hid_mousepoll_interval; -+static unsigned int hid_mousepoll_interval = ~0; - module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); - MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); - -@@ -1090,8 +1090,12 @@ static int usbhid_start(struct hid_device *hid) - } - - /* Change the polling interval of mice. */ -- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) -- interval = hid_mousepoll_interval; -+ if (hid->collection->usage == HID_GD_MOUSE) { -+ if (hid_mousepoll_interval == ~0 && interval < 16) -+ interval = 16; -+ else if (hid_mousepoll_interval != ~0 && hid_mousepoll_interval != 0) -+ interval = hid_mousepoll_interval; -+ } - - ret = -ENOMEM; - if (usb_endpoint_dir_in(endpoint)) { - -From 72f91c3f7d8b2944ccadbe7d3d57128c1fc08a8b Mon Sep 17 00:00:00 2001 -From: P33M -Date: Thu, 24 Jul 2014 21:24:03 +0100 -Subject: [PATCH 048/216] usb: core: make overcurrent messages more prominent - -Hub overcurrent messages are more serious than "debug". Increase loglevel. ---- - drivers/usb/core/hub.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c -index 3b71516..8324c14 100644 ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -4922,7 +4922,7 @@ static void port_event(struct usb_hub *hub, int port1) - if (portchange & USB_PORT_STAT_C_OVERCURRENT) { - u16 status = 0, unused; - -- dev_dbg(&port_dev->dev, "over-current change\n"); -+ dev_notice(&port_dev->dev, "over-current change\n"); - usb_clear_port_feature(hdev, port1, - USB_PORT_FEAT_C_OVER_CURRENT); - msleep(100); /* Cool down */ - -From cf880d700f626df4e4910b8dedea887720bf6018 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 7 Aug 2014 02:03:50 +0100 -Subject: [PATCH 049/216] Revert "ARM: dma: Use dma_pfn_offset for dma address - translation" - -This reverts commit 6ce0d20016925d031f1e24d64302e4c976d7cec6. ---- - arch/arm/include/asm/dma-mapping.h | 18 +----------------- - 1 file changed, 1 insertion(+), 17 deletions(-) - -diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h -index b52101d3..f5572d9 100644 ---- a/arch/arm/include/asm/dma-mapping.h -+++ b/arch/arm/include/asm/dma-mapping.h -@@ -58,37 +58,21 @@ static inline int dma_set_mask(struct device *dev, u64 mask) - #ifndef __arch_pfn_to_dma - static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) - { -- if (dev) -- pfn -= dev->dma_pfn_offset; - return (dma_addr_t)__pfn_to_bus(pfn); - } - - static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) - { -- unsigned long pfn = __bus_to_pfn(addr); -- -- if (dev) -- pfn += dev->dma_pfn_offset; -- -- return pfn; -+ return __bus_to_pfn(addr); - } - - static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) - { -- if (dev) { -- unsigned long pfn = dma_to_pfn(dev, addr); -- -- return phys_to_virt(__pfn_to_phys(pfn)); -- } -- - return (void *)__bus_to_virt((unsigned long)addr); - } - - static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) - { -- if (dev) -- return pfn_to_dma(dev, virt_to_pfn(addr)); -- - return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); - } - - -From 3492b141fbae950fd9614cb643257658e5d89329 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Mon, 4 Aug 2014 10:06:56 +0200 -Subject: [PATCH 050/216] Added support for HiFiBerry DAC+ - -The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses -a different codec chip (PCM5122), therefore a new driver is necessary. ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++ - sound/soc/bcm/Kconfig | 7 +++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_dacplus.c | 119 ++++++++++++++++++++++++++++++++++++++ - 4 files changed, 147 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_dacplus.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index a81200e..5f7df9e 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -649,6 +649,20 @@ static struct platform_device snd_pcm5102a_codec_device = { - }; - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+static struct platform_device snd_rpi_hifiberry_dacplus_device = { -+ .name = "snd-rpi-hifiberry-dacplus", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("pcm5122", 0x4d) -+ }, -+}; -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) - static struct platform_device snd_hifiberry_digi_device = { - .name = "snd-hifiberry-digi", -@@ -852,6 +866,11 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&snd_pcm5102a_codec_device); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) -+ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); -+ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) - bcm_register_device_dt(&snd_hifiberry_digi_device); - i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index faa89ef..7675501 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC - help - Say Y or M if you want to add support for HifiBerry DAC. - -+config SND_BCM2708_SOC_HIFIBERRY_DACPLUS -+ tristate "Support for HifiBerry DAC+" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_PCM512x -+ help -+ Say Y or M if you want to add support for HifiBerry DAC+. -+ - config SND_BCM2708_SOC_HIFIBERRY_DIGI - tristate "Support for HifiBerry Digi" - depends on SND_BCM2708_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index d597fb0..c02e3a2 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -10,11 +10,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - - # BCM2708 Machine Support - snd-soc-hifiberry-dac-objs := hifiberry_dac.o -+snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o - snd-soc-rpi-dac-objs := rpi-dac.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -new file mode 100644 -index 0000000..c63387b ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -0,0 +1,119 @@ -+/* -+ * ASoC Driver for HiFiBerry DAC+ -+ * -+ * Author: Daniel Matuschek -+ * Copyright 2014 -+ * based on code by Florian Meier -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "../codecs/pcm512x.h" -+ -+static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); -+ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+} -+ -+static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); -+ return 0; -+} -+ -+static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); -+} -+ -+/* machine stream operations */ -+static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = { -+ .hw_params = snd_rpi_hifiberry_dacplus_hw_params, -+ .startup = snd_rpi_hifiberry_dacplus_startup, -+ .shutdown = snd_rpi_hifiberry_dacplus_shutdown, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = { -+{ -+ .name = "HiFiBerry DAC+", -+ .stream_name = "HiFiBerry DAC+ HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "pcm512x-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "pcm512x.1-004d", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_dacplus_ops, -+ .init = snd_rpi_hifiberry_dacplus_init, -+}, -+}; -+ -+/* audio machine driver */ -+static struct snd_soc_card snd_rpi_hifiberry_dacplus = { -+ .name = "snd_rpi_hifiberry_dacplus", -+ .dai_link = snd_rpi_hifiberry_dacplus_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), -+}; -+ -+static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); -+ if (ret) -+ dev_err(&pdev->dev, -+ "snd_soc_register_card() failed: %d\n", ret); -+ -+ return ret; -+} -+ -+static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); -+} -+ -+static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { -+ .driver = { -+ .name = "snd-rpi-hifiberry-dacplus", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_dacplus_probe, -+ .remove = snd_rpi_hifiberry_dacplus_remove, -+}; -+ -+module_platform_driver(snd_rpi_hifiberry_dacplus_driver); -+ -+MODULE_AUTHOR("Daniel Matuschek "); -+MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); -+MODULE_LICENSE("GPL v2"); - -From 3663a863bd1a077dfe48177181118e464a1d6f08 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Mon, 4 Aug 2014 11:09:58 +0200 -Subject: [PATCH 051/216] Added driver for HiFiBerry Amp amplifier add-on board - -The driver contains a low-level hardware driver for the TAS5713 and the -drivers for the Raspberry Pi I2S subsystem. ---- - arch/arm/mach-bcm2708/bcm2708.c | 19 +++ - sound/soc/bcm/Kconfig | 7 + - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/hifiberry_amp.c | 106 ++++++++++++ - sound/soc/codecs/Kconfig | 4 + - sound/soc/codecs/Makefile | 2 + - sound/soc/codecs/tas5713.c | 362 ++++++++++++++++++++++++++++++++++++++++ - sound/soc/codecs/tas5713.h | 210 +++++++++++++++++++++++ - 8 files changed, 712 insertions(+) - create mode 100644 sound/soc/bcm/hifiberry_amp.c - create mode 100644 sound/soc/codecs/tas5713.c - create mode 100644 sound/soc/codecs/tas5713.h - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 5f7df9e..66bc839 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -678,6 +678,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { - - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+static struct platform_device snd_hifiberry_amp_device = { -+ .name = "snd-hifiberry-amp", -+ .id = 0, -+ .num_resources = 0, -+}; -+ -+static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { -+ { -+ I2C_BOARD_INFO("tas5713", 0x1b) -+ }, -+}; -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - static struct platform_device snd_rpi_dac_device = { - .name = "snd-rpi-dac", -@@ -876,6 +890,11 @@ void __init bcm2708_init(void) - i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); - #endif - -+#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) -+ bcm_register_device_dt(&snd_hifiberry_amp_device); -+ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); -+#endif -+ - #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) - bcm_register_device_dt(&snd_rpi_dac_device); - bcm_register_device_dt(&snd_pcm1794a_codec_device); -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 7675501..40d27c1 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -40,6 +40,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI - help - Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. - -+config SND_BCM2708_SOC_HIFIBERRY_AMP -+ tristate "Support for the HifiBerry Amp" -+ depends on SND_BCM2708_SOC_I2S -+ select SND_SOC_TAS5713 -+ help -+ Say Y or M if you want to add support for the HifiBerry Amp amplifier board. -+ - config SND_BCM2708_SOC_RPI_DAC - tristate "Support for RPi-DAC" - depends on SND_BCM2708_SOC_I2S -diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile -index c02e3a2..17ea2b0 100644 ---- a/sound/soc/bcm/Makefile -+++ b/sound/soc/bcm/Makefile -@@ -12,11 +12,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o - snd-soc-hifiberry-dac-objs := hifiberry_dac.o - snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o - snd-soc-hifiberry-digi-objs := hifiberry_digi.o -+snd-soc-hifiberry-amp-objs := hifiberry_amp.o - snd-soc-rpi-dac-objs := rpi-dac.o - snd-soc-iqaudio-dac-objs := iqaudio-dac.o - - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o - obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o -+obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o - obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o - obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o -diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c -new file mode 100644 -index 0000000..1e87ee06 ---- /dev/null -+++ b/sound/soc/bcm/hifiberry_amp.c -@@ -0,0 +1,106 @@ -+/* -+ * ASoC Driver for HifiBerry AMP -+ * -+ * Author: Sebastian Eickhoff -+ * Copyright 2014 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd) -+{ -+ // ToDo: init of the dsp-registers. -+ return 0; -+} -+ -+static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params ) -+{ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; -+ -+ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); -+} -+ -+static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = { -+ .hw_params = snd_rpi_hifiberry_amp_hw_params, -+}; -+ -+static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = { -+ { -+ .name = "HifiBerry AMP", -+ .stream_name = "HifiBerry AMP HiFi", -+ .cpu_dai_name = "bcm2708-i2s.0", -+ .codec_dai_name = "tas5713-hifi", -+ .platform_name = "bcm2708-i2s.0", -+ .codec_name = "tas5713.1-001b", -+ .dai_fmt = SND_SOC_DAIFMT_I2S | -+ SND_SOC_DAIFMT_NB_NF | -+ SND_SOC_DAIFMT_CBS_CFS, -+ .ops = &snd_rpi_hifiberry_amp_ops, -+ .init = snd_rpi_hifiberry_amp_init, -+ }, -+}; -+ -+ -+static struct snd_soc_card snd_rpi_hifiberry_amp = { -+ .name = "snd_rpi_hifiberry_amp", -+ .dai_link = snd_rpi_hifiberry_amp_dai, -+ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), -+}; -+ -+ -+static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) -+{ -+ int ret = 0; -+ -+ snd_rpi_hifiberry_amp.dev = &pdev->dev; -+ -+ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp); -+ -+ if (ret != 0) { -+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -+ } -+ -+ return ret; -+} -+ -+ -+static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev) -+{ -+ return snd_soc_unregister_card(&snd_rpi_hifiberry_amp); -+} -+ -+ -+static struct platform_driver snd_rpi_hifiberry_amp_driver = { -+ .driver = { -+ .name = "snd-hifiberry-amp", -+ .owner = THIS_MODULE, -+ }, -+ .probe = snd_rpi_hifiberry_amp_probe, -+ .remove = snd_rpi_hifiberry_amp_remove, -+}; -+ -+ -+module_platform_driver(snd_rpi_hifiberry_amp_driver); -+ -+ -+MODULE_AUTHOR("Sebastian Eickhoff "); -+MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig -index 8682bcf..f49e15d 100644 ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -108,6 +108,7 @@ config SND_SOC_ALL_CODECS - select SND_SOC_TFA9879 if I2C - select SND_SOC_TLV320AIC23_I2C if I2C - select SND_SOC_TLV320AIC23_SPI if SPI_MASTER -+ select SND_SOC_TAS5713 if I2C - select SND_SOC_TLV320AIC26 if SPI_MASTER - select SND_SOC_TLV320AIC31XX if I2C - select SND_SOC_TLV320AIC32X4 if I2C -@@ -618,6 +619,9 @@ config SND_SOC_TFA9879 - tristate "NXP Semiconductors TFA9879 amplifier" - depends on I2C - -+config SND_SOC_TAS5713 -+ tristate -+ - config SND_SOC_TLV320AIC23 - tristate - -diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile -index c9bceba..078943d 100644 ---- a/sound/soc/codecs/Makefile -+++ b/sound/soc/codecs/Makefile -@@ -108,6 +108,7 @@ snd-soc-sta529-objs := sta529.o - snd-soc-stac9766-objs := stac9766.o - snd-soc-tas5086-objs := tas5086.o - snd-soc-tfa9879-objs := tfa9879.o -+snd-soc-tas5713-objs := tas5713.o - snd-soc-tlv320aic23-objs := tlv320aic23.o - snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o - snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o -@@ -289,6 +290,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o - obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o - obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o - obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o -+obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o - obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o - obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o - obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o -diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c -new file mode 100644 -index 0000000..a24c1da ---- /dev/null -+++ b/sound/soc/codecs/tas5713.c -@@ -0,0 +1,362 @@ -+/* -+ * ASoC Driver for TAS5713 -+ * -+ * Author: Sebastian Eickhoff -+ * Copyright 2014 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "tas5713.h" -+ -+ -+static struct i2c_client *i2c; -+ -+struct tas5713_priv { -+ struct regmap *regmap; -+ int mclk_div; -+ struct snd_soc_codec *codec; -+}; -+ -+static struct tas5713_priv *priv_data; -+ -+ -+ -+ -+/* -+ * _ _ ___ _ ___ _ _ -+ * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___ -+ * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-< -+ * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/ -+ * -+ */ -+ -+static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1); -+ -+ -+static const struct snd_kcontrol_new tas5713_snd_controls[] = { -+ SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv), -+ SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv) -+}; -+ -+ -+ -+ -+/* -+ * __ __ _ _ ___ _ -+ * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _ -+ * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_| -+ * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_| -+ * -+ */ -+ -+static int tas5713_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ u16 blen = 0x00; -+ -+ struct snd_soc_codec *codec; -+ codec = dai->codec; -+ priv_data->codec = dai->codec; -+ -+ switch (params_format(params)) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ blen = 0x03; -+ break; -+ case SNDRV_PCM_FORMAT_S20_3LE: -+ blen = 0x1; -+ break; -+ case SNDRV_PCM_FORMAT_S24_LE: -+ blen = 0x04; -+ break; -+ case SNDRV_PCM_FORMAT_S32_LE: -+ blen = 0x05; -+ break; -+ default: -+ dev_err(dai->dev, "Unsupported word length: %u\n", -+ params_format(params)); -+ return -EINVAL; -+ } -+ -+ // set word length -+ snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen); -+ -+ return 0; -+} -+ -+ -+static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream) -+{ -+ unsigned int val = 0; -+ -+ struct tas5713_priv *tas5713; -+ struct snd_soc_codec *codec = dai->codec; -+ tas5713 = snd_soc_codec_get_drvdata(codec); -+ -+ if (mute) { -+ val = TAS5713_SOFT_MUTE_ALL; -+ } -+ -+ return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val); -+} -+ -+ -+static const struct snd_soc_dai_ops tas5713_dai_ops = { -+ .hw_params = tas5713_hw_params, -+ .mute_stream = tas5713_mute_stream, -+}; -+ -+ -+static struct snd_soc_dai_driver tas5713_dai = { -+ .name = "tas5713-hifi", -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_8000_48000, -+ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ), -+ }, -+ .ops = &tas5713_dai_ops, -+}; -+ -+ -+ -+ -+/* -+ * ___ _ ___ _ -+ * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _ -+ * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_| -+ * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_| -+ * -+ */ -+ -+static int tas5713_remove(struct snd_soc_codec *codec) -+{ -+ struct tas5713_priv *tas5713; -+ -+ tas5713 = snd_soc_codec_get_drvdata(codec); -+ -+ return 0; -+} -+ -+ -+static int tas5713_probe(struct snd_soc_codec *codec) -+{ -+ struct tas5713_priv *tas5713; -+ int i, ret; -+ -+ i2c = container_of(codec->dev, struct i2c_client, dev); -+ -+ tas5713 = snd_soc_codec_get_drvdata(codec); -+ -+ // Reset error -+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ -+ // Trim oscillator -+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); -+ msleep(1000); -+ -+ // Reset error -+ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ -+ // Clock mode: 44/48kHz, MCLK=64xfs -+ ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); -+ -+ // I2S 24bit -+ ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); -+ -+ // Unmute -+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -+ ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); -+ -+ // Set volume to 0db -+ ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); -+ -+ // Now start programming the default initialization sequence -+ for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { -+ ret = i2c_master_send(i2c, -+ tas5713_init_sequence[i].data, -+ tas5713_init_sequence[i].size); -+ -+ if (ret < 0) { -+ printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); -+ } -+ } -+ -+ // Unmute -+ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -+ -+ -+ return 0; -+} -+ -+ -+static struct snd_soc_codec_driver soc_codec_dev_tas5713 = { -+ .probe = tas5713_probe, -+ .remove = tas5713_remove, -+ .controls = tas5713_snd_controls, -+ .num_controls = ARRAY_SIZE(tas5713_snd_controls), -+}; -+ -+ -+ -+ -+/* -+ * ___ ___ ___ ___ _ -+ * |_ _|_ ) __| | \ _ _(_)_ _____ _ _ -+ * | | / / (__ | |) | '_| \ V / -_) '_| -+ * |___/___\___| |___/|_| |_|\_/\___|_| -+ * -+ */ -+ -+static const struct reg_default tas5713_reg_defaults[] = { -+ { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB -+ { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB -+ { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB -+ { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB -+}; -+ -+ -+static bool tas5713_reg_volatile(struct device *dev, unsigned int reg) -+{ -+ switch (reg) { -+ case TAS5713_DEVICE_ID: -+ case TAS5713_ERROR_STATUS: -+ return true; -+ default: -+ return false; -+ } -+} -+ -+ -+static const struct of_device_id tas5713_of_match[] = { -+ { .compatible = "ti,tas5713", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, tas5713_of_match); -+ -+ -+static struct regmap_config tas5713_regmap_config = { -+ .reg_bits = 8, -+ .val_bits = 8, -+ -+ .max_register = TAS5713_MAX_REGISTER, -+ .volatile_reg = tas5713_reg_volatile, -+ -+ .cache_type = REGCACHE_RBTREE, -+ .reg_defaults = tas5713_reg_defaults, -+ .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults), -+}; -+ -+ -+static int tas5713_i2c_probe(struct i2c_client *i2c, -+ const struct i2c_device_id *id) -+{ -+ int ret; -+ -+ priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL); -+ if (!priv_data) -+ return -ENOMEM; -+ -+ priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config); -+ if (IS_ERR(priv_data->regmap)) { -+ ret = PTR_ERR(priv_data->regmap); -+ return ret; -+ } -+ -+ i2c_set_clientdata(i2c, priv_data); -+ -+ ret = snd_soc_register_codec(&i2c->dev, -+ &soc_codec_dev_tas5713, &tas5713_dai, 1); -+ -+ return ret; -+} -+ -+ -+static int tas5713_i2c_remove(struct i2c_client *i2c) -+{ -+ snd_soc_unregister_codec(&i2c->dev); -+ i2c_set_clientdata(i2c, NULL); -+ -+ kfree(priv_data); -+ -+ return 0; -+} -+ -+ -+static const struct i2c_device_id tas5713_i2c_id[] = { -+ { "tas5713", 0 }, -+ { } -+}; -+ -+MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id); -+ -+ -+static struct i2c_driver tas5713_i2c_driver = { -+ .driver = { -+ .name = "tas5713", -+ .owner = THIS_MODULE, -+ .of_match_table = tas5713_of_match, -+ }, -+ .probe = tas5713_i2c_probe, -+ .remove = tas5713_i2c_remove, -+ .id_table = tas5713_i2c_id -+}; -+ -+ -+static int __init tas5713_modinit(void) -+{ -+ int ret = 0; -+ -+ ret = i2c_add_driver(&tas5713_i2c_driver); -+ if (ret) { -+ printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n", -+ ret); -+ } -+ -+ return ret; -+} -+module_init(tas5713_modinit); -+ -+ -+static void __exit tas5713_exit(void) -+{ -+ i2c_del_driver(&tas5713_i2c_driver); -+} -+module_exit(tas5713_exit); -+ -+ -+MODULE_AUTHOR("Sebastian Eickhoff "); -+MODULE_DESCRIPTION("ASoC driver for TAS5713"); -+MODULE_LICENSE("GPL v2"); -diff --git a/sound/soc/codecs/tas5713.h b/sound/soc/codecs/tas5713.h -new file mode 100644 -index 0000000..8f019e0 ---- /dev/null -+++ b/sound/soc/codecs/tas5713.h -@@ -0,0 +1,210 @@ -+/* -+ * ASoC Driver for TAS5713 -+ * -+ * Author: Sebastian Eickhoff -+ * Copyright 2014 -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#ifndef _TAS5713_H -+#define _TAS5713_H -+ -+ -+// TAS5713 I2C-bus register addresses -+ -+#define TAS5713_CLOCK_CTRL 0x00 -+#define TAS5713_DEVICE_ID 0x01 -+#define TAS5713_ERROR_STATUS 0x02 -+#define TAS5713_SYSTEM_CTRL1 0x03 -+#define TAS5713_SERIAL_DATA_INTERFACE 0x04 -+#define TAS5713_SYSTEM_CTRL2 0x05 -+#define TAS5713_SOFT_MUTE 0x06 -+#define TAS5713_VOL_MASTER 0x07 -+#define TAS5713_VOL_CH1 0x08 -+#define TAS5713_VOL_CH2 0x09 -+#define TAS5713_VOL_HEADPHONE 0x0A -+#define TAS5713_VOL_CONFIG 0x0E -+#define TAS5713_MODULATION_LIMIT 0x10 -+#define TAS5713_IC_DLY_CH1 0x11 -+#define TAS5713_IC_DLY_CH2 0x12 -+#define TAS5713_IC_DLY_CH3 0x13 -+#define TAS5713_IC_DLY_CH4 0x14 -+ -+#define TAS5713_START_STOP_PERIOD 0x1A -+#define TAS5713_OSC_TRIM 0x1B -+#define TAS5713_BKND_ERR 0x1C -+ -+#define TAS5713_INPUT_MUX 0x20 -+#define TAS5713_SRC_SELECT_CH4 0x21 -+#define TAS5713_PWM_MUX 0x25 -+ -+#define TAS5713_CH1_BQ0 0x29 -+#define TAS5713_CH1_BQ1 0x2A -+#define TAS5713_CH1_BQ2 0x2B -+#define TAS5713_CH1_BQ3 0x2C -+#define TAS5713_CH1_BQ4 0x2D -+#define TAS5713_CH1_BQ5 0x2E -+#define TAS5713_CH1_BQ6 0x2F -+#define TAS5713_CH1_BQ7 0x58 -+#define TAS5713_CH1_BQ8 0x59 -+ -+#define TAS5713_CH2_BQ0 0x30 -+#define TAS5713_CH2_BQ1 0x31 -+#define TAS5713_CH2_BQ2 0x32 -+#define TAS5713_CH2_BQ3 0x33 -+#define TAS5713_CH2_BQ4 0x34 -+#define TAS5713_CH2_BQ5 0x35 -+#define TAS5713_CH2_BQ6 0x36 -+#define TAS5713_CH2_BQ7 0x5C -+#define TAS5713_CH2_BQ8 0x5D -+ -+#define TAS5713_CH4_BQ0 0x5A -+#define TAS5713_CH4_BQ1 0x5B -+#define TAS5713_CH3_BQ0 0x5E -+#define TAS5713_CH3_BQ1 0x5F -+ -+#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B -+#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C -+#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E -+#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F -+#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40 -+#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43 -+#define TAS5713_DRC_CTRL 0x46 -+ -+#define TAS5713_BANK_SW_CTRL 0x50 -+#define TAS5713_CH1_OUTPUT_MIXER 0x51 -+#define TAS5713_CH2_OUTPUT_MIXER 0x52 -+#define TAS5713_CH1_INPUT_MIXER 0x53 -+#define TAS5713_CH2_INPUT_MIXER 0x54 -+#define TAS5713_OUTPUT_POST_SCALE 0x56 -+#define TAS5713_OUTPUT_PRESCALE 0x57 -+ -+#define TAS5713_IDF_POST_SCALE 0x62 -+ -+#define TAS5713_CH1_INLINE_MIXER 0x70 -+#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71 -+#define TAS5713_CH1_R_CHANNEL_MIXER 0x72 -+#define TAS5713_CH1_L_CHANNEL_MIXER 0x73 -+#define TAS5713_CH2_INLINE_MIXER 0x74 -+#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75 -+#define TAS5713_CH2_L_CHANNEL_MIXER 0x76 -+#define TAS5713_CH2_R_CHANNEL_MIXER 0x77 -+ -+#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8 -+#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9 -+ -+#define TAS5713_REGISTER_COUNT 0x46 -+#define TAS5713_MAX_REGISTER 0xF9 -+ -+ -+// Bitmasks for registers -+#define TAS5713_SOFT_MUTE_ALL 0x07 -+ -+ -+ -+struct tas5713_init_command { -+ const int size; -+ const char *const data; -+}; -+ -+static const struct tas5713_init_command tas5713_init_sequence[] = { -+ -+ // Trim oscillator -+ { .size = 2, .data = "\x1B\x00" }, -+ // System control register 1 (0x03): block DC -+ { .size = 2, .data = "\x03\x80" }, -+ // Mute everything -+ { .size = 2, .data = "\x05\x40" }, -+ // Modulation limit register (0x10): 97.7% -+ { .size = 2, .data = "\x10\x02" }, -+ // Interchannel delay registers -+ // (0x11, 0x12, 0x13, and 0x14): BD mode -+ { .size = 2, .data = "\x11\xB8" }, -+ { .size = 2, .data = "\x12\x60" }, -+ { .size = 2, .data = "\x13\xA0" }, -+ { .size = 2, .data = "\x14\x48" }, -+ // PWM shutdown group register (0x19): no shutdown -+ { .size = 2, .data = "\x19\x00" }, -+ // Input multiplexer register (0x20): BD mode -+ { .size = 2, .data = "\x20\x00\x89\x77\x72" }, -+ // PWM output mux register (0x25) -+ // Channel 1 --> OUTA, channel 1 neg --> OUTB -+ // Channel 2 --> OUTC, channel 2 neg --> OUTD -+ { .size = 5, .data = "\x25\x01\x02\x13\x45" }, -+ // DRC control (0x46): DRC off -+ { .size = 5, .data = "\x46\x00\x00\x00\x00" }, -+ // BKND_ERR register (0x1C): 299ms reset period -+ { .size = 2, .data = "\x1C\x07" }, -+ // Mute channel 3 -+ { .size = 2, .data = "\x0A\xFF" }, -+ // Volume configuration register (0x0E): volume slew 512 steps -+ { .size = 2, .data = "\x0E\x90" }, -+ // Clock control register (0x00): 44/48kHz, MCLK=64xfs -+ { .size = 2, .data = "\x00\x60" }, -+ // Bank switch and eq control (0x50): no bank switching -+ { .size = 5, .data = "\x50\x00\x00\x00\x00" }, -+ // Volume registers (0x07, 0x08, 0x09, 0x0A) -+ { .size = 2, .data = "\x07\x20" }, -+ { .size = 2, .data = "\x08\x30" }, -+ { .size = 2, .data = "\x09\x30" }, -+ { .size = 2, .data = "\x0A\xFF" }, -+ // 0x72, 0x73, 0x76, 0x77 input mixer: -+ // no intermix between channels -+ { .size = 5, .data = "\x72\x00\x00\x00\x00" }, -+ { .size = 5, .data = "\x73\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x76\x00\x00\x00\x00" }, -+ { .size = 5, .data = "\x77\x00\x80\x00\x00" }, -+ // 0x70, 0x71, 0x74, 0x75 inline DRC mixer: -+ // no inline DRC inmix -+ { .size = 5, .data = "\x70\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x71\x00\x00\x00\x00" }, -+ { .size = 5, .data = "\x74\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x75\x00\x00\x00\x00" }, -+ // 0x56, 0x57 Output scale -+ { .size = 5, .data = "\x56\x00\x80\x00\x00" }, -+ { .size = 5, .data = "\x57\x00\x02\x00\x00" }, -+ // 0x3B, 0x3c -+ { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" }, -+ { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" }, -+ { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, -+ // 0x51, 0x52: output mixer -+ { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" }, -+ { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" }, -+ // PEQ defaults -+ { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+ { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, -+}; -+ -+ -+#endif /* _TAS5713_H */ - -From 5cd70cb7da74d3817f6037213f1a79ff31254d89 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 13 Apr 2015 19:14:18 +0100 -Subject: [PATCH 052/216] bcm2708: Allow option card devices to be configured - via DT - -If the kernel is built with Device Tree support, and if a DT blob -is provided for the kernel at boot time, then the platform devices -for option cards are not created. This avoids both the need to -blacklist unwanted devices, and the need to update the board -support code with each new device. ---- - sound/soc/bcm/bcm2835-i2s.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c -index 03fa1cb..c816526 100644 ---- a/sound/soc/bcm/bcm2835-i2s.c -+++ b/sound/soc/bcm/bcm2835-i2s.c -@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { - { .compatible = "brcm,bcm2835-i2s", }, - {}, - }; -+MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); - - static struct platform_driver bcm2835_i2s_driver = { - .probe = bcm2835_i2s_probe, - -From b2ee40fa3d362faf4071abda9f1e273b6e80ec78 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 13 Apr 2015 18:45:39 +0100 -Subject: [PATCH 053/216] Adding Device Tree support for some RPi audio cards - ---- - arch/arm/boot/dts/hifiberry-dac-overlay.dts | 34 +++++++++++++++++++++ - arch/arm/boot/dts/hifiberry-dacplus-overlay.dts | 39 +++++++++++++++++++++++++ - arch/arm/boot/dts/hifiberry-digi-overlay.dts | 39 +++++++++++++++++++++++++ - arch/arm/boot/dts/iqaudio-dac-overlay.dts | 39 +++++++++++++++++++++++++ - arch/arm/boot/dts/iqaudio-dacplus-overlay.dts | 39 +++++++++++++++++++++++++ - sound/soc/bcm/hifiberry_dac.c | 22 ++++++++++++++ - sound/soc/bcm/hifiberry_dacplus.c | 22 ++++++++++++++ - sound/soc/bcm/hifiberry_digi.c | 22 ++++++++++++++ - sound/soc/bcm/iqaudio-dac.c | 16 ++++++++++ - sound/soc/codecs/pcm5102a.c | 7 +++++ - 10 files changed, 279 insertions(+) - create mode 100644 arch/arm/boot/dts/hifiberry-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/hifiberry-dacplus-overlay.dts - create mode 100644 arch/arm/boot/dts/hifiberry-digi-overlay.dts - create mode 100644 arch/arm/boot/dts/iqaudio-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/iqaudio-dacplus-overlay.dts - -diff --git a/arch/arm/boot/dts/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/hifiberry-dac-overlay.dts -new file mode 100644 -index 0000000..5e7633a ---- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for HiFiBerry DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm5102a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5102a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -new file mode 100644 -index 0000000..deb9c625 ---- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dacplus"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/hifiberry-digi-overlay.dts -new file mode 100644 -index 0000000..d0e0d8a ---- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-digi-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Digi -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-digi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8804@3b { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8804"; -+ reg = <0x3b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/iqaudio-dac-overlay.dts -new file mode 100644 -index 0000000..ea8173e ---- /dev/null -+++ b/arch/arm/boot/dts/iqaudio-dac-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -new file mode 100644 -index 0000000..735d8ab ---- /dev/null -+++ b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c -index 4b70b45..3ab0f47 100644 ---- a/sound/soc/bcm/hifiberry_dac.c -+++ b/sound/soc/bcm/hifiberry_dac.c -@@ -72,6 +72,21 @@ static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -@@ -84,10 +99,17 @@ static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) - return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); - } - -+static const struct of_device_id snd_rpi_hifiberry_dac_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-dac", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dac_of_match); -+ - static struct platform_driver snd_rpi_hifiberry_dac_driver = { - .driver = { - .name = "snd-hifiberry-dac", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_dac_of_match, - }, - .probe = snd_rpi_hifiberry_dac_probe, - .remove = snd_rpi_hifiberry_dac_remove, -diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c -index c63387b..11e4f39 100644 ---- a/sound/soc/bcm/hifiberry_dacplus.c -+++ b/sound/soc/bcm/hifiberry_dacplus.c -@@ -90,6 +90,21 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_dacplus.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); - if (ret) - dev_err(&pdev->dev, -@@ -103,10 +118,17 @@ static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) - return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); - } - -+static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-dacplus", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match); -+ - static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { - .driver = { - .name = "snd-rpi-hifiberry-dacplus", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_dacplus_of_match, - }, - .probe = snd_rpi_hifiberry_dacplus_probe, - .remove = snd_rpi_hifiberry_dacplus_remove, -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index 446ecdd..74a8c73 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -125,6 +125,21 @@ static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_hifiberry_digi.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_digi_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); -@@ -137,10 +152,17 @@ static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) - return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); - } - -+static const struct of_device_id snd_rpi_hifiberry_digi_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-digi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_digi_of_match); -+ - static struct platform_driver snd_rpi_hifiberry_digi_driver = { - .driver = { - .name = "snd-hifiberry-digi", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_digi_of_match, - }, - .probe = snd_rpi_hifiberry_digi_probe, - .remove = snd_rpi_hifiberry_digi_remove, -diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c -index aff7377..a38e874 100644 ---- a/sound/soc/bcm/iqaudio-dac.c -+++ b/sound/soc/bcm/iqaudio-dac.c -@@ -82,6 +82,21 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) - int ret = 0; - - snd_rpi_iqaudio_dac.dev = &pdev->dev; -+ -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); - if (ret) - dev_err(&pdev->dev, -@@ -99,6 +114,7 @@ static const struct of_device_id iqaudio_of_match[] = { - { .compatible = "iqaudio,iqaudio-dac", }, - {}, - }; -+MODULE_DEVICE_TABLE(of, iqaudio_of_match); - - static struct platform_driver snd_rpi_iqaudio_dac_driver = { - .driver = { -diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c -index 126f1e9..7c6598e 100644 ---- a/sound/soc/codecs/pcm5102a.c -+++ b/sound/soc/codecs/pcm5102a.c -@@ -47,12 +47,19 @@ static int pcm5102a_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id pcm5102a_of_match[] = { -+ { .compatible = "ti,pcm5102a", }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, pcm5102a_of_match); -+ - static struct platform_driver pcm5102a_codec_driver = { - .probe = pcm5102a_probe, - .remove = pcm5102a_remove, - .driver = { - .name = "pcm5102a-codec", - .owner = THIS_MODULE, -+ .of_match_table = pcm5102a_of_match, - }, - }; - - -From ea3aad745389e9631e71c1b175e37d6874ee980b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Dec 2014 17:26:26 +0000 -Subject: [PATCH 054/216] fdt: Add support for the CONFIG_CMDLINE_EXTEND option - ---- - drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- - 1 file changed, 24 insertions(+), 5 deletions(-) - -diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c -index 3a896c9..0320a6f 100644 ---- a/drivers/of/fdt.c -+++ b/drivers/of/fdt.c -@@ -915,19 +915,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, - - /* Retrieve command line */ - p = of_get_flat_dt_prop(node, "bootargs", &l); -- if (p != NULL && l > 0) -- strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); - - /* - * CONFIG_CMDLINE is meant to be a default in case nothing else - * managed to set the command line, unless CONFIG_CMDLINE_FORCE - * is set in which case we override whatever was found earlier. -+ * -+ * However, it can be useful to be able to treat the default as -+ * a starting point to be extended using CONFIG_CMDLINE_EXTEND. - */ -+ ((char *)data)[0] = '\0'; -+ - #ifdef CONFIG_CMDLINE --#ifndef CONFIG_CMDLINE_FORCE -- if (!((char *)data)[0]) -+ strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -+ -+ if (p != NULL && l > 0) { -+#if defined(CONFIG_CMDLINE_EXTEND) -+ int len = strlen(data); -+ if (len > 0) { -+ strlcat(data, " ", COMMAND_LINE_SIZE); -+ len++; -+ } -+ strlcpy((char *)data + len, p, min((int)l, COMMAND_LINE_SIZE - len)); -+#elif defined(CONFIG_CMDLINE_FORCE) -+ pr_warning("Ignoring bootargs property (using the default kernel command line)\n"); -+#else -+ /* Neither extend nor force - just override */ -+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); - #endif -- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); -+ } -+#else /* CONFIG_CMDLINE */ -+ if (p != NULL && l > 0) { -+ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); - #endif /* CONFIG_CMDLINE */ - - pr_debug("Command line is: %s\n", (char*)data); - -From a9a57c353bdccbc5cd60d995c53d6146addf78fc Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 16 Dec 2014 10:23:48 +0000 -Subject: [PATCH 055/216] DT: Add overrides to enable i2c0, i2c1, spi and i2s - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 10 ++++++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 10 ++++++++++ - 2 files changed, 20 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 983c23f..d9886c3 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -79,3 +79,13 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2s_pins>; - }; -+ -+ -+/ { -+ __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index d8c6d15..167b22b 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -79,3 +79,13 @@ - pinctrl-names = "default"; - pinctrl-0 = <&i2s_pins>; - }; -+ -+ -+/ { -+ __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ }; -+}; - -From 4bdc71b8c2f9444a8ec6fe833cb92ba4fd4130f7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 18 Dec 2014 16:48:32 +0000 -Subject: [PATCH 056/216] lirc-rpi: Add device tree support, and a suitable - overlay - -The overlay supports DT parameters that match the old module -parameters, except that gpio_in_pull should be set using the -strings "up", "down" or "off". - -lirc-rpi: Also support pinctrl-bcm2835 in non-DT mode ---- - arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 ++++++++++++ - drivers/staging/media/lirc/lirc_rpi.c | 154 +++++++++++++++++++++++++++------ - 2 files changed, 183 insertions(+), 28 deletions(-) - create mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts - -diff --git a/arch/arm/boot/dts/lirc-rpi-overlay.dts b/arch/arm/boot/dts/lirc-rpi-overlay.dts -new file mode 100644 -index 0000000..7d5d82b ---- /dev/null -+++ b/arch/arm/boot/dts/lirc-rpi-overlay.dts -@@ -0,0 +1,57 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ lirc_rpi: lirc_rpi { -+ compatible = "rpi,lirc-rpi"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lirc_pins>; -+ status = "okay"; -+ -+ // Override autodetection of IR receiver circuit -+ // (0 = active high, 1 = active low, -1 = no override ) -+ rpi,sense = <0xffffffff>; -+ -+ // Software carrier -+ // (0 = off, 1 = on) -+ rpi,softcarrier = <1>; -+ -+ // Invert output -+ // (0 = off, 1 = on) -+ rpi,invert = <0>; -+ -+ // Enable debugging messages -+ // (0 = off, 1 = on) -+ rpi,debug = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lirc_pins: lirc_pins { -+ brcm,pins = <17 18>; -+ brcm,function = <1 0>; // out in -+ brcm,pull = <0 1>; // off down -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; -+ gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; -+ gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; -+ -+ sense = <&lirc_rpi>,"rpi,sense:0"; -+ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; -+ invert = <&lirc_rpi>,"rpi,invert:0"; -+ debug = <&lirc_rpi>,"rpi,debug:0"; -+ }; -+}; -diff --git a/drivers/staging/media/lirc/lirc_rpi.c b/drivers/staging/media/lirc/lirc_rpi.c -index 8aa452d..24563ec 100644 ---- a/drivers/staging/media/lirc/lirc_rpi.c -+++ b/drivers/staging/media/lirc/lirc_rpi.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - - #include - -@@ -303,32 +304,117 @@ static int is_right_chip(struct gpio_chip *chip, void *data) - return 0; - } - -+static inline int read_bool_property(const struct device_node *np, -+ const char *propname, -+ bool *out_value) -+{ -+ u32 value = 0; -+ int err = of_property_read_u32(np, propname, &value); -+ if (err == 0) -+ *out_value = (value != 0); -+ return err; -+} -+ -+static void read_pin_settings(struct device_node *node) -+{ -+ u32 pin; -+ int index; -+ -+ for (index = 0; -+ of_property_read_u32_index( -+ node, -+ "brcm,pins", -+ index, -+ &pin) == 0; -+ index++) { -+ u32 function; -+ int err; -+ err = of_property_read_u32_index( -+ node, -+ "brcm,function", -+ index, -+ &function); -+ if (err == 0) { -+ if (function == 1) /* Output */ -+ gpio_out_pin = pin; -+ else if (function == 0) /* Input */ -+ gpio_in_pin = pin; -+ } -+ } -+} -+ - static int init_port(void) - { - int i, nlow, nhigh, ret; -+ struct device_node *node; -+ -+ node = lirc_rpi_dev->dev.of_node; - - gpiochip = gpiochip_find("bcm2708_gpio", is_right_chip); - -- if (!gpiochip) -+ /* -+ * Because of the lack of a setpull function, only support -+ * pinctrl-bcm2835 if using device tree. -+ */ -+ if (!gpiochip && node) -+ gpiochip = gpiochip_find("pinctrl-bcm2835", is_right_chip); -+ -+ if (!gpiochip) { -+ pr_err(LIRC_DRIVER_NAME ": gpio chip not found!\n"); - return -ENODEV; -+ } -+ -+ if (node) { -+ struct device_node *pins_node; -+ -+ pins_node = of_parse_phandle(node, "pinctrl-0", 0); -+ if (!pins_node) { -+ printk(KERN_ERR LIRC_DRIVER_NAME -+ ": pinctrl settings not found!\n"); -+ ret = -EINVAL; -+ goto exit_init_port; -+ } -+ -+ read_pin_settings(pins_node); -+ -+ of_property_read_u32(node, "rpi,sense", &sense); -+ -+ read_bool_property(node, "rpi,softcarrier", &softcarrier); -+ -+ read_bool_property(node, "rpi,invert", &invert); -+ -+ read_bool_property(node, "rpi,debug", &debug); - -- if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -- printk(KERN_ALERT LIRC_DRIVER_NAME -- ": cant claim gpio pin %d\n", gpio_out_pin); -- ret = -ENODEV; -- goto exit_init_port; - } -+ else -+ { -+ if (gpio_in_pin >= BCM2708_NR_GPIOS || -+ gpio_out_pin >= BCM2708_NR_GPIOS) { -+ ret = -EINVAL; -+ printk(KERN_ERR LIRC_DRIVER_NAME -+ ": invalid GPIO pin(s) specified!\n"); -+ goto exit_init_port; -+ } - -- if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { -- printk(KERN_ALERT LIRC_DRIVER_NAME -- ": cant claim gpio pin %d\n", gpio_in_pin); -- ret = -ENODEV; -- goto exit_gpio_free_out_pin; -+ if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_out_pin); -+ ret = -ENODEV; -+ goto exit_init_port; -+ } -+ -+ if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { -+ printk(KERN_ALERT LIRC_DRIVER_NAME -+ ": cant claim gpio pin %d\n", gpio_in_pin); -+ ret = -ENODEV; -+ goto exit_gpio_free_out_pin; -+ } -+ -+ bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); -+ gpiochip->direction_input(gpiochip, gpio_in_pin); -+ gpiochip->direction_output(gpiochip, gpio_out_pin, 1); - } - -- bcm2708_gpio_setpull(gpiochip, gpio_in_pin, gpio_in_pull); -- gpiochip->direction_input(gpiochip, gpio_in_pin); -- gpiochip->direction_output(gpiochip, gpio_out_pin, 1); - gpiochip->set(gpiochip, gpio_out_pin, invert); - - irq_num = gpiochip->to_irq(gpiochip, gpio_in_pin); -@@ -522,15 +608,23 @@ static struct lirc_driver driver = { - .owner = THIS_MODULE, - }; - -+static const struct of_device_id lirc_rpi_of_match[] = { -+ { .compatible = "rpi,lirc-rpi", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, lirc_rpi_of_match); -+ - static struct platform_driver lirc_rpi_driver = { - .driver = { - .name = LIRC_DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(lirc_rpi_of_match), - }, - }; - - static int __init lirc_rpi_init(void) - { -+ struct device_node *node; - int result; - - /* Init read buffer. */ -@@ -545,15 +639,26 @@ static int __init lirc_rpi_init(void) - goto exit_buffer_free; - } - -- lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); -- if (!lirc_rpi_dev) { -- result = -ENOMEM; -- goto exit_driver_unregister; -+ node = of_find_compatible_node(NULL, NULL, -+ lirc_rpi_of_match[0].compatible); -+ -+ if (node) { -+ /* DT-enabled */ -+ lirc_rpi_dev = of_find_device_by_node(node); -+ WARN_ON(lirc_rpi_dev->dev.of_node != node); -+ of_node_put(node); - } -+ else { -+ lirc_rpi_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0); -+ if (!lirc_rpi_dev) { -+ result = -ENOMEM; -+ goto exit_driver_unregister; -+ } - -- result = platform_device_add(lirc_rpi_dev); -- if (result) -- goto exit_device_put; -+ result = platform_device_add(lirc_rpi_dev); -+ if (result) -+ goto exit_device_put; -+ } - - return 0; - -@@ -585,13 +690,6 @@ static int __init lirc_rpi_init_module(void) - if (result) - return result; - -- if (gpio_in_pin >= BCM2708_NR_GPIOS || gpio_out_pin >= BCM2708_NR_GPIOS) { -- result = -EINVAL; -- printk(KERN_ERR LIRC_DRIVER_NAME -- ": invalid GPIO pin(s) specified!\n"); -- goto exit_rpi; -- } -- - result = init_port(); - if (result < 0) - goto exit_rpi; - -From fb3c953810dfcbba431ad3c70eb5751d014db152 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 6 Jan 2015 12:06:55 +0000 -Subject: [PATCH 057/216] Fix the activity LED in DT mode - -Add a "leds" node to the base DTBs, and a subnode for the activity -LED. You can change the LED function like this: - - dtparam=act_led_trigger=heartbeat - -Add aliases for the other main nodes (soc, intc). - -Issue: linux #757 ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 18 ++++++++++++++---- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 18 ++++++++++++++---- - arch/arm/boot/dts/bcm2708.dtsi | 11 ++++++++++- - 3 files changed, 38 insertions(+), 9 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index d9886c3..95f03ba 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -7,11 +7,14 @@ - model = "Raspberry Pi Model B+"; - - aliases { -+ soc = &soc; - spi0 = &spi0; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2s = &i2s; - gpio = &gpio; -+ intc = &intc; -+ leds = &leds; - sound = &sound; - }; - -@@ -80,12 +83,19 @@ - pinctrl-0 = <&i2s_pins>; - }; - -+&act_led { -+ gpios = <&gpio 47 0>; -+}; - - / { - __overrides__ { -- i2s = <&i2s>,"status"; -- spi = <&spi0>,"status"; -- i2c0 = <&i2c0>,"status"; -- i2c1 = <&i2c1>,"status"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 167b22b..0631f45 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -7,11 +7,14 @@ - model = "Raspberry Pi Model B"; - - aliases { -+ soc = &soc; - spi0 = &spi0; - i2c0 = &i2c0; - i2c1 = &i2c1; - i2s = &i2s; - gpio = &gpio; -+ intc = &intc; -+ leds = &leds; - sound = &sound; - }; - -@@ -80,12 +83,19 @@ - pinctrl-0 = <&i2s_pins>; - }; - -+&act_led { -+ gpios = <&gpio 16 1>; -+}; - - / { - __overrides__ { -- i2s = <&i2s>,"status"; -- spi = <&spi0>,"status"; -- i2c0 = <&i2c0>,"status"; -- i2c1 = <&i2c1>,"status"; -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 0a916a4..d879316 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -11,7 +11,7 @@ - bootargs = ""; - }; - -- soc { -+ soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; -@@ -76,6 +76,15 @@ - #size-cells = <0>; - status = "disabled"; - }; -+ -+ leds: leds { -+ compatible = "gpio-leds"; -+ -+ act_led: act { -+ label = "ACT"; -+ linux,default-trigger = "mmc0"; -+ }; -+ }; - }; - - clocks { - -From 1c9f91aafc02bd624edc56899972cb13f48f921d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 15 Jan 2015 10:39:06 +0000 -Subject: [PATCH 058/216] Adding w1-gpio device tree overlays - -N.B. Requires firmware supporting multi-target overrides - -w1-gpio-overlay: - Use if a pullup pin is not required. - Parameters: - gpiopin= // default 4 - -w1-gpio-pullup-overlay: - Use if a pullup pin is required. - Parameters: - gpiopin= // default 4 - pullup= // default 5 ---- - arch/arm/boot/dts/w1-gpio-overlay.dts | 37 ++++++++++++++++++++++++++ - arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 39 ++++++++++++++++++++++++++++ - 2 files changed, 76 insertions(+) - create mode 100644 arch/arm/boot/dts/w1-gpio-overlay.dts - create mode 100644 arch/arm/boot/dts/w1-gpio-pullup-overlay.dts - -diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts -new file mode 100644 -index 0000000..b2c5ee2 ---- /dev/null -+++ b/arch/arm/boot/dts/w1-gpio-overlay.dts -@@ -0,0 +1,37 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4>; -+ brcm,function = <0>; // in (initially) -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -new file mode 100644 -index 0000000..b3e97c2 ---- /dev/null -+++ b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>, <&gpio 5 1>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4 5>; -+ brcm,function = <0 1>; // in out -+ brcm,pull = <0 0>; // off off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ pullup = <&w1>,"gpios:16", -+ <&w1_pins>,"brcm,pins:4"; -+ }; -+}; - -From 740e2da8a9fa6f84e95707ee0a10b4a4cfeaed4a Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Fri, 23 Jan 2015 16:41:17 +0100 -Subject: [PATCH 059/216] TAS5713: return error if initialisation fails - -Existing TAS5713 driver logs errors during initialisation, but does not return -an error code. Therefore even if initialisation fails, the driver will still be -loaded, but won't work. This patch fixes this. I2C communication error will now -reported correctly by a non-zero return code. ---- - sound/soc/codecs/tas5713.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c -index a24c1da..9b27138 100644 ---- a/sound/soc/codecs/tas5713.c -+++ b/sound/soc/codecs/tas5713.c -@@ -182,33 +182,40 @@ static int tas5713_probe(struct snd_soc_codec *codec) - - // Reset error - ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ if (ret < 0) return ret; - - // Trim oscillator -- ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); -+ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); -+ if (ret < 0) return ret; - msleep(1000); - - // Reset error - ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); -+ if (ret < 0) return ret; - - // Clock mode: 44/48kHz, MCLK=64xfs - ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); -+ if (ret < 0) return ret; - - // I2S 24bit - ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); -+ if (ret < 0) return ret; - - // Unmute - ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -+ if (ret < 0) return ret; - ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); -+ if (ret < 0) return ret; - - // Set volume to 0db - ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); -+ if (ret < 0) return ret; - - // Now start programming the default initialization sequence - for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { - ret = i2c_master_send(i2c, - tas5713_init_sequence[i].data, - tas5713_init_sequence[i].size); -- - if (ret < 0) { - printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); - } -@@ -216,7 +223,7 @@ static int tas5713_probe(struct snd_soc_codec *codec) - - // Unmute - ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); -- -+ if (ret < 0) return ret; - - return 0; - } - -From 9615583a44fc9449d77a247d0207b35eab1db982 Mon Sep 17 00:00:00 2001 +From 0ecc87e37d9107eb533346a4a482bbf78920d16c Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 23 Jan 2015 14:48:55 +0000 -Subject: [PATCH 060/216] scripts/dtc: Update to upstream version with overlay +Subject: [PATCH 23/77] scripts/dtc: Update to upstream version with overlay patches --- @@ -123717,736 +117880,716 @@ index 54d4e904..d644002 100644 -#define DTC_VERSION "DTC 1.4.0-dirty" +#define DTC_VERSION "DTC 1.4.1-g36c70742" -From 453099dc662c02d1308039ab2dabb176e052eabf Mon Sep 17 00:00:00 2001 +From 4cccd63c16e3ef4e2a35144e2806d1d1c56bc381 Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Fri, 23 Jan 2015 15:18:03 +0000 -Subject: [PATCH 061/216] BCM2708_DT: Build the overlays as well +Date: Mon, 11 May 2015 09:00:42 +0100 +Subject: [PATCH 24/77] scripts: Add mkknlimg and knlinfo scripts from tools + repo +The Raspberry Pi firmware looks for a trailer on the kernel image to +determine whether it was compiled with Device Tree support enabled. +If the firmware finds a kernel without this trailer, or which has a +trailer indicating that it isn't DT-capable, it disables DT support +and reverts to using ATAGs. + +The mkknlimg utility adds that trailer, having first analysed the +image to look for signs of DT support and the kernel version string. + +knlinfo displays the contents of the trailer in the given kernel image. + +scripts/mkknlimg: Add support for ARCH_BCM2835 + +Add a new trailer field indicating whether this is an ARCH_BCM2835 +build, as opposed to MACH_BCM2708/9. If the loader finds this flag +is set it changes the default base dtb file name from bcm270x... +to bcm283y... + +Also update knlinfo to show the status of the field. --- - arch/arm/boot/dts/Makefile | 9 +++++++++ - 1 file changed, 9 insertions(+) + scripts/knlinfo | 168 +++++++++++++++++++++++++++++++++ + scripts/mkknlimg | 275 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 443 insertions(+) + create mode 100755 scripts/knlinfo + create mode 100755 scripts/mkknlimg -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 25fbf52..63d902c 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,15 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+ - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb - # Keep at91 dtb files sorted alphabetically for each SoC - -From b39dde193e6242ec53938122e553e3af4cd528ed Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Sun, 25 Jan 2015 19:41:06 +0100 -Subject: [PATCH 062/216] Add device tree overlay for HiFiBerry Amp/Amp+ - -This patch add the missing device tree file for the HiFiBerry Amp and Amp+ boards. ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/hifiberry-amp-overlay.dts | 39 +++++++++++++++++++++++++++++ - 2 files changed, 40 insertions(+) - create mode 100644 arch/arm/boot/dts/hifiberry-amp-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 63d902c..63d89df 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -15,6 +15,7 @@ endif - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -diff --git a/arch/arm/boot/dts/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/hifiberry-amp-overlay.dts -new file mode 100644 -index 0000000..2c81448 +diff --git a/scripts/knlinfo b/scripts/knlinfo +new file mode 100755 +index 0000000..a0e8663 --- /dev/null -+++ b/arch/arm/boot/dts/hifiberry-amp-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Amp/Amp+ -+/dts-v1/; -+/plugin/; ++++ b/scripts/knlinfo +@@ -0,0 +1,168 @@ ++#!/usr/bin/env perl ++# ---------------------------------------------------------------------- ++# knlinfo by Phil Elwell for Raspberry Pi ++# ++# (c) 2014,2015 Raspberry Pi (Trading) Limited ++# ++# Licensed under the terms of the GNU General Public License. ++# ---------------------------------------------------------------------- + -+/ { -+ compatible = "brcm,bcm2708"; ++use strict; ++use integer; + -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-amp"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; ++use Fcntl ":seek"; + -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; ++my $trailer_magic = 'RPTL'; + -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; ++my %atom_formats = ++( ++ 'DTOK' => \&format_bool, ++ 'KVer' => \&format_string, ++ '283x' => \&format_bool, ++); + -+ tas5713@1b { -+ #sound-dai-cells = <0>; -+ compatible = "ti,tas5713"; -+ reg = <0x1b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; - -From da11da093a2c65a9faa481e0688b0f242476ee78 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 26 Jan 2015 09:18:24 +0000 -Subject: [PATCH 063/216] Add pps-gpio DT overlay - -Parameters: - gpiopin= // Default 18 ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pps-gpio-overlay.dts | 34 ++++++++++++++++++++++++++++++++++ - 2 files changed, 35 insertions(+) - create mode 100644 arch/arm/boot/dts/pps-gpio-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 63d89df..18637de 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -19,6 +19,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/pps-gpio-overlay.dts b/arch/arm/boot/dts/pps-gpio-overlay.dts -new file mode 100644 -index 0000000..40bf0e1 ---- /dev/null -+++ b/arch/arm/boot/dts/pps-gpio-overlay.dts -@@ -0,0 +1,34 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ pps: pps { -+ compatible = "pps-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pps_pins>; -+ gpios = <&gpio 18 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pps_pins: pps_pins { -+ brcm,pins = <18>; -+ brcm,function = <0>; // in -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&pps>,"gpios:4", -+ <&pps_pins>,"brcm,pins:0"; -+ }; -+}; - -From 4cddfa6e3758e34eaeeb8457e0f012965436bc1c Mon Sep 17 00:00:00 2001 -From: Timo Kokkonen -Date: Wed, 29 Oct 2014 23:30:30 -0700 -Subject: [PATCH 064/216] Added support to reserve/enable a GPIO pin to be used - from pps-gpio module (LinuxPPS). Enable PPS modules in default config for - RPi. - ---- - arch/arm/mach-bcm2708/bcm2708.c | 27 +++++++++++++++++++++++++++ - arch/arm/mach-bcm2709/bcm2709.c | 27 +++++++++++++++++++++++++++ - 2 files changed, 54 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 66bc839..cc3e56c 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -93,6 +94,7 @@ static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; -+static int pps_gpio_pin = -1; - - static unsigned use_dt = 0; - -@@ -278,6 +280,19 @@ static struct platform_device w1_device = { - }; - #endif - -+static struct pps_gpio_platform_data pps_gpio_info = { -+ .assert_falling_edge = false, -+ .capture_clear = false, -+ .gpio_pin = -1, -+ .gpio_label = "PPS", -+}; -+ -+static struct platform_device pps_gpio_device = { -+ .name = "pps-gpio", -+ .id = PLATFORM_DEVID_NONE, -+ .dev.platform_data = &pps_gpio_info, -+}; -+ - static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_fb_device = { -@@ -846,6 +861,16 @@ void __init bcm2708_init(void) - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -+ -+#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) -+ if (!use_dt && (pps_gpio_pin >= 0)) { -+ pr_info("bcm2708: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); -+ pps_gpio_info.gpio_pin = pps_gpio_pin; -+ pps_gpio_device.id = pps_gpio_pin; -+ bcm_register_device(&pps_gpio_device); -+ } -+#endif -+ - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1099,3 +1124,5 @@ module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); - module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); -+module_param(pps_gpio_pin, int, 0644); -+MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index c4bd0a4..914c970 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -95,6 +96,7 @@ static unsigned disk_led_active_low = 1; - static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; -+static int pps_gpio_pin = -1; - - static unsigned use_dt = 0; - -@@ -288,6 +290,19 @@ static struct platform_device w1_device = { - }; - #endif - -+static struct pps_gpio_platform_data pps_gpio_info = { -+ .assert_falling_edge = false, -+ .capture_clear = false, -+ .gpio_pin = -1, -+ .gpio_label = "PPS", -+}; -+ -+static struct platform_device pps_gpio_device = { -+ .name = "pps-gpio", -+ .id = PLATFORM_DEVID_NONE, -+ .dev.platform_data = &pps_gpio_info, -+}; -+ - static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_fb_device = { -@@ -868,6 +883,16 @@ void __init bcm2709_init(void) - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -+ -+#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) -+ if (!use_dt && (pps_gpio_pin >= 0)) { -+ pr_info("bcm2709: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); -+ pps_gpio_info.gpio_pin = pps_gpio_pin; -+ pps_gpio_device.id = pps_gpio_pin; -+ bcm_register_device(&pps_gpio_device); -+ } -+#endif -+ - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - w1_gpio_pdata.pin = w1_gpio_pin; - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; -@@ -1267,3 +1292,5 @@ module_param(disk_led_active_low, uint, 0644); - module_param(reboot_part, uint, 0644); - module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); -+module_param(pps_gpio_pin, int, 0644); -+MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); - -From 2ff35a0e682880dbae67c842805ea848285b373f Mon Sep 17 00:00:00 2001 -From: Serge Schneider -Date: Wed, 3 Sep 2014 14:44:22 +0100 -Subject: [PATCH 065/216] I2C: Only register the I2C device for the current - board revision - ---- - arch/arm/mach-bcm2708/bcm2708.c | 14 ++++++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 14 ++++++++++++-- - 2 files changed, 24 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index cc3e56c..c8aea5b 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -95,6 +95,7 @@ static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; - static int pps_gpio_pin = -1; -+static bool vc_i2c_override = false; - - static unsigned use_dt = 0; - -@@ -890,8 +891,15 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); -- bcm_register_device_dt(&bcm2708_bsc0_device); -- bcm_register_device_dt(&bcm2708_bsc1_device); -+ -+ if (vc_i2c_override) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ } else { -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } - - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); -@@ -1126,3 +1134,5 @@ module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); - module_param(pps_gpio_pin, int, 0644); - MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -+module_param(vc_i2c_override, bool, 0644); -+MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 914c970..259d552 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -97,6 +97,7 @@ static unsigned reboot_part = 0; - static unsigned w1_gpio_pin = W1_GPIO; - static unsigned w1_gpio_pullup = W1_PULLUP; - static int pps_gpio_pin = -1; -+static bool vc_i2c_override = false; - - static unsigned use_dt = 0; - -@@ -914,8 +915,15 @@ void __init bcm2709_init(void) - bcm_register_device(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); -- bcm_register_device_dt(&bcm2708_bsc0_device); -- bcm_register_device_dt(&bcm2708_bsc1_device); -+ -+ if (vc_i2c_override) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) { -+ bcm_register_device_dt(&bcm2708_bsc0_device); -+ } else { -+ bcm_register_device_dt(&bcm2708_bsc1_device); -+ } - - bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device(&bcm2835_thermal_device); -@@ -1294,3 +1302,5 @@ module_param(w1_gpio_pin, uint, 0644); - module_param(w1_gpio_pullup, uint, 0644); - module_param(pps_gpio_pin, int, 0644); - MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); -+module_param(vc_i2c_override, bool, 0644); -+MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); - -From 32bee38e1fca47be55a48205e850c16901127982 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 28 Jan 2015 16:22:04 +0000 -Subject: [PATCH 066/216] BCM2708_DT: Add pcf8523-rtc overlay - ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pcf8523-rtc-overlay.dts | 22 ++++++++++++++++++++++ - 2 files changed, 23 insertions(+) - create mode 100644 arch/arm/boot/dts/pcf8523-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 18637de..c909f7b 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -19,6 +19,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -diff --git a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -new file mode 100644 -index 0000000..0071f62 ---- /dev/null -+++ b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF8523 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; - -From 7358633426ec4c3897c26cb1575a0ab7309e4f73 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Sat, 31 Jan 2015 16:07:56 +0100 -Subject: [PATCH 067/216] Add a parameter to turn off SPDIF output if no audio - is playing - -This patch adds the paramater auto_shutdown_output to the kernel module. -Default behaviour of the module is the same, but when auto_shutdown_output -is set to 1, the SPDIF oputput will shutdown if no stream is playing. ---- - sound/soc/bcm/hifiberry_digi.c | 29 ++++++++++++++++++++++++++++- - 1 file changed, 28 insertions(+), 1 deletion(-) - -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index 74a8c73..a245995 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -26,6 +26,11 @@ - - #include "../codecs/wm8804.h" - -+static short int auto_shutdown_output = 0; -+module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); -+MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped"); -+ -+ - static int samplerate=44100; - - static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) -@@ -38,6 +43,25 @@ static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) - return 0; - } - -+static int snd_rpi_hifiberry_digi_startup(struct snd_pcm_substream *substream) { -+ /* turn on digital output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00); -+ return 0; ++if (@ARGV != 1) ++{ ++ print ("Usage: knlinfo \n"); ++ exit(1); +} + -+static void snd_rpi_hifiberry_digi_shutdown(struct snd_pcm_substream *substream) { -+ /* turn off output */ -+ if (auto_shutdown_output) { -+ /* turn off output */ -+ struct snd_soc_pcm_runtime *rtd = substream->private_data; -+ struct snd_soc_codec *codec = rtd->codec; -+ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c); ++my $kernel_file = $ARGV[0]; ++ ++ ++my ($atoms, $pos) = read_trailer($kernel_file); ++ ++exit(1) if (!$atoms); ++ ++printf("Kernel trailer found at %d/0x%x:\n", $pos, $pos); ++ ++foreach my $atom (@$atoms) ++{ ++ printf(" %s: %s\n", $atom->[0], format_atom($atom)); ++} ++ ++exit(0); ++ ++sub read_trailer ++{ ++ my ($kernel_file) = @_; ++ my $fh; ++ ++ if (!open($fh, '<', $kernel_file)) ++ { ++ print ("* Failed to open '$kernel_file'\n"); ++ return undef; + } ++ ++ if (!seek($fh, -12, SEEK_END)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ ++ my $last_bytes; ++ sysread($fh, $last_bytes, 12); ++ ++ my ($trailer_len, $data_len, $magic) = unpack('VVa4', $last_bytes); ++ ++ if (($magic ne $trailer_magic) || ($data_len != 4)) ++ { ++ print ("* no trailer\n"); ++ return undef; ++ } ++ if (!seek($fh, -12, SEEK_END)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ ++ $trailer_len -= 12; ++ ++ while ($trailer_len > 0) ++ { ++ if ($trailer_len < 8) ++ { ++ print ("* truncated atom header in trailer\n"); ++ return undef; ++ } ++ if (!seek($fh, -8, SEEK_CUR)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ $trailer_len -= 8; ++ ++ my $atom_hdr; ++ sysread($fh, $atom_hdr, 8); ++ my ($atom_len, $atom_type) = unpack('Va4', $atom_hdr); ++ ++ if ($trailer_len < $atom_len) ++ { ++ print ("* truncated atom data in trailer\n"); ++ return undef; ++ } ++ ++ my $rounded_len = (($atom_len + 3) & ~3); ++ if (!seek($fh, -(8 + $rounded_len), SEEK_CUR)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ $trailer_len -= $rounded_len; ++ ++ my $atom_data; ++ sysread($fh, $atom_data, $atom_len); ++ ++ if (!seek($fh, -$atom_len, SEEK_CUR)) ++ { ++ print ("* seek error in '$kernel_file'\n"); ++ return undef; ++ } ++ ++ push @$atoms, [ $atom_type, $atom_data ]; ++ } ++ ++ if (($$atoms[-1][0] eq "\x00\x00\x00\x00") && ++ ($$atoms[-1][1] eq "")) ++ { ++ pop @$atoms; ++ } ++ else ++ { ++ print ("* end marker missing from trailer\n"); ++ } ++ ++ return ($atoms, tell($fh)); ++} ++ ++sub format_atom ++{ ++ my ($atom) = @_; ++ ++ my $format_func = $atom_formats{$atom->[0]} || \&format_hex; ++ return $format_func->($atom->[1]); ++} ++ ++sub format_bool ++{ ++ my ($data) = @_; ++ return unpack('V', $data) ? 'true' : 'false'; ++} ++ ++sub format_int ++{ ++ my ($data) = @_; ++ return unpack('V', $data); ++} ++ ++sub format_string ++{ ++ my ($data) = @_; ++ return '"'.$data.'"'; ++} ++ ++sub format_hex ++{ ++ my ($data) = @_; ++ return unpack('H*', $data); ++} +diff --git a/scripts/mkknlimg b/scripts/mkknlimg +new file mode 100755 +index 0000000..3dff948 +--- /dev/null ++++ b/scripts/mkknlimg +@@ -0,0 +1,275 @@ ++#!/usr/bin/env perl ++# ---------------------------------------------------------------------- ++# mkknlimg by Phil Elwell for Raspberry Pi ++# based on extract-ikconfig by Dick Streefland ++# ++# (c) 2009,2010 Dick Streefland ++# (c) 2014,2015 Raspberry Pi (Trading) Limited ++# ++# Licensed under the terms of the GNU General Public License. ++# ---------------------------------------------------------------------- ++ ++use strict; ++use warnings; ++use integer; ++ ++my $trailer_magic = 'RPTL'; ++ ++my $tmpfile1 = "/tmp/mkknlimg_$$.1"; ++my $tmpfile2 = "/tmp/mkknlimg_$$.2"; ++ ++my $dtok = 0; ++my $is_283x = 0; ++ ++while (@ARGV && ($ARGV[0] =~ /^-/)) ++{ ++ my $arg = shift(@ARGV); ++ if ($arg eq '--dtok') ++ { ++ $dtok = 1; ++ } ++ elsif ($arg eq '--283x') ++ { ++ $is_283x = 1; ++ } ++ else ++ { ++ print ("* Unknown option '$arg'\n"); ++ usage(); ++ } ++} ++ ++usage() if (@ARGV != 2); ++ ++my $kernel_file = $ARGV[0]; ++my $out_file = $ARGV[1]; ++ ++if (! -r $kernel_file) ++{ ++ print ("* File '$kernel_file' not found\n"); ++ usage(); ++} ++ ++my @wanted_config_lines = ++( ++ 'CONFIG_BCM2708_DT', ++ 'CONFIG_ARCH_BCM2835' ++); ++ ++my @wanted_strings = ++( ++ 'bcm2708_fb', ++ 'brcm,bcm2835-mmc', ++ 'brcm,bcm2835-sdhost', ++ 'brcm,bcm2708-pinctrl', ++ 'brcm,bcm2835-gpio', ++ 'brcm,bcm2835-pm-wdt' ++); ++ ++my $res = try_extract($kernel_file, $tmpfile1); ++$res = try_decompress('\037\213\010', 'xy', 'gunzip', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\3757zXZ\000', 'abcde', 'unxz --single-stream', -1, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('BZh', 'xy', 'bunzip2', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\135\0\0\0', 'xxx', 'unlzma', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\211\114\132', 'xy', 'lzop -d', 0, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++$res = try_decompress('\002\041\114\030', 'xy', 'lz4 -d', 1, ++ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); ++ ++my $append_trailer; ++my $trailer; ++my $kver = '?'; ++ ++$append_trailer = $dtok; ++ ++if ($res) ++{ ++ $kver = $res->{''} || '?'; ++ print("Version: $kver\n"); ++ ++ $append_trailer = $dtok; ++ if (!$dtok) ++ { ++ if (config_bool($res, 'bcm2708_fb') || ++ config_bool($res, 'brcm,bcm2835-mmc') || ++ config_bool($res, 'brcm,bcm2835-sdhost')) ++ { ++ $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); ++ $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); ++ $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); ++ $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); ++ $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); ++ $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt'); ++ $append_trailer = 1; ++ } ++ else ++ { ++ print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n"); ++ } ++ } ++} ++elsif (!$dtok) ++{ ++ print ("* Is this a valid kernel? In pass-through mode.\n"); ++} ++ ++if ($append_trailer) ++{ ++ printf("DT: %s\n", $dtok ? "y" : "n"); ++ printf("283x: %s\n", $is_283x ? "y" : "n"); ++ ++ my @atoms; ++ ++ push @atoms, [ $trailer_magic, pack('V', 0) ]; ++ push @atoms, [ 'KVer', $kver ]; ++ push @atoms, [ 'DTOK', pack('V', $dtok) ]; ++ push @atoms, [ '283x', pack('V', $is_283x) ]; ++ ++ $trailer = pack_trailer(\@atoms); ++ $atoms[0]->[1] = pack('V', length($trailer)); ++ ++ $trailer = pack_trailer(\@atoms); ++} ++ ++my $ofh; ++my $total_len = 0; ++ ++if ($out_file eq $kernel_file) ++{ ++ die "* Failed to open '$out_file' for append\n" ++ if (!open($ofh, '>>', $out_file)); ++ $total_len = tell($ofh); ++} ++else ++{ ++ die "* Failed to open '$kernel_file'\n" ++ if (!open(my $ifh, '<', $kernel_file)); ++ die "* Failed to create '$out_file'\n" ++ if (!open($ofh, '>', $out_file)); ++ ++ my $copybuf; ++ while (1) ++ { ++ my $bytes = sysread($ifh, $copybuf, 64*1024); ++ last if (!$bytes); ++ syswrite($ofh, $copybuf, $bytes); ++ $total_len += $bytes; ++ } ++ close($ifh); ++} ++ ++if ($trailer) ++{ ++ # Pad to word-alignment ++ syswrite($ofh, "\x000\x000\x000", (-$total_len & 0x3)); ++ syswrite($ofh, $trailer); ++} ++ ++close($ofh); ++ ++exit($trailer ? 0 : 1); ++ ++END { ++ unlink($tmpfile1) if ($tmpfile1); ++ unlink($tmpfile2) if ($tmpfile2); +} + + - static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) - { -@@ -70,7 +94,8 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - break; - default: - dev_err(codec->dev, -- "Failed to set WM8804 SYSCLK, unsupported samplerate\n"); -+ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n", -+ samplerate); - } - - snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); -@@ -96,6 +121,8 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - /* machine stream operations */ - static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = { - .hw_params = snd_rpi_hifiberry_digi_hw_params, -+ .startup = snd_rpi_hifiberry_digi_startup, -+ .shutdown = snd_rpi_hifiberry_digi_shutdown, - }; - - static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { - -From fdcfdf08df6289445d33e8acaf68faa5f5b4923b Mon Sep 17 00:00:00 2001 -From: Joerg Hohensohn -Date: Sun, 1 Feb 2015 22:08:03 +0100 -Subject: [PATCH 068/216] bugfix for 32kHz sample rate, was missing - ---- - sound/soc/bcm/hifiberry_digi.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index a245995..a294a1b 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -80,6 +80,7 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - samplerate = params_rate(params); - - switch (samplerate) { -+ case 32000: - case 44100: - case 48000: - case 88200: - -From 601bc9883a6bf209e736d2b1cc5991176ed1abf3 Mon Sep 17 00:00:00 2001 -From: Ryan Coe -Date: Sat, 31 Jan 2015 18:25:49 -0700 -Subject: [PATCH 069/216] Update ds1307 driver for device-tree support - -Signed-off-by: Ryan Coe ---- - drivers/rtc/rtc-ds1307.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c -index 4ffabb3..c6789a7 100644 ---- a/drivers/rtc/rtc-ds1307.c -+++ b/drivers/rtc/rtc-ds1307.c -@@ -1242,6 +1242,14 @@ static int ds1307_remove(struct i2c_client *client) - return 0; - } - -+#ifdef CONFIG_OF -+static const struct of_device_id ds1307_of_match[] = { -+ { .compatible = "maxim,ds1307" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, ds1307_of_match); -+#endif ++sub usage ++{ ++ print ("Usage: mkknlimg [--dtok] [--283x] \n"); ++ exit(1); ++} + - static struct i2c_driver ds1307_driver = { - .driver = { - .name = "rtc-ds1307", - -From c6e4ebd2dec4446f061cab8fa0a860e0fe7fd30a Mon Sep 17 00:00:00 2001 -From: Ryan Coe -Date: Sat, 31 Jan 2015 18:26:03 -0700 -Subject: [PATCH 070/216] Add device-tree overlay for ds1307 - -Signed-off-by: Ryan Coe ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/ds1307-rtc-overlay.dts | 22 ++++++++++++++++++++++ - 2 files changed, 23 insertions(+) - create mode 100644 arch/arm/boot/dts/ds1307-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index c909f7b..7755a84 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - -+dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -diff --git a/arch/arm/boot/dts/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/ds1307-rtc-overlay.dts -new file mode 100644 -index 0000000..7d27044 ---- /dev/null -+++ b/arch/arm/boot/dts/ds1307-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for DS1307 Real Time Clock -+/dts-v1/; -+/plugin/; ++sub try_extract ++{ ++ my ($knl, $tmp) = @_; + -+/ { -+ compatible = "brcm,bcm2708"; ++ my $ver = `strings "$knl" | grep -a -E "^Linux version [1-9]"`; + -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; ++ return undef if (!$ver); + -+ ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; ++ chomp($ver); ++ ++ my $res = { ''=>$ver }; ++ my $string_pattern = '^('.join('|', @wanted_strings).')$'; ++ ++ my @matches = `strings \"$knl\" | grep -E \"$string_pattern\"`; ++ foreach my $match (@matches) ++ { ++ chomp($match); ++ $res->{$match} = 1; ++ } ++ ++ my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$'; ++ my $cf1 = 'IKCFG_ST\037\213\010'; ++ my $cf2 = '0123456789'; ++ ++ my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`; ++ if ($pos) ++ { ++ $pos =~ s/:.*[\r\n]*$//s; ++ $pos += 8; ++ my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8); ++ if (($err == 0) || ($err == 2)) ++ { ++ if (open(my $fh, '<', $tmp)) ++ { ++ while (my $line = <$fh>) ++ { ++ chomp($line); ++ $res->{$1} = $2 if ($line =~ /$config_pattern/); ++ } ++ ++ close($fh); ++ } ++ } ++ } ++ ++ return $res; ++} ++ ++ ++sub try_decompress ++{ ++ my ($magic, $subst, $zcat, $idx, $knl, $tmp1, $tmp2) = @_; ++ ++ my $pos = `tr "$magic\n$subst" "\n$subst=" < "$knl" | grep -abo "^$subst"`; ++ if ($pos) ++ { ++ chomp($pos); ++ $pos = (split(/[\r\n]+/, $pos))[$idx]; ++ return undef if (!defined($pos)); ++ $pos =~ s/:.*[\r\n]*$//s; ++ my $cmd = "tail -c+$pos \"$knl\" | $zcat > $tmp2 2> /dev/null"; ++ my $err = (system($cmd) >> 8); ++ return undef if (($err != 0) && ($err != 2)); ++ ++ return try_extract($tmp2, $tmp1); ++ } ++ ++ return undef; ++} ++ ++sub pack_trailer ++{ ++ my ($atoms) = @_; ++ my $trailer = pack('VV', 0, 0); ++ for (my $i = $#$atoms; $i>=0; $i--) ++ { ++ my $atom = $atoms->[$i]; ++ $trailer .= pack('a*x!4Va4', $atom->[1], length($atom->[1]), $atom->[0]); ++ } ++ return $trailer; ++} ++ ++sub config_bool ++{ ++ my ($configs, $wanted) = @_; ++ my $val = $configs->{$wanted} || 'n'; ++ return (($val eq 'y') || ($val eq '1')); ++} -From 7abd2997600af8ee74045e490c6db3a41f716636 Mon Sep 17 00:00:00 2001 +From 780d72c0e43679ff58f9f3f005ef17a5fa79ee9f Mon Sep 17 00:00:00 2001 From: Phil Elwell -Date: Fri, 6 Feb 2015 13:50:57 +0000 -Subject: [PATCH 071/216] BCM270x_DT: Add pwr_led, and the required "input" - trigger +Date: Fri, 5 Dec 2014 17:26:26 +0000 +Subject: [PATCH 25/77] fdt: Add support for the CONFIG_CMDLINE_EXTEND option -The "input" trigger makes the associated GPIO an input. This is to support -the Raspberry Pi PWR LED, which is driven by external hardware in normal use. - -N.B. pwr_led is not available on Model A or B boards. --- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 18 ++++- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 8 ++- - arch/arm/boot/dts/bcm2708.dtsi | 7 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 115 +++++++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2709.dtsi | 5 -- - drivers/leds/trigger/Kconfig | 7 ++ - drivers/leds/trigger/Makefile | 1 + - drivers/leds/trigger/ledtrig-input.c | 65 +++++++++++++++++ - 8 files changed, 213 insertions(+), 13 deletions(-) + drivers/of/fdt.c | 29 ++++++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index cde35c5d01..dd7fbfe 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -933,19 +933,38 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, + + /* Retrieve command line */ + p = of_get_flat_dt_prop(node, "bootargs", &l); +- if (p != NULL && l > 0) +- strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + + /* + * CONFIG_CMDLINE is meant to be a default in case nothing else + * managed to set the command line, unless CONFIG_CMDLINE_FORCE + * is set in which case we override whatever was found earlier. ++ * ++ * However, it can be useful to be able to treat the default as ++ * a starting point to be extended using CONFIG_CMDLINE_EXTEND. + */ ++ ((char *)data)[0] = '\0'; ++ + #ifdef CONFIG_CMDLINE +-#ifndef CONFIG_CMDLINE_FORCE +- if (!((char *)data)[0]) ++ strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); ++ ++ if (p != NULL && l > 0) { ++#if defined(CONFIG_CMDLINE_EXTEND) ++ int len = strlen(data); ++ if (len > 0) { ++ strlcat(data, " ", COMMAND_LINE_SIZE); ++ len++; ++ } ++ strlcpy((char *)data + len, p, min((int)l, COMMAND_LINE_SIZE - len)); ++#elif defined(CONFIG_CMDLINE_FORCE) ++ pr_warning("Ignoring bootargs property (using the default kernel command line)\n"); ++#else ++ /* Neither extend nor force - just override */ ++ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + #endif +- strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE); ++ } ++#else /* CONFIG_CMDLINE */ ++ if (p != NULL && l > 0) { ++ strlcpy(data, p, min((int)l, COMMAND_LINE_SIZE)); + #endif /* CONFIG_CMDLINE */ + + pr_debug("Command line is: %s\n", (char*)data); + +From 7ff1afbc6732a16d87c5640be8fec1de73a39770 Mon Sep 17 00:00:00 2001 +From: notro +Date: Wed, 9 Jul 2014 14:46:08 +0200 +Subject: [PATCH 26/77] BCM2708: Add core Device Tree support + +Add the bare minimum needed to boot BCM2708 from a Device Tree. + +Signed-off-by: Noralf Tronnes + +BCM2708: DT: change 'axi' nodename to 'soc' + +Change DT node named 'axi' to 'soc' so it matches ARCH_BCM2835. +The VC4 bootloader fills in certain properties in the 'axi' subtree, +but since this is part of an upstreaming effort, the name is changed. + +Signed-off-by: Noralf Tronnes notro@tronnes.org + +BCM2708_DT: Correct length of the peripheral space +--- + arch/arm/boot/dts/Makefile | 27 ++ + arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 140 ++++++ + arch/arm/boot/dts/bcm2708-rpi-b.dts | 130 ++++++ + arch/arm/boot/dts/bcm2708-rpi-cm.dts | 18 + + arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 51 +++ + arch/arm/boot/dts/bcm2708.dtsi | 19 + + arch/arm/boot/dts/bcm2708_common.dtsi | 230 ++++++++++ + arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 140 ++++++ + arch/arm/boot/dts/bcm2709.dtsi | 70 +++ + arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 45 +- + arch/arm/boot/dts/bcm2835-rpi-b.dts | 29 +- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 97 +++- + arch/arm/boot/dts/bcm2835.dtsi | 45 +- + arch/arm/boot/dts/overlays/Makefile | 57 +++ + arch/arm/boot/dts/overlays/README | 493 +++++++++++++++++++++ + arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 ++++ + .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + + arch/arm/boot/dts/overlays/dht11-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 50 +++ + .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ + .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ + .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ + .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 ++++ + arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 ++++++ + arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 49 ++ + arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts | 13 + + arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ + .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 +++ + .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 +++ + arch/arm/boot/dts/overlays/mmc-overlay.dts | 19 + + arch/arm/boot/dts/overlays/mz61581-overlay.dts | 109 +++++ + arch/arm/boot/dts/overlays/piscreen-overlay.dts | 96 ++++ + .../dts/overlays/pitft28-resistive-overlay.dts | 115 +++++ + arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ + arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ + arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 ++++ + arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ + arch/arm/boot/dts/overlays/sdhost-overlay.dts | 78 ++++ + arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 18 + + arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts | 18 + + arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 +++++++++ + arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ + .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ + 45 files changed, 3316 insertions(+), 54 deletions(-) + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b-plus.dts + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-b.dts + create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts + create mode 100644 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi + create mode 100644 arch/arm/boot/dts/bcm2708.dtsi + create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi create mode 100644 arch/arm/boot/dts/bcm2709-rpi-2-b.dts - create mode 100644 drivers/leds/trigger/ledtrig-input.c + create mode 100644 arch/arm/boot/dts/bcm2709.dtsi + create mode 100644 arch/arm/boot/dts/overlays/Makefile + create mode 100644 arch/arm/boot/dts/overlays/README + create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/dht11-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts + create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts + create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 992736b..12de305 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -1,5 +1,21 @@ + ifeq ($(CONFIG_OF),y) + ++dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb ++dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb ++dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb ++dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb ++ ++# Raspberry Pi ++ifeq ($(CONFIG_BCM2708_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_BCM2709_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_ARCH_BCM2835),y) ++ RPI_DT_OVERLAYS=y ++endif ++ + dtb-$(CONFIG_ARCH_ALPINE) += \ + alpine-db.dtb + dtb-$(CONFIG_MACH_ASM9260) += \ +@@ -660,7 +676,18 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt6592-evb.dtb \ + mt8127-moose.dtb \ + mt8135-evbp1.dtb ++ ++targets += dtbs dtbs_install ++targets += $(dtb-y) ++ + endif + + always := $(dtb-y) + clean-files := *.dtb ++ ++# Enable fixups to support overlays on BCM2708 platforms ++ifeq ($(RPI_DT_OVERLAYS),y) ++ DTC_FLAGS ?= -@ ++endif ++ ++subdir-y += overlays diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 95f03ba..b409c2c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -83,8 +83,18 @@ - pinctrl-0 = <&i2s_pins>; - }; - --&act_led { -- gpios = <&gpio 47 0>; -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 47 0>; -+ }; -+ -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; -+ }; - }; - - / { -@@ -97,5 +107,9 @@ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 0631f45..1ecd1a1 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -83,8 +83,12 @@ - pinctrl-0 = <&i2s_pins>; - }; - --&act_led { -- gpios = <&gpio 16 1>; -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 16 1>; -+ }; - }; - - / { -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index d879316..0713a1ed 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -79,11 +79,10 @@ - - leds: leds { - compatible = "gpio-leds"; -+ }; - -- act_led: act { -- label = "ACT"; -- linux,default-trigger = "mmc0"; -- }; -+ arm-pmu { -+ compatible = "arm,arm1176-pmu"; - }; - }; - -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts new file mode 100644 -index 0000000..46f4908 +index 0000000..0fa2210 --- /dev/null -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -0,0 +1,115 @@ ++++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts +@@ -0,0 +1,140 @@ +/dts-v1/; + -+/include/ "bcm2709.dtsi" ++/include/ "bcm2708.dtsi" + +/ { -+ compatible = "brcm,bcm2709"; -+ model = "Raspberry Pi 2 Model B"; ++ compatible = "brcm,bcm2708"; ++ model = "Raspberry Pi Model B+"; + + aliases { + soc = &soc; @@ -124457,7 +118600,11 @@ index 0000000..46f4908 + gpio = &gpio; + intc = &intc; + leds = &leds; ++ audio = &audio; + sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; + }; + + sound: sound { @@ -124486,6 +118633,19 @@ index 0000000..46f4908 + }; +}; + ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; @@ -124541,10 +118701,14 @@ index 0000000..46f4908 + +/ { + __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; + i2s = <&i2s>,"status"; + spi = <&spi0>,"status"; + i2c0 = <&i2c0>,"status"; + i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; + + act_led_gpio = <&act_led>,"gpios:4"; + act_led_activelow = <&act_led>,"gpios:8"; @@ -124553,24 +118717,8655 @@ index 0000000..46f4908 + pwr_led_gpio = <&pwr_led>,"gpios:4"; + pwr_led_activelow = <&pwr_led>,"gpios:8"; + pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts +new file mode 100644 +index 0000000..3fd49d0 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts +@@ -0,0 +1,130 @@ ++/dts-v1/; ++ ++/include/ "bcm2708.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ model = "Raspberry Pi Model B"; ++ ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ audio = &audio; ++ sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; ++ }; ++ ++ sound: sound { ++ }; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <28 29 30 31>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 16 1>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts +new file mode 100755 +index 0000000..238bd65 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts +@@ -0,0 +1,18 @@ ++/dts-v1/; ++ ++/include/ "bcm2708-rpi-cm.dtsi" ++ ++/ { ++ model = "Raspberry Pi Compute Module"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi +new file mode 100644 +index 0000000..3da7d3b +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi +@@ -0,0 +1,51 @@ ++/include/ "bcm2708.dtsi" ++ ++/ { ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ audio = &audio; ++ sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; ++ }; ++ ++ sound: sound { ++ }; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&audio { ++ status = "okay"; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi +new file mode 100644 +index 0000000..0d47427 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708.dtsi +@@ -0,0 +1,19 @@ ++/include/ "bcm2708_common.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ model = "BCM2708"; ++ ++ chosen { ++ /* No padding required - the boot loader can do that. */ ++ bootargs = ""; ++ }; ++ ++ soc { ++ ranges = <0x7e000000 0x20000000 0x01000000>; ++ ++ arm-pmu { ++ compatible = "arm,arm1176-pmu"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi +new file mode 100644 +index 0000000..8caa234 +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2708_common.dtsi +@@ -0,0 +1,230 @@ ++/include/ "skeleton.dtsi" ++ ++/ { ++ interrupt-parent = <&intc>; ++ ++ /* Onboard audio */ ++ audio: audio { ++ compatible = "brcm,bcm2835-audio"; ++ brcm,pwm-channels = <8>; ++ status = "disabled"; ++ }; ++ ++ soc: soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ dma: dma@7e007000 { ++ compatible = "brcm,bcm2835-dma"; ++ reg = <0x7e007000 0xf00>; ++ interrupts = <1 16>, ++ <1 17>, ++ <1 18>, ++ <1 19>, ++ <1 20>, ++ <1 21>, ++ <1 22>, ++ <1 23>, ++ <1 24>, ++ <1 25>, ++ <1 26>, ++ <1 27>, ++ <1 28>; ++ ++ #dma-cells = <1>; ++ brcm,dma-channel-mask = <0x7f35>; ++ }; ++ ++ intc: interrupt-controller { ++ compatible = "brcm,bcm2708-armctrl-ic"; ++ reg = <0x7e00b200 0x200>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ watchdog: watchdog@7e100000 { ++ compatible = "brcm,bcm2835-pm-wdt"; ++ reg = <0x7e100000 0x28>; ++ status = "disabled"; ++ }; ++ ++ random: rng@7e104000 { ++ compatible = "brcm,bcm2835-rng"; ++ reg = <0x7e104000 0x10>; ++ status = "disabled"; ++ }; ++ ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2708-vcio"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ }; ++ ++ gpio: gpio { ++ compatible = "brcm,bcm2835-gpio"; ++ reg = <0x7e200000 0xb4>; ++ interrupts = <2 17>, <2 18>; ++ ++ gpio-controller; ++ #gpio-cells = <2>; ++ ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ ++ mmc: mmc@7e300000 { ++ compatible = "brcm,bcm2835-mmc"; ++ reg = <0x7e300000 0x100>; ++ interrupts = <2 30>; ++ clocks = <&clk_mmc>; ++ dmas = <&dma 11>, ++ <&dma 11>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ uart0: uart@7e201000 { ++ compatible = "arm,pl011", "arm,primecell"; ++ reg = <0x7e201000 0x1000>; ++ interrupts = <2 25>; ++ clocks = <&clk_uart0 &clk_apb_p>; ++ clock-names = "uartclk","apb_pclk"; ++ arm,primecell-periphid = <0x00241011>; // For an explanation, see ++ // https://github.com/raspberrypi/linux/commit/13731d862cf5219216533a3b0de052cee4cc5038 ++ status = "disabled"; ++ }; ++ ++ i2s: i2s@7e203000 { ++ compatible = "brcm,bcm2708-i2s"; ++ reg = <0x7e203000 0x20>, ++ <0x7e101098 0x02>; ++ ++ //dmas = <&dma 2>, ++ // <&dma 3>; ++ dma-names = "tx", "rx"; ++ status = "disabled"; ++ }; ++ ++ spi0: spi@7e204000 { ++ compatible = "brcm,bcm2835-spi"; ++ reg = <0x7e204000 0x1000>; ++ interrupts = <2 22>; ++ clocks = <&clk_spi>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ /* the dma channels */ ++ dmas = <&dma 6>, <&dma 7>; ++ dma-names = "tx", "rx"; ++ /* the chipselects used - <0> means native GPIO ++ * add more gpios if necessary as <&gpio 6 1> ++ * (but do not forget to make them output!) ++ */ ++ cs-gpios = <0>, <0>; ++ }; ++ ++ i2c0: i2c@7e205000 { ++ compatible = "brcm,bcm2708-i2c"; ++ reg = <0x7e205000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clk_i2c>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ uart1: uart@7e215040 { ++ compatible = "brcm,bcm2835-aux-uart", "ns16550"; ++ reg = <0x7e215040 0x40>; ++ interrupts = <1 29>; ++ clock-frequency = <500000000>; ++ reg-shift = <2>; ++ no-loopback-test; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@7e804000 { ++ compatible = "brcm,bcm2708-i2c"; ++ reg = <0x7e804000 0x1000>; ++ interrupts = <2 21>; ++ clocks = <&clk_i2c>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ usb: usb@7e980000 { ++ compatible = "brcm,bcm2708-usb"; ++ reg = <0x7e980000 0x10000>, ++ <0x7e006000 0x1000>; ++ interrupts = <2 0>, ++ <1 9>; ++ }; ++ ++ leds: leds { ++ compatible = "gpio-leds"; ++ }; ++ ++ fb: fb { ++ compatible = "brcm,bcm2708-fb"; ++ status = "disabled"; ++ }; ++ ++ vchiq: vchiq { ++ compatible = "brcm,bcm2835-vchiq"; ++ reg = <0x7e00b840 0xf>; ++ interrupts = <0 2>; ++ }; ++ ++ thermal: thermal { ++ compatible = "brcm,bcm2835-thermal"; ++ }; ++ }; ++ ++ clocks: clocks { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ clk_mmc: clock@0 { ++ compatible = "fixed-clock"; ++ reg = <0>; ++ #clock-cells = <0>; ++ clock-output-names = "mmc"; ++ clock-frequency = <250000000>; ++ }; ++ ++ clk_i2c: clock@1 { ++ compatible = "fixed-clock"; ++ reg = <1>; ++ #clock-cells = <0>; ++ clock-output-names = "i2c"; ++ clock-frequency = <250000000>; ++ }; ++ ++ clk_spi: clock@2 { ++ compatible = "fixed-clock"; ++ reg = <2>; ++ #clock-cells = <0>; ++ clock-output-names = "spi"; ++ clock-frequency = <250000000>; ++ }; ++ ++ clk_uart0: clock@3 { ++ compatible = "fixed-clock"; ++ reg = <3>; ++ #clock-cells = <0>; ++ clock-output-names = "uart0_pclk"; ++ clock-frequency = <3000000>; ++ }; ++ ++ clk_apb_p: clock@4 { ++ compatible = "fixed-clock"; ++ reg = <4>; ++ #clock-cells = <0>; ++ clock-output-names = "apb_pclk"; ++ clock-frequency = <126000000>; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +new file mode 100644 +index 0000000..8aaaf1f +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts +@@ -0,0 +1,140 @@ ++/dts-v1/; ++ ++/include/ "bcm2709.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2709"; ++ model = "Raspberry Pi 2 Model B"; ++ ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ audio = &audio; ++ sound = &sound; ++ uart0 = &uart0; ++ uart1 = &uart1; ++ clocks = &clocks; ++ }; ++ ++ sound: sound { ++ }; ++}; ++ ++&gpio { ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; ++ }; ++ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++ ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&mmc { ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++&fb { ++ status = "okay"; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; ++ }; ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ clock-frequency = <100000>; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&leds { ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; ++ gpios = <&gpio 47 0>; ++ }; ++ ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&gpio 35 0>; ++ }; ++}; ++ ++/ { ++ __overrides__ { ++ uart0 = <&uart0>,"status"; ++ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; ++ ++ audio = <&audio>,"status"; ++ watchdog = <&watchdog>,"status"; ++ random = <&random>,"status"; + }; +}; diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index 15c7e65..34d2226 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi +new file mode 100644 +index 0000000..5e0b935 +--- /dev/null +++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -79,11 +79,6 @@ +@@ -0,0 +1,70 @@ ++/include/ "bcm2708_common.dtsi" ++ ++/ { ++ compatible = "brcm,bcm2709"; ++ model = "BCM2709"; ++ ++ chosen { ++ /* No padding required - the boot loader can do that. */ ++ bootargs = ""; ++ }; ++ ++ soc { ++ ranges = <0x7e000000 0x3f000000 0x01000000>; ++ ++ arm-pmu { ++ compatible = "arm,cortex-a7-pmu"; ++ interrupts = <3 9>; ++ }; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ clock-frequency = <19200000>; ++ interrupts = <3 0>, // PHYS_SECURE_PPI ++ <3 1>, // PHYS_NONSECURE_PPI ++ <3 3>, // VIRT_PPI ++ <3 2>; // HYP_PPI ++ always-on; ++ }; ++ ++ cpus: cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ v7_cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf00>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf01>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf02>; ++ clock-frequency = <800000000>; ++ }; ++ ++ v7_cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0xf03>; ++ clock-frequency = <800000000>; ++ }; ++ }; ++ ++ __overrides__ { ++ arm_freq = <&v7_cpu0>, "clock-frequency:0", ++ <&v7_cpu1>, "clock-frequency:0", ++ <&v7_cpu2>, "clock-frequency:0", ++ <&v7_cpu3>, "clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +index e479515..b0fb0e8 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +@@ -4,27 +4,40 @@ + / { + compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; + model = "Raspberry Pi Model B+"; ++}; ++ ++&gpio { ++ i2s_pins: i2s { ++ brcm,pins = <18 19 20 21>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; - leds: leds { - compatible = "gpio-leds"; +- leds { +- act { +- gpios = <&gpio 47 0>; +- }; ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&act_led { ++ gpios = <&gpio 47 0>; ++}; + +- pwr { +- label = "PWR"; +- gpios = <&gpio 35 0>; +- default-state = "keep"; +- linux,default-trigger = "default-on"; +- }; ++&leds { ++ pwr_led: pwr { ++ label = "led1"; ++ linux,default-trigger = "input"; ++ gpios = <&gpio 35 0>; + }; + }; + +-&gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; + +- /* I2S interface */ +- i2s_alt0: i2s_alt0 { +- brcm,pins = <18 19 20 21>; +- brcm,function = <4>; /* alt0 */ ++ pwr_led_gpio = <&pwr_led>,"gpios:4"; ++ pwr_led_activelow = <&pwr_led>,"gpios:8"; ++ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts +index bafa46f..b867224 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts ++++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts +@@ -5,19 +5,28 @@ + compatible = "raspberrypi,model-b", "brcm,bcm2835"; + model = "Raspberry Pi Model B"; + +- leds { +- act { +- gpios = <&gpio 16 1>; +- }; +- }; + }; + + &gpio { +- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; - -- act_led: act { -- label = "led0"; -- linux,default-trigger = "mmc0"; -- }; +- /* I2S interface */ +- i2s_alt2: i2s_alt2 { ++ i2s_pins: i2s { + brcm,pins = <28 29 30 31>; +- brcm,function = <6>; /* alt2 */ ++ brcm,function = <4>; /* alt0 */ ++ }; ++}; ++ ++&i2s { ++ #sound-dai-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2s_pins>; ++}; ++ ++&act_led { ++ gpios = <&gpio 16 1>; ++}; ++ ++/ { ++ __overrides__ { ++ act_led_gpio = <&act_led>,"gpios:4"; ++ act_led_activelow = <&act_led>,"gpios:8"; + }; + }; +diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi +index c706448..466f02b 100644 +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -1,51 +1,112 @@ + /include/ "bcm2835.dtsi" + + / { ++ /* This is left here in case u-boot needs it */ + memory { + reg = <0 0x10000000>; + }; + +- leds { ++ aliases { ++ soc = &soc; ++ spi0 = &spi0; ++ i2c0 = &i2c0; ++ i2c1 = &i2c1; ++ i2s = &i2s; ++ gpio = &gpio; ++ intc = &intc; ++ leds = &leds; ++ sound = &sound; ++ }; ++ ++ leds: leds { + compatible = "gpio-leds"; + +- act { +- label = "ACT"; +- default-state = "keep"; +- linux,default-trigger = "heartbeat"; ++ act_led: act { ++ label = "led0"; ++ linux,default-trigger = "mmc0"; + }; + }; ++ ++ /* Onboard audio */ ++ audio: audio { ++ compatible = "brcm,bcm2835-audio"; ++ brcm,pwm-channels = <8>; ++ status = "disabled"; ++ }; ++ ++ /* External sound card */ ++ sound: sound { ++ }; + }; + + &gpio { +- pinctrl-names = "default"; ++ spi0_pins: spi0_pins { ++ brcm,pins = <7 8 9 10 11>; ++ brcm,function = <4>; /* alt0 */ ++ }; + +- gpioout: gpioout { +- brcm,pins = <6>; +- brcm,function = <1>; /* GPIO out */ ++ i2c0_pins: i2c0 { ++ brcm,pins = <0 1>; ++ brcm,function = <4>; + }; + +- alt0: alt0 { +- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; +- brcm,function = <4>; /* alt0 */ ++ i2c1_pins: i2c1 { ++ brcm,pins = <2 3>; ++ brcm,function = <4>; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ ++ spidev@0{ ++ compatible = "spidev"; ++ reg = <0>; /* CE0 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; + }; + +- alt3: alt3 { +- brcm,pins = <48 49 50 51 52 53>; +- brcm,function = <7>; /* alt3 */ ++ spidev@1{ ++ compatible = "spidev"; ++ reg = <1>; /* CE1 */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ spi-max-frequency = <500000>; + }; + }; + + &i2c0 { +- status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; + clock-frequency = <100000>; + }; + + &i2c1 { +- status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; + clock-frequency = <100000>; + }; + +-&sdhci { ++&mmc { + status = "okay"; + bus-width = <4>; + }; ++ ++&fb { ++ status = "okay"; ++}; ++ ++/ { ++ __overrides__ { ++ i2s = <&i2s>,"status"; ++ spi = <&spi0>,"status"; ++ i2c0 = <&i2c0>,"status"; ++ i2c1 = <&i2c1>,"status"; ++ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; ++ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; ++ act_led_trigger = <&act_led>,"linux,default-trigger"; ++ audio = <&audio>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi +index 3342cb1..4b6dd65f 100644 +--- a/arch/arm/boot/dts/bcm2835.dtsi ++++ b/arch/arm/boot/dts/bcm2835.dtsi +@@ -6,14 +6,15 @@ + interrupt-parent = <&intc>; + + chosen { +- bootargs = "earlyprintk console=ttyAMA0"; ++ bootargs = ""; + }; + +- soc { ++ soc: soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x7e000000 0x20000000 0x02000000>; ++ dma-ranges = <0x40000000 0x00000000 0x20000000>; + + timer@7e003000 { + compatible = "brcm,bcm2835-system-timer"; +@@ -50,16 +51,22 @@ + #interrupt-cells = <2>; }; +- watchdog@7e100000 { ++ watchdog: watchdog@7e100000 { + compatible = "brcm,bcm2835-pm-wdt"; + reg = <0x7e100000 0x28>; + }; + +- rng@7e104000 { ++ random: rng@7e104000 { + compatible = "brcm,bcm2835-rng"; + reg = <0x7e104000 0x10>; + }; + ++ mailbox: mailbox@7e00b800 { ++ compatible = "brcm,bcm2708-vcio"; ++ reg = <0x7e00b880 0x40>; ++ interrupts = <0 1>; ++ }; ++ + gpio: gpio@7e200000 { + compatible = "brcm,bcm2835-gpio"; + reg = <0x7e200000 0xb4>; +@@ -83,7 +90,7 @@ + #interrupt-cells = <2>; + }; + +- uart@7e201000 { ++ uart0: uart@7e201000 { + compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; + reg = <0x7e201000 0x1000>; + interrupts = <2 25>; +@@ -102,7 +109,7 @@ + status = "disabled"; + }; + +- spi: spi@7e204000 { ++ spi0: spi@7e204000 { + compatible = "brcm,bcm2835-spi"; + reg = <0x7e204000 0x1000>; + interrupts = <2 22>; +@@ -122,11 +129,14 @@ + status = "disabled"; + }; + +- sdhci: sdhci@7e300000 { +- compatible = "brcm,bcm2835-sdhci"; ++ mmc: mmc@7e300000 { ++ compatible = "brcm,bcm2835-mmc"; + reg = <0x7e300000 0x100>; + interrupts = <2 30>; + clocks = <&clk_mmc>; ++ dmas = <&dma 11>, ++ <&dma 11>; ++ dma-names = "tx", "rx"; + status = "disabled"; + }; + +@@ -140,7 +150,7 @@ + status = "disabled"; + }; + +- usb@7e980000 { ++ usb: usb@7e980000 { + compatible = "brcm,bcm2835-usb"; + reg = <0x7e980000 0x10000>; + interrupts = <1 9>; +@@ -149,6 +159,21 @@ arm-pmu { + compatible = "arm,arm1176-pmu"; + }; ++ ++ fb: fb { ++ compatible = "brcm,bcm2708-fb"; ++ status = "disabled"; ++ }; ++ ++ vchiq: vchiq { ++ compatible = "brcm,bcm2835-vchiq"; ++ reg = <0x7e00b840 0xf>; ++ interrupts = <0 2>; ++ }; ++ ++ thermal: thermal { ++ compatible = "brcm,bcm2835-thermal"; ++ }; + }; + + clocks { +@@ -161,7 +186,7 @@ + reg = <0>; + #clock-cells = <0>; + clock-output-names = "mmc"; +- clock-frequency = <100000000>; ++ clock-frequency = <250000000>; + }; + + clk_i2c: clock@1 { +diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile +new file mode 100644 +index 0000000..6947556 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/Makefile +@@ -0,0 +1,57 @@ ++ifeq ($(CONFIG_OF),y) ++ ++# Overlays for the Raspberry Pi platform ++ ++ifeq ($(CONFIG_BCM2708_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_BCM2709_DT),y) ++ RPI_DT_OVERLAYS=y ++endif ++ifeq ($(CONFIG_ARCH_BCM2835),y) ++ RPI_DT_OVERLAYS=y ++endif ++ ++dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += dht11-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += i2s-mmap-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb ++dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb ++ ++targets += dtbs dtbs_install ++targets += $(dtb-y) ++ ++endif ++ ++always := $(dtb-y) ++clean-files := *.dtb ++ ++# Enable fixups to support overlays on BCM2708 platforms ++ifeq ($(RPI_DT_OVERLAYS),y) ++ DTC_FLAGS ?= -@ ++endif +diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README +new file mode 100644 +index 0000000..3e08f98 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/README +@@ -0,0 +1,493 @@ ++Introduction ++============ ++ ++This directory contains Device Tree overlays. Device Tree makes it possible ++to support many hardware configurations with a single kernel and without the ++need to explicitly load or blacklist kernel modules. Note that this isn't a ++"pure" Device Tree configuration (c.f. MACH_BCM2835) - some on-board devices ++are still configured by the board support code, but the intention is to ++eventually reach that goal. ++ ++On Raspberry Pi, Device Tree usage is controlled from /boot/config.txt. By ++default, the Raspberry Pi kernel boots with device tree enabled. You can ++completely disable DT usage (for now) by adding: ++ ++ device_tree= ++ ++to your config.txt, which should cause your Pi to revert to the old way of ++doing things after a reboot. ++ ++In /boot you will find a .dtb for each base platform. This describes the ++hardware that is part of the Raspberry Pi board. The loader (start.elf and its ++siblings) selects the .dtb file appropriate for the platform by name, and reads ++it into memory. At this point, all of the optional interfaces (i2c, i2s, spi) ++are disabled, but they can be enabled using Device Tree parameters: ++ ++ dtparam=i2c=on,i2s=on,spi=on ++ ++However, this shouldn't be necessary in many use cases because loading an ++overlay that requires one of those interfaces will cause it to be enabled ++automatically, and it is advisable to only enable interfaces if they are ++needed. ++ ++Configuring additional, optional hardware is done using Device Tree overlays ++(see below). ++ ++raspi-config ++============ ++ ++The Advanced Options section of the raspi-config utility can enable and disable ++Device Tree use, as well as toggling the I2C and SPI interfaces. Note that it ++is possible to both enable an interface and blacklist the driver, if for some ++reason you should want to defer the loading. ++ ++Modules ++======= ++ ++As well as describing the hardware, Device Tree also gives enough information ++to allow suitable driver modules to be located and loaded, with the corollary ++that unneeded modules are not loaded. As a result it should be possible to ++remove lines from /etc/modules, and /etc/modprobe.d/raspi-blacklist.conf can ++have its contents deleted (or commented out). ++ ++Using Overlays ++============== ++ ++Overlays are loaded using the "dtoverlay" directive. As an example, consider the ++popular lirc-rpi module, the Linux Infrared Remote Control driver. In the ++pre-DT world this would be loaded from /etc/modules, with an explicit ++"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, ++this becomes a line in config.txt: ++ ++ dtoverlay=lirc-rpi ++ ++This causes the file /boot/overlays/lirc-rpi-overlay.dtb to be loaded. By ++default it will use GPIOs 17 (out) and 18 (in), but this can be modified using ++DT parameters: ++ ++ dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 ++ ++Parameters always have default values, although in some cases (e.g. "w1-gpio") ++it is necessary to provided multiple overlays in order to get the desired ++behaviour. See the list of overlays below for a description of the parameters and their defaults. ++ ++The Overlay and Parameter Reference ++=================================== ++ ++Name: ++Info: Configures the base Raspberry Pi hardware ++Load: ++Params: ++ audio Set to "on" to disable the onboard ALSA audio ++ interface (default "off") ++ ++ i2c_arm Set to "on" to enable the ARM's i2c interface ++ (default "off") ++ ++ i2c_vc Set to "on" to enable the i2c interface ++ usually reserved for the VideoCore processor ++ (default "off") ++ ++ i2c An alias for i2c_arm ++ ++ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface ++ (default "100000") ++ ++ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface ++ (default "100000") ++ ++ i2c_baudrate An alias for i2c_arm_baudrate ++ ++ i2s Set to "on" to enable the i2s interface ++ (default "off") ++ ++ spi Set to "on" to enable the spi interfaces ++ (default "off") ++ ++ random Set to "on" to enable the hardware random ++ number generator (default "off") ++ ++ uart0 Set to "off" to disable uart0 (default "on") ++ ++ watchdog Set to "on" to enable the hardware watchdog ++ (default "off") ++ ++ act_led_trigger Choose which activity the LED tracks. ++ Use "heartbeat" for a nice load indicator. ++ (default "mmc") ++ ++ act_led_activelow Set to "on" to invert the sense of the LED ++ (default "off") ++ ++ act_led_gpio Set which GPIO to use for the activity LED ++ (in case you want to connect it to an external ++ device) ++ (default "16" on a non-Plus board, "47" on a ++ Plus or Pi 2) ++ ++ pwr_led_trigger ++ pwr_led_activelow ++ pwr_led_gpio ++ As for act_led_*, but using the PWR LED. ++ Not available on Model A/B boards. ++ ++ N.B. It is recommended to only enable those interfaces that are needed. ++ Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc ++ interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) ++ Note also that i2c, i2c_arm and i2c_vc are aliases for the physical ++ interfaces i2c0 and i2c1. Use of the numeric variants is still possible ++ but deprecated because the ARM/VC assignments differ between board ++ revisions. The same board-specific mapping applies to i2c_baudrate, ++ and the other i2c baudrate parameters. ++ ++ ++Name: ads7846 ++Info: ADS7846 Touch controller ++Load: dtoverlay=ads7846,= ++Params: cs SPI bus Chip Select (default 1) ++ speed SPI bus speed (default 2Mhz, max 3.25MHz) ++ penirq GPIO used for PENIRQ. REQUIRED ++ penirq_pull Set GPIO pull (default 0=none, 2=pullup) ++ swapxy Swap x and y axis ++ xmin Minimum value on the X axis (default 0) ++ ymin Minimum value on the Y axis (default 0) ++ xmax Maximum value on the X axis (default 4095) ++ ymax Maximum value on the Y axis (default 4095) ++ pmin Minimum reported pressure value (default 0) ++ pmax Maximum reported pressure value (default 65535) ++ xohms Touchpanel sensitivity (X-plate resistance) ++ (default 400) ++ ++ penirq is required and usually xohms (60-100) has to be set as well. ++ Apart from that, pmax (255) and swapxy are also common. ++ The rest of the calibration can be done with xinput-calibrator. ++ See: github.com/notro/fbtft/wiki/FBTFT-on-Raspian ++ Device Tree binding document: ++ www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt ++ ++ ++Name: bmp085_i2c-sensor ++Info: Configures the BMP085/BMP180 digital barometric pressure and temperature ++ sensors from Bosch Sensortec ++Load: dtoverlay=bmp085_i2c-sensor ++Params: ++ ++ ++[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++Name: enc28j60 ++Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) ++Load: dtoverlay=enc28j60,= ++Params: int_pin GPIO used for INT (default 25) ++ ++ speed SPI bus speed (default 12000000) ++ ++ ++Name: hifiberry-amp ++Info: Configures the HifiBerry Amp and Amp+ audio cards ++Load: dtoverlay=hifiberry-amp ++Params: ++ ++ ++Name: hifiberry-dac ++Info: Configures the HifiBerry DAC audio card ++Load: dtoverlay=hifiberry-dac ++Params: ++ ++ ++Name: hifiberry-dacplus ++Info: Configures the HifiBerry DAC+ audio card ++Load: dtoverlay=hifiberry-dacplus ++Params: ++ ++ ++Name: hifiberry-digi ++Info: Configures the HifiBerry Digi audio card ++Load: dtoverlay=hifiberry-digi ++Params: ++ ++ ++Name: hy28a ++Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics ++ Default values match Texy's display shield ++Load: dtoverlay=hy28a,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ resetgpio GPIO used to reset controller ++ ++ ledgpio GPIO used to control backlight ++ ++ ++Name: hy28b ++Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics ++ Default values match Texy's display shield ++Load: dtoverlay=hy28b,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ resetgpio GPIO used to reset controller ++ ++ ledgpio GPIO used to control backlight ++ ++ ++Name: i2c-rtc ++Info: Adds support for a number of I2C Real Time Clock devices ++Load: dtoverlay=i2c-rtc, ++Params: ds1307 Select the DS1307 device ++ ++ ds3231 Select the DS3231 device ++ ++ pcf2127 Select the PCF2127 device ++ ++ pcf8523 Select the PCF8523 device ++ ++ pcf8563 Select the PCF8563 device ++ ++ ++Name: iqaudio-dac ++Info: Configures the IQaudio DAC audio card ++Load: dtoverlay=iqaudio-dac ++Params: ++ ++ ++Name: iqaudio-dacplus ++Info: Configures the IQaudio DAC+ audio card ++Load: dtoverlay=iqaudio-dacplus ++Params: ++ ++ ++Name: lirc-rpi ++Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) ++ Consult the module documentation for more details. ++Load: dtoverlay=lirc-rpi,=,... ++Params: gpio_out_pin GPIO for output (default "17") ++ ++ gpio_in_pin GPIO for input (default "18") ++ ++ gpio_in_pull Pull up/down/off on the input pin ++ (default "down") ++ ++ sense Override the IR receive auto-detection logic: ++ "1" = force active high ++ "0" = force active low ++ "-1" = use auto-detection ++ (default "-1") ++ ++ softcarrier Turn the software carrier "on" or "off" ++ (default "on") ++ ++ invert "on" = invert the output pin (default "off") ++ ++ debug "on" = enable additional debug messages ++ (default "off") ++ ++ ++Name: mcp2515-can0 ++Info: Configures the MCP2515 CAN controller ++Load: dtoverlay=mcp2515-can0,= ++Params: oscillator Clock frequency for the CAN controller (Hz) ++ ++ spimaxfrequency Maximum SPI frequence (Hz) ++ ++ interrupt GPIO for interrupt signal ++ ++ ++Name: mmc ++Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock ++Load: dtoverlay=mmc,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ force_pio Disable DMA support ++ ++ ++Name: mz61581 ++Info: MZ61581 display by Tontec ++Load: dtoverlay=mz61581,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++[ The pcf8523-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] ++ ++ ++Name: piscreen ++Info: PiScreen display by OzzMaker.com ++Load: dtoverlay=piscreen,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: pitft28-resistive ++Info: Adafruit PiTFT 2.8" resistive touch screen ++Load: dtoverlay=pitft28-resistive,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ ++Name: pps-gpio ++Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). ++Load: dtoverlay=pps-gpio,= ++Params: gpiopin Input GPIO (default "18") ++ ++ ++Name: rpi-dac ++Info: Configures the RPi DAC audio card ++Load: dtoverlay=rpi-dac ++Params: ++ ++ ++Name: rpi-display ++Info: RPi-Display - 2.8" Touch Display by Watterott ++Load: dtoverlay=rpi-display,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ xohms Touchpanel sensitivity (X-plate resistance) ++ ++ ++Name: rpi-proto ++Info: Configures the RPi Proto audio card ++Load: dtoverlay=rpi-proto ++Params: ++ ++ ++Name: sdhost ++Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock ++Load: dtoverlay=sdhost,= ++Params: overclock_50 Clock (in MHz) to use when the MMC framework ++ requests 50MHz ++ force_pio Disable DMA support ++ ++ ++Name: spi-bcm2708 ++Info: Selects the bcm2708-spi SPI driver ++Load: dtoverlay=spi-bcm2708 ++Params: ++ ++ ++Name: spi-bcm2835 ++Info: Selects the bcm2835-spi SPI driver ++Load: dtoverlay=spi-bcm2835 ++Params: ++ ++ ++Name: tinylcd35 ++Info: 3.5" Color TFT Display by www.tinylcd.com ++ Options: Touch, RTC, keypad ++Load: dtoverlay=tinylcd35,= ++Params: speed Display SPI bus speed ++ ++ rotate Display rotation {0,90,180,270} ++ ++ fps Delay between frame updates ++ ++ debug Debug output level {0-7} ++ ++ touch Enable touch panel ++ ++ touchgpio Touch controller IRQ GPIO ++ ++ xohms Touchpanel: Resistance of X-plate in ohms ++ ++ rtc-pcf PCF8563 Real Time Clock ++ ++ rtc-ds DS1307 Real Time Clock ++ ++ keypad Enable keypad ++ ++ Examples: ++ Display with touchpanel, PCF8563 RTC and keypad: ++ dtoverlay=tinylcd35,touch,rtc-pcf,keypad ++ Old touch display: ++ dtoverlay=tinylcd35,touch,touchgpio=3 ++ ++ ++Name: w1-gpio ++Info: Configures the w1-gpio Onewire interface module. ++ Use this overlay if you *don't* need a GPIO to drive an external pullup. ++Load: dtoverlay=w1-gpio,= ++Params: gpiopin GPIO for I/O (default "4") ++ ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature ++ ++ ++Name: w1-gpio-pullup ++Info: Configures the w1-gpio Onewire interface module. ++ Use this overlay if you *do* need a GPIO to drive an external pullup. ++Load: dtoverlay=w1-gpio-pullup,=,... ++Params: gpiopin GPIO for I/O (default "4") ++ ++ pullup Non-zero, "on", or "y" to enable the parasitic ++ power (2-wire, power-on-data) feature ++ ++ extpullup GPIO for external pullup (default "5") ++ ++ ++Troubleshooting ++=============== ++ ++If you are experiencing problems that you think are DT-related, enable DT ++diagnostic output by adding this to /boot/config.txt: ++ ++ dtdebug=on ++ ++and rebooting. Then run: ++ ++ sudo vcdbg log msg ++ ++and look for relevant messages. ++ ++Further reading ++=============== ++ ++This is only meant to be a quick introduction to the subject of Device Tree on ++Raspberry Pi. There is a more complete explanation here: ++ ++http://www.raspberrypi.org/documentation/configuration/device-tree.md +diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts +new file mode 100644 +index 0000000..6a92cd1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts +@@ -0,0 +1,83 @@ ++/* ++ * Generic Device Tree overlay for the ADS7846 touch controller ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ ads7846_pins: ads7846_pins { ++ brcm,pins = <255>; /* illegal default value */ ++ brcm,function = <0>; /* in */ ++ brcm,pull = <0>; /* none */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ads7846: ads7846@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ads7846_pins>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <255 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 255 0>; ++ ++ /* driver defaults */ ++ ti,x-min = /bits/ 16 <0>; ++ ti,y-min = /bits/ 16 <0>; ++ ti,x-max = /bits/ 16 <0x0FFF>; ++ ti,y-max = /bits/ 16 <0x0FFF>; ++ ti,pressure-min = /bits/ 16 <0>; ++ ti,pressure-max = /bits/ 16 <0xFFFF>; ++ ti,x-plate-ohms = /bits/ 16 <400>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ cs = <&ads7846>,"reg:0"; ++ speed = <&ads7846>,"spi-max-frequency:0"; ++ penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ ++ <&ads7846>,"interrupts:0", ++ <&ads7846>,"pendown-gpio:4"; ++ penirq_pull = <&ads7846_pins>,"brcm,pull:0"; ++ swapxy = <&ads7846>,"ti,swap-xy?"; ++ xmin = <&ads7846>,"ti,x-min;0"; ++ ymin = <&ads7846>,"ti,y-min;0"; ++ xmax = <&ads7846>,"ti,x-max;0"; ++ ymax = <&ads7846>,"ti,y-max;0"; ++ pmin = <&ads7846>,"ti,pressure-min;0"; ++ pmax = <&ads7846>,"ti,pressure-max;0"; ++ xohms = <&ads7846>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts +new file mode 100644 +index 0000000..b830bf2 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts +@@ -0,0 +1,23 @@ ++// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ bmp085@77 { ++ compatible = "bosch,bmp085"; ++ reg = <0x77>; ++ default-oversampling = <3>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/dht11-overlay.dts b/arch/arm/boot/dts/overlays/dht11-overlay.dts +new file mode 100644 +index 0000000..9bf67fd +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/dht11-overlay.dts +@@ -0,0 +1,39 @@ ++/* ++ * Overlay for the DHT11/21/22 humidity/temperature sensor modules. ++ */ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ dht11: dht11@0 { ++ compatible = "dht11"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&dht11_pins>; ++ gpios = <&gpio 4 0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ dht11_pins: dht11_pins { ++ brcm,pins = <4>; ++ brcm,function = <0>; // in ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&dht11_pins>,"brcm,pins:0", ++ <&dht11>,"gpios:4"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts +new file mode 100644 +index 0000000..8fae869 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts +@@ -0,0 +1,50 @@ ++// Overlay for the Microchip ENC28J60 Ethernet Controller ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ eth1: enc28j60@0{ ++ compatible = "microchip,enc28j60"; ++ reg = <0>; /* CE0 */ ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð1_pins>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 0x2>; /* falling edge */ ++ spi-max-frequency = <12000000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ eth1_pins: eth1_pins { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <0>; /* none */ ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ int_pin = <ð1>, "interrupts:0", ++ <ð1_pins>, "brcm,pins:0"; ++ speed = <ð1>, "spi-max-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts +new file mode 100644 +index 0000000..2c81448 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for HiFiBerry Amp/Amp+ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-amp"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ tas5713@1b { ++ #sound-dai-cells = <0>; ++ compatible = "ti,tas5713"; ++ reg = <0x1b>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts +new file mode 100644 +index 0000000..5e7633a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts +@@ -0,0 +1,34 @@ ++// Definitions for HiFiBerry DAC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ pcm5102a-codec { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5102a"; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts +new file mode 100644 +index 0000000..deb9c625 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for HiFiBerry DAC+ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-dacplus"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4d { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4d>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts +new file mode 100644 +index 0000000..d0e0d8a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for HiFiBerry Digi ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "hifiberry,hifiberry-digi"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ wm8804@3b { ++ #sound-dai-cells = <0>; ++ compatible = "wlf,wm8804"; ++ reg = <0x3b>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts +new file mode 100644 +index 0000000..3cd3083 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts +@@ -0,0 +1,87 @@ ++/* ++ * Device Tree overlay for HY28A display ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ hy28a_pins: hy28a_pins { ++ brcm,pins = <17 25 18>; ++ brcm,function = <0 1 1>; /* in out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hy28a: hy28a@0{ ++ compatible = "ilitek,ili9320"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hy28a_pins>; ++ ++ spi-max-frequency = <32000000>; ++ spi-cpol; ++ spi-cpha; ++ rotate = <270>; ++ bgr; ++ fps = <50>; ++ buswidth = <8>; ++ startbyte = <0x70>; ++ reset-gpios = <&gpio 25 0>; ++ led-gpios = <&gpio 18 1>; ++ debug = <0>; ++ }; ++ ++ hy28a_ts: hy28a-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&hy28a>,"spi-max-frequency:0"; ++ rotate = <&hy28a>,"rotate:0"; ++ fps = <&hy28a>,"fps:0"; ++ debug = <&hy28a>,"debug:0"; ++ xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; ++ resetgpio = <&hy28a>,"reset-gpios:4", ++ <&hy28a_pins>, "brcm,pins:1"; ++ ledgpio = <&hy28a>,"led-gpios:4", ++ <&hy28a_pins>, "brcm,pins:2"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts +new file mode 100644 +index 0000000..f774c4a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts +@@ -0,0 +1,142 @@ ++/* ++ * Device Tree overlay for HY28b display shield by Texy ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ hy28b_pins: hy28b_pins { ++ brcm,pins = <17 25 18>; ++ brcm,function = <0 1 1>; /* in out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ hy28b: hy28b@0{ ++ compatible = "ilitek,ili9325"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&hy28b_pins>; ++ ++ spi-max-frequency = <48000000>; ++ spi-cpol; ++ spi-cpha; ++ rotate = <270>; ++ bgr; ++ fps = <50>; ++ buswidth = <8>; ++ startbyte = <0x70>; ++ reset-gpios = <&gpio 25 0>; ++ led-gpios = <&gpio 18 1>; ++ ++ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; ++ ++ init = <0x10000e7 0x0010 ++ 0x1000000 0x0001 ++ 0x1000001 0x0100 ++ 0x1000002 0x0700 ++ 0x1000003 0x1030 ++ 0x1000004 0x0000 ++ 0x1000008 0x0207 ++ 0x1000009 0x0000 ++ 0x100000a 0x0000 ++ 0x100000c 0x0001 ++ 0x100000d 0x0000 ++ 0x100000f 0x0000 ++ 0x1000010 0x0000 ++ 0x1000011 0x0007 ++ 0x1000012 0x0000 ++ 0x1000013 0x0000 ++ 0x2000032 ++ 0x1000010 0x1590 ++ 0x1000011 0x0227 ++ 0x2000032 ++ 0x1000012 0x009c ++ 0x2000032 ++ 0x1000013 0x1900 ++ 0x1000029 0x0023 ++ 0x100002b 0x000e ++ 0x2000032 ++ 0x1000020 0x0000 ++ 0x1000021 0x0000 ++ 0x2000032 ++ 0x1000050 0x0000 ++ 0x1000051 0x00ef ++ 0x1000052 0x0000 ++ 0x1000053 0x013f ++ 0x1000060 0xa700 ++ 0x1000061 0x0001 ++ 0x100006a 0x0000 ++ 0x1000080 0x0000 ++ 0x1000081 0x0000 ++ 0x1000082 0x0000 ++ 0x1000083 0x0000 ++ 0x1000084 0x0000 ++ 0x1000085 0x0000 ++ 0x1000090 0x0010 ++ 0x1000092 0x0000 ++ 0x1000093 0x0003 ++ 0x1000095 0x0110 ++ 0x1000097 0x0000 ++ 0x1000098 0x0000 ++ 0x1000007 0x0133 ++ 0x1000020 0x0000 ++ 0x1000021 0x0000 ++ 0x2000064>; ++ debug = <0>; ++ }; ++ ++ hy28b_ts: hy28b-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&hy28b>,"spi-max-frequency:0"; ++ rotate = <&hy28b>,"rotate:0"; ++ fps = <&hy28b>,"fps:0"; ++ debug = <&hy28b>,"debug:0"; ++ xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; ++ resetgpio = <&hy28b>,"reset-gpios:4", ++ <&hy28b_pins>, "brcm,pins:1"; ++ ledgpio = <&hy28b>,"led-gpios:4", ++ <&hy28b_pins>, "brcm,pins:2"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +new file mode 100644 +index 0000000..6bccfdc +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts +@@ -0,0 +1,49 @@ ++// Definitions for several I2C based Real Time Clocks ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ ds1307: ds1307@68 { ++ compatible = "maxim,ds1307"; ++ reg = <0x68>; ++ status = "disable"; ++ }; ++ ds3231: ds3231@68 { ++ compatible = "maxim,ds3231"; ++ reg = <0x68>; ++ status = "disable"; ++ }; ++ pcf2127: pcf2127@51 { ++ compatible = "nxp,pcf2127"; ++ reg = <0x51>; ++ status = "disable"; ++ }; ++ pcf8523: pcf8523@68 { ++ compatible = "nxp,pcf8523"; ++ reg = <0x68>; ++ status = "disable"; ++ }; ++ pcf8563: pcf8563@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ status = "disable"; ++ }; ++ }; ++ }; ++ __overrides__ { ++ ds1307 = <&ds1307>,"status"; ++ ds3231 = <&ds3231>,"status"; ++ pcf2127 = <&pcf2127>,"status"; ++ pcf8523 = <&pcf8523>,"status"; ++ pcf8563 = <&pcf8563>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts +new file mode 100644 +index 0000000..a11160a +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/i2s-mmap-overlay.dts +@@ -0,0 +1,13 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&i2s>; ++ __overlay__ { ++ brcm,enable-mmap; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts +new file mode 100644 +index 0000000..ea8173e +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for IQaudIO DAC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "iqaudio,iqaudio-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts +new file mode 100644 +index 0000000..735d8ab +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for IQaudIO DAC+ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "iqaudio,iqaudio-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ pcm5122@4c { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm5122"; ++ reg = <0x4c>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts +new file mode 100644 +index 0000000..7d5d82b +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts +@@ -0,0 +1,57 @@ ++// Definitions for lirc-rpi module ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ lirc_rpi: lirc_rpi { ++ compatible = "rpi,lirc-rpi"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&lirc_pins>; ++ status = "okay"; ++ ++ // Override autodetection of IR receiver circuit ++ // (0 = active high, 1 = active low, -1 = no override ) ++ rpi,sense = <0xffffffff>; ++ ++ // Software carrier ++ // (0 = off, 1 = on) ++ rpi,softcarrier = <1>; ++ ++ // Invert output ++ // (0 = off, 1 = on) ++ rpi,invert = <0>; ++ ++ // Enable debugging messages ++ // (0 = off, 1 = on) ++ rpi,debug = <0>; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ lirc_pins: lirc_pins { ++ brcm,pins = <17 18>; ++ brcm,function = <1 0>; // out in ++ brcm,pull = <0 1>; // off down ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; ++ gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; ++ gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; ++ ++ sense = <&lirc_rpi>,"rpi,sense:0"; ++ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; ++ invert = <&lirc_rpi>,"rpi,invert:0"; ++ debug = <&lirc_rpi>,"rpi,debug:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts +new file mode 100755 +index 0000000..398d59c +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts +@@ -0,0 +1,69 @@ ++/* ++ * Device tree overlay for mcp251x/can0 on spi0.0 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* disable spi-dev for spi0.0 */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ spidev@0{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ /* the interrupt pin of the can-controller */ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ can0_pins: can0_pins { ++ brcm,pins = <25>; ++ brcm,function = <0>; /* input */ ++ }; ++ }; ++ }; ++ ++ /* the clock/oscillator of the can-controller */ ++ fragment@2 { ++ target-path = "/clocks"; ++ __overlay__ { ++ /* external oscillator of mcp2515 on SPI0.0 */ ++ can0_osc: can0_osc { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <16000000>; ++ }; ++ }; ++ }; ++ ++ /* the spi config of the can-controller itself binding everything together */ ++ fragment@3 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ can0: mcp2515@0 { ++ reg = <0>; ++ compatible = "microchip,mcp2515"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&can0_pins>; ++ spi-max-frequency = <10000000>; ++ interrupt-parent = <&gpio>; ++ interrupts = <25 0x2>; ++ clocks = <&can0_osc>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ oscillator = <&can0_osc>,"clock-frequency:0"; ++ spimaxfrequency = <&can0>,"spi-max-frequency:0"; ++ interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts +new file mode 100644 +index 0000000..0a37cf4 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts +@@ -0,0 +1,19 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&mmc>; ++ ++ __overlay__ { ++ brcm,overclock-50 = <0>; ++ }; ++ }; ++ ++ __overrides__ { ++ overclock_50 = <&mmc>,"brcm,overclock-50:0"; ++ force_pio = <&mmc>,"brcm,force-pio?"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts +new file mode 100644 +index 0000000..c06fe12 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts +@@ -0,0 +1,109 @@ ++/* ++ * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ mz61581_pins: mz61581_pins { ++ brcm,pins = <4 15 18 25>; ++ brcm,function = <0 1 1 1>; /* in out out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ mz61581: mz61581@0{ ++ compatible = "samsung,s6d02a1"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mz61581_pins>; ++ ++ spi-max-frequency = <128000000>; ++ spi-cpol; ++ spi-cpha; ++ ++ width = <320>; ++ height = <480>; ++ rotate = <270>; ++ bgr; ++ fps = <30>; ++ buswidth = <8>; ++ ++ reset-gpios = <&gpio 15 0>; ++ dc-gpios = <&gpio 25 0>; ++ led-gpios = <&gpio 18 0>; ++ ++ init = <0x10000b0 00 ++ 0x1000011 ++ 0x20000ff ++ 0x10000b3 0x02 0x00 0x00 0x00 ++ 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 ++ 0x10000c1 0x08 0x16 0x08 0x08 ++ 0x10000c4 0x11 0x07 0x03 0x03 ++ 0x10000c6 0x00 ++ 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 ++ 0x1000035 0x00 ++ 0x1000036 0xa0 ++ 0x100003a 0x55 ++ 0x1000044 0x00 0x01 ++ 0x10000d0 0x07 0x07 0x1d 0x03 ++ 0x10000d1 0x03 0x30 0x10 ++ 0x10000d2 0x03 0x14 0x04 ++ 0x1000029 ++ 0x100002c>; ++ ++ /* This is a workaround to make sure the init sequence slows down and doesn't fail */ ++ debug = <3>; ++ }; ++ ++ mz61581_ts: mz61581_ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <4 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 4 0>; ++ ++ ti,x-plate-ohms = /bits/ 16 <60>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&mz61581>, "spi-max-frequency:0"; ++ rotate = <&mz61581>, "rotate:0"; ++ fps = <&mz61581>, "fps:0"; ++ debug = <&mz61581>, "debug:0"; ++ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +new file mode 100644 +index 0000000..ba4ad33 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts +@@ -0,0 +1,96 @@ ++/* ++ * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ piscreen_pins: piscreen_pins { ++ brcm,pins = <17 25 24 22>; ++ brcm,function = <0 1 1 1>; /* in out out out */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ piscreen: piscreen@0{ ++ compatible = "ilitek,ili9486"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&piscreen_pins>; ++ ++ spi-max-frequency = <24000000>; ++ rotate = <270>; ++ bgr; ++ fps = <30>; ++ buswidth = <8>; ++ regwidth = <16>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 22 1>; ++ debug = <0>; ++ ++ init = <0x10000b0 0x00 ++ 0x1000011 ++ 0x20000ff ++ 0x100003a 0x55 ++ 0x1000036 0x28 ++ 0x10000c2 0x44 ++ 0x10000c5 0x00 0x00 0x00 0x00 ++ 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 ++ 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 ++ 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 ++ 0x1000011 ++ 0x1000029>; ++ }; ++ ++ piscreen_ts: piscreen-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <17 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 17 0>; ++ ti,swap-xy; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&piscreen>,"spi-max-frequency:0"; ++ rotate = <&piscreen>,"rotate:0"; ++ fps = <&piscreen>,"fps:0"; ++ debug = <&piscreen>,"debug:0"; ++ xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts +new file mode 100644 +index 0000000..d506eae +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts +@@ -0,0 +1,115 @@ ++/* ++ * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ pitft_pins: pitft_pins { ++ brcm,pins = <24 25>; ++ brcm,function = <0 1>; /* in out */ ++ brcm,pull = <2 0>; /* pullup none */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pitft: pitft@0{ ++ compatible = "ilitek,ili9340"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pitft_pins>; ++ ++ spi-max-frequency = <32000000>; ++ rotate = <90>; ++ fps = <25>; ++ bgr; ++ buswidth = <8>; ++ dc-gpios = <&gpio 25 0>; ++ debug = <0>; ++ }; ++ ++ pitft_ts@1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "st,stmpe610"; ++ reg = <1>; ++ ++ spi-max-frequency = <500000>; ++ irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ ++ interrupts = <24 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ interrupt-controller; ++ ++ stmpe_touchscreen { ++ compatible = "st,stmpe-ts"; ++ st,sample-time = <4>; ++ st,mod-12b = <1>; ++ st,ref-sel = <0>; ++ st,adc-freq = <2>; ++ st,ave-ctrl = <3>; ++ st,touch-det-delay = <4>; ++ st,settling = <2>; ++ st,fraction-z = <7>; ++ st,i-drive = <0>; ++ }; ++ ++ stmpe_gpio: stmpe_gpio { ++ #gpio-cells = <2>; ++ compatible = "st,stmpe-gpio"; ++ /* ++ * only GPIO2 is wired/available ++ * and it is wired to the backlight ++ */ ++ st,norequest-mask = <0x7b>; ++ }; ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target-path = "/soc"; ++ __overlay__ { ++ backlight { ++ compatible = "gpio-backlight"; ++ gpios = <&stmpe_gpio 2 0>; ++ default-on; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ speed = <&pitft>,"spi-max-frequency:0"; ++ rotate = <&pitft>,"rotate:0"; ++ fps = <&pitft>,"fps:0"; ++ debug = <&pitft>,"debug:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts +new file mode 100644 +index 0000000..40bf0e1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts +@@ -0,0 +1,34 @@ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ pps: pps { ++ compatible = "pps-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pps_pins>; ++ gpios = <&gpio 18 0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ pps_pins: pps_pins { ++ brcm,pins = <18>; ++ brcm,function = <0>; // in ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&pps>,"gpios:4", ++ <&pps_pins>,"brcm,pins:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts +new file mode 100644 +index 0000000..7fc6ac9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts +@@ -0,0 +1,34 @@ ++// Definitions for RPi DAC ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "rpi,rpi-dac"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target-path = "/"; ++ __overlay__ { ++ pcm1794a-codec { ++ #sound-dai-cells = <0>; ++ compatible = "ti,pcm1794a"; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts +new file mode 100644 +index 0000000..a8fa974 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts +@@ -0,0 +1,82 @@ ++/* ++ * Device Tree overlay for rpi-display by Watterott ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ rpi_display_pins: rpi_display_pins { ++ brcm,pins = <18 23 24 25>; ++ brcm,function = <1 1 1 0>; /* out out out in */ ++ brcm,pull = <0 0 0 2>; /* - - - up */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ rpidisplay: rpi-display@0{ ++ compatible = "ilitek,ili9341"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rpi_display_pins>; ++ ++ spi-max-frequency = <32000000>; ++ rotate = <270>; ++ bgr; ++ fps = <30>; ++ buswidth = <8>; ++ reset-gpios = <&gpio 23 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 18 1>; ++ debug = <0>; ++ }; ++ ++ rpidisplay_ts: rpi-display-ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <25 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 25 0>; ++ ti,x-plate-ohms = /bits/ 16 <60>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ __overrides__ { ++ speed = <&rpidisplay>,"spi-max-frequency:0"; ++ rotate = <&rpidisplay>,"rotate:0"; ++ fps = <&rpidisplay>,"fps:0"; ++ debug = <&rpidisplay>,"debug:0"; ++ xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts +new file mode 100644 +index 0000000..2029930 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for Rpi-Proto ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&sound>; ++ __overlay__ { ++ compatible = "rpi,rpi-proto"; ++ i2s-controller = <&i2s>; ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&i2s>; ++ __overlay__ { ++ status = "okay"; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ wm8731@1a { ++ #sound-dai-cells = <0>; ++ compatible = "wlf,wm8731"; ++ reg = <0x1a>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts +new file mode 100644 +index 0000000..8fb28e9 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts +@@ -0,0 +1,78 @@ ++/dts-v1/; ++/plugin/; ++ ++/{ ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target = <&soc>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ sdhost: sdhost@7e202000 { ++ compatible = "brcm,bcm2835-sdhost"; ++ reg = <0x7e202000 0x100>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_pins>; ++ interrupts = <2 24>; ++ clocks = <&clk_sdhost>; ++ dmas = <&dma 13>, ++ <&dma 13>; ++ dma-names = "tx", "rx"; ++ brcm,delay-after-stop = <0>; ++ brcm,overclock-50 = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&clocks>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ clk_sdhost: sdhost { ++ compatible = "fixed-clock"; ++ reg = <0>; ++ #clock-cells = <0>; ++ clock-output-names = "sdhost"; ++ clock-frequency = <250000000>; ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&gpio>; ++ __overlay__ { ++ sdhost_pins: sdhost_pins { ++ brcm,pins = <48 49 50 51 52 53>; ++ brcm,function = <4>; /* alt0 */ ++ }; ++ }; ++ }; ++ ++ fragment@3 { ++ target = <&mmc>; ++ __overlay__ { ++ /* Find a way to disable the other driver */ ++ compatible = ""; ++ status = "disabled"; ++ }; ++ }; ++ ++ fragment@4 { ++ target-path = "/__overrides__"; ++ __overlay__ { ++ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ }; ++ }; ++ ++ __overrides__ { ++ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; ++ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; ++ force_pio = <&sdhost>,"brcm,force-pio?"; ++ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts +new file mode 100644 +index 0000000..e378ef1 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts +@@ -0,0 +1,18 @@ ++/* ++ * Device tree overlay for spi-bcm2835 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ compatible = "brcm,bcm2708-spi"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts +new file mode 100644 +index 0000000..fc1e39b +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts +@@ -0,0 +1,18 @@ ++/* ++ * Device tree overlay for spi-bcm2835 ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; ++ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ compatible = "brcm,bcm2835-spi"; ++ }; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +new file mode 100644 +index 0000000..f7102c8 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts +@@ -0,0 +1,216 @@ ++/* ++ * tinylcd35-overlay.dts ++ * ++ * ------------------------------------------------- ++ * www.tinlylcd.com ++ * ------------------------------------------------- ++ * Device---Driver-----BUS GPIO's ++ * display tinylcd35 spi0.0 25 24 18 ++ * touch ads7846 spi0.1 5 ++ * rtc ds1307 i2c1-0068 ++ * rtc pcf8563 i2c1-0051 ++ * keypad gpio-keys --------- 17 22 27 23 28 ++ * ++ * ++ * TinyLCD.com 3.5 inch TFT ++ * ++ * Version 001 ++ * 5/3/2015 -- Noralf Trønnes Initial Device tree framework ++ * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. ++ * ++ */ ++ ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; ++ ++ fragment@0 { ++ target = <&spi0>; ++ __overlay__ { ++ status = "okay"; ++ ++ spidev@0{ ++ status = "disabled"; ++ }; ++ ++ spidev@1{ ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ tinylcd35_pins: tinylcd35_pins { ++ brcm,pins = <25 24 18>; ++ brcm,function = <1>; /* out */ ++ }; ++ tinylcd35_ts_pins: tinylcd35_ts_pins { ++ brcm,pins = <5>; ++ brcm,function = <0>; /* in */ ++ }; ++ keypad_pins: keypad_pins { ++ brcm,pins = <4 17 22 23 27>; ++ brcm,function = <0>; /* in */ ++ brcm,pull = <1>; /* down */ ++ }; ++ }; ++ }; ++ ++ fragment@2 { ++ target = <&spi0>; ++ __overlay__ { ++ /* needed to avoid dtc warning */ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ tinylcd35: tinylcd35@0{ ++ compatible = "neosec,tinylcd"; ++ reg = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&tinylcd35_pins>, ++ <&tinylcd35_ts_pins>; ++ ++ spi-max-frequency = <48000000>; ++ rotate = <270>; ++ fps = <20>; ++ bgr; ++ buswidth = <8>; ++ reset-gpios = <&gpio 25 0>; ++ dc-gpios = <&gpio 24 0>; ++ led-gpios = <&gpio 18 1>; ++ debug = <0>; ++ ++ init = <0x10000B0 0x80 ++ 0x10000C0 0x0A 0x0A ++ 0x10000C1 0x01 0x01 ++ 0x10000C2 0x33 ++ 0x10000C5 0x00 0x42 0x80 ++ 0x10000B1 0xD0 0x11 ++ 0x10000B4 0x02 ++ 0x10000B6 0x00 0x22 0x3B ++ 0x10000B7 0x07 ++ 0x1000036 0x58 ++ 0x10000F0 0x36 0xA5 0xD3 ++ 0x10000E5 0x80 ++ 0x10000E5 0x01 ++ 0x10000B3 0x00 ++ 0x10000E5 0x00 ++ 0x10000F0 0x36 0xA5 0x53 ++ 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 ++ 0x100003A 0x55 ++ 0x1000011 ++ 0x2000001 ++ 0x1000029>; ++ }; ++ ++ tinylcd35_ts: tinylcd35_ts@1 { ++ compatible = "ti,ads7846"; ++ reg = <1>; ++ status = "disabled"; ++ ++ spi-max-frequency = <2000000>; ++ interrupts = <5 2>; /* high-to-low edge triggered */ ++ interrupt-parent = <&gpio>; ++ pendown-gpio = <&gpio 5 0>; ++ ti,x-plate-ohms = /bits/ 16 <100>; ++ ti,pressure-max = /bits/ 16 <255>; ++ }; ++ }; ++ }; ++ ++ /* RTC */ ++ ++ fragment@3 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ pcf8563: pcf8563@51 { ++ compatible = "nxp,pcf8563"; ++ reg = <0x51>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ fragment@4 { ++ target = <&i2c1>; ++ __overlay__ { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ds1307: ds1307@68 { ++ compatible = "maxim,ds1307"; ++ reg = <0x68>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ /* ++ * Values for input event code is found under the ++ * 'Keys and buttons' heading in include/uapi/linux/input.h ++ */ ++ fragment@5 { ++ target-path = "/soc"; ++ __overlay__ { ++ keypad: keypad { ++ compatible = "gpio-keys"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&keypad_pins>; ++ status = "disabled"; ++ autorepeat; ++ ++ button@17 { ++ label = "GPIO KEY_UP"; ++ linux,code = <103>; ++ gpios = <&gpio 17 0>; ++ }; ++ button@22 { ++ label = "GPIO KEY_DOWN"; ++ linux,code = <108>; ++ gpios = <&gpio 22 0>; ++ }; ++ button@27 { ++ label = "GPIO KEY_LEFT"; ++ linux,code = <105>; ++ gpios = <&gpio 27 0>; ++ }; ++ button@23 { ++ label = "GPIO KEY_RIGHT"; ++ linux,code = <106>; ++ gpios = <&gpio 23 0>; ++ }; ++ button@4 { ++ label = "GPIO KEY_ENTER"; ++ linux,code = <28>; ++ gpios = <&gpio 4 0>; ++ }; ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ speed = <&tinylcd35>,"spi-max-frequency:0"; ++ rotate = <&tinylcd35>,"rotate:0"; ++ fps = <&tinylcd35>,"fps:0"; ++ debug = <&tinylcd35>,"debug:0"; ++ touch = <&tinylcd35_ts>,"status"; ++ touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", ++ <&tinylcd35_ts>,"interrupts:0", ++ <&tinylcd35_ts>,"pendown-gpio:4"; ++ xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; ++ rtc-pcf = <&i2c1>,"status", ++ <&pcf8563>,"status"; ++ rtc-ds = <&i2c1>,"status", ++ <&ds1307>,"status"; ++ keypad = <&keypad>,"status"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts +new file mode 100644 +index 0000000..29a3b48 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts +@@ -0,0 +1,39 @@ ++// Definitions for w1-gpio module (without external pullup) ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ w1: onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&gpio 4 0>; ++ rpi,parasitic-power = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ brcm,pins = <4>; ++ brcm,function = <0>; // in (initially) ++ brcm,pull = <0>; // off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&w1>,"gpios:4", ++ <&w1_pins>,"brcm,pins:0"; ++ pullup = <&w1>,"rpi,parasitic-power:0"; ++ }; ++}; +diff --git a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +new file mode 100644 +index 0000000..66a98f6 +--- /dev/null ++++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts +@@ -0,0 +1,41 @@ ++// Definitions for w1-gpio module (with external pullup) ++/dts-v1/; ++/plugin/; ++ ++/ { ++ compatible = "brcm,bcm2708"; ++ ++ fragment@0 { ++ target-path = "/"; ++ __overlay__ { ++ ++ w1: onewire@0 { ++ compatible = "w1-gpio"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&w1_pins>; ++ gpios = <&gpio 4 0>, <&gpio 5 1>; ++ rpi,parasitic-power = <0>; ++ status = "okay"; ++ }; ++ }; ++ }; ++ ++ fragment@1 { ++ target = <&gpio>; ++ __overlay__ { ++ w1_pins: w1_pins { ++ brcm,pins = <4 5>; ++ brcm,function = <0 1>; // in out ++ brcm,pull = <0 0>; // off off ++ }; ++ }; ++ }; ++ ++ __overrides__ { ++ gpiopin = <&w1>,"gpios:4", ++ <&w1_pins>,"brcm,pins:0"; ++ extpullup = <&w1>,"gpios:16", ++ <&w1_pins>,"brcm,pins:4"; ++ pullup = <&w1>,"rpi,parasitic-power:0"; ++ }; ++}; + +From 4bd17cf8893beb8fb36fe6e321abfe2bc091eb17 Mon Sep 17 00:00:00 2001 +From: Siarhei Siamashka +Date: Mon, 17 Jun 2013 13:32:11 +0300 +Subject: [PATCH 27/77] fbdev: add FBIOCOPYAREA ioctl + +Based on the patch authored by Ali Gholami Rudi at + https://lkml.org/lkml/2009/7/13/153 + +Provide an ioctl for userspace applications, but only if this operation +is hardware accelerated (otherwide it does not make any sense). + +Signed-off-by: Siarhei Siamashka +--- + drivers/video/fbdev/core/fbmem.c | 30 ++++++++++++++++++++++++++++++ + include/uapi/linux/fb.h | 5 +++++ + 2 files changed, 35 insertions(+) + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index 0705d88..771992a 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1084,6 +1084,25 @@ fb_blank(struct fb_info *info, int blank) + } + EXPORT_SYMBOL(fb_blank); + ++static int fb_copyarea_user(struct fb_info *info, ++ struct fb_copyarea *copy) ++{ ++ int ret = 0; ++ if (!lock_fb_info(info)) ++ return -ENODEV; ++ if (copy->dx + copy->width > info->var.xres || ++ copy->sx + copy->width > info->var.xres || ++ copy->dy + copy->height > info->var.yres || ++ copy->sy + copy->height > info->var.yres) { ++ ret = -EINVAL; ++ goto out; ++ } ++ info->fbops->fb_copyarea(info, copy); ++out: ++ unlock_fb_info(info); ++ return ret; ++} ++ + static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + unsigned long arg) + { +@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + struct fb_cmap cmap_from; + struct fb_cmap_user cmap; + struct fb_event event; ++ struct fb_copyarea copy; + void __user *argp = (void __user *)arg; + long ret = 0; + +@@ -1211,6 +1231,15 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, + unlock_fb_info(info); + console_unlock(); + break; ++ case FBIOCOPYAREA: ++ if (info->flags & FBINFO_HWACCEL_COPYAREA) { ++ /* only provide this ioctl if it is accelerated */ ++ if (copy_from_user(©, argp, sizeof(copy))) ++ return -EFAULT; ++ ret = fb_copyarea_user(info, ©); ++ break; ++ } ++ /* fall through */ + default: + if (!lock_fb_info(info)) + return -ENODEV; +@@ -1365,6 +1394,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, + case FBIOPAN_DISPLAY: + case FBIOGET_CON2FBMAP: + case FBIOPUT_CON2FBMAP: ++ case FBIOCOPYAREA: + arg = (unsigned long) compat_ptr(arg); + case FBIOBLANK: + ret = do_fb_ioctl(info, cmd, arg); +diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h +index fb795c3..fa72af0 100644 +--- a/include/uapi/linux/fb.h ++++ b/include/uapi/linux/fb.h +@@ -34,6 +34,11 @@ + #define FBIOPUT_MODEINFO 0x4617 + #define FBIOGET_DISPINFO 0x4618 + #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) ++/* ++ * HACK: use 'z' in order not to clash with any other ioctl numbers which might ++ * be concurrently added to the mainline kernel ++ */ ++#define FBIOCOPYAREA _IOW('z', 0x21, struct fb_copyarea) + + #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ + #define FB_TYPE_PLANES 1 /* Non interleaved planes */ + +From 54459bf0dcbd9019a1bc98cdc77a5c37811c1be5 Mon Sep 17 00:00:00 2001 +From: Harm Hanemaaijer +Date: Thu, 20 Jun 2013 20:21:39 +0200 +Subject: [PATCH 30/77] Speed up console framebuffer imageblit function + +Especially on platforms with a slower CPU but a relatively high +framebuffer fill bandwidth, like current ARM devices, the existing +console monochrome imageblit function used to draw console text is +suboptimal for common pixel depths such as 16bpp and 32bpp. The existing +code is quite general and can deal with several pixel depths. By creating +special case functions for 16bpp and 32bpp, by far the most common pixel +formats used on modern systems, a significant speed-up is attained +which can be readily felt on ARM-based devices like the Raspberry Pi +and the Allwinner platform, but should help any platform using the +fb layer. + +The special case functions allow constant folding, eliminating a number +of instructions including divide operations, and allow the use of an +unrolled loop, eliminating instructions with a variable shift size, +reducing source memory access instructions, and eliminating excessive +branching. These unrolled loops also allow much better code optimization +by the C compiler. The code that selects which optimized variant is used +is also simplified, eliminating integer divide instructions. + +The speed-up, measured by timing 'cat file.txt' in the console, varies +between 40% and 70%, when testing on the Raspberry Pi and Allwinner +ARM-based platforms, depending on font size and the pixel depth, with +the greater benefit for 32bpp. + +Signed-off-by: Harm Hanemaaijer +--- + drivers/video/fbdev/core/cfbimgblt.c | 152 +++++++++++++++++++++++++++++++++-- + 1 file changed, 147 insertions(+), 5 deletions(-) + +diff --git a/drivers/video/fbdev/core/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c +index a2bb276..436494f 100644 +--- a/drivers/video/fbdev/core/cfbimgblt.c ++++ b/drivers/video/fbdev/core/cfbimgblt.c +@@ -28,6 +28,11 @@ + * + * Also need to add code to deal with cards endians that are different than + * the native cpu endians. I also need to deal with MSB position in the word. ++ * Modified by Harm Hanemaaijer (fgenfb@yahoo.com) 2013: ++ * - Provide optimized versions of fast_imageblit for 16 and 32bpp that are ++ * significantly faster than the previous implementation. ++ * - Simplify the fast/slow_imageblit selection code, avoiding integer ++ * divides. + */ + #include + #include +@@ -262,6 +267,133 @@ static inline void fast_imageblit(const struct fb_image *image, struct fb_info * + } + } + ++/* ++ * Optimized fast_imageblit for bpp == 16. ppw = 2, bit_mask = 3 folded ++ * into the code, main loop unrolled. ++ */ ++ ++static inline void fast_imageblit16(const struct fb_image *image, ++ struct fb_info *p, u8 __iomem * dst1, ++ u32 fgcolor, u32 bgcolor) ++{ ++ u32 fgx = fgcolor, bgx = bgcolor; ++ u32 spitch = (image->width + 7) / 8; ++ u32 end_mask, eorx; ++ const char *s = image->data, *src; ++ u32 __iomem *dst; ++ const u32 *tab = NULL; ++ int i, j, k; ++ ++ tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; ++ ++ fgx <<= 16; ++ bgx <<= 16; ++ fgx |= fgcolor; ++ bgx |= bgcolor; ++ ++ eorx = fgx ^ bgx; ++ k = image->width / 2; ++ ++ for (i = image->height; i--;) { ++ dst = (u32 __iomem *) dst1; ++ src = s; ++ ++ j = k; ++ while (j >= 4) { ++ u8 bits = *src; ++ end_mask = tab[(bits >> 6) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 4) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 2) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[bits & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ src++; ++ j -= 4; ++ } ++ if (j != 0) { ++ u8 bits = *src; ++ end_mask = tab[(bits >> 6) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ if (j >= 2) { ++ end_mask = tab[(bits >> 4) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ if (j == 3) { ++ end_mask = tab[(bits >> 2) & 3]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst); ++ } ++ } ++ } ++ dst1 += p->fix.line_length; ++ s += spitch; ++ } ++} ++ ++/* ++ * Optimized fast_imageblit for bpp == 32. ppw = 1, bit_mask = 1 folded ++ * into the code, main loop unrolled. ++ */ ++ ++static inline void fast_imageblit32(const struct fb_image *image, ++ struct fb_info *p, u8 __iomem * dst1, ++ u32 fgcolor, u32 bgcolor) ++{ ++ u32 fgx = fgcolor, bgx = bgcolor; ++ u32 spitch = (image->width + 7) / 8; ++ u32 end_mask, eorx; ++ const char *s = image->data, *src; ++ u32 __iomem *dst; ++ const u32 *tab = NULL; ++ int i, j, k; ++ ++ tab = cfb_tab32; ++ ++ eorx = fgx ^ bgx; ++ k = image->width; ++ ++ for (i = image->height; i--;) { ++ dst = (u32 __iomem *) dst1; ++ src = s; ++ ++ j = k; ++ while (j >= 8) { ++ u8 bits = *src; ++ end_mask = tab[(bits >> 7) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 6) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 5) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 4) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 3) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 2) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[(bits >> 1) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ end_mask = tab[bits & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ src++; ++ j -= 8; ++ } ++ if (j != 0) { ++ u32 bits = (u32) * src; ++ while (j > 1) { ++ end_mask = tab[(bits >> 7) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst++); ++ bits <<= 1; ++ j--; ++ } ++ end_mask = tab[(bits >> 7) & 1]; ++ FB_WRITEL((end_mask & eorx) ^ bgx, dst); ++ } ++ dst1 += p->fix.line_length; ++ s += spitch; ++ } ++} ++ + void cfb_imageblit(struct fb_info *p, const struct fb_image *image) + { + u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; +@@ -294,11 +426,21 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) + bgcolor = image->bg_color; + } + +- if (32 % bpp == 0 && !start_index && !pitch_index && +- ((width & (32/bpp-1)) == 0) && +- bpp >= 8 && bpp <= 32) +- fast_imageblit(image, p, dst1, fgcolor, bgcolor); +- else ++ if (!start_index && !pitch_index) { ++ if (bpp == 32) ++ fast_imageblit32(image, p, dst1, fgcolor, ++ bgcolor); ++ else if (bpp == 16 && (width & 1) == 0) ++ fast_imageblit16(image, p, dst1, fgcolor, ++ bgcolor); ++ else if (bpp == 8 && (width & 3) == 0) ++ fast_imageblit(image, p, dst1, fgcolor, ++ bgcolor); ++ else ++ slow_imageblit(image, p, dst1, fgcolor, ++ bgcolor, ++ start_index, pitch_index); ++ } else + slow_imageblit(image, p, dst1, fgcolor, bgcolor, + start_index, pitch_index); + } else + +From b78abfc78e582f82fda5e69816eaa97b1097c853 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 26 Mar 2013 17:26:38 +0000 +Subject: [PATCH 31/77] Allow mac address to be set in smsc95xx + +Signed-off-by: popcornmix +--- + drivers/net/usb/smsc95xx.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 56 insertions(+) + +diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c +index 26423ad..e29a323 100644 +--- a/drivers/net/usb/smsc95xx.c ++++ b/drivers/net/usb/smsc95xx.c +@@ -59,6 +59,7 @@ + #define SUSPEND_SUSPEND3 (0x08) + #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ + SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) ++#define MAC_ADDR_LEN (6) + + struct smsc95xx_priv { + u32 mac_cr; +@@ -74,6 +75,10 @@ static bool turbo_mode = true; + module_param(turbo_mode, bool, 0644); + MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); + ++static char *macaddr = ":"; ++module_param(macaddr, charp, 0); ++MODULE_PARM_DESC(macaddr, "MAC address"); ++ + static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index, + u32 *data, int in_pm) + { +@@ -763,8 +768,59 @@ static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) + return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); + } + ++/* Check the macaddr module parameter for a MAC address */ ++static int smsc95xx_is_macaddr_param(struct usbnet *dev, u8 *dev_mac) ++{ ++ int i, j, got_num, num; ++ u8 mtbl[MAC_ADDR_LEN]; ++ ++ if (macaddr[0] == ':') ++ return 0; ++ ++ i = 0; ++ j = 0; ++ num = 0; ++ got_num = 0; ++ while (j < MAC_ADDR_LEN) { ++ if (macaddr[i] && macaddr[i] != ':') { ++ got_num++; ++ if ('0' <= macaddr[i] && macaddr[i] <= '9') ++ num = num * 16 + macaddr[i] - '0'; ++ else if ('A' <= macaddr[i] && macaddr[i] <= 'F') ++ num = num * 16 + 10 + macaddr[i] - 'A'; ++ else if ('a' <= macaddr[i] && macaddr[i] <= 'f') ++ num = num * 16 + 10 + macaddr[i] - 'a'; ++ else ++ break; ++ i++; ++ } else if (got_num == 2) { ++ mtbl[j++] = (u8) num; ++ num = 0; ++ got_num = 0; ++ i++; ++ } else { ++ break; ++ } ++ } ++ ++ if (j == MAC_ADDR_LEN) { ++ netif_dbg(dev, ifup, dev->net, "Overriding MAC address with: " ++ "%02x:%02x:%02x:%02x:%02x:%02x\n", mtbl[0], mtbl[1], mtbl[2], ++ mtbl[3], mtbl[4], mtbl[5]); ++ for (i = 0; i < MAC_ADDR_LEN; i++) ++ dev_mac[i] = mtbl[i]; ++ return 1; ++ } else { ++ return 0; ++ } ++} ++ + static void smsc95xx_init_mac_address(struct usbnet *dev) + { ++ /* Check module parameters */ ++ if (smsc95xx_is_macaddr_param(dev, dev->net->dev_addr)) ++ return; ++ + /* try reading mac address from EEPROM */ + if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN, + dev->net->dev_addr) == 0) { + +From 468a5ebe451a5e3bc693fdbd67173f2fadb7d217 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 8 May 2013 11:46:50 +0100 +Subject: [PATCH 32/77] enabling the realtime clock 1-wire chip DS1307 and + 1-wire on GPIO4 (as a module) + +1-wire: Add support for configuring pin for w1-gpio kernel module +See: https://github.com/raspberrypi/linux/pull/457 + +Add bitbanging pullups, use them for w1-gpio + +Allows parasite power to work, uses module option pullup=1 + +bcm2708: Ensure 1-wire pullup is disabled by default, and expose as module parameter + +Signed-off-by: Alex J Lennon + +w1-gpio: Add gpiopin module parameter and correctly free up gpio pull-up pin, if set + +Signed-off-by: Alex J Lennon + +w1-gpio: Sort out the pullup/parasitic power tangle +--- + arch/arm/mach-bcm2708/bcm2708.c | 29 +++++++++++++++++ + arch/arm/mach-bcm2709/bcm2709.c | 29 +++++++++++++++++ + drivers/w1/masters/w1-gpio.c | 69 +++++++++++++++++++++++++++++++++++++---- + drivers/w1/w1.h | 6 ++++ + drivers/w1/w1_int.c | 14 +++++++++ + drivers/w1/w1_io.c | 18 +++++++++-- + include/linux/w1-gpio.h | 1 + + 7 files changed, 157 insertions(+), 9 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index efb3544..c7b4b61 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -77,12 +78,19 @@ + */ + #define DMA_MASK_BITS_COMMON 32 + ++// use GPIO 4 for the one-wire GPIO pin, if enabled ++#define W1_GPIO 4 ++// ensure one-wire GPIO pullup is disabled by default ++#define W1_PULLUP -1 ++ + /* command line parameters */ + static unsigned boardrev, serial; + static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static unsigned w1_gpio_pin = W1_GPIO; ++static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; + + static unsigned use_dt = 0; +@@ -303,6 +311,20 @@ static struct platform_device bcm2708_dmaengine_device = { + .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), + }; + ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++static struct w1_gpio_platform_data w1_gpio_pdata = { ++ .pin = W1_GPIO, ++ .ext_pullup_enable_pin = W1_PULLUP, ++ .is_open_drain = 0, ++}; ++ ++static struct platform_device w1_device = { ++ .name = "w1-gpio", ++ .id = -1, ++ .dev.platform_data = &w1_gpio_pdata, ++}; ++#endif ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -729,6 +751,11 @@ void __init bcm2708_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++ w1_gpio_pdata.pin = w1_gpio_pin; ++ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; ++ bcm_register_device_dt(&w1_device); ++#endif + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); + +@@ -942,5 +969,7 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(w1_gpio_pin, uint, 0644); ++module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 8017c50..03e208b 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -79,12 +80,19 @@ + */ + #define DMA_MASK_BITS_COMMON 32 + ++// use GPIO 4 for the one-wire GPIO pin, if enabled ++#define W1_GPIO 4 ++// ensure one-wire GPIO pullup is disabled by default ++#define W1_PULLUP -1 ++ + /* command line parameters */ + static unsigned boardrev, serial; + static unsigned uart_clock = UART0_CLOCK; + static unsigned disk_led_gpio = 16; + static unsigned disk_led_active_low = 1; + static unsigned reboot_part = 0; ++static unsigned w1_gpio_pin = W1_GPIO; ++static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; + + static unsigned use_dt = 0; +@@ -313,6 +321,20 @@ static struct platform_device bcm2708_dmaengine_device = { + .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), + }; + ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++static struct w1_gpio_platform_data w1_gpio_pdata = { ++ .pin = W1_GPIO, ++ .ext_pullup_enable_pin = W1_PULLUP, ++ .is_open_drain = 0, ++}; ++ ++static struct platform_device w1_device = { ++ .name = "w1-gpio", ++ .id = -1, ++ .dev.platform_data = &w1_gpio_pdata, ++}; ++#endif ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -749,6 +771,11 @@ void __init bcm2709_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) ++ w1_gpio_pdata.pin = w1_gpio_pin; ++ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; ++ bcm_register_device_dt(&w1_device); ++#endif + bcm_register_device_dt(&bcm2708_fb_device); + bcm_register_device_dt(&bcm2708_usb_device); + +@@ -1110,5 +1137,7 @@ module_param(uart_clock, uint, 0644); + module_param(disk_led_gpio, uint, 0644); + module_param(disk_led_active_low, uint, 0644); + module_param(reboot_part, uint, 0644); ++module_param(w1_gpio_pin, uint, 0644); ++module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); +diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c +index 8f7848c6..2240f32 100644 +--- a/drivers/w1/masters/w1-gpio.c ++++ b/drivers/w1/masters/w1-gpio.c +@@ -23,6 +23,19 @@ + #include "../w1.h" + #include "../w1_int.h" + ++static int w1_gpio_pullup = 0; ++static int w1_gpio_pullup_orig = 0; ++module_param_named(pullup, w1_gpio_pullup, int, 0); ++MODULE_PARM_DESC(pullup, "Enable parasitic power (power on data) mode"); ++static int w1_gpio_pullup_pin = -1; ++static int w1_gpio_pullup_pin_orig = -1; ++module_param_named(extpullup, w1_gpio_pullup_pin, int, 0); ++MODULE_PARM_DESC(extpullup, "GPIO external pullup pin number"); ++static int w1_gpio_pin = -1; ++static int w1_gpio_pin_orig = -1; ++module_param_named(gpiopin, w1_gpio_pin, int, 0); ++MODULE_PARM_DESC(gpiopin, "GPIO pin number"); ++ + static u8 w1_gpio_set_pullup(void *data, int delay) + { + struct w1_gpio_platform_data *pdata = data; +@@ -67,6 +80,16 @@ static u8 w1_gpio_read_bit(void *data) + return gpio_get_value(pdata->pin) ? 1 : 0; + } + ++static void w1_gpio_bitbang_pullup(void *data, u8 on) ++{ ++ struct w1_gpio_platform_data *pdata = data; ++ ++ if (on) ++ gpio_direction_output(pdata->pin, 1); ++ else ++ gpio_direction_input(pdata->pin); ++} ++ + #if defined(CONFIG_OF) + static const struct of_device_id w1_gpio_dt_ids[] = { + { .compatible = "w1-gpio" }, +@@ -80,6 +103,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct device_node *np = pdev->dev.of_node; + int gpio; ++ u32 value; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) +@@ -88,6 +112,9 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + if (of_get_property(np, "linux,open-drain", NULL)) + pdata->is_open_drain = 1; + ++ if (of_property_read_u32(np, "rpi,parasitic-power", &value) == 0) ++ pdata->parasitic_power = (value != 0); ++ + gpio = of_get_gpio(np, 0); + if (gpio < 0) { + if (gpio != -EPROBE_DEFER) +@@ -103,7 +130,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + if (gpio == -EPROBE_DEFER) + return gpio; + /* ignore other errors as the pullup gpio is optional */ +- pdata->ext_pullup_enable_pin = gpio; ++ pdata->ext_pullup_enable_pin = (gpio >= 0) ? gpio : -1; + + pdev->dev.platform_data = pdata; + +@@ -113,13 +140,15 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) + static int w1_gpio_probe(struct platform_device *pdev) + { + struct w1_bus_master *master; +- struct w1_gpio_platform_data *pdata; ++ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; + int err; + +- if (of_have_populated_dt()) { +- err = w1_gpio_probe_dt(pdev); +- if (err < 0) +- return err; ++ if(pdata == NULL) { ++ if (of_have_populated_dt()) { ++ err = w1_gpio_probe_dt(pdev); ++ if (err < 0) ++ return err; ++ } + } + + pdata = dev_get_platdata(&pdev->dev); +@@ -136,6 +165,22 @@ static int w1_gpio_probe(struct platform_device *pdev) + return -ENOMEM; + } + ++ w1_gpio_pin_orig = pdata->pin; ++ w1_gpio_pullup_pin_orig = pdata->ext_pullup_enable_pin; ++ w1_gpio_pullup_orig = pdata->parasitic_power; ++ ++ if(gpio_is_valid(w1_gpio_pin)) { ++ pdata->pin = w1_gpio_pin; ++ pdata->ext_pullup_enable_pin = -1; ++ pdata->parasitic_power = -1; ++ } ++ pdata->parasitic_power |= w1_gpio_pullup; ++ if(gpio_is_valid(w1_gpio_pullup_pin)) { ++ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin; ++ } ++ ++ dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power); ++ + err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); + if (err) { + dev_err(&pdev->dev, "gpio_request (pin) failed\n"); +@@ -165,6 +210,14 @@ static int w1_gpio_probe(struct platform_device *pdev) + master->set_pullup = w1_gpio_set_pullup; + } + ++ if (pdata->parasitic_power) { ++ if (pdata->is_open_drain) ++ printk(KERN_ERR "w1-gpio 'pullup'(parasitic power) " ++ "option doesn't work with open drain GPIO\n"); ++ else ++ master->bitbang_pullup = w1_gpio_bitbang_pullup; ++ } ++ + err = w1_add_master_device(master); + if (err) { + dev_err(&pdev->dev, "w1_add_master device failed\n"); +@@ -195,6 +248,10 @@ static int w1_gpio_remove(struct platform_device *pdev) + + w1_remove_master_device(master); + ++ pdata->pin = w1_gpio_pin_orig; ++ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin_orig; ++ pdata->parasitic_power = w1_gpio_pullup_orig; ++ + return 0; + } + +diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h +index 56a49ba..881d728 100644 +--- a/drivers/w1/w1.h ++++ b/drivers/w1/w1.h +@@ -171,6 +171,12 @@ struct w1_bus_master + + u8 (*set_pullup)(void *, int); + ++ /** ++ * Turns the pullup on/off in bitbanging mode, takes an on/off argument. ++ * @return -1=Error, 0=completed ++ */ ++ void (*bitbang_pullup) (void *, u8); ++ + void (*search)(void *, struct w1_master *, + u8, w1_slave_found_callback); + }; +diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c +index 47249a3..a4b4a8d 100644 +--- a/drivers/w1/w1_int.c ++++ b/drivers/w1/w1_int.c +@@ -123,6 +123,20 @@ int w1_add_master_device(struct w1_bus_master *master) + return(-EINVAL); + } + ++ /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup ++ * and takes care of timing itself */ ++ if (!master->write_byte && !master->touch_bit && master->set_pullup) { ++ printk(KERN_ERR "w1_add_master_device: set_pullup requires " ++ "write_byte or touch_bit, disabling\n"); ++ master->set_pullup = NULL; ++ } ++ ++ if (master->set_pullup && master->bitbang_pullup) { ++ printk(KERN_ERR "w1_add_master_device: set_pullup should not " ++ "be set when bitbang_pullup is used, disabling\n"); ++ master->set_pullup = NULL; ++ } ++ + /* Lock until the device is added (or not) to w1_masters. */ + mutex_lock(&w1_mlock); + /* Search for the first available id (starting at 1). */ +diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c +index 2820924..fd0550f 100644 +--- a/drivers/w1/w1_io.c ++++ b/drivers/w1/w1_io.c +@@ -134,10 +134,22 @@ static void w1_pre_write(struct w1_master *dev) + static void w1_post_write(struct w1_master *dev) + { + if (dev->pullup_duration) { +- if (dev->enable_pullup && dev->bus_master->set_pullup) +- dev->bus_master->set_pullup(dev->bus_master->data, 0); +- else ++ if (dev->enable_pullup) { ++ if (dev->bus_master->set_pullup) { ++ dev->bus_master->set_pullup(dev-> ++ bus_master->data, ++ 0); ++ } else if (dev->bus_master->bitbang_pullup) { ++ dev->bus_master-> ++ bitbang_pullup(dev->bus_master->data, 1); ++ msleep(dev->pullup_duration); ++ dev->bus_master-> ++ bitbang_pullup(dev->bus_master->data, 0); ++ } ++ } else { + msleep(dev->pullup_duration); ++ } ++ + dev->pullup_duration = 0; + } + } +diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h +index d58594a..feae942 100644 +--- a/include/linux/w1-gpio.h ++++ b/include/linux/w1-gpio.h +@@ -18,6 +18,7 @@ + struct w1_gpio_platform_data { + unsigned int pin; + unsigned int is_open_drain:1; ++ unsigned int parasitic_power:1; + void (*enable_external_pullup)(int enable); + unsigned int ext_pullup_enable_pin; + unsigned int pullup_duration; + +From 00d8013737c9e736f70e04e07b761517559e495e Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 18 Dec 2013 22:16:19 +0000 +Subject: [PATCH 34/77] config: Enable CONFIG_MEMCG, but leave it disabled (due + to memory cost). Enable with cgroup_enable=memory. + +--- + kernel/cgroup.c | 23 +++++++++++++++++++++++ + mm/memcontrol.c | 1 + + 2 files changed, 24 insertions(+) + +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index 469dd54..c9684da 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -5395,6 +5395,29 @@ static int __init cgroup_disable(char *str) + } + __setup("cgroup_disable=", cgroup_disable); + ++static int __init cgroup_enable(char *str) ++{ ++ struct cgroup_subsys *ss; ++ char *token; ++ int i; ++ ++ while ((token = strsep(&str, ",")) != NULL) { ++ if (!*token) ++ continue; ++ ++ for_each_subsys(ss, i) { ++ if (!strcmp(token, ss->name)) { ++ ss->disabled = 0; ++ printk(KERN_INFO "Enabling %s control group" ++ " subsystem\n", ss->name); ++ break; ++ } ++ } ++ } ++ return 1; ++} ++__setup("cgroup_enable=", cgroup_enable); ++ + static int __init cgroup_set_legacy_files_on_dfl(char *str) + { + printk("cgroup: using legacy files on the default hierarchy\n"); +diff --git a/mm/memcontrol.c b/mm/memcontrol.c +index a04225d..a2ef8af 100644 +--- a/mm/memcontrol.c ++++ b/mm/memcontrol.c +@@ -5388,6 +5388,7 @@ struct cgroup_subsys memory_cgrp_subsys = { + .dfl_cftypes = memory_files, + .legacy_cftypes = mem_cgroup_legacy_files, + .early_init = 0, ++ .disabled = 1, + }; + + /** + +From 5e192d7296061c5d70da39b3fbd1eeedef467923 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 14:33:38 +0100 +Subject: [PATCH 35/77] ASoC: Add support for BCM2708 + +This driver adds support for digital audio (I2S) +for the BCM2708 SoC that is used by the +Raspberry Pi. External audio codecs can be +connected to the Raspberry Pi via P5 header. + +It relies on cyclic DMA engine support for BCM2708. + +Signed-off-by: Florian Meier + +ASoC: BCM2708: Add 24 bit support + +This adds 24 bit support to the I2S driver of the BCM2708. +Besides enabling the 24 bit flags, it includes two bug fixes: + +MMAP is not supported. Claiming this leads to strange issues +when the format of driver and file do not match. + +The datasheet states that the width extension bit should be set +for widths greater than 24, but greater or equal would be correct. +This follows from the definition of the width field. + +Signed-off-by: Florian Meier + +bcm2708-i2s: Update bclk_ratio to more correct values + +Move GPIO setup to hw_params. + +This is used to stop the I2S driver from breaking +the GPIO setup for other uses of the PCM interface + +Configure GPIOs for I2S based on revision/card settings + +With RPi model B+, assignment of the I2S GPIO pins has changed. +This patch uses the board revision to auto-detect the GPIOs used +for I2S. It also allows sound card drivers to set the GPIOs that +should be used. This is especially important with the Compute +Module. + +bcm2708-i2s: Avoid leak from iomap when accessing gpio + +bcm2708: Eliminate i2s debugfs directory error + +Qualify the two regmap ranges uses by bcm2708-i2s ('-i2s' and '-clk') +to avoid the name clash when registering debugfs entries. +--- + sound/soc/bcm/Kconfig | 11 + + sound/soc/bcm/Makefile | 4 + + sound/soc/bcm/bcm2708-i2s.c | 1009 +++++++++++++++++++++++++++++++++++++++++++ + sound/soc/bcm/bcm2708-i2s.h | 35 ++ + 4 files changed, 1059 insertions(+) + create mode 100644 sound/soc/bcm/bcm2708-i2s.c + create mode 100644 sound/soc/bcm/bcm2708-i2s.h + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 6a834e1..8642296 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -7,3 +7,14 @@ config SND_BCM2835_SOC_I2S + Say Y or M if you want to add support for codecs attached to + the BCM2835 I2S interface. You will also need + to select the audio interfaces to support below. ++ ++config SND_BCM2708_SOC_I2S ++ tristate "SoC Audio support for the Broadcom BCM2708 I2S module" ++ depends on MACH_BCM2708 || MACH_BCM2709 ++ select REGMAP_MMIO ++ select SND_SOC_DMAENGINE_PCM ++ select SND_SOC_GENERIC_DMAENGINE_PCM ++ help ++ Say Y or M if you want to add support for codecs attached to ++ the BCM2708 I2S interface. You will also need ++ to select the audio interfaces to support below. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index bc816b7..f8bbe1f 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -3,3 +3,7 @@ snd-soc-bcm2835-i2s-objs := bcm2835-i2s.o + + obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o + ++# BCM2708 Platform Support ++snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o ++ ++obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +new file mode 100644 +index 0000000..a3b65dc +--- /dev/null ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -0,0 +1,1009 @@ ++/* ++ * ALSA SoC I2S Audio Layer for Broadcom BCM2708 SoC ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * Based on ++ * Raspberry Pi PCM I2S ALSA Driver ++ * Copyright (c) by Phil Poole 2013 ++ * ++ * ALSA SoC I2S (McBSP) Audio Layer for TI DAVINCI processor ++ * Vladimir Barinov, ++ * Copyright (C) 2007 MontaVista Software, Inc., ++ * ++ * OMAP ALSA SoC DAI driver using McBSP port ++ * Copyright (C) 2008 Nokia Corporation ++ * Contact: Jarkko Nikula ++ * Peter Ujfalusi ++ * ++ * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver ++ * Author: Timur Tabi ++ * Copyright 2007-2010 Freescale Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * 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. ++ */ ++ ++#include "bcm2708-i2s.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* Clock registers */ ++#define BCM2708_CLK_PCMCTL_REG 0x00 ++#define BCM2708_CLK_PCMDIV_REG 0x04 ++ ++/* Clock register settings */ ++#define BCM2708_CLK_PASSWD (0x5a000000) ++#define BCM2708_CLK_PASSWD_MASK (0xff000000) ++#define BCM2708_CLK_MASH(v) ((v) << 9) ++#define BCM2708_CLK_FLIP BIT(8) ++#define BCM2708_CLK_BUSY BIT(7) ++#define BCM2708_CLK_KILL BIT(5) ++#define BCM2708_CLK_ENAB BIT(4) ++#define BCM2708_CLK_SRC(v) (v) ++ ++#define BCM2708_CLK_SHIFT (12) ++#define BCM2708_CLK_DIVI(v) ((v) << BCM2708_CLK_SHIFT) ++#define BCM2708_CLK_DIVF(v) (v) ++#define BCM2708_CLK_DIVF_MASK (0xFFF) ++ ++enum { ++ BCM2708_CLK_MASH_0 = 0, ++ BCM2708_CLK_MASH_1, ++ BCM2708_CLK_MASH_2, ++ BCM2708_CLK_MASH_3, ++}; ++ ++enum { ++ BCM2708_CLK_SRC_GND = 0, ++ BCM2708_CLK_SRC_OSC, ++ BCM2708_CLK_SRC_DBG0, ++ BCM2708_CLK_SRC_DBG1, ++ BCM2708_CLK_SRC_PLLA, ++ BCM2708_CLK_SRC_PLLC, ++ BCM2708_CLK_SRC_PLLD, ++ BCM2708_CLK_SRC_HDMI, ++}; ++ ++/* Most clocks are not useable (freq = 0) */ ++static const unsigned int bcm2708_clk_freq[BCM2708_CLK_SRC_HDMI+1] = { ++ [BCM2708_CLK_SRC_GND] = 0, ++ [BCM2708_CLK_SRC_OSC] = 19200000, ++ [BCM2708_CLK_SRC_DBG0] = 0, ++ [BCM2708_CLK_SRC_DBG1] = 0, ++ [BCM2708_CLK_SRC_PLLA] = 0, ++ [BCM2708_CLK_SRC_PLLC] = 0, ++ [BCM2708_CLK_SRC_PLLD] = 500000000, ++ [BCM2708_CLK_SRC_HDMI] = 0, ++}; ++ ++/* I2S registers */ ++#define BCM2708_I2S_CS_A_REG 0x00 ++#define BCM2708_I2S_FIFO_A_REG 0x04 ++#define BCM2708_I2S_MODE_A_REG 0x08 ++#define BCM2708_I2S_RXC_A_REG 0x0c ++#define BCM2708_I2S_TXC_A_REG 0x10 ++#define BCM2708_I2S_DREQ_A_REG 0x14 ++#define BCM2708_I2S_INTEN_A_REG 0x18 ++#define BCM2708_I2S_INTSTC_A_REG 0x1c ++#define BCM2708_I2S_GRAY_REG 0x20 ++ ++/* I2S register settings */ ++#define BCM2708_I2S_STBY BIT(25) ++#define BCM2708_I2S_SYNC BIT(24) ++#define BCM2708_I2S_RXSEX BIT(23) ++#define BCM2708_I2S_RXF BIT(22) ++#define BCM2708_I2S_TXE BIT(21) ++#define BCM2708_I2S_RXD BIT(20) ++#define BCM2708_I2S_TXD BIT(19) ++#define BCM2708_I2S_RXR BIT(18) ++#define BCM2708_I2S_TXW BIT(17) ++#define BCM2708_I2S_CS_RXERR BIT(16) ++#define BCM2708_I2S_CS_TXERR BIT(15) ++#define BCM2708_I2S_RXSYNC BIT(14) ++#define BCM2708_I2S_TXSYNC BIT(13) ++#define BCM2708_I2S_DMAEN BIT(9) ++#define BCM2708_I2S_RXTHR(v) ((v) << 7) ++#define BCM2708_I2S_TXTHR(v) ((v) << 5) ++#define BCM2708_I2S_RXCLR BIT(4) ++#define BCM2708_I2S_TXCLR BIT(3) ++#define BCM2708_I2S_TXON BIT(2) ++#define BCM2708_I2S_RXON BIT(1) ++#define BCM2708_I2S_EN (1) ++ ++#define BCM2708_I2S_CLKDIS BIT(28) ++#define BCM2708_I2S_PDMN BIT(27) ++#define BCM2708_I2S_PDME BIT(26) ++#define BCM2708_I2S_FRXP BIT(25) ++#define BCM2708_I2S_FTXP BIT(24) ++#define BCM2708_I2S_CLKM BIT(23) ++#define BCM2708_I2S_CLKI BIT(22) ++#define BCM2708_I2S_FSM BIT(21) ++#define BCM2708_I2S_FSI BIT(20) ++#define BCM2708_I2S_FLEN(v) ((v) << 10) ++#define BCM2708_I2S_FSLEN(v) (v) ++ ++#define BCM2708_I2S_CHWEX BIT(15) ++#define BCM2708_I2S_CHEN BIT(14) ++#define BCM2708_I2S_CHPOS(v) ((v) << 4) ++#define BCM2708_I2S_CHWID(v) (v) ++#define BCM2708_I2S_CH1(v) ((v) << 16) ++#define BCM2708_I2S_CH2(v) (v) ++ ++#define BCM2708_I2S_TX_PANIC(v) ((v) << 24) ++#define BCM2708_I2S_RX_PANIC(v) ((v) << 16) ++#define BCM2708_I2S_TX(v) ((v) << 8) ++#define BCM2708_I2S_RX(v) (v) ++ ++#define BCM2708_I2S_INT_RXERR BIT(3) ++#define BCM2708_I2S_INT_TXERR BIT(2) ++#define BCM2708_I2S_INT_RXR BIT(1) ++#define BCM2708_I2S_INT_TXW BIT(0) ++ ++/* I2S DMA interface */ ++#define BCM2708_I2S_FIFO_PHYSICAL_ADDR 0x7E203004 ++#define BCM2708_DMA_DREQ_PCM_TX 2 ++#define BCM2708_DMA_DREQ_PCM_RX 3 ++ ++/* I2S pin configuration */ ++static int bcm2708_i2s_gpio=BCM2708_I2S_GPIO_AUTO; ++ ++/* General device struct */ ++struct bcm2708_i2s_dev { ++ struct device *dev; ++ struct snd_dmaengine_dai_dma_data dma_data[2]; ++ unsigned int fmt; ++ unsigned int bclk_ratio; ++ ++ struct regmap *i2s_regmap; ++ struct regmap *clk_regmap; ++}; ++ ++void bcm2708_i2s_set_gpio(int gpio) { ++ bcm2708_i2s_gpio=gpio; ++} ++EXPORT_SYMBOL(bcm2708_i2s_set_gpio); ++ ++ ++static void bcm2708_i2s_start_clock(struct bcm2708_i2s_dev *dev) ++{ ++ /* Start the clock if in master mode */ ++ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; ++ ++ switch (master) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ case SND_SOC_DAIFMT_CBS_CFM: ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, ++ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void bcm2708_i2s_stop_clock(struct bcm2708_i2s_dev *dev) ++{ ++ uint32_t clkreg; ++ int timeout = 1000; ++ ++ /* Stop clock */ ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, ++ BCM2708_CLK_PASSWD); ++ ++ /* Wait for the BUSY flag going down */ ++ while (--timeout) { ++ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); ++ if (!(clkreg & BCM2708_CLK_BUSY)) ++ break; ++ } ++ ++ if (!timeout) { ++ /* KILL the clock */ ++ dev_err(dev->dev, "I2S clock didn't stop. Kill the clock!\n"); ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD_MASK, ++ BCM2708_CLK_KILL | BCM2708_CLK_PASSWD); ++ } ++} ++ ++static void bcm2708_i2s_clear_fifos(struct bcm2708_i2s_dev *dev, ++ bool tx, bool rx) ++{ ++ int timeout = 1000; ++ uint32_t syncval; ++ uint32_t csreg; ++ uint32_t i2s_active_state; ++ uint32_t clkreg; ++ uint32_t clk_active_state; ++ uint32_t off; ++ uint32_t clr; ++ ++ off = tx ? BCM2708_I2S_TXON : 0; ++ off |= rx ? BCM2708_I2S_RXON : 0; ++ ++ clr = tx ? BCM2708_I2S_TXCLR : 0; ++ clr |= rx ? BCM2708_I2S_RXCLR : 0; ++ ++ /* Backup the current state */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); ++ i2s_active_state = csreg & (BCM2708_I2S_RXON | BCM2708_I2S_TXON); ++ ++ regmap_read(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, &clkreg); ++ clk_active_state = clkreg & BCM2708_CLK_ENAB; ++ ++ /* Start clock if not running */ ++ if (!clk_active_state) { ++ regmap_update_bits(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, ++ BCM2708_CLK_PASSWD_MASK | BCM2708_CLK_ENAB, ++ BCM2708_CLK_PASSWD | BCM2708_CLK_ENAB); ++ } ++ ++ /* Stop I2S module */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, off, 0); ++ ++ /* ++ * Clear the FIFOs ++ * Requires at least 2 PCM clock cycles to take effect ++ */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, clr, clr); ++ ++ /* Wait for 2 PCM clock cycles */ ++ ++ /* ++ * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back ++ * FIXME: This does not seem to work for slave mode! ++ */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &syncval); ++ syncval &= BCM2708_I2S_SYNC; ++ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_SYNC, ~syncval); ++ ++ /* Wait for the SYNC flag changing it's state */ ++ while (--timeout) { ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); ++ if ((csreg & BCM2708_I2S_SYNC) != syncval) ++ break; ++ } ++ ++ if (!timeout) ++ dev_err(dev->dev, "I2S SYNC error!\n"); ++ ++ /* Stop clock if it was not running before */ ++ if (!clk_active_state) ++ bcm2708_i2s_stop_clock(dev); ++ ++ /* Restore I2S state */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_RXON | BCM2708_I2S_TXON, i2s_active_state); ++} ++ ++static int bcm2708_i2s_set_dai_fmt(struct snd_soc_dai *dai, ++ unsigned int fmt) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ dev->fmt = fmt; ++ return 0; ++} ++ ++static int bcm2708_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, ++ unsigned int ratio) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ dev->bclk_ratio = ratio; ++ return 0; ++} ++ ++ ++static int bcm2708_i2s_set_function(unsigned offset, int function) ++{ ++ #define GPIOFSEL(x) (0x00+(x)*4) ++ void __iomem *gpio = __io_address(GPIO_BASE); ++ unsigned alt = function <= 3 ? function + 4: function == 4 ? 3 : 2; ++ unsigned gpiodir; ++ unsigned gpio_bank = offset / 10; ++ unsigned gpio_field_offset = (offset - 10 * gpio_bank) * 3; ++ ++ if (offset >= BCM2708_NR_GPIOS) ++ return -EINVAL; ++ ++ gpiodir = readl(gpio + GPIOFSEL(gpio_bank)); ++ gpiodir &= ~(7 << gpio_field_offset); ++ gpiodir |= alt << gpio_field_offset; ++ writel(gpiodir, gpio + GPIOFSEL(gpio_bank)); ++ return 0; ++} ++ ++static void bcm2708_i2s_setup_gpio(void) ++{ ++ /* ++ * This is the common way to handle the GPIO pins for ++ * the Raspberry Pi. ++ * TODO Better way would be to handle ++ * this in the device tree! ++ */ ++ int pin,pinconfig,startpin,alt; ++ ++ /* SPI is on different GPIOs on different boards */ ++ /* for Raspberry Pi B+, this is pin GPIO18-21, for original on 28-31 */ ++ if (bcm2708_i2s_gpio==BCM2708_I2S_GPIO_AUTO) { ++ if ((system_rev & 0xffffff) >= 0x10) { ++ /* Model B+ */ ++ pinconfig=BCM2708_I2S_GPIO_PIN18; ++ } else { ++ /* original */ ++ pinconfig=BCM2708_I2S_GPIO_PIN28; ++ } ++ } else { ++ pinconfig=bcm2708_i2s_gpio; ++ } ++ ++ if (pinconfig==BCM2708_I2S_GPIO_PIN18) { ++ startpin=18; ++ alt=BCM2708_I2S_GPIO_PIN18_ALT; ++ } else if (pinconfig==BCM2708_I2S_GPIO_PIN28) { ++ startpin=28; ++ alt=BCM2708_I2S_GPIO_PIN28_ALT; ++ } else { ++ printk(KERN_INFO "Can't configure I2S GPIOs, unknown pin mode for I2S: %i\n",pinconfig); ++ return; ++ } ++ ++ /* configure I2S pins to correct ALT mode */ ++ for (pin = startpin; pin <= startpin+3; pin++) { ++ bcm2708_i2s_set_function(pin, alt); ++ } ++} ++ ++static int bcm2708_i2s_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ unsigned int sampling_rate = params_rate(params); ++ unsigned int data_length, data_delay, bclk_ratio; ++ unsigned int ch1pos, ch2pos, mode, format; ++ unsigned int mash = BCM2708_CLK_MASH_1; ++ unsigned int divi, divf, target_frequency; ++ int clk_src = -1; ++ unsigned int master = dev->fmt & SND_SOC_DAIFMT_MASTER_MASK; ++ bool bit_master = (master == SND_SOC_DAIFMT_CBS_CFS ++ || master == SND_SOC_DAIFMT_CBS_CFM); ++ ++ bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS ++ || master == SND_SOC_DAIFMT_CBM_CFS); ++ uint32_t csreg; ++ ++ /* ++ * If a stream is already enabled, ++ * the registers are already set properly. ++ */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &csreg); ++ ++ if (csreg & (BCM2708_I2S_TXON | BCM2708_I2S_RXON)) ++ return 0; ++ ++ ++ bcm2708_i2s_setup_gpio(); ++ ++ /* ++ * Adjust the data length according to the format. ++ * We prefill the half frame length with an integer ++ * divider of 2400 as explained at the clock settings. ++ * Maybe it is overwritten there, if the Integer mode ++ * does not apply. ++ */ ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ data_length = 16; ++ bclk_ratio = 50; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ data_length = 24; ++ bclk_ratio = 50; ++ break; ++ case SNDRV_PCM_FORMAT_S32_LE: ++ data_length = 32; ++ bclk_ratio = 100; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* If bclk_ratio already set, use that one. */ ++ if (dev->bclk_ratio) ++ bclk_ratio = dev->bclk_ratio; ++ ++ /* ++ * Clock Settings ++ * ++ * The target frequency of the bit clock is ++ * sampling rate * frame length ++ * ++ * Integer mode: ++ * Sampling rates that are multiples of 8000 kHz ++ * can be driven by the oscillator of 19.2 MHz ++ * with an integer divider as long as the frame length ++ * is an integer divider of 19200000/8000=2400 as set up above. ++ * This is no longer possible if the sampling rate ++ * is too high (e.g. 192 kHz), because the oscillator is too slow. ++ * ++ * MASH mode: ++ * For all other sampling rates, it is not possible to ++ * have an integer divider. Approximate the clock ++ * with the MASH module that induces a slight frequency ++ * variance. To minimize that it is best to have the fastest ++ * clock here. That is PLLD with 500 MHz. ++ */ ++ target_frequency = sampling_rate * bclk_ratio; ++ clk_src = BCM2708_CLK_SRC_OSC; ++ mash = BCM2708_CLK_MASH_0; ++ ++ if (bcm2708_clk_freq[clk_src] % target_frequency == 0 ++ && bit_master && frame_master) { ++ divi = bcm2708_clk_freq[clk_src] / target_frequency; ++ divf = 0; ++ } else { ++ uint64_t dividend; ++ ++ if (!dev->bclk_ratio) { ++ /* ++ * Overwrite bclk_ratio, because the ++ * above trick is not needed or can ++ * not be used. ++ */ ++ bclk_ratio = 2 * data_length; ++ } ++ ++ target_frequency = sampling_rate * bclk_ratio; ++ ++ clk_src = BCM2708_CLK_SRC_PLLD; ++ mash = BCM2708_CLK_MASH_1; ++ ++ dividend = bcm2708_clk_freq[clk_src]; ++ dividend <<= BCM2708_CLK_SHIFT; ++ do_div(dividend, target_frequency); ++ divi = dividend >> BCM2708_CLK_SHIFT; ++ divf = dividend & BCM2708_CLK_DIVF_MASK; ++ } ++ ++ /* Clock should only be set up here if CPU is clock master */ ++ if (((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFS) || ++ ((dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBS_CFM)) { ++ /* Set clock divider */ ++ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMDIV_REG, BCM2708_CLK_PASSWD ++ | BCM2708_CLK_DIVI(divi) ++ | BCM2708_CLK_DIVF(divf)); ++ ++ /* Setup clock, but don't start it yet */ ++ regmap_write(dev->clk_regmap, BCM2708_CLK_PCMCTL_REG, BCM2708_CLK_PASSWD ++ | BCM2708_CLK_MASH(mash) ++ | BCM2708_CLK_SRC(clk_src)); ++ } ++ ++ /* Setup the frame format */ ++ format = BCM2708_I2S_CHEN; ++ ++ if (data_length >= 24) ++ format |= BCM2708_I2S_CHWEX; ++ ++ format |= BCM2708_I2S_CHWID((data_length-8)&0xf); ++ ++ switch (dev->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { ++ case SND_SOC_DAIFMT_I2S: ++ data_delay = 1; ++ break; ++ default: ++ /* ++ * TODO ++ * Others are possible but are not implemented at the moment. ++ */ ++ dev_err(dev->dev, "%s:bad format\n", __func__); ++ return -EINVAL; ++ } ++ ++ ch1pos = data_delay; ++ ch2pos = bclk_ratio / 2 + data_delay; ++ ++ switch (params_channels(params)) { ++ case 2: ++ format = BCM2708_I2S_CH1(format) | BCM2708_I2S_CH2(format); ++ format |= BCM2708_I2S_CH1(BCM2708_I2S_CHPOS(ch1pos)); ++ format |= BCM2708_I2S_CH2(BCM2708_I2S_CHPOS(ch2pos)); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ /* ++ * Set format for both streams. ++ * We cannot set another frame length ++ * (and therefore word length) anyway, ++ * so the format will be the same. ++ */ ++ regmap_write(dev->i2s_regmap, BCM2708_I2S_RXC_A_REG, format); ++ regmap_write(dev->i2s_regmap, BCM2708_I2S_TXC_A_REG, format); ++ ++ /* Setup the I2S mode */ ++ mode = 0; ++ ++ if (data_length <= 16) { ++ /* ++ * Use frame packed mode (2 channels per 32 bit word) ++ * We cannot set another frame length in the second stream ++ * (and therefore word length) anyway, ++ * so the format will be the same. ++ */ ++ mode |= BCM2708_I2S_FTXP | BCM2708_I2S_FRXP; ++ } ++ ++ mode |= BCM2708_I2S_FLEN(bclk_ratio - 1); ++ mode |= BCM2708_I2S_FSLEN(bclk_ratio / 2); ++ ++ /* Master or slave? */ ++ switch (dev->fmt & SND_SOC_DAIFMT_MASTER_MASK) { ++ case SND_SOC_DAIFMT_CBS_CFS: ++ /* CPU is master */ ++ break; ++ case SND_SOC_DAIFMT_CBM_CFS: ++ /* ++ * CODEC is bit clock master ++ * CPU is frame master ++ */ ++ mode |= BCM2708_I2S_CLKM; ++ break; ++ case SND_SOC_DAIFMT_CBS_CFM: ++ /* ++ * CODEC is frame master ++ * CPU is bit clock master ++ */ ++ mode |= BCM2708_I2S_FSM; ++ break; ++ case SND_SOC_DAIFMT_CBM_CFM: ++ /* CODEC is master */ ++ mode |= BCM2708_I2S_CLKM; ++ mode |= BCM2708_I2S_FSM; ++ break; ++ default: ++ dev_err(dev->dev, "%s:bad master\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* ++ * Invert clocks? ++ * ++ * The BCM approach seems to be inverted to the classical I2S approach. ++ */ ++ switch (dev->fmt & SND_SOC_DAIFMT_INV_MASK) { ++ case SND_SOC_DAIFMT_NB_NF: ++ /* None. Therefore, both for BCM */ ++ mode |= BCM2708_I2S_CLKI; ++ mode |= BCM2708_I2S_FSI; ++ break; ++ case SND_SOC_DAIFMT_IB_IF: ++ /* Both. Therefore, none for BCM */ ++ break; ++ case SND_SOC_DAIFMT_NB_IF: ++ /* ++ * Invert only frame sync. Therefore, ++ * invert only bit clock for BCM ++ */ ++ mode |= BCM2708_I2S_CLKI; ++ break; ++ case SND_SOC_DAIFMT_IB_NF: ++ /* ++ * Invert only bit clock. Therefore, ++ * invert only frame sync for BCM ++ */ ++ mode |= BCM2708_I2S_FSI; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ regmap_write(dev->i2s_regmap, BCM2708_I2S_MODE_A_REG, mode); ++ ++ /* Setup the DMA parameters */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_RXTHR(1) ++ | BCM2708_I2S_TXTHR(1) ++ | BCM2708_I2S_DMAEN, 0xffffffff); ++ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_DREQ_A_REG, ++ BCM2708_I2S_TX_PANIC(0x10) ++ | BCM2708_I2S_RX_PANIC(0x30) ++ | BCM2708_I2S_TX(0x30) ++ | BCM2708_I2S_RX(0x20), 0xffffffff); ++ ++ /* Clear FIFOs */ ++ bcm2708_i2s_clear_fifos(dev, true, true); ++ ++ return 0; ++} ++ ++static int bcm2708_i2s_prepare(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ uint32_t cs_reg; ++ ++ bcm2708_i2s_start_clock(dev); ++ ++ /* ++ * Clear both FIFOs if the one that should be started ++ * is not empty at the moment. This should only happen ++ * after overrun. Otherwise, hw_params would have cleared ++ * the FIFO. ++ */ ++ regmap_read(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, &cs_reg); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ++ && !(cs_reg & BCM2708_I2S_TXE)) ++ bcm2708_i2s_clear_fifos(dev, true, false); ++ else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE ++ && (cs_reg & BCM2708_I2S_RXD)) ++ bcm2708_i2s_clear_fifos(dev, false, true); ++ ++ return 0; ++} ++ ++static void bcm2708_i2s_stop(struct bcm2708_i2s_dev *dev, ++ struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ uint32_t mask; ++ ++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ++ mask = BCM2708_I2S_RXON; ++ else ++ mask = BCM2708_I2S_TXON; ++ ++ regmap_update_bits(dev->i2s_regmap, ++ BCM2708_I2S_CS_A_REG, mask, 0); ++ ++ /* Stop also the clock when not SND_SOC_DAIFMT_CONT */ ++ if (!dai->active && !(dev->fmt & SND_SOC_DAIFMT_CONT)) ++ bcm2708_i2s_stop_clock(dev); ++} ++ ++static int bcm2708_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ uint32_t mask; ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ case SNDRV_PCM_TRIGGER_RESUME: ++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ bcm2708_i2s_start_clock(dev); ++ ++ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ++ mask = BCM2708_I2S_RXON; ++ else ++ mask = BCM2708_I2S_TXON; ++ ++ regmap_update_bits(dev->i2s_regmap, ++ BCM2708_I2S_CS_A_REG, mask, mask); ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ case SNDRV_PCM_TRIGGER_SUSPEND: ++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ bcm2708_i2s_stop(dev, substream, dai); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static int bcm2708_i2s_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ if (dai->active) ++ return 0; ++ ++ /* Should this still be running stop it */ ++ bcm2708_i2s_stop_clock(dev); ++ ++ /* Enable PCM block */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_EN, BCM2708_I2S_EN); ++ ++ /* ++ * Disable STBY. ++ * Requires at least 4 PCM clock cycles to take effect. ++ */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_STBY, BCM2708_I2S_STBY); ++ ++ return 0; ++} ++ ++static void bcm2708_i2s_shutdown(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ bcm2708_i2s_stop(dev, substream, dai); ++ ++ /* If both streams are stopped, disable module and clock */ ++ if (dai->active) ++ return; ++ ++ /* Disable the module */ ++ regmap_update_bits(dev->i2s_regmap, BCM2708_I2S_CS_A_REG, ++ BCM2708_I2S_EN, 0); ++ ++ /* ++ * Stopping clock is necessary, because stop does ++ * not stop the clock when SND_SOC_DAIFMT_CONT ++ */ ++ bcm2708_i2s_stop_clock(dev); ++} ++ ++static const struct snd_soc_dai_ops bcm2708_i2s_dai_ops = { ++ .startup = bcm2708_i2s_startup, ++ .shutdown = bcm2708_i2s_shutdown, ++ .prepare = bcm2708_i2s_prepare, ++ .trigger = bcm2708_i2s_trigger, ++ .hw_params = bcm2708_i2s_hw_params, ++ .set_fmt = bcm2708_i2s_set_dai_fmt, ++ .set_bclk_ratio = bcm2708_i2s_set_dai_bclk_ratio ++}; ++ ++static int bcm2708_i2s_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct bcm2708_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; ++ dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; ++ ++ return 0; ++} ++ ++static struct snd_soc_dai_driver bcm2708_i2s_dai = { ++ .name = "bcm2708-i2s", ++ .probe = bcm2708_i2s_dai_probe, ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE ++ | SNDRV_PCM_FMTBIT_S32_LE ++ }, ++ .capture = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE ++ | SNDRV_PCM_FMTBIT_S24_LE ++ | SNDRV_PCM_FMTBIT_S32_LE ++ }, ++ .ops = &bcm2708_i2s_dai_ops, ++ .symmetric_rates = 1 ++}; ++ ++static bool bcm2708_i2s_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case BCM2708_I2S_CS_A_REG: ++ case BCM2708_I2S_FIFO_A_REG: ++ case BCM2708_I2S_INTSTC_A_REG: ++ case BCM2708_I2S_GRAY_REG: ++ return true; ++ default: ++ return false; ++ }; ++} ++ ++static bool bcm2708_i2s_precious_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case BCM2708_I2S_FIFO_A_REG: ++ return true; ++ default: ++ return false; ++ }; ++} ++ ++static bool bcm2708_clk_volatile_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case BCM2708_CLK_PCMCTL_REG: ++ return true; ++ default: ++ return false; ++ }; ++} ++ ++static const struct regmap_config bcm2708_regmap_config[] = { ++ { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .max_register = BCM2708_I2S_GRAY_REG, ++ .precious_reg = bcm2708_i2s_precious_reg, ++ .volatile_reg = bcm2708_i2s_volatile_reg, ++ .cache_type = REGCACHE_RBTREE, ++ .name = "i2s", ++ }, ++ { ++ .reg_bits = 32, ++ .reg_stride = 4, ++ .val_bits = 32, ++ .max_register = BCM2708_CLK_PCMDIV_REG, ++ .volatile_reg = bcm2708_clk_volatile_reg, ++ .cache_type = REGCACHE_RBTREE, ++ .name = "clk", ++ }, ++}; ++ ++static const struct snd_soc_component_driver bcm2708_i2s_component = { ++ .name = "bcm2708-i2s-comp", ++}; ++ ++static const struct snd_pcm_hardware bcm2708_pcm_hardware = { ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_JOINT_DUPLEX, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE, ++ .period_bytes_min = 32, ++ .period_bytes_max = 64 * PAGE_SIZE, ++ .periods_min = 2, ++ .periods_max = 255, ++ .buffer_bytes_max = 128 * PAGE_SIZE, ++}; ++ ++static const struct snd_dmaengine_pcm_config bcm2708_dmaengine_pcm_config = { ++ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, ++ .pcm_hardware = &bcm2708_pcm_hardware, ++ .prealloc_buffer_size = 256 * PAGE_SIZE, ++}; ++ ++ ++static int bcm2708_i2s_probe(struct platform_device *pdev) ++{ ++ struct bcm2708_i2s_dev *dev; ++ int i; ++ int ret; ++ struct regmap *regmap[2]; ++ struct resource *mem[2]; ++ ++ /* Request both ioareas */ ++ for (i = 0; i <= 1; i++) { ++ void __iomem *base; ++ ++ mem[i] = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ base = devm_ioremap_resource(&pdev->dev, mem[i]); ++ if (IS_ERR(base)) ++ return PTR_ERR(base); ++ ++ regmap[i] = devm_regmap_init_mmio(&pdev->dev, base, ++ &bcm2708_regmap_config[i]); ++ if (IS_ERR(regmap[i])) { ++ dev_err(&pdev->dev, "I2S probe: regmap init failed\n"); ++ return PTR_ERR(regmap[i]); ++ } ++ } ++ ++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), ++ GFP_KERNEL); ++ if (IS_ERR(dev)) ++ return PTR_ERR(dev); ++ ++ dev->i2s_regmap = regmap[0]; ++ dev->clk_regmap = regmap[1]; ++ ++ /* Set the DMA address */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = ++ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; ++ ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = ++ (dma_addr_t)BCM2708_I2S_FIFO_PHYSICAL_ADDR; ++ ++ /* Set the DREQ */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].slave_id = ++ BCM2708_DMA_DREQ_PCM_TX; ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].slave_id = ++ BCM2708_DMA_DREQ_PCM_RX; ++ ++ /* Set the bus width */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr_width = ++ DMA_SLAVE_BUSWIDTH_4_BYTES; ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr_width = ++ DMA_SLAVE_BUSWIDTH_4_BYTES; ++ ++ /* Set burst */ ++ dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].maxburst = 2; ++ dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].maxburst = 2; ++ ++ /* BCLK ratio - use default */ ++ dev->bclk_ratio = 0; ++ ++ /* Store the pdev */ ++ dev->dev = &pdev->dev; ++ dev_set_drvdata(&pdev->dev, dev); ++ ++ ret = snd_soc_register_component(&pdev->dev, ++ &bcm2708_i2s_component, &bcm2708_i2s_dai, 1); ++ ++ if (ret) { ++ dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ++ ret = -ENOMEM; ++ return ret; ++ } ++ ++ ret = snd_dmaengine_pcm_register(&pdev->dev, ++ &bcm2708_dmaengine_pcm_config, ++ SND_DMAENGINE_PCM_FLAG_COMPAT); ++ if (ret) { ++ dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); ++ snd_soc_unregister_component(&pdev->dev); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bcm2708_i2s_remove(struct platform_device *pdev) ++{ ++ snd_dmaengine_pcm_unregister(&pdev->dev); ++ snd_soc_unregister_component(&pdev->dev); ++ return 0; ++} ++ ++static const struct of_device_id bcm2708_i2s_of_match[] = { ++ { .compatible = "brcm,bcm2708-i2s", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, bcm2708_i2s_of_match); ++ ++static struct platform_driver bcm2708_i2s_driver = { ++ .probe = bcm2708_i2s_probe, ++ .remove = bcm2708_i2s_remove, ++ .driver = { ++ .name = "bcm2708-i2s", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm2708_i2s_of_match, ++ }, ++}; ++ ++module_platform_driver(bcm2708_i2s_driver); ++ ++MODULE_ALIAS("platform:bcm2708-i2s"); ++MODULE_DESCRIPTION("BCM2708 I2S interface"); ++MODULE_AUTHOR("Florian Meier "); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/bcm/bcm2708-i2s.h b/sound/soc/bcm/bcm2708-i2s.h +new file mode 100644 +index 0000000..6fdcbc1 +--- /dev/null ++++ b/sound/soc/bcm/bcm2708-i2s.h +@@ -0,0 +1,35 @@ ++/* ++ * I2S configuration for sound cards. ++ * ++ * Copyright (c) 2014 Daniel Matuschek ++ * ++ * 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 BCM2708_I2S_H ++#define BCM2708_I2S_H ++ ++/* I2S pin assignment */ ++#define BCM2708_I2S_GPIO_AUTO 0 ++#define BCM2708_I2S_GPIO_PIN18 1 ++#define BCM2708_I2S_GPIO_PIN28 2 ++ ++/* Alt mode to enable I2S */ ++#define BCM2708_I2S_GPIO_PIN18_ALT 0 ++#define BCM2708_I2S_GPIO_PIN28_ALT 2 ++ ++extern void bcm2708_i2s_set_gpio(int gpio); ++ ++#endif + +From 355253cae3f2e9200926bfeb8d21646600d0768e Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 14:59:51 +0100 +Subject: [PATCH 36/77] ASoC: Add support for PCM5102A codec + +Some definitions to support the PCM5102A codec +by Texas Instruments. + +Signed-off-by: Florian Meier +--- + sound/soc/codecs/Kconfig | 4 +++ + sound/soc/codecs/Makefile | 2 ++ + sound/soc/codecs/pcm5102a.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 69 insertions(+) + create mode 100644 sound/soc/codecs/pcm5102a.c + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 061c465..a3d70f9 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -83,6 +83,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_PCM512x_I2C if I2C + select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RT286 if I2C ++ select SND_SOC_PCM5102A if I2C + select SND_SOC_RT5631 if I2C + select SND_SOC_RT5640 if I2C + select SND_SOC_RT5645 if I2C +@@ -511,6 +512,9 @@ config SND_SOC_RT286 + tristate + depends on I2C + ++config SND_SOC_PCM5102A ++ tristate ++ + config SND_SOC_RT5631 + tristate "Realtek ALC5631/RT5631 CODEC" + depends on I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index abe2d7e..a0fda52 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o + snd-soc-pcm512x-spi-objs := pcm512x-spi.o + snd-soc-rl6231-objs := rl6231.o + snd-soc-rt286-objs := rt286.o ++snd-soc-pcm5102a-objs := pcm5102a.o + snd-soc-rt5631-objs := rt5631.o + snd-soc-rt5640-objs := rt5640.o + snd-soc-rt5645-objs := rt5645.o +@@ -263,6 +264,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o + obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o + obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o ++obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o + obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o + obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o + obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o +diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c +new file mode 100644 +index 0000000..126f1e9 +--- /dev/null ++++ b/sound/soc/codecs/pcm5102a.c +@@ -0,0 +1,63 @@ ++/* ++ * Driver for the PCM5102A codec ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++ ++#include ++#include ++#include ++ ++#include ++ ++static struct snd_soc_dai_driver pcm5102a_dai = { ++ .name = "pcm5102a-hifi", ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE | ++ SNDRV_PCM_FMTBIT_S32_LE ++ }, ++}; ++ ++static struct snd_soc_codec_driver soc_codec_dev_pcm5102a; ++ ++static int pcm5102a_probe(struct platform_device *pdev) ++{ ++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm5102a, ++ &pcm5102a_dai, 1); ++} ++ ++static int pcm5102a_remove(struct platform_device *pdev) ++{ ++ snd_soc_unregister_codec(&pdev->dev); ++ return 0; ++} ++ ++static struct platform_driver pcm5102a_codec_driver = { ++ .probe = pcm5102a_probe, ++ .remove = pcm5102a_remove, ++ .driver = { ++ .name = "pcm5102a-codec", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(pcm5102a_codec_driver); ++ ++MODULE_DESCRIPTION("ASoC PCM5102A codec driver"); ++MODULE_AUTHOR("Florian Meier "); ++MODULE_LICENSE("GPL v2"); + +From 49e137bd21361ad8f4439f35956ceab424013411 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 19:04:54 +0100 +Subject: [PATCH 37/77] BCM2708: Add I2S support to board file + +Adds the required initializations for I2S +to the board file of mach-bcm2708. + +Signed-off-by: Florian Meier + +bcm2708-i2s: Enable MMAP support via a DT property and overlay + +The i2s driver used to claim to support MMAP, but that feature was disabled +when some problems were found. Add the ability to enable this feature +through Device Tree, using the i2s-mmap overlay. + +See: #1004 +--- + arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ + sound/soc/bcm/bcm2708-i2s.c | 7 ++++++- + 2 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index c7b4b61..dc57983 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -616,6 +616,28 @@ static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++static struct resource bcm2708_i2s_resources[] = { ++ { ++ .start = I2S_BASE, ++ .end = I2S_BASE + 0x20, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = PCM_CLOCK_BASE, ++ .end = PCM_CLOCK_BASE + 0x02, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device bcm2708_i2s_device = { ++ .name = "bcm2708-i2s", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), ++ .resource = bcm2708_i2s_resources, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -780,6 +802,10 @@ void __init bcm2708_init(void) + + bcm_register_device_dt(&bcm2835_thermal_device); + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++ bcm_register_device_dt(&bcm2708_i2s_device); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/bcm2708-i2s.c b/sound/soc/bcm/bcm2708-i2s.c +index a3b65dc..a515992 100644 +--- a/sound/soc/bcm/bcm2708-i2s.c ++++ b/sound/soc/bcm/bcm2708-i2s.c +@@ -874,7 +874,7 @@ static const struct snd_soc_component_driver bcm2708_i2s_component = { + .name = "bcm2708-i2s-comp", + }; + +-static const struct snd_pcm_hardware bcm2708_pcm_hardware = { ++static struct snd_pcm_hardware bcm2708_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_JOINT_DUPLEX, + .formats = SNDRV_PCM_FMTBIT_S16_LE | +@@ -902,6 +902,11 @@ static int bcm2708_i2s_probe(struct platform_device *pdev) + struct regmap *regmap[2]; + struct resource *mem[2]; + ++ if (of_property_read_bool(pdev->dev.of_node, "brcm,enable-mmap")) ++ bcm2708_pcm_hardware.info |= ++ SNDRV_PCM_INFO_MMAP | ++ SNDRV_PCM_INFO_MMAP_VALID; ++ + /* Request both ioareas */ + for (i = 0; i <= 1; i++) { + void __iomem *base; + +From 5786483930fcb7863012d8bb81d1f73a67b258da Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 19:19:08 +0100 +Subject: [PATCH 38/77] ASoC: Add support for HifiBerry DAC + +This adds a machine driver for the HifiBerry DAC. +It is a sound card that can +be stacked onto the Raspberry Pi. + +Signed-off-by: Florian Meier +--- + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 5 +++ + sound/soc/bcm/hifiberry_dac.c | 100 ++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 112 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_dac.c + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 8642296..a4a3e86 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -18,3 +18,10 @@ config SND_BCM2708_SOC_I2S + Say Y or M if you want to add support for codecs attached to + the BCM2708 I2S interface. You will also need + to select the audio interfaces to support below. ++ ++config SND_BCM2708_SOC_HIFIBERRY_DAC ++ tristate "Support for HifiBerry DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM5102A ++ help ++ Say Y or M if you want to add support for HifiBerry DAC. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index f8bbe1f..be90a49cb 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -7,3 +7,8 @@ obj-$(CONFIG_SND_BCM2835_SOC_I2S) += snd-soc-bcm2835-i2s.o + snd-soc-bcm2708-i2s-objs := bcm2708-i2s.o + + obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o ++ ++# BCM2708 Machine Support ++snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++ ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o +diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c +new file mode 100644 +index 0000000..4b70b45 +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_dac.c +@@ -0,0 +1,100 @@ ++/* ++ * ASoC Driver for HifiBerry DAC ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_hifiberry_dac_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dac_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ unsigned int sample_bits = ++ snd_pcm_format_physical_width(params_format(params)); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_dac_ops = { ++ .hw_params = snd_rpi_hifiberry_dac_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_dac_dai[] = { ++{ ++ .name = "HifiBerry DAC", ++ .stream_name = "HifiBerry DAC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm5102a-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm5102a-codec", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_dac_ops, ++ .init = snd_rpi_hifiberry_dac_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_dac = { ++ .name = "snd_rpi_hifiberry_dac", ++ .dai_link = snd_rpi_hifiberry_dac_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dac_dai), ++}; ++ ++static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_dac.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); ++} ++ ++static struct platform_driver snd_rpi_hifiberry_dac_driver = { ++ .driver = { ++ .name = "snd-hifiberry-dac", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_hifiberry_dac_probe, ++ .remove = snd_rpi_hifiberry_dac_remove, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_dac_driver); ++ ++MODULE_AUTHOR("Florian Meier "); ++MODULE_DESCRIPTION("ASoC Driver for HifiBerry DAC"); ++MODULE_LICENSE("GPL v2"); + +From 47d7a2a48fd4b2da2f9400de4307febe755b2ef2 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 22 Nov 2013 19:21:34 +0100 +Subject: [PATCH 39/77] BCM2708: Add HifiBerry DAC to board file + +This adds the initalization of the HifiBerry DAC +to the mach-bcm2708 board file. + +Signed-off-by: Florian Meier +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index dc57983..ef7c48d 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -638,6 +638,20 @@ static struct platform_device bcm2708_i2s_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++static struct platform_device snd_hifiberry_dac_device = { ++ .name = "snd-hifiberry-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm5102a_codec_device = { ++ .name = "pcm5102a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -806,6 +820,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&bcm2708_i2s_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + +From 403dc5c76505dd5813174532b2f032e52cbe06b8 Mon Sep 17 00:00:00 2001 +From: Florian Meier +Date: Fri, 6 Dec 2013 20:50:28 +0100 +Subject: [PATCH 40/77] ASoC: BCM2708: Add support for RPi-DAC + +This adds a machine driver for the RPi-DAC. + +Signed-off-by: Florian Meier +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/rpi-dac.c | 97 +++++++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/Kconfig | 4 ++ + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/pcm1794a.c | 62 ++++++++++++++++++++++++++ + 7 files changed, 193 insertions(+) + create mode 100644 sound/soc/bcm/rpi-dac.c + create mode 100644 sound/soc/codecs/pcm1794a.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index ef7c48d..be27073 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++static struct platform_device snd_rpi_dac_device = { ++ .name = "snd-rpi-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm1794a_codec_device = { ++ .name = "pcm1794a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -825,6 +839,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_dac_device); ++ bcm_register_device_dt(&snd_pcm1794a_codec_device); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index a4a3e86..cb7c0c2 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -25,3 +25,10 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC + select SND_SOC_PCM5102A + help + Say Y or M if you want to add support for HifiBerry DAC. ++ ++config SND_BCM2708_SOC_RPI_DAC ++ tristate "Support for RPi-DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM1794A ++ help ++ Say Y or M if you want to add support for RPi-DAC. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index be90a49cb..ccc9809 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -10,5 +10,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + + # BCM2708 Machine Support + snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++snd-soc-rpi-dac-objs := rpi-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o +diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c +new file mode 100644 +index 0000000..6d6e0ba +--- /dev/null ++++ b/sound/soc/bcm/rpi-dac.c +@@ -0,0 +1,97 @@ ++/* ++ * ASoC Driver for RPi-DAC. ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_rpi_dac_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ return 0; ++} ++ ++static int snd_rpi_rpi_dac_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 32*2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_rpi_dac_ops = { ++ .hw_params = snd_rpi_rpi_dac_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_rpi_dac_dai[] = { ++{ ++ .name = "RPi-DAC", ++ .stream_name = "RPi-DAC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm1794a-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm1794a-codec", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_rpi_dac_ops, ++ .init = snd_rpi_rpi_dac_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_rpi_dac = { ++ .name = "snd_rpi_rpi_dac", ++ .dai_link = snd_rpi_rpi_dac_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_rpi_dac_dai), ++}; ++ ++static int snd_rpi_rpi_dac_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_rpi_dac.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_rpi_dac); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_rpi_dac_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_rpi_dac); ++} ++ ++static struct platform_driver snd_rpi_rpi_dac_driver = { ++ .driver = { ++ .name = "snd-rpi-dac", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_rpi_dac_probe, ++ .remove = snd_rpi_rpi_dac_remove, ++}; ++ ++module_platform_driver(snd_rpi_rpi_dac_driver); ++ ++MODULE_AUTHOR("Florian Meier "); ++MODULE_DESCRIPTION("ASoC Driver for RPi-DAC"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index a3d70f9..dc3df1a 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -84,6 +84,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_PCM512x_SPI if SPI_MASTER + select SND_SOC_RT286 if I2C + select SND_SOC_PCM5102A if I2C ++ select SND_SOC_PCM1794A if I2C + select SND_SOC_RT5631 if I2C + select SND_SOC_RT5640 if I2C + select SND_SOC_RT5645 if I2C +@@ -512,6 +513,9 @@ config SND_SOC_RT286 + tristate + depends on I2C + ++config SND_SOC_PCM1794A ++ tristate ++ + config SND_SOC_PCM5102A + tristate + +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index a0fda52..c1f6ba6 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -78,6 +78,7 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o + snd-soc-pcm512x-spi-objs := pcm512x-spi.o + snd-soc-rl6231-objs := rl6231.o + snd-soc-rt286-objs := rt286.o ++snd-soc-pcm1794a-objs := pcm1794a.o + snd-soc-pcm5102a-objs := pcm5102a.o + snd-soc-rt5631-objs := rt5631.o + snd-soc-rt5640-objs := rt5640.o +@@ -264,6 +265,7 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o + obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o + obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o + obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o ++obj-$(CONFIG_SND_SOC_PCM1794A) += snd-soc-pcm1794a.o + obj-$(CONFIG_SND_SOC_PCM5102A) += snd-soc-pcm5102a.o + obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o + obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o +diff --git a/sound/soc/codecs/pcm1794a.c b/sound/soc/codecs/pcm1794a.c +new file mode 100644 +index 0000000..b4eaa44 +--- /dev/null ++++ b/sound/soc/codecs/pcm1794a.c +@@ -0,0 +1,62 @@ ++/* ++ * Driver for the PCM1794A codec ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++ ++#include ++#include ++#include ++ ++#include ++ ++static struct snd_soc_dai_driver pcm1794a_dai = { ++ .name = "pcm1794a-hifi", ++ .playback = { ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_192000, ++ .formats = SNDRV_PCM_FMTBIT_S16_LE | ++ SNDRV_PCM_FMTBIT_S24_LE ++ }, ++}; ++ ++static struct snd_soc_codec_driver soc_codec_dev_pcm1794a; ++ ++static int pcm1794a_probe(struct platform_device *pdev) ++{ ++ return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pcm1794a, ++ &pcm1794a_dai, 1); ++} ++ ++static int pcm1794a_remove(struct platform_device *pdev) ++{ ++ snd_soc_unregister_codec(&pdev->dev); ++ return 0; ++} ++ ++static struct platform_driver pcm1794a_codec_driver = { ++ .probe = pcm1794a_probe, ++ .remove = pcm1794a_remove, ++ .driver = { ++ .name = "pcm1794a-codec", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(pcm1794a_codec_driver); ++ ++MODULE_DESCRIPTION("ASoC PCM1794A codec driver"); ++MODULE_AUTHOR("Florian Meier "); ++MODULE_LICENSE("GPL v2"); + +From 0418e9bd3eab8e21b5d69ed0b7899dd5a80263f1 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Wed, 15 Jan 2014 21:41:23 +0100 +Subject: [PATCH 41/77] ASoC: wm8804: Implement MCLK configuration options, add + 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for + most sample rates. At 192kHz only 128xfs is supported. The existing driver + selects 128xfs automatically for some lower samples rates. By using an + additional mclk_div divider, it is now possible to control the behaviour. + This allows using 256xfs PLL frequency on all sample rates up to 96kHz. It + should allow lower jitter and better signal quality. The behavior has to be + controlled by the sound card driver, because some sample frequency share the + same setting. e.g. 192kHz and 96kHz use 24.576MHz master clock. The only + difference is the MCLK divider. + +This also added support for 32bit data. + +Signed-off-by: Daniel Matuschek +--- + sound/soc/codecs/wm8804.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c +index 1e403f6..d4efa85 100644 +--- a/sound/soc/codecs/wm8804.c ++++ b/sound/soc/codecs/wm8804.c +@@ -304,6 +304,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream, + blen = 0x1; + break; + case 24: ++ case 32: + blen = 0x2; + break; + default: +@@ -515,7 +516,7 @@ static const struct snd_soc_dai_ops wm8804_dai_ops = { + }; + + #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ +- SNDRV_PCM_FMTBIT_S24_LE) ++ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) + + #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ + +From 82c2f5a297701240bf5a77611d2d93c041497246 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Wed, 15 Jan 2014 21:42:08 +0100 +Subject: [PATCH 42/77] ASoC: BCM:Add support for HiFiBerry Digi. Driver is + based on the patched WM8804 driver. + +Signed-off-by: Daniel Matuschek + +Add a parameter to turn off SPDIF output if no audio is playing + +This patch adds the paramater auto_shutdown_output to the kernel module. +Default behaviour of the module is the same, but when auto_shutdown_output +is set to 1, the SPDIF oputput will shutdown if no stream is playing. + +bugfix for 32kHz sample rate, was missing + +HiFiBerry Digi: set SPDIF status bits for sample rate + +The HiFiBerry Digi driver did not signal the sample rate in the SPDIF status bits. +While this is optional, some DACs and receivers do not accept this signal. This patch +adds the sample rate bits in the SPDIF status block. +--- + sound/soc/bcm/Kconfig | 7 ++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_digi.c | 201 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 210 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_digi.c + +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index cb7c0c2..2e26e12 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC + help + Say Y or M if you want to add support for HifiBerry DAC. + ++config SND_BCM2708_SOC_HIFIBERRY_DIGI ++ tristate "Support for HifiBerry Digi" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_WM8804 ++ help ++ Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. ++ + config SND_BCM2708_SOC_RPI_DAC + tristate "Support for RPi-DAC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index ccc9809..826df7d 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -10,7 +10,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + + # BCM2708 Machine Support + snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++snd-soc-hifiberry-digi-objs := hifiberry_digi.o + snd-soc-rpi-dac-objs := rpi-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o +diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c +new file mode 100644 +index 0000000..92e9e46 +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_digi.c +@@ -0,0 +1,201 @@ ++/* ++ * ASoC Driver for HifiBerry Digi ++ * ++ * Author: Daniel Matuschek ++ * based on the HifiBerry DAC driver by Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/wm8804.h" ++ ++static short int auto_shutdown_output = 0; ++module_param(auto_shutdown_output, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); ++MODULE_PARM_DESC(auto_shutdown_output, "Shutdown SP/DIF output if playback is stopped"); ++ ++ ++static int samplerate=44100; ++ ++static int snd_rpi_hifiberry_digi_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ /* enable TX output */ ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); ++ ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_digi_startup(struct snd_pcm_substream *substream) { ++ /* turn on digital output */ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x00); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_digi_shutdown(struct snd_pcm_substream *substream) { ++ /* turn off output */ ++ if (auto_shutdown_output) { ++ /* turn off output */ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x3c, 0x3c); ++ } ++} ++ ++ ++static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ struct snd_soc_codec *codec = rtd->codec; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ int sysclk = 27000000; /* This is fixed on this board */ ++ ++ long mclk_freq=0; ++ int mclk_div=1; ++ int sampling_freq=1; ++ ++ int ret; ++ ++ samplerate = params_rate(params); ++ ++ if (samplerate<=96000) { ++ mclk_freq=samplerate*256; ++ mclk_div=WM8804_MCLKDIV_256FS; ++ } else { ++ mclk_freq=samplerate*128; ++ mclk_div=WM8804_MCLKDIV_128FS; ++ } ++ ++ switch (samplerate) { ++ case 32000: ++ sampling_freq=0x03; ++ break; ++ case 44100: ++ sampling_freq=0x00; ++ break; ++ case 48000: ++ sampling_freq=0x02; ++ break; ++ case 88200: ++ sampling_freq=0x08; ++ break; ++ case 96000: ++ sampling_freq=0x0a; ++ break; ++ case 176400: ++ sampling_freq=0x0c; ++ break; ++ case 192000: ++ sampling_freq=0x0e; ++ break; ++ default: ++ dev_err(codec->dev, ++ "Failed to set WM8804 SYSCLK, unsupported samplerate %d\n", ++ samplerate); ++ } ++ ++ snd_soc_dai_set_clkdiv(codec_dai, WM8804_MCLK_DIV, mclk_div); ++ snd_soc_dai_set_pll(codec_dai, 0, 0, sysclk, mclk_freq); ++ ++ ret = snd_soc_dai_set_sysclk(codec_dai, WM8804_TX_CLKSRC_PLL, ++ sysclk, SND_SOC_CLOCK_OUT); ++ if (ret < 0) { ++ dev_err(codec->dev, ++ "Failed to set WM8804 SYSCLK: %d\n", ret); ++ return ret; ++ } ++ ++ /* Enable TX output */ ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x0); ++ ++ /* Power on */ ++ snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); ++ ++ /* set sampling frequency status bits */ ++ snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai,64); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_digi_ops = { ++ .hw_params = snd_rpi_hifiberry_digi_hw_params, ++ .startup = snd_rpi_hifiberry_digi_startup, ++ .shutdown = snd_rpi_hifiberry_digi_shutdown, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_digi_dai[] = { ++{ ++ .name = "HifiBerry Digi", ++ .stream_name = "HifiBerry Digi HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "wm8804-spdif", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "wm8804.1-003b", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBM_CFM, ++ .ops = &snd_rpi_hifiberry_digi_ops, ++ .init = snd_rpi_hifiberry_digi_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_digi = { ++ .name = "snd_rpi_hifiberry_digi", ++ .dai_link = snd_rpi_hifiberry_digi_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_digi_dai), ++}; ++ ++static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_digi.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); ++ if (ret) ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); ++} ++ ++static struct platform_driver snd_rpi_hifiberry_digi_driver = { ++ .driver = { ++ .name = "snd-hifiberry-digi", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_hifiberry_digi_probe, ++ .remove = snd_rpi_hifiberry_digi_remove, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_digi_driver); ++ ++MODULE_AUTHOR("Daniel Matuschek "); ++MODULE_DESCRIPTION("ASoC Driver for HifiBerry Digi"); ++MODULE_LICENSE("GPL v2"); + +From df14e52cd5e411324c58e28ec158f503d4905dbb Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Thu, 16 Jan 2014 07:26:08 +0100 +Subject: [PATCH 43/77] BCM2708: Added support for HiFiBerry Digi board Board + initalization by I2C + +Signed-off-by: Daniel Matuschek +--- + arch/arm/mach-bcm2708/bcm2708.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index be27073..2a33663 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -652,6 +652,21 @@ static struct platform_device snd_pcm5102a_codec_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++static struct platform_device snd_hifiberry_digi_device = { ++ .name = "snd-hifiberry-digi", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("wm8804", 0x3b) ++ }, ++}; ++ ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + static struct platform_device snd_rpi_dac_device = { + .name = "snd-rpi-dac", +@@ -839,6 +854,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_digi_device); ++ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + bcm_register_device_dt(&snd_rpi_dac_device); + bcm_register_device_dt(&snd_pcm1794a_codec_device); + +From d8de9644604c68b7148b023608d70d8ac3bf466f Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Thu, 16 Jan 2014 07:36:35 +0100 +Subject: [PATCH 44/77] ASoC: wm8804: Set idle_bias_off to false Idle bias has + been change to remove warning on driver startup + +Signed-off-by: Daniel Matuschek +--- + sound/soc/codecs/wm8804.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c +index d4efa85..f3f26a2 100644 +--- a/sound/soc/codecs/wm8804.c ++++ b/sound/soc/codecs/wm8804.c +@@ -544,7 +544,7 @@ static struct snd_soc_dai_driver wm8804_dai = { + }; + + static const struct snd_soc_codec_driver soc_codec_dev_wm8804 = { +- .idle_bias_off = true, ++ .idle_bias_off = false, + + .dapm_widgets = wm8804_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8804_dapm_widgets), + +From 40f01186460630fa704c88adbefbc347e5e402e4 Mon Sep 17 00:00:00 2001 +From: Gordon Garrity +Date: Sat, 8 Mar 2014 16:56:57 +0000 +Subject: [PATCH 45/77] Add IQaudIO Sound Card support for Raspberry Pi + +Set a limit of 0dB on Digital Volume Control + +The main volume control in the PCM512x DAC has a range up to ++24dB. This is dangerously loud and can potentially cause massive +clipping in the output stages. Therefore this sets a sensible +limit of 0dB for this control. +--- + arch/arm/mach-bcm2708/bcm2708.c | 21 ++++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/iqaudio-dac.c | 117 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 147 insertions(+) + create mode 100644 sound/soc/bcm/iqaudio-dac.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 2a33663..957504e 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -681,6 +681,22 @@ static struct platform_device snd_pcm1794a_codec_device = { + }; + #endif + ++ ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++static struct platform_device snd_rpi_iqaudio_dac_device = { ++ .name = "snd-rpi-iqaudio-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++// Use the actual device name rather than generic driver name ++static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4c) ++ }, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -864,6 +880,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm1794a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 2e26e12..f6f8ec1 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -39,3 +39,10 @@ config SND_BCM2708_SOC_RPI_DAC + select SND_SOC_PCM1794A + help + Say Y or M if you want to add support for RPi-DAC. ++ ++config SND_BCM2708_SOC_IQAUDIO_DAC ++ tristate "Support for IQaudIO-DAC" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM512x_I2C ++ help ++ Say Y or M if you want to add support for IQaudIO-DAC. +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index 826df7d..d597fb0 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -12,7 +12,9 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + snd-soc-hifiberry-dac-objs := hifiberry_dac.o + snd-soc-hifiberry-digi-objs := hifiberry_digi.o + snd-soc-rpi-dac-objs := rpi-dac.o ++snd-soc-iqaudio-dac-objs := iqaudio-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c +new file mode 100644 +index 0000000..aff7377 +--- /dev/null ++++ b/sound/soc/bcm/iqaudio-dac.c +@@ -0,0 +1,117 @@ ++/* ++ * ASoC Driver for IQaudIO DAC ++ * ++ * Author: Florian Meier ++ * Copyright 2013 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_iqaudio_dac_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ int ret; ++ struct snd_soc_card *card = rtd->card; ++ struct snd_soc_codec *codec = rtd->codec; ++ ++ ret = snd_soc_limit_volume(codec, "Digital Playback Volume", 207); ++ if (ret < 0) ++ dev_warn(card->dev, "Failed to set volume limit: %d\n", ret); ++ ++ return 0; ++} ++ ++static int snd_rpi_iqaudio_dac_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++// NOT USED struct snd_soc_dai *codec_dai = rtd->codec_dai; ++// NOT USED struct snd_soc_codec *codec = rtd->codec; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ unsigned int sample_bits = ++ snd_pcm_format_physical_width(params_format(params)); ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_iqaudio_dac_ops = { ++ .hw_params = snd_rpi_iqaudio_dac_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_iqaudio_dac_dai[] = { ++{ ++ .name = "IQaudIO DAC", ++ .stream_name = "IQaudIO DAC HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm512x-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm512x.1-004c", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_iqaudio_dac_ops, ++ .init = snd_rpi_iqaudio_dac_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_iqaudio_dac = { ++ .name = "IQaudIODAC", ++ .dai_link = snd_rpi_iqaudio_dac_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_iqaudio_dac_dai), ++}; ++ ++static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_iqaudio_dac.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); ++ if (ret) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_iqaudio_dac_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_iqaudio_dac); ++} ++ ++static const struct of_device_id iqaudio_of_match[] = { ++ { .compatible = "iqaudio,iqaudio-dac", }, ++ {}, ++}; ++ ++static struct platform_driver snd_rpi_iqaudio_dac_driver = { ++ .driver = { ++ .name = "snd-rpi-iqaudio-dac", ++ .owner = THIS_MODULE, ++ .of_match_table = iqaudio_of_match, ++ }, ++ .probe = snd_rpi_iqaudio_dac_probe, ++ .remove = snd_rpi_iqaudio_dac_remove, ++}; ++ ++module_platform_driver(snd_rpi_iqaudio_dac_driver); ++ ++MODULE_AUTHOR("Florian Meier "); ++MODULE_DESCRIPTION("ASoC Driver for IQAudio DAC"); ++MODULE_LICENSE("GPL v2"); + +From 5d1014e6dfa91f7f4b07851eefaa0a8bc544fda8 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 18 Jun 2014 13:42:01 +0100 +Subject: [PATCH 46/77] vmstat: Workaround for issue where dirty page count + goes negative + +See: +https://github.com/raspberrypi/linux/issues/617 +http://www.spinics.net/lists/linux-mm/msg72236.html +--- + include/linux/vmstat.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h +index 82e7db7..f87d16d 100644 +--- a/include/linux/vmstat.h ++++ b/include/linux/vmstat.h +@@ -241,7 +241,11 @@ static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item) + static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item) + { + atomic_long_dec(&zone->vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&zone->vm_stat[item]) < 0)) ++ atomic_long_set(&zone->vm_stat[item], 0); + atomic_long_dec(&vm_stat[item]); ++ if (item == NR_FILE_DIRTY && unlikely(atomic_long_read(&vm_stat[item]) < 0)) ++ atomic_long_set(&vm_stat[item], 0); + } + + static inline void __inc_zone_page_state(struct page *page, + +From 462ac627ee409f190f5519727c80942afafd0d6d Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 14 Jul 2014 22:02:09 +0100 +Subject: [PATCH 47/77] hid: Reduce default mouse polling interval to 60Hz + +Reduces overhead when using X +--- + drivers/hid/usbhid/hid-core.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c +index bfbe1be..a738b25 100644 +--- a/drivers/hid/usbhid/hid-core.c ++++ b/drivers/hid/usbhid/hid-core.c +@@ -49,7 +49,7 @@ + * Module parameters. + */ + +-static unsigned int hid_mousepoll_interval; ++static unsigned int hid_mousepoll_interval = ~0; + module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); + MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); + +@@ -1090,8 +1090,12 @@ static int usbhid_start(struct hid_device *hid) + } + + /* Change the polling interval of mice. */ +- if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) +- interval = hid_mousepoll_interval; ++ if (hid->collection->usage == HID_GD_MOUSE) { ++ if (hid_mousepoll_interval == ~0 && interval < 16) ++ interval = 16; ++ else if (hid_mousepoll_interval != ~0 && hid_mousepoll_interval != 0) ++ interval = hid_mousepoll_interval; ++ } + + ret = -ENOMEM; + if (usb_endpoint_dir_in(endpoint)) { + +From 6a68d9854eed6f1c5741aff8466cb5877deecd54 Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Mon, 4 Aug 2014 10:06:56 +0200 +Subject: [PATCH 48/77] Added support for HiFiBerry DAC+ + +The driver is based on the HiFiBerry DAC driver. However HiFiBerry DAC+ uses +a different codec chip (PCM5122), therefore a new driver is necessary. +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 ++++++ + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_dacplus.c | 119 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 147 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_dacplus.c + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 957504e..90459b8 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -652,6 +652,20 @@ static struct platform_device snd_pcm5102a_codec_device = { + }; + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++static struct platform_device snd_rpi_hifiberry_dacplus_device = { ++ .name = "snd-rpi-hifiberry-dacplus", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4d) ++ }, ++}; ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) + static struct platform_device snd_hifiberry_digi_device = { + .name = "snd-hifiberry-digi", +@@ -870,6 +884,11 @@ void __init bcm2708_init(void) + bcm_register_device_dt(&snd_pcm5102a_codec_device); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) + bcm_register_device_dt(&snd_hifiberry_digi_device); + i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index f6f8ec1..8b45ac5 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -26,6 +26,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DAC + help + Say Y or M if you want to add support for HifiBerry DAC. + ++config SND_BCM2708_SOC_HIFIBERRY_DACPLUS ++ tristate "Support for HifiBerry DAC+" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_PCM512x ++ help ++ Say Y or M if you want to add support for HifiBerry DAC+. ++ + config SND_BCM2708_SOC_HIFIBERRY_DIGI + tristate "Support for HifiBerry Digi" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index d597fb0..c02e3a2 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -10,11 +10,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + + # BCM2708 Machine Support + snd-soc-hifiberry-dac-objs := hifiberry_dac.o ++snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-digi-objs := hifiberry_digi.o + snd-soc-rpi-dac-objs := rpi-dac.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c +new file mode 100644 +index 0000000..c63387b +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -0,0 +1,119 @@ ++/* ++ * ASoC Driver for HiFiBerry DAC+ ++ * ++ * Author: Daniel Matuschek ++ * Copyright 2014 ++ * based on code by Florian Meier ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "../codecs/pcm512x.h" ++ ++static int snd_rpi_hifiberry_dacplus_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, PCM512x_GPIO_EN, 0x08, 0x08); ++ snd_soc_update_bits(codec, PCM512x_GPIO_OUTPUT_4, 0xf, 0x02); ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_dacplus_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++} ++ ++static int snd_rpi_hifiberry_dacplus_startup(struct snd_pcm_substream *substream) { ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x08); ++ return 0; ++} ++ ++static void snd_rpi_hifiberry_dacplus_shutdown(struct snd_pcm_substream *substream) { ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_codec *codec = rtd->codec; ++ snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08,0x00); ++} ++ ++/* machine stream operations */ ++static struct snd_soc_ops snd_rpi_hifiberry_dacplus_ops = { ++ .hw_params = snd_rpi_hifiberry_dacplus_hw_params, ++ .startup = snd_rpi_hifiberry_dacplus_startup, ++ .shutdown = snd_rpi_hifiberry_dacplus_shutdown, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_dacplus_dai[] = { ++{ ++ .name = "HiFiBerry DAC+", ++ .stream_name = "HiFiBerry DAC+ HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "pcm512x-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "pcm512x.1-004d", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_dacplus_ops, ++ .init = snd_rpi_hifiberry_dacplus_init, ++}, ++}; ++ ++/* audio machine driver */ ++static struct snd_soc_card snd_rpi_hifiberry_dacplus = { ++ .name = "snd_rpi_hifiberry_dacplus", ++ .dai_link = snd_rpi_hifiberry_dacplus_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_dacplus_dai), ++}; ++ ++static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_dacplus.dev = &pdev->dev; ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); ++ if (ret) ++ dev_err(&pdev->dev, ++ "snd_soc_register_card() failed: %d\n", ret); ++ ++ return ret; ++} ++ ++static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); ++} ++ ++static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { ++ .driver = { ++ .name = "snd-rpi-hifiberry-dacplus", ++ .owner = THIS_MODULE, ++ }, ++ .probe = snd_rpi_hifiberry_dacplus_probe, ++ .remove = snd_rpi_hifiberry_dacplus_remove, ++}; ++ ++module_platform_driver(snd_rpi_hifiberry_dacplus_driver); ++ ++MODULE_AUTHOR("Daniel Matuschek "); ++MODULE_DESCRIPTION("ASoC Driver for HiFiBerry DAC+"); ++MODULE_LICENSE("GPL v2"); + +From 1ca3777a5f3e17847136937e1bab1717281c73ca Mon Sep 17 00:00:00 2001 +From: Daniel Matuschek +Date: Mon, 4 Aug 2014 11:09:58 +0200 +Subject: [PATCH 49/77] Added driver for HiFiBerry Amp amplifier add-on board + +The driver contains a low-level hardware driver for the TAS5713 and the +drivers for the Raspberry Pi I2S subsystem. + +TAS5713: return error if initialisation fails + +Existing TAS5713 driver logs errors during initialisation, but does not return +an error code. Therefore even if initialisation fails, the driver will still be +loaded, but won't work. This patch fixes this. I2C communication error will now +reported correctly by a non-zero return code. + +HiFiBerry Amp: fix device-tree problems + +Some code to load the driver based on device-tree-overlays was missing. This is added by this patch. +--- + arch/arm/mach-bcm2708/bcm2708.c | 19 +++ + sound/soc/bcm/Kconfig | 7 + + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/hifiberry_amp.c | 127 ++++++++++++++ + sound/soc/codecs/Kconfig | 4 + + sound/soc/codecs/Makefile | 2 + + sound/soc/codecs/tas5713.c | 369 ++++++++++++++++++++++++++++++++++++++++ + sound/soc/codecs/tas5713.h | 210 +++++++++++++++++++++++ + 8 files changed, 740 insertions(+) + create mode 100644 sound/soc/bcm/hifiberry_amp.c + create mode 100644 sound/soc/codecs/tas5713.c + create mode 100644 sound/soc/codecs/tas5713.h + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 90459b8..785cf1a 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -681,6 +681,20 @@ static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { + + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++static struct platform_device snd_hifiberry_amp_device = { ++ .name = "snd-hifiberry-amp", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("tas5713", 0x1b) ++ }, ++}; ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + static struct platform_device snd_rpi_dac_device = { + .name = "snd-rpi-dac", +@@ -894,6 +908,11 @@ void __init bcm2708_init(void) + i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); + #endif + ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_amp_device); ++ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); ++#endif ++ + #if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) + bcm_register_device_dt(&snd_rpi_dac_device); + bcm_register_device_dt(&snd_pcm1794a_codec_device); +diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig +index 8b45ac5..bdcf12f 100644 +--- a/sound/soc/bcm/Kconfig ++++ b/sound/soc/bcm/Kconfig +@@ -40,6 +40,13 @@ config SND_BCM2708_SOC_HIFIBERRY_DIGI + help + Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. + ++config SND_BCM2708_SOC_HIFIBERRY_AMP ++ tristate "Support for the HifiBerry Amp" ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S ++ select SND_SOC_TAS5713 ++ help ++ Say Y or M if you want to add support for the HifiBerry Amp amplifier board. ++ + config SND_BCM2708_SOC_RPI_DAC + tristate "Support for RPi-DAC" + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S +diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile +index c02e3a2..17ea2b0 100644 +--- a/sound/soc/bcm/Makefile ++++ b/sound/soc/bcm/Makefile +@@ -12,11 +12,13 @@ obj-$(CONFIG_SND_BCM2708_SOC_I2S) += snd-soc-bcm2708-i2s.o + snd-soc-hifiberry-dac-objs := hifiberry_dac.o + snd-soc-hifiberry-dacplus-objs := hifiberry_dacplus.o + snd-soc-hifiberry-digi-objs := hifiberry_digi.o ++snd-soc-hifiberry-amp-objs := hifiberry_amp.o + snd-soc-rpi-dac-objs := rpi-dac.o + snd-soc-iqaudio-dac-objs := iqaudio-dac.o + + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) += snd-soc-hifiberry-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) += snd-soc-hifiberry-dacplus.o + obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) += snd-soc-hifiberry-digi.o ++obj-$(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) += snd-soc-hifiberry-amp.o + obj-$(CONFIG_SND_BCM2708_SOC_RPI_DAC) += snd-soc-rpi-dac.o + obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o +diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c +new file mode 100644 +index 0000000..5903915 +--- /dev/null ++++ b/sound/soc/bcm/hifiberry_amp.c +@@ -0,0 +1,127 @@ ++/* ++ * ASoC Driver for HifiBerry AMP ++ * ++ * Author: Sebastian Eickhoff ++ * Copyright 2014 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int snd_rpi_hifiberry_amp_init(struct snd_soc_pcm_runtime *rtd) ++{ ++ // ToDo: init of the dsp-registers. ++ return 0; ++} ++ ++static int snd_rpi_hifiberry_amp_hw_params( struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params ) ++{ ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; ++ ++ return snd_soc_dai_set_bclk_ratio(cpu_dai, 64); ++} ++ ++static struct snd_soc_ops snd_rpi_hifiberry_amp_ops = { ++ .hw_params = snd_rpi_hifiberry_amp_hw_params, ++}; ++ ++static struct snd_soc_dai_link snd_rpi_hifiberry_amp_dai[] = { ++ { ++ .name = "HifiBerry AMP", ++ .stream_name = "HifiBerry AMP HiFi", ++ .cpu_dai_name = "bcm2708-i2s.0", ++ .codec_dai_name = "tas5713-hifi", ++ .platform_name = "bcm2708-i2s.0", ++ .codec_name = "tas5713.1-001b", ++ .dai_fmt = SND_SOC_DAIFMT_I2S | ++ SND_SOC_DAIFMT_NB_NF | ++ SND_SOC_DAIFMT_CBS_CFS, ++ .ops = &snd_rpi_hifiberry_amp_ops, ++ .init = snd_rpi_hifiberry_amp_init, ++ }, ++}; ++ ++ ++static struct snd_soc_card snd_rpi_hifiberry_amp = { ++ .name = "snd_rpi_hifiberry_amp", ++ .dai_link = snd_rpi_hifiberry_amp_dai, ++ .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), ++}; ++ ++static const struct of_device_id snd_rpi_hifiberry_amp_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-amp", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_amp_of_match); ++ ++ ++static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) ++{ ++ int ret = 0; ++ ++ snd_rpi_hifiberry_amp.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_amp_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ ++ ret = snd_soc_register_card(&snd_rpi_hifiberry_amp); ++ ++ if (ret != 0) { ++ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); ++ } ++ ++ return ret; ++} ++ ++ ++static int snd_rpi_hifiberry_amp_remove(struct platform_device *pdev) ++{ ++ return snd_soc_unregister_card(&snd_rpi_hifiberry_amp); ++} ++ ++ ++static struct platform_driver snd_rpi_hifiberry_amp_driver = { ++ .driver = { ++ .name = "snd-hifiberry-amp", ++ .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_amp_of_match, ++ }, ++ .probe = snd_rpi_hifiberry_amp_probe, ++ .remove = snd_rpi_hifiberry_amp_remove, ++}; ++ ++ ++module_platform_driver(snd_rpi_hifiberry_amp_driver); ++ ++ ++MODULE_AUTHOR("Sebastian Eickhoff "); ++MODULE_DESCRIPTION("ASoC driver for HiFiBerry-AMP"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index dc3df1a..8a9f07c 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -109,6 +109,7 @@ config SND_SOC_ALL_CODECS + select SND_SOC_TFA9879 if I2C + select SND_SOC_TLV320AIC23_I2C if I2C + select SND_SOC_TLV320AIC23_SPI if SPI_MASTER ++ select SND_SOC_TAS5713 if I2C + select SND_SOC_TLV320AIC26 if SPI_MASTER + select SND_SOC_TLV320AIC31XX if I2C + select SND_SOC_TLV320AIC32X4 if I2C +@@ -623,6 +624,9 @@ config SND_SOC_TFA9879 + tristate "NXP Semiconductors TFA9879 amplifier" + depends on I2C + ++config SND_SOC_TAS5713 ++ tristate ++ + config SND_SOC_TLV320AIC23 + tristate + +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index c1f6ba6..8ebf7f1 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -109,6 +109,7 @@ snd-soc-sta529-objs := sta529.o + snd-soc-stac9766-objs := stac9766.o + snd-soc-tas5086-objs := tas5086.o + snd-soc-tfa9879-objs := tfa9879.o ++snd-soc-tas5713-objs := tas5713.o + snd-soc-tlv320aic23-objs := tlv320aic23.o + snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o + snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o +@@ -293,6 +294,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o + obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o + obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o + obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o ++obj-$(CONFIG_SND_SOC_TAS5713) += snd-soc-tas5713.o + obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o + obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o + obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o +diff --git a/sound/soc/codecs/tas5713.c b/sound/soc/codecs/tas5713.c +new file mode 100644 +index 0000000..9b27138 +--- /dev/null ++++ b/sound/soc/codecs/tas5713.c +@@ -0,0 +1,369 @@ ++/* ++ * ASoC Driver for TAS5713 ++ * ++ * Author: Sebastian Eickhoff ++ * Copyright 2014 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "tas5713.h" ++ ++ ++static struct i2c_client *i2c; ++ ++struct tas5713_priv { ++ struct regmap *regmap; ++ int mclk_div; ++ struct snd_soc_codec *codec; ++}; ++ ++static struct tas5713_priv *priv_data; ++ ++ ++ ++ ++/* ++ * _ _ ___ _ ___ _ _ ++ * /_\ | | / __| /_\ / __|___ _ _| |_ _ _ ___| |___ ++ * / _ \| |__\__ \/ _ \ | (__/ _ \ ' \ _| '_/ _ \ (_-< ++ * /_/ \_\____|___/_/ \_\ \___\___/_||_\__|_| \___/_/__/ ++ * ++ */ ++ ++static const DECLARE_TLV_DB_SCALE(tas5713_vol_tlv, -10000, 50, 1); ++ ++ ++static const struct snd_kcontrol_new tas5713_snd_controls[] = { ++ SOC_SINGLE_TLV ("Master" , TAS5713_VOL_MASTER, 0, 248, 1, tas5713_vol_tlv), ++ SOC_DOUBLE_R_TLV("Channels" , TAS5713_VOL_CH1, TAS5713_VOL_CH2, 0, 248, 1, tas5713_vol_tlv) ++}; ++ ++ ++ ++ ++/* ++ * __ __ _ _ ___ _ ++ * | \/ |__ _ __| |_ (_)_ _ ___ | \ _ _(_)_ _____ _ _ ++ * | |\/| / _` / _| ' \| | ' \/ -_) | |) | '_| \ V / -_) '_| ++ * |_| |_\__,_\__|_||_|_|_||_\___| |___/|_| |_|\_/\___|_| ++ * ++ */ ++ ++static int tas5713_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params, ++ struct snd_soc_dai *dai) ++{ ++ u16 blen = 0x00; ++ ++ struct snd_soc_codec *codec; ++ codec = dai->codec; ++ priv_data->codec = dai->codec; ++ ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ blen = 0x03; ++ break; ++ case SNDRV_PCM_FORMAT_S20_3LE: ++ blen = 0x1; ++ break; ++ case SNDRV_PCM_FORMAT_S24_LE: ++ blen = 0x04; ++ break; ++ case SNDRV_PCM_FORMAT_S32_LE: ++ blen = 0x05; ++ break; ++ default: ++ dev_err(dai->dev, "Unsupported word length: %u\n", ++ params_format(params)); ++ return -EINVAL; ++ } ++ ++ // set word length ++ snd_soc_update_bits(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x7, blen); ++ ++ return 0; ++} ++ ++ ++static int tas5713_mute_stream(struct snd_soc_dai *dai, int mute, int stream) ++{ ++ unsigned int val = 0; ++ ++ struct tas5713_priv *tas5713; ++ struct snd_soc_codec *codec = dai->codec; ++ tas5713 = snd_soc_codec_get_drvdata(codec); ++ ++ if (mute) { ++ val = TAS5713_SOFT_MUTE_ALL; ++ } ++ ++ return regmap_write(tas5713->regmap, TAS5713_SOFT_MUTE, val); ++} ++ ++ ++static const struct snd_soc_dai_ops tas5713_dai_ops = { ++ .hw_params = tas5713_hw_params, ++ .mute_stream = tas5713_mute_stream, ++}; ++ ++ ++static struct snd_soc_dai_driver tas5713_dai = { ++ .name = "tas5713-hifi", ++ .playback = { ++ .stream_name = "Playback", ++ .channels_min = 2, ++ .channels_max = 2, ++ .rates = SNDRV_PCM_RATE_8000_48000, ++ .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE ), ++ }, ++ .ops = &tas5713_dai_ops, ++}; ++ ++ ++ ++ ++/* ++ * ___ _ ___ _ ++ * / __|___ __| |___ __ | \ _ _(_)_ _____ _ _ ++ * | (__/ _ \/ _` / -_) _| | |) | '_| \ V / -_) '_| ++ * \___\___/\__,_\___\__| |___/|_| |_|\_/\___|_| ++ * ++ */ ++ ++static int tas5713_remove(struct snd_soc_codec *codec) ++{ ++ struct tas5713_priv *tas5713; ++ ++ tas5713 = snd_soc_codec_get_drvdata(codec); ++ ++ return 0; ++} ++ ++ ++static int tas5713_probe(struct snd_soc_codec *codec) ++{ ++ struct tas5713_priv *tas5713; ++ int i, ret; ++ ++ i2c = container_of(codec->dev, struct i2c_client, dev); ++ ++ tas5713 = snd_soc_codec_get_drvdata(codec); ++ ++ // Reset error ++ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); ++ if (ret < 0) return ret; ++ ++ // Trim oscillator ++ ret = snd_soc_write(codec, TAS5713_OSC_TRIM, 0x00); ++ if (ret < 0) return ret; ++ msleep(1000); ++ ++ // Reset error ++ ret = snd_soc_write(codec, TAS5713_ERROR_STATUS, 0x00); ++ if (ret < 0) return ret; ++ ++ // Clock mode: 44/48kHz, MCLK=64xfs ++ ret = snd_soc_write(codec, TAS5713_CLOCK_CTRL, 0x60); ++ if (ret < 0) return ret; ++ ++ // I2S 24bit ++ ret = snd_soc_write(codec, TAS5713_SERIAL_DATA_INTERFACE, 0x05); ++ if (ret < 0) return ret; ++ ++ // Unmute ++ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); ++ if (ret < 0) return ret; ++ ret = snd_soc_write(codec, TAS5713_SOFT_MUTE, 0x00); ++ if (ret < 0) return ret; ++ ++ // Set volume to 0db ++ ret = snd_soc_write(codec, TAS5713_VOL_MASTER, 0x00); ++ if (ret < 0) return ret; ++ ++ // Now start programming the default initialization sequence ++ for (i = 0; i < ARRAY_SIZE(tas5713_init_sequence); ++i) { ++ ret = i2c_master_send(i2c, ++ tas5713_init_sequence[i].data, ++ tas5713_init_sequence[i].size); ++ if (ret < 0) { ++ printk(KERN_INFO "TAS5713 CODEC PROBE: InitSeq returns: %d\n", ret); ++ } ++ } ++ ++ // Unmute ++ ret = snd_soc_write(codec, TAS5713_SYSTEM_CTRL2, 0x00); ++ if (ret < 0) return ret; ++ ++ return 0; ++} ++ ++ ++static struct snd_soc_codec_driver soc_codec_dev_tas5713 = { ++ .probe = tas5713_probe, ++ .remove = tas5713_remove, ++ .controls = tas5713_snd_controls, ++ .num_controls = ARRAY_SIZE(tas5713_snd_controls), ++}; ++ ++ ++ ++ ++/* ++ * ___ ___ ___ ___ _ ++ * |_ _|_ ) __| | \ _ _(_)_ _____ _ _ ++ * | | / / (__ | |) | '_| \ V / -_) '_| ++ * |___/___\___| |___/|_| |_|\_/\___|_| ++ * ++ */ ++ ++static const struct reg_default tas5713_reg_defaults[] = { ++ { 0x07 ,0x80 }, // R7 - VOL_MASTER - -40dB ++ { 0x08 , 30 }, // R8 - VOL_CH1 - 0dB ++ { 0x09 , 30 }, // R9 - VOL_CH2 - 0dB ++ { 0x0A ,0x80 }, // R10 - VOL_HEADPHONE - -40dB ++}; ++ ++ ++static bool tas5713_reg_volatile(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case TAS5713_DEVICE_ID: ++ case TAS5713_ERROR_STATUS: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++ ++static const struct of_device_id tas5713_of_match[] = { ++ { .compatible = "ti,tas5713", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, tas5713_of_match); ++ ++ ++static struct regmap_config tas5713_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ ++ .max_register = TAS5713_MAX_REGISTER, ++ .volatile_reg = tas5713_reg_volatile, ++ ++ .cache_type = REGCACHE_RBTREE, ++ .reg_defaults = tas5713_reg_defaults, ++ .num_reg_defaults = ARRAY_SIZE(tas5713_reg_defaults), ++}; ++ ++ ++static int tas5713_i2c_probe(struct i2c_client *i2c, ++ const struct i2c_device_id *id) ++{ ++ int ret; ++ ++ priv_data = devm_kzalloc(&i2c->dev, sizeof *priv_data, GFP_KERNEL); ++ if (!priv_data) ++ return -ENOMEM; ++ ++ priv_data->regmap = devm_regmap_init_i2c(i2c, &tas5713_regmap_config); ++ if (IS_ERR(priv_data->regmap)) { ++ ret = PTR_ERR(priv_data->regmap); ++ return ret; ++ } ++ ++ i2c_set_clientdata(i2c, priv_data); ++ ++ ret = snd_soc_register_codec(&i2c->dev, ++ &soc_codec_dev_tas5713, &tas5713_dai, 1); ++ ++ return ret; ++} ++ ++ ++static int tas5713_i2c_remove(struct i2c_client *i2c) ++{ ++ snd_soc_unregister_codec(&i2c->dev); ++ i2c_set_clientdata(i2c, NULL); ++ ++ kfree(priv_data); ++ ++ return 0; ++} ++ ++ ++static const struct i2c_device_id tas5713_i2c_id[] = { ++ { "tas5713", 0 }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(i2c, tas5713_i2c_id); ++ ++ ++static struct i2c_driver tas5713_i2c_driver = { ++ .driver = { ++ .name = "tas5713", ++ .owner = THIS_MODULE, ++ .of_match_table = tas5713_of_match, ++ }, ++ .probe = tas5713_i2c_probe, ++ .remove = tas5713_i2c_remove, ++ .id_table = tas5713_i2c_id ++}; ++ ++ ++static int __init tas5713_modinit(void) ++{ ++ int ret = 0; ++ ++ ret = i2c_add_driver(&tas5713_i2c_driver); ++ if (ret) { ++ printk(KERN_ERR "Failed to register tas5713 I2C driver: %d\n", ++ ret); ++ } ++ ++ return ret; ++} ++module_init(tas5713_modinit); ++ ++ ++static void __exit tas5713_exit(void) ++{ ++ i2c_del_driver(&tas5713_i2c_driver); ++} ++module_exit(tas5713_exit); ++ ++ ++MODULE_AUTHOR("Sebastian Eickhoff "); ++MODULE_DESCRIPTION("ASoC driver for TAS5713"); ++MODULE_LICENSE("GPL v2"); +diff --git a/sound/soc/codecs/tas5713.h b/sound/soc/codecs/tas5713.h +new file mode 100644 +index 0000000..8f019e0 +--- /dev/null ++++ b/sound/soc/codecs/tas5713.h +@@ -0,0 +1,210 @@ ++/* ++ * ASoC Driver for TAS5713 ++ * ++ * Author: Sebastian Eickhoff ++ * Copyright 2014 ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef _TAS5713_H ++#define _TAS5713_H ++ ++ ++// TAS5713 I2C-bus register addresses ++ ++#define TAS5713_CLOCK_CTRL 0x00 ++#define TAS5713_DEVICE_ID 0x01 ++#define TAS5713_ERROR_STATUS 0x02 ++#define TAS5713_SYSTEM_CTRL1 0x03 ++#define TAS5713_SERIAL_DATA_INTERFACE 0x04 ++#define TAS5713_SYSTEM_CTRL2 0x05 ++#define TAS5713_SOFT_MUTE 0x06 ++#define TAS5713_VOL_MASTER 0x07 ++#define TAS5713_VOL_CH1 0x08 ++#define TAS5713_VOL_CH2 0x09 ++#define TAS5713_VOL_HEADPHONE 0x0A ++#define TAS5713_VOL_CONFIG 0x0E ++#define TAS5713_MODULATION_LIMIT 0x10 ++#define TAS5713_IC_DLY_CH1 0x11 ++#define TAS5713_IC_DLY_CH2 0x12 ++#define TAS5713_IC_DLY_CH3 0x13 ++#define TAS5713_IC_DLY_CH4 0x14 ++ ++#define TAS5713_START_STOP_PERIOD 0x1A ++#define TAS5713_OSC_TRIM 0x1B ++#define TAS5713_BKND_ERR 0x1C ++ ++#define TAS5713_INPUT_MUX 0x20 ++#define TAS5713_SRC_SELECT_CH4 0x21 ++#define TAS5713_PWM_MUX 0x25 ++ ++#define TAS5713_CH1_BQ0 0x29 ++#define TAS5713_CH1_BQ1 0x2A ++#define TAS5713_CH1_BQ2 0x2B ++#define TAS5713_CH1_BQ3 0x2C ++#define TAS5713_CH1_BQ4 0x2D ++#define TAS5713_CH1_BQ5 0x2E ++#define TAS5713_CH1_BQ6 0x2F ++#define TAS5713_CH1_BQ7 0x58 ++#define TAS5713_CH1_BQ8 0x59 ++ ++#define TAS5713_CH2_BQ0 0x30 ++#define TAS5713_CH2_BQ1 0x31 ++#define TAS5713_CH2_BQ2 0x32 ++#define TAS5713_CH2_BQ3 0x33 ++#define TAS5713_CH2_BQ4 0x34 ++#define TAS5713_CH2_BQ5 0x35 ++#define TAS5713_CH2_BQ6 0x36 ++#define TAS5713_CH2_BQ7 0x5C ++#define TAS5713_CH2_BQ8 0x5D ++ ++#define TAS5713_CH4_BQ0 0x5A ++#define TAS5713_CH4_BQ1 0x5B ++#define TAS5713_CH3_BQ0 0x5E ++#define TAS5713_CH3_BQ1 0x5F ++ ++#define TAS5713_DRC1_SOFTENING_FILTER_ALPHA_OMEGA 0x3B ++#define TAS5713_DRC1_ATTACK_RELEASE_RATE 0x3C ++#define TAS5713_DRC2_SOFTENING_FILTER_ALPHA_OMEGA 0x3E ++#define TAS5713_DRC2_ATTACK_RELEASE_RATE 0x3F ++#define TAS5713_DRC1_ATTACK_RELEASE_THRES 0x40 ++#define TAS5713_DRC2_ATTACK_RELEASE_THRES 0x43 ++#define TAS5713_DRC_CTRL 0x46 ++ ++#define TAS5713_BANK_SW_CTRL 0x50 ++#define TAS5713_CH1_OUTPUT_MIXER 0x51 ++#define TAS5713_CH2_OUTPUT_MIXER 0x52 ++#define TAS5713_CH1_INPUT_MIXER 0x53 ++#define TAS5713_CH2_INPUT_MIXER 0x54 ++#define TAS5713_OUTPUT_POST_SCALE 0x56 ++#define TAS5713_OUTPUT_PRESCALE 0x57 ++ ++#define TAS5713_IDF_POST_SCALE 0x62 ++ ++#define TAS5713_CH1_INLINE_MIXER 0x70 ++#define TAS5713_CH1_INLINE_DRC_EN_MIXER 0x71 ++#define TAS5713_CH1_R_CHANNEL_MIXER 0x72 ++#define TAS5713_CH1_L_CHANNEL_MIXER 0x73 ++#define TAS5713_CH2_INLINE_MIXER 0x74 ++#define TAS5713_CH2_INLINE_DRC_EN_MIXER 0x75 ++#define TAS5713_CH2_L_CHANNEL_MIXER 0x76 ++#define TAS5713_CH2_R_CHANNEL_MIXER 0x77 ++ ++#define TAS5713_UPDATE_DEV_ADDR_KEY 0xF8 ++#define TAS5713_UPDATE_DEV_ADDR_REG 0xF9 ++ ++#define TAS5713_REGISTER_COUNT 0x46 ++#define TAS5713_MAX_REGISTER 0xF9 ++ ++ ++// Bitmasks for registers ++#define TAS5713_SOFT_MUTE_ALL 0x07 ++ ++ ++ ++struct tas5713_init_command { ++ const int size; ++ const char *const data; ++}; ++ ++static const struct tas5713_init_command tas5713_init_sequence[] = { ++ ++ // Trim oscillator ++ { .size = 2, .data = "\x1B\x00" }, ++ // System control register 1 (0x03): block DC ++ { .size = 2, .data = "\x03\x80" }, ++ // Mute everything ++ { .size = 2, .data = "\x05\x40" }, ++ // Modulation limit register (0x10): 97.7% ++ { .size = 2, .data = "\x10\x02" }, ++ // Interchannel delay registers ++ // (0x11, 0x12, 0x13, and 0x14): BD mode ++ { .size = 2, .data = "\x11\xB8" }, ++ { .size = 2, .data = "\x12\x60" }, ++ { .size = 2, .data = "\x13\xA0" }, ++ { .size = 2, .data = "\x14\x48" }, ++ // PWM shutdown group register (0x19): no shutdown ++ { .size = 2, .data = "\x19\x00" }, ++ // Input multiplexer register (0x20): BD mode ++ { .size = 2, .data = "\x20\x00\x89\x77\x72" }, ++ // PWM output mux register (0x25) ++ // Channel 1 --> OUTA, channel 1 neg --> OUTB ++ // Channel 2 --> OUTC, channel 2 neg --> OUTD ++ { .size = 5, .data = "\x25\x01\x02\x13\x45" }, ++ // DRC control (0x46): DRC off ++ { .size = 5, .data = "\x46\x00\x00\x00\x00" }, ++ // BKND_ERR register (0x1C): 299ms reset period ++ { .size = 2, .data = "\x1C\x07" }, ++ // Mute channel 3 ++ { .size = 2, .data = "\x0A\xFF" }, ++ // Volume configuration register (0x0E): volume slew 512 steps ++ { .size = 2, .data = "\x0E\x90" }, ++ // Clock control register (0x00): 44/48kHz, MCLK=64xfs ++ { .size = 2, .data = "\x00\x60" }, ++ // Bank switch and eq control (0x50): no bank switching ++ { .size = 5, .data = "\x50\x00\x00\x00\x00" }, ++ // Volume registers (0x07, 0x08, 0x09, 0x0A) ++ { .size = 2, .data = "\x07\x20" }, ++ { .size = 2, .data = "\x08\x30" }, ++ { .size = 2, .data = "\x09\x30" }, ++ { .size = 2, .data = "\x0A\xFF" }, ++ // 0x72, 0x73, 0x76, 0x77 input mixer: ++ // no intermix between channels ++ { .size = 5, .data = "\x72\x00\x00\x00\x00" }, ++ { .size = 5, .data = "\x73\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x76\x00\x00\x00\x00" }, ++ { .size = 5, .data = "\x77\x00\x80\x00\x00" }, ++ // 0x70, 0x71, 0x74, 0x75 inline DRC mixer: ++ // no inline DRC inmix ++ { .size = 5, .data = "\x70\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x71\x00\x00\x00\x00" }, ++ { .size = 5, .data = "\x74\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x75\x00\x00\x00\x00" }, ++ // 0x56, 0x57 Output scale ++ { .size = 5, .data = "\x56\x00\x80\x00\x00" }, ++ { .size = 5, .data = "\x57\x00\x02\x00\x00" }, ++ // 0x3B, 0x3c ++ { .size = 9, .data = "\x3B\x00\x08\x00\x00\x00\x78\x00\x00" }, ++ { .size = 9, .data = "\x3C\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ { .size = 9, .data = "\x3E\x00\x08\x00\x00\x00\x78\x00\x00" }, ++ { .size = 9, .data = "\x3F\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ { .size = 9, .data = "\x40\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ { .size = 9, .data = "\x43\x00\x00\x01\x00\xFF\xFF\xFF\x00" }, ++ // 0x51, 0x52: output mixer ++ { .size = 9, .data = "\x51\x00\x80\x00\x00\x00\x00\x00\x00" }, ++ { .size = 9, .data = "\x52\x00\x80\x00\x00\x00\x00\x00\x00" }, ++ // PEQ defaults ++ { .size = 21, .data = "\x29\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x2F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x30\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x31\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x32\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x33\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x34\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x35\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x36\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x58\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x59\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5C\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5D\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5E\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5F\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5A\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++ { .size = 21, .data = "\x5B\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }, ++}; ++ ++ ++#endif /* _TAS5713_H */ + +From 06c9b132b1340b495048f8814be13fe71b5cd77e Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Mon, 13 Apr 2015 19:14:18 +0100 +Subject: [PATCH 50/77] bcm2708: Allow option card devices to be configured via + DT + +If the kernel is built with Device Tree support, and if a DT blob +is provided for the kernel at boot time, then the platform devices +for option cards are not created. This avoids both the need to +blacklist unwanted devices, and the need to update the board +support code with each new device. +--- + sound/soc/bcm/bcm2835-i2s.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c +index 03fa1cb..c816526 100644 +--- a/sound/soc/bcm/bcm2835-i2s.c ++++ b/sound/soc/bcm/bcm2835-i2s.c +@@ -861,6 +861,7 @@ static const struct of_device_id bcm2835_i2s_of_match[] = { + { .compatible = "brcm,bcm2835-i2s", }, + {}, + }; ++MODULE_DEVICE_TABLE(of, bcm2835_i2s_of_match); + + static struct platform_driver bcm2835_i2s_driver = { + .probe = bcm2835_i2s_probe, + +From a9fff3c9005e6658977bd5e7df92114e70e1f813 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Mon, 13 Apr 2015 18:45:39 +0100 +Subject: [PATCH 51/77] Adding Device Tree support for some RPi audio cards + +--- + arch/arm/mach-bcm2709/bcm2709.c | 143 ++++++++++++++++++++++++++++++++++++++ + sound/soc/bcm/hifiberry_dac.c | 22 ++++++ + sound/soc/bcm/hifiberry_dacplus.c | 22 ++++++ + sound/soc/bcm/hifiberry_digi.c | 22 ++++++ + sound/soc/bcm/iqaudio-dac.c | 16 +++++ + sound/soc/codecs/pcm5102a.c | 7 ++ + 6 files changed, 232 insertions(+) + +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 03e208b..2ae79d9 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -636,6 +636,115 @@ static struct platform_device bcm2835_thermal_device = { + .name = "bcm2835_thermal", + }; + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++static struct resource bcm2708_i2s_resources[] = { ++ { ++ .start = I2S_BASE, ++ .end = I2S_BASE + 0x20, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = PCM_CLOCK_BASE, ++ .end = PCM_CLOCK_BASE + 0x02, ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device bcm2708_i2s_device = { ++ .name = "bcm2708-i2s", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(bcm2708_i2s_resources), ++ .resource = bcm2708_i2s_resources, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++static struct platform_device snd_hifiberry_dac_device = { ++ .name = "snd-hifiberry-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm5102a_codec_device = { ++ .name = "pcm5102a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++static struct platform_device snd_rpi_hifiberry_dacplus_device = { ++ .name = "snd-rpi-hifiberry-dacplus", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_pcm512x_hbdacplus_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4d) ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++static struct platform_device snd_hifiberry_digi_device = { ++ .name = "snd-hifiberry-digi", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_wm8804_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("wm8804", 0x3b) ++ }, ++}; ++ ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++static struct platform_device snd_hifiberry_amp_device = { ++ .name = "snd-hifiberry-amp", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct i2c_board_info __initdata snd_tas5713_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("tas5713", 0x1b) ++ }, ++}; ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++static struct platform_device snd_rpi_dac_device = { ++ .name = "snd-rpi-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++static struct platform_device snd_pcm1794a_codec_device = { ++ .name = "pcm1794a-codec", ++ .id = -1, ++ .num_resources = 0, ++}; ++#endif ++ ++ ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++static struct platform_device snd_rpi_iqaudio_dac_device = { ++ .name = "snd-rpi-iqaudio-dac", ++ .id = 0, ++ .num_resources = 0, ++}; ++ ++// Use the actual device name rather than generic driver name ++static struct i2c_board_info __initdata snd_pcm512x_i2c_devices[] = { ++ { ++ I2C_BOARD_INFO("pcm5122", 0x4c) ++ }, ++}; ++#endif ++ + int __init bcm_register_device(struct platform_device *pdev) + { + int ret; +@@ -800,6 +909,40 @@ void __init bcm2709_init(void) + + bcm_register_device_dt(&bcm2835_thermal_device); + ++#if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) ++ bcm_register_device_dt(&bcm2708_i2s_device); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_dac_device); ++ bcm_register_device_dt(&snd_pcm5102a_codec_device); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS_MODULE) ++ bcm_register_device_dt(&snd_rpi_hifiberry_dacplus_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_hbdacplus_i2c_devices, ARRAY_SIZE(snd_pcm512x_hbdacplus_i2c_devices)); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_digi_device); ++ i2c_register_board_info_dt(1, snd_wm8804_i2c_devices, ARRAY_SIZE(snd_wm8804_i2c_devices)); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP) || defined(CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP_MODULE) ++ bcm_register_device_dt(&snd_hifiberry_amp_device); ++ i2c_register_board_info_dt(1, snd_tas5713_i2c_devices, ARRAY_SIZE(snd_tas5713_i2c_devices)); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_RPI_DAC) || defined(CONFIG_SND_BCM2708_SOC_RPI_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_dac_device); ++ bcm_register_device_dt(&snd_pcm1794a_codec_device); ++#endif ++ ++#if defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) || defined(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC_MODULE) ++ bcm_register_device_dt(&snd_rpi_iqaudio_dac_device); ++ i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); ++#endif ++ + if (!use_dt) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; +diff --git a/sound/soc/bcm/hifiberry_dac.c b/sound/soc/bcm/hifiberry_dac.c +index 4b70b45..3ab0f47 100644 +--- a/sound/soc/bcm/hifiberry_dac.c ++++ b/sound/soc/bcm/hifiberry_dac.c +@@ -72,6 +72,21 @@ static int snd_rpi_hifiberry_dac_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_hifiberry_dac.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dac_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_hifiberry_dac); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); +@@ -84,10 +99,17 @@ static int snd_rpi_hifiberry_dac_remove(struct platform_device *pdev) + return snd_soc_unregister_card(&snd_rpi_hifiberry_dac); + } + ++static const struct of_device_id snd_rpi_hifiberry_dac_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-dac", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dac_of_match); ++ + static struct platform_driver snd_rpi_hifiberry_dac_driver = { + .driver = { + .name = "snd-hifiberry-dac", + .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_dac_of_match, + }, + .probe = snd_rpi_hifiberry_dac_probe, + .remove = snd_rpi_hifiberry_dac_remove, +diff --git a/sound/soc/bcm/hifiberry_dacplus.c b/sound/soc/bcm/hifiberry_dacplus.c +index c63387b..11e4f39 100644 +--- a/sound/soc/bcm/hifiberry_dacplus.c ++++ b/sound/soc/bcm/hifiberry_dacplus.c +@@ -90,6 +90,21 @@ static int snd_rpi_hifiberry_dacplus_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_hifiberry_dacplus.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_dacplus_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_hifiberry_dacplus); + if (ret) + dev_err(&pdev->dev, +@@ -103,10 +118,17 @@ static int snd_rpi_hifiberry_dacplus_remove(struct platform_device *pdev) + return snd_soc_unregister_card(&snd_rpi_hifiberry_dacplus); + } + ++static const struct of_device_id snd_rpi_hifiberry_dacplus_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-dacplus", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_dacplus_of_match); ++ + static struct platform_driver snd_rpi_hifiberry_dacplus_driver = { + .driver = { + .name = "snd-rpi-hifiberry-dacplus", + .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_dacplus_of_match, + }, + .probe = snd_rpi_hifiberry_dacplus_probe, + .remove = snd_rpi_hifiberry_dacplus_remove, +diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c +index 92e9e46..80732b8 100644 +--- a/sound/soc/bcm/hifiberry_digi.c ++++ b/sound/soc/bcm/hifiberry_digi.c +@@ -173,6 +173,21 @@ static int snd_rpi_hifiberry_digi_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_hifiberry_digi.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_digi_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_hifiberry_digi); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", ret); +@@ -185,10 +200,17 @@ static int snd_rpi_hifiberry_digi_remove(struct platform_device *pdev) + return snd_soc_unregister_card(&snd_rpi_hifiberry_digi); + } + ++static const struct of_device_id snd_rpi_hifiberry_digi_of_match[] = { ++ { .compatible = "hifiberry,hifiberry-digi", }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_digi_of_match); ++ + static struct platform_driver snd_rpi_hifiberry_digi_driver = { + .driver = { + .name = "snd-hifiberry-digi", + .owner = THIS_MODULE, ++ .of_match_table = snd_rpi_hifiberry_digi_of_match, + }, + .probe = snd_rpi_hifiberry_digi_probe, + .remove = snd_rpi_hifiberry_digi_remove, +diff --git a/sound/soc/bcm/iqaudio-dac.c b/sound/soc/bcm/iqaudio-dac.c +index aff7377..a38e874 100644 +--- a/sound/soc/bcm/iqaudio-dac.c ++++ b/sound/soc/bcm/iqaudio-dac.c +@@ -82,6 +82,21 @@ static int snd_rpi_iqaudio_dac_probe(struct platform_device *pdev) + int ret = 0; + + snd_rpi_iqaudio_dac.dev = &pdev->dev; ++ ++ if (pdev->dev.of_node) { ++ struct device_node *i2s_node; ++ struct snd_soc_dai_link *dai = &snd_rpi_iqaudio_dac_dai[0]; ++ i2s_node = of_parse_phandle(pdev->dev.of_node, ++ "i2s-controller", 0); ++ ++ if (i2s_node) { ++ dai->cpu_dai_name = NULL; ++ dai->cpu_of_node = i2s_node; ++ dai->platform_name = NULL; ++ dai->platform_of_node = i2s_node; ++ } ++ } ++ + ret = snd_soc_register_card(&snd_rpi_iqaudio_dac); + if (ret) + dev_err(&pdev->dev, +@@ -99,6 +114,7 @@ static const struct of_device_id iqaudio_of_match[] = { + { .compatible = "iqaudio,iqaudio-dac", }, + {}, + }; ++MODULE_DEVICE_TABLE(of, iqaudio_of_match); + + static struct platform_driver snd_rpi_iqaudio_dac_driver = { + .driver = { +diff --git a/sound/soc/codecs/pcm5102a.c b/sound/soc/codecs/pcm5102a.c +index 126f1e9..7c6598e 100644 +--- a/sound/soc/codecs/pcm5102a.c ++++ b/sound/soc/codecs/pcm5102a.c +@@ -47,12 +47,19 @@ static int pcm5102a_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id pcm5102a_of_match[] = { ++ { .compatible = "ti,pcm5102a", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, pcm5102a_of_match); ++ + static struct platform_driver pcm5102a_codec_driver = { + .probe = pcm5102a_probe, + .remove = pcm5102a_remove, + .driver = { + .name = "pcm5102a-codec", + .owner = THIS_MODULE, ++ .of_match_table = pcm5102a_of_match, + }, + }; + + +From 9518bd237c4fb516a0ec78f7ec81e5784f8425e0 Mon Sep 17 00:00:00 2001 +From: Timo Kokkonen +Date: Wed, 29 Oct 2014 23:30:30 -0700 +Subject: [PATCH 52/77] Added support to reserve/enable a GPIO pin to be used + from pps-gpio module (LinuxPPS). Enable PPS modules in default config for + RPi. + +--- + arch/arm/mach-bcm2708/bcm2708.c | 27 +++++++++++++++++++++++++++ + arch/arm/mach-bcm2709/bcm2709.c | 27 +++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + +diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c +index 785cf1a..e42f5a5 100644 +--- a/arch/arm/mach-bcm2708/bcm2708.c ++++ b/arch/arm/mach-bcm2708/bcm2708.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -92,6 +93,7 @@ static unsigned reboot_part = 0; + static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; ++static int pps_gpio_pin = -1; + + static unsigned use_dt = 0; + +@@ -325,6 +327,19 @@ static struct platform_device w1_device = { + }; + #endif + ++static struct pps_gpio_platform_data pps_gpio_info = { ++ .assert_falling_edge = false, ++ .capture_clear = false, ++ .gpio_pin = -1, ++ .gpio_label = "PPS", ++}; ++ ++static struct platform_device pps_gpio_device = { ++ .name = "pps-gpio", ++ .id = PLATFORM_DEVID_NONE, ++ .dev.platform_data = &pps_gpio_info, ++}; ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -860,6 +875,16 @@ void __init bcm2708_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++ ++#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) ++ if (!use_dt && (pps_gpio_pin >= 0)) { ++ pr_info("bcm2708: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); ++ pps_gpio_info.gpio_pin = pps_gpio_pin; ++ pps_gpio_device.id = pps_gpio_pin; ++ bcm_register_device(&pps_gpio_device); ++ } ++#endif ++ + #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + w1_gpio_pdata.pin = w1_gpio_pin; + w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; +@@ -1116,3 +1141,5 @@ module_param(w1_gpio_pin, uint, 0644); + module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); ++module_param(pps_gpio_pin, int, 0644); ++MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); +diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c +index 2ae79d9..95223ff 100644 +--- a/arch/arm/mach-bcm2709/bcm2709.c ++++ b/arch/arm/mach-bcm2709/bcm2709.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -94,6 +95,7 @@ static unsigned reboot_part = 0; + static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; ++static int pps_gpio_pin = -1; + + static unsigned use_dt = 0; + +@@ -335,6 +337,19 @@ static struct platform_device w1_device = { + }; + #endif + ++static struct pps_gpio_platform_data pps_gpio_info = { ++ .assert_falling_edge = false, ++ .capture_clear = false, ++ .gpio_pin = -1, ++ .gpio_label = "PPS", ++}; ++ ++static struct platform_device pps_gpio_device = { ++ .name = "pps-gpio", ++ .id = PLATFORM_DEVID_NONE, ++ .dev.platform_data = &pps_gpio_info, ++}; ++ + static u64 fb_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); + + static struct platform_device bcm2708_fb_device = { +@@ -880,6 +895,16 @@ void __init bcm2709_init(void) + #ifdef CONFIG_BCM2708_GPIO + bcm_register_device_dt(&bcm2708_gpio_device); + #endif ++ ++#if defined(CONFIG_PPS_CLIENT_GPIO) || defined(CONFIG_PPS_CLIENT_GPIO_MODULE) ++ if (!use_dt && (pps_gpio_pin >= 0)) { ++ pr_info("bcm2709: GPIO %d setup as pps-gpio device\n", pps_gpio_pin); ++ pps_gpio_info.gpio_pin = pps_gpio_pin; ++ pps_gpio_device.id = pps_gpio_pin; ++ bcm_register_device(&pps_gpio_device); ++ } ++#endif ++ + #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) + w1_gpio_pdata.pin = w1_gpio_pin; + w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; +@@ -1284,3 +1309,5 @@ module_param(w1_gpio_pin, uint, 0644); + module_param(w1_gpio_pullup, uint, 0644); + module_param(vc_i2c_override, bool, 0644); + MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral."); ++module_param(pps_gpio_pin, int, 0644); ++MODULE_PARM_DESC(pps_gpio_pin, "Set GPIO pin to reserve for PPS"); + +From 6831eded602a01774036cb24d3195dbbd51f9135 Mon Sep 17 00:00:00 2001 +From: Ryan Coe +Date: Sat, 31 Jan 2015 18:25:49 -0700 +Subject: [PATCH 53/77] Update ds1307 driver for device-tree support + +Signed-off-by: Ryan Coe +--- + drivers/rtc/rtc-ds1307.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c +index 4ffabb3..c6789a7 100644 +--- a/drivers/rtc/rtc-ds1307.c ++++ b/drivers/rtc/rtc-ds1307.c +@@ -1242,6 +1242,14 @@ static int ds1307_remove(struct i2c_client *client) + return 0; + } + ++#ifdef CONFIG_OF ++static const struct of_device_id ds1307_of_match[] = { ++ { .compatible = "maxim,ds1307" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, ds1307_of_match); ++#endif ++ + static struct i2c_driver ds1307_driver = { + .driver = { + .name = "rtc-ds1307", + +From 47ca2482bc03a888435d35139cd2f5989354ee1b Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Fri, 6 Feb 2015 13:50:57 +0000 +Subject: [PATCH 54/77] BCM270x_DT: Add pwr_led, and the required "input" + trigger + +The "input" trigger makes the associated GPIO an input. This is to support +the Raspberry Pi PWR LED, which is driven by external hardware in normal use. + +N.B. pwr_led is not available on Model A or B boards. +--- + drivers/leds/trigger/Kconfig | 7 ++++ + drivers/leds/trigger/Makefile | 1 + + drivers/leds/trigger/ledtrig-input.c | 65 ++++++++++++++++++++++++++++++++++++ + 3 files changed, 73 insertions(+) + create mode 100644 drivers/leds/trigger/ledtrig-input.c + diff --git a/drivers/leds/trigger/Kconfig b/drivers/leds/trigger/Kconfig index 49794b4..640756b 100644 --- a/drivers/leds/trigger/Kconfig @@ -124668,10 +127463,10 @@ index 0000000..2ca2b98 +MODULE_DESCRIPTION("Set LED GPIO to Input \"trigger\""); +MODULE_LICENSE("GPL"); -From be825a324f0b4e90f3fc396b0ed17442c5cb771d Mon Sep 17 00:00:00 2001 +From 38c278bba1388423ba1508d0712babb717685530 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 20 Jun 2014 17:19:27 +0100 -Subject: [PATCH 072/216] bcm2709: Simplify and strip down IRQ handler +Subject: [PATCH 55/77] bcm2709: Simplify and strip down IRQ handler --- arch/arm/include/asm/entry-macro-multi.S | 2 + @@ -124890,737 +127685,10 @@ index d08591b..08d184c 100644 +1: get_irqnr_and_base r0, r2, r6, lr + .endm -From 219ae1b83de018ba2a3e3d909c0cbfce14579c14 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Tue, 3 Feb 2015 07:15:19 +0100 -Subject: [PATCH 073/216] HiFiBerry Amp: fix device-tree problems - -Some code to load the driver based on device-tree-overlays was missing. This is added by this patch. ---- - sound/soc/bcm/hifiberry_amp.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/sound/soc/bcm/hifiberry_amp.c b/sound/soc/bcm/hifiberry_amp.c -index 1e87ee06..5903915 100644 ---- a/sound/soc/bcm/hifiberry_amp.c -+++ b/sound/soc/bcm/hifiberry_amp.c -@@ -65,6 +65,12 @@ static struct snd_soc_card snd_rpi_hifiberry_amp = { - .num_links = ARRAY_SIZE(snd_rpi_hifiberry_amp_dai), - }; - -+static const struct of_device_id snd_rpi_hifiberry_amp_of_match[] = { -+ { .compatible = "hifiberry,hifiberry-amp", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_rpi_hifiberry_amp_of_match); -+ - - static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) - { -@@ -72,6 +78,20 @@ static int snd_rpi_hifiberry_amp_probe(struct platform_device *pdev) - - snd_rpi_hifiberry_amp.dev = &pdev->dev; - -+ if (pdev->dev.of_node) { -+ struct device_node *i2s_node; -+ struct snd_soc_dai_link *dai = &snd_rpi_hifiberry_amp_dai[0]; -+ i2s_node = of_parse_phandle(pdev->dev.of_node, -+ "i2s-controller", 0); -+ -+ if (i2s_node) { -+ dai->cpu_dai_name = NULL; -+ dai->cpu_of_node = i2s_node; -+ dai->platform_name = NULL; -+ dai->platform_of_node = i2s_node; -+ } -+ } -+ - ret = snd_soc_register_card(&snd_rpi_hifiberry_amp); - - if (ret != 0) { -@@ -92,6 +112,7 @@ static struct platform_driver snd_rpi_hifiberry_amp_driver = { - .driver = { - .name = "snd-hifiberry-amp", - .owner = THIS_MODULE, -+ .of_match_table = snd_rpi_hifiberry_amp_of_match, - }, - .probe = snd_rpi_hifiberry_amp_probe, - .remove = snd_rpi_hifiberry_amp_remove, - -From 81042a79740e7b0c61fcbfa97e76c3d97c40b630 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 3 Feb 2015 11:41:38 +0000 -Subject: [PATCH 074/216] BCM270x_DT: Add i2c0_baudrate and i2c1_baudrate - parameters - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index b409c2c..7f84473 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -103,6 +103,8 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 1ecd1a1..a39562f 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -97,6 +97,8 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 46f4908..75c222f 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -103,6 +103,8 @@ - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; - i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; - - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - -From 4ff8b4c54db8215c8daa7a1d70c623b642143f16 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 4 Feb 2015 10:02:24 +0000 -Subject: [PATCH 075/216] pinctrl-bcm2835: bcm2835_gpio_direction_output must - set the value - ---- - drivers/pinctrl/pinctrl-bcm2835.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index 9d1149e..d9c727b 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -355,7 +355,14 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) - static int bcm2835_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) - { -- return pinctrl_gpio_direction_output(chip->base + offset); -+ struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); -+ int ret; -+ -+ ret = pinctrl_gpio_direction_output(chip->base + offset); -+ if (ret >= 0) -+ bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset); -+ -+ return ret; - } - - static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) - -From 1184251f953b0cd578ee44fa36d67f7f9091e6a5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 4 Feb 2015 12:59:36 +0000 -Subject: [PATCH 076/216] w1-gpio: Sort out the pullup/parasitic power tangle - ---- - arch/arm/boot/dts/w1-gpio-overlay.dts | 4 +++- - arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 6 +++-- - drivers/w1/masters/w1-gpio.c | 36 ++++++++++++++++++---------- - include/linux/w1-gpio.h | 1 + - 4 files changed, 32 insertions(+), 15 deletions(-) - -diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts -index b2c5ee2..29a3b48 100644 ---- a/arch/arm/boot/dts/w1-gpio-overlay.dts -+++ b/arch/arm/boot/dts/w1-gpio-overlay.dts -@@ -1,4 +1,4 @@ --// Definitions for lirc-rpi module -+// Definitions for w1-gpio module (without external pullup) - /dts-v1/; - /plugin/; - -@@ -14,6 +14,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&w1_pins>; - gpios = <&gpio 4 0>; -+ rpi,parasitic-power = <0>; - status = "okay"; - }; - }; -@@ -33,5 +34,6 @@ - __overrides__ { - gpiopin = <&w1>,"gpios:4", - <&w1_pins>,"brcm,pins:0"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; - }; - }; -diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -index b3e97c2..66a98f6 100644 ---- a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -+++ b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -@@ -1,4 +1,4 @@ --// Definitions for lirc-rpi module -+// Definitions for w1-gpio module (with external pullup) - /dts-v1/; - /plugin/; - -@@ -14,6 +14,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&w1_pins>; - gpios = <&gpio 4 0>, <&gpio 5 1>; -+ rpi,parasitic-power = <0>; - status = "okay"; - }; - }; -@@ -33,7 +34,8 @@ - __overrides__ { - gpiopin = <&w1>,"gpios:4", - <&w1_pins>,"brcm,pins:0"; -- pullup = <&w1>,"gpios:16", -+ extpullup = <&w1>,"gpios:16", - <&w1_pins>,"brcm,pins:4"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; - }; - }; -diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c -index 3ad15cc..e34d418 100644 ---- a/drivers/w1/masters/w1-gpio.c -+++ b/drivers/w1/masters/w1-gpio.c -@@ -23,10 +23,14 @@ - #include "../w1.h" - #include "../w1_int.h" - --static int w1_gpio_pullup = -1; --static int w1_gpio_pullup_orig = -1; -+static int w1_gpio_pullup = 0; -+static int w1_gpio_pullup_orig = 0; - module_param_named(pullup, w1_gpio_pullup, int, 0); --MODULE_PARM_DESC(pullup, "GPIO pin pullup number"); -+MODULE_PARM_DESC(pullup, "Enable parasitic power (power on data) mode"); -+static int w1_gpio_pullup_pin = -1; -+static int w1_gpio_pullup_pin_orig = -1; -+module_param_named(extpullup, w1_gpio_pullup_pin, int, 0); -+MODULE_PARM_DESC(extpullup, "GPIO external pullup pin number"); - static int w1_gpio_pin = -1; - static int w1_gpio_pin_orig = -1; - module_param_named(gpiopin, w1_gpio_pin, int, 0); -@@ -99,6 +103,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; - int gpio; -+ u32 value; - - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) -@@ -107,6 +112,9 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - if (of_get_property(np, "linux,open-drain", NULL)) - pdata->is_open_drain = 1; - -+ if (of_property_read_u32(np, "rpi,parasitic-power", &value) == 0) -+ pdata->parasitic_power = (value != 0); -+ - gpio = of_get_gpio(np, 0); - if (gpio < 0) { - if (gpio != -EPROBE_DEFER) -@@ -122,7 +130,7 @@ static int w1_gpio_probe_dt(struct platform_device *pdev) - if (gpio == -EPROBE_DEFER) - return gpio; - /* ignore other errors as the pullup gpio is optional */ -- pdata->ext_pullup_enable_pin = gpio; -+ pdata->ext_pullup_enable_pin = (gpio >= 0) ? gpio : -1; - - pdev->dev.platform_data = pdata; - -@@ -158,17 +166,20 @@ static int w1_gpio_probe(struct platform_device *pdev) - } - - w1_gpio_pin_orig = pdata->pin; -- w1_gpio_pullup_orig = pdata->ext_pullup_enable_pin; -+ w1_gpio_pullup_pin_orig = pdata->ext_pullup_enable_pin; -+ w1_gpio_pullup_orig = pdata->parasitic_power; - - if(gpio_is_valid(w1_gpio_pin)) { - pdata->pin = w1_gpio_pin; - pdata->ext_pullup_enable_pin = -1; -+ pdata->parasitic_power = -1; - } -- if(gpio_is_valid(w1_gpio_pullup)) { -- pdata->ext_pullup_enable_pin = w1_gpio_pullup; -+ pdata->parasitic_power |= w1_gpio_pullup; -+ if(gpio_is_valid(w1_gpio_pullup_pin)) { -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin; - } - -- dev_info(&pdev->dev, "gpio pin %d, gpio pullup pin %d\n", pdata->pin, pdata->ext_pullup_enable_pin); -+ dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power); - - err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); - if (err) { -@@ -199,10 +210,10 @@ static int w1_gpio_probe(struct platform_device *pdev) - master->set_pullup = w1_gpio_set_pullup; - } - -- if (gpio_is_valid(w1_gpio_pullup)) { -+ if (pdata->parasitic_power) { - if (pdata->is_open_drain) -- printk(KERN_ERR "w1-gpio 'pullup' option " -- "doesn't work with open drain GPIO\n"); -+ printk(KERN_ERR "w1-gpio 'pullup'(parasitic power) " -+ "option doesn't work with open drain GPIO\n"); - else - master->bitbang_pullup = w1_gpio_bitbang_pullup; - } -@@ -238,7 +249,8 @@ static int w1_gpio_remove(struct platform_device *pdev) - w1_remove_master_device(master); - - pdata->pin = w1_gpio_pin_orig; -- pdata->ext_pullup_enable_pin = w1_gpio_pullup_orig; -+ pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin_orig; -+ pdata->parasitic_power = w1_gpio_pullup_orig; - - return 0; - } -diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h -index d58594a..feae942 100644 ---- a/include/linux/w1-gpio.h -+++ b/include/linux/w1-gpio.h -@@ -18,6 +18,7 @@ - struct w1_gpio_platform_data { - unsigned int pin; - unsigned int is_open_drain:1; -+ unsigned int parasitic_power:1; - void (*enable_external_pullup)(int enable); - unsigned int ext_pullup_enable_pin; - unsigned int pullup_duration; - -From a0d0e3ba49f5daa0ece5234cdf688fb490ee15a7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 5 Feb 2015 16:01:44 +0000 -Subject: [PATCH 077/216] i2c_bcm2708: Fix clock reference counting - ---- - drivers/i2c/busses/i2c-bcm2708.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 526129b..fda59ba 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -337,11 +337,17 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - return PTR_ERR(clk); - } - -+ err = clk_prepare_enable(clk); -+ if (err) { -+ dev_err(&pdev->dev, "could not enable clk: %d\n", err); -+ goto out_clk_put; -+ } -+ - bcm2708_i2c_init_pinmode(pdev->id); - - bi = kzalloc(sizeof(*bi), GFP_KERNEL); - if (!bi) -- goto out_clk_put; -+ goto out_clk_disable; - - platform_set_drvdata(pdev, bi); - -@@ -412,6 +418,8 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - iounmap(bi->base); - out_free_bi: - kfree(bi); -+out_clk_disable: -+ clk_disable_unprepare(clk); - out_clk_put: - clk_put(clk); - return err; -@@ -426,7 +434,7 @@ static int bcm2708_i2c_remove(struct platform_device *pdev) - i2c_del_adapter(&bi->adapter); - free_irq(bi->irq, bi); - iounmap(bi->base); -- clk_disable(bi->clk); -+ clk_disable_unprepare(bi->clk); - clk_put(bi->clk); - kfree(bi); - - -From dffb6179317e46f3f2d60c62b6b4c6c1008990ef Mon Sep 17 00:00:00 2001 -From: Byron Bradley -Date: Fri, 6 Feb 2015 14:19:41 +0000 -Subject: [PATCH 078/216] Add device-tree overlay for pcf2127 - -Signed-off-by: Byron Bradley ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pcf2127-rtc-overlay.dts | 22 ++++++++++++++++++++++ - 2 files changed, 23 insertions(+) - create mode 100644 arch/arm/boot/dts/pcf2127-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 7755a84..6cb743a 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -20,6 +20,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -diff --git a/arch/arm/boot/dts/pcf2127-rtc-overlay.dts b/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -new file mode 100644 -index 0000000..01fc81d ---- /dev/null -+++ b/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF2127 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; - -From 6547e99ab9f5be7bc839f36becfc18e6dd879d0d Mon Sep 17 00:00:00 2001 -From: android -Date: Mon, 25 Aug 2014 13:18:21 +0100 -Subject: [PATCH 079/216] BCM2708_VCIO : Add automatic creation of device node - ---- - arch/arm/mach-bcm2708/vcio.c | 12 +++++++++++- - arch/arm/mach-bcm2709/vcio.c | 12 +++++++++++- - 2 files changed, 22 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 5e43e85..700bff4 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -61,7 +61,7 @@ - #define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) - - #define MBOX_MAGIC 0xd0d0c0de -- -+static struct class *vcio_class = NULL; - struct vc_mailbox { - struct device *dev; /* parent device */ - void __iomem *status; -@@ -421,6 +421,13 @@ static int bcm_vcio_probe(struct platform_device *pdev) - "Failed registering the character device %d\n", ret); - return ret; - } -+ vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ return ret ; -+ } -+ device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); - } - return ret; - } -@@ -462,6 +469,9 @@ static int __init bcm_mbox_init(void) - - static void __exit bcm_mbox_exit(void) - { -+ device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - } - -diff --git a/arch/arm/mach-bcm2709/vcio.c b/arch/arm/mach-bcm2709/vcio.c -index 5e43e85..700bff4 100644 ---- a/arch/arm/mach-bcm2709/vcio.c -+++ b/arch/arm/mach-bcm2709/vcio.c -@@ -61,7 +61,7 @@ - #define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) - - #define MBOX_MAGIC 0xd0d0c0de -- -+static struct class *vcio_class = NULL; - struct vc_mailbox { - struct device *dev; /* parent device */ - void __iomem *status; -@@ -421,6 +421,13 @@ static int bcm_vcio_probe(struct platform_device *pdev) - "Failed registering the character device %d\n", ret); - return ret; - } -+ vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ return ret ; -+ } -+ device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); - } - return ret; - } -@@ -462,6 +469,9 @@ static int __init bcm_mbox_init(void) - - static void __exit bcm_mbox_exit(void) - { -+ device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - } - - -From 05b37dedc10f2da009b868c101623c742eda1c3f Mon Sep 17 00:00:00 2001 -From: jeanleflambeur -Date: Sun, 1 Feb 2015 12:35:38 +0100 -Subject: [PATCH 080/216] Fix grabbing lock from atomic context in i2c driver - -2 main changes: -- check for timeouts in the bcm2708_bsc_setup function as indicated by this comment: - /* poll for transfer start bit (should only take 1-20 polls) */ - This implies that the setup function can now fail so account for this everywhere it's called -- Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock. - -removed dead code and update comment - -fixed typo in comment ---- - drivers/i2c/busses/i2c-bcm2708.c | 90 +++++++++++++++++++++++++++++----------- - 1 file changed, 65 insertions(+), 25 deletions(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index fda59ba..81e9374 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -68,6 +68,7 @@ - #define BSC_S_TA 0x00000001 - - #define I2C_TIMEOUT_MS 150 -+#define I2C_WAIT_LOOP_COUNT 40 - - #define DRV_NAME "bcm2708_i2c" - -@@ -86,6 +87,7 @@ struct bcm2708_i2c { - void __iomem *base; - int irq; - struct clk *clk; -+ u32 cdiv; - - struct completion done; - -@@ -109,10 +111,10 @@ static void bcm2708_i2c_init_pinmode(int id) - int pin; - u32 *gpio = ioremap(GPIO_BASE, SZ_16K); - -- BUG_ON(id != 0 && id != 1); -+ BUG_ON(id != 0 && id != 1); - /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */ - for (pin = id*2+0; pin <= id*2+1; pin++) { --printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); -+ printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin); - INP_GPIO(pin); /* set mode to GPIO input first */ - SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */ - } -@@ -151,16 +153,16 @@ static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi) - bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); - } - --static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) -+static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi) - { -- unsigned long bus_hz; - u32 cdiv, s; - u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1; -+ int wait_loops = I2C_WAIT_LOOP_COUNT; - -- bus_hz = clk_get_rate(bi->clk); -- cdiv = bus_hz / baudrate; -- if (cdiv > 0xffff) -- cdiv = 0xffff; -+ /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked. -+ * Use the value that we cached in the probe. -+ */ -+ cdiv = bi->cdiv; - - if (bi->msg->flags & I2C_M_RD) - c |= BSC_C_INTR | BSC_C_READ; -@@ -177,17 +179,25 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) - - Both messages to same slave address - - Write message can fit inside FIFO (16 bytes or less) */ - if ( (bi->nmsgs > 1) && -- !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && -- (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { -+ !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) && -+ (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) { - /* Fill FIFO with entire write message (16 byte FIFO) */ -- while (bi->pos < bi->msg->len) -+ while (bi->pos < bi->msg->len) { - bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]); -+ } - /* Start write transfer (no interrupts, don't clear FIFO) */ - bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST); -+ - /* poll for transfer start bit (should only take 1-20 polls) */ - do { - s = bcm2708_rd(bi, BSC_S); -- } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE))); -+ } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0); -+ -+ /* did we time out or some error occured? */ -+ if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) { -+ return -1; -+ } -+ - /* Send next read message before the write transfer finishes. */ - bi->nmsgs--; - bi->msg++; -@@ -197,6 +207,8 @@ static inline void bcm2708_bsc_setup(struct bcm2708_i2c *bi) - } - } - bcm2708_wr(bi, BSC_C, c); -+ -+ return 0; - } - - static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) -@@ -204,13 +216,15 @@ static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) - struct bcm2708_i2c *bi = dev_id; - bool handled = true; - u32 s; -+ int ret; - - spin_lock(&bi->lock); - - /* we may see camera interrupts on the "other" I2C channel -- Just return if we've not sent anything */ -- if (!bi->nmsgs || !bi->msg ) -+ Just return if we've not sent anything */ -+ if (!bi->nmsgs || !bi->msg) { - goto early_exit; -+ } - - s = bcm2708_rd(bi, BSC_S); - -@@ -218,13 +232,16 @@ static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) - bcm2708_bsc_reset(bi); - bi->error = true; - -+ bi->msg = 0; /* to inform the that all work is done */ -+ bi->nmsgs = 0; - /* wake up our bh */ - complete(&bi->done); - } else if (s & BSC_S_DONE) { - bi->nmsgs--; - -- if (bi->msg->flags & I2C_M_RD) -+ if (bi->msg->flags & I2C_M_RD) { - bcm2708_bsc_fifo_drain(bi); -+ } - - bcm2708_bsc_reset(bi); - -@@ -232,8 +249,19 @@ static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id) - /* advance to next message */ - bi->msg++; - bi->pos = 0; -- bcm2708_bsc_setup(bi); -+ ret = bcm2708_bsc_setup(bi); -+ if (ret < 0) { -+ bcm2708_bsc_reset(bi); -+ bi->error = true; -+ bi->msg = 0; /* to inform the that all work is done */ -+ bi->nmsgs = 0; -+ /* wake up our bh */ -+ complete(&bi->done); -+ goto early_exit; -+ } - } else { -+ bi->msg = 0; /* to inform the that all work is done */ -+ bi->nmsgs = 0; - /* wake up our bh */ - complete(&bi->done); - } -@@ -266,22 +294,33 @@ static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap, - bi->nmsgs = num; - bi->error = false; - -- bcm2708_bsc_setup(bi); -+ ret = bcm2708_bsc_setup(bi); - -- /* unlockig _after_ the setup to avoid races with the interrupt routine */ - spin_unlock_irqrestore(&bi->lock, flags); - -- ret = wait_for_completion_timeout(&bi->done, -- msecs_to_jiffies(I2C_TIMEOUT_MS)); -+ /* check the result of the setup */ -+ if (ret < 0) -+ { -+ dev_err(&adap->dev, "transfer setup timed out\n"); -+ goto error_timeout; -+ } -+ -+ ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS)); - if (ret == 0) { - dev_err(&adap->dev, "transfer timed out\n"); -- spin_lock_irqsave(&bi->lock, flags); -- bcm2708_bsc_reset(bi); -- spin_unlock_irqrestore(&bi->lock, flags); -- return -ETIMEDOUT; -+ goto error_timeout; - } - -- return bi->error ? -EIO : num; -+ ret = bi->error ? -EIO : num; -+ return ret; -+ -+error_timeout: -+ spin_lock_irqsave(&bi->lock, flags); -+ bcm2708_bsc_reset(bi); -+ bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */ -+ bi->nmsgs = 0; -+ spin_unlock_irqrestore(&bi->lock, flags); -+ return -ETIMEDOUT; - } - - static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap) -@@ -406,6 +445,7 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - cdiv = 0xffff; - baudrate = bus_hz / cdiv; - } -+ bi->cdiv = cdiv; - - dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n", - pdev->id, (unsigned long)regs->start, irq, baudrate); - -From 2e3d8378c9031150eda4fd030b14d6c4ea762786 Mon Sep 17 00:00:00 2001 +From a69146643bae1215ab2860b9646f0f380bd3c50f Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 12 Feb 2015 11:17:53 +0000 -Subject: [PATCH 081/216] Fix LED "input" trigger implementation for 3.19 +Subject: [PATCH 56/77] Fix LED "input" trigger implementation for 3.19 --- drivers/leds/leds-gpio.c | 10 +++++++++- @@ -125629,7 +127697,7 @@ Subject: [PATCH 081/216] Fix LED "input" trigger implementation for 3.19 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c -index d26af0a..9e49c72 100644 +index 15eb3f8..3cfbd6a 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -41,6 +41,13 @@ static void gpio_led_work(struct work_struct *work) @@ -125693,13 +127761,13 @@ index 2ca2b98..07d1219 100644 static struct led_trigger input_led_trigger = { diff --git a/include/linux/leds.h b/include/linux/leds.h -index f70f84f..f3fcaa1 100644 +index 9a2b000..60accc5 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h -@@ -48,6 +48,9 @@ struct led_classdev { +@@ -47,6 +47,9 @@ struct led_classdev { + #define SET_BRIGHTNESS_ASYNC (1 << 21) #define SET_BRIGHTNESS_SYNC (1 << 22) #define LED_DEV_CAP_FLASH (1 << 23) - #define LED_DEV_CAP_SYNC_STROBE (1 << 24) + /* Additions for Raspberry Pi PWR LED */ +#define SET_GPIO_INPUT (1 << 30) +#define SET_GPIO_OUTPUT (1 << 31) @@ -125707,65 +127775,67 @@ index f70f84f..f3fcaa1 100644 /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ -From 9bdca5da4acd1e4893a10183c0202b2b1293b9cd Mon Sep 17 00:00:00 2001 -From: Rainer Herbers -Date: Sun, 15 Feb 2015 13:44:14 +0100 -Subject: [PATCH 082/216] Create bmp085_i2c-sensor-overlay.dts and update - Makefile +From d8f6c527b14c125e58173e8bd0e7c6c59bab4919 Mon Sep 17 00:00:00 2001 +From: notro +Date: Thu, 10 Jul 2014 13:59:47 +0200 +Subject: [PATCH 57/77] pinctrl-bcm2835: Set base to 0 give expected gpio + numbering + +Signed-off-by: Noralf Tronnes +--- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 8d908e3..7a1900d 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -382,7 +382,7 @@ static struct gpio_chip bcm2835_gpio_chip = { + .get = bcm2835_gpio_get, + .set = bcm2835_gpio_set, + .to_irq = bcm2835_gpio_to_irq, +- .base = -1, ++ .base = 0, + .ngpio = BCM2835_NUM_GPIOS, + .can_sleep = false, + }; + +From bf8c97c74733237b219a22da649cb6cb7029615d Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Wed, 4 Feb 2015 10:02:24 +0000 +Subject: [PATCH 58/77] pinctrl-bcm2835: bcm2835_gpio_direction_output must set + the value --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts | 23 +++++++++++++++++++++++ - 2 files changed, 24 insertions(+) - create mode 100644 arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 6cb743a..7946143 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 7a1900d..62f85aa 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -355,7 +355,14 @@ static int bcm2835_gpio_get(struct gpio_chip *chip, unsigned offset) + static int bcm2835_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int value) + { +- return pinctrl_gpio_direction_output(chip->base + offset); ++ struct bcm2835_pinctrl *pc = dev_get_drvdata(chip->dev); ++ int ret; ++ ++ ret = pinctrl_gpio_direction_output(chip->base + offset); ++ if (ret >= 0) ++ bcm2835_gpio_set_bit(pc, value ? GPSET0 : GPCLR0, offset); ++ ++ return ret; + } -+dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -new file mode 100644 -index 0000000..b830bf2 ---- /dev/null -+++ b/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -@@ -0,0 +1,23 @@ -+// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ bmp085@77 { -+ compatible = "bosch,bmp085"; -+ reg = <0x77>; -+ default-oversampling = <3>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; + static void bcm2835_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -From 92765161f74e60edf1eb2c752f2cd3ea9d531d14 Mon Sep 17 00:00:00 2001 +From 1262602778ac5adbe798e7ace41b22262a578fcf Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Tue, 24 Feb 2015 13:40:50 +0000 -Subject: [PATCH 083/216] pinctrl-bcm2835: Fix interrupt handling for GPIOs - 28-31 and 46-53 +Subject: [PATCH 59/77] pinctrl-bcm2835: Fix interrupt handling for GPIOs 28-31 + and 46-53 Contrary to the documentation, the BCM2835 GPIO controller actually has four interrupt lines - one each for the three IRQ groups and one common. Rather @@ -125781,13 +127851,13 @@ This bug has only just been observed because GPIOs above 27 can only be accessed on an old Raspberry Pi with the optional P5 header fitted, where the pins are often used for I2S instead. --- - drivers/pinctrl/pinctrl-bcm2835.c | 51 ++++++++++++++++++++++++++++++--------- + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 51 ++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index d9c727b..ae68710 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index 62f85aa..c7cf266 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -47,6 +47,7 @@ #define MODULE_NAME "pinctrl-bcm2835" #define BCM2835_NUM_GPIOS 54 @@ -125842,9 +127912,9 @@ index d9c727b..ae68710 100644 events &= pc->enabled_irq_map[bank]; for_each_set_bit(offset, &events, 32) { gpio = (32 * bank) + offset; -@@ -420,7 +420,30 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) - if (type & IRQ_TYPE_LEVEL_MASK) - bcm2835_gpio_set_bit(pc, GPEDS0, gpio); +@@ -412,7 +412,30 @@ static irqreturn_t bcm2835_gpio_irq_handler(int irq, void *dev_id) + + generic_handle_irq(irq_linear_revmap(pc->irq_domain, gpio)); } - return events ? IRQ_HANDLED : IRQ_NONE; + @@ -125874,7 +127944,7 @@ index d9c727b..ae68710 100644 } static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, -@@ -992,8 +1015,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1000,8 +1023,6 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for (i = 0; i < BCM2835_NUM_BANKS; i++) { unsigned long events; unsigned offset; @@ -125883,7 +127953,7 @@ index d9c727b..ae68710 100644 /* clear event detection flags */ bcm2835_gpio_wr(pc, GPREN0 + i * 4, 0); -@@ -1008,10 +1029,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +@@ -1016,10 +1037,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) for_each_set_bit(offset, &events, 32) bcm2835_gpio_wr(pc, GPEDS0 + i * 4, BIT(offset)); @@ -125901,7 +127971,7 @@ index d9c727b..ae68710 100644 len = strlen(dev_name(pc->dev)) + 16; name = devm_kzalloc(pc->dev, len, GFP_KERNEL); -@@ -1069,6 +1095,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { +@@ -1077,6 +1103,7 @@ static struct platform_driver bcm2835_pinctrl_driver = { .remove = bcm2835_pinctrl_remove, .driver = { .name = MODULE_NAME, @@ -125910,11 +127980,11 @@ index d9c727b..ae68710 100644 }, }; -From d1f5e57c873c1acf3be524693888af970a08f4fb Mon Sep 17 00:00:00 2001 +From fd7e740e1c83bd550444192a8beff54ea5291c50 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 26 Feb 2015 09:58:22 +0000 -Subject: [PATCH 084/216] pinctrl-bcm2835: Only request the interrupts listed - in the DTB +Subject: [PATCH 60/77] pinctrl-bcm2835: Only request the interrupts listed in + the DTB Although the GPIO controller can generate three interrupts (four counting the common one), the device tree files currently only specify two. In the @@ -125923,14 +127993,14 @@ registering 0), which has the effect of making it impossible to generate interrupts for GPIOs 46-53 which, since they share pins with the SD card interface, is unlikely to be a problem. --- - drivers/pinctrl/pinctrl-bcm2835.c | 2 ++ + drivers/pinctrl/bcm/pinctrl-bcm2835.c | 2 ++ 1 file changed, 2 insertions(+) -diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c -index ae68710..87b7a4a 100644 ---- a/drivers/pinctrl/pinctrl-bcm2835.c -+++ b/drivers/pinctrl/pinctrl-bcm2835.c -@@ -1036,6 +1036,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) +diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +index c7cf266..986779a 100644 +--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c ++++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c +@@ -1044,6 +1044,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) int len; char *name; pc->irq[i] = irq_of_parse_and_map(np, i); @@ -125940,1282 +128010,16 @@ index ae68710..87b7a4a 100644 pc->irq_data[i].irqgroup = i; -From a10a9f8313c8fff626c82bf63608f3f00188c5db Mon Sep 17 00:00:00 2001 -From: Dave Martin -Date: Fri, 27 Feb 2015 15:51:37 +0000 -Subject: [PATCH 085/216] serial/amba-pl011: Activate TX IRQ passively - -The current PL011 driver transmits a dummy character when the UART -is opened, to assert the TX IRQ for the first time -(see pl011_startup()). The UART is put in loopback mode temporarily, -so the receiver presumably shouldn't see anything. - -However... - -At least some platforms containing a PL011 send characters down the -wire even when loopback mode is enabled. This means that a -spurious NUL character may be seen at the receiver when the PL011 is -opened through the TTY layer. - -The current code also temporarily sets the baud rate to maximum and -the character width to the minimum, to that the dummy TX completes -as quickly as possible. If this is seen by the receiver it will -result in a framing error and can knock the receiver out of sync -- -turning subsequent output into garbage until synchronisation -is reestablished. (Particularly problematic during boot with systemd.) - -To avoid spurious transmissions, this patch removes assumptions about -whether the TX IRQ will fire until at least one TX IRQ has been seen. - -Instead, the UART will unmask the TX IRQ and then slow-start via -polling and timer-based soft IRQs initially. If the TTY layer writes -enough data to fill the FIFO to the interrupt threshold in one go, -the TX IRQ should assert, at which point the driver changes to -fully interrupt-driven TX. - -In this way, the TX IRQ is activated as a side-effect instead of -being done deliberately. - -This should also mean that the driver works on the SBSA Generic -UART[1] (a cut-down PL011) without invasive changes. The Generic -UART lacks some features needed for the dummy TX approach to work -(FIFO disabling and loopback). - -[1] Server Base System Architecture (ARM-DEN-0029-v2.3) - http://infocenter.arm.com/ - (click-thru required :/) - -Signed-off-by: Dave Martin ---- - drivers/tty/serial/amba-pl011.c | 165 ++++++++++++++++++++++++++++------------ - 1 file changed, 115 insertions(+), 50 deletions(-) - -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index 16ca535..c243729 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -58,6 +58,7 @@ - #include - #include - #include -+#include - - #define UART_NR 14 - -@@ -156,7 +157,9 @@ struct uart_amba_port { - unsigned int lcrh_tx; /* vendor-specific */ - unsigned int lcrh_rx; /* vendor-specific */ - unsigned int old_cr; /* state during shutdown */ -+ struct delayed_work tx_softirq_work; - bool autorts; -+ unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */ - char type[12]; - #ifdef CONFIG_DMA_ENGINE - /* DMA stuff */ -@@ -440,8 +443,9 @@ static void pl011_dma_remove(struct uart_amba_port *uap) - dma_release_channel(uap->dmarx.chan); - } - --/* Forward declare this for the refill routine */ -+/* Forward declare these for the refill routine */ - static int pl011_dma_tx_refill(struct uart_amba_port *uap); -+static void pl011_start_tx_pio(struct uart_amba_port *uap); - - /* - * The current DMA TX buffer has been sent. -@@ -479,14 +483,13 @@ static void pl011_dma_tx_callback(void *data) - return; - } - -- if (pl011_dma_tx_refill(uap) <= 0) { -+ if (pl011_dma_tx_refill(uap) <= 0) - /* - * We didn't queue a DMA buffer for some reason, but we - * have data pending to be sent. Re-enable the TX IRQ. - */ -- uap->im |= UART011_TXIM; -- writew(uap->im, uap->port.membase + UART011_IMSC); -- } -+ pl011_start_tx_pio(uap); -+ - spin_unlock_irqrestore(&uap->port.lock, flags); - } - -@@ -664,12 +667,10 @@ static inline bool pl011_dma_tx_start(struct uart_amba_port *uap) - if (!uap->dmatx.queued) { - if (pl011_dma_tx_refill(uap) > 0) { - uap->im &= ~UART011_TXIM; -- ret = true; -- } else { -- uap->im |= UART011_TXIM; -+ writew(uap->im, uap->port.membase + -+ UART011_IMSC); -+ } else - ret = false; -- } -- writew(uap->im, uap->port.membase + UART011_IMSC); - } else if (!(uap->dmacr & UART011_TXDMAE)) { - uap->dmacr |= UART011_TXDMAE; - writew(uap->dmacr, -@@ -1208,15 +1209,24 @@ static void pl011_stop_tx(struct uart_port *port) - pl011_dma_tx_stop(uap); - } - -+static bool pl011_tx_chars(struct uart_amba_port *uap); -+ -+/* Start TX with programmed I/O only (no DMA) */ -+static void pl011_start_tx_pio(struct uart_amba_port *uap) -+{ -+ uap->im |= UART011_TXIM; -+ writew(uap->im, uap->port.membase + UART011_IMSC); -+ if (!uap->tx_irq_seen) -+ pl011_tx_chars(uap); -+} -+ - static void pl011_start_tx(struct uart_port *port) - { - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); - -- if (!pl011_dma_tx_start(uap)) { -- uap->im |= UART011_TXIM; -- writew(uap->im, uap->port.membase + UART011_IMSC); -- } -+ if (!pl011_dma_tx_start(uap)) -+ pl011_start_tx_pio(uap); - } - - static void pl011_stop_rx(struct uart_port *port) -@@ -1274,40 +1284,87 @@ __acquires(&uap->port.lock) - spin_lock(&uap->port.lock); - } - --static void pl011_tx_chars(struct uart_amba_port *uap) -+/* -+ * Transmit a character -+ * There must be at least one free entry in the TX FIFO to accept the char. -+ * -+ * Returns true if the FIFO might have space in it afterwards; -+ * returns false if the FIFO definitely became full. -+ */ -+static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) -+{ -+ writew(c, uap->port.membase + UART01x_DR); -+ uap->port.icount.tx++; -+ -+ if (likely(uap->tx_irq_seen > 1)) -+ return true; -+ -+ return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); -+} -+ -+static bool pl011_tx_chars(struct uart_amba_port *uap) - { - struct circ_buf *xmit = &uap->port.state->xmit; - int count; - -+ if (unlikely(uap->tx_irq_seen < 2)) -+ /* -+ * Initial FIFO fill level unknown: we must check TXFF -+ * after each write, so just try to fill up the FIFO. -+ */ -+ count = uap->fifosize; -+ else /* tx_irq_seen >= 2 */ -+ /* -+ * FIFO initially at least half-empty, so we can simply -+ * write half the FIFO without polling TXFF. -+ -+ * Note: the *first* TX IRQ can still race with -+ * pl011_start_tx_pio(), which can result in the FIFO -+ * being fuller than expected in that case. -+ */ -+ count = uap->fifosize >> 1; -+ -+ /* -+ * If the FIFO is full we're guaranteed a TX IRQ at some later point, -+ * and can't transmit immediately in any case: -+ */ -+ if (unlikely(uap->tx_irq_seen < 2 && -+ readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)) -+ return false; -+ - if (uap->port.x_char) { -- writew(uap->port.x_char, uap->port.membase + UART01x_DR); -- uap->port.icount.tx++; -+ pl011_tx_char(uap, uap->port.x_char); - uap->port.x_char = 0; -- return; -+ --count; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { - pl011_stop_tx(&uap->port); -- return; -+ goto done; - } - - /* If we are using DMA mode, try to send some characters. */ - if (pl011_dma_tx_irq(uap)) -- return; -+ goto done; - -- count = uap->fifosize >> 1; -- do { -- writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); -+ while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) { - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -- uap->port.icount.tx++; - if (uart_circ_empty(xmit)) - break; -- } while (--count > 0); -+ } - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uap->port); - -- if (uart_circ_empty(xmit)) -+ if (uart_circ_empty(xmit)) { - pl011_stop_tx(&uap->port); -+ goto done; -+ } -+ -+ if (unlikely(!uap->tx_irq_seen)) -+ schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout); -+ -+done: -+ return false; - } - - static void pl011_modem_status(struct uart_amba_port *uap) -@@ -1334,6 +1391,28 @@ static void pl011_modem_status(struct uart_amba_port *uap) - wake_up_interruptible(&uap->port.state->port.delta_msr_wait); - } - -+static void pl011_tx_softirq(struct work_struct *work) -+{ -+ struct delayed_work *dwork = to_delayed_work(work); -+ struct uart_amba_port *uap = -+ container_of(dwork, struct uart_amba_port, tx_softirq_work); -+ -+ spin_lock(&uap->port.lock); -+ while (pl011_tx_chars(uap)) ; -+ spin_unlock(&uap->port.lock); -+} -+ -+static void pl011_tx_irq_seen(struct uart_amba_port *uap) -+{ -+ if (likely(uap->tx_irq_seen > 1)) -+ return; -+ -+ uap->tx_irq_seen++; -+ if (uap->tx_irq_seen < 2) -+ /* first TX IRQ */ -+ cancel_delayed_work(&uap->tx_softirq_work); -+} -+ - static irqreturn_t pl011_int(int irq, void *dev_id) - { - struct uart_amba_port *uap = dev_id; -@@ -1372,8 +1451,10 @@ static irqreturn_t pl011_int(int irq, void *dev_id) - if (status & (UART011_DSRMIS|UART011_DCDMIS| - UART011_CTSMIS|UART011_RIMIS)) - pl011_modem_status(uap); -- if (status & UART011_TXIS) -+ if (status & UART011_TXIS) { -+ pl011_tx_irq_seen(uap); - pl011_tx_chars(uap); -+ } - - if (pass_counter-- == 0) - break; -@@ -1577,7 +1658,7 @@ static int pl011_startup(struct uart_port *port) - { - struct uart_amba_port *uap = - container_of(port, struct uart_amba_port, port); -- unsigned int cr, lcr_h, fbrd, ibrd; -+ unsigned int cr; - int retval; - - retval = pl011_hwinit(port); -@@ -1595,29 +1676,10 @@ static int pl011_startup(struct uart_port *port) - - writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); - -- /* -- * Provoke TX FIFO interrupt into asserting. Taking care to preserve -- * baud rate and data format specified by FBRD, IBRD and LCRH as the -- * UART may already be in use as a console. -- */ -- spin_lock_irq(&uap->port.lock); -- -- fbrd = readw(uap->port.membase + UART011_FBRD); -- ibrd = readw(uap->port.membase + UART011_IBRD); -- lcr_h = readw(uap->port.membase + uap->lcrh_rx); -- -- cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE; -- writew(cr, uap->port.membase + UART011_CR); -- writew(0, uap->port.membase + UART011_FBRD); -- writew(1, uap->port.membase + UART011_IBRD); -- pl011_write_lcr_h(uap, 0); -- writew(0, uap->port.membase + UART01x_DR); -- while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) -- barrier(); -+ /* Assume that TX IRQ doesn't work until we see one: */ -+ uap->tx_irq_seen = 0; - -- writew(fbrd, uap->port.membase + UART011_FBRD); -- writew(ibrd, uap->port.membase + UART011_IBRD); -- pl011_write_lcr_h(uap, lcr_h); -+ spin_lock_irq(&uap->port.lock); - - /* restore RTS and DTR */ - cr = uap->old_cr & (UART011_CR_RTS | UART011_CR_DTR); -@@ -1672,6 +1734,8 @@ static void pl011_shutdown(struct uart_port *port) - container_of(port, struct uart_amba_port, port); - unsigned int cr; - -+ cancel_delayed_work_sync(&uap->tx_softirq_work); -+ - /* - * disable all interrupts - */ -@@ -2218,6 +2282,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) - uap->port.ops = &amba_pl011_pops; - uap->port.flags = UPF_BOOT_AUTOCONF; - uap->port.line = i; -+ INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); - pl011_dma_probe(&dev->dev, uap); - - /* Ensure interrupts from this UART are masked and cleared */ - -From 75d9fae636d84117aa46cf0c2dcc556d02d67aca Mon Sep 17 00:00:00 2001 -From: Dave Martin -Date: Wed, 1 Apr 2015 14:08:31 +0100 -Subject: [PATCH 086/216] serial/amba-pl011: Refactor and simplify TX FIFO - handling - -Commit 734745c serial/amba-pl011: Activate TX IRQ passively -adds some complexity and overhead in the form of a softirq -mechanism for transmitting in the absence of interrupts. - -This patch simplifies the code flow to reduce the reliance on -subtle behaviour and avoid fragility under future maintenance. - -To this end, the TX softirq mechanism is removed and instead -pl011_start_tx() will now simply stuff the FIFO until full -(guaranteeing future TX IRQs), or until there are no more chars -to write (in which case we don't care whether an IRQ happens). - -Signed-off-by: Dave Martin -Signed-off-by: Jakub Kicinski ---- - drivers/tty/serial/amba-pl011.c | 119 +++++++++------------------------------- - 1 file changed, 26 insertions(+), 93 deletions(-) - -diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c -index c243729..e32f4d7 100644 ---- a/drivers/tty/serial/amba-pl011.c -+++ b/drivers/tty/serial/amba-pl011.c -@@ -58,7 +58,6 @@ - #include - #include - #include --#include - - #define UART_NR 14 - -@@ -157,9 +156,7 @@ struct uart_amba_port { - unsigned int lcrh_tx; /* vendor-specific */ - unsigned int lcrh_rx; /* vendor-specific */ - unsigned int old_cr; /* state during shutdown */ -- struct delayed_work tx_softirq_work; - bool autorts; -- unsigned int tx_irq_seen; /* 0=none, 1=1, 2=2 or more */ - char type[12]; - #ifdef CONFIG_DMA_ENGINE - /* DMA stuff */ -@@ -1209,15 +1206,14 @@ static void pl011_stop_tx(struct uart_port *port) - pl011_dma_tx_stop(uap); - } - --static bool pl011_tx_chars(struct uart_amba_port *uap); -+static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq); - - /* Start TX with programmed I/O only (no DMA) */ - static void pl011_start_tx_pio(struct uart_amba_port *uap) - { - uap->im |= UART011_TXIM; - writew(uap->im, uap->port.membase + UART011_IMSC); -- if (!uap->tx_irq_seen) -- pl011_tx_chars(uap); -+ pl011_tx_chars(uap, false); - } - - static void pl011_start_tx(struct uart_port *port) -@@ -1284,87 +1280,54 @@ __acquires(&uap->port.lock) - spin_lock(&uap->port.lock); - } - --/* -- * Transmit a character -- * There must be at least one free entry in the TX FIFO to accept the char. -- * -- * Returns true if the FIFO might have space in it afterwards; -- * returns false if the FIFO definitely became full. -- */ --static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c) -+static bool pl011_tx_char(struct uart_amba_port *uap, unsigned char c, -+ bool from_irq) - { -+ if (unlikely(!from_irq) && -+ readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) -+ return false; /* unable to transmit character */ -+ - writew(c, uap->port.membase + UART01x_DR); - uap->port.icount.tx++; - -- if (likely(uap->tx_irq_seen > 1)) -- return true; -- -- return !(readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF); -+ return true; - } - --static bool pl011_tx_chars(struct uart_amba_port *uap) -+static void pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) - { - struct circ_buf *xmit = &uap->port.state->xmit; -- int count; -- -- if (unlikely(uap->tx_irq_seen < 2)) -- /* -- * Initial FIFO fill level unknown: we must check TXFF -- * after each write, so just try to fill up the FIFO. -- */ -- count = uap->fifosize; -- else /* tx_irq_seen >= 2 */ -- /* -- * FIFO initially at least half-empty, so we can simply -- * write half the FIFO without polling TXFF. -- -- * Note: the *first* TX IRQ can still race with -- * pl011_start_tx_pio(), which can result in the FIFO -- * being fuller than expected in that case. -- */ -- count = uap->fifosize >> 1; -- -- /* -- * If the FIFO is full we're guaranteed a TX IRQ at some later point, -- * and can't transmit immediately in any case: -- */ -- if (unlikely(uap->tx_irq_seen < 2 && -- readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)) -- return false; -+ int count = uap->fifosize >> 1; - - if (uap->port.x_char) { -- pl011_tx_char(uap, uap->port.x_char); -+ if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) -+ return; - uap->port.x_char = 0; - --count; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { - pl011_stop_tx(&uap->port); -- goto done; -+ return; - } - - /* If we are using DMA mode, try to send some characters. */ - if (pl011_dma_tx_irq(uap)) -- goto done; -+ return; - -- while (count-- > 0 && pl011_tx_char(uap, xmit->buf[xmit->tail])) { -- xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -- if (uart_circ_empty(xmit)) -+ do { -+ if (likely(from_irq) && count-- == 0) - break; -- } -+ -+ if (!pl011_tx_char(uap, xmit->buf[xmit->tail], from_irq)) -+ break; -+ -+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -+ } while (!uart_circ_empty(xmit)); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uap->port); - -- if (uart_circ_empty(xmit)) { -+ if (uart_circ_empty(xmit)) - pl011_stop_tx(&uap->port); -- goto done; -- } -- -- if (unlikely(!uap->tx_irq_seen)) -- schedule_delayed_work(&uap->tx_softirq_work, uap->port.timeout); -- --done: -- return false; - } - - static void pl011_modem_status(struct uart_amba_port *uap) -@@ -1391,28 +1354,6 @@ static void pl011_modem_status(struct uart_amba_port *uap) - wake_up_interruptible(&uap->port.state->port.delta_msr_wait); - } - --static void pl011_tx_softirq(struct work_struct *work) --{ -- struct delayed_work *dwork = to_delayed_work(work); -- struct uart_amba_port *uap = -- container_of(dwork, struct uart_amba_port, tx_softirq_work); -- -- spin_lock(&uap->port.lock); -- while (pl011_tx_chars(uap)) ; -- spin_unlock(&uap->port.lock); --} -- --static void pl011_tx_irq_seen(struct uart_amba_port *uap) --{ -- if (likely(uap->tx_irq_seen > 1)) -- return; -- -- uap->tx_irq_seen++; -- if (uap->tx_irq_seen < 2) -- /* first TX IRQ */ -- cancel_delayed_work(&uap->tx_softirq_work); --} -- - static irqreturn_t pl011_int(int irq, void *dev_id) - { - struct uart_amba_port *uap = dev_id; -@@ -1451,10 +1392,8 @@ static irqreturn_t pl011_int(int irq, void *dev_id) - if (status & (UART011_DSRMIS|UART011_DCDMIS| - UART011_CTSMIS|UART011_RIMIS)) - pl011_modem_status(uap); -- if (status & UART011_TXIS) { -- pl011_tx_irq_seen(uap); -- pl011_tx_chars(uap); -- } -+ if (status & UART011_TXIS) -+ pl011_tx_chars(uap, true); - - if (pass_counter-- == 0) - break; -@@ -1676,9 +1615,6 @@ static int pl011_startup(struct uart_port *port) - - writew(uap->vendor->ifls, uap->port.membase + UART011_IFLS); - -- /* Assume that TX IRQ doesn't work until we see one: */ -- uap->tx_irq_seen = 0; -- - spin_lock_irq(&uap->port.lock); - - /* restore RTS and DTR */ -@@ -1734,8 +1670,6 @@ static void pl011_shutdown(struct uart_port *port) - container_of(port, struct uart_amba_port, port); - unsigned int cr; - -- cancel_delayed_work_sync(&uap->tx_softirq_work); -- - /* - * disable all interrupts - */ -@@ -2282,7 +2216,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) - uap->port.ops = &amba_pl011_pops; - uap->port.flags = UPF_BOOT_AUTOCONF; - uap->port.line = i; -- INIT_DELAYED_WORK(&uap->tx_softirq_work, pl011_tx_softirq); - pl011_dma_probe(&dev->dev, uap); - - /* Ensure interrupts from this UART are masked and cleared */ - -From 29cd864c0ec9d9d593e569ee5d4fcb463d36cb35 Mon Sep 17 00:00:00 2001 -From: Jon Burgess -Date: Tue, 17 Feb 2015 13:22:17 +0000 -Subject: [PATCH 087/216] Create generic i2c-rtc overlay for supporting ds1307, - ds3231, pcf2127 and pcf8523. - -Signed-off-by: Jon Burgess ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/i2c-rtc-overlay.dts | 43 +++++++++++++++++++++++++++++++++++ - 2 files changed, 44 insertions(+) - create mode 100644 arch/arm/boot/dts/i2c-rtc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 7946143..6753fcb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -14,6 +14,7 @@ endif - - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -diff --git a/arch/arm/boot/dts/i2c-rtc-overlay.dts b/arch/arm/boot/dts/i2c-rtc-overlay.dts -new file mode 100644 -index 0000000..5d5abb1 ---- /dev/null -+++ b/arch/arm/boot/dts/i2c-rtc-overlay.dts -@@ -0,0 +1,43 @@ -+// Definitions for several I2C based Real Time Clocks -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ ds3231: ds3231@68 { -+ compatible = "maxim,ds3231"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ pcf2127: pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "disable"; -+ }; -+ pcf8523: pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ }; -+ }; -+ __overrides__ { -+ ds1307 = <&ds1307>,"status"; -+ ds3231 = <&ds3231>,"status"; -+ pcf2127 = <&pcf2127>,"status"; -+ pcf8523 = <&pcf8523>,"status"; -+ }; -+}; - -From 600d5e0e89ecc723b7ffb29209b058d0275502e2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:24:05 +0100 -Subject: [PATCH 088/216] dts: overlay: add support for rpi-display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for rpi-display by Watterott. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/rpi-display-overlay.dts | 81 +++++++++++++++++++++++++++++++ - 2 files changed, 82 insertions(+) - create mode 100644 arch/arm/boot/dts/rpi-display-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 6753fcb..de47748 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -25,6 +25,7 @@ dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - -diff --git a/arch/arm/boot/dts/rpi-display-overlay.dts b/arch/arm/boot/dts/rpi-display-overlay.dts -new file mode 100644 -index 0000000..0578810 ---- /dev/null -+++ b/arch/arm/boot/dts/rpi-display-overlay.dts -@@ -0,0 +1,81 @@ -+/* -+ * Device Tree overlay for rpi-display by Watterott -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ rpi_display_pins: rpi_display_pins { -+ brcm,pins = <18 23 24 25>; -+ brcm,function = <1 1 1 0>; /* out out out in */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rpidisplay: rpi-display@0{ -+ compatible = "ilitek,ili9341"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rpi_display_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ reset-gpios = <&gpio 23 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ rpidisplay_ts: rpi-display-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <25 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 25 0>; -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&rpidisplay>,"spi-max-frequency:0"; -+ rotate = <&rpidisplay>,"rotate:0"; -+ fps = <&rpidisplay>,"fps:0"; -+ debug = <&rpidisplay>,"debug:0"; -+ xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; - -From 525949ace298ff41d93fc2025ac768654e745642 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:36:27 +0100 -Subject: [PATCH 089/216] dts: overlay: add support for HY28A display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for HY28A display by HAOYU Electronics. -Default values are set to match Texy's display shield. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/hy28a-overlay.dts | 87 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 88 insertions(+) - create mode 100644 arch/arm/boot/dts/hy28a-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index de47748..8d7e535 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -19,6 +19,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -diff --git a/arch/arm/boot/dts/hy28a-overlay.dts b/arch/arm/boot/dts/hy28a-overlay.dts -new file mode 100644 -index 0000000..3cd3083 ---- /dev/null -+++ b/arch/arm/boot/dts/hy28a-overlay.dts -@@ -0,0 +1,87 @@ -+/* -+ * Device Tree overlay for HY28A display -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28a_pins: hy28a_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28a: hy28a@0{ -+ compatible = "ilitek,ili9320"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28a_pins>; -+ -+ spi-max-frequency = <32000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ hy28a_ts: hy28a-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28a>,"spi-max-frequency:0"; -+ rotate = <&hy28a>,"rotate:0"; -+ fps = <&hy28a>,"fps:0"; -+ debug = <&hy28a>,"debug:0"; -+ xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28a>,"reset-gpios:4", -+ <&hy28a_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28a>,"led-gpios:4", -+ <&hy28a_pins>, "brcm,pins:2"; -+ }; -+}; - -From 131c6ba7b078b8536755c8cae2e31c09053b5804 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:38:00 +0100 -Subject: [PATCH 090/216] dts: overlay: add support for HY28B display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for HY28B display by HAOYU Electronics. -Default values are set to match Texy's display shield. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/hy28b-overlay.dts | 142 ++++++++++++++++++++++++++++++++++++ - 2 files changed, 143 insertions(+) - create mode 100644 arch/arm/boot/dts/hy28b-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 8d7e535..ec26431b1 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -20,6 +20,7 @@ dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -diff --git a/arch/arm/boot/dts/hy28b-overlay.dts b/arch/arm/boot/dts/hy28b-overlay.dts -new file mode 100644 -index 0000000..f774c4a ---- /dev/null -+++ b/arch/arm/boot/dts/hy28b-overlay.dts -@@ -0,0 +1,142 @@ -+/* -+ * Device Tree overlay for HY28b display shield by Texy -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28b_pins: hy28b_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28b: hy28b@0{ -+ compatible = "ilitek,ili9325"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28b_pins>; -+ -+ spi-max-frequency = <48000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ -+ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -+ -+ init = <0x10000e7 0x0010 -+ 0x1000000 0x0001 -+ 0x1000001 0x0100 -+ 0x1000002 0x0700 -+ 0x1000003 0x1030 -+ 0x1000004 0x0000 -+ 0x1000008 0x0207 -+ 0x1000009 0x0000 -+ 0x100000a 0x0000 -+ 0x100000c 0x0001 -+ 0x100000d 0x0000 -+ 0x100000f 0x0000 -+ 0x1000010 0x0000 -+ 0x1000011 0x0007 -+ 0x1000012 0x0000 -+ 0x1000013 0x0000 -+ 0x2000032 -+ 0x1000010 0x1590 -+ 0x1000011 0x0227 -+ 0x2000032 -+ 0x1000012 0x009c -+ 0x2000032 -+ 0x1000013 0x1900 -+ 0x1000029 0x0023 -+ 0x100002b 0x000e -+ 0x2000032 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000032 -+ 0x1000050 0x0000 -+ 0x1000051 0x00ef -+ 0x1000052 0x0000 -+ 0x1000053 0x013f -+ 0x1000060 0xa700 -+ 0x1000061 0x0001 -+ 0x100006a 0x0000 -+ 0x1000080 0x0000 -+ 0x1000081 0x0000 -+ 0x1000082 0x0000 -+ 0x1000083 0x0000 -+ 0x1000084 0x0000 -+ 0x1000085 0x0000 -+ 0x1000090 0x0010 -+ 0x1000092 0x0000 -+ 0x1000093 0x0003 -+ 0x1000095 0x0110 -+ 0x1000097 0x0000 -+ 0x1000098 0x0000 -+ 0x1000007 0x0133 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000064>; -+ debug = <0>; -+ }; -+ -+ hy28b_ts: hy28b-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28b>,"spi-max-frequency:0"; -+ rotate = <&hy28b>,"rotate:0"; -+ fps = <&hy28b>,"fps:0"; -+ debug = <&hy28b>,"debug:0"; -+ xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28b>,"reset-gpios:4", -+ <&hy28b_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28b>,"led-gpios:4", -+ <&hy28b_pins>, "brcm,pins:2"; -+ }; -+}; - -From 33ce6c6c093580873f0f54b8633f44479d31786b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 26 Feb 2015 21:38:47 +0100 -Subject: [PATCH 091/216] dts: overlay: add support for PiScreen display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for PiScreen display by OzzMaker.com - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/piscreen-overlay.dts | 94 ++++++++++++++++++++++++++++++++++ - 2 files changed, 95 insertions(+) - create mode 100644 arch/arm/boot/dts/piscreen-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index ec26431b1..107448d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -26,6 +26,7 @@ dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -diff --git a/arch/arm/boot/dts/piscreen-overlay.dts b/arch/arm/boot/dts/piscreen-overlay.dts -new file mode 100644 -index 0000000..8cd6a95 ---- /dev/null -+++ b/arch/arm/boot/dts/piscreen-overlay.dts -@@ -0,0 +1,94 @@ -+/* -+ * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen_pins: piscreen_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen: piscreen@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c2 0x44 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 -+ 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x1000011 -+ 0x1000029>; -+ }; -+ -+ piscreen-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen>,"spi-max-frequency:0"; -+ rotate = <&piscreen>,"rotate:0"; -+ fps = <&piscreen>,"fps:0"; -+ debug = <&piscreen>,"debug:0"; -+ }; -+}; - -From 5ef8657c77133ceed5a8ddf80fed6d3002ac9dca Mon Sep 17 00:00:00 2001 +From c24fbfc7a5bc3c7cb35f51d0a40ad25b98a8a422 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 27 Feb 2015 15:10:24 +0000 -Subject: [PATCH 092/216] enc28j60: Add device tree compatible string and an +Subject: [PATCH 61/77] enc28j60: Add device tree compatible string and an overlay --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/enc28j60-overlay.dts | 29 +++++++++++++++++++++++++++++ drivers/net/ethernet/microchip/enc28j60.c | 11 +++++++++++ - 3 files changed, 41 insertions(+) - create mode 100755 arch/arm/boot/dts/enc28j60-overlay.dts + 1 file changed, 11 insertions(+) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 107448d..81afe85 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -14,6 +14,7 @@ endif - - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -diff --git a/arch/arm/boot/dts/enc28j60-overlay.dts b/arch/arm/boot/dts/enc28j60-overlay.dts -new file mode 100755 -index 0000000..aa9b645 ---- /dev/null -+++ b/arch/arm/boot/dts/enc28j60-overlay.dts -@@ -0,0 +1,29 @@ -+// Overlay for the Microchip ENC28J60 Ethernet Controller -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ enc28j60@0{ -+ compatible = "microchip,enc28j60"; -+ reg = <0>; /* CE0 */ -+ spi-max-frequency = <12000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index b1b5f66..c6b6e1a 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c @@ -127243,1131 +128047,10 @@ index b1b5f66..c6b6e1a 100644 .probe = enc28j60_probe, .remove = enc28j60_remove, -From 04e8bf899200ef72d464ce9ee362d4377fbd7d87 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 27 Feb 2015 18:17:25 +0100 -Subject: [PATCH 093/216] dts: overlay: add support for Adafruit PiTFT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add DT overlay for the Adafruit PiTFT 2.8" resistive touch screen - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/pitft28-resistive-overlay.dts | 115 ++++++++++++++++++++++++ - 2 files changed, 116 insertions(+) - create mode 100644 arch/arm/boot/dts/pitft28-resistive-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 81afe85..07c6eeb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -28,6 +28,7 @@ dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -diff --git a/arch/arm/boot/dts/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/pitft28-resistive-overlay.dts -new file mode 100644 -index 0000000..d506eae ---- /dev/null -+++ b/arch/arm/boot/dts/pitft28-resistive-overlay.dts -@@ -0,0 +1,115 @@ -+/* -+ * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pitft_pins: pitft_pins { -+ brcm,pins = <24 25>; -+ brcm,function = <0 1>; /* in out */ -+ brcm,pull = <2 0>; /* pullup none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pitft: pitft@0{ -+ compatible = "ilitek,ili9340"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pitft_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <90>; -+ fps = <25>; -+ bgr; -+ buswidth = <8>; -+ dc-gpios = <&gpio 25 0>; -+ debug = <0>; -+ }; -+ -+ pitft_ts@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stmpe610"; -+ reg = <1>; -+ -+ spi-max-frequency = <500000>; -+ irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ -+ interrupts = <24 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ interrupt-controller; -+ -+ stmpe_touchscreen { -+ compatible = "st,stmpe-ts"; -+ st,sample-time = <4>; -+ st,mod-12b = <1>; -+ st,ref-sel = <0>; -+ st,adc-freq = <2>; -+ st,ave-ctrl = <3>; -+ st,touch-det-delay = <4>; -+ st,settling = <2>; -+ st,fraction-z = <7>; -+ st,i-drive = <0>; -+ }; -+ -+ stmpe_gpio: stmpe_gpio { -+ #gpio-cells = <2>; -+ compatible = "st,stmpe-gpio"; -+ /* -+ * only GPIO2 is wired/available -+ * and it is wired to the backlight -+ */ -+ st,norequest-mask = <0x7b>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/soc"; -+ __overlay__ { -+ backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&stmpe_gpio 2 0>; -+ default-on; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&pitft>,"spi-max-frequency:0"; -+ rotate = <&pitft>,"rotate:0"; -+ fps = <&pitft>,"fps:0"; -+ debug = <&pitft>,"debug:0"; -+ }; -+}; - -From 917597bfd056d8d37b02a21e7ea4e56023a3e630 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 2 Mar 2015 09:37:02 +0000 -Subject: [PATCH 094/216] enable compiling spi-bcm2835 and add overlay to allow - us to load the driver - ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/spi-bcm2835-overlay.dts | 18 ++++++++++++++++++ - 2 files changed, 19 insertions(+) - create mode 100644 arch/arm/boot/dts/spi-bcm2835-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 07c6eeb..e83179f 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -33,6 +33,7 @@ dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb - - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -diff --git a/arch/arm/boot/dts/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/spi-bcm2835-overlay.dts -new file mode 100644 -index 0000000..fc1e39b ---- /dev/null -+++ b/arch/arm/boot/dts/spi-bcm2835-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2835-spi"; -+ }; -+ }; -+}; - -From 58f834d50fb0e6eb0f1a8c48bdb3551866addc62 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 7 Mar 2015 20:39:30 +0100 -Subject: [PATCH 095/216] dts: overlay: add support for MZ61581 display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for MZ61581 display by Tontec. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/mz61581-overlay.dts | 109 ++++++++++++++++++++++++++++++++++ - 2 files changed, 110 insertions(+) - create mode 100644 arch/arm/boot/dts/mz61581-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index e83179f..f99eccf 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -25,6 +25,7 @@ dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -diff --git a/arch/arm/boot/dts/mz61581-overlay.dts b/arch/arm/boot/dts/mz61581-overlay.dts -new file mode 100644 -index 0000000..c06fe12 ---- /dev/null -+++ b/arch/arm/boot/dts/mz61581-overlay.dts -@@ -0,0 +1,109 @@ -+/* -+ * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ mz61581_pins: mz61581_pins { -+ brcm,pins = <4 15 18 25>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mz61581: mz61581@0{ -+ compatible = "samsung,s6d02a1"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mz61581_pins>; -+ -+ spi-max-frequency = <128000000>; -+ spi-cpol; -+ spi-cpha; -+ -+ width = <320>; -+ height = <480>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ -+ reset-gpios = <&gpio 15 0>; -+ dc-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 0>; -+ -+ init = <0x10000b0 00 -+ 0x1000011 -+ 0x20000ff -+ 0x10000b3 0x02 0x00 0x00 0x00 -+ 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 -+ 0x10000c1 0x08 0x16 0x08 0x08 -+ 0x10000c4 0x11 0x07 0x03 0x03 -+ 0x10000c6 0x00 -+ 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 -+ 0x1000035 0x00 -+ 0x1000036 0xa0 -+ 0x100003a 0x55 -+ 0x1000044 0x00 0x01 -+ 0x10000d0 0x07 0x07 0x1d 0x03 -+ 0x10000d1 0x03 0x30 0x10 -+ 0x10000d2 0x03 0x14 0x04 -+ 0x1000029 -+ 0x100002c>; -+ -+ /* This is a workaround to make sure the init sequence slows down and doesn't fail */ -+ debug = <3>; -+ }; -+ -+ mz61581_ts: mz61581_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <4 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 4 0>; -+ -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&mz61581>, "spi-max-frequency:0"; -+ rotate = <&mz61581>, "rotate:0"; -+ fps = <&mz61581>, "fps:0"; -+ debug = <&mz61581>, "debug:0"; -+ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; - -From 080c66dfc13694a3c6123d6732d6255361e49733 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 7 Mar 2015 20:40:07 +0100 -Subject: [PATCH 096/216] dts: overlay: piscreen: set speed to 24MHz -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some of the displays can't handle the 32MHz speed. -Lower the default speed to 24MHz. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/piscreen-overlay.dts | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/piscreen-overlay.dts b/arch/arm/boot/dts/piscreen-overlay.dts -index 8cd6a95..b7fd7ea 100644 ---- a/arch/arm/boot/dts/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/piscreen-overlay.dts -@@ -47,7 +47,7 @@ - pinctrl-names = "default"; - pinctrl-0 = <&piscreen_pins>; - -- spi-max-frequency = <32000000>; -+ spi-max-frequency = <24000000>; - rotate = <270>; - bgr; - fps = <30>; - -From c34aef0866b8605b64dd7b7c1bf4c1db77933089 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 7 Mar 2015 20:40:43 +0100 -Subject: [PATCH 097/216] dts: overlay: rpi-display: pullup irq gpio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -An early version of rpi-display needs the touch controller irq -to be pulled up. This is the version with 9-bit SPI as default. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/rpi-display-overlay.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/rpi-display-overlay.dts b/arch/arm/boot/dts/rpi-display-overlay.dts -index 0578810..a8fa974 100644 ---- a/arch/arm/boot/dts/rpi-display-overlay.dts -+++ b/arch/arm/boot/dts/rpi-display-overlay.dts -@@ -30,6 +30,7 @@ - rpi_display_pins: rpi_display_pins { - brcm,pins = <18 23 24 25>; - brcm,function = <1 1 1 0>; /* out out out in */ -+ brcm,pull = <0 0 0 2>; /* - - - up */ - }; - }; - }; - -From 7268b2f16833d36f6568add569f15325b398497b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 24 Mar 2015 14:48:30 +0100 -Subject: [PATCH 098/216] BCM270x_DT: add bcm2835-dma entry -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree entry for bcm2835-dma. -The entry doesn't contain any resources since they are handled -by the arch/arm/mach-bcm270x/dma.c driver. -In non-DT mode, don't add the device in the board file. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708.dtsi | 5 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 5 +++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 4 files changed, 12 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 0713a1ed..846f148 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -17,6 +17,11 @@ - #size-cells = <1>; - ranges = <0x7e000000 0x20000000 0x01000000>; - -+ dma: dma@7e007000 { -+ compatible = "brcm,bcm2835-dma"; -+ #dma-cells = <1>; -+ }; -+ - intc: interrupt-controller { - compatible = "brcm,bcm2708-armctrl-ic"; - reg = <0x7e00b200 0x200>; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index 34d2226..d468363 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -17,6 +17,11 @@ - #size-cells = <1>; - ranges = <0x7e000000 0x3f000000 0x01000000>; - -+ dma: dma@7e007000 { -+ compatible = "brcm,bcm2835-dma"; -+ #dma-cells = <1>; -+ }; -+ - intc: interrupt-controller { - compatible = "brcm,bcm2708-armctrl-ic"; - reg = <0x7e00b200 0x200>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index c8aea5b..6a08e95 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -857,7 +857,7 @@ void __init bcm2708_init(void) - bcm2708_dt_init(); - - bcm_register_device(&bcm2708_dmaman_device); -- bcm_register_device(&bcm2708_dmaengine_device); -+ bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 259d552..3c1c1dc 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -879,7 +879,7 @@ void __init bcm2709_init(void) - bcm2709_dt_init(); - - bcm_register_device(&bcm2708_dmaman_device); -- bcm_register_device(&bcm2708_dmaengine_device); -+ bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - -From ccc2b25ac7ffe4252a482901541a1894c86bb4c3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 24 Mar 2015 14:50:19 +0100 -Subject: [PATCH 099/216] bcm270x: add mmc-bcm2835 clock -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add clock for the mmc-bcm2835.0 device. -Will be used in non-DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 1 + - arch/arm/mach-bcm2709/bcm2709.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6a08e95..b5f22e2 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -233,6 +233,7 @@ void __init bcm2708_init_clocks(void) - bcm2708_register_clkdev(clk, "dev:f1"); - - clk = bcm2708_clk_register("sdhost_clk", 250000000); -+ bcm2708_register_clkdev(clk, "mmc-bcm2835.0"); - bcm2708_register_clkdev(clk, "bcm2708_spi.0"); - bcm2708_register_clkdev(clk, "bcm2708_i2c.0"); - bcm2708_register_clkdev(clk, "bcm2708_i2c.1"); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 3c1c1dc..e10667d 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -243,6 +243,7 @@ void __init bcm2709_init_clocks(void) - bcm2709_register_clkdev(clk, "dev:f1"); - - clk = bcm2709_clk_register("sdhost_clk", 250000000); -+ bcm2709_register_clkdev(clk, "mmc-bcm2835.0"); - bcm2709_register_clkdev(clk, "bcm2708_spi.0"); - bcm2709_register_clkdev(clk, "bcm2708_i2c.0"); - bcm2709_register_clkdev(clk, "bcm2708_i2c.1"); - -From 7520bcefca288277ace88e3df254045eee89c189 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 24 Mar 2015 15:12:35 +0100 -Subject: [PATCH 100/216] BCM270x_DT: add bcm2835-mmc entry -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree entry for bcm2835-mmc. -In non-DT mode, don't add the device in the board file. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 5 +++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 5 +++++ - arch/arm/boot/dts/bcm2708.dtsi | 19 +++++++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 5 +++++ - arch/arm/boot/dts/bcm2709.dtsi | 19 +++++++++++++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 7 files changed, 55 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 7f84473..f25563a 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -44,6 +44,11 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index a39562f..17b4b8c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -44,6 +44,11 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 846f148..42edda5 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -41,6 +41,17 @@ - #interrupt-cells = <2>; - }; - -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; - reg = <0x7e203000 0x20>, -@@ -96,6 +107,14 @@ - #address-cells = <1>; - #size-cells = <0>; - -+ clk_mmc: clock@0 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "mmc"; -+ clock-frequency = <250000000>; -+ }; -+ - clk_i2c: i2c { - compatible = "fixed-clock"; - reg = <1>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 75c222f..c73249b 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -44,6 +44,11 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index d468363..bd6605d 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -41,6 +41,17 @@ - #interrupt-cells = <2>; - }; - -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; - reg = <0x7e203000 0x20>, -@@ -97,6 +108,14 @@ - #address-cells = <1>; - #size-cells = <0>; - -+ clk_mmc: clock@0 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "mmc"; -+ clock-frequency = <250000000>; -+ }; -+ - clk_i2c: i2c { - compatible = "fixed-clock"; - reg = <1>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index b5f22e2..16ba248 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -885,7 +885,7 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 -- bcm_register_device(&bcm2835_emmc_device); -+ bcm_register_device_dt(&bcm2835_emmc_device); - #endif - bcm2708_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index e10667d..dcad008 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -909,7 +909,7 @@ void __init bcm2709_init(void) - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 -- bcm_register_device(&bcm2835_emmc_device); -+ bcm_register_device_dt(&bcm2835_emmc_device); - #endif - bcm2709_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - -From 7504524f3f951bf8c40c5decf231ea6538d1380b Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 27 Mar 2015 11:45:44 +0000 -Subject: [PATCH 101/216] BCM270x_DT: Refactor bcm2708.dtsi and bcm2709.dtsi - -Extract the common elements, creating bcm2708_common.dtsi ---- - arch/arm/boot/dts/bcm2708.dtsi | 118 +-------------------------------- - arch/arm/boot/dts/bcm2708_common.dtsi | 120 ++++++++++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2709.dtsi | 118 +-------------------------------- - 3 files changed, 124 insertions(+), 232 deletions(-) - create mode 100644 arch/arm/boot/dts/bcm2708_common.dtsi - -diff --git a/arch/arm/boot/dts/bcm2708.dtsi b/arch/arm/boot/dts/bcm2708.dtsi -index 42edda5..0d47427 100644 ---- a/arch/arm/boot/dts/bcm2708.dtsi -+++ b/arch/arm/boot/dts/bcm2708.dtsi -@@ -1,133 +1,19 @@ --/include/ "skeleton.dtsi" -+/include/ "bcm2708_common.dtsi" - - / { - compatible = "brcm,bcm2708"; - model = "BCM2708"; - -- interrupt-parent = <&intc>; -- - chosen { - /* No padding required - the boot loader can do that. */ - bootargs = ""; - }; - -- soc: soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -+ soc { - ranges = <0x7e000000 0x20000000 0x01000000>; - -- dma: dma@7e007000 { -- compatible = "brcm,bcm2835-dma"; -- #dma-cells = <1>; -- }; -- -- intc: interrupt-controller { -- compatible = "brcm,bcm2708-armctrl-ic"; -- reg = <0x7e00b200 0x200>; -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- gpio: gpio { -- compatible = "brcm,bcm2835-gpio"; -- reg = <0x7e200000 0xb4>; -- interrupts = <2 17>, <2 18>; -- -- gpio-controller; -- #gpio-cells = <2>; -- -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- mmc: mmc@7e300000 { -- compatible = "brcm,bcm2835-mmc"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- i2s: i2s@7e203000 { -- compatible = "brcm,bcm2708-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -- -- //dmas = <&dma 2>, -- // <&dma 3>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- spi0: spi@7e204000 { -- compatible = "brcm,bcm2708-spi"; -- reg = <0x7e204000 0x1000>; -- interrupts = <2 22>; -- clocks = <&clk_spi>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c0: i2c@7e205000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e205000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c1: i2c@7e804000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e804000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- leds: leds { -- compatible = "gpio-leds"; -- }; -- - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; - }; -- -- clocks { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_mmc: clock@0 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "mmc"; -- clock-frequency = <250000000>; -- }; -- -- clk_i2c: i2c { -- compatible = "fixed-clock"; -- reg = <1>; -- #clock-cells = <0>; -- clock-frequency = <250000000>; -- }; -- -- clk_spi: clock@2 { -- compatible = "fixed-clock"; -- reg = <2>; -- #clock-cells = <0>; -- clock-output-names = "spi"; -- clock-frequency = <250000000>; -- }; -- }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -new file mode 100644 -index 0000000..ff70c58 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -0,0 +1,120 @@ -+/include/ "skeleton.dtsi" -+ -+/ { -+ interrupt-parent = <&intc>; -+ -+ soc: soc { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ dma: dma@7e007000 { -+ compatible = "brcm,bcm2835-dma"; -+ #dma-cells = <1>; -+ }; -+ -+ intc: interrupt-controller { -+ compatible = "brcm,bcm2708-armctrl-ic"; -+ reg = <0x7e00b200 0x200>; -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ gpio: gpio { -+ compatible = "brcm,bcm2835-gpio"; -+ reg = <0x7e200000 0xb4>; -+ interrupts = <2 17>, <2 18>; -+ -+ gpio-controller; -+ #gpio-cells = <2>; -+ -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ }; -+ -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; -+ reg = <0x7e300000 0x100>; -+ interrupts = <2 30>; -+ clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ i2s: i2s@7e203000 { -+ compatible = "brcm,bcm2708-i2s"; -+ reg = <0x7e203000 0x20>, -+ <0x7e101098 0x02>; -+ -+ //dmas = <&dma 2>, -+ // <&dma 3>; -+ dma-names = "tx", "rx"; -+ status = "disabled"; -+ }; -+ -+ spi0: spi@7e204000 { -+ compatible = "brcm,bcm2708-spi"; -+ reg = <0x7e204000 0x1000>; -+ interrupts = <2 22>; -+ clocks = <&clk_spi>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c0: i2c@7e205000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e205000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ i2c1: i2c@7e804000 { -+ compatible = "brcm,bcm2708-i2c"; -+ reg = <0x7e804000 0x1000>; -+ interrupts = <2 21>; -+ clocks = <&clk_i2c>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "disabled"; -+ }; -+ -+ leds: leds { -+ compatible = "gpio-leds"; -+ }; -+ }; -+ -+ clocks { -+ compatible = "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_mmc: clock@0 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "mmc"; -+ clock-frequency = <250000000>; -+ }; -+ -+ clk_i2c: i2c { -+ compatible = "fixed-clock"; -+ reg = <1>; -+ #clock-cells = <0>; -+ clock-frequency = <250000000>; -+ }; -+ -+ clk_spi: clock@2 { -+ compatible = "fixed-clock"; -+ reg = <2>; -+ #clock-cells = <0>; -+ clock-output-names = "spi"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2709.dtsi b/arch/arm/boot/dts/bcm2709.dtsi -index bd6605d..5e0b935 100644 ---- a/arch/arm/boot/dts/bcm2709.dtsi -+++ b/arch/arm/boot/dts/bcm2709.dtsi -@@ -1,137 +1,23 @@ --/include/ "skeleton.dtsi" -+/include/ "bcm2708_common.dtsi" - - / { - compatible = "brcm,bcm2709"; - model = "BCM2709"; - -- interrupt-parent = <&intc>; -- - chosen { - /* No padding required - the boot loader can do that. */ - bootargs = ""; - }; - -- soc: soc { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <1>; -+ soc { - ranges = <0x7e000000 0x3f000000 0x01000000>; - -- dma: dma@7e007000 { -- compatible = "brcm,bcm2835-dma"; -- #dma-cells = <1>; -- }; -- -- intc: interrupt-controller { -- compatible = "brcm,bcm2708-armctrl-ic"; -- reg = <0x7e00b200 0x200>; -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- gpio: gpio { -- compatible = "brcm,bcm2835-gpio"; -- reg = <0x7e200000 0xb4>; -- interrupts = <2 17>, <2 18>; -- -- gpio-controller; -- #gpio-cells = <2>; -- -- interrupt-controller; -- #interrupt-cells = <2>; -- }; -- -- mmc: mmc@7e300000 { -- compatible = "brcm,bcm2835-mmc"; -- reg = <0x7e300000 0x100>; -- interrupts = <2 30>; -- clocks = <&clk_mmc>; -- dmas = <&dma 11>, -- <&dma 11>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- i2s: i2s@7e203000 { -- compatible = "brcm,bcm2708-i2s"; -- reg = <0x7e203000 0x20>, -- <0x7e101098 0x02>; -- -- //dmas = <&dma 2>, -- // <&dma 3>; -- dma-names = "tx", "rx"; -- status = "disabled"; -- }; -- -- spi0: spi@7e204000 { -- compatible = "brcm,bcm2708-spi"; -- reg = <0x7e204000 0x1000>; -- interrupts = <2 22>; -- clocks = <&clk_spi>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c0: i2c@7e205000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e205000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- i2c1: i2c@7e804000 { -- compatible = "brcm,bcm2708-i2c"; -- reg = <0x7e804000 0x1000>; -- interrupts = <2 21>; -- clocks = <&clk_i2c>; -- #address-cells = <1>; -- #size-cells = <0>; -- status = "disabled"; -- }; -- -- leds: leds { -- compatible = "gpio-leds"; -- }; -- - arm-pmu { - compatible = "arm,cortex-a7-pmu"; - interrupts = <3 9>; - }; - }; - -- clocks { -- compatible = "simple-bus"; -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_mmc: clock@0 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "mmc"; -- clock-frequency = <250000000>; -- }; -- -- clk_i2c: i2c { -- compatible = "fixed-clock"; -- reg = <1>; -- #clock-cells = <0>; -- clock-frequency = <250000000>; -- }; -- -- clk_spi: clock@2 { -- compatible = "fixed-clock"; -- reg = <2>; -- #clock-cells = <0>; -- clock-output-names = "spi"; -- clock-frequency = <250000000>; -- }; -- }; -- - timer { - compatible = "arm,armv7-timer"; - clock-frequency = <19200000>; - -From 5d44aea95dbfd69851ffeb426ccf419f5894e70e Mon Sep 17 00:00:00 2001 +From 331cdec0de30933d5e7839f0e3def9b98d3fa968 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Wed, 25 Mar 2015 09:26:17 +0100 -Subject: [PATCH 102/216] Add driver for rpi-proto +Subject: [PATCH 62/77] Add driver for rpi-proto Forward port of 3.10.x driver from https://github.com/koalo We are using a custom board and would like to use rpi 3.18.x @@ -128380,74 +128063,14 @@ Playback tested with devicetree enabled. Signed-off-by: Waldemar Brodkorb --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/rpi-proto-overlay.dts | 39 ++++++++ - sound/soc/bcm/Kconfig | 7 ++ - sound/soc/bcm/Makefile | 2 + - sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++ - 5 files changed, 202 insertions(+) - create mode 100644 arch/arm/boot/dts/rpi-proto-overlay.dts + sound/soc/bcm/Kconfig | 7 +++ + sound/soc/bcm/Makefile | 2 + + sound/soc/bcm/rpi-proto.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 162 insertions(+) create mode 100644 sound/soc/bcm/rpi-proto.c -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index f99eccf..daf51d2 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -24,6 +24,7 @@ dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb -diff --git a/arch/arm/boot/dts/rpi-proto-overlay.dts b/arch/arm/boot/dts/rpi-proto-overlay.dts -new file mode 100644 -index 0000000..2029930 ---- /dev/null -+++ b/arch/arm/boot/dts/rpi-proto-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for Rpi-Proto -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-proto"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8731@1a { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8731"; -+ reg = <0x1a>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 40d27c1..003ae28 100644 +index bdcf12f..fc151ea 100644 --- a/sound/soc/bcm/Kconfig +++ b/sound/soc/bcm/Kconfig @@ -54,6 +54,13 @@ config SND_BCM2708_SOC_RPI_DAC @@ -128456,14 +128079,14 @@ index 40d27c1..003ae28 100644 +config SND_BCM2708_SOC_RPI_PROTO + tristate "Support for Rpi-PROTO" -+ depends on SND_BCM2708_SOC_I2S ++ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S + select SND_SOC_WM8731 + help + Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731). + config SND_BCM2708_SOC_IQAUDIO_DAC tristate "Support for IQaudIO-DAC" - depends on SND_BCM2708_SOC_I2S + depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S diff --git a/sound/soc/bcm/Makefile b/sound/soc/bcm/Makefile index 17ea2b0..883241b 100644 --- a/sound/soc/bcm/Makefile @@ -128642,71 +128265,16 @@ index 0000000..c6e45a0 +MODULE_DESCRIPTION("ASoC Driver for Raspberry Pi connected to PROTO board (WM8731)"); +MODULE_LICENSE("GPL"); -From b1c2c58f341642e8bcc337b592f19d5543ae51ad Mon Sep 17 00:00:00 2001 +From 2079392f1bde4f50d8c1ad65c2f7b52a6ff34848 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Thu, 2 Apr 2015 12:22:55 +0100 -Subject: [PATCH 103/216] Add Device Tree support for RPi-DAC. +Subject: [PATCH 63/77] Add Device Tree support for RPi-DAC. --- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/rpi-dac-overlay.dts | 34 ++++++++++++++++++++++++++++++++++ - sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++ - sound/soc/codecs/pcm1794a.c | 7 +++++++ - 4 files changed, 63 insertions(+) - create mode 100644 arch/arm/boot/dts/rpi-dac-overlay.dts + sound/soc/bcm/rpi-dac.c | 21 +++++++++++++++++++++ + sound/soc/codecs/pcm1794a.c | 7 +++++++ + 2 files changed, 28 insertions(+) -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index daf51d2..980b78e0 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -24,6 +24,7 @@ dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -diff --git a/arch/arm/boot/dts/rpi-dac-overlay.dts b/arch/arm/boot/dts/rpi-dac-overlay.dts -new file mode 100644 -index 0000000..7fc6ac9 ---- /dev/null -+++ b/arch/arm/boot/dts/rpi-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for RPi DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm1794a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm1794a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; diff --git a/sound/soc/bcm/rpi-dac.c b/sound/soc/bcm/rpi-dac.c index 6d6e0ba..d5fac1b 100644 --- a/sound/soc/bcm/rpi-dac.c @@ -128775,24 +128343,24 @@ index b4eaa44..afe1b41 100644 }; -From c3bd8511bef07e4a3ebf9e78fc1ed0889aaf1d62 Mon Sep 17 00:00:00 2001 +From 4725644a3f7c09811486c1324f9653e79ecbdcb7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Apr 2015 17:16:29 +0100 -Subject: [PATCH 104/216] config: Add default configs +Subject: [PATCH 64/77] config: Add default configs --- - arch/arm/configs/bcm2709_defconfig | 1191 ++++++++++++++++++++++++++++++++++++ - arch/arm/configs/bcmrpi_defconfig | 1186 +++++++++++++++++++++++++++++++++++ - 2 files changed, 2377 insertions(+) + arch/arm/configs/bcm2709_defconfig | 1204 ++++++++++++++++++++++++++++++++++++ + arch/arm/configs/bcmrpi_defconfig | 1199 +++++++++++++++++++++++++++++++++++ + 2 files changed, 2403 insertions(+) create mode 100644 arch/arm/configs/bcm2709_defconfig create mode 100644 arch/arm/configs/bcmrpi_defconfig diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig new file mode 100644 -index 0000000..7cec5f8 +index 0000000..a3067bf --- /dev/null +++ b/arch/arm/configs/bcm2709_defconfig -@@ -0,0 +1,1191 @@ +@@ -0,0 +1,1204 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +CONFIG_LOCALVERSION="-v7" @@ -129315,7 +128883,8 @@ index 0000000..7cec5f8 +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m -+# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m @@ -129350,6 +128919,7 @@ index 0000000..7cec5f8 +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y +CONFIG_BRCM_CHAR_DRIVERS=y @@ -129392,6 +128962,7 @@ index 0000000..7cec5f8 +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y +CONFIG_BCM2708_WDT=m ++CONFIG_BCM2835_WDT=m +CONFIG_UCB1400_CORE=m +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y @@ -129564,6 +129135,7 @@ index 0000000..7cec5f8 +CONFIG_VIDEO_MT9V011=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y ++CONFIG_FB_SSD1307=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -129751,6 +129323,7 @@ index 0000000..7cec5f8 +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835=y +CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=m @@ -129846,9 +129419,16 @@ index 0000000..7cec5f8 +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2708_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_DHT11=m +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -129910,6 +129490,7 @@ index 0000000..7cec5f8 +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_9P_FS=m @@ -129986,10 +129567,10 @@ index 0000000..7cec5f8 +CONFIG_LIBCRC32C=y diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig new file mode 100644 -index 0000000..e77173b +index 0000000..6a41231 --- /dev/null +++ b/arch/arm/configs/bcmrpi_defconfig -@@ -0,0 +1,1186 @@ +@@ -0,0 +1,1199 @@ +# CONFIG_ARM_PATCH_PHYS_VIRT is not set +CONFIG_PHYS_OFFSET=0 +# CONFIG_LOCALVERSION_AUTO is not set @@ -130505,7 +130086,8 @@ index 0000000..e77173b +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=m -+# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_IFORCE=m @@ -130540,6 +130122,7 @@ index 0000000..e77173b +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_TTY_PRINTK=y +CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_BCM2835=m +CONFIG_HW_RANDOM_BCM2708=m +CONFIG_RAW_DRIVER=y +CONFIG_BRCM_CHAR_DRIVERS=y @@ -130582,6 +130165,7 @@ index 0000000..e77173b +CONFIG_THERMAL_BCM2835=y +CONFIG_WATCHDOG=y +CONFIG_BCM2708_WDT=m ++CONFIG_BCM2835_WDT=m +CONFIG_UCB1400_CORE=m +CONFIG_MFD_STMPE=y +CONFIG_STMPE_SPI=y @@ -130754,6 +130338,7 @@ index 0000000..e77173b +CONFIG_VIDEO_MT9V011=m +CONFIG_FB=y +CONFIG_FB_BCM2708=y ++CONFIG_FB_SSD1307=m +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_GPIO=m +CONFIG_FRAMEBUFFER_CONSOLE=y @@ -130941,6 +130526,7 @@ index 0000000..e77173b +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_BCM2835=y +CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SPI=m @@ -131036,9 +130622,16 @@ index 0000000..e77173b +CONFIG_FB_TFT_WATTEROTT=m +CONFIG_FB_FLEX=m +CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2708_MBOX=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXTCON=m +CONFIG_EXTCON_ARIZONA=m ++CONFIG_IIO=m ++CONFIG_IIO_BUFFER=y ++CONFIG_IIO_BUFFER_CB=y ++CONFIG_IIO_KFIFO_BUF=m ++CONFIG_DHT11=m +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y @@ -131100,6 +130693,7 @@ index 0000000..e77173b +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_9P_FS=m @@ -131177,1110 +130771,10 @@ index 0000000..e77173b +CONFIG_CRC_ITU_T=y +CONFIG_LIBCRC32C=y -From 196c354f9d8f85f9e56bd2ce11113883f98bccaa Mon Sep 17 00:00:00 2001 -From: Jakub Kicinski -Date: Mon, 2 Mar 2015 16:34:37 +0100 -Subject: [PATCH 105/216] bcm2708: fix uart1 parameters - -System clock is 250MHz, but the device uses a non-standard -oversampling rate (8 instead of 16) hence the clock rate -has to be multiplied by 16/8 = 2. Currently the clock -rate seems to be divided by 2. - -Also correct the .type and .flags. - -Signed-off-by: Jakub Kicinski ---- - arch/arm/mach-bcm2708/bcm2708.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 16ba248..b848e4a 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -312,11 +312,12 @@ static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { - { - .mapbase = UART1_BASE + 0x40, - .irq = IRQ_AUX, -- .uartclk = 125000000, -+ .uartclk = 500000000, - .regshift = 2, - .iotype = UPIO_MEM, -- .flags = UPF_FIXED_TYPE | UPF_IOREMAP | UPF_SKIP_TEST, -- .type = PORT_8250, -+ .flags = UPF_SHARE_IRQ | UPF_FIXED_TYPE | UPF_FIXED_PORT | -+ UPF_IOREMAP | UPF_SKIP_TEST, -+ .type = PORT_16550, - }, - {}, - }; - -From 8243fc28ee2c92452173c695fdb7990e3758fdc3 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Fri, 20 Mar 2015 15:26:11 +0100 -Subject: [PATCH 106/216] spi: bcm2835: fix all checkpath --strict messages - -The following errors/warnings issued by checkpatch.pl --strict have been fixed: -drivers/spi/spi-bcm2835.c:182: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:191: CHECK: braces {} should be used on all arms of this statement -drivers/spi/spi-bcm2835.c:234: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:256: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:271: CHECK: Alignment should match open parenthesis -drivers/spi/spi-bcm2835.c:346: CHECK: Alignment should match open parenthesis -total: 0 errors, 0 warnings, 6 checks, 403 lines checked - -In 2 locations the arguments had to get split/moved to the next line so that the -line width stays below 80 chars. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 419a782..779d3a8 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -179,7 +179,7 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - } - - static int bcm2835_spi_start_transfer(struct spi_device *spi, -- struct spi_transfer *tfr) -+ struct spi_transfer *tfr) - { - struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); - unsigned long spi_hz, clk_hz, cdiv; -@@ -196,8 +196,9 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - - if (cdiv >= 65536) - cdiv = 0; /* 0 is the slowest we can go */ -- } else -+ } else { - cdiv = 0; /* 0 is the slowest we can go */ -+ } - - if (spi->mode & SPI_CPOL) - cs |= BCM2835_SPI_CS_CPOL; -@@ -231,7 +232,8 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - } - - static int bcm2835_spi_finish_transfer(struct spi_device *spi, -- struct spi_transfer *tfr, bool cs_change) -+ struct spi_transfer *tfr, -+ bool cs_change) - { - struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -@@ -253,7 +255,7 @@ static int bcm2835_spi_finish_transfer(struct spi_device *spi, - } - - static int bcm2835_spi_transfer_one(struct spi_master *master, -- struct spi_message *mesg) -+ struct spi_message *mesg) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - struct spi_transfer *tfr; -@@ -267,8 +269,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - if (err) - goto out; - -- timeout = wait_for_completion_timeout(&bs->done, -- msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS)); -+ timeout = wait_for_completion_timeout( -+ &bs->done, -+ msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS) -+ ); - if (!timeout) { - err = -ETIMEDOUT; - goto out; -@@ -343,7 +347,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - clk_prepare_enable(bs->clk); - - err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, -- dev_name(&pdev->dev), master); -+ dev_name(&pdev->dev), master); - if (err) { - dev_err(&pdev->dev, "could not request IRQ: %d\n", err); - goto out_clk_disable; - -From 54e38f321ea8bb1990d6f496c0710532224a35ad Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 23 Mar 2015 15:11:53 +0100 -Subject: [PATCH 107/216] spi: bcm2835: fill/drain SPI-fifo as much as possible - during interrupt - -Implement the recommendation from the BCM2835 data-sheet -with regards to polling drivers to fill/drain the FIFO as much data as possible -also for the interrupt-driven case (which this driver is making use of). - -This means that for long transfers (>64bytes) we need one interrupt -every 64 bytes instead of every 12 bytes, as the FIFO is 16 words (not bytes) wide. - -Tested with mcp251x (can bus), fb_st7735 (TFT framebuffer device) -and enc28j60 (ethernet) drivers. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 78 +++++++++++------------------------------------ - 1 file changed, 17 insertions(+), 61 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 779d3a8..960dcce 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -91,25 +91,23 @@ static inline void bcm2835_wr(struct bcm2835_spi *bs, unsigned reg, u32 val) - writel(val, bs->regs + reg); - } - --static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs, int len) -+static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- while (len--) { -+ while (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD) { - byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); - if (bs->rx_buf) - *bs->rx_buf++ = byte; - } - } - --static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs, int len) -+static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- if (len > bs->len) -- len = bs->len; -- -- while (len--) { -+ while ((bs->len) && -+ (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) { - byte = bs->tx_buf ? *bs->tx_buf++ : 0; - bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); - bs->len--; -@@ -122,60 +120,24 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - struct bcm2835_spi *bs = spi_master_get_devdata(master); - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - -- /* -- * RXR - RX needs Reading. This means 12 (or more) bytes have been -- * transmitted and hence 12 (or more) bytes have been received. -- * -- * The FIFO is 16-bytes deep. We check for this interrupt to keep the -- * FIFO full; we have a 4-byte-time buffer for IRQ latency. We check -- * this before DONE (TX empty) just in case we delayed processing this -- * interrupt for some reason. -- * -- * We only check for this case if we have more bytes to TX; at the end -- * of the transfer, we ignore this pipelining optimization, and let -- * bcm2835_spi_finish_transfer() drain the RX FIFO. -- */ -- if (bs->len && (cs & BCM2835_SPI_CS_RXR)) { -- /* Read 12 bytes of data */ -- bcm2835_rd_fifo(bs, 12); -+ /* Read as many bytes as possible from FIFO */ -+ bcm2835_rd_fifo(bs); - -- /* Write up to 12 bytes */ -- bcm2835_wr_fifo(bs, 12); -+ if (bs->len) { /* there is more data to transmit */ -+ bcm2835_wr_fifo(bs); -+ } else { /* Transfer complete */ -+ /* Disable SPI interrupts */ -+ cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); - - /* -- * We must have written something to the TX FIFO due to the -- * bs->len check above, so cannot be DONE. Hence, return -- * early. Note that DONE could also be set if we serviced an -- * RXR interrupt really late. -+ * Wake up bcm2835_spi_transfer_one(), which will call -+ * bcm2835_spi_finish_transfer(), to drain the RX FIFO. - */ -- return IRQ_HANDLED; -+ complete(&bs->done); - } - -- /* -- * DONE - TX empty. This occurs when we first enable the transfer -- * since we do not pre-fill the TX FIFO. At any other time, given that -- * we refill the TX FIFO above based on RXR, and hence ignore DONE if -- * RXR is set, DONE really does mean end-of-transfer. -- */ -- if (cs & BCM2835_SPI_CS_DONE) { -- if (bs->len) { /* First interrupt in a transfer */ -- bcm2835_wr_fifo(bs, 16); -- } else { /* Transfer complete */ -- /* Disable SPI interrupts */ -- cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); -- bcm2835_wr(bs, BCM2835_SPI_CS, cs); -- -- /* -- * Wake up bcm2835_spi_transfer_one(), which will call -- * bcm2835_spi_finish_transfer(), to drain the RX FIFO. -- */ -- complete(&bs->done); -- } -- -- return IRQ_HANDLED; -- } -- -- return IRQ_NONE; -+ return IRQ_HANDLED; - } - - static int bcm2835_spi_start_transfer(struct spi_device *spi, -@@ -238,12 +200,6 @@ static int bcm2835_spi_finish_transfer(struct spi_device *spi, - struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - -- /* Drain RX FIFO */ -- while (cs & BCM2835_SPI_CS_RXD) { -- bcm2835_rd_fifo(bs, 1); -- cs = bcm2835_rd(bs, BCM2835_SPI_CS); -- } -- - if (tfr->delay_usecs) - udelay(tfr->delay_usecs); - - -From 52469b2a3843dbd5aad2109a73e1b41371f83be3 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 19 Mar 2015 09:01:52 +0000 -Subject: [PATCH 108/216] spi: bcm2835: clock divider can be a multiple of 2 - -The official documentation is wrong in this respect. -Has been tested empirically for dividers 2-1024 - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 960dcce..8de1925 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -153,8 +153,9 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - if (spi_hz >= clk_hz / 2) { - cdiv = 2; /* clk_hz/2 is the fastest we can go */ - } else if (spi_hz) { -- /* CDIV must be a power of two */ -- cdiv = roundup_pow_of_two(DIV_ROUND_UP(clk_hz, spi_hz)); -+ /* CDIV must be a multiple of two */ -+ cdiv = DIV_ROUND_UP(clk_hz, spi_hz); -+ cdiv += (cdiv % 2); - - if (cdiv >= 65536) - cdiv = 0; /* 0 is the slowest we can go */ - -From b3622510de92a35d73778905be9ab4ad4235bd66 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 19 Mar 2015 09:01:53 +0000 -Subject: [PATCH 109/216] spi: bcm2835: enable support of 3-wire mode - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 8de1925..3f93718 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -67,7 +67,8 @@ - #define BCM2835_SPI_CS_CS_01 0x00000001 - - #define BCM2835_SPI_TIMEOUT_MS 30000 --#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_NO_CS) -+#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ -+ | SPI_NO_CS | SPI_3WIRE) - - #define DRV_NAME "spi-bcm2835" - -@@ -163,6 +164,9 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - cdiv = 0; /* 0 is the slowest we can go */ - } - -+ if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) -+ cs |= BCM2835_SPI_CS_REN; -+ - if (spi->mode & SPI_CPOL) - cs |= BCM2835_SPI_CS_CPOL; - if (spi->mode & SPI_CPHA) - -From c71501bcc7b07a82119e2f7b27309a62f90aa02a Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 26 Mar 2015 11:08:36 +0100 -Subject: [PATCH 110/216] spi: bcm2835: move to the transfer_one driver model - -This also allows for GPIO-CS to get used removing the limitation of -2/3 SPI devises on the SPI bus. - -Fixes: spi-cs-high with native CS with multiple devices on the spi-bus -resetting the chip selects to "normal" polarity after a finished -transfer. - -No other functionality/improvements added. - -Tested with the following 4 devices on the spi-bus: -* mcp2515 with native CS -* mcp2515 with gpio CS -* fb_st7735r with native CS - (plus spi-cs-high via transistor inverting polarity) -* enc28j60 with gpio-CS -Tested-by: Martin Sperl - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 212 +++++++++++++++++++++++++++------------------- - 1 file changed, 124 insertions(+), 88 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 3f93718..31d80eb0 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -3,6 +3,7 @@ - * - * Copyright (C) 2012 Chris Boot - * Copyright (C) 2013 Stephen Warren -+ * Copyright (C) 2015 Martin Sperl - * - * This driver is inspired by: - * spi-ath79.c, Copyright (C) 2009-2011 Gabor Juhos -@@ -29,6 +30,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -76,10 +78,10 @@ struct bcm2835_spi { - void __iomem *regs; - struct clk *clk; - int irq; -- struct completion done; - const u8 *tx_buf; - u8 *rx_buf; -- int len; -+ int tx_len; -+ int rx_len; - }; - - static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg) -@@ -96,10 +98,12 @@ static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- while (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD) { -+ while ((bs->rx_len) && -+ (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD)) { - byte = bcm2835_rd(bs, BCM2835_SPI_FIFO); - if (bs->rx_buf) - *bs->rx_buf++ = byte; -+ bs->rx_len--; - } - } - -@@ -107,47 +111,60 @@ static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs) - { - u8 byte; - -- while ((bs->len) && -+ while ((bs->tx_len) && - (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) { - byte = bs->tx_buf ? *bs->tx_buf++ : 0; - bcm2835_wr(bs, BCM2835_SPI_FIFO, byte); -- bs->len--; -+ bs->tx_len--; - } - } - -+static void bcm2835_spi_reset_hw(struct spi_master *master) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -+ -+ /* Disable SPI interrupts and transfer */ -+ cs &= ~(BCM2835_SPI_CS_INTR | -+ BCM2835_SPI_CS_INTD | -+ BCM2835_SPI_CS_TA); -+ /* and reset RX/TX FIFOS */ -+ cs |= BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX; -+ -+ /* and reset the SPI_HW */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+} -+ - static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - { - struct spi_master *master = dev_id; - struct bcm2835_spi *bs = spi_master_get_devdata(master); -- u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - - /* Read as many bytes as possible from FIFO */ - bcm2835_rd_fifo(bs); -- -- if (bs->len) { /* there is more data to transmit */ -- bcm2835_wr_fifo(bs); -- } else { /* Transfer complete */ -- /* Disable SPI interrupts */ -- cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD); -- bcm2835_wr(bs, BCM2835_SPI_CS, cs); -- -- /* -- * Wake up bcm2835_spi_transfer_one(), which will call -- * bcm2835_spi_finish_transfer(), to drain the RX FIFO. -- */ -- complete(&bs->done); -+ /* Write as many bytes as possible to FIFO */ -+ bcm2835_wr_fifo(bs); -+ -+ /* based on flags decide if we can finish the transfer */ -+ if (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE) { -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* wake up the framework */ -+ complete(&master->xfer_completion); - } - - return IRQ_HANDLED; - } - --static int bcm2835_spi_start_transfer(struct spi_device *spi, -- struct spi_transfer *tfr) -+static int bcm2835_spi_transfer_one(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr) - { -- struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long spi_hz, clk_hz, cdiv; -- u32 cs = BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - -+ /* set clock */ - spi_hz = tfr->speed_hz; - clk_hz = clk_get_rate(bs->clk); - -@@ -163,100 +180,118 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi, - } else { - cdiv = 0; /* 0 is the slowest we can go */ - } -+ bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); - -+ /* handle all the modes */ - if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf)) - cs |= BCM2835_SPI_CS_REN; -- - if (spi->mode & SPI_CPOL) - cs |= BCM2835_SPI_CS_CPOL; - if (spi->mode & SPI_CPHA) - cs |= BCM2835_SPI_CS_CPHA; - -- if (!(spi->mode & SPI_NO_CS)) { -- if (spi->mode & SPI_CS_HIGH) { -- cs |= BCM2835_SPI_CS_CSPOL; -- cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select; -- } -- -- cs |= spi->chip_select; -- } -+ /* for gpio_cs set dummy CS so that no HW-CS get changed -+ * we can not run this in bcm2835_spi_set_cs, as it does -+ * not get called for cs_gpio cases, so we need to do it here -+ */ -+ if (gpio_is_valid(spi->cs_gpio) || (spi->mode & SPI_NO_CS)) -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; - -- reinit_completion(&bs->done); -+ /* set transmit buffers and length */ - bs->tx_buf = tfr->tx_buf; - bs->rx_buf = tfr->rx_buf; -- bs->len = tfr->len; -+ bs->tx_len = tfr->len; -+ bs->rx_len = tfr->len; - -- bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); - /* - * Enable the HW block. This will immediately trigger a DONE (TX - * empty) interrupt, upon which we will fill the TX FIFO with the - * first TX bytes. Pre-filling the TX FIFO here to avoid the - * interrupt doesn't work:-( - */ -+ cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; - bcm2835_wr(bs, BCM2835_SPI_CS, cs); - -- return 0; -+ /* signal that we need to wait for completion */ -+ return 1; - } - --static int bcm2835_spi_finish_transfer(struct spi_device *spi, -- struct spi_transfer *tfr, -- bool cs_change) -+static void bcm2835_spi_handle_err(struct spi_master *master, -+ struct spi_message *msg) - { -- struct bcm2835_spi *bs = spi_master_get_devdata(spi->master); -- u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -- -- if (tfr->delay_usecs) -- udelay(tfr->delay_usecs); -- -- if (cs_change) -- /* Clear TA flag */ -- bcm2835_wr(bs, BCM2835_SPI_CS, cs & ~BCM2835_SPI_CS_TA); -- -- return 0; -+ bcm2835_spi_reset_hw(master); - } - --static int bcm2835_spi_transfer_one(struct spi_master *master, -- struct spi_message *mesg) -+static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level) - { -+ /* -+ * we can assume that we are "native" as per spi_set_cs -+ * calling us ONLY when cs_gpio is not set -+ * we can also assume that we are CS < 3 as per bcm2835_spi_setup -+ * we would not get called because of error handling there. -+ * the level passed is the electrical level not enabled/disabled -+ * so it has to get translated back to enable/disable -+ * see spi_set_cs in spi.c for the implementation -+ */ -+ -+ struct spi_master *master = spi->master; - struct bcm2835_spi *bs = spi_master_get_devdata(master); -- struct spi_transfer *tfr; -- struct spi_device *spi = mesg->spi; -- int err = 0; -- unsigned int timeout; -- bool cs_change; -- -- list_for_each_entry(tfr, &mesg->transfers, transfer_list) { -- err = bcm2835_spi_start_transfer(spi, tfr); -- if (err) -- goto out; -- -- timeout = wait_for_completion_timeout( -- &bs->done, -- msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS) -- ); -- if (!timeout) { -- err = -ETIMEDOUT; -- goto out; -- } -+ u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); -+ bool enable; - -- cs_change = tfr->cs_change || -- list_is_last(&tfr->transfer_list, &mesg->transfers); -+ /* calculate the enable flag from the passed gpio_level */ -+ enable = (spi->mode & SPI_CS_HIGH) ? gpio_level : !gpio_level; - -- err = bcm2835_spi_finish_transfer(spi, tfr, cs_change); -- if (err) -- goto out; -+ /* set flags for "reverse" polarity in the registers */ -+ if (spi->mode & SPI_CS_HIGH) { -+ /* set the correct CS-bits */ -+ cs |= BCM2835_SPI_CS_CSPOL; -+ cs |= BCM2835_SPI_CS_CSPOL0 << spi->chip_select; -+ } else { -+ /* clean the CS-bits */ -+ cs &= ~BCM2835_SPI_CS_CSPOL; -+ cs &= ~(BCM2835_SPI_CS_CSPOL0 << spi->chip_select); -+ } - -- mesg->actual_length += (tfr->len - bs->len); -+ /* select the correct chip_select depending on disabled/enabled */ -+ if (enable) { -+ /* set cs correctly */ -+ if (spi->mode & SPI_NO_CS) { -+ /* use the "undefined" chip-select */ -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; -+ } else { -+ /* set the chip select */ -+ cs &= ~(BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01); -+ cs |= spi->chip_select; -+ } -+ } else { -+ /* disable CSPOL which puts HW-CS into deselected state */ -+ cs &= ~BCM2835_SPI_CS_CSPOL; -+ /* use the "undefined" chip-select as precaution */ -+ cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01; - } - --out: -- /* Clear FIFOs, and disable the HW block */ -- bcm2835_wr(bs, BCM2835_SPI_CS, -- BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); -- mesg->status = err; -- spi_finalize_current_message(master); -+ /* finally set the calculated flags in SPI_CS */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+} - -- return 0; -+static int bcm2835_spi_setup(struct spi_device *spi) -+{ -+ /* -+ * sanity checking the native-chipselects -+ */ -+ if (spi->mode & SPI_NO_CS) -+ return 0; -+ if (gpio_is_valid(spi->cs_gpio)) -+ return 0; -+ if (spi->chip_select < 3) -+ return 0; -+ -+ /* error in the case of native CS requested with CS-id > 2 */ -+ dev_err(&spi->dev, -+ "setup: only three native chip-selects are supported\n" -+ ); -+ return -EINVAL; - } - - static int bcm2835_spi_probe(struct platform_device *pdev) -@@ -277,13 +312,14 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - master->mode_bits = BCM2835_SPI_MODE_BITS; - master->bits_per_word_mask = SPI_BPW_MASK(8); - master->num_chipselect = 3; -- master->transfer_one_message = bcm2835_spi_transfer_one; -+ master->setup = bcm2835_spi_setup; -+ master->set_cs = bcm2835_spi_set_cs; -+ master->transfer_one = bcm2835_spi_transfer_one; -+ //master->handle_err = bcm2835_spi_handle_err; - master->dev.of_node = pdev->dev.of_node; - - bs = spi_master_get_devdata(master); - -- init_completion(&bs->done); -- - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - bs->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(bs->regs)) { -@@ -314,7 +350,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) - goto out_clk_disable; - } - -- /* initialise the hardware */ -+ /* initialise the hardware with the default polarities */ - bcm2835_wr(bs, BCM2835_SPI_CS, - BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - - -From cf51ed163d8109aa02dfc267633ed4c0a4a81f08 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 29 Mar 2015 16:03:23 +0200 -Subject: [PATCH 111/216] spi: bcm2835: fix code formatting issue - -Signed-off-by: Martin Sperl -Tested-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 31d80eb0..4aa80fd 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -289,8 +289,7 @@ static int bcm2835_spi_setup(struct spi_device *spi) - - /* error in the case of native CS requested with CS-id > 2 */ - dev_err(&spi->dev, -- "setup: only three native chip-selects are supported\n" -- ); -+ "setup: only three native chip-selects are supported\n"); - return -EINVAL; - } - - -From 8f0e96a797cebd49ab5054b3c150386a5f840855 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Sun, 29 Mar 2015 16:03:25 +0200 -Subject: [PATCH 112/216] spi: bcm2835: fill FIFO before enabling interrupts to - reduce interrupts/message - -To reduce the number of interrupts/message we fill the FIFO before -enabling interrupts - for short messages this reduces the interrupt count -from 2 to 1 interrupt. - -There have been rare cases where short (<200ns) chip-select switches with -native CS have been observed during such operation, this is why this -optimization is only enabled for GPIO-CS. - -Signed-off-by: Martin Sperl -Tested-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 4aa80fd..321dbe2 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -203,6 +203,22 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - bs->tx_len = tfr->len; - bs->rx_len = tfr->len; - -+ /* fill in fifo if we have gpio-cs -+ * note that there have been rare events where the native-CS -+ * flapped for <1us which may change the behaviour -+ * with gpio-cs this does not happen, so it is implemented -+ * only for this case -+ */ -+ if (gpio_is_valid(spi->cs_gpio)) { -+ /* enable HW block, but without interrupts enabled -+ * this would triggern an immediate interrupt -+ */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, -+ cs | BCM2835_SPI_CS_TA); -+ /* fill in tx fifo as much as possible */ -+ bcm2835_wr_fifo(bs); -+ } -+ - /* - * Enable the HW block. This will immediately trigger a DONE (TX - * empty) interrupt, upon which we will fill the TX FIFO with the - -From 31a827ccaeac10f8a5ac4ee4dc4fcdda68470eb7 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 6 Apr 2015 17:16:31 +0000 -Subject: [PATCH 113/216] spi: bcm2835: transform native-cs to gpio-cs on first - spi_setup - -Transforms the bcm-2835 native SPI-chip select to their gpio-cs equivalent. - -This allows for some support of some optimizations that are not -possible due to HW-gliches on the CS line - especially filling -the FIFO before enabling SPI interrupts (by writing to CS register) -while the transfer is already in progress (See commit: e3a2be3030e2) - -This patch also works arround some issues in bcm2835-pinctrl which does not -set the value when setting the GPIO as output - it just sets up output and -(typically) leaves the GPIO as low. When a fix for this is merged then this -gpio_set_value can get removed from bcm2835_spi_setup. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 49 ++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 44 insertions(+), 5 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 321dbe2..033b93f 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -291,8 +291,15 @@ static void bcm2835_spi_set_cs(struct spi_device *spi, bool gpio_level) - bcm2835_wr(bs, BCM2835_SPI_CS, cs); - } - -+static int chip_match_name(struct gpio_chip *chip, void *data) -+{ -+ return !strcmp(chip->label, data); -+} -+ - static int bcm2835_spi_setup(struct spi_device *spi) - { -+ int err; -+ struct gpio_chip *chip; - /* - * sanity checking the native-chipselects - */ -@@ -300,13 +307,45 @@ static int bcm2835_spi_setup(struct spi_device *spi) - return 0; - if (gpio_is_valid(spi->cs_gpio)) - return 0; -- if (spi->chip_select < 3) -+ if (spi->chip_select > 1) { -+ /* error in the case of native CS requested with CS > 1 -+ * officially there is a CS2, but it is not documented -+ * which GPIO is connected with that... -+ */ -+ dev_err(&spi->dev, -+ "setup: only two native chip-selects are supported\n"); -+ return -EINVAL; -+ } -+ /* now translate native cs to GPIO */ -+ -+ /* get the gpio chip for the base */ -+ chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); -+ if (!chip) - return 0; - -- /* error in the case of native CS requested with CS-id > 2 */ -- dev_err(&spi->dev, -- "setup: only three native chip-selects are supported\n"); -- return -EINVAL; -+ /* and calculate the real CS */ -+ spi->cs_gpio = chip->base + 8 - spi->chip_select; -+ -+ /* and set up the "mode" and level */ -+ dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n", -+ spi->chip_select, spi->cs_gpio); -+ -+ /* set up GPIO as output and pull to the correct level */ -+ err = gpio_direction_output(spi->cs_gpio, -+ (spi->mode & SPI_CS_HIGH) ? 0 : 1); -+ if (err) { -+ dev_err(&spi->dev, -+ "could not set CS%i gpio %i as output: %i", -+ spi->chip_select, spi->cs_gpio, err); -+ return err; -+ } -+ /* the implementation of pinctrl-bcm2835 currently does not -+ * set the GPIO value when using gpio_direction_output -+ * so we are setting it here explicitly -+ */ -+ gpio_set_value(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ? 0 : 1); -+ -+ return 0; - } - - static int bcm2835_spi_probe(struct platform_device *pdev) - -From 776aadc5da23cf97862d5eb535d8d9b8a038552f Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 6 Apr 2015 17:16:30 +0000 -Subject: [PATCH 114/216] spi: bcm2835: enabling polling mode for transfers - shorter than 30us - -In cases of short transfer times the CPU is spending lots of time -in the interrupt handler and scheduler to reschedule the worker thread. - -Measurements show that we have times where it takes 29.32us to between -the last clock change and the time that the worker-thread is running again -returning from wait_for_completion_timeout(). - -During this time the interrupt-handler is running calling complete() -and then also the scheduler is rescheduling the worker thread. - -This time can vary depending on how much of the code is still in -CPU-caches, when there is a burst of spi transfers the subsequent delays -are in the order of 25us, so the value of 30us seems reasonable. - -With polling the whole transfer of 4 bytes at 10MHz finishes after 6.16us -(CS down to up) with the real transfer (clock running) taking 3.56us. -So the efficiency has much improved and is also freeing CPU cycles, -reducing interrupts and context switches. - -Because of the above 30us seems to be a reasonable limit for polling. - -Signed-off-by: Martin Sperl -Signed-off-by: Mark Brown ---- - drivers/spi/spi-bcm2835.c | 112 +++++++++++++++++++++++++++++++++++----------- - 1 file changed, 86 insertions(+), 26 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 033b93f..44ee1f3 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -68,7 +68,8 @@ - #define BCM2835_SPI_CS_CS_10 0x00000002 - #define BCM2835_SPI_CS_CS_01 0x00000001 - --#define BCM2835_SPI_TIMEOUT_MS 30000 -+#define BCM2835_SPI_POLLING_LIMIT_US 30 -+#define BCM2835_SPI_TIMEOUT_MS 30000 - #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ - | SPI_NO_CS | SPI_3WIRE) - -@@ -156,12 +157,86 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) - return IRQ_HANDLED; - } - -+static int bcm2835_spi_transfer_one_poll(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs, -+ unsigned long xfer_time_us) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ unsigned long timeout = jiffies + -+ max(4 * xfer_time_us * HZ / 1000000, 2uL); -+ -+ /* enable HW block without interrupts */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); -+ -+ /* set timeout to 4x the expected time, or 2 jiffies */ -+ /* loop until finished the transfer */ -+ while (bs->rx_len) { -+ /* read from fifo as much as possible */ -+ bcm2835_rd_fifo(bs); -+ /* fill in tx fifo as much as possible */ -+ bcm2835_wr_fifo(bs); -+ /* if we still expect some data after the read, -+ * check for a possible timeout -+ */ -+ if (bs->rx_len && time_after(jiffies, timeout)) { -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* and return timeout */ -+ return -ETIMEDOUT; -+ } -+ } -+ -+ /* Transfer complete - reset SPI HW */ -+ bcm2835_spi_reset_hw(master); -+ /* and return without waiting for completion */ -+ return 0; -+} -+ -+static int bcm2835_spi_transfer_one_irq(struct spi_master *master, -+ struct spi_device *spi, -+ struct spi_transfer *tfr, -+ u32 cs) -+{ -+ struct bcm2835_spi *bs = spi_master_get_devdata(master); -+ -+ /* fill in fifo if we have gpio-cs -+ * note that there have been rare events where the native-CS -+ * flapped for <1us which may change the behaviour -+ * with gpio-cs this does not happen, so it is implemented -+ * only for this case -+ */ -+ if (gpio_is_valid(spi->cs_gpio)) { -+ /* enable HW block, but without interrupts enabled -+ * this would triggern an immediate interrupt -+ */ -+ bcm2835_wr(bs, BCM2835_SPI_CS, -+ cs | BCM2835_SPI_CS_TA); -+ /* fill in tx fifo as much as possible */ -+ bcm2835_wr_fifo(bs); -+ } -+ -+ /* -+ * Enable the HW block. This will immediately trigger a DONE (TX -+ * empty) interrupt, upon which we will fill the TX FIFO with the -+ * first TX bytes. Pre-filling the TX FIFO here to avoid the -+ * interrupt doesn't work:-( -+ */ -+ cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; -+ bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+ -+ /* signal that we need to wait for completion */ -+ return 1; -+} -+ - static int bcm2835_spi_transfer_one(struct spi_master *master, - struct spi_device *spi, - struct spi_transfer *tfr) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); - unsigned long spi_hz, clk_hz, cdiv; -+ unsigned long spi_used_hz, xfer_time_us; - u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); - - /* set clock */ -@@ -180,6 +255,7 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - } else { - cdiv = 0; /* 0 is the slowest we can go */ - } -+ spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); - bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); - - /* handle all the modes */ -@@ -203,33 +279,17 @@ static int bcm2835_spi_transfer_one(struct spi_master *master, - bs->tx_len = tfr->len; - bs->rx_len = tfr->len; - -- /* fill in fifo if we have gpio-cs -- * note that there have been rare events where the native-CS -- * flapped for <1us which may change the behaviour -- * with gpio-cs this does not happen, so it is implemented -- * only for this case -- */ -- if (gpio_is_valid(spi->cs_gpio)) { -- /* enable HW block, but without interrupts enabled -- * this would triggern an immediate interrupt -- */ -- bcm2835_wr(bs, BCM2835_SPI_CS, -- cs | BCM2835_SPI_CS_TA); -- /* fill in tx fifo as much as possible */ -- bcm2835_wr_fifo(bs); -- } -+ /* calculate the estimated time in us the transfer runs */ -+ xfer_time_us = tfr->len -+ * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */ -+ * 1000000 / spi_used_hz; - -- /* -- * Enable the HW block. This will immediately trigger a DONE (TX -- * empty) interrupt, upon which we will fill the TX FIFO with the -- * first TX bytes. Pre-filling the TX FIFO here to avoid the -- * interrupt doesn't work:-( -- */ -- cs |= BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD | BCM2835_SPI_CS_TA; -- bcm2835_wr(bs, BCM2835_SPI_CS, cs); -+ /* for short requests run polling*/ -+ if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US) -+ return bcm2835_spi_transfer_one_poll(master, spi, tfr, -+ cs, xfer_time_us); - -- /* signal that we need to wait for completion */ -- return 1; -+ return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs); - } - - static void bcm2835_spi_handle_err(struct spi_master *master, - -From 0a92a30733013eae878dc15c597dfa718f2865f5 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Thu, 16 Apr 2015 21:18:47 +0100 -Subject: [PATCH 115/216] spi: bcm2835: change timeout of polling driver to 1s - -The way that the timeout code is written in the polling function -the timeout does also trigger when interrupted or rescheduled while -in the polling loop. - -This patch changes the timeout from effectively 20ms (=2 jiffies) to -1 second and removes the time that the transfer really takes out of -the computation, as - per design - this is <30us and the jiffie resolution -is 10ms so that does not make any difference what so ever. - -Signed-off-by: Martin Sperl ---- - drivers/spi/spi-bcm2835.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c -index 44ee1f3..1a915e5 100644 ---- a/drivers/spi/spi-bcm2835.c -+++ b/drivers/spi/spi-bcm2835.c -@@ -164,13 +164,12 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master, - unsigned long xfer_time_us) - { - struct bcm2835_spi *bs = spi_master_get_devdata(master); -- unsigned long timeout = jiffies + -- max(4 * xfer_time_us * HZ / 1000000, 2uL); -+ /* set timeout to 1 second of maximum polling */ -+ unsigned long timeout = jiffies + HZ; - - /* enable HW block without interrupts */ - bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA); - -- /* set timeout to 4x the expected time, or 2 jiffies */ - /* loop until finished the transfer */ - while (bs->rx_len) { - /* read from fifo as much as possible */ - -From a53606a32ae4bdadc08985d0a67a6924c09633f1 Mon Sep 17 00:00:00 2001 +From 7de29243d1ac891a526c77e17129d6e2d547361d Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 19 Feb 2015 18:47:12 +0000 -Subject: [PATCH 116/216] smsx95xx: fix crimes against truesize +Subject: [PATCH 65/77] smsx95xx: fix crimes against truesize smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings. @@ -132315,10 +130809,10 @@ index e29a323..aff63dc usbnet_skb_return(dev, ax_skb); } -From a6f41e34aeb0834ce943e48ee5f6655716dd53c4 Mon Sep 17 00:00:00 2001 +From 4772a6e4cc3921cb41515b7b0a91ad646d1491aa Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 17 Apr 2015 16:58:45 +0100 -Subject: [PATCH 117/216] smsc95xx: Disable turbo mode by default +Subject: [PATCH 66/77] smsc95xx: Disable turbo mode by default --- drivers/net/usb/smsc95xx.c | 2 +- @@ -132338,133 +130832,10 @@ index aff63dc..08a8a8c 100755 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction"); -From d8512fe40402051a7fb3ec7e7ad25f38d0abab65 Mon Sep 17 00:00:00 2001 -From: Daniel Matuschek -Date: Wed, 18 Mar 2015 18:06:52 +0100 -Subject: [PATCH 118/216] HiFiBerry Digi: set SPDIF status bits for sample rate - -The HiFiBerry Digi driver did not signal the sample rate in the SPDIF status bits. -While this is optional, some DACs and receivers do not accept this signal. This patch -adds the sample rate bits in the SPDIF status block. ---- - sound/soc/bcm/hifiberry_digi.c | 28 ++++++++++++++++++++++++---- - 1 file changed, 24 insertions(+), 4 deletions(-) - -diff --git a/sound/soc/bcm/hifiberry_digi.c b/sound/soc/bcm/hifiberry_digi.c -index a294a1b..80732b8 100644 ---- a/sound/soc/bcm/hifiberry_digi.c -+++ b/sound/soc/bcm/hifiberry_digi.c -@@ -74,24 +74,41 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - - long mclk_freq=0; - int mclk_div=1; -+ int sampling_freq=1; - - int ret; - - samplerate = params_rate(params); - -+ if (samplerate<=96000) { -+ mclk_freq=samplerate*256; -+ mclk_div=WM8804_MCLKDIV_256FS; -+ } else { -+ mclk_freq=samplerate*128; -+ mclk_div=WM8804_MCLKDIV_128FS; -+ } -+ - switch (samplerate) { - case 32000: -+ sampling_freq=0x03; -+ break; - case 44100: -+ sampling_freq=0x00; -+ break; - case 48000: -+ sampling_freq=0x02; -+ break; - case 88200: -+ sampling_freq=0x08; -+ break; - case 96000: -- mclk_freq=samplerate*256; -- mclk_div=WM8804_MCLKDIV_256FS; -+ sampling_freq=0x0a; - break; - case 176400: -+ sampling_freq=0x0c; -+ break; - case 192000: -- mclk_freq=samplerate*128; -- mclk_div=WM8804_MCLKDIV_128FS; -+ sampling_freq=0x0e; - break; - default: - dev_err(codec->dev, -@@ -116,6 +133,9 @@ static int snd_rpi_hifiberry_digi_hw_params(struct snd_pcm_substream *substream, - /* Power on */ - snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); - -+ /* set sampling frequency status bits */ -+ snd_soc_update_bits(codec, WM8804_SPDTX4, 0x0f, sampling_freq); -+ - return snd_soc_dai_set_bclk_ratio(cpu_dai,64); - } - - -From 496a822ba4493536df3181be27d4b2d2906d4fde Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Sat, 18 Apr 2015 17:20:14 +0100 -Subject: [PATCH 119/216] bcm2708-dmaengine: Add debug options - ---- - drivers/dma/bcm2708-dmaengine.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 6150b8f..8182b16 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -56,6 +56,7 @@ - - #include "virt-dma.h" - -+static unsigned dma_debug; - - struct bcm2835_dmadev { - struct dma_device ddev; -@@ -600,7 +601,10 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( - } - - /* Common part */ -- control_block->info |= BCM2835_DMA_WAITS(SDHCI_BCM_DMA_WAITS); -+ u32 waits = SDHCI_BCM_DMA_WAITS; -+ if ((dma_debug >> 0) & 0x1f) -+ waits = (dma_debug >> 0) & 0x1f; -+ control_block->info |= BCM2835_DMA_WAITS(waits); - control_block->info |= BCM2835_DMA_WAIT_RESP; - - /* Enable */ -@@ -952,6 +956,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - } - - dev_info(&pdev->dev, "Load BCM2835 DMA engine driver\n"); -+ dev_info(&pdev->dev, "dma_debug:%x\n", dma_debug); - - return 0; - -@@ -982,6 +987,7 @@ static struct platform_driver bcm2835_dma_driver = { - - module_platform_driver(bcm2835_dma_driver); - -+module_param(dma_debug, uint, 0644); - MODULE_ALIAS("platform:bcm2835-dma"); - MODULE_DESCRIPTION("BCM2835 DMA engine driver"); - MODULE_AUTHOR("Florian Meier "); - -From 4dc3a781a0d5718153bc38b1f1294523d44b8f66 Mon Sep 17 00:00:00 2001 +From 9d1fbb7b2dbe16c506f54984c361a55d1b2603fb Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Fri, 17 Apr 2015 19:30:22 +0100 -Subject: [PATCH 120/216] Add blk_pos parameter to mmc multi_io_quirk callback +Subject: [PATCH 67/77] Add blk_pos parameter to mmc multi_io_quirk callback --- drivers/mmc/card/block.c | 1 + @@ -132475,7 +130846,7 @@ Subject: [PATCH 120/216] Add blk_pos parameter to mmc multi_io_quirk callback 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c -index ed2e71a..ce854a9 100644 +index 60f7141..1f15cb5 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1413,6 +1413,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, @@ -132487,10 +130858,10 @@ index ed2e71a..ce854a9 100644 } diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index f84cfb0..fec8c12 100644 +index 9df2b68..8c0ee4a 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1798,7 +1798,9 @@ static int omap_hsmmc_disable_fclk(struct mmc_host *mmc) +@@ -1749,7 +1749,9 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) } static int omap_hsmmc_multi_io_quirk(struct mmc_card *card, @@ -132502,7 +130873,7 @@ index f84cfb0..fec8c12 100644 /* This controller can't do multiblock reads due to hw bugs */ if (direction == MMC_DATA_READ) diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c -index 6906a90..1fb7577 100644 +index 354f4f3..4f1ccf3 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -170,7 +170,9 @@ static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) @@ -132532,10 +130903,10 @@ index dba7e1c..0c87f4f 100644 struct tmio_mmc_host *host = mmc_priv(card->host); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h -index c3b84a2..c1c3868f 100644 +index b0258e8..d3cdad9 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h -@@ -146,7 +146,9 @@ struct mmc_host_ops { +@@ -140,7 +140,9 @@ struct mmc_host_ops { * I/O. Returns the number of supported blocks for the request. */ int (*multi_io_quirk)(struct mmc_card *card, @@ -132547,3870 +130918,10 @@ index c3b84a2..c1c3868f 100644 struct mmc_card; -From 12b12cf1a7a825c46dcefa06bdde683cac053189 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 25 Mar 2015 17:49:47 +0000 -Subject: [PATCH 121/216] Adding bcm2835-sdhost driver, and an overlay to - enable it - -BCM2835 has two SD card interfaces. This driver uses the other one. ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/sdhost-overlay.dts | 73 ++ - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - drivers/mmc/host/Kconfig | 10 + - drivers/mmc/host/Makefile | 1 + - drivers/mmc/host/bcm2835-sdhost.c | 1685 ++++++++++++++++++++++++++++++++++ - 7 files changed, 1772 insertions(+) - create mode 100644 arch/arm/boot/dts/sdhost-overlay.dts - create mode 100644 drivers/mmc/host/bcm2835-sdhost.c - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 980b78e0..9cb5a2d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -34,6 +34,7 @@ dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -diff --git a/arch/arm/boot/dts/sdhost-overlay.dts b/arch/arm/boot/dts/sdhost-overlay.dts -new file mode 100644 -index 0000000..33db96e ---- /dev/null -+++ b/arch/arm/boot/dts/sdhost-overlay.dts -@@ -0,0 +1,73 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sdhost: sdhost@7e202000 { -+ compatible = "brcm,bcm2835-sdhost"; -+ reg = <0x7e202000 0x100>; -+ interrupts = <2 24>; -+ clocks = <&clk_sdhost>; -+ dmas = <&dma 13>, -+ <&dma 13>; -+ dma-names = "tx", "rx"; -+ brcm,delay-after-stop = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ status = "okay"; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_sdhost: clock@3 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mmc>; -+ __overlay__ { -+ /* Find a way to disable the other driver */ -+ compatible = ""; -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/__overrides__"; -+ __overlay__ { -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+ }; -+ -+ __overrides__ { -+ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ force_pio = <&sdhost>,"brcm,force-pio?"; -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 7cec5f8..367a04a 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -956,6 +956,7 @@ CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 - CONFIG_MMC_BCM2835=y - CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SPI=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e77173b..db287f3 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -949,6 +949,7 @@ CONFIG_MMC=y - CONFIG_MMC_BLOCK_MINORS=32 - CONFIG_MMC_BCM2835=y - CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SPI=m -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 7c093a6..1666c6c 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -33,6 +33,16 @@ config MMC_BCM2835_PIO_DMA_BARRIER - - If unsure, say 2 here. - -+config MMC_BCM2835_SDHOST -+ tristate "Support for the SDHost controller on BCM2708/9" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ help -+ This selects the SDHost controller on BCM2835/6. -+ -+ If you have a controller with this interface, say Y or M here. -+ -+ If unsure, say N. -+ - config MMC_ARMMMCI - tristate "ARM AMBA Multimedia Card Interface support" - depends on ARM_AMBA -diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 9d41de9..8a7e43e 100644 ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -18,6 +18,7 @@ obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o - obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o - obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o - obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o -+obj-$(CONFIG_MMC_BCM2835_SDHOST) += bcm2835-sdhost.o - obj-$(CONFIG_MMC_BCM2835) += bcm2835-mmc.o - obj-$(CONFIG_MMC_WBSD) += wbsd.o - obj-$(CONFIG_MMC_AU1X) += au1xmmc.o -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -new file mode 100644 -index 0000000..0c311b5 ---- /dev/null -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -0,0 +1,1685 @@ -+/* -+ * BCM2835 SD host driver. -+ * -+ * Author: Phil Elwell -+ * Copyright 2015 -+ * -+ * Based on -+ * mmc-bcm2835.c by Gellert Weisz -+ * which is, in turn, based on -+ * sdhci-bcm2708.c by Broadcom -+ * sdhci-bcm2835.c by Stephen Warren and Oleksandr Tymoshenko -+ * sdhci.c and sdhci-pci.c by Pierre Ossman -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms and conditions of the GNU General Public License, -+ * version 2, as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#define SAFE_READ_THRESHOLD 4 -+#define SAFE_WRITE_THRESHOLD 4 -+#define ALLOW_DMA 1 -+#define ALLOW_CMD23 0 -+#define ALLOW_FAST 1 -+#define USE_BLOCK_IRQ 1 -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "sdhost-bcm2835" -+ -+#define SDCMD 0x00 /* Command to SD card - 16 R/W */ -+#define SDARG 0x04 /* Argument to SD card - 32 R/W */ -+#define SDTOUT 0x08 /* Start value for timeout counter - 32 R/W */ -+#define SDCDIV 0x0c /* Start value for clock divider - 11 R/W */ -+#define SDRSP0 0x10 /* SD card response (31:0) - 32 R */ -+#define SDRSP1 0x14 /* SD card response (63:32) - 32 R */ -+#define SDRSP2 0x18 /* SD card response (95:64) - 32 R */ -+#define SDRSP3 0x1c /* SD card response (127:96) - 32 R */ -+#define SDHSTS 0x20 /* SD host status - 11 R */ -+#define SDVDD 0x30 /* SD card power control - 1 R/W */ -+#define SDEDM 0x34 /* Emergency Debug Mode - 13 R/W */ -+#define SDHCFG 0x38 /* Host configuration - 2 R/W */ -+#define SDHBCT 0x3c /* Host byte count (debug) - 32 R/W */ -+#define SDDATA 0x40 /* Data to/from SD card - 32 R/W */ -+#define SDHBLC 0x50 /* Host block count (SDIO/SDHC) - 9 R/W */ -+ -+#define SDCMD_NEW_FLAG 0x8000 -+#define SDCMD_FAIL_FLAG 0x4000 -+#define SDCMD_BUSYWAIT 0x800 -+#define SDCMD_NO_RESPONSE 0x400 -+#define SDCMD_LONG_RESPONSE 0x200 -+#define SDCMD_WRITE_CMD 0x80 -+#define SDCMD_READ_CMD 0x40 -+#define SDCMD_CMD_MASK 0x3f -+ -+#define SDCDIV_MAX_CDIV 0x7ff -+ -+#define SDHSTS_BUSY_IRPT 0x400 -+#define SDHSTS_BLOCK_IRPT 0x200 -+#define SDHSTS_SDIO_IRPT 0x100 -+#define SDHSTS_REW_TIME_OUT 0x80 -+#define SDHSTS_CMD_TIME_OUT 0x40 -+#define SDHSTS_CRC16_ERROR 0x20 -+#define SDHSTS_CRC7_ERROR 0x10 -+#define SDHSTS_FIFO_ERROR 0x08 -+/* Reserved */ -+/* Reserved */ -+#define SDHSTS_DATA_FLAG 0x01 -+ -+#define SDHSTS_TRANSFER_ERROR_MASK (SDHSTS_CRC16_ERROR|SDHSTS_REW_TIME_OUT|SDHSTS_FIFO_ERROR) -+#define SDHSTS_ERROR_MASK (SDHSTS_CMD_TIME_OUT|SDHSTS_TRANSFER_ERROR_MASK) -+/* SDHSTS_CRC7_ERROR - ignore this as MMC cards generate this spuriously */ -+ -+#define SDHCFG_BUSY_IRPT_EN (1<<10) -+#define SDHCFG_BLOCK_IRPT_EN (1<<8) -+#define SDHCFG_SDIO_IRPT_EN (1<<5) -+#define SDHCFG_DATA_IRPT_EN (1<<4) -+#define SDHCFG_SLOW_CARD (1<<3) -+#define SDHCFG_WIDE_EXT_BUS (1<<2) -+#define SDHCFG_WIDE_INT_BUS (1<<1) -+#define SDHCFG_REL_CMD_LINE (1<<0) -+ -+#define SDEDM_FORCE_DATA_MODE (1<<19) -+#define SDEDM_CLOCK_PULSE (1<<20) -+#define SDEDM_BYPASS (1<<21) -+ -+#define SDEDM_WRITE_THRESHOLD_SHIFT 9 -+#define SDEDM_READ_THRESHOLD_SHIFT 14 -+#define SDEDM_THRESHOLD_MASK 0x1f -+ -+/* the inclusive limit in bytes under which PIO will be used instead of DMA */ -+#ifdef CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_SDHOST_PIO_DMA_BARRIER -+#else -+#define PIO_DMA_BARRIER 0 -+#endif -+ -+#define MIN_FREQ 400000 -+#define TIMEOUT_VAL 0xE -+#define BCM2835_SDHOST_WRITE_DELAY(f) (((2 * 1000000) / f) + 1) -+ -+#ifndef BCM2708_PERI_BASE -+ #define BCM2708_PERI_BASE 0x20000000 -+#endif -+ -+/* FIXME: Needs IOMMU support */ -+#define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) -+ -+ -+struct bcm2835_host { -+ spinlock_t lock; -+ -+ void __iomem *ioaddr; -+ u32 phys_addr; -+ -+ struct mmc_host *mmc; -+ -+ u32 timeout; -+ -+ int clock; /* Current clock speed */ -+ -+ bool slow_card; /* Force 11-bit divisor */ -+ -+ unsigned int max_clk; /* Max possible freq */ -+ unsigned int timeout_clk; /* Timeout freq (KHz) */ -+ -+ struct tasklet_struct finish_tasklet; /* Tasklet structures */ -+ -+ struct timer_list timer; /* Timer for timeouts */ -+ -+ struct sg_mapping_iter sg_miter; /* SG state for PIO */ -+ unsigned int blocks; /* remaining PIO blocks */ -+ -+ int irq; /* Device IRQ */ -+ -+ -+ /* cached registers */ -+ u32 hcfg; -+ u32 cdiv; -+ -+ struct mmc_request *mrq; /* Current request */ -+ struct mmc_command *cmd; /* Current command */ -+ struct mmc_data *data; /* Current data request */ -+ unsigned int data_complete:1; /* Data finished before cmd */ -+ -+ unsigned int flush_fifo:1; /* Drain the fifo when finishing */ -+ -+ unsigned int use_busy:1; /* Wait for busy interrupt */ -+ -+ u32 thread_isr; -+ -+ /*DMA part*/ -+ struct dma_chan *dma_chan_rx; /* DMA channel for reads */ -+ struct dma_chan *dma_chan_tx; /* DMA channel for writes */ -+ -+ bool allow_dma; -+ bool have_dma; -+ bool use_dma; -+ /*end of DMA part*/ -+ -+ int max_delay; /* maximum length of time spent waiting */ -+ struct timeval stop_time; /* when the last stop was issued */ -+ u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ -+}; -+ -+ -+static inline void bcm2835_sdhost_write(struct bcm2835_host *host, u32 val, int reg) -+{ -+ writel(val, host->ioaddr + reg); -+} -+ -+static inline u32 bcm2835_sdhost_read(struct bcm2835_host *host, int reg) -+{ -+ return readl(host->ioaddr + reg); -+} -+ -+static inline u32 bcm2835_sdhost_read_relaxed(struct bcm2835_host *host, int reg) -+{ -+ return readl_relaxed(host->ioaddr + reg); -+} -+ -+static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host) -+{ -+ pr_info(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", -+ mmc_hostname(host->mmc)); -+ -+ pr_info(DRIVER_NAME ": SDCMD 0x%08x\n", -+ bcm2835_sdhost_read(host, SDCMD)); -+ pr_info(DRIVER_NAME ": SDARG 0x%08x\n", -+ bcm2835_sdhost_read(host, SDARG)); -+ pr_info(DRIVER_NAME ": SDTOUT 0x%08x\n", -+ bcm2835_sdhost_read(host, SDTOUT)); -+ pr_info(DRIVER_NAME ": SDCDIV 0x%08x\n", -+ bcm2835_sdhost_read(host, SDCDIV)); -+ pr_info(DRIVER_NAME ": SDRSP0 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP0)); -+ pr_info(DRIVER_NAME ": SDRSP1 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP1)); -+ pr_info(DRIVER_NAME ": SDRSP2 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP2)); -+ pr_info(DRIVER_NAME ": SDRSP3 0x%08x\n", -+ bcm2835_sdhost_read(host, SDRSP3)); -+ pr_info(DRIVER_NAME ": SDHSTS 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHSTS)); -+ pr_info(DRIVER_NAME ": SDVDD 0x%08x\n", -+ bcm2835_sdhost_read(host, SDVDD)); -+ pr_info(DRIVER_NAME ": SDEDM 0x%08x\n", -+ bcm2835_sdhost_read(host, SDEDM)); -+ pr_info(DRIVER_NAME ": SDHCFG 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHCFG)); -+ pr_info(DRIVER_NAME ": SDHBCT 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHBCT)); -+ pr_info(DRIVER_NAME ": SDHBLC 0x%08x\n", -+ bcm2835_sdhost_read(host, SDHBLC)); -+ -+ pr_debug(DRIVER_NAME ": ===========================================\n"); -+} -+ -+ -+static void bcm2835_sdhost_set_power(struct bcm2835_host *host, bool on) -+{ -+ bcm2835_sdhost_write(host, on ? 1 : 0, SDVDD); -+} -+ -+ -+static void bcm2835_sdhost_reset(struct bcm2835_host *host) -+{ -+ u32 temp; -+ -+ pr_debug("bcm2835_sdhost_reset\n"); -+ -+ bcm2835_sdhost_set_power(host, false); -+ -+ bcm2835_sdhost_write(host, 0, SDCMD); -+ bcm2835_sdhost_write(host, 0, SDARG); -+ bcm2835_sdhost_write(host, 0xf00000, SDTOUT); -+ bcm2835_sdhost_write(host, 0, SDCDIV); -+ bcm2835_sdhost_write(host, 0x7f8, SDHSTS); /* Write 1s to clear */ -+ bcm2835_sdhost_write(host, 0, SDHCFG); -+ bcm2835_sdhost_write(host, 0, SDHBCT); -+ bcm2835_sdhost_write(host, 0, SDHBLC); -+ -+ /* Limit fifo usage due to silicon bug */ -+ temp = bcm2835_sdhost_read(host, SDEDM); -+ temp &= ~((SDEDM_THRESHOLD_MASK<clock = 0; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ mmiowb(); -+} -+ -+static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); -+ -+static void bcm2835_sdhost_init(struct bcm2835_host *host, int soft) -+{ -+ pr_debug("bcm2835_sdhost_init(%d)\n", soft); -+ -+ /* Set interrupt enables */ -+ host->hcfg = SDHCFG_BUSY_IRPT_EN; -+ -+ bcm2835_sdhost_reset(host); -+ -+ if (soft) { -+ /* force clock reconfiguration */ -+ host->clock = 0; -+ bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios); -+ } -+} -+ -+static bool bcm2835_sdhost_is_write_complete(struct bcm2835_host *host) -+{ -+ bool write_complete = ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1); -+ -+ if (!write_complete) { -+ /* Request an IRQ for the last block */ -+ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if ((bcm2835_sdhost_read(host, SDEDM) & 0xf) == 1) { -+ /* The write has now completed. Disable the interrupt -+ and clear the status flag */ -+ host->hcfg &= ~SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ bcm2835_sdhost_write(host, SDHSTS_BLOCK_IRPT, SDHSTS); -+ write_complete = true; -+ } -+ } -+ -+ return write_complete; -+} -+ -+static void bcm2835_sdhost_wait_write_complete(struct bcm2835_host *host) -+{ -+ int timediff; -+#ifdef DEBUG -+ static struct timeval start_time; -+ static int max_stall_time = 0; -+ static int total_stall_time = 0; -+ struct timeval before, after; -+ -+ do_gettimeofday(&before); -+ if (max_stall_time == 0) -+ start_time = before; -+#endif -+ -+ timediff = 0; -+ -+ while (1) { -+ u32 edm = bcm2835_sdhost_read(host, SDEDM); -+ if ((edm & 0xf) == 1) -+ break; -+ timediff++; -+ if (timediff > 5000000) { -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); -+ -+ pr_err(" wait_write_complete - still waiting after %dus\n", -+ timediff); -+#else -+ pr_err(" wait_write_complete - still waiting after %d retries\n", -+ timediff); -+#endif -+ bcm2835_sdhost_dumpregs(host); -+ host->data->error = -ETIMEDOUT; -+ return; -+ } -+ } -+ -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + (after.tv_usec - before.tv_usec); -+ -+ total_stall_time += timediff; -+ if (timediff > max_stall_time) -+ max_stall_time = timediff; -+ -+ if ((after.tv_sec - start_time.tv_sec) > 10) { -+ pr_debug(" wait_write_complete - max wait %dus, total %dus\n", -+ max_stall_time, total_stall_time); -+ start_time = after; -+ max_stall_time = 0; -+ total_stall_time = 0; -+ } -+#endif -+} -+ -+static void bcm2835_sdhost_finish_data(struct bcm2835_host *host); -+ -+static void bcm2835_sdhost_dma_complete(void *param) -+{ -+ struct bcm2835_host *host = param; -+ struct dma_chan *dma_chan; -+ unsigned long flags; -+ u32 dir_data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->data) { -+ bool write_complete; -+ if (USE_BLOCK_IRQ) -+ write_complete = bcm2835_sdhost_is_write_complete(host); -+ else { -+ bcm2835_sdhost_wait_write_complete(host); -+ write_complete = true; -+ } -+ pr_debug("dma_complete() - write_complete=%d\n", -+ write_complete); -+ -+ if (write_complete || (host->data->flags & MMC_DATA_READ)) -+ { -+ if (write_complete) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ } else { -+ dma_chan = host->dma_chan_rx; -+ dir_data = DMA_FROM_DEVICE; -+ } -+ -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ } -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void bcm2835_sdhost_read_block_pio(struct bcm2835_host *host) -+{ -+ unsigned long flags; -+ size_t blksize, len; -+ u32 *buf; -+ -+ blksize = host->data->blksz; -+ -+ local_irq_save(flags); -+ -+ while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); -+ -+ len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); -+ -+ blksize -= len; -+ host->sg_miter.consumed = len; -+ -+ buf = (u32 *)host->sg_miter.addr; -+ -+ while (len) { -+ while (1) { -+ u32 hsts; -+ hsts = bcm2835_sdhost_read(host, SDHSTS); -+ if (hsts & SDHSTS_DATA_FLAG) -+ break; -+ -+ if (hsts & SDHSTS_ERROR_MASK) { -+ pr_err("%s: Transfer error - HSTS %x, HBCT %x - %x left\n", -+ mmc_hostname(host->mmc), -+ hsts, -+ bcm2835_sdhost_read(host, SDHBCT), -+ blksize + len); -+ if (hsts & SDHSTS_REW_TIME_OUT) -+ host->data->error = -ETIMEDOUT; -+ else if (hsts & (SDHSTS_CRC16_ERROR || -+ SDHSTS_CRC7_ERROR)) -+ host->data->error = -EILSEQ; -+ else { -+ pr_err("%s: unexpected data error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ } -+ } -+ } -+ -+ *(buf++) = bcm2835_sdhost_read(host, SDDATA); -+ len -= 4; -+ } -+ } -+ -+ sg_miter_stop(&host->sg_miter); -+ -+ local_irq_restore(flags); -+} -+ -+static void bcm2835_sdhost_write_block_pio(struct bcm2835_host *host) -+{ -+ unsigned long flags; -+ size_t blksize, len; -+ u32 *buf; -+ -+ blksize = host->data->blksz; -+ -+ local_irq_save(flags); -+ -+ while (blksize) { -+ if (!sg_miter_next(&host->sg_miter)) -+ BUG(); -+ -+ len = min(host->sg_miter.length, blksize); -+ BUG_ON(len % 4); -+ -+ blksize -= len; -+ host->sg_miter.consumed = len; -+ -+ buf = host->sg_miter.addr; -+ -+ while (len) { -+ while (!(bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG)) -+ continue; -+ bcm2835_sdhost_write(host, *(buf++), SDDATA); -+ len -= 4; -+ } -+ } -+ -+ sg_miter_stop(&host->sg_miter); -+ -+ local_irq_restore(flags); -+} -+ -+ -+static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host) -+{ -+ BUG_ON(!host->data); -+ -+ if (host->data->flags & MMC_DATA_READ) -+ bcm2835_sdhost_read_block_pio(host); -+ else -+ bcm2835_sdhost_write_block_pio(host); -+} -+ -+ -+static void bcm2835_sdhost_transfer_dma(struct bcm2835_host *host) -+{ -+ u32 len, dir_data, dir_slave; -+ struct dma_async_tx_descriptor *desc = NULL; -+ struct dma_chan *dma_chan; -+ -+ pr_debug("bcm2835_sdhost_transfer_dma()\n"); -+ -+ WARN_ON(!host->data); -+ -+ if (!host->data) -+ return; -+ -+ if (host->data->flags & MMC_DATA_READ) { -+ dma_chan = host->dma_chan_rx; -+ dir_data = DMA_FROM_DEVICE; -+ dir_slave = DMA_DEV_TO_MEM; -+ } else { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ dir_slave = DMA_MEM_TO_DEV; -+ } -+ -+ BUG_ON(!dma_chan->device); -+ BUG_ON(!dma_chan->device->dev); -+ BUG_ON(!host->data->sg); -+ -+ len = dma_map_sg(dma_chan->device->dev, host->data->sg, -+ host->data->sg_len, dir_data); -+ if (len > 0) { -+ desc = dmaengine_prep_slave_sg(dma_chan, host->data->sg, -+ len, dir_slave, -+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); -+ } else { -+ dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); -+ } -+ if (desc) { -+ desc->callback = bcm2835_sdhost_dma_complete; -+ desc->callback_param = host; -+ dmaengine_submit(desc); -+ dma_async_issue_pending(dma_chan); -+ } -+ -+} -+ -+ -+static void bcm2835_sdhost_set_transfer_irqs(struct bcm2835_host *host) -+{ -+ u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | -+ SDHCFG_BUSY_IRPT_EN; -+ if (host->use_dma) -+ host->hcfg = (host->hcfg & ~all_irqs) | -+ SDHCFG_BUSY_IRPT_EN; -+ else -+ host->hcfg = (host->hcfg & ~all_irqs) | -+ SDHCFG_DATA_IRPT_EN | -+ SDHCFG_BUSY_IRPT_EN; -+ -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+} -+ -+ -+static void bcm2835_sdhost_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd) -+{ -+ struct mmc_data *data = cmd->data; -+ -+ WARN_ON(host->data); -+ -+ if (!data) -+ return; -+ -+ /* Sanity checks */ -+ BUG_ON(data->blksz * data->blocks > 524288); -+ BUG_ON(data->blksz > host->mmc->max_blk_size); -+ BUG_ON(data->blocks > 65535); -+ -+ host->data = data; -+ host->data_complete = 0; -+ host->flush_fifo = 0; -+ host->data->bytes_xfered = 0; -+ -+ if (!host->use_dma) { -+ int flags; -+ -+ flags = SG_MITER_ATOMIC; -+ if (data->flags & MMC_DATA_READ) -+ flags |= SG_MITER_TO_SG; -+ else -+ flags |= SG_MITER_FROM_SG; -+ sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); -+ host->blocks = data->blocks; -+ } -+ -+ host->use_dma = host->have_dma && data->blocks > PIO_DMA_BARRIER; -+ -+ bcm2835_sdhost_set_transfer_irqs(host); -+ -+ bcm2835_sdhost_write(host, data->blksz, SDHBCT); -+ if (host->use_dma) -+ bcm2835_sdhost_write(host, data->blocks, SDHBLC); -+ -+ BUG_ON(!host->data); -+} -+ -+ -+void bcm2835_sdhost_send_command(struct bcm2835_host *host, struct mmc_command *cmd) -+{ -+ u32 sdcmd; -+ unsigned long timeout; -+ -+ WARN_ON(host->cmd); -+ -+ if (1) { -+ pr_debug("bcm2835_sdhost_send_command: %08x %08x (flags %x)\n", -+ cmd->opcode, cmd->arg, (cmd->flags & 0xff) | (cmd->data ? cmd->data->flags : 0)); -+ if (cmd->data) -+ pr_debug("bcm2835_sdhost_send_command: %s %d*%x\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ } -+ -+ /* Wait max 10 ms */ -+ timeout = 1000; -+ -+ while (bcm2835_sdhost_read(host, SDCMD) & SDCMD_NEW_FLAG) { -+ if (timeout == 0) { -+ pr_err("%s: Previous command never completed.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ timeout--; -+ udelay(10); -+ } -+ -+ if ((1000-timeout)/100 > 1 && (1000-timeout)/100 > host->max_delay) { -+ host->max_delay = (1000-timeout)/100; -+ pr_warning("Warning: SDHost controller hung for %d ms\n", host->max_delay); -+ } -+ -+ timeout = jiffies; -+#ifdef CONFIG_ARCH_BCM2835 -+ if (!cmd->data && cmd->busy_timeout > 9000) -+ timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; -+ else -+#endif -+ timeout += 10 * HZ; -+ mod_timer(&host->timer, timeout); -+ -+ host->cmd = cmd; -+ -+ bcm2835_sdhost_prepare_data(host, cmd); -+ -+ bcm2835_sdhost_write(host, cmd->arg, SDARG); -+ -+ if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { -+ pr_err("%s: Unsupported response type!\n", -+ mmc_hostname(host->mmc)); -+ cmd->error = -EINVAL; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ -+ sdcmd = cmd->opcode & SDCMD_CMD_MASK; -+ -+ if (!(cmd->flags & MMC_RSP_PRESENT)) -+ sdcmd |= SDCMD_NO_RESPONSE; -+ else { -+ if (cmd->flags & MMC_RSP_136) -+ sdcmd |= SDCMD_LONG_RESPONSE; -+ if (cmd->flags & MMC_RSP_BUSY) { -+ sdcmd |= SDCMD_BUSYWAIT; -+ host->use_busy = 1; -+ } -+ } -+ -+ if (cmd->data) { -+ if (host->delay_after_stop) { -+ struct timeval now; -+ int time_since_stop; -+ do_gettimeofday(&now); -+ time_since_stop = (now.tv_sec - host->stop_time.tv_sec); -+ if (time_since_stop < 2) { -+ /* Possibly less than one second */ -+ time_since_stop = time_since_stop * 1000000 + -+ (now.tv_usec - host->stop_time.tv_usec); -+ if (time_since_stop < host->delay_after_stop) -+ udelay(host->delay_after_stop - -+ time_since_stop); -+ } -+ } -+ -+ if (cmd->data->flags & MMC_DATA_WRITE) -+ sdcmd |= SDCMD_WRITE_CMD; -+ if (cmd->data->flags & MMC_DATA_READ) -+ sdcmd |= SDCMD_READ_CMD; -+ } -+ -+ bcm2835_sdhost_write(host, sdcmd | SDCMD_NEW_FLAG, SDCMD); -+} -+ -+ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host); -+static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host); -+ -+static void bcm2835_sdhost_finish_data(struct bcm2835_host *host) -+{ -+ struct mmc_data *data; -+ -+ data = host->data; -+ BUG_ON(!data); -+ -+ pr_debug("finish_data(error %d, stop %d, sbc %d)\n", -+ data->error, data->stop ? 1 : 0, -+ host->mrq->sbc ? 1 : 0); -+ -+ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ -+ if (data->error) { -+ data->bytes_xfered = 0; -+ } else -+ data->bytes_xfered = data->blksz * data->blocks; -+ -+ host->data_complete = 1; -+ -+ if (host->cmd) { -+ /* -+ * Data managed to finish before the -+ * command completed. Make sure we do -+ * things in the proper order. -+ */ -+ pr_debug("Finished early - HSTS %x\n", -+ bcm2835_sdhost_read(host, SDHSTS)); -+ } -+ else -+ bcm2835_sdhost_transfer_complete(host); -+} -+ -+ -+static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host) -+{ -+ struct mmc_data *data; -+ -+ BUG_ON(host->cmd); -+ BUG_ON(!host->data); -+ BUG_ON(!host->data_complete); -+ -+ data = host->data; -+ host->data = NULL; -+ -+ pr_debug("transfer_complete(error %d, stop %d)\n", -+ data->error, data->stop ? 1 : 0); -+ -+ if (data->error) -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ bcm2835_sdhost_reset(host); -+ -+ /* -+ * Need to send CMD12 if - -+ * a) open-ended multiblock transfer (no CMD23) -+ * b) error in multiblock transfer -+ */ -+ if (data->stop && -+ (data->error || -+ !host->mrq->sbc)) { -+ host->flush_fifo = 1; -+ bcm2835_sdhost_send_command(host, data->stop); -+ if (host->delay_after_stop) -+ do_gettimeofday(&host->stop_time); -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+ } else { -+ tasklet_schedule(&host->finish_tasklet); -+ } -+} -+ -+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host) -+{ -+ u32 sdcmd; -+ int timeout = 1000; -+#ifdef DEBUG -+ struct timeval before, after; -+ int timediff = 0; -+#endif -+ -+ pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD)); -+ -+ BUG_ON(!host->cmd || !host->mrq); -+ -+#ifdef DEBUG -+ do_gettimeofday(&before); -+#endif -+ for (sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ (sdcmd & SDCMD_NEW_FLAG) && timeout; -+ timeout--) { -+ if (host->flush_fifo) { -+ while (bcm2835_sdhost_read(host, SDHSTS) & -+ SDHSTS_DATA_FLAG) -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ udelay(10); -+ sdcmd = bcm2835_sdhost_read(host, SDCMD); -+ } -+#ifdef DEBUG -+ do_gettimeofday(&after); -+ timediff = (after.tv_sec - before.tv_sec)*1000000 + -+ (after.tv_usec - before.tv_usec); -+ -+ pr_debug(" finish_command - waited %dus\n", timediff); -+#endif -+ -+ if (timeout == 0) { -+ pr_err("%s: Command never completed.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ -+ if (host->flush_fifo) { -+ for (timeout = 100; -+ (bcm2835_sdhost_read(host, SDHSTS) & SDHSTS_DATA_FLAG) && timeout; -+ timeout--) { -+ (void)bcm2835_sdhost_read(host, SDDATA); -+ } -+ host->flush_fifo = 0; -+ if (timeout == 0) { -+ pr_err("%s: FIFO never drained.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ } -+ -+ /* Check for errors */ -+ if (sdcmd & SDCMD_FAIL_FLAG) -+ { -+ u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS); -+ -+ pr_debug("%s: error detected - CMD %x, HSTS %03x, EDM %x\n", -+ mmc_hostname(host->mmc), sdcmd, sdhsts, -+ bcm2835_sdhost_read(host, SDEDM)); -+ -+ if (sdhsts & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ { -+ pr_err("%s: unexpected command error\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ host->cmd->error = -EIO; -+ } -+ tasklet_schedule(&host->finish_tasklet); -+ return; -+ } -+ -+ if (host->cmd->flags & MMC_RSP_PRESENT) { -+ if (host->cmd->flags & MMC_RSP_136) { -+ int i; -+ for (i = 0; i < 4; i++) -+ host->cmd->resp[3 - i] = bcm2835_sdhost_read(host, SDRSP0 + i*4); -+ pr_debug("bcm2835_sdhost_finish_command: %08x %08x %08x %08x\n", -+ host->cmd->resp[0], host->cmd->resp[1], host->cmd->resp[2], host->cmd->resp[3]); -+ } else { -+ host->cmd->resp[0] = bcm2835_sdhost_read(host, SDRSP0); -+ pr_debug("bcm2835_sdhost_finish_command: %08x\n", -+ host->cmd->resp[0]); -+ } -+ } -+ -+ host->cmd->error = 0; -+ -+ if (host->cmd == host->mrq->sbc) { -+ /* Finished CMD23, now send actual command. */ -+ host->cmd = NULL; -+ bcm2835_sdhost_send_command(host, host->mrq->cmd); -+ -+ if (host->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+ } else if (host->cmd == host->mrq->stop) -+ /* Finished CMD12 */ -+ tasklet_schedule(&host->finish_tasklet); -+ else { -+ /* Processed actual command. */ -+ host->cmd = NULL; -+ if (!host->data) -+ tasklet_schedule(&host->finish_tasklet); -+ else if (host->data_complete) -+ bcm2835_sdhost_transfer_complete(host); -+ } -+} -+ -+static void bcm2835_sdhost_timeout_timer(unsigned long data) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ host = (struct bcm2835_host *)data; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (host->mrq) { -+ pr_err("%s: Timeout waiting for hardware interrupt.\n", -+ mmc_hostname(host->mmc)); -+ bcm2835_sdhost_dumpregs(host); -+ -+ if (host->data) { -+ host->data->error = -ETIMEDOUT; -+ bcm2835_sdhost_finish_data(host); -+ } else { -+ if (host->cmd) -+ host->cmd->error = -ETIMEDOUT; -+ else -+ host->mrq->cmd->error = -ETIMEDOUT; -+ -+ pr_debug("timeout_timer tasklet_schedule\n"); -+ tasklet_schedule(&host->finish_tasklet); -+ } -+ } -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable) -+{ -+ if (enable) -+ host->hcfg |= SDHCFG_SDIO_IRPT_EN; -+ else -+ host->hcfg &= ~SDHCFG_SDIO_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ mmiowb(); -+} -+ -+static void bcm2835_sdhost_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ -+ pr_debug("bcm2835_sdhost_enable_sdio_irq(%d)\n", enable); -+ spin_lock_irqsave(&host->lock, flags); -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, enable); -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static u32 bcm2835_sdhost_busy_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ -+ if (!host->cmd) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " -+ "though no command operation was in progress.\n", -+ mmc_hostname(host->mmc), (unsigned)intmask); -+ bcm2835_sdhost_dumpregs(host); -+ return 0; -+ } -+ -+ if (!host->use_busy) { -+ pr_err("%s: Got command busy interrupt 0x%08x even " -+ "though not expecting one.\n", -+ mmc_hostname(host->mmc), (unsigned)intmask); -+ bcm2835_sdhost_dumpregs(host); -+ return 0; -+ } -+ host->use_busy = 0; -+ -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if (intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR | -+ SDHSTS_FIFO_ERROR)) -+ host->cmd->error = -EILSEQ; -+ -+ if (host->cmd->error) -+ tasklet_schedule(&host->finish_tasklet); -+ else -+ bcm2835_sdhost_finish_command(host); -+ -+ return handled; -+} -+ -+static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ -+ /* There are no dedicated data/space available interrupt -+ status bits, so it is necessary to use the single shared -+ data/space available FIFO status bits. It is therefore not -+ an error to get here when there is no data transfer in -+ progress. */ -+ if (!host->data) -+ return 0; -+ -+ // XXX FIFO_ERROR -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; -+ -+ /* Use the block interrupt for writes after the first block */ -+ if (!(host->data->flags & MMC_DATA_READ)) { -+ host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); -+ host->hcfg |= SDHCFG_BLOCK_IRPT_EN; -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ if (host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ bcm2835_sdhost_transfer_pio(host); -+ } else { -+ if (!host->data->error) { -+ bcm2835_sdhost_transfer_pio(host); -+ host->blocks--; -+ } -+ if ((host->blocks == 0) || host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ return handled; -+} -+ -+static u32 bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask) -+{ -+ struct dma_chan *dma_chan; -+ u32 dir_data; -+ const u32 handled = (SDHSTS_CMD_TIME_OUT | SDHSTS_CRC16_ERROR | -+ SDHSTS_CRC7_ERROR | SDHSTS_FIFO_ERROR); -+ -+ if (!host->data) { -+ pr_err("%s: Got block interrupt 0x%08x even " -+ "though no data operation was in progress.\n", -+ mmc_hostname(host->mmc), (unsigned)intmask); -+ bcm2835_sdhost_dumpregs(host); -+ return handled; -+ } -+ -+ if (intmask & SDHSTS_CMD_TIME_OUT) -+ host->cmd->error = -ETIMEDOUT; -+ else if ((intmask & (SDHSTS_CRC16_ERROR | SDHSTS_CRC7_ERROR)) && -+ ((bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK) -+ != MMC_BUS_TEST_R)) -+ host->cmd->error = -EILSEQ; -+ -+ if (!host->use_dma) { -+ BUG_ON(!host->blocks); -+ host->blocks--; -+ if ((host->blocks == 0) || host->data->error) -+ bcm2835_sdhost_finish_data(host); -+ else -+ bcm2835_sdhost_transfer_pio(host); -+ } else if (host->data->flags & MMC_DATA_WRITE) { -+ dma_chan = host->dma_chan_tx; -+ dir_data = DMA_TO_DEVICE; -+ dma_unmap_sg(dma_chan->device->dev, -+ host->data->sg, host->data->sg_len, -+ dir_data); -+ -+ bcm2835_sdhost_finish_data(host); -+ } -+ -+ return handled; -+} -+ -+ -+static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) -+{ -+ irqreturn_t result = IRQ_NONE; -+ struct bcm2835_host *host = dev_id; -+ u32 unexpected = 0, early = 0; -+ int loops = 0; -+#ifndef CONFIG_ARCH_BCM2835 -+ int cardint = 0; -+#endif -+ spin_lock(&host->lock); -+ -+ for (loops = 0; loops < 1; loops++) { -+ u32 intmask, handled; -+ -+ intmask = bcm2835_sdhost_read(host, SDHSTS); -+ handled = intmask & (SDHSTS_BUSY_IRPT | -+ SDHSTS_BLOCK_IRPT | -+ SDHSTS_SDIO_IRPT | -+ SDHSTS_DATA_FLAG); -+ if ((handled == SDHSTS_DATA_FLAG) && // XXX -+ (loops == 0) && !host->data) { -+ pr_err("%s: sdhost_irq data interrupt 0x%08x even " -+ "though no data operation was in progress.\n", -+ mmc_hostname(host->mmc), -+ (unsigned)intmask); -+ -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+ if (loops) -+ early |= handled; -+ -+ if (!handled) -+ break; -+ -+ result = IRQ_HANDLED; -+ -+ /* Clear all interrupts and notifications */ -+ bcm2835_sdhost_write(host, intmask, SDHSTS); -+ -+ if (intmask & SDHSTS_BUSY_IRPT) -+ handled |= bcm2835_sdhost_busy_irq(host, intmask); -+ -+ /* There is no true data interrupt status bit, so it is -+ necessary to qualify the data flag with the interrupt -+ enable bit */ -+ if ((intmask & SDHSTS_DATA_FLAG) && -+ (host->hcfg & SDHCFG_DATA_IRPT_EN)) -+ handled |= bcm2835_sdhost_data_irq(host, intmask); -+ -+ if (intmask & SDHSTS_BLOCK_IRPT) -+ handled |= bcm2835_sdhost_block_irq(host, intmask); -+ -+ if (intmask & SDHSTS_SDIO_IRPT) { -+#ifndef CONFIG_ARCH_BCM2835 -+ cardint = 1; -+#else -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, false); -+ host->thread_isr |= SDHSTS_SDIO_IRPT; -+ result = IRQ_WAKE_THREAD; -+#endif -+ } -+ -+ unexpected |= (intmask & ~handled); -+ } -+ -+ mmiowb(); -+ -+ spin_unlock(&host->lock); -+ -+ if (early) -+ pr_debug("%s: early %x (loops %d)\n", mmc_hostname(host->mmc), early, loops); -+ -+ if (unexpected) { -+ pr_err("%s: Unexpected interrupt 0x%08x.\n", -+ mmc_hostname(host->mmc), unexpected); -+ bcm2835_sdhost_dumpregs(host); -+ } -+ -+#ifndef CONFIG_ARCH_BCM2835 -+ if (cardint) -+ mmc_signal_sdio_irq(host->mmc); -+#endif -+ -+ return result; -+} -+ -+#ifdef CONFIG_ARCH_BCM2835 -+static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) -+{ -+ struct bcm2835_host *host = dev_id; -+ unsigned long flags; -+ u32 isr; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ isr = host->thread_isr; -+ host->thread_isr = 0; -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (isr & SDHSTS_SDIO_IRPT) { -+ sdio_run_irqs(host->mmc); -+ -+/* Is this necessary? Why re-enable an interrupt which is enabled? -+ spin_lock_irqsave(&host->lock, flags); -+ if (host->flags & SDHSTS_SDIO_IRPT_ENABLED) -+ bcm2835_sdhost_enable_sdio_irq_nolock(host, true); -+ spin_unlock_irqrestore(&host->lock, flags); -+*/ -+ } -+ -+ return isr ? IRQ_HANDLED : IRQ_NONE; -+} -+#endif -+ -+ -+ -+void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) -+{ -+ int div = 0; /* Initialized for compiler warning */ -+ -+ /* The SDCDIV register has 11 bits, and holds (div - 2). -+ But in data mode the max is 50MHz wihout a minimum, and only the -+ bottom 3 bits are used. Since the switch over is automatic (unless -+ we have marked the card as slow...), chosen values have to make -+ sense in both modes. -+ Ident mode must be 100-400KHz, so can range check the requested -+ clock. CMD15 must be used to return to data mode, so this can be -+ monitored. -+ -+ clock 250MHz -> 0->125MHz, 1->83.3MHz, 2->62.5MHz, 3->50.0MHz -+ 4->41.7MHz, 5->35.7MHz, 6->31.3MHz, 7->27.8MHz -+ -+ 623->400KHz/27.8MHz -+ reset value (507)->491159/50MHz -+ -+ BUT, the 3-bit clock divisor in data mode is too small if the -+ core clock is higher than 250MHz, so instead use the SLOW_CARD -+ configuration bit to force the use of the ident clock divisor -+ at all times. -+ */ -+ -+ host->mmc->actual_clock = 0; -+ -+ if (clock < 100000) { -+ /* Can't stop the clock, but make it as slow as possible -+ * to show willing -+ */ -+ host->cdiv = SDCDIV_MAX_CDIV; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ return; -+ } -+ -+ div = host->max_clk / clock; -+ if (div < 2) -+ div = 2; -+ if ((host->max_clk / div) > clock) -+ div++; -+ div -= 2; -+ -+ if (div > SDCDIV_MAX_CDIV) -+ div = SDCDIV_MAX_CDIV; -+ -+ host->mmc->actual_clock = host->max_clk / (div + 2); -+ -+ host->cdiv = div; -+ bcm2835_sdhost_write(host, host->cdiv, SDCDIV); -+ -+ pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -+ clock, host->max_clk, host->cdiv, host->mmc->actual_clock); -+} -+ -+static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ -+ if (1) { -+ struct mmc_command *cmd = mrq->cmd; -+ const char *src = "cmd"; -+ BUG_ON(!cmd); -+ pr_debug("bcm2835_sdhost_request: %s %08x %08x (flags %x)\n", -+ src, cmd->opcode, cmd->arg, cmd->flags); -+ if (cmd->data) -+ pr_debug("bcm2835_sdhost_request: %s %d*%d\n", -+ (cmd->data->flags & MMC_DATA_READ) ? -+ "read" : "write", cmd->data->blocks, -+ cmd->data->blksz); -+ } -+ -+ if (mrq->data && !is_power_of_2(mrq->data->blksz)) { -+ pr_err("%s: Unsupported block size (%d bytes)\n", -+ mmc_hostname(mmc), mrq->data->blksz); -+ mrq->cmd->error = -EINVAL; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ -+ host = mmc_priv(mmc); -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ WARN_ON(host->mrq != NULL); -+ -+ host->mrq = mrq; -+ -+ if (mrq->sbc) -+ bcm2835_sdhost_send_command(host, mrq->sbc); -+ else -+ bcm2835_sdhost_send_command(host, mrq->cmd); -+ -+ mmiowb(); -+ spin_unlock_irqrestore(&host->lock, flags); -+ -+ if (!mrq->sbc && mrq->cmd->data && host->use_dma) -+ /* DMA transfer starts now, PIO starts after irq */ -+ bcm2835_sdhost_transfer_dma(host); -+ -+ if (!host->use_busy) -+ bcm2835_sdhost_finish_command(host); -+} -+ -+ -+static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ -+ struct bcm2835_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ -+ pr_debug("bcm2835_sdhost_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ if (!ios->clock || ios->clock != host->clock) { -+ bcm2835_sdhost_set_clock(host, ios->clock); -+ host->clock = ios->clock; -+ } -+ -+ /* set bus width */ -+ host->hcfg &= ~SDHCFG_WIDE_EXT_BUS; -+ if (ios->bus_width == MMC_BUS_WIDTH_4) -+ host->hcfg |= SDHCFG_WIDE_EXT_BUS; -+ -+ host->hcfg |= SDHCFG_WIDE_INT_BUS; -+ -+ /* Disable clever clock switching, to cope with fast core clocks */ -+ host->hcfg |= SDHCFG_SLOW_CARD; -+ -+ bcm2835_sdhost_write(host, host->hcfg, SDHCFG); -+ -+ mmiowb(); -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+} -+ -+static int bcm2835_sdhost_multi_io_quirk(struct mmc_card *card, -+ unsigned int direction, -+ u32 blk_pos, int blk_size) -+{ -+ /* There is a bug in the host controller hardware that makes -+ reading the final sector of the card as part of a multiple read -+ problematic. Detect that case and shorten the read accordingly. -+ */ -+ /* csd.capacity is in weird units - convert to sectors */ -+ u32 card_sectors = (card->csd.capacity << (card->csd.read_blkbits - 9)); -+ -+ if ((direction == MMC_DATA_READ) && -+ ((blk_pos + blk_size) == card_sectors)) -+ blk_size--; -+ -+ return blk_size; -+} -+ -+ -+static struct mmc_host_ops bcm2835_sdhost_ops = { -+ .request = bcm2835_sdhost_request, -+ .set_ios = bcm2835_sdhost_set_ios, -+ .enable_sdio_irq = bcm2835_sdhost_enable_sdio_irq, -+ .multi_io_quirk = bcm2835_sdhost_multi_io_quirk, -+}; -+ -+ -+static void bcm2835_sdhost_tasklet_finish(unsigned long param) -+{ -+ struct bcm2835_host *host; -+ unsigned long flags; -+ struct mmc_request *mrq; -+ -+ host = (struct bcm2835_host *)param; -+ -+ spin_lock_irqsave(&host->lock, flags); -+ -+ /* -+ * If this tasklet gets rescheduled while running, it will -+ * be run again afterwards but without any active request. -+ */ -+ if (!host->mrq) { -+ spin_unlock_irqrestore(&host->lock, flags); -+ return; -+ } -+ -+ del_timer(&host->timer); -+ -+ mrq = host->mrq; -+ -+ /* -+ * The controller needs a reset of internal state machines -+ * upon error conditions. -+ */ -+ if (((mrq->cmd && mrq->cmd->error) || -+ (mrq->data && (mrq->data->error || -+ (mrq->data->stop && mrq->data->stop->error))))) { -+ -+ bcm2835_sdhost_reset(host); -+ } -+ -+ host->mrq = NULL; -+ host->cmd = NULL; -+ host->data = NULL; -+ -+ mmiowb(); -+ -+ spin_unlock_irqrestore(&host->lock, flags); -+ mmc_request_done(host->mmc, mrq); -+} -+ -+ -+ -+int bcm2835_sdhost_add_host(struct bcm2835_host *host) -+{ -+ struct mmc_host *mmc; -+ struct dma_slave_config cfg; -+ int ret; -+ -+ mmc = host->mmc; -+ -+ bcm2835_sdhost_reset(host); -+ -+ mmc->f_max = host->max_clk; -+ mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV; -+ -+ /* SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK */ -+ host->timeout_clk = mmc->f_max / 1000; -+#ifdef CONFIG_ARCH_BCM2835 -+ mmc->max_busy_timeout = (1 << 27) / host->timeout_clk; -+#endif -+ /* host controller capabilities */ -+ mmc->caps |= /* MMC_CAP_SDIO_IRQ |*/ MMC_CAP_4_BIT_DATA | -+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED | -+ MMC_CAP_NEEDS_POLL | -+ (ALLOW_CMD23 * MMC_CAP_CMD23); -+ -+ spin_lock_init(&host->lock); -+ -+ if (host->allow_dma) { -+ if (!host->dma_chan_tx || !host->dma_chan_rx || -+ IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) { -+ pr_err("%s: Unable to initialise DMA channels. Falling back to PIO\n", DRIVER_NAME); -+ host->have_dma = false; -+ } else { -+ pr_info("DMA channels allocated for the SDHost driver"); -+ host->have_dma = true; -+ -+ cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ cfg.slave_id = 13; /* DREQ channel */ -+ -+ cfg.direction = DMA_MEM_TO_DEV; -+ cfg.src_addr = 0; -+ cfg.dst_addr = host->phys_addr + SDDATA; -+ ret = dmaengine_slave_config(host->dma_chan_tx, &cfg); -+ -+ cfg.direction = DMA_DEV_TO_MEM; -+ cfg.src_addr = host->phys_addr + SDDATA; -+ cfg.dst_addr = 0; -+ ret = dmaengine_slave_config(host->dma_chan_rx, &cfg); -+ } -+ } else { -+ pr_info("Forcing PIO mode\n"); -+ host->have_dma = false; -+ } -+ -+ mmc->max_segs = 128; -+ mmc->max_req_size = 524288; -+ mmc->max_seg_size = mmc->max_req_size; -+ mmc->max_blk_size = 512; -+ mmc->max_blk_count = 65535; -+ -+ /* report supported voltage ranges */ -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ -+ tasklet_init(&host->finish_tasklet, -+ bcm2835_sdhost_tasklet_finish, (unsigned long)host); -+ -+ setup_timer(&host->timer, bcm2835_sdhost_timeout_timer, (unsigned long)host); -+ -+ bcm2835_sdhost_init(host, 0); -+#ifndef CONFIG_ARCH_BCM2835 -+ ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/, -+ mmc_hostname(mmc), host); -+#else -+ ret = request_threaded_irq(host->irq, bcm2835_sdhost_irq, bcm2835_sdhost_thread_irq, -+ IRQF_SHARED, mmc_hostname(mmc), host); -+#endif -+ if (ret) { -+ pr_err("%s: Failed to request IRQ %d: %d\n", -+ mmc_hostname(mmc), host->irq, ret); -+ goto untasklet; -+ } -+ -+ mmiowb(); -+ mmc_add_host(mmc); -+ -+ pr_info("Load BCM2835 SDHost driver\n"); -+ if (host->delay_after_stop) -+ pr_info("BCM2835 SDHost: delay_after_stop=%dus\n", -+ host->delay_after_stop); -+ -+ return 0; -+ -+untasklet: -+ tasklet_kill(&host->finish_tasklet); -+ -+ return ret; -+} -+ -+static int bcm2835_sdhost_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device_node *node = dev->of_node; -+ struct clk *clk; -+ struct resource *iomem; -+ struct bcm2835_host *host; -+ struct mmc_host *mmc; -+ int ret; -+ -+ pr_debug("bcm2835_sdhost_probe\n"); -+ mmc = mmc_alloc_host(sizeof(*host), dev); -+ if (!mmc) -+ return -ENOMEM; -+ -+ mmc->ops = &bcm2835_sdhost_ops; -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ host->timeout = msecs_to_jiffies(1000); -+ spin_lock_init(&host->lock); -+ -+ iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ host->ioaddr = devm_ioremap_resource(dev, iomem); -+ if (IS_ERR(host->ioaddr)) { -+ ret = PTR_ERR(host->ioaddr); -+ goto err; -+ } -+ -+ host->phys_addr = iomem->start + BCM2835_VCMMU_SHIFT; -+ pr_debug(" - ioaddr %lx, iomem->start %lx, phys_addr %lx\n", -+ (unsigned long)host->ioaddr, -+ (unsigned long)iomem->start, -+ (unsigned long)host->phys_addr); -+ -+ host->allow_dma = ALLOW_DMA; -+ -+ if (node) { -+ /* Read any custom properties */ -+ of_property_read_u32(node, -+ "brcm,delay-after-stop", -+ &host->delay_after_stop); -+ host->allow_dma = ALLOW_DMA && -+ !of_property_read_bool(node, "brcm,force-pio"); -+ } -+ -+ if (host->allow_dma) { -+ if (node) { -+ host->dma_chan_tx = -+ dma_request_slave_channel(dev, "tx"); -+ host->dma_chan_rx = -+ dma_request_slave_channel(dev, "rx"); -+ } else { -+ dma_cap_mask_t mask; -+ -+ dma_cap_zero(mask); -+ /* we don't care about the channel, any would work */ -+ dma_cap_set(DMA_SLAVE, mask); -+ host->dma_chan_tx = -+ dma_request_channel(mask, NULL, NULL); -+ host->dma_chan_rx = -+ dma_request_channel(mask, NULL, NULL); -+ } -+ } -+ -+ clk = devm_clk_get(dev, NULL); -+ if (IS_ERR(clk)) { -+ dev_err(dev, "could not get clk\n"); -+ ret = PTR_ERR(clk); -+ goto err; -+ } -+ -+ host->max_clk = clk_get_rate(clk); -+ -+ host->irq = platform_get_irq(pdev, 0); -+ if (host->irq <= 0) { -+ dev_err(dev, "get IRQ failed\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ pr_debug(" - max_clk %lx, irq %d\n", -+ (unsigned long)host->max_clk, -+ (int)host->irq); -+ -+ if (node) -+ mmc_of_parse(mmc); -+ else -+ mmc->caps |= MMC_CAP_4_BIT_DATA; -+ -+ ret = bcm2835_sdhost_add_host(host); -+ if (ret) -+ goto err; -+ -+ platform_set_drvdata(pdev, host); -+ -+ pr_debug("bcm2835_sdhost_probe -> OK\n"); -+ -+ return 0; -+ -+err: -+ pr_debug("bcm2835_sdhost_probe -> err %d\n", ret); -+ mmc_free_host(mmc); -+ -+ return ret; -+} -+ -+static int bcm2835_sdhost_remove(struct platform_device *pdev) -+{ -+ struct bcm2835_host *host = platform_get_drvdata(pdev); -+ -+ pr_debug("bcm2835_sdhost_remove\n"); -+ -+ mmc_remove_host(host->mmc); -+ -+ bcm2835_sdhost_set_power(host, false); -+ -+ free_irq(host->irq, host); -+ -+ del_timer_sync(&host->timer); -+ -+ tasklet_kill(&host->finish_tasklet); -+ -+ mmc_free_host(host->mmc); -+ platform_set_drvdata(pdev, NULL); -+ -+ pr_debug("bcm2835_sdhost_remove - OK\n"); -+ return 0; -+} -+ -+ -+static const struct of_device_id bcm2835_sdhost_match[] = { -+ { .compatible = "brcm,bcm2835-sdhost" }, -+ { } -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_sdhost_match); -+ -+ -+ -+static struct platform_driver bcm2835_sdhost_driver = { -+ .probe = bcm2835_sdhost_probe, -+ .remove = bcm2835_sdhost_remove, -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm2835_sdhost_match, -+ }, -+}; -+module_platform_driver(bcm2835_sdhost_driver); -+ -+MODULE_ALIAS("platform:sdhost-bcm2835"); -+MODULE_DESCRIPTION("BCM2835 SDHost driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("Phil Elwell"); - -From 4504d17456cfc2f8b8b987d8709adcf759c8ea2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:24:30 +0200 -Subject: [PATCH 122/216] BCM270x: Add memory and irq resources to dmaengine - device and DT -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Prepare for merging of the legacy DMA API arch driver dma.c -with bcm2708-dmaengine by adding memory and irq resources both -to platform file device and Device Tree node. -Don't use BCM_DMAMAN_DRIVER_NAME so we don't have to include mach/dma.h - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 16 +++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 65 +++++++++++++++++++++++++++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 65 +++++++++++++++++++++++++++++++++-- - 3 files changed, 142 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index ff70c58..065a424 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -10,7 +10,23 @@ - - dma: dma@7e007000 { - compatible = "brcm,bcm2835-dma"; -+ reg = <0x7e007000 0xf00>; -+ interrupts = <1 16>, -+ <1 17>, -+ <1 18>, -+ <1 19>, -+ <1 20>, -+ <1 21>, -+ <1 22>, -+ <1 23>, -+ <1 24>, -+ <1 25>, -+ <1 26>, -+ <1 27>, -+ <1 28>; -+ - #dma-cells = <1>; -+ brcm,dma-channel-mask = <0x7f35>; - }; - - intc: interrupt-controller { -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index b848e4a..703215d 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -55,7 +55,6 @@ - #include - - #include --#include - #include - #include - -@@ -257,15 +256,77 @@ static struct resource bcm2708_dmaman_resources[] = { - }; - - static struct platform_device bcm2708_dmaman_device = { -- .name = BCM_DMAMAN_DRIVER_NAME, -+ .name = "bcm2708_dma", - .id = 0, /* first bcm2708_dma */ - .resource = bcm2708_dmaman_resources, - .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), - }; - -+static struct resource bcm2708_dmaengine_resources[] = { -+ { -+ .start = DMA_BASE, -+ .end = DMA_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_DMA0, -+ .end = IRQ_DMA0, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA1, -+ .end = IRQ_DMA1, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA2, -+ .end = IRQ_DMA2, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA3, -+ .end = IRQ_DMA3, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA4, -+ .end = IRQ_DMA4, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA5, -+ .end = IRQ_DMA5, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA6, -+ .end = IRQ_DMA6, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA7, -+ .end = IRQ_DMA7, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA8, -+ .end = IRQ_DMA8, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA9, -+ .end = IRQ_DMA9, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA10, -+ .end = IRQ_DMA10, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA11, -+ .end = IRQ_DMA11, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA12, -+ .end = IRQ_DMA12, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ - static struct platform_device bcm2708_dmaengine_device = { - .name = "bcm2708-dmaengine", - .id = -1, -+ .resource = bcm2708_dmaengine_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), - }; - - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index dcad008..97116c3 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -56,7 +56,6 @@ - #include - - #include --#include - #include - #include - -@@ -267,15 +266,77 @@ static struct resource bcm2708_dmaman_resources[] = { - }; - - static struct platform_device bcm2708_dmaman_device = { -- .name = BCM_DMAMAN_DRIVER_NAME, -+ .name = "bcm2708_dma", - .id = 0, /* first bcm2708_dma */ - .resource = bcm2708_dmaman_resources, - .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), - }; - -+static struct resource bcm2708_dmaengine_resources[] = { -+ { -+ .start = DMA_BASE, -+ .end = DMA_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_DMA0, -+ .end = IRQ_DMA0, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA1, -+ .end = IRQ_DMA1, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA2, -+ .end = IRQ_DMA2, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA3, -+ .end = IRQ_DMA3, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA4, -+ .end = IRQ_DMA4, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA5, -+ .end = IRQ_DMA5, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA6, -+ .end = IRQ_DMA6, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA7, -+ .end = IRQ_DMA7, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA8, -+ .end = IRQ_DMA8, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA9, -+ .end = IRQ_DMA9, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA10, -+ .end = IRQ_DMA10, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA11, -+ .end = IRQ_DMA11, -+ .flags = IORESOURCE_IRQ, -+ }, { -+ .start = IRQ_DMA12, -+ .end = IRQ_DMA12, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ - static struct platform_device bcm2708_dmaengine_device = { - .name = "bcm2708-dmaengine", - .id = -1, -+ .resource = bcm2708_dmaengine_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_dmaengine_resources), - }; - - #if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE) - -From 4111e2c08fdfcfaa72b531689e2b9bc2b8c29453 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:25:43 +0200 -Subject: [PATCH 123/216] dmaengine: bcm2708: Merge with arch dma.c driver and - disable dma.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Merge the legacy DMA API driver with bcm2708-dmaengine. -This is done so we can use bcm2708_fb on ARCH_BCM2835 (mailbox -driver is also needed). - -Changes to the dma.c code: -- Use BIT() macro. -- Cutdown some comments to one line. -- Add mutex to vc_dmaman and use this, since the dev lock is locked - during probing of the engine part. -- Add global g_dmaman variable since drvdata is used by the engine part. -- Restructure for readability: - vc_dmaman_chan_alloc() - vc_dmaman_chan_free() - bcm_dma_chan_free() -- Restructure bcm_dma_chan_alloc() to simplify error handling. -- Use device irq resources instead of hardcoded bcm_dma_irqs table. -- Remove dev_dmaman_register() and code it directly. -- Remove dev_dmaman_deregister() and code it directly. -- Simplify bcm_dmaman_probe() using devm_* functions. -- Get dmachans from DT if available. -- Keep 'dma.dmachans' module argument name for backwards compatibility. - -Make it available on ARCH_BCM2835 as well. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/include/mach/dma.h | 96 +-------- - arch/arm/mach-bcm2709/Makefile | 2 +- - arch/arm/mach-bcm2709/include/mach/dma.h | 96 +-------- - drivers/dma/Kconfig | 9 +- - drivers/dma/bcm2708-dmaengine.c | 333 ++++++++++++++++++++++++++++-- - include/linux/platform_data/dma-bcm2708.h | 127 ++++++++++++ - 7 files changed, 457 insertions(+), 208 deletions(-) - create mode 100644 include/linux/platform_data/dma-bcm2708.h - -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index 21e3521..454408c 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -index d03e7b5..d826705 100644 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ b/arch/arm/mach-bcm2708/include/mach/dma.h -@@ -1,94 +1,2 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/dma.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- -- --#ifndef _MACH_BCM2708_DMA_H --#define _MACH_BCM2708_DMA_H -- --#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -- --/* DMA CS Control and Status bits */ --#define BCM2708_DMA_ACTIVE (1 << 0) --#define BCM2708_DMA_INT (1 << 2) --#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ --#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ --#define BCM2708_DMA_ERR (1 << 8) --#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ --#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -- --/* DMA control block "info" field bits */ --#define BCM2708_DMA_INT_EN (1 << 0) --#define BCM2708_DMA_TDMODE (1 << 1) --#define BCM2708_DMA_WAIT_RESP (1 << 3) --#define BCM2708_DMA_D_INC (1 << 4) --#define BCM2708_DMA_D_WIDTH (1 << 5) --#define BCM2708_DMA_D_DREQ (1 << 6) --#define BCM2708_DMA_S_INC (1 << 8) --#define BCM2708_DMA_S_WIDTH (1 << 9) --#define BCM2708_DMA_S_DREQ (1 << 10) -- --#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) --#define BCM2708_DMA_PER_MAP(x) ((x) << 16) --#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -- --#define BCM2708_DMA_DREQ_EMMC 11 --#define BCM2708_DMA_DREQ_SDHOST 13 -- --#define BCM2708_DMA_CS 0x00 /* Control and Status */ --#define BCM2708_DMA_ADDR 0x04 --/* the current control block appears in the following registers - read only */ --#define BCM2708_DMA_INFO 0x08 --#define BCM2708_DMA_SOURCE_AD 0x0c --#define BCM2708_DMA_DEST_AD 0x10 --#define BCM2708_DMA_NEXTCB 0x1C --#define BCM2708_DMA_DEBUG 0x20 -- --#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) --#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -- --#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -- --struct bcm2708_dma_cb { -- unsigned long info; -- unsigned long src; -- unsigned long dst; -- unsigned long length; -- unsigned long stride; -- unsigned long next; -- unsigned long pad[2]; --}; --struct scatterlist; -- --extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); --extern void bcm_dma_start(void __iomem *dma_chan_base, -- dma_addr_t control_block); --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); --extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -- --/* When listing features we can ask for when allocating DMA channels give -- those with higher priority smaller ordinal numbers */ --#define BCM_DMA_FEATURE_FAST_ORD 0 --#define BCM_DMA_FEATURE_BULK_ORD 1 --#define BCM_DMA_FEATURE_NORMAL_ORD 2 --#define BCM_DMA_FEATURE_LITE_ORD 3 --#define BCM_DMA_FEATURE_FAST (1< -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index 2a803bb..f07c38b 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o dma.o -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/include/mach/dma.h b/arch/arm/mach-bcm2709/include/mach/dma.h -index d03e7b5..d826705 100644 ---- a/arch/arm/mach-bcm2709/include/mach/dma.h -+++ b/arch/arm/mach-bcm2709/include/mach/dma.h -@@ -1,94 +1,2 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/dma.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- -- --#ifndef _MACH_BCM2708_DMA_H --#define _MACH_BCM2708_DMA_H -- --#define BCM_DMAMAN_DRIVER_NAME "bcm2708_dma" -- --/* DMA CS Control and Status bits */ --#define BCM2708_DMA_ACTIVE (1 << 0) --#define BCM2708_DMA_INT (1 << 2) --#define BCM2708_DMA_ISPAUSED (1 << 4) /* Pause requested or not active */ --#define BCM2708_DMA_ISHELD (1 << 5) /* Is held by DREQ flow control */ --#define BCM2708_DMA_ERR (1 << 8) --#define BCM2708_DMA_ABORT (1 << 30) /* stop current CB, go to next, WO */ --#define BCM2708_DMA_RESET (1 << 31) /* WO, self clearing */ -- --/* DMA control block "info" field bits */ --#define BCM2708_DMA_INT_EN (1 << 0) --#define BCM2708_DMA_TDMODE (1 << 1) --#define BCM2708_DMA_WAIT_RESP (1 << 3) --#define BCM2708_DMA_D_INC (1 << 4) --#define BCM2708_DMA_D_WIDTH (1 << 5) --#define BCM2708_DMA_D_DREQ (1 << 6) --#define BCM2708_DMA_S_INC (1 << 8) --#define BCM2708_DMA_S_WIDTH (1 << 9) --#define BCM2708_DMA_S_DREQ (1 << 10) -- --#define BCM2708_DMA_BURST(x) (((x)&0xf) << 12) --#define BCM2708_DMA_PER_MAP(x) ((x) << 16) --#define BCM2708_DMA_WAITS(x) (((x)&0x1f) << 21) -- --#define BCM2708_DMA_DREQ_EMMC 11 --#define BCM2708_DMA_DREQ_SDHOST 13 -- --#define BCM2708_DMA_CS 0x00 /* Control and Status */ --#define BCM2708_DMA_ADDR 0x04 --/* the current control block appears in the following registers - read only */ --#define BCM2708_DMA_INFO 0x08 --#define BCM2708_DMA_SOURCE_AD 0x0c --#define BCM2708_DMA_DEST_AD 0x10 --#define BCM2708_DMA_NEXTCB 0x1C --#define BCM2708_DMA_DEBUG 0x20 -- --#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4)+BCM2708_DMA_CS) --#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4)+BCM2708_DMA_ADDR) -- --#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -- --struct bcm2708_dma_cb { -- unsigned long info; -- unsigned long src; -- unsigned long dst; -- unsigned long length; -- unsigned long stride; -- unsigned long next; -- unsigned long pad[2]; --}; --struct scatterlist; -- --extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); --extern void bcm_dma_start(void __iomem *dma_chan_base, -- dma_addr_t control_block); --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base); --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base); --extern int /*rc*/ bcm_dma_abort(void __iomem *dma_chan_base); -- --/* When listing features we can ask for when allocating DMA channels give -- those with higher priority smaller ordinal numbers */ --#define BCM_DMA_FEATURE_FAST_ORD 0 --#define BCM_DMA_FEATURE_BULK_ORD 1 --#define BCM_DMA_FEATURE_NORMAL_ORD 2 --#define BCM_DMA_FEATURE_LITE_ORD 3 --#define BCM_DMA_FEATURE_FAST (1< -diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig -index 2395f63..41097c7 100644 ---- a/drivers/dma/Kconfig -+++ b/drivers/dma/Kconfig -@@ -339,10 +339,15 @@ config DMA_BCM2835 - - config DMA_BCM2708 - tristate "BCM2708 DMA engine support" -- depends on MACH_BCM2708 || MACH_BCM2709 -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 - select DMA_ENGINE - select DMA_VIRTUAL_CHANNELS - -+config DMA_BCM2708_LEGACY -+ bool "BCM2708 DMA legacy API support" -+ depends on DMA_BCM2708 -+ default y -+ - config TI_CPPI41 - tristate "AM33xx CPPI41 DMA support" - depends on ARCH_OMAP -@@ -381,7 +386,7 @@ config MOXART_DMA - select DMA_VIRTUAL_CHANNELS - help - Enable support for the MOXA ART SoC DMA controller. -- -+ - config FSL_EDMA - tristate "Freescale eDMA engine support" - depends on OF -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 8182b16..937fd60 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -37,26 +37,304 @@ - #include - #include - #include -+#include - #include - #include - #include - #include -+#include -+#include - --#ifndef CONFIG_ARCH_BCM2835 -+#include "virt-dma.h" - --/* dma manager */ --#include -+static unsigned dma_debug; - --//#define DMA_COMPLETE DMA_SUCCESS -+/* -+ * Legacy DMA API -+ */ - --#endif -+#ifdef CONFIG_DMA_BCM2708_LEGACY - --#include --#include -+#define CACHE_LINE_MASK 31 -+#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ - --#include "virt-dma.h" -+/* valid only for channels 0 - 14, 15 has its own base address */ -+#define BCM2708_DMA_CHAN(n) ((n) << 8) /* base address */ -+#define BCM2708_DMA_CHANIO(dma_base, n) \ -+ ((void __iomem *)((char *)(dma_base) + BCM2708_DMA_CHAN(n))) - --static unsigned dma_debug; -+struct vc_dmaman { -+ void __iomem *dma_base; -+ u32 chan_available; /* bitmap of available channels */ -+ u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ -+ struct mutex lock; -+}; -+ -+static struct device *dmaman_dev; /* we assume there's only one! */ -+static struct vc_dmaman *g_dmaman; /* DMA manager */ -+static int dmachans = -1; /* module parameter */ -+ -+/* DMA Auxiliary Functions */ -+ -+/* A DMA buffer on an arbitrary boundary may separate a cache line into a -+ section inside the DMA buffer and another section outside it. -+ Even if we flush DMA buffers from the cache there is always the chance that -+ during a DMA someone will access the part of a cache line that is outside -+ the DMA buffer - which will then bring in unwelcome data. -+ Without being able to dictate our own buffer pools we must insist that -+ DMA buffers consist of a whole number of cache lines. -+*/ -+extern int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) -+{ -+ int i; -+ -+ for (i = 0; i < sg_len; i++) { -+ if (sg_ptr[i].offset & CACHE_LINE_MASK || -+ sg_ptr[i].length & CACHE_LINE_MASK) -+ return 0; -+ } -+ -+ return 1; -+} -+EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -+ -+extern void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block) -+{ -+ dsb(); /* ARM data synchronization (push) operation */ -+ -+ writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -+ writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); -+} -+EXPORT_SYMBOL_GPL(bcm_dma_start); -+ -+extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ /* ugly busy wait only option for now */ -+ while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -+ cpu_relax(); -+} -+EXPORT_SYMBOL_GPL(bcm_dma_wait_idle); -+ -+extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ dsb(); -+ -+ return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -+ -+/* Complete an ongoing DMA (assuming its results are to be ignored) -+ Does nothing if there is no DMA in progress. -+ This routine waits for the current AXI transfer to complete before -+ terminating the current DMA. If the current transfer is hung on a DREQ used -+ by an uncooperative peripheral the AXI transfer may never complete. In this -+ case the routine times out and return a non-zero error code. -+ Use of this routine doesn't guarantee that the ongoing or aborted DMA -+ does not produce an interrupt. -+*/ -+extern int bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ unsigned long int cs; -+ int rc = 0; -+ -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (BCM2708_DMA_ACTIVE & cs) { -+ long int timeout = 10000; -+ -+ /* write 0 to the active bit - pause the DMA */ -+ writel(0, dma_chan_base + BCM2708_DMA_CS); -+ -+ /* wait for any current AXI transfer to complete */ -+ while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -+ cs = readl(dma_chan_base + BCM2708_DMA_CS); -+ -+ if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -+ /* we'll un-pause when we set of our next DMA */ -+ rc = -ETIMEDOUT; -+ -+ } else if (BCM2708_DMA_ACTIVE & cs) { -+ /* terminate the control block chain */ -+ writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -+ -+ /* abort the whole DMA */ -+ writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -+ dma_chan_base + BCM2708_DMA_CS); -+ } -+ } -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_abort); -+ -+ /* DMA Manager Device Methods */ -+ -+static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -+ u32 chans_available) -+{ -+ dmaman->dma_base = dma_base; -+ dmaman->chan_available = chans_available; -+ dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* 2 & 3 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* 0 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* 1 to 7 */ -+ dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* 8 to 14 */ -+} -+ -+static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -+ unsigned preferred_feature_set) -+{ -+ u32 chans; -+ int chan = 0; -+ int feature; -+ -+ chans = dmaman->chan_available; -+ for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -+ /* select the subset of available channels with the desired -+ feature so long as some of the candidate channels have that -+ feature */ -+ if ((preferred_feature_set & (1 << feature)) && -+ (chans & dmaman->has_feature[feature])) -+ chans &= dmaman->has_feature[feature]; -+ -+ if (!chans) -+ return -ENOENT; -+ -+ /* return the ordinal of the first channel in the bitmap */ -+ while (chans != 0 && (chans & 1) == 0) { -+ chans >>= 1; -+ chan++; -+ } -+ /* claim the channel */ -+ dmaman->chan_available &= ~(1 << chan); -+ -+ return chan; -+} -+ -+static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) -+{ -+ if (chan < 0) -+ return -EINVAL; -+ -+ if ((1 << chan) & dmaman->chan_available) -+ return -EIDRM; -+ -+ dmaman->chan_available |= (1 << chan); -+ -+ return 0; -+} -+ -+/* DMA Manager Monitor */ -+ -+extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq) -+{ -+ struct vc_dmaman *dmaman = g_dmaman; -+ struct platform_device *pdev = to_platform_device(dmaman_dev); -+ struct resource *r; -+ int chan; -+ -+ if (!dmaman_dev) -+ return -ENODEV; -+ -+ mutex_lock(&dmaman->lock); -+ chan = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -+ if (chan < 0) -+ goto out; -+ -+ r = platform_get_resource(pdev, IORESOURCE_IRQ, (unsigned int)chan); -+ if (!r) { -+ dev_err(dmaman_dev, "failed to get irq for DMA channel %d\n", -+ chan); -+ vc_dmaman_chan_free(dmaman, chan); -+ chan = -ENOENT; -+ goto out; -+ } -+ -+ *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, chan); -+ *out_dma_irq = r->start; -+ dev_dbg(dmaman_dev, -+ "Legacy API allocated channel=%d, base=%p, irq=%i\n", -+ chan, *out_dma_base, *out_dma_irq); -+ -+out: -+ mutex_unlock(&dmaman->lock); -+ -+ return chan; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -+ -+extern int bcm_dma_chan_free(int channel) -+{ -+ struct vc_dmaman *dmaman = g_dmaman; -+ int rc; -+ -+ if (!dmaman_dev) -+ return -ENODEV; -+ -+ mutex_lock(&dmaman->lock); -+ rc = vc_dmaman_chan_free(dmaman, channel); -+ mutex_unlock(&dmaman->lock); -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -+ -+static int bcm_dmaman_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct vc_dmaman *dmaman; -+ struct resource *r; -+ void __iomem *dma_base; -+ uint32_t val; -+ -+ if (!of_property_read_u32(dev->of_node, -+ "brcm,dma-channel-mask", &val)) -+ dmachans = val; -+ else if (dmachans == -1) -+ dmachans = DEFAULT_DMACHAN_BITMAP; -+ -+ dmaman = devm_kzalloc(dev, sizeof(*dmaman), GFP_KERNEL); -+ if (!dmaman) -+ return -ENOMEM; -+ -+ mutex_init(&dmaman->lock); -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ dma_base = devm_ioremap_resource(dev, r); -+ if (IS_ERR(dma_base)) -+ return PTR_ERR(dma_base); -+ -+ vc_dmaman_init(dmaman, dma_base, dmachans); -+ g_dmaman = dmaman; -+ dmaman_dev = dev; -+ -+ dev_info(dev, "DMA legacy API manager at %p, dmachans=0x%x\n", -+ dma_base, dmachans); -+ -+ return 0; -+} -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ dmaman_dev = NULL; -+ -+ return 0; -+} -+ -+#else /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+static int bcm_dmaman_remove(struct platform_device *pdev) -+{ -+ return 0; -+} -+ -+#endif /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+/* -+ * DMA engine -+ */ - - struct bcm2835_dmadev { - struct dma_device ddev; -@@ -709,7 +987,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan) - return 0; - } - --#ifdef CONFIG_ARCH_BCM2835 -+#ifndef CONFIG_DMA_BCM2708_LEGACY - static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) - { - struct bcm2835_chan *c; -@@ -787,7 +1065,7 @@ static struct dma_chan *bcm2835_dma_xlate(struct of_phandle_args *spec, - static int bcm2835_dma_probe(struct platform_device *pdev) - { - struct bcm2835_dmadev *od; --#ifdef CONFIG_ARCH_BCM2835 -+#ifndef CONFIG_DMA_BCM2708_LEGACY - struct resource *res; - void __iomem *base; - uint32_t chans_available; -@@ -800,10 +1078,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; - -- /* If CONFIG_ARCH_BCM2835 is selected, device tree is used */ -- /* hence the difference between probing */ -- --#ifndef CONFIG_ARCH_BCM2835 -+#ifdef CONFIG_DMA_BCM2708_LEGACY - - rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (rc) -@@ -815,6 +1090,10 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - if (!od) - return -ENOMEM; - -+ rc = bcm_dmaman_probe(pdev); -+ if (rc) -+ return rc; -+ - pdev->dev.dma_parms = &od->dma_parms; - dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF); - -@@ -971,6 +1250,7 @@ static int bcm2835_dma_remove(struct platform_device *pdev) - - dma_async_device_unregister(&od->ddev); - bcm2835_dma_free(od); -+ bcm_dmaman_remove(pdev); - - return 0; - } -@@ -985,9 +1265,30 @@ static struct platform_driver bcm2835_dma_driver = { - }, - }; - --module_platform_driver(bcm2835_dma_driver); -+static int bcm2835_init(void) -+{ -+ return platform_driver_register(&bcm2835_dma_driver); -+} -+ -+static void bcm2835_exit(void) -+{ -+ platform_driver_unregister(&bcm2835_dma_driver); -+} -+ -+/* -+ * Load after serial driver (arch_initcall) so we see the messages if it fails, -+ * but before drivers (module_init) that need a DMA channel. -+ */ -+subsys_initcall(bcm2835_init); -+module_exit(bcm2835_exit); - - module_param(dma_debug, uint, 0644); -+#ifdef CONFIG_DMA_BCM2708_LEGACY -+/* Keep backward compatibility: dma.dmachans= */ -+#undef MODULE_PARAM_PREFIX -+#define MODULE_PARAM_PREFIX "dma." -+module_param(dmachans, int, 0644); -+#endif - MODULE_ALIAS("platform:bcm2835-dma"); - MODULE_DESCRIPTION("BCM2835 DMA engine driver"); - MODULE_AUTHOR("Florian Meier "); -diff --git a/include/linux/platform_data/dma-bcm2708.h b/include/linux/platform_data/dma-bcm2708.h -new file mode 100644 -index 0000000..2310e34 ---- /dev/null -+++ b/include/linux/platform_data/dma-bcm2708.h -@@ -0,0 +1,127 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef _PLAT_BCM2708_DMA_H -+#define _PLAT_BCM2708_DMA_H -+ -+/* DMA CS Control and Status bits */ -+#define BCM2708_DMA_ACTIVE BIT(0) -+#define BCM2708_DMA_INT BIT(2) -+#define BCM2708_DMA_ISPAUSED BIT(4) /* Pause requested or not active */ -+#define BCM2708_DMA_ISHELD BIT(5) /* Is held by DREQ flow control */ -+#define BCM2708_DMA_ERR BIT(8) -+#define BCM2708_DMA_ABORT BIT(30) /* stop current CB, go to next, WO */ -+#define BCM2708_DMA_RESET BIT(31) /* WO, self clearing */ -+ -+/* DMA control block "info" field bits */ -+#define BCM2708_DMA_INT_EN BIT(0) -+#define BCM2708_DMA_TDMODE BIT(1) -+#define BCM2708_DMA_WAIT_RESP BIT(3) -+#define BCM2708_DMA_D_INC BIT(4) -+#define BCM2708_DMA_D_WIDTH BIT(5) -+#define BCM2708_DMA_D_DREQ BIT(6) -+#define BCM2708_DMA_S_INC BIT(8) -+#define BCM2708_DMA_S_WIDTH BIT(9) -+#define BCM2708_DMA_S_DREQ BIT(10) -+ -+#define BCM2708_DMA_BURST(x) (((x) & 0xf) << 12) -+#define BCM2708_DMA_PER_MAP(x) ((x) << 16) -+#define BCM2708_DMA_WAITS(x) (((x) & 0x1f) << 21) -+ -+#define BCM2708_DMA_DREQ_EMMC 11 -+#define BCM2708_DMA_DREQ_SDHOST 13 -+ -+#define BCM2708_DMA_CS 0x00 /* Control and Status */ -+#define BCM2708_DMA_ADDR 0x04 -+/* the current control block appears in the following registers - read only */ -+#define BCM2708_DMA_INFO 0x08 -+#define BCM2708_DMA_SOURCE_AD 0x0c -+#define BCM2708_DMA_DEST_AD 0x10 -+#define BCM2708_DMA_NEXTCB 0x1C -+#define BCM2708_DMA_DEBUG 0x20 -+ -+#define BCM2708_DMA4_CS (BCM2708_DMA_CHAN(4) + BCM2708_DMA_CS) -+#define BCM2708_DMA4_ADDR (BCM2708_DMA_CHAN(4) + BCM2708_DMA_ADDR) -+ -+#define BCM2708_DMA_TDMODE_LEN(w, h) ((h) << 16 | (w)) -+ -+/* When listing features we can ask for when allocating DMA channels give -+ those with higher priority smaller ordinal numbers */ -+#define BCM_DMA_FEATURE_FAST_ORD 0 -+#define BCM_DMA_FEATURE_BULK_ORD 1 -+#define BCM_DMA_FEATURE_NORMAL_ORD 2 -+#define BCM_DMA_FEATURE_LITE_ORD 3 -+#define BCM_DMA_FEATURE_FAST BIT(BCM_DMA_FEATURE_FAST_ORD) -+#define BCM_DMA_FEATURE_BULK BIT(BCM_DMA_FEATURE_BULK_ORD) -+#define BCM_DMA_FEATURE_NORMAL BIT(BCM_DMA_FEATURE_NORMAL_ORD) -+#define BCM_DMA_FEATURE_LITE BIT(BCM_DMA_FEATURE_LITE_ORD) -+#define BCM_DMA_FEATURE_COUNT 4 -+ -+struct bcm2708_dma_cb { -+ unsigned long info; -+ unsigned long src; -+ unsigned long dst; -+ unsigned long length; -+ unsigned long stride; -+ unsigned long next; -+ unsigned long pad[2]; -+}; -+ -+struct scatterlist; -+ -+#ifdef CONFIG_DMA_BCM2708_LEGACY -+ -+int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len); -+void bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block); -+void bcm_dma_wait_idle(void __iomem *dma_chan_base); -+bool bcm_dma_is_busy(void __iomem *dma_chan_base); -+int bcm_dma_abort(void __iomem *dma_chan_base); -+ -+/* return channel no or -ve error */ -+int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, int *out_dma_irq); -+int bcm_dma_chan_free(int channel); -+ -+#else /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+static inline int bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, -+ int sg_len) -+{ -+ return 0; -+} -+ -+static inline void bcm_dma_start(void __iomem *dma_chan_base, -+ dma_addr_t control_block) { } -+ -+static inline void bcm_dma_wait_idle(void __iomem *dma_chan_base) { } -+ -+static inline bool bcm_dma_is_busy(void __iomem *dma_chan_base) -+{ -+ return false; -+} -+ -+static inline int bcm_dma_abort(void __iomem *dma_chan_base) -+{ -+ return -EINVAL; -+} -+ -+static inline int bcm_dma_chan_alloc(unsigned preferred_feature_set, -+ void __iomem **out_dma_base, -+ int *out_dma_irq) -+{ -+ return -EINVAL; -+} -+ -+static inline int bcm_dma_chan_free(int channel) -+{ -+ return -EINVAL; -+} -+ -+#endif /* CONFIG_DMA_BCM2708_LEGACY */ -+ -+#endif /* _PLAT_BCM2708_DMA_H */ - -From 2b9f3386a080d00da4e6335272fe3b94cc51cfef Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:26:59 +0200 -Subject: [PATCH 124/216] BCM270x: dma: Remove driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove dma.c driver which is now merged with bcm2708-dmaengine. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/dma.c | 409 -------------------------------------------- - arch/arm/mach-bcm2709/dma.c | 409 -------------------------------------------- - 2 files changed, 818 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/dma.c - delete mode 100644 arch/arm/mach-bcm2709/dma.c - -diff --git a/arch/arm/mach-bcm2708/dma.c b/arch/arm/mach-bcm2708/dma.c -deleted file mode 100644 -index a5e58d1..0000000 ---- a/arch/arm/mach-bcm2708/dma.c -+++ /dev/null -@@ -1,409 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/dma.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- --#include --#include --#include --#include --#include -- --#include --#include -- --/*****************************************************************************\ -- * * -- * Configuration * -- * * --\*****************************************************************************/ -- --#define CACHE_LINE_MASK 31 --#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME --#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -- --/* valid only for channels 0 - 14, 15 has its own base address */ --#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ --#define BCM2708_DMA_CHANIO(dma_base, n) \ -- ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -- -- --/*****************************************************************************\ -- * * -- * DMA Auxilliary Functions * -- * * --\*****************************************************************************/ -- --/* A DMA buffer on an arbitrary boundary may separate a cache line into a -- section inside the DMA buffer and another section outside it. -- Even if we flush DMA buffers from the cache there is always the chance that -- during a DMA someone will access the part of a cache line that is outside -- the DMA buffer - which will then bring in unwelcome data. -- Without being able to dictate our own buffer pools we must insist that -- DMA buffers consist of a whole number of cache lines. --*/ -- --extern int --bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) --{ -- int i; -- -- for (i = 0; i < sg_len; i++) { -- if (sg_ptr[i].offset & CACHE_LINE_MASK || -- sg_ptr[i].length & CACHE_LINE_MASK) -- return 0; -- } -- -- return 1; --} --EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -- --extern void --bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) --{ -- dsb(); /* ARM data synchronization (push) operation */ -- -- writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -- writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); --} -- --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) --{ -- dsb(); -- -- /* ugly busy wait only option for now */ -- while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -- cpu_relax(); --} -- --EXPORT_SYMBOL_GPL(bcm_dma_start); -- --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) --{ -- dsb(); -- -- return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; --} --EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -- --/* Complete an ongoing DMA (assuming its results are to be ignored) -- Does nothing if there is no DMA in progress. -- This routine waits for the current AXI transfer to complete before -- terminating the current DMA. If the current transfer is hung on a DREQ used -- by an uncooperative peripheral the AXI transfer may never complete. In this -- case the routine times out and return a non-zero error code. -- Use of this routine doesn't guarantee that the ongoing or aborted DMA -- does not produce an interrupt. --*/ --extern int --bcm_dma_abort(void __iomem *dma_chan_base) --{ -- unsigned long int cs; -- int rc = 0; -- -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (BCM2708_DMA_ACTIVE & cs) { -- long int timeout = 10000; -- -- /* write 0 to the active bit - pause the DMA */ -- writel(0, dma_chan_base + BCM2708_DMA_CS); -- -- /* wait for any current AXI transfer to complete */ -- while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -- /* we'll un-pause when we set of our next DMA */ -- rc = -ETIMEDOUT; -- -- } else if (BCM2708_DMA_ACTIVE & cs) { -- /* terminate the control block chain */ -- writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -- -- /* abort the whole DMA */ -- writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -- dma_chan_base + BCM2708_DMA_CS); -- } -- } -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_dma_abort); -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Device Methods * -- * * --\*****************************************************************************/ -- --struct vc_dmaman { -- void __iomem *dma_base; -- u32 chan_available; /* bitmap of available channels */ -- u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ --}; -- --static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -- u32 chans_available) --{ -- dmaman->dma_base = dma_base; -- dmaman->chan_available = chans_available; -- dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -- dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -- dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -- dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ --} -- --static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -- unsigned preferred_feature_set) --{ -- u32 chans; -- int feature; -- -- chans = dmaman->chan_available; -- for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -- /* select the subset of available channels with the desired -- feature so long as some of the candidate channels have that -- feature */ -- if ((preferred_feature_set & (1 << feature)) && -- (chans & dmaman->has_feature[feature])) -- chans &= dmaman->has_feature[feature]; -- -- if (chans) { -- int chan = 0; -- /* return the ordinal of the first channel in the bitmap */ -- while (chans != 0 && (chans & 1) == 0) { -- chans >>= 1; -- chan++; -- } -- /* claim the channel */ -- dmaman->chan_available &= ~(1 << chan); -- return chan; -- } else -- return -ENOMEM; --} -- --static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) --{ -- if (chan < 0) -- return -EINVAL; -- else if ((1 << chan) & dmaman->chan_available) -- return -EIDRM; -- else { -- dmaman->chan_available |= (1 << chan); -- return 0; -- } --} -- --/*****************************************************************************\ -- * * -- * DMA IRQs * -- * * --\*****************************************************************************/ -- --static unsigned char bcm_dma_irqs[] = { -- IRQ_DMA0, -- IRQ_DMA1, -- IRQ_DMA2, -- IRQ_DMA3, -- IRQ_DMA4, -- IRQ_DMA5, -- IRQ_DMA6, -- IRQ_DMA7, -- IRQ_DMA8, -- IRQ_DMA9, -- IRQ_DMA10, -- IRQ_DMA11, -- IRQ_DMA12 --}; -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Monitor * -- * * --\*****************************************************************************/ -- --static struct device *dmaman_dev; /* we assume there's only one! */ -- --extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -- void __iomem **out_dma_base, int *out_dma_irq) --{ -- if (!dmaman_dev) -- return -ENODEV; -- else { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -- if (rc >= 0) { -- *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -- rc); -- *out_dma_irq = bcm_dma_irqs[rc]; -- } -- device_unlock(dmaman_dev); -- -- return rc; -- } --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -- --extern int bcm_dma_chan_free(int channel) --{ -- if (dmaman_dev) { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_free(dmaman, channel); -- device_unlock(dmaman_dev); -- -- return rc; -- } else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -- --static int dev_dmaman_register(const char *dev_name, struct device *dev) --{ -- int rc = dmaman_dev ? -EINVAL : 0; -- dmaman_dev = dev; -- return rc; --} -- --static void dev_dmaman_deregister(const char *dev_name, struct device *dev) --{ -- dmaman_dev = NULL; --} -- --/*****************************************************************************\ -- * * -- * DMA Device * -- * * --\*****************************************************************************/ -- --static int dmachans = -1; /* module parameter */ -- --static int bcm_dmaman_probe(struct platform_device *pdev) --{ -- int ret = 0; -- struct vc_dmaman *dmaman; -- struct resource *dma_res = NULL; -- void __iomem *dma_base = NULL; -- int have_dma_region = 0; -- -- dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -- if (NULL == dmaman) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "DMA management memory\n"); -- ret = -ENOMEM; -- } else { -- -- dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (dma_res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -- ret = -ENODEV; -- } else if (!request_mem_region(dma_res->start, -- resource_size(dma_res), -- DRIVER_NAME)) { -- dev_err(&pdev->dev, "cannot obtain DMA region\n"); -- ret = -EBUSY; -- } else { -- have_dma_region = 1; -- dma_base = ioremap(dma_res->start, -- resource_size(dma_res)); -- if (!dma_base) { -- dev_err(&pdev->dev, "cannot map DMA region\n"); -- ret = -ENOMEM; -- } else { -- /* use module parameter if one was provided */ -- if (dmachans > 0) -- vc_dmaman_init(dmaman, dma_base, -- dmachans); -- else -- vc_dmaman_init(dmaman, dma_base, -- DEFAULT_DMACHAN_BITMAP); -- -- platform_set_drvdata(pdev, dmaman); -- dev_dmaman_register(DRIVER_NAME, &pdev->dev); -- -- printk(KERN_INFO DRIVER_NAME ": DMA manager " -- "at %p\n", dma_base); -- } -- } -- } -- if (ret != 0) { -- if (dma_base) -- iounmap(dma_base); -- if (dma_res && have_dma_region) -- release_mem_region(dma_res->start, -- resource_size(dma_res)); -- if (dmaman) -- kfree(dmaman); -- } -- return ret; --} -- --static int bcm_dmaman_remove(struct platform_device *pdev) --{ -- struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -- -- platform_set_drvdata(pdev, NULL); -- dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -- kfree(dmaman); -- -- return 0; --} -- --static struct platform_driver bcm_dmaman_driver = { -- .probe = bcm_dmaman_probe, -- .remove = bcm_dmaman_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; -- --/*****************************************************************************\ -- * * -- * Driver init/exit * -- * * --\*****************************************************************************/ -- --static int __init bcm_dmaman_drv_init(void) --{ -- int ret; -- -- ret = platform_driver_register(&bcm_dmaman_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -- -- return ret; --} -- --static void __exit bcm_dmaman_drv_exit(void) --{ -- platform_driver_unregister(&bcm_dmaman_driver); --} -- --module_init(bcm_dmaman_drv_init); --module_exit(bcm_dmaman_drv_exit); -- --module_param(dmachans, int, 0644); -- --MODULE_AUTHOR("Gray Girling "); --MODULE_DESCRIPTION("DMA channel manager driver"); --MODULE_LICENSE("GPL"); -- --MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); -diff --git a/arch/arm/mach-bcm2709/dma.c b/arch/arm/mach-bcm2709/dma.c -deleted file mode 100644 -index a5e58d1..0000000 ---- a/arch/arm/mach-bcm2709/dma.c -+++ /dev/null -@@ -1,409 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/dma.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- */ -- --#include --#include --#include --#include --#include -- --#include --#include -- --/*****************************************************************************\ -- * * -- * Configuration * -- * * --\*****************************************************************************/ -- --#define CACHE_LINE_MASK 31 --#define DRIVER_NAME BCM_DMAMAN_DRIVER_NAME --#define DEFAULT_DMACHAN_BITMAP 0x10 /* channel 4 only */ -- --/* valid only for channels 0 - 14, 15 has its own base address */ --#define BCM2708_DMA_CHAN(n) ((n)<<8) /* base address */ --#define BCM2708_DMA_CHANIO(dma_base, n) \ -- ((void __iomem *)((char *)(dma_base)+BCM2708_DMA_CHAN(n))) -- -- --/*****************************************************************************\ -- * * -- * DMA Auxilliary Functions * -- * * --\*****************************************************************************/ -- --/* A DMA buffer on an arbitrary boundary may separate a cache line into a -- section inside the DMA buffer and another section outside it. -- Even if we flush DMA buffers from the cache there is always the chance that -- during a DMA someone will access the part of a cache line that is outside -- the DMA buffer - which will then bring in unwelcome data. -- Without being able to dictate our own buffer pools we must insist that -- DMA buffers consist of a whole number of cache lines. --*/ -- --extern int --bcm_sg_suitable_for_dma(struct scatterlist *sg_ptr, int sg_len) --{ -- int i; -- -- for (i = 0; i < sg_len; i++) { -- if (sg_ptr[i].offset & CACHE_LINE_MASK || -- sg_ptr[i].length & CACHE_LINE_MASK) -- return 0; -- } -- -- return 1; --} --EXPORT_SYMBOL_GPL(bcm_sg_suitable_for_dma); -- --extern void --bcm_dma_start(void __iomem *dma_chan_base, dma_addr_t control_block) --{ -- dsb(); /* ARM data synchronization (push) operation */ -- -- writel(control_block, dma_chan_base + BCM2708_DMA_ADDR); -- writel(BCM2708_DMA_ACTIVE, dma_chan_base + BCM2708_DMA_CS); --} -- --extern void bcm_dma_wait_idle(void __iomem *dma_chan_base) --{ -- dsb(); -- -- /* ugly busy wait only option for now */ -- while (readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE) -- cpu_relax(); --} -- --EXPORT_SYMBOL_GPL(bcm_dma_start); -- --extern bool bcm_dma_is_busy(void __iomem *dma_chan_base) --{ -- dsb(); -- -- return readl(dma_chan_base + BCM2708_DMA_CS) & BCM2708_DMA_ACTIVE; --} --EXPORT_SYMBOL_GPL(bcm_dma_is_busy); -- --/* Complete an ongoing DMA (assuming its results are to be ignored) -- Does nothing if there is no DMA in progress. -- This routine waits for the current AXI transfer to complete before -- terminating the current DMA. If the current transfer is hung on a DREQ used -- by an uncooperative peripheral the AXI transfer may never complete. In this -- case the routine times out and return a non-zero error code. -- Use of this routine doesn't guarantee that the ongoing or aborted DMA -- does not produce an interrupt. --*/ --extern int --bcm_dma_abort(void __iomem *dma_chan_base) --{ -- unsigned long int cs; -- int rc = 0; -- -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (BCM2708_DMA_ACTIVE & cs) { -- long int timeout = 10000; -- -- /* write 0 to the active bit - pause the DMA */ -- writel(0, dma_chan_base + BCM2708_DMA_CS); -- -- /* wait for any current AXI transfer to complete */ -- while (0 != (cs & BCM2708_DMA_ISPAUSED) && --timeout >= 0) -- cs = readl(dma_chan_base + BCM2708_DMA_CS); -- -- if (0 != (cs & BCM2708_DMA_ISPAUSED)) { -- /* we'll un-pause when we set of our next DMA */ -- rc = -ETIMEDOUT; -- -- } else if (BCM2708_DMA_ACTIVE & cs) { -- /* terminate the control block chain */ -- writel(0, dma_chan_base + BCM2708_DMA_NEXTCB); -- -- /* abort the whole DMA */ -- writel(BCM2708_DMA_ABORT | BCM2708_DMA_ACTIVE, -- dma_chan_base + BCM2708_DMA_CS); -- } -- } -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_dma_abort); -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Device Methods * -- * * --\*****************************************************************************/ -- --struct vc_dmaman { -- void __iomem *dma_base; -- u32 chan_available; /* bitmap of available channels */ -- u32 has_feature[BCM_DMA_FEATURE_COUNT]; /* bitmap of feature presence */ --}; -- --static void vc_dmaman_init(struct vc_dmaman *dmaman, void __iomem *dma_base, -- u32 chans_available) --{ -- dmaman->dma_base = dma_base; -- dmaman->chan_available = chans_available; -- dmaman->has_feature[BCM_DMA_FEATURE_FAST_ORD] = 0x0c; /* chans 2 & 3 */ -- dmaman->has_feature[BCM_DMA_FEATURE_BULK_ORD] = 0x01; /* chan 0 */ -- dmaman->has_feature[BCM_DMA_FEATURE_NORMAL_ORD] = 0xfe; /* chans 1 to 7 */ -- dmaman->has_feature[BCM_DMA_FEATURE_LITE_ORD] = 0x7f00; /* chans 8 to 14 */ --} -- --static int vc_dmaman_chan_alloc(struct vc_dmaman *dmaman, -- unsigned preferred_feature_set) --{ -- u32 chans; -- int feature; -- -- chans = dmaman->chan_available; -- for (feature = 0; feature < BCM_DMA_FEATURE_COUNT; feature++) -- /* select the subset of available channels with the desired -- feature so long as some of the candidate channels have that -- feature */ -- if ((preferred_feature_set & (1 << feature)) && -- (chans & dmaman->has_feature[feature])) -- chans &= dmaman->has_feature[feature]; -- -- if (chans) { -- int chan = 0; -- /* return the ordinal of the first channel in the bitmap */ -- while (chans != 0 && (chans & 1) == 0) { -- chans >>= 1; -- chan++; -- } -- /* claim the channel */ -- dmaman->chan_available &= ~(1 << chan); -- return chan; -- } else -- return -ENOMEM; --} -- --static int vc_dmaman_chan_free(struct vc_dmaman *dmaman, int chan) --{ -- if (chan < 0) -- return -EINVAL; -- else if ((1 << chan) & dmaman->chan_available) -- return -EIDRM; -- else { -- dmaman->chan_available |= (1 << chan); -- return 0; -- } --} -- --/*****************************************************************************\ -- * * -- * DMA IRQs * -- * * --\*****************************************************************************/ -- --static unsigned char bcm_dma_irqs[] = { -- IRQ_DMA0, -- IRQ_DMA1, -- IRQ_DMA2, -- IRQ_DMA3, -- IRQ_DMA4, -- IRQ_DMA5, -- IRQ_DMA6, -- IRQ_DMA7, -- IRQ_DMA8, -- IRQ_DMA9, -- IRQ_DMA10, -- IRQ_DMA11, -- IRQ_DMA12 --}; -- -- --/***************************************************************************** \ -- * * -- * DMA Manager Monitor * -- * * --\*****************************************************************************/ -- --static struct device *dmaman_dev; /* we assume there's only one! */ -- --extern int bcm_dma_chan_alloc(unsigned preferred_feature_set, -- void __iomem **out_dma_base, int *out_dma_irq) --{ -- if (!dmaman_dev) -- return -ENODEV; -- else { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_alloc(dmaman, preferred_feature_set); -- if (rc >= 0) { -- *out_dma_base = BCM2708_DMA_CHANIO(dmaman->dma_base, -- rc); -- *out_dma_irq = bcm_dma_irqs[rc]; -- } -- device_unlock(dmaman_dev); -- -- return rc; -- } --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_alloc); -- --extern int bcm_dma_chan_free(int channel) --{ -- if (dmaman_dev) { -- struct vc_dmaman *dmaman = dev_get_drvdata(dmaman_dev); -- int rc; -- -- device_lock(dmaman_dev); -- rc = vc_dmaman_chan_free(dmaman, channel); -- device_unlock(dmaman_dev); -- -- return rc; -- } else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_dma_chan_free); -- --static int dev_dmaman_register(const char *dev_name, struct device *dev) --{ -- int rc = dmaman_dev ? -EINVAL : 0; -- dmaman_dev = dev; -- return rc; --} -- --static void dev_dmaman_deregister(const char *dev_name, struct device *dev) --{ -- dmaman_dev = NULL; --} -- --/*****************************************************************************\ -- * * -- * DMA Device * -- * * --\*****************************************************************************/ -- --static int dmachans = -1; /* module parameter */ -- --static int bcm_dmaman_probe(struct platform_device *pdev) --{ -- int ret = 0; -- struct vc_dmaman *dmaman; -- struct resource *dma_res = NULL; -- void __iomem *dma_base = NULL; -- int have_dma_region = 0; -- -- dmaman = kzalloc(sizeof(*dmaman), GFP_KERNEL); -- if (NULL == dmaman) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "DMA management memory\n"); -- ret = -ENOMEM; -- } else { -- -- dma_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (dma_res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -- ret = -ENODEV; -- } else if (!request_mem_region(dma_res->start, -- resource_size(dma_res), -- DRIVER_NAME)) { -- dev_err(&pdev->dev, "cannot obtain DMA region\n"); -- ret = -EBUSY; -- } else { -- have_dma_region = 1; -- dma_base = ioremap(dma_res->start, -- resource_size(dma_res)); -- if (!dma_base) { -- dev_err(&pdev->dev, "cannot map DMA region\n"); -- ret = -ENOMEM; -- } else { -- /* use module parameter if one was provided */ -- if (dmachans > 0) -- vc_dmaman_init(dmaman, dma_base, -- dmachans); -- else -- vc_dmaman_init(dmaman, dma_base, -- DEFAULT_DMACHAN_BITMAP); -- -- platform_set_drvdata(pdev, dmaman); -- dev_dmaman_register(DRIVER_NAME, &pdev->dev); -- -- printk(KERN_INFO DRIVER_NAME ": DMA manager " -- "at %p\n", dma_base); -- } -- } -- } -- if (ret != 0) { -- if (dma_base) -- iounmap(dma_base); -- if (dma_res && have_dma_region) -- release_mem_region(dma_res->start, -- resource_size(dma_res)); -- if (dmaman) -- kfree(dmaman); -- } -- return ret; --} -- --static int bcm_dmaman_remove(struct platform_device *pdev) --{ -- struct vc_dmaman *dmaman = platform_get_drvdata(pdev); -- -- platform_set_drvdata(pdev, NULL); -- dev_dmaman_deregister(DRIVER_NAME, &pdev->dev); -- kfree(dmaman); -- -- return 0; --} -- --static struct platform_driver bcm_dmaman_driver = { -- .probe = bcm_dmaman_probe, -- .remove = bcm_dmaman_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; -- --/*****************************************************************************\ -- * * -- * Driver init/exit * -- * * --\*****************************************************************************/ -- --static int __init bcm_dmaman_drv_init(void) --{ -- int ret; -- -- ret = platform_driver_register(&bcm_dmaman_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -- -- return ret; --} -- --static void __exit bcm_dmaman_drv_exit(void) --{ -- platform_driver_unregister(&bcm_dmaman_driver); --} -- --module_init(bcm_dmaman_drv_init); --module_exit(bcm_dmaman_drv_exit); -- --module_param(dmachans, int, 0644); -- --MODULE_AUTHOR("Gray Girling "); --MODULE_DESCRIPTION("DMA channel manager driver"); --MODULE_LICENSE("GPL"); -- --MODULE_PARM_DESC(dmachans, "Bitmap of DMA channels available to the ARM"); - -From d2647dd924553835bc9b8f6ec0dce6cc25662d32 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 28 Apr 2015 19:54:17 +0200 -Subject: [PATCH 125/216] BCM270x: Remove dmaman device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove the dmaman device since the dmaengine now handles -the legacy API manager. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 16 ---------------- - arch/arm/mach-bcm2709/bcm2709.c | 16 ---------------- - 2 files changed, 32 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 703215d..486e090 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -247,21 +247,6 @@ static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - }; - --static struct resource bcm2708_dmaman_resources[] = { -- { -- .start = DMA_BASE, -- .end = DMA_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- } --}; -- --static struct platform_device bcm2708_dmaman_device = { -- .name = "bcm2708_dma", -- .id = 0, /* first bcm2708_dma */ -- .resource = bcm2708_dmaman_resources, -- .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), --}; -- - static struct resource bcm2708_dmaengine_resources[] = { - { - .start = DMA_BASE, -@@ -919,7 +904,6 @@ void __init bcm2708_init(void) - bcm2708_init_clocks(); - bcm2708_dt_init(); - -- bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 97116c3..44bfc50 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -257,21 +257,6 @@ static struct amba_device *amba_devs[] __initdata = { - &uart0_device, - }; - --static struct resource bcm2708_dmaman_resources[] = { -- { -- .start = DMA_BASE, -- .end = DMA_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- } --}; -- --static struct platform_device bcm2708_dmaman_device = { -- .name = "bcm2708_dma", -- .id = 0, /* first bcm2708_dma */ -- .resource = bcm2708_dmaman_resources, -- .num_resources = ARRAY_SIZE(bcm2708_dmaman_resources), --}; -- - static struct resource bcm2708_dmaengine_resources[] = { - { - .start = DMA_BASE, -@@ -940,7 +925,6 @@ void __init bcm2709_init(void) - bcm2709_init_clocks(); - bcm2709_dt_init(); - -- bcm_register_device(&bcm2708_dmaman_device); - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); - #ifdef CONFIG_BCM2708_GPIO - -From 149df0acaf7510d53047e19054e3b13607f60afd Mon Sep 17 00:00:00 2001 +From d8492b31751e7eda1b9b2c92dd381b5d7df1679d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 29 Apr 2015 17:24:02 +0200 -Subject: [PATCH 126/216] bcm2835: bcm2835_defconfig +Subject: [PATCH 68/77] bcm2835: bcm2835_defconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -136420,4129 +130931,1330 @@ some have changed. Update to keep functionality. No longer available: SCSI_MULTI_LUN and RESOURCE_COUNTERS. +Signed-off-by: Noralf Trønnes + +bcm2835: bcm2835_defconfig enable MMC_BCM2835 + +Enable the downstream bcm2835-mmc driver and DMA support. + +Signed-off-by: Noralf Trønnes + +bcm2835: bcm2835_defconfig enable BCM2708_MBOX + +Enable the mailbox driver. + +Signed-off-by: Noralf Trønnes + +bcm2835: bcm2835_defconfig use FB_BCM2708 + +Enable the bcm2708 framebuffer driver. +Disable the simple framebuffer driver, which matches the +device handed over by u-boot. + +Signed-off-by: Noralf Trønnes + +bcm2835: Merge bcm2835_defconfig with bcmrpi_defconfig + +These commands where used to make this commit: + +./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg + +cat << EOF > filter +CONFIG_ARCH_BCM2708 +CONFIG_BCM2708_DT +CONFIG_ARM_PATCH_PHYS_VIRT +CONFIG_PHYS_OFFSET +CONFIG_CMDLINE +CONFIG_BCM2708_WDT +CONFIG_HW_RANDOM_BCM2708 +CONFIG_I2C_BCM2708 +CONFIG_SPI_BCM2708 +CONFIG_SND_BCM2708_SOC_I2S +CONFIG_USB_DWCOTG +CONFIG_LIRC_RPI +EOF + +grep -F -v -f filter merge.cfg > filtered.cfg + +cat << EOF > added.cfg +CONFIG_WATCHDOG=y +CONFIG_BCM2835_WDT=y +CONFIG_MISC_FILESYSTEMS=y +CONFIG_SND_BCM2835_SOC_I2S=m +EOF + +ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg +ARCH=arm make oldconfig + +ARCH=arm make savedefconfig +cp defconfig arch/arm/configs/bcm2835_defconfig + +rm merge.cfg filter filtered.cfg added.cfg defconfig + +ARCH=arm make bcm2835_defconfig +ARCH=arm make oldconfig + Signed-off-by: Noralf Trønnes --- - arch/arm/configs/bcm2835_defconfig | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) + arch/arm/configs/bcm2835_defconfig | 1132 +++++++++++++++++++++++++++++++++++- + 1 file changed, 1107 insertions(+), 25 deletions(-) diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 31cb073..245aede 100644 +index 31cb073..2e8a95a 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig -@@ -10,7 +10,6 @@ CONFIG_CGROUP_FREEZER=y +@@ -1,105 +1,1071 @@ + # CONFIG_LOCALVERSION_AUTO is not set + CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y + CONFIG_FHANDLE=y + CONFIG_NO_HZ=y + CONFIG_HIGH_RES_TIMERS=y + CONFIG_BSD_PROCESS_ACCT=y + CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_XACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_IKCONFIG=m ++CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=18 + CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y ++CONFIG_MEMCG=y CONFIG_CGROUP_PERF=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y -@@ -18,10 +17,6 @@ CONFIG_NAMESPACES=y ++CONFIG_BLK_CGROUP=y + CONFIG_NAMESPACES=y CONFIG_SCHED_AUTOGROUP=y - CONFIG_RELAY=y +-CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y - CONFIG_KALLSYMS_ALL=y +-CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y -@@ -29,6 +24,7 @@ CONFIG_EMBEDDED=y + # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y - CONFIG_OPROFILE=y +-CONFIG_OPROFILE=y ++CONFIG_OPROFILE=m ++CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y +CONFIG_CC_STACKPROTECTOR_REGULAR=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODVERSIONS=y ++CONFIG_MODULE_SRCVERSION_ALL=y ++CONFIG_BLK_DEV_THROTTLING=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_MAC_PARTITION=y ++CONFIG_CFQ_GROUP_IOSCHED=y CONFIG_ARCH_MULTI_V6=y # CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_BCM=y -@@ -38,7 +34,6 @@ CONFIG_AEABI=y + CONFIG_ARCH_BCM2835=y +-CONFIG_PREEMPT_VOLUNTARY=y ++CONFIG_PREEMPT=y + CONFIG_AEABI=y ++CONFIG_OABI_COMPAT=y CONFIG_KSM=y CONFIG_CLEANCACHE=y ++CONFIG_FRONTSWAP=y ++CONFIG_CMA=y ++CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_SECCOMP=y -CONFIG_CC_STACKPROTECTOR=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_KEXEC=y CONFIG_CRASH_DUMP=y ++CONFIG_CPU_FREQ=y ++CONFIG_CPU_FREQ_STAT=m ++CONFIG_CPU_FREQ_STAT_DETAILS=y ++CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_VFP=y -@@ -57,7 +52,6 @@ CONFIG_DEVTMPFS_MOUNT=y + # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_BINFMT_MISC=m + # CONFIG_SUSPEND is not set + 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_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_RARP=y ++CONFIG_NET_IPIP=m ++CONFIG_NET_IPGRE_DEMUX=m ++CONFIG_NET_IPGRE=m ++CONFIG_IP_MROUTE=y ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_PIMSM_V1=y ++CONFIG_IP_PIMSM_V2=y ++CONFIG_SYN_COOKIES=y ++CONFIG_INET_AH=m ++CONFIG_INET_ESP=m ++CONFIG_INET_IPCOMP=m ++CONFIG_INET_XFRM_MODE_TRANSPORT=m ++CONFIG_INET_XFRM_MODE_TUNNEL=m ++CONFIG_INET_XFRM_MODE_BEET=m ++CONFIG_INET_LRO=m ++CONFIG_INET_DIAG=m ++CONFIG_INET6_AH=m ++CONFIG_INET6_ESP=m ++CONFIG_INET6_IPCOMP=m ++CONFIG_IPV6_TUNNEL=m ++CONFIG_IPV6_MULTIPLE_TABLES=y ++CONFIG_IPV6_MROUTE=y ++CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IPV6_PIMSM_V2=y + CONFIG_NETWORK_SECMARK=y + CONFIG_NETFILTER=y +-CONFIG_CFG80211=y +-CONFIG_MAC80211=y ++CONFIG_NF_CONNTRACK=m ++CONFIG_NF_CONNTRACK_ZONES=y ++CONFIG_NF_CONNTRACK_EVENTS=y ++CONFIG_NF_CONNTRACK_TIMESTAMP=y ++CONFIG_NF_CT_PROTO_DCCP=m ++CONFIG_NF_CT_PROTO_UDPLITE=m ++CONFIG_NF_CONNTRACK_AMANDA=m ++CONFIG_NF_CONNTRACK_FTP=m ++CONFIG_NF_CONNTRACK_H323=m ++CONFIG_NF_CONNTRACK_IRC=m ++CONFIG_NF_CONNTRACK_NETBIOS_NS=m ++CONFIG_NF_CONNTRACK_SNMP=m ++CONFIG_NF_CONNTRACK_PPTP=m ++CONFIG_NF_CONNTRACK_SANE=m ++CONFIG_NF_CONNTRACK_SIP=m ++CONFIG_NF_CONNTRACK_TFTP=m ++CONFIG_NF_CT_NETLINK=m ++CONFIG_NETFILTER_XT_SET=m ++CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m ++CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m ++CONFIG_NETFILTER_XT_TARGET_CONNMARK=m ++CONFIG_NETFILTER_XT_TARGET_DSCP=m ++CONFIG_NETFILTER_XT_TARGET_HMARK=m ++CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m ++CONFIG_NETFILTER_XT_TARGET_LED=m ++CONFIG_NETFILTER_XT_TARGET_LOG=m ++CONFIG_NETFILTER_XT_TARGET_MARK=m ++CONFIG_NETFILTER_XT_TARGET_NFLOG=m ++CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m ++CONFIG_NETFILTER_XT_TARGET_NOTRACK=m ++CONFIG_NETFILTER_XT_TARGET_TEE=m ++CONFIG_NETFILTER_XT_TARGET_TPROXY=m ++CONFIG_NETFILTER_XT_TARGET_TRACE=m ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=m ++CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m ++CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m ++CONFIG_NETFILTER_XT_MATCH_BPF=m ++CONFIG_NETFILTER_XT_MATCH_CLUSTER=m ++CONFIG_NETFILTER_XT_MATCH_COMMENT=m ++CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m ++CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m ++CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=m ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m ++CONFIG_NETFILTER_XT_MATCH_CPU=m ++CONFIG_NETFILTER_XT_MATCH_DCCP=m ++CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m ++CONFIG_NETFILTER_XT_MATCH_DSCP=m ++CONFIG_NETFILTER_XT_MATCH_ESP=m ++CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m ++CONFIG_NETFILTER_XT_MATCH_HELPER=m ++CONFIG_NETFILTER_XT_MATCH_IPRANGE=m ++CONFIG_NETFILTER_XT_MATCH_IPVS=m ++CONFIG_NETFILTER_XT_MATCH_LENGTH=m ++CONFIG_NETFILTER_XT_MATCH_LIMIT=m ++CONFIG_NETFILTER_XT_MATCH_MAC=m ++CONFIG_NETFILTER_XT_MATCH_MARK=m ++CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m ++CONFIG_NETFILTER_XT_MATCH_NFACCT=m ++CONFIG_NETFILTER_XT_MATCH_OSF=m ++CONFIG_NETFILTER_XT_MATCH_OWNER=m ++CONFIG_NETFILTER_XT_MATCH_POLICY=m ++CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m ++CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m ++CONFIG_NETFILTER_XT_MATCH_QUOTA=m ++CONFIG_NETFILTER_XT_MATCH_RATEEST=m ++CONFIG_NETFILTER_XT_MATCH_REALM=m ++CONFIG_NETFILTER_XT_MATCH_RECENT=m ++CONFIG_NETFILTER_XT_MATCH_SOCKET=m ++CONFIG_NETFILTER_XT_MATCH_STATE=m ++CONFIG_NETFILTER_XT_MATCH_STATISTIC=m ++CONFIG_NETFILTER_XT_MATCH_STRING=m ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=m ++CONFIG_NETFILTER_XT_MATCH_TIME=m ++CONFIG_NETFILTER_XT_MATCH_U32=m ++CONFIG_IP_SET=m ++CONFIG_IP_SET_BITMAP_IP=m ++CONFIG_IP_SET_BITMAP_IPMAC=m ++CONFIG_IP_SET_BITMAP_PORT=m ++CONFIG_IP_SET_HASH_IP=m ++CONFIG_IP_SET_HASH_IPPORT=m ++CONFIG_IP_SET_HASH_IPPORTIP=m ++CONFIG_IP_SET_HASH_IPPORTNET=m ++CONFIG_IP_SET_HASH_NET=m ++CONFIG_IP_SET_HASH_NETPORT=m ++CONFIG_IP_SET_HASH_NETIFACE=m ++CONFIG_IP_SET_LIST_SET=m ++CONFIG_IP_VS=m ++CONFIG_IP_VS_PROTO_TCP=y ++CONFIG_IP_VS_PROTO_UDP=y ++CONFIG_IP_VS_PROTO_ESP=y ++CONFIG_IP_VS_PROTO_AH=y ++CONFIG_IP_VS_PROTO_SCTP=y ++CONFIG_IP_VS_RR=m ++CONFIG_IP_VS_WRR=m ++CONFIG_IP_VS_LC=m ++CONFIG_IP_VS_WLC=m ++CONFIG_IP_VS_LBLC=m ++CONFIG_IP_VS_LBLCR=m ++CONFIG_IP_VS_DH=m ++CONFIG_IP_VS_SH=m ++CONFIG_IP_VS_SED=m ++CONFIG_IP_VS_NQ=m ++CONFIG_IP_VS_FTP=m ++CONFIG_IP_VS_PE_SIP=m ++CONFIG_NF_CONNTRACK_IPV4=m ++CONFIG_IP_NF_IPTABLES=m ++CONFIG_IP_NF_MATCH_AH=m ++CONFIG_IP_NF_MATCH_ECN=m ++CONFIG_IP_NF_MATCH_TTL=m ++CONFIG_IP_NF_FILTER=m ++CONFIG_IP_NF_TARGET_REJECT=m ++CONFIG_IP_NF_NAT=m ++CONFIG_IP_NF_TARGET_MASQUERADE=m ++CONFIG_IP_NF_TARGET_NETMAP=m ++CONFIG_IP_NF_TARGET_REDIRECT=m ++CONFIG_IP_NF_MANGLE=m ++CONFIG_IP_NF_TARGET_CLUSTERIP=m ++CONFIG_IP_NF_TARGET_ECN=m ++CONFIG_IP_NF_TARGET_TTL=m ++CONFIG_IP_NF_RAW=m ++CONFIG_IP_NF_ARPTABLES=m ++CONFIG_IP_NF_ARPFILTER=m ++CONFIG_IP_NF_ARP_MANGLE=m ++CONFIG_NF_CONNTRACK_IPV6=m ++CONFIG_IP6_NF_IPTABLES=m ++CONFIG_IP6_NF_MATCH_AH=m ++CONFIG_IP6_NF_MATCH_EUI64=m ++CONFIG_IP6_NF_MATCH_FRAG=m ++CONFIG_IP6_NF_MATCH_OPTS=m ++CONFIG_IP6_NF_MATCH_HL=m ++CONFIG_IP6_NF_MATCH_IPV6HEADER=m ++CONFIG_IP6_NF_MATCH_MH=m ++CONFIG_IP6_NF_MATCH_RT=m ++CONFIG_IP6_NF_TARGET_HL=m ++CONFIG_IP6_NF_FILTER=m ++CONFIG_IP6_NF_TARGET_REJECT=m ++CONFIG_IP6_NF_MANGLE=m ++CONFIG_IP6_NF_RAW=m ++CONFIG_IP6_NF_NAT=m ++CONFIG_IP6_NF_TARGET_MASQUERADE=m ++CONFIG_IP6_NF_TARGET_NPT=m ++CONFIG_BRIDGE_NF_EBTABLES=m ++CONFIG_BRIDGE_EBT_BROUTE=m ++CONFIG_BRIDGE_EBT_T_FILTER=m ++CONFIG_BRIDGE_EBT_T_NAT=m ++CONFIG_BRIDGE_EBT_802_3=m ++CONFIG_BRIDGE_EBT_AMONG=m ++CONFIG_BRIDGE_EBT_ARP=m ++CONFIG_BRIDGE_EBT_IP=m ++CONFIG_BRIDGE_EBT_IP6=m ++CONFIG_BRIDGE_EBT_LIMIT=m ++CONFIG_BRIDGE_EBT_MARK=m ++CONFIG_BRIDGE_EBT_PKTTYPE=m ++CONFIG_BRIDGE_EBT_STP=m ++CONFIG_BRIDGE_EBT_VLAN=m ++CONFIG_BRIDGE_EBT_ARPREPLY=m ++CONFIG_BRIDGE_EBT_DNAT=m ++CONFIG_BRIDGE_EBT_MARK_T=m ++CONFIG_BRIDGE_EBT_REDIRECT=m ++CONFIG_BRIDGE_EBT_SNAT=m ++CONFIG_BRIDGE_EBT_LOG=m ++CONFIG_BRIDGE_EBT_NFLOG=m ++CONFIG_SCTP_COOKIE_HMAC_SHA1=y ++CONFIG_ATM=m ++CONFIG_L2TP=m ++CONFIG_L2TP_V3=y ++CONFIG_L2TP_IP=m ++CONFIG_L2TP_ETH=m ++CONFIG_BRIDGE=m ++CONFIG_VLAN_8021Q=m ++CONFIG_VLAN_8021Q_GVRP=y ++CONFIG_ATALK=m ++CONFIG_6LOWPAN=m ++CONFIG_NET_SCHED=y ++CONFIG_NET_SCH_CBQ=m ++CONFIG_NET_SCH_HTB=m ++CONFIG_NET_SCH_HFSC=m ++CONFIG_NET_SCH_PRIO=m ++CONFIG_NET_SCH_MULTIQ=m ++CONFIG_NET_SCH_RED=m ++CONFIG_NET_SCH_SFB=m ++CONFIG_NET_SCH_SFQ=m ++CONFIG_NET_SCH_TEQL=m ++CONFIG_NET_SCH_TBF=m ++CONFIG_NET_SCH_GRED=m ++CONFIG_NET_SCH_DSMARK=m ++CONFIG_NET_SCH_NETEM=m ++CONFIG_NET_SCH_DRR=m ++CONFIG_NET_SCH_MQPRIO=m ++CONFIG_NET_SCH_CHOKE=m ++CONFIG_NET_SCH_QFQ=m ++CONFIG_NET_SCH_CODEL=m ++CONFIG_NET_SCH_FQ_CODEL=m ++CONFIG_NET_SCH_INGRESS=m ++CONFIG_NET_SCH_PLUG=m ++CONFIG_NET_CLS_BASIC=m ++CONFIG_NET_CLS_TCINDEX=m ++CONFIG_NET_CLS_ROUTE4=m ++CONFIG_NET_CLS_FW=m ++CONFIG_NET_CLS_U32=m ++CONFIG_CLS_U32_MARK=y ++CONFIG_NET_CLS_RSVP=m ++CONFIG_NET_CLS_RSVP6=m ++CONFIG_NET_CLS_FLOW=m ++CONFIG_NET_CLS_CGROUP=m ++CONFIG_NET_EMATCH=y ++CONFIG_NET_EMATCH_CMP=m ++CONFIG_NET_EMATCH_NBYTE=m ++CONFIG_NET_EMATCH_U32=m ++CONFIG_NET_EMATCH_META=m ++CONFIG_NET_EMATCH_TEXT=m ++CONFIG_NET_EMATCH_IPSET=m ++CONFIG_NET_CLS_ACT=y ++CONFIG_NET_ACT_POLICE=m ++CONFIG_NET_ACT_GACT=m ++CONFIG_GACT_PROB=y ++CONFIG_NET_ACT_MIRRED=m ++CONFIG_NET_ACT_IPT=m ++CONFIG_NET_ACT_NAT=m ++CONFIG_NET_ACT_PEDIT=m ++CONFIG_NET_ACT_SIMP=m ++CONFIG_NET_ACT_SKBEDIT=m ++CONFIG_NET_ACT_CSUM=m ++CONFIG_BATMAN_ADV=m ++CONFIG_OPENVSWITCH=m ++CONFIG_NET_PKTGEN=m ++CONFIG_HAMRADIO=y ++CONFIG_AX25=m ++CONFIG_NETROM=m ++CONFIG_ROSE=m ++CONFIG_MKISS=m ++CONFIG_6PACK=m ++CONFIG_BPQETHER=m ++CONFIG_BAYCOM_SER_FDX=m ++CONFIG_BAYCOM_SER_HDX=m ++CONFIG_YAM=m ++CONFIG_CAN=m ++CONFIG_CAN_VCAN=m ++CONFIG_CAN_MCP251X=m ++CONFIG_IRDA=m ++CONFIG_IRLAN=m ++CONFIG_IRNET=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_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_6LOWPAN=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_BT_WILINK=m ++CONFIG_MAC80211=m ++CONFIG_MAC80211_MESH=y ++CONFIG_WIMAX=m ++CONFIG_RFKILL=m ++CONFIG_RFKILL_INPUT=y ++CONFIG_NET_9P=m ++CONFIG_NFC=m ++CONFIG_NFC_PN533=m + CONFIG_DEVTMPFS=y + CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=5 ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_CRYPTOLOOP=m ++CONFIG_BLK_DEV_DRBD=m ++CONFIG_BLK_DEV_NBD=m ++CONFIG_BLK_DEV_RAM=y ++CONFIG_CDROM_PKTCDVD=m ++CONFIG_ATA_OVER_ETH=m ++CONFIG_EEPROM_AT24=m CONFIG_SCSI=y ++# CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_MULTI_LUN=y ++CONFIG_CHR_DEV_ST=m ++CONFIG_CHR_DEV_OSST=m ++CONFIG_BLK_DEV_SR=m ++CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y ++CONFIG_SCSI_ISCSI_ATTRS=y ++CONFIG_ISCSI_TCP=m ++CONFIG_ISCSI_BOOT_SYSFS=m ++CONFIG_MD=y ++CONFIG_MD_LINEAR=m ++CONFIG_MD_RAID0=m ++CONFIG_BLK_DEV_DM=m ++CONFIG_DM_CRYPT=m ++CONFIG_DM_SNAPSHOT=m ++CONFIG_DM_MIRROR=m ++CONFIG_DM_LOG_USERSPACE=m ++CONFIG_DM_RAID=m ++CONFIG_DM_ZERO=m ++CONFIG_DM_DELAY=m CONFIG_NETDEVICES=y -@@ -83,11 +77,15 @@ CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_BONDING=m ++CONFIG_DUMMY=m ++CONFIG_IFB=m ++CONFIG_MACVLAN=m ++CONFIG_NETCONSOLE=m ++CONFIG_TUN=m ++CONFIG_VETH=m ++CONFIG_ENC28J60=m ++CONFIG_MDIO_BITBANG=m ++CONFIG_PPP=m ++CONFIG_PPP_BSDCOMP=m ++CONFIG_PPP_DEFLATE=m ++CONFIG_PPP_FILTER=y ++CONFIG_PPP_MPPE=m ++CONFIG_PPP_MULTILINK=y ++CONFIG_PPPOATM=m ++CONFIG_PPPOE=m ++CONFIG_PPPOL2TP=m ++CONFIG_PPP_ASYNC=m ++CONFIG_PPP_SYNC_TTY=m ++CONFIG_SLIP=m ++CONFIG_SLIP_COMPRESSED=y ++CONFIG_SLIP_SMART=y ++CONFIG_USB_CATC=m ++CONFIG_USB_KAWETH=m ++CONFIG_USB_PEGASUS=m ++CONFIG_USB_RTL8150=m ++CONFIG_USB_RTL8152=m + CONFIG_USB_USBNET=y ++CONFIG_USB_NET_AX8817X=m ++CONFIG_USB_NET_AX88179_178A=m ++CONFIG_USB_NET_CDCETHER=m ++CONFIG_USB_NET_CDC_EEM=m ++CONFIG_USB_NET_CDC_NCM=m ++CONFIG_USB_NET_HUAWEI_CDC_NCM=m ++CONFIG_USB_NET_CDC_MBIM=m ++CONFIG_USB_NET_DM9601=m ++CONFIG_USB_NET_SR9700=m ++CONFIG_USB_NET_SR9800=m ++CONFIG_USB_NET_SMSC75XX=m + CONFIG_USB_NET_SMSC95XX=y +-CONFIG_ZD1211RW=y +-CONFIG_INPUT_EVDEV=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_EPSON2888=y ++CONFIG_USB_KC2190=y ++CONFIG_USB_NET_ZAURUS=m ++CONFIG_USB_NET_CX82310_ETH=m ++CONFIG_USB_NET_KALMIA=m ++CONFIG_USB_NET_QMI_WWAN=m ++CONFIG_USB_HSO=m ++CONFIG_USB_NET_INT51X1=m ++CONFIG_USB_IPHETH=m ++CONFIG_USB_SIERRA_NET=m ++CONFIG_USB_VL600=m ++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_CARDS=m ++CONFIG_ATH9K=m ++CONFIG_ATH9K_HTC=m ++CONFIG_CARL9170=m ++CONFIG_ATH6KL=m ++CONFIG_ATH6KL_USB=m ++CONFIG_AR5523=m ++CONFIG_B43=m ++# CONFIG_B43_PHY_N is not set ++CONFIG_B43LEGACY=m ++CONFIG_BRCMFMAC=m ++CONFIG_BRCMFMAC_USB=y ++CONFIG_HOSTAP=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_RT3573=y ++CONFIG_RT2800USB_RT53XX=y ++CONFIG_RT2800USB_RT55XX=y ++CONFIG_RT2800USB_UNKNOWN=y ++CONFIG_RTL8192CU=m ++CONFIG_ZD1211RW=m ++CONFIG_MWIFIEX=m ++CONFIG_MWIFIEX_SDIO=m ++CONFIG_WIMAX_I2400M_USB=m ++CONFIG_INPUT_POLLDEV=m ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++CONFIG_INPUT_JOYDEV=m ++CONFIG_INPUT_EVDEV=m ++# CONFIG_KEYBOARD_ATKBD is not set ++CONFIG_KEYBOARD_GPIO=m ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_JOYSTICK=y ++CONFIG_JOYSTICK_IFORCE=m ++CONFIG_JOYSTICK_IFORCE_USB=y ++CONFIG_JOYSTICK_XPAD=m ++CONFIG_JOYSTICK_XPAD_FF=y ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_ADS7846=m ++CONFIG_TOUCHSCREEN_EGALAX=m ++CONFIG_TOUCHSCREEN_USB_COMPOSITE=m ++CONFIG_TOUCHSCREEN_STMPE=m ++CONFIG_INPUT_MISC=y ++CONFIG_INPUT_AD714X=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_DEVPTS_MULTIPLE_INSTANCES=y + # CONFIG_LEGACY_PTYS is not set + # CONFIG_DEVKMEM is not set + CONFIG_SERIAL_AMBA_PL011=y + CONFIG_SERIAL_AMBA_PL011_CONSOLE=y + CONFIG_TTY_PRINTK=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_BCM2835=m ++CONFIG_RAW_DRIVER=y ++CONFIG_BRCM_CHAR_DRIVERS=y ++CONFIG_BCM_VC_CMA=y ++CONFIG_BCM_VC_SM=y + CONFIG_I2C=y +-CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_CHARDEV=m + CONFIG_I2C_BCM2835=y + CONFIG_SPI=y +-CONFIG_SPI_BCM2835=y ++CONFIG_SPI_BCM2835=m ++CONFIG_SPI_SPIDEV=y ++CONFIG_PPS=m ++CONFIG_PPS_CLIENT_LDISC=m ++CONFIG_PPS_CLIENT_GPIO=m + CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_ARIZONA=m ++CONFIG_GPIO_STMPE=y ++CONFIG_W1=m ++CONFIG_W1_MASTER_DS2490=m ++CONFIG_W1_MASTER_DS2482=m ++CONFIG_W1_MASTER_DS1WM=m ++CONFIG_W1_MASTER_GPIO=m ++CONFIG_W1_SLAVE_THERM=m ++CONFIG_W1_SLAVE_SMEM=m ++CONFIG_W1_SLAVE_DS2408=m ++CONFIG_W1_SLAVE_DS2413=m ++CONFIG_W1_SLAVE_DS2406=m ++CONFIG_W1_SLAVE_DS2423=m ++CONFIG_W1_SLAVE_DS2431=m ++CONFIG_W1_SLAVE_DS2433=m ++CONFIG_W1_SLAVE_DS2760=m ++CONFIG_W1_SLAVE_DS2780=m ++CONFIG_W1_SLAVE_DS2781=m ++CONFIG_W1_SLAVE_DS28E04=m ++CONFIG_W1_SLAVE_BQ27000=m ++CONFIG_BATTERY_DS2760=m + # CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_THERMAL_BCM2835=y ++CONFIG_WATCHDOG=y ++CONFIG_BCM2835_WDT=y ++CONFIG_UCB1400_CORE=m ++CONFIG_MFD_STMPE=y ++CONFIG_STMPE_SPI=y ++CONFIG_MFD_ARIZONA_I2C=m ++CONFIG_MFD_ARIZONA_SPI=m ++CONFIG_MFD_WM5102=y ++CONFIG_MEDIA_SUPPORT=m ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_ANALOG_TV_SUPPORT=y ++CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y ++CONFIG_MEDIA_RADIO_SUPPORT=y ++CONFIG_MEDIA_RC_SUPPORT=y ++CONFIG_MEDIA_CONTROLLER=y ++CONFIG_LIRC=m ++CONFIG_RC_DEVICES=y ++CONFIG_RC_ATI_REMOTE=m ++CONFIG_IR_IMON=m ++CONFIG_IR_MCEUSB=m ++CONFIG_IR_REDRAT3=m ++CONFIG_IR_STREAMZAP=m ++CONFIG_IR_IGUANA=m ++CONFIG_IR_TTUSBIR=m ++CONFIG_RC_LOOPBACK=m ++CONFIG_IR_GPIO_CIR=m ++CONFIG_MEDIA_USB_SUPPORT=y ++CONFIG_USB_VIDEO_CLASS=m ++CONFIG_USB_M5602=m ++CONFIG_USB_STV06XX=m ++CONFIG_USB_GL860=m ++CONFIG_USB_GSPCA_BENQ=m ++CONFIG_USB_GSPCA_CONEX=m ++CONFIG_USB_GSPCA_CPIA1=m ++CONFIG_USB_GSPCA_DTCS033=m ++CONFIG_USB_GSPCA_ETOMS=m ++CONFIG_USB_GSPCA_FINEPIX=m ++CONFIG_USB_GSPCA_JEILINJ=m ++CONFIG_USB_GSPCA_JL2005BCD=m ++CONFIG_USB_GSPCA_KINECT=m ++CONFIG_USB_GSPCA_KONICA=m ++CONFIG_USB_GSPCA_MARS=m ++CONFIG_USB_GSPCA_MR97310A=m ++CONFIG_USB_GSPCA_NW80X=m ++CONFIG_USB_GSPCA_OV519=m ++CONFIG_USB_GSPCA_OV534=m ++CONFIG_USB_GSPCA_OV534_9=m ++CONFIG_USB_GSPCA_PAC207=m ++CONFIG_USB_GSPCA_PAC7302=m ++CONFIG_USB_GSPCA_PAC7311=m ++CONFIG_USB_GSPCA_SE401=m ++CONFIG_USB_GSPCA_SN9C2028=m ++CONFIG_USB_GSPCA_SN9C20X=m ++CONFIG_USB_GSPCA_SONIXB=m ++CONFIG_USB_GSPCA_SONIXJ=m ++CONFIG_USB_GSPCA_SPCA500=m ++CONFIG_USB_GSPCA_SPCA501=m ++CONFIG_USB_GSPCA_SPCA505=m ++CONFIG_USB_GSPCA_SPCA506=m ++CONFIG_USB_GSPCA_SPCA508=m ++CONFIG_USB_GSPCA_SPCA561=m ++CONFIG_USB_GSPCA_SPCA1528=m ++CONFIG_USB_GSPCA_SQ905=m ++CONFIG_USB_GSPCA_SQ905C=m ++CONFIG_USB_GSPCA_SQ930X=m ++CONFIG_USB_GSPCA_STK014=m ++CONFIG_USB_GSPCA_STK1135=m ++CONFIG_USB_GSPCA_STV0680=m ++CONFIG_USB_GSPCA_SUNPLUS=m ++CONFIG_USB_GSPCA_T613=m ++CONFIG_USB_GSPCA_TOPRO=m ++CONFIG_USB_GSPCA_TV8532=m ++CONFIG_USB_GSPCA_VC032X=m ++CONFIG_USB_GSPCA_VICAM=m ++CONFIG_USB_GSPCA_XIRLINK_CIT=m ++CONFIG_USB_GSPCA_ZC3XX=m ++CONFIG_USB_PWC=m ++CONFIG_VIDEO_CPIA2=m ++CONFIG_USB_ZR364XX=m ++CONFIG_USB_STKWEBCAM=m ++CONFIG_USB_S2255=m ++CONFIG_VIDEO_USBTV=m ++CONFIG_VIDEO_PVRUSB2=m ++CONFIG_VIDEO_HDPVR=m ++CONFIG_VIDEO_USBVISION=m ++CONFIG_VIDEO_STK1160_COMMON=m ++CONFIG_VIDEO_STK1160_AC97=y ++CONFIG_VIDEO_GO7007=m ++CONFIG_VIDEO_GO7007_USB=m ++CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m ++CONFIG_VIDEO_AU0828=m ++CONFIG_VIDEO_AU0828_RC=y ++CONFIG_VIDEO_CX231XX=m ++CONFIG_VIDEO_CX231XX_ALSA=m ++CONFIG_VIDEO_CX231XX_DVB=m ++CONFIG_VIDEO_TM6000=m ++CONFIG_VIDEO_TM6000_ALSA=m ++CONFIG_VIDEO_TM6000_DVB=m ++CONFIG_DVB_USB=m ++CONFIG_DVB_USB_A800=m ++CONFIG_DVB_USB_DIBUSB_MB=m ++CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y ++CONFIG_DVB_USB_DIBUSB_MC=m ++CONFIG_DVB_USB_DIB0700=m ++CONFIG_DVB_USB_UMT_010=m ++CONFIG_DVB_USB_CXUSB=m ++CONFIG_DVB_USB_M920X=m ++CONFIG_DVB_USB_DIGITV=m ++CONFIG_DVB_USB_VP7045=m ++CONFIG_DVB_USB_VP702X=m ++CONFIG_DVB_USB_GP8PSK=m ++CONFIG_DVB_USB_NOVA_T_USB2=m ++CONFIG_DVB_USB_TTUSB2=m ++CONFIG_DVB_USB_DTT200U=m ++CONFIG_DVB_USB_OPERA1=m ++CONFIG_DVB_USB_AF9005=m ++CONFIG_DVB_USB_AF9005_REMOTE=m ++CONFIG_DVB_USB_PCTV452E=m ++CONFIG_DVB_USB_DW2102=m ++CONFIG_DVB_USB_CINERGY_T2=m ++CONFIG_DVB_USB_DTV5100=m ++CONFIG_DVB_USB_FRIIO=m ++CONFIG_DVB_USB_AZ6027=m ++CONFIG_DVB_USB_TECHNISAT_USB2=m ++CONFIG_DVB_USB_V2=m ++CONFIG_DVB_USB_AF9015=m ++CONFIG_DVB_USB_AF9035=m ++CONFIG_DVB_USB_ANYSEE=m ++CONFIG_DVB_USB_AU6610=m ++CONFIG_DVB_USB_AZ6007=m ++CONFIG_DVB_USB_CE6230=m ++CONFIG_DVB_USB_EC168=m ++CONFIG_DVB_USB_GL861=m ++CONFIG_DVB_USB_LME2510=m ++CONFIG_DVB_USB_MXL111SF=m ++CONFIG_DVB_USB_RTL28XXU=m ++CONFIG_DVB_USB_DVBSKY=m ++CONFIG_SMS_USB_DRV=m ++CONFIG_DVB_B2C2_FLEXCOP_USB=m ++CONFIG_DVB_AS102=m ++CONFIG_VIDEO_EM28XX=m ++CONFIG_VIDEO_EM28XX_V4L2=m ++CONFIG_VIDEO_EM28XX_ALSA=m ++CONFIG_VIDEO_EM28XX_DVB=m ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_BCM2835=y ++CONFIG_VIDEO_BCM2835_MMAL=m ++CONFIG_RADIO_SI470X=y ++CONFIG_USB_SI470X=m ++CONFIG_I2C_SI470X=m ++CONFIG_RADIO_SI4713=m ++CONFIG_I2C_SI4713=m ++CONFIG_USB_MR800=m ++CONFIG_USB_DSBR=m ++CONFIG_RADIO_SHARK=m ++CONFIG_RADIO_SHARK2=m ++CONFIG_USB_KEENE=m ++CONFIG_USB_MA901=m ++CONFIG_RADIO_TEA5764=m ++CONFIG_RADIO_SAA7706H=m ++CONFIG_RADIO_TEF6862=m ++CONFIG_RADIO_WL1273=m ++CONFIG_RADIO_WL128X=m ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_VIDEO_UDA1342=m ++CONFIG_VIDEO_SONY_BTF_MPX=m ++CONFIG_VIDEO_TVP5150=m ++CONFIG_VIDEO_TW2804=m ++CONFIG_VIDEO_TW9903=m ++CONFIG_VIDEO_TW9906=m ++CONFIG_VIDEO_OV7640=m ++CONFIG_VIDEO_MT9V011=m + CONFIG_FB=y +-CONFIG_FB_SIMPLE=y ++CONFIG_FB_BCM2708=y ++CONFIG_FB_SSD1307=m ++# CONFIG_BACKLIGHT_GENERIC is not set ++CONFIG_BACKLIGHT_GPIO=m + CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=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_CAIAQ_INPUT=y ++CONFIG_SND_USB_6FIRE=m ++CONFIG_SND_SOC=m ++CONFIG_SND_BCM2835_SOC_I2S=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m ++CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m ++CONFIG_SND_BCM2708_SOC_RPI_DAC=m ++CONFIG_SND_BCM2708_SOC_RPI_PROTO=m ++CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m ++CONFIG_SND_SIMPLE_CARD=m ++CONFIG_SOUND_PRIME=m ++CONFIG_HIDRAW=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_ELO=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_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_THINGM=m ++CONFIG_HID_THRUSTMASTER=m ++CONFIG_HID_WACOM=m ++CONFIG_HID_WIIMOTE=m ++CONFIG_HID_XINMO=m ++CONFIG_HID_ZEROPLUS=m ++CONFIG_HID_ZYDACRON=m ++CONFIG_HID_PID=y ++CONFIG_USB_HIDDEV=y CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_MON=m ++CONFIG_USB_PRINTER=m 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_MDC800=m ++CONFIG_USB_MICROTEK=m ++CONFIG_USBIP_CORE=m ++CONFIG_USBIP_VHCI_HCD=m ++CONFIG_USBIP_HOST=m +CONFIG_USB_DWC2=y ++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_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_F81232=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_METRO=m ++CONFIG_USB_SERIAL_MOS7720=m ++CONFIG_USB_SERIAL_MOS7840=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_SAFE=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_XSENS_MT=m ++CONFIG_USB_SERIAL_WISHBONE=m ++CONFIG_USB_SERIAL_SSU100=m ++CONFIG_USB_SERIAL_QT2=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_USB_ATM=m ++CONFIG_USB_SPEEDTOUCH=m ++CONFIG_USB_CXACRU=m ++CONFIG_USB_UEAGLEATM=m ++CONFIG_USB_XUSBATM=m CONFIG_MMC=y ++CONFIG_MMC_BLOCK_MINORS=32 ++CONFIG_MMC_BCM2835=y ++CONFIG_MMC_BCM2835_DMA=y ++CONFIG_MMC_BCM2835_SDHOST=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_BCM2835=y -+CONFIG_NEW_LEDS=y ++CONFIG_MMC_SPI=m +CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y -+CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y -@@ -97,8 +95,6 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - CONFIG_LEDS_TRIGGER_TRANSIENT=y - CONFIG_LEDS_TRIGGER_CAMERA=y ++CONFIG_LEDS_TRIGGER_BACKLIGHT=y + CONFIG_LEDS_TRIGGER_CPU=y + CONFIG_LEDS_TRIGGER_GPIO=y + CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +-CONFIG_LEDS_TRIGGER_TRANSIENT=y +-CONFIG_LEDS_TRIGGER_CAMERA=y ++CONFIG_LEDS_TRIGGER_TRANSIENT=m ++CONFIG_LEDS_TRIGGER_CAMERA=m ++CONFIG_LEDS_TRIGGER_INPUT=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_DS1307=m ++CONFIG_RTC_DRV_DS1374=m ++CONFIG_RTC_DRV_DS1672=m ++CONFIG_RTC_DRV_DS3232=m ++CONFIG_RTC_DRV_MAX6900=m ++CONFIG_RTC_DRV_RS5C372=m ++CONFIG_RTC_DRV_ISL1208=m ++CONFIG_RTC_DRV_ISL12022=m ++CONFIG_RTC_DRV_ISL12057=m ++CONFIG_RTC_DRV_X1205=m ++CONFIG_RTC_DRV_PCF2127=m ++CONFIG_RTC_DRV_PCF8523=m ++CONFIG_RTC_DRV_PCF8563=m ++CONFIG_RTC_DRV_PCF8583=m ++CONFIG_RTC_DRV_M41T80=m ++CONFIG_RTC_DRV_BQ32K=m ++CONFIG_RTC_DRV_S35390A=m ++CONFIG_RTC_DRV_FM3130=m ++CONFIG_RTC_DRV_RX8581=m ++CONFIG_RTC_DRV_RX8025=m ++CONFIG_RTC_DRV_EM3027=m ++CONFIG_RTC_DRV_RV3029C2=m ++CONFIG_RTC_DRV_M41T93=m ++CONFIG_RTC_DRV_M41T94=m ++CONFIG_RTC_DRV_DS1305=m ++CONFIG_RTC_DRV_DS1390=m ++CONFIG_RTC_DRV_MAX6902=m ++CONFIG_RTC_DRV_R9701=m ++CONFIG_RTC_DRV_RS5C348=m ++CONFIG_RTC_DRV_DS3234=m ++CONFIG_RTC_DRV_PCF2123=m ++CONFIG_RTC_DRV_RX4581=m ++CONFIG_DMADEVICES=y ++CONFIG_DMA_BCM2708=y ++CONFIG_UIO=m ++CONFIG_UIO_PDRV_GENIRQ=m CONFIG_STAGING=y -CONFIG_USB_DWC2=y -CONFIG_USB_DWC2_HOST=y ++CONFIG_PRISM2_USB=m ++CONFIG_R8712U=m ++CONFIG_R8188EU=m ++CONFIG_R8723AU=m ++CONFIG_VT6656=m ++CONFIG_SPEAKUP=m ++CONFIG_SPEAKUP_SYNTH_SOFT=m ++CONFIG_STAGING_MEDIA=y ++CONFIG_LIRC_STAGING=y ++CONFIG_LIRC_IMON=m ++CONFIG_LIRC_SASEM=m ++CONFIG_LIRC_SERIAL=m ++CONFIG_FB_TFT=m ++CONFIG_FB_TFT_AGM1264K_FL=m ++CONFIG_FB_TFT_BD663474=m ++CONFIG_FB_TFT_HX8340BN=m ++CONFIG_FB_TFT_HX8347D=m ++CONFIG_FB_TFT_HX8353D=m ++CONFIG_FB_TFT_ILI9320=m ++CONFIG_FB_TFT_ILI9325=m ++CONFIG_FB_TFT_ILI9340=m ++CONFIG_FB_TFT_ILI9341=m ++CONFIG_FB_TFT_ILI9481=m ++CONFIG_FB_TFT_ILI9486=m ++CONFIG_FB_TFT_PCD8544=m ++CONFIG_FB_TFT_RA8875=m ++CONFIG_FB_TFT_S6D02A1=m ++CONFIG_FB_TFT_S6D1121=m ++CONFIG_FB_TFT_SSD1289=m ++CONFIG_FB_TFT_SSD1306=m ++CONFIG_FB_TFT_SSD1331=m ++CONFIG_FB_TFT_SSD1351=m ++CONFIG_FB_TFT_ST7735R=m ++CONFIG_FB_TFT_TINYLCD=m ++CONFIG_FB_TFT_TLS8204=m ++CONFIG_FB_TFT_UC1701=m ++CONFIG_FB_TFT_UPD161704=m ++CONFIG_FB_TFT_WATTEROTT=m ++CONFIG_FB_FLEX=m ++CONFIG_FB_TFT_FBTFT_DEVICE=m ++CONFIG_MAILBOX=y ++CONFIG_BCM2708_MBOX=y # CONFIG_IOMMU_SUPPORT is not set ++CONFIG_EXTCON=m ++CONFIG_EXTCON_ARIZONA=m CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y - -From 40cd8a80edbedd6bef0da2bcd55e777f80ef30ae Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:24:46 +0200 -Subject: [PATCH 127/216] mmc: bcm2835-mmc: Make available on ARCH_BCM2835 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make the bcm2835-mmc driver available for use on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - drivers/mmc/host/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 1666c6c..41d6e47 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -6,7 +6,7 @@ comment "MMC/SD/SDIO Host Controller Drivers" - - config MMC_BCM2835 - tristate "MMC support on BCM2835" -- depends on (MACH_BCM2708 || MACH_BCM2709) -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 - help - This selects the MMC Interface on BCM2835. - - -From 6c0c225509561cc261c594db00d429f2c032ebfa Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:28:22 +0200 -Subject: [PATCH 128/216] bcm2835: bcm2835_defconfig enable MMC_BCM2835 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enable the downstream bcm2835-mmc driver and DMA support. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 245aede..cf2e7a6 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -79,6 +79,8 @@ CONFIG_USB=y - CONFIG_USB_STORAGE=y - CONFIG_USB_DWC2=y - CONFIG_MMC=y -+CONFIG_MMC_BCM2835=y -+CONFIG_MMC_BCM2835_DMA=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2835=y -@@ -94,6 +96,8 @@ CONFIG_LEDS_TRIGGER_GPIO=y - CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - CONFIG_LEDS_TRIGGER_TRANSIENT=y - CONFIG_LEDS_TRIGGER_CAMERA=y -+CONFIG_DMADEVICES=y -+CONFIG_DMA_BCM2708=y - CONFIG_STAGING=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXT2_FS=y - -From 8bff84b0504771b895a12dcc5975b26345a3f9a1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 29 Apr 2015 17:29:04 +0200 -Subject: [PATCH 129/216] bcm2835: Change to use bcm2835-mmc in Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use downstream bcm2835-mmc driver to get increased throughput -and DMA support. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- - arch/arm/boot/dts/bcm2835.dtsi | 9 ++++++--- - 2 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index c706448..9f4ed2f 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -45,7 +45,7 @@ - clock-frequency = <100000>; - }; - --&sdhci { -+&mmc { - status = "okay"; - bus-width = <4>; - }; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 3342cb1..f2dec21 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -122,11 +122,14 @@ - status = "disabled"; - }; - -- sdhci: sdhci@7e300000 { -- compatible = "brcm,bcm2835-sdhci"; -+ mmc: mmc@7e300000 { -+ compatible = "brcm,bcm2835-mmc"; - reg = <0x7e300000 0x100>; - interrupts = <2 30>; - clocks = <&clk_mmc>; -+ dmas = <&dma 11>, -+ <&dma 11>; -+ dma-names = "tx", "rx"; - status = "disabled"; - }; - -@@ -161,7 +164,7 @@ - reg = <0>; - #clock-cells = <0>; - clock-output-names = "mmc"; -- clock-frequency = <100000000>; -+ clock-frequency = <250000000>; - }; - - clk_i2c: clock@1 { - -From 89df9a42f6e60b3c54c4b49b1fafff7ef201ac72 Mon Sep 17 00:00:00 2001 -From: Christopher Freeman -Date: Wed, 4 Mar 2015 01:16:58 -0800 -Subject: [PATCH 130/216] dmaengine: increment privatecnt when using - dma_get_any_slave_channel - -Channels allocated via dma_get_any_slave_channel were not increasing -the counter tracking private allocations. When these channels were -released, privatecnt may erroneously fall to zero. The DMA device -would then lose its DMA_PRIVATE cap and fail to allocate future private -channels (via private_candidate) as any allocations still outstanding -would incorrectly be seen as public allocations. - -Signed-off-by: Christopher Freeman -Signed-off-by: Vinod Koul ---- - drivers/dma/dmaengine.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c -index ac336a9..bb2b914 100644 ---- a/drivers/dma/dmaengine.c -+++ b/drivers/dma/dmaengine.c -@@ -589,11 +589,15 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) - - chan = private_candidate(&mask, device, NULL, NULL); - if (chan) { -+ dma_cap_set(DMA_PRIVATE, device->cap_mask); -+ device->privatecnt++; - err = dma_chan_get(chan); - if (err) { - pr_debug("%s: failed to get %s: (%d)\n", - __func__, dma_chan_name(chan), err); - chan = NULL; -+ if (--device->privatecnt == 0) -+ dma_cap_clear(DMA_PRIVATE, device->cap_mask); - } - } - - -From 0ecdaeb739edb714add6d8ae452d12d2ce821573 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 1 May 2015 17:46:56 +0100 -Subject: [PATCH 131/216] bcm2835-mmc: Add locks when accessing sdhost - registers - ---- - drivers/mmc/host/bcm2835-mmc.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index eef0d351..1c34f476 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -133,17 +133,20 @@ struct bcm2835_host { - - static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) - { -+ lockdep_assert_held_once(&host->lock); - writel(val, host->ioaddr + reg); - udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); - } - - static inline void mmc_raw_writel(struct bcm2835_host *host, u32 val, int reg) - { -+ lockdep_assert_held_once(&host->lock); - writel(val, host->ioaddr + reg); - } - - static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) - { -+ lockdep_assert_held_once(&host->lock); - return readl(host->ioaddr + reg); - } - -@@ -255,7 +258,9 @@ static void bcm2835_mmc_dumpregs(struct bcm2835_host *host) - static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) - { - unsigned long timeout; -+ unsigned long flags; - -+ spin_lock_irqsave(&host->lock, flags); - bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET); - - if (mask & SDHCI_RESET_ALL) -@@ -273,19 +278,23 @@ static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask) - return; - } - timeout--; -+ spin_unlock_irqrestore(&host->lock, flags); - mdelay(1); -+ spin_lock_irqsave(&host->lock, flags); - } - - if (100-timeout > 10 && 100-timeout > host->max_delay) { - host->max_delay = 100-timeout; - pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay); - } -+ spin_unlock_irqrestore(&host->lock, flags); - } - - static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); - - static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) - { -+ unsigned long flags; - if (soft) - bcm2835_mmc_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); - else -@@ -297,8 +306,10 @@ static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) - SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | - SDHCI_INT_RESPONSE; - -+ spin_lock_irqsave(&host->lock, flags); - bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); - bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ spin_unlock_irqrestore(&host->lock, flags); - - if (soft) { - /* force clock reconfiguration */ -@@ -497,11 +508,14 @@ static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host) - dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n"); - } - if (desc) { -+ unsigned long flags; -+ spin_lock_irqsave(&host->lock, flags); - bcm2835_mmc_unsignal_irqs(host, SDHCI_INT_DATA_AVAIL | - SDHCI_INT_SPACE_AVAIL); - host->tx_desc = desc; - desc->callback = bcm2835_mmc_dma_complete; - desc->callback_param = host; -+ spin_unlock_irqrestore(&host->lock, flags); - dmaengine_submit(desc); - dma_async_issue_pending(dma_chan); - } -@@ -1243,8 +1257,10 @@ static void bcm2835_mmc_tasklet_finish(unsigned long param) - (mrq->data && (mrq->data->error || - (mrq->data->stop && mrq->data->stop->error))))) { - -+ spin_unlock_irqrestore(&host->lock, flags); - bcm2835_mmc_reset(host, SDHCI_RESET_CMD); - bcm2835_mmc_reset(host, SDHCI_RESET_DATA); -+ spin_lock_irqsave(&host->lock, flags); - } - - host->mrq = NULL; -@@ -1259,7 +1275,7 @@ static void bcm2835_mmc_tasklet_finish(unsigned long param) - - - --int bcm2835_mmc_add_host(struct bcm2835_host *host) -+static int bcm2835_mmc_add_host(struct bcm2835_host *host) - { - struct mmc_host *mmc = host->mmc; - struct device *dev = mmc->parent; -@@ -1287,8 +1303,6 @@ int bcm2835_mmc_add_host(struct bcm2835_host *host) - - host->flags = SDHCI_AUTO_CMD23; - -- spin_lock_init(&host->lock); -- - #ifdef FORCE_PIO - dev_info(dev, "Forcing PIO mode\n"); - host->have_dma = false; - -From d7580af2f81793fd3312608de95a9009123d8710 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 13 Apr 2015 23:34:50 +0100 -Subject: [PATCH 132/216] bcm2835-mmc: Add range of debug options for slowing - things down - -bcm2835-mmc: Add option to disable some delays - -bcm2835-mmc: Add option to disable MMC_QUIRK_BLK_NO_CMD23 - -bcm2835-mmc: Default to disabling MMC_QUIRK_BLK_NO_CMD23 ---- - drivers/mmc/core/quirks.c | 2 ++ - drivers/mmc/host/bcm2835-mmc.c | 44 ++++++++++++++++++++++++++++-------------- - 2 files changed, 32 insertions(+), 14 deletions(-) - -diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c -index f472082..bc3bbad 100644 ---- a/drivers/mmc/core/quirks.c -+++ b/drivers/mmc/core/quirks.c -@@ -71,6 +71,7 @@ static const struct mmc_fixup mmc_fixup_methods[] = { - - void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - { -+ extern unsigned mmc_debug; - const struct mmc_fixup *f; - u64 rev = cid_rev_card(card); - -@@ -98,6 +99,7 @@ void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table) - /* SDHCI on BCM2708 - bug causes a certain sequence of CMD23 operations to fail. - * Disable this flag for all cards (fall-back to CMD25/CMD18 multi-block transfers). - */ -+ if (mmc_debug & (1<<13)) - card->quirks |= MMC_QUIRK_BLK_NO_CMD23; - } - EXPORT_SYMBOL(mmc_fixup_device); -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 1c34f476..68314d5 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -71,6 +71,9 @@ pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x) - #define BCM2835_VCMMU_SHIFT (0x7E000000 - BCM2708_PERI_BASE) - - -+unsigned mmc_debug; -+unsigned mmc_debug2; -+ - struct bcm2835_host { - spinlock_t lock; - -@@ -131,17 +134,27 @@ struct bcm2835_host { - }; - - --static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg) -+static inline void bcm2835_mmc_writel(struct bcm2835_host *host, u32 val, int reg, int from) - { -+ unsigned delay; - lockdep_assert_held_once(&host->lock); - writel(val, host->ioaddr + reg); - udelay(BCM2835_SDHCI_WRITE_DELAY(max(host->clock, MIN_FREQ))); -+ -+ delay = ((mmc_debug >> 16) & 0xf) << ((mmc_debug >> 20) & 0xf); -+ if (delay && !((1<lock); - writel(val, host->ioaddr + reg); -+ -+ delay = ((mmc_debug >> 24) & 0xf) << ((mmc_debug >> 28) & 0xf); -+ if (delay) -+ udelay(delay); - } - - static inline u32 bcm2835_mmc_readl(struct bcm2835_host *host, int reg) -@@ -162,7 +175,7 @@ static inline void bcm2835_mmc_writew(struct bcm2835_host *host, u16 val, int re - if (reg == SDHCI_TRANSFER_MODE) - host->shadow = newval; - else -- bcm2835_mmc_writel(host, newval, reg & ~3); -+ bcm2835_mmc_writel(host, newval, reg & ~3, 0); - - } - -@@ -174,7 +187,7 @@ static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg - u32 mask = 0xff << byte_shift; - u32 newval = (oldval & ~mask) | (val << byte_shift); - -- bcm2835_mmc_writel(host, newval, reg & ~3); -+ bcm2835_mmc_writel(host, newval, reg & ~3, 1); - } - - -@@ -206,7 +219,7 @@ static void bcm2835_mmc_unsignal_irqs(struct bcm2835_host *host, u32 clear) - ier &= ~clear; - /* change which requests generate IRQs - makes no difference to - the content of SDHCI_INT_STATUS, or the need to acknowledge IRQs */ -- bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, ier, SDHCI_SIGNAL_ENABLE, 2); - } - - -@@ -307,8 +320,8 @@ static void bcm2835_mmc_init(struct bcm2835_host *host, int soft) - SDHCI_INT_RESPONSE; - - spin_lock_irqsave(&host->lock, flags); -- bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -- bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 3); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 3); - spin_unlock_irqrestore(&host->lock, flags); - - if (soft) { -@@ -534,8 +547,8 @@ static void bcm2835_mmc_set_transfer_irqs(struct bcm2835_host *host) - else - host->ier = (host->ier & ~dma_irqs) | pio_irqs; - -- bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -- bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 4); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 4); - } - - -@@ -617,7 +630,7 @@ static void bcm2835_mmc_set_transfer_mode(struct bcm2835_host *host, - mode |= SDHCI_TRNS_AUTO_CMD12; - else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { - mode |= SDHCI_TRNS_AUTO_CMD23; -- bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2); -+ bcm2835_mmc_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2, 5); - } - } - -@@ -680,7 +693,7 @@ void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd - - bcm2835_mmc_prepare_data(host, cmd); - -- bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT); -+ bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT, 6); - - bcm2835_mmc_set_transfer_mode(host, cmd); - -@@ -837,8 +850,8 @@ static void bcm2835_mmc_enable_sdio_irq_nolock(struct bcm2835_host *host, int en - else - host->ier &= ~SDHCI_INT_CARD_INT; - -- bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE); -- bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 7); -+ bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 7); - mmiowb(); - } - } -@@ -985,7 +998,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) - /* Clear selected interrupts. */ - mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | - SDHCI_INT_BUS_POWER); -- bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS); -+ bcm2835_mmc_writel(host, mask, SDHCI_INT_STATUS, 8); - - - if (intmask & SDHCI_INT_CMD_MASK) -@@ -1015,7 +1028,7 @@ static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id) - - if (intmask) { - unexpected |= intmask; -- bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS); -+ bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS, 9); - } - - if (result == IRQ_NONE) -@@ -1303,6 +1316,7 @@ static int bcm2835_mmc_add_host(struct bcm2835_host *host) - - host->flags = SDHCI_AUTO_CMD23; - -+ dev_info(dev, "mmc_debug:%x mmc_debug2:%x\n", mmc_debug, mmc_debug2); - #ifdef FORCE_PIO - dev_info(dev, "Forcing PIO mode\n"); - host->have_dma = false; -@@ -1514,6 +1528,8 @@ static struct platform_driver bcm2835_mmc_driver = { - }; - module_platform_driver(bcm2835_mmc_driver); - -+module_param(mmc_debug, uint, 0644); -+module_param(mmc_debug2, uint, 0644); - MODULE_ALIAS("platform:mmc-bcm2835"); - MODULE_DESCRIPTION("BCM2835 SDHCI driver"); - MODULE_LICENSE("GPL v2"); - -From e34578092803603a960a2a7bcccde5d0c8240b9a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 19:08:54 +0200 -Subject: [PATCH 133/216] BCM270x: Correct vcio device memory resource and add - irq resource -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The vcio driver hardcodes these resources, so this is the first -step in correcting this. Spell out the device name so we don't -have to include mach/vcio.h, since this header file will eventually -go away when the driver is later moved to drivers/mailbox. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 17 ++++++++++------- - arch/arm/mach-bcm2708/include/mach/platform.h | 1 + - arch/arm/mach-bcm2709/bcm2709.c | 17 ++++++++++------- - arch/arm/mach-bcm2709/include/mach/platform.h | 1 + - 4 files changed, 22 insertions(+), 14 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 486e090..51f8efa 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -55,7 +55,6 @@ - #include - - #include --#include - #include - - #include -@@ -414,17 +413,21 @@ static struct platform_device bcm2708_usb_device = { - }; - - static struct resource bcm2708_vcio_resources[] = { -- [0] = { /* mailbox/semaphore/doorbell access */ -- .start = MCORE_BASE, -- .end = MCORE_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- }, -+ { -+ .start = ARMCTRL_0_MAIL0_BASE, -+ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_MAILBOX, -+ .end = IRQ_ARM_MAILBOX, -+ .flags = IORESOURCE_IRQ, -+ }, - }; - - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = BCM_VCIO_DRIVER_NAME, -+ .name = "bcm2708_vcio", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h -index 2e7e1bb..bef3e5a 100644 ---- a/arch/arm/mach-bcm2708/include/mach/platform.h -+++ b/arch/arm/mach-bcm2708/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - - /* -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 44bfc50..8ed88b4 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -56,7 +56,6 @@ - #include - - #include --#include - #include - - #include -@@ -433,17 +432,21 @@ static struct platform_device bcm2708_usb_device = { - }; - - static struct resource bcm2708_vcio_resources[] = { -- [0] = { /* mailbox/semaphore/doorbell access */ -- .start = MCORE_BASE, -- .end = MCORE_BASE + SZ_4K - 1, -- .flags = IORESOURCE_MEM, -- }, -+ { -+ .start = ARMCTRL_0_MAIL0_BASE, -+ .end = ARMCTRL_0_MAIL0_BASE + SZ_64 - 1, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_MAILBOX, -+ .end = IRQ_ARM_MAILBOX, -+ .flags = IORESOURCE_IRQ, -+ }, - }; - - static u64 vcio_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); - - static struct platform_device bcm2708_vcio_device = { -- .name = BCM_VCIO_DRIVER_NAME, -+ .name = "bcm2708_vcio", - .id = -1, /* only one VideoCore I/O area */ - .resource = bcm2708_vcio_resources, - .num_resources = ARRAY_SIZE(bcm2708_vcio_resources), -diff --git a/arch/arm/mach-bcm2709/include/mach/platform.h b/arch/arm/mach-bcm2709/include/mach/platform.h -index 7157f38..5574bb5 100644 ---- a/arch/arm/mach-bcm2709/include/mach/platform.h -+++ b/arch/arm/mach-bcm2709/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - - /* - -From 4b03fd4291b9ed1cd100b359967f1b1fdc39984a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 2 May 2015 09:55:53 +0200 -Subject: [PATCH 134/216] video: fbdev: bcm2708_fb: Don't panic on error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to panic the kernel if the video driver fails. -Just print a message and return an error. - -Signed-off-by: Noralf Trønnes ---- - drivers/video/fbdev/bcm2708_fb.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 9179291..52e655a 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -325,8 +325,8 @@ static int bcm2708_fb_set_par(struct fb_info *info) - /* the console may currently be locked */ - console_trylock(); - console_unlock(); -- -- BUG(); /* what can we do here */ -+ pr_err("bcm2708_fb_set_par: Failed to set screen_base\n"); -+ return -EIO; - } - } - print_debug -@@ -677,7 +677,9 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - */ - - fb_set_var(&fb->fb, &fb->fb.var); -- bcm2708_fb_set_par(&fb->fb); -+ ret = bcm2708_fb_set_par(&fb->fb); -+ if (ret) -+ return ret; - - print_debug("BCM2708FB: registering framebuffer (%dx%d@%d) (%d)\n", fbwidth, - fbheight, fbdepth, fbswap); - -From 1965f1d8dcc748e1f9ba3ff28c8fb5191e081a4d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 20:49:04 +0200 -Subject: [PATCH 135/216] BCM2708: vcio: Fix checkpatch issues -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -checkpatch.pl errors and warnings: -Many whitespace related issues in some form or another. -Consider using instead of . -braces {} are not necessary for single statement blocks. -Use pr_* instead of printk. -Do not initialise statics to 0 or NULL. -Avoid CamelCase. -sizeof size should be sizeof(size). -break is not useful after a goto or return. -struct file_operations should normally be const -Possible unnecessary 'out of memory' message -Comparison to NULL could be written "!res" -quoted string split across lines. - -This has not been adressed: -WARNING: consider using a completion - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/vcio.h | 12 ++- - arch/arm/mach-bcm2708/vcio.c | 123 ++++++++++++++---------------- - 2 files changed, 62 insertions(+), 73 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -index 8e11d67e..58188b74 100644 ---- a/arch/arm/mach-bcm2708/include/mach/vcio.h -+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h -@@ -12,10 +12,6 @@ - * 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 _MACH_BCM2708_VCIO_H - #define _MACH_BCM2708_VCIO_H -@@ -34,12 +30,14 @@ - #define MBOX_CHAN_COUNT 9 - - enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 -+ VCMSG_PROCESS_REQUEST = 0x00000000 - }; -+ - enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 - }; -+ - /* Mailbox property tags */ - enum { - VCMSG_PROPERTY_END = 0x00000000, -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 700bff4..5e9e777 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -37,8 +37,7 @@ - #include - #include - --#include -- -+#include - - #define DRIVER_NAME BCM_VCIO_DRIVER_NAME - -@@ -61,7 +60,9 @@ - #define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) - - #define MBOX_MAGIC 0xd0d0c0de --static struct class *vcio_class = NULL; -+ -+static struct class *vcio_class; -+ - struct vc_mailbox { - struct device *dev; /* parent device */ - void __iomem *status; -@@ -102,9 +103,9 @@ static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - { - int rc; - -- if (mbox->magic != MBOX_MAGIC) -+ if (mbox->magic != MBOX_MAGIC) { - rc = -EINVAL; -- else { -+ } else { - /* wait for the mailbox FIFO to have some space in it */ - while (0 != (readl(mbox->status) & ARM_MS_FULL)) - cpu_relax(); -@@ -119,9 +120,9 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - { - int rc; - -- if (mbox->magic != MBOX_MAGIC) -+ if (mbox->magic != MBOX_MAGIC) { - rc = -EINVAL; -- else { -+ } else { - down(&mbox->sema[chan]); - *data28 = MBOX_DATA28(mbox->msg[chan]); - mbox->msg[chan] = 0; -@@ -133,17 +134,18 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - static irqreturn_t mbox_irq(int irq, void *dev_id) - { - /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -+ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; - int status = readl(mbox->status); - int ret = IRQ_NONE; - - while (!(status & ARM_MS_EMPTY)) { - uint32_t msg = readl(mbox->read); - int chan = MBOX_CHAN(msg); -+ - if (chan < MBOX_CHAN_COUNT) { - if (mbox->msg[chan]) { - /* Overflow */ -- printk(KERN_ERR DRIVER_NAME -+ pr_err(DRIVER_NAME - ": mbox chan %d overflow - drop %08x\n", - chan, msg); - } else { -@@ -151,7 +153,7 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - up(&mbox->sema[chan]); - } - } else { -- printk(KERN_ERR DRIVER_NAME -+ pr_err(DRIVER_NAME - ": invalid channel selector (msg %08x)\n", msg); - } - ret = IRQ_HANDLED; -@@ -174,9 +176,9 @@ static struct device *mbox_dev; /* we assume there's only one! */ - - static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) - { -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); - int rc; - -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); - device_lock(dev); - rc = mbox_write(mailbox, chan, data28); - device_unlock(dev); -@@ -186,9 +188,9 @@ static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) - - static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) - { -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); - int rc; - -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); - device_lock(dev); - rc = mbox_read(mailbox, chan, data28); - device_unlock(dev); -@@ -221,41 +223,36 @@ static void dev_mbox_register(const char *dev_name, struct device *dev) - - static int mbox_copy_from_user(void *dst, const void *src, int size) - { -- if ( (uint32_t)src < TASK_SIZE) -- { -+ if ((uint32_t)src < TASK_SIZE) - return copy_from_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } -+ -+ memcpy(dst, src, size); -+ -+ return 0; - } - - static int mbox_copy_to_user(void *dst, const void *src, int size) - { -- if ( (uint32_t)dst < TASK_SIZE) -- { -+ if ((uint32_t)dst < TASK_SIZE) - return copy_to_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } -+ -+ memcpy(dst, src, size); -+ -+ return 0; - } - - static DEFINE_MUTEX(mailbox_lock); - extern int bcm_mailbox_property(void *data, int size) - { - uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ - int s = 0; - -- mutex_lock(&mailbox_lock); -+ mutex_lock(&mailbox_lock); - /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -+ GFP_ATOMIC); - if (mem_kern) { - /* create the message */ - mbox_copy_from_user(mem_kern, data, size); -@@ -263,9 +260,8 @@ extern int bcm_mailbox_property(void *data, int size) - /* send the message */ - wmb(); - s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) { -+ if (s == 0) - s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- } - if (s == 0) { - /* copy the response */ - rmb(); -@@ -276,9 +272,9 @@ extern int bcm_mailbox_property(void *data, int size) - s = -ENOMEM; - } - if (s != 0) -- printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); - -- mutex_unlock(&mailbox_lock); -+ mutex_unlock(&mailbox_lock); - return s; - } - EXPORT_SYMBOL_GPL(bcm_mailbox_property); -@@ -291,7 +287,7 @@ EXPORT_SYMBOL_GPL(bcm_mailbox_property); - * Is the device open right now? Used to prevent - * concurent access into the same device - */ --static int Device_Open = 0; -+static bool device_is_open; - - /* - * This is called whenever a process attempts to open the device file -@@ -301,10 +297,10 @@ static int device_open(struct inode *inode, struct file *file) - /* - * We don't want to talk to two processes at the same time - */ -- if (Device_Open) -+ if (device_is_open) - return -EBUSY; - -- Device_Open++; -+ device_is_open = true; - /* - * Initialize the message - */ -@@ -317,7 +313,7 @@ static int device_release(struct inode *inode, struct file *file) - /* - * We're now ready for our next caller - */ -- Device_Open--; -+ device_is_open = false; - - module_put(THIS_MODULE); - return 0; -@@ -333,9 +329,8 @@ static int device_release(struct inode *inode, struct file *file) - * calling process), the ioctl call returns the output of this function. - * - */ --static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -- unsigned int ioctl_num, /* number and param for ioctl */ -- unsigned long ioctl_param) -+static long device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) - { - unsigned size; - /* -@@ -348,11 +343,10 @@ static long device_ioctl(struct file *file, /* see include/linux/fs.h */ - * to be the device's message. Get the parameter given to - * ioctl by the process. - */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); - return bcm_mailbox_property((void *)ioctl_param, size); -- break; - default: -- printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); - return -EINVAL; - } - -@@ -368,7 +362,7 @@ static long device_ioctl(struct file *file, /* see include/linux/fs.h */ - * the devices table, it can't be local to - * init_module. NULL is for unimplemented functios. - */ --struct file_operations fops = { -+const struct file_operations fops = { - .unlocked_ioctl = device_ioctl, - .open = device_open, - .release = device_release, /* a.k.a. close */ -@@ -380,17 +374,15 @@ static int bcm_vcio_probe(struct platform_device *pdev) - struct vc_mailbox *mailbox; - - mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -- if (NULL == mailbox) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "mailbox memory\n"); -+ if (!mailbox) { - ret = -ENOMEM; - } else { - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -+ if (!res) { -+ pr_err(DRIVER_NAME -+ ": failed to obtain memory resource\n"); - ret = -ENODEV; - kfree(mailbox); - } else { -@@ -402,8 +394,8 @@ static int bcm_vcio_probe(struct platform_device *pdev) - - mbox_irqaction.dev_id = mailbox; - setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -- printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -- __io_address(ARM_0_MAIL0_RD)); -+ dev_info(&pdev->dev, "mailbox at %p\n", -+ __io_address(ARM_0_MAIL0_RD)); - } - } - -@@ -417,17 +409,18 @@ static int bcm_vcio_probe(struct platform_device *pdev) - * Negative values signify an error - */ - if (ret < 0) { -- printk(KERN_ERR DRIVER_NAME -- "Failed registering the character device %d\n", ret); -+ pr_err(DRIVER_NAME -+ "Failed registering the character device %d\n", -+ ret); - return ret; - } - vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); - if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- return ret ; -+ ret = PTR_ERR(vcio_class); -+ return ret; - } - device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -+ "vcio"); - } - return ret; - } -@@ -456,20 +449,18 @@ static int __init bcm_mbox_init(void) - { - int ret; - -- printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -+ pr_info("mailbox: Broadcom VideoCore Mailbox driver\n"); - - ret = platform_driver_register(&bcm_mbox_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -+ if (ret) -+ pr_err(DRIVER_NAME ": failed to register on platform\n"); - - return ret; - } - - static void __exit bcm_mbox_exit(void) - { -- device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); - class_destroy(vcio_class); - unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - -From f7567a97143abdc87b5dc258b3b628ba115ce0b2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:02:44 +0200 -Subject: [PATCH 136/216] BCM2708: vcio: Remove unused code and compact - comments -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The config reference SERIAL_BCM_MBOX_CONSOLE does not exist, -so remove the whole clause as it will always be false. - -Remove includes that are not needed. -Add . -Also sort include headers alphabetically, since this -is now the preferred coding style. - -Remove vc_mailbox->dev since it is not used. - -Compact some comments to one line. -Remove superfluous comments. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 68 ++++++++++---------------------------------- - 1 file changed, 15 insertions(+), 53 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 5e9e777..270f126 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -12,39 +12,24 @@ - * VideoCore processor - */ - --#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) --#define SUPPORT_SYSRQ --#endif -- -+#include -+#include - #include --#include --#include --#include - #include --#include -+#include - #include --#include --#include --#include --#include --#include --#include - #include --#include -- - #include -+#include -+#include -+#include -+#include - - #include - #include - --#include -- - #define DRIVER_NAME BCM_VCIO_DRIVER_NAME - --/* ---------------------------------------------------------------------- -- * Mailbox -- * -------------------------------------------------------------------- */ -- - /* offsets from a mail box base address */ - #define MAIL_WRT 0x00 /* write - and next 4 words */ - #define MAIL_RD 0x00 /* read - and next 4 words */ -@@ -64,7 +49,6 @@ - static struct class *vcio_class; - - struct vc_mailbox { -- struct device *dev; /* parent device */ - void __iomem *status; - void __iomem *config; - void __iomem *read; -@@ -79,7 +63,6 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - { - int i; - -- mbox_out->dev = dev; - mbox_out->status = __io_address(addr_mbox + MAIL_STA); - mbox_out->config = __io_address(addr_mbox + MAIL_CNF); - mbox_out->read = __io_address(addr_mbox + MAIL_RD); -@@ -144,7 +127,6 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - - if (chan < MBOX_CHAN_COUNT) { - if (mbox->msg[chan]) { -- /* Overflow */ - pr_err(DRIVER_NAME - ": mbox chan %d overflow - drop %08x\n", - chan, msg); -@@ -168,9 +150,7 @@ static struct irqaction mbox_irqaction = { - .handler = mbox_irq, - }; - --/* ---------------------------------------------------------------------- -- * Mailbox Methods -- * -------------------------------------------------------------------- */ -+/* Mailbox Methods */ - - static struct device *mbox_dev; /* we assume there's only one! */ - -@@ -279,9 +259,7 @@ extern int bcm_mailbox_property(void *data, int size) - } - EXPORT_SYMBOL_GPL(bcm_mailbox_property); - --/* ---------------------------------------------------------------------- -- * Platform Device for Mailbox -- * -------------------------------------------------------------------- */ -+/* Platform Device for Mailbox */ - - /* - * Is the device open right now? Used to prevent -@@ -289,33 +267,26 @@ EXPORT_SYMBOL_GPL(bcm_mailbox_property); - */ - static bool device_is_open; - --/* -- * This is called whenever a process attempts to open the device file -- */ -+/* This is called whenever a process attempts to open the device file */ - static int device_open(struct inode *inode, struct file *file) - { -- /* -- * We don't want to talk to two processes at the same time -- */ -+ /* We don't want to talk to two processes at the same time */ - if (device_is_open) - return -EBUSY; - - device_is_open = true; -- /* -- * Initialize the message -- */ - try_module_get(THIS_MODULE); -+ - return 0; - } - - static int device_release(struct inode *inode, struct file *file) - { -- /* -- * We're now ready for our next caller -- */ -+ /* We're now ready for our next caller */ - device_is_open = false; - - module_put(THIS_MODULE); -+ - return 0; - } - -@@ -333,9 +304,7 @@ static long device_ioctl(struct file *file, unsigned int ioctl_num, - unsigned long ioctl_param) - { - unsigned size; -- /* -- * Switch according to the ioctl called -- */ -+ - switch (ioctl_num) { - case IOCTL_MBOX_PROPERTY: - /* -@@ -400,14 +369,7 @@ static int bcm_vcio_probe(struct platform_device *pdev) - } - - if (ret == 0) { -- /* -- * Register the character device -- */ - ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- -- /* -- * Negative values signify an error -- */ - if (ret < 0) { - pr_err(DRIVER_NAME - "Failed registering the character device %d\n", - -From 406f0f628a2f978a1da4d25dda3b5eafb94cefd0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:10:18 +0200 -Subject: [PATCH 137/216] BCM2708: vcio: Move character device teardown to - driver remove -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -chrdev is created in the probe function, but teared down in module exit. -Move chrdev teardown to happen on device removal. -Also add missing mbox_dev disabling. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 270f126..cac8dd7 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -391,8 +391,12 @@ static int bcm_vcio_remove(struct platform_device *pdev) - { - struct vc_mailbox *mailbox = platform_get_drvdata(pdev); - -+ mbox_dev = NULL; - platform_set_drvdata(pdev, NULL); - kfree(mailbox); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - - return 0; - } -@@ -422,9 +426,6 @@ static int __init bcm_mbox_init(void) - - static void __exit bcm_mbox_exit(void) - { -- device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); - platform_driver_unregister(&bcm_mbox_driver); - } - - -From fa189cd5d18e5cda8438873181a329fc489a6649 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:20:46 +0200 -Subject: [PATCH 138/216] BCM2708: vcio: Restructure error paths -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to use if/else clauses on error when return can be used directly. -Also test for errors first if possible. -This is done to enhance readability. -bcm_vcio_probe() is not touched, it will be reworked later. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 48 +++++++++++++++++++------------------------- - 1 file changed, 21 insertions(+), 27 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index cac8dd7..36e0f1e 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -84,34 +84,28 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - - static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - { -- int rc; -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; - -- if (mbox->magic != MBOX_MAGIC) { -- rc = -EINVAL; -- } else { -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->status) & ARM_MS_FULL)) -- cpu_relax(); -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ cpu_relax(); - -- writel(MBOX_MSG(chan, data28), mbox->write); -- rc = 0; -- } -- return rc; -+ writel(MBOX_MSG(chan, data28), mbox->write); -+ -+ return 0; - } - - static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - { -- int rc; -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; - -- if (mbox->magic != MBOX_MAGIC) { -- rc = -EINVAL; -- } else { -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- rc = 0; -- } -- return rc; -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ -+ return 0; - } - - static irqreturn_t mbox_irq(int irq, void *dev_id) -@@ -180,19 +174,19 @@ static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) - - extern int bcm_mailbox_write(unsigned chan, uint32_t data28) - { -- if (mbox_dev) -- return dev_mbox_write(mbox_dev, chan, data28); -- else -+ if (!mbox_dev) - return -ENODEV; -+ -+ return dev_mbox_write(mbox_dev, chan, data28); - } - EXPORT_SYMBOL_GPL(bcm_mailbox_write); - - extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) - { -- if (mbox_dev) -- return dev_mbox_read(mbox_dev, chan, data28); -- else -+ if (!mbox_dev) - return -ENODEV; -+ -+ return dev_mbox_read(mbox_dev, chan, data28); - } - EXPORT_SYMBOL_GPL(bcm_mailbox_read); - - -From ce2c991a11f0a94679423655dceed9bb80604892 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:28:31 +0200 -Subject: [PATCH 139/216] BCM2708: vcio: Move some macros from header to driver -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Move some macros that are only used by the driver: -MAJOR_NUM -IOCTL_MBOX_PROPERTY -DEVICE_FILE_NAME - -This one becomes superfluous: BCM_VCIO_DRIVER_NAME - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/vcio.h | 35 ------------------------------- - arch/arm/mach-bcm2708/vcio.c | 9 ++++++-- - 2 files changed, 7 insertions(+), 37 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -index 58188b74..95ad121 100644 ---- a/arch/arm/mach-bcm2708/include/mach/vcio.h -+++ b/arch/arm/mach-bcm2708/include/mach/vcio.h -@@ -20,8 +20,6 @@ - * (semaphores, doorbells, mailboxes) - */ - --#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -- - /* Constants shared with the ARM identifying separate mailbox channels */ - #define MBOX_CHAN_POWER 0 /* for use by the power management interface */ - #define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -@@ -127,37 +125,4 @@ extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); - extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); - extern int /*rc*/ bcm_mailbox_property(void *data, int size); - --#include -- --/* -- * The major device number. We can't rely on dynamic -- * registration any more, because ioctls need to know -- * it. -- */ --#define MAJOR_NUM 100 -- --/* -- * Set the message of the device driver -- */ --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) --/* -- * _IOWR means that we're creating an ioctl command -- * number for passing information from a user process -- * to the kernel module and from the kernel module to user process -- * -- * The first arguments, MAJOR_NUM, is the major device -- * number we're using. -- * -- * The second argument is the number of the command -- * (there could be several with different meanings). -- * -- * The third argument is the type we want to get from -- * the process to the kernel. -- */ -- --/* -- * The name of the device file -- */ --#define DEVICE_FILE_NAME "vcio" -- - #endif -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 36e0f1e..75cf955 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -28,7 +29,8 @@ - #include - #include - --#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -+#define DRIVER_NAME "bcm2708_vcio" -+#define DEVICE_FILE_NAME "vcio" - - /* offsets from a mail box base address */ - #define MAIL_WRT 0x00 /* write - and next 4 words */ -@@ -46,6 +48,9 @@ - - #define MBOX_MAGIC 0xd0d0c0de - -+#define MAJOR_NUM 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+ - static struct class *vcio_class; - - struct vc_mailbox { -@@ -370,7 +375,7 @@ static int bcm_vcio_probe(struct platform_device *pdev) - ret); - return ret; - } -- vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); - if (IS_ERR(vcio_class)) { - ret = PTR_ERR(vcio_class); - return ret; - -From 71c6a7270af56930e1e31ff243048c1ac12ebc1f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:40:03 +0200 -Subject: [PATCH 140/216] BCM2708: vcio: Only store the register base address -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to keep pointers to the sub registers. Only -store the base address. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 37 ++++++++++++++----------------------- - 1 file changed, 14 insertions(+), 23 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index 75cf955..e67fa3e 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -33,12 +33,12 @@ - #define DEVICE_FILE_NAME "vcio" - - /* offsets from a mail box base address */ --#define MAIL_WRT 0x00 /* write - and next 4 words */ --#define MAIL_RD 0x00 /* read - and next 4 words */ --#define MAIL_POL 0x10 /* read without popping the fifo */ --#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL_STA 0x18 /* status */ --#define MAIL_CNF 0x1C /* configuration */ -+#define MAIL0_RD 0x00 /* read - and next 4 words */ -+#define MAIL0_POL 0x10 /* read without popping the fifo */ -+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL0_STA 0x18 /* status */ -+#define MAIL0_CNF 0x1C /* configuration */ -+#define MAIL1_WRT 0x20 /* write - and next 4 words */ - - #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) - #define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -@@ -54,10 +54,7 @@ - static struct class *vcio_class; - - struct vc_mailbox { -- void __iomem *status; -- void __iomem *config; -- void __iomem *read; -- void __iomem *write; -+ void __iomem *regs; - uint32_t msg[MBOX_CHAN_COUNT]; - struct semaphore sema[MBOX_CHAN_COUNT]; - uint32_t magic; -@@ -68,13 +65,7 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - { - int i; - -- mbox_out->status = __io_address(addr_mbox + MAIL_STA); -- mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -- mbox_out->read = __io_address(addr_mbox + MAIL_RD); -- /* Write to the other mailbox */ -- mbox_out->write = -- __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -- MAIL_WRT); -+ mbox_out->regs = __io_address(addr_mbox); - - for (i = 0; i < MBOX_CHAN_COUNT; i++) { - mbox_out->msg[i] = 0; -@@ -82,7 +73,7 @@ static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, - } - - /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); - - mbox_out->magic = MBOX_MAGIC; - } -@@ -93,10 +84,10 @@ static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - return -EINVAL; - - /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->status) & ARM_MS_FULL)) -+ while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) - cpu_relax(); - -- writel(MBOX_MSG(chan, data28), mbox->write); -+ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); - - return 0; - } -@@ -117,11 +108,11 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - { - /* wait for the mailbox FIFO to have some data in it */ - struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -- int status = readl(mbox->status); -+ int status = readl(mbox->regs + MAIL0_STA); - int ret = IRQ_NONE; - - while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->read); -+ uint32_t msg = readl(mbox->regs + MAIL0_RD); - int chan = MBOX_CHAN(msg); - - if (chan < MBOX_CHAN_COUNT) { -@@ -138,7 +129,7 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - ": invalid channel selector (msg %08x)\n", msg); - } - ret = IRQ_HANDLED; -- status = readl(mbox->status); -+ status = readl(mbox->regs + MAIL0_STA); - } - return ret; - } - -From 30e7622ceffd50a31b6544e3a3e05bb0743c3bc2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 21:44:39 +0200 -Subject: [PATCH 141/216] BCM2708: vcio: Do not print messages in module init -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It is not common practice to print messages from a -module init function that only register a driver. -Remove obsolete module alias. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 11 +---------- - 1 file changed, 1 insertion(+), 10 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index e67fa3e..ff50ebd 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -403,15 +403,7 @@ static struct platform_driver bcm_mbox_driver = { - - static int __init bcm_mbox_init(void) - { -- int ret; -- -- pr_info("mailbox: Broadcom VideoCore Mailbox driver\n"); -- -- ret = platform_driver_register(&bcm_mbox_driver); -- if (ret) -- pr_err(DRIVER_NAME ": failed to register on platform\n"); -- -- return ret; -+ return platform_driver_register(&bcm_mbox_driver); - } - - static void __exit bcm_mbox_exit(void) -@@ -425,4 +417,3 @@ module_exit(bcm_mbox_exit); - MODULE_AUTHOR("Gray Girling"); - MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); - MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm-mbox"); - -From 7a9128973d51200625a3d3f8ff72a4580cb9f14b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 30 Apr 2015 23:33:43 +0200 -Subject: [PATCH 142/216] BCM2708: vcio: Use device resources -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use device resources instead of hardcoding them. -Use devm_* functions where possible. -Merge dev_mbox_register() with probe function. -Add Device Tree support. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/vcio.c | 122 +++++++++++++++++++++---------------------- - 1 file changed, 61 insertions(+), 61 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -index ff50ebd..c4c2bcd 100644 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ b/arch/arm/mach-bcm2708/vcio.c -@@ -21,13 +21,10 @@ - #include - #include - #include --#include - #include --#include - #include - - #include --#include - - #define DRIVER_NAME "bcm2708_vcio" - #define DEVICE_FILE_NAME "vcio" -@@ -60,13 +57,10 @@ struct vc_mailbox { - uint32_t magic; - }; - --static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -- uint32_t addr_mbox) -+static void mbox_init(struct vc_mailbox *mbox_out) - { - int i; - -- mbox_out->regs = __io_address(addr_mbox); -- - for (i = 0; i < MBOX_CHAN_COUNT; i++) { - mbox_out->msg[i] = 0; - sema_init(&mbox_out->sema[i], 0); -@@ -104,7 +98,7 @@ static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) - return 0; - } - --static irqreturn_t mbox_irq(int irq, void *dev_id) -+static irqreturn_t mbox_irq_handler(int irq, void *dev_id) - { - /* wait for the mailbox FIFO to have some data in it */ - struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -@@ -134,12 +128,6 @@ static irqreturn_t mbox_irq(int irq, void *dev_id) - return ret; - } - --static struct irqaction mbox_irqaction = { -- .name = "ARM Mailbox IRQ", -- .flags = IRQF_DISABLED | IRQF_IRQPOLL, -- .handler = mbox_irq, --}; -- - /* Mailbox Methods */ - - static struct device *mbox_dev; /* we assume there's only one! */ -@@ -186,11 +174,6 @@ extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) - } - EXPORT_SYMBOL_GPL(bcm_mailbox_read); - --static void dev_mbox_register(const char *dev_name, struct device *dev) --{ -- mbox_dev = dev; --} -- - static int mbox_copy_from_user(void *dst, const void *src, int size) - { - if ((uint32_t)src < TASK_SIZE) -@@ -329,61 +312,71 @@ const struct file_operations fops = { - - static int bcm_vcio_probe(struct platform_device *pdev) - { -- int ret = 0; -+ struct device *dev = &pdev->dev; -+ struct device *vdev; - struct vc_mailbox *mailbox; -+ struct resource *res; -+ int irq, ret; -+ -+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -+ if (!mailbox) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mailbox->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mailbox->regs)) -+ return PTR_ERR(mailbox->regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, irq, mbox_irq_handler, -+ IRQF_DISABLED | IRQF_IRQPOLL, -+ dev_name(dev), mailbox); -+ if (ret) { -+ dev_err(dev, "Interrupt request failed %d\n", ret); -+ return ret; -+ } - -- mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -- if (!mailbox) { -- ret = -ENOMEM; -- } else { -- struct resource *res; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!res) { -- pr_err(DRIVER_NAME -- ": failed to obtain memory resource\n"); -- ret = -ENODEV; -- kfree(mailbox); -- } else { -- /* should be based on the registers from res really */ -- mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -- -- platform_set_drvdata(pdev, mailbox); -- dev_mbox_register(DRIVER_NAME, &pdev->dev); -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ if (ret < 0) { -+ pr_err("Character device registration failed %d\n", ret); -+ return ret; -+ } - -- mbox_irqaction.dev_id = mailbox; -- setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -- dev_info(&pdev->dev, "mailbox at %p\n", -- __io_address(ARM_0_MAIL0_RD)); -- } -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ pr_err("Class creation failed %d\n", ret); -+ goto err_class; - } - -- if (ret == 0) { -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- if (ret < 0) { -- pr_err(DRIVER_NAME -- "Failed registering the character device %d\n", -- ret); -- return ret; -- } -- vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- return ret; -- } -- device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -+ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); -+ if (IS_ERR(vdev)) { -+ ret = PTR_ERR(vdev); -+ pr_err("Device creation failed %d\n", ret); -+ goto err_dev; - } -+ -+ mbox_init(mailbox); -+ platform_set_drvdata(pdev, mailbox); -+ mbox_dev = dev; -+ -+ dev_info(dev, "mailbox at %p\n", mailbox->regs); -+ -+ return 0; -+ -+err_dev: -+ class_destroy(vcio_class); -+err_class: -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ - return ret; - } - - static int bcm_vcio_remove(struct platform_device *pdev) - { -- struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -- - mbox_dev = NULL; - platform_set_drvdata(pdev, NULL); -- kfree(mailbox); - device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); - class_destroy(vcio_class); - unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -@@ -391,6 +384,12 @@ static int bcm_vcio_remove(struct platform_device *pdev) - return 0; - } - -+static const struct of_device_id bcm_vcio_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-vcio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -+ - static struct platform_driver bcm_mbox_driver = { - .probe = bcm_vcio_probe, - .remove = bcm_vcio_remove, -@@ -398,6 +397,7 @@ static struct platform_driver bcm_mbox_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm_vcio_of_match_table, - }, - }; - - -From bb294088d80bcba531bc3d58b4a6c08b8cdcb0b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 19:11:03 +0200 -Subject: [PATCH 143/216] mailbox: bcm2708: Add bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Copy the arch vcio.c driver to drivers/mailbox. -This is done to make it available on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/Kconfig | 6 + - drivers/mailbox/Makefile | 2 + - drivers/mailbox/bcm2708-vcio.c | 426 ++++++++++++++++++++++++++ - include/linux/platform_data/mailbox-bcm2708.h | 126 ++++++++ - 4 files changed, 560 insertions(+) - create mode 100644 drivers/mailbox/bcm2708-vcio.c - create mode 100644 include/linux/platform_data/mailbox-bcm2708.h - -diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig -index 84325f2..fdcb206 100644 ---- a/drivers/mailbox/Kconfig -+++ b/drivers/mailbox/Kconfig -@@ -6,6 +6,12 @@ menuconfig MAILBOX - signals. Say Y if your platform supports hardware mailboxes. - - if MAILBOX -+config BCM2708_MBOX -+ bool "Broadcom BCM2708 Mailbox (vcio)" -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 -+ help -+ Broadcom BCM2708 Mailbox (vcio) -+ - config PL320_MBOX - bool "ARM PL320 Mailbox" - depends on ARM_AMBA -diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile -index 2e79231..c2d2bed 100644 ---- a/drivers/mailbox/Makefile -+++ b/drivers/mailbox/Makefile -@@ -2,6 +2,8 @@ - - obj-$(CONFIG_MAILBOX) += mailbox.o - -+obj-$(CONFIG_BCM2708_MBOX) += bcm2708-vcio.o -+ - obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o - - obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -new file mode 100644 -index 0000000..ee3e778 ---- /dev/null -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -0,0 +1,426 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/vcio.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for writing to the mailboxes, -+ * semaphores, doorbells etc. that are shared between the ARM and the -+ * VideoCore processor -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_vcio" -+#define DEVICE_FILE_NAME "vcio" -+ -+/* offsets from a mail box base address */ -+#define MAIL0_RD 0x00 /* read - and next 4 words */ -+#define MAIL0_POL 0x10 /* read without popping the fifo */ -+#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ -+#define MAIL0_STA 0x18 /* status */ -+#define MAIL0_CNF 0x1C /* configuration */ -+#define MAIL1_WRT 0x20 /* write - and next 4 words */ -+ -+/* On MACH_BCM270x these come through (arm_control.h ) */ -+#ifndef ARM_MS_EMPTY -+#define ARM_MS_EMPTY BIT(30) -+#define ARM_MS_FULL BIT(31) -+ -+#define ARM_MC_IHAVEDATAIRQEN BIT(0) -+#endif -+ -+#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) -+#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) -+#define MBOX_CHAN(msg) ((msg) & 0xf) -+#define MBOX_DATA28(msg) ((msg) & ~0xf) -+#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -+ -+#define MBOX_MAGIC 0xd0d0c0de -+ -+#define MAJOR_NUM 100 -+#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -+ -+static struct class *vcio_class; -+ -+struct vc_mailbox { -+ void __iomem *regs; -+ uint32_t msg[MBOX_CHAN_COUNT]; -+ struct semaphore sema[MBOX_CHAN_COUNT]; -+ uint32_t magic; -+}; -+ -+static void mbox_init(struct vc_mailbox *mbox_out) -+{ -+ int i; -+ -+ for (i = 0; i < MBOX_CHAN_COUNT; i++) { -+ mbox_out->msg[i] = 0; -+ sema_init(&mbox_out->sema[i], 0); -+ } -+ -+ /* Enable the interrupt on data reception */ -+ writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -+ -+ mbox_out->magic = MBOX_MAGIC; -+} -+ -+static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ /* wait for the mailbox FIFO to have some space in it */ -+ while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) -+ cpu_relax(); -+ -+ writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -+ -+ return 0; -+} -+ -+static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) -+{ -+ if (mbox->magic != MBOX_MAGIC) -+ return -EINVAL; -+ -+ down(&mbox->sema[chan]); -+ *data28 = MBOX_DATA28(mbox->msg[chan]); -+ mbox->msg[chan] = 0; -+ -+ return 0; -+} -+ -+static irqreturn_t mbox_irq_handler(int irq, void *dev_id) -+{ -+ /* wait for the mailbox FIFO to have some data in it */ -+ struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -+ int status = readl(mbox->regs + MAIL0_STA); -+ int ret = IRQ_NONE; -+ -+ while (!(status & ARM_MS_EMPTY)) { -+ uint32_t msg = readl(mbox->regs + MAIL0_RD); -+ int chan = MBOX_CHAN(msg); -+ -+ if (chan < MBOX_CHAN_COUNT) { -+ if (mbox->msg[chan]) { -+ pr_err(DRIVER_NAME -+ ": mbox chan %d overflow - drop %08x\n", -+ chan, msg); -+ } else { -+ mbox->msg[chan] = (msg | 0xf); -+ up(&mbox->sema[chan]); -+ } -+ } else { -+ pr_err(DRIVER_NAME -+ ": invalid channel selector (msg %08x)\n", msg); -+ } -+ ret = IRQ_HANDLED; -+ status = readl(mbox->regs + MAIL0_STA); -+ } -+ return ret; -+} -+ -+/* Mailbox Methods */ -+ -+static struct device *mbox_dev; /* we assume there's only one! */ -+ -+static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_write(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) -+{ -+ struct vc_mailbox *mailbox = dev_get_drvdata(dev); -+ int rc; -+ -+ device_lock(dev); -+ rc = mbox_read(mailbox, chan, data28); -+ device_unlock(dev); -+ -+ return rc; -+} -+ -+extern int bcm_mailbox_write(unsigned chan, uint32_t data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_write(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_write); -+ -+extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) -+{ -+ if (!mbox_dev) -+ return -ENODEV; -+ -+ return dev_mbox_read(mbox_dev, chan, data28); -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_read); -+ -+static int mbox_copy_from_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)src < TASK_SIZE) -+ return copy_from_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static int mbox_copy_to_user(void *dst, const void *src, int size) -+{ -+ if ((uint32_t)dst < TASK_SIZE) -+ return copy_to_user(dst, src, size); -+ -+ memcpy(dst, src, size); -+ -+ return 0; -+} -+ -+static DEFINE_MUTEX(mailbox_lock); -+extern int bcm_mailbox_property(void *data, int size) -+{ -+ uint32_t success; -+ dma_addr_t mem_bus; /* the memory address accessed from videocore */ -+ void *mem_kern; /* the memory address accessed from driver */ -+ int s = 0; -+ -+ mutex_lock(&mailbox_lock); -+ /* allocate some memory for the messages communicating with GPU */ -+ mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -+ GFP_ATOMIC); -+ if (mem_kern) { -+ /* create the message */ -+ mbox_copy_from_user(mem_kern, data, size); -+ -+ /* send the message */ -+ wmb(); -+ s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -+ if (s == 0) -+ s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -+ if (s == 0) { -+ /* copy the response */ -+ rmb(); -+ mbox_copy_to_user(data, mem_kern, size); -+ } -+ dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -+ } else { -+ s = -ENOMEM; -+ } -+ if (s != 0) -+ pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -+ -+ mutex_unlock(&mailbox_lock); -+ return s; -+} -+EXPORT_SYMBOL_GPL(bcm_mailbox_property); -+ -+/* Platform Device for Mailbox */ -+ -+/* -+ * Is the device open right now? Used to prevent -+ * concurent access into the same device -+ */ -+static bool device_is_open; -+ -+/* This is called whenever a process attempts to open the device file */ -+static int device_open(struct inode *inode, struct file *file) -+{ -+ /* We don't want to talk to two processes at the same time */ -+ if (device_is_open) -+ return -EBUSY; -+ -+ device_is_open = true; -+ try_module_get(THIS_MODULE); -+ -+ return 0; -+} -+ -+static int device_release(struct inode *inode, struct file *file) -+{ -+ /* We're now ready for our next caller */ -+ device_is_open = false; -+ -+ module_put(THIS_MODULE); -+ -+ return 0; -+} -+ -+/* -+ * This function is called whenever a process tries to do an ioctl on our -+ * device file. We get two extra parameters (additional to the inode and file -+ * structures, which all device functions get): the number of the ioctl called -+ * and the parameter given to the ioctl function. -+ * -+ * If the ioctl is write or read/write (meaning output is returned to the -+ * calling process), the ioctl call returns the output of this function. -+ * -+ */ -+static long device_ioctl(struct file *file, unsigned int ioctl_num, -+ unsigned long ioctl_param) -+{ -+ unsigned size; -+ -+ switch (ioctl_num) { -+ case IOCTL_MBOX_PROPERTY: -+ /* -+ * Receive a pointer to a message (in user space) and set that -+ * to be the device's message. Get the parameter given to -+ * ioctl by the process. -+ */ -+ mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -+ return bcm_mailbox_property((void *)ioctl_param, size); -+ default: -+ pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+/* Module Declarations */ -+ -+/* -+ * This structure will hold the functions to be called -+ * when a process does something to the device we -+ * created. Since a pointer to this structure is kept in -+ * the devices table, it can't be local to -+ * init_module. NULL is for unimplemented functios. -+ */ -+const struct file_operations fops = { -+ .unlocked_ioctl = device_ioctl, -+ .open = device_open, -+ .release = device_release, /* a.k.a. close */ -+}; -+ -+static int bcm_vcio_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ struct device *vdev; -+ struct vc_mailbox *mailbox; -+ struct resource *res; -+ int irq, ret; -+ -+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -+ if (!mailbox) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ mailbox->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(mailbox->regs)) -+ return PTR_ERR(mailbox->regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(dev, irq, mbox_irq_handler, -+ IRQF_DISABLED | IRQF_IRQPOLL, -+ dev_name(dev), mailbox); -+ if (ret) { -+ dev_err(dev, "Interrupt request failed %d\n", ret); -+ return ret; -+ } -+ -+ ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -+ if (ret < 0) { -+ pr_err("Character device registration failed %d\n", ret); -+ return ret; -+ } -+ -+ vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vcio_class)) { -+ ret = PTR_ERR(vcio_class); -+ pr_err("Class creation failed %d\n", ret); -+ goto err_class; -+ } -+ -+ vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -+ "vcio"); -+ if (IS_ERR(vdev)) { -+ ret = PTR_ERR(vdev); -+ pr_err("Device creation failed %d\n", ret); -+ goto err_dev; -+ } -+ -+ mbox_init(mailbox); -+ platform_set_drvdata(pdev, mailbox); -+ mbox_dev = dev; -+ -+ dev_info(dev, "mailbox at %p\n", mailbox->regs); -+ -+ return 0; -+ -+err_dev: -+ class_destroy(vcio_class); -+err_class: -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return ret; -+} -+ -+static int bcm_vcio_remove(struct platform_device *pdev) -+{ -+ mbox_dev = NULL; -+ platform_set_drvdata(pdev, NULL); -+ device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -+ class_destroy(vcio_class); -+ unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -+ -+ return 0; -+} -+ -+static const struct of_device_id bcm_vcio_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-vcio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -+ -+static struct platform_driver bcm_mbox_driver = { -+ .probe = bcm_vcio_probe, -+ .remove = bcm_vcio_remove, -+ -+ .driver = { -+ .name = DRIVER_NAME, -+ .owner = THIS_MODULE, -+ .of_match_table = bcm_vcio_of_match_table, -+ }, -+}; -+ -+static int __init bcm_mbox_init(void) -+{ -+ return platform_driver_register(&bcm_mbox_driver); -+} -+ -+static void __exit bcm_mbox_exit(void) -+{ -+ platform_driver_unregister(&bcm_mbox_driver); -+} -+ -+arch_initcall(bcm_mbox_init); /* Initialize early */ -+module_exit(bcm_mbox_exit); -+ -+MODULE_AUTHOR("Gray Girling"); -+MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/platform_data/mailbox-bcm2708.h b/include/linux/platform_data/mailbox-bcm2708.h -new file mode 100644 -index 0000000..cc284ed ---- /dev/null -+++ b/include/linux/platform_data/mailbox-bcm2708.h -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * 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. -+ */ -+#ifndef _PLAT_MAILBOX_BCM2708_H -+#define _PLAT_MAILBOX_BCM2708_H -+ -+/* Routines to handle I/O via the VideoCore "ARM control" registers -+ * (semaphores, doorbells, mailboxes) -+ */ -+ -+/* Constants shared with the ARM identifying separate mailbox channels */ -+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ -+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ -+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ -+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ -+#define MBOX_CHAN_COUNT 9 -+ -+enum { -+ VCMSG_PROCESS_REQUEST = 0x00000000 -+}; -+ -+enum { -+ VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -+ VCMSG_REQUEST_FAILED = 0x80000001 -+}; -+ -+/* Mailbox property tags */ -+enum { -+ VCMSG_PROPERTY_END = 0x00000000, -+ VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -+ VCMSG_GET_BOARD_MODEL = 0x00010001, -+ VCMSG_GET_BOARD_REVISION = 0x00010002, -+ VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -+ VCMSG_GET_BOARD_SERIAL = 0x00010004, -+ VCMSG_GET_ARM_MEMORY = 0x00010005, -+ VCMSG_GET_VC_MEMORY = 0x00010006, -+ VCMSG_GET_CLOCKS = 0x00010007, -+ VCMSG_GET_COMMAND_LINE = 0x00050001, -+ VCMSG_GET_DMA_CHANNELS = 0x00060001, -+ VCMSG_GET_POWER_STATE = 0x00020001, -+ VCMSG_GET_TIMING = 0x00020002, -+ VCMSG_SET_POWER_STATE = 0x00028001, -+ VCMSG_GET_CLOCK_STATE = 0x00030001, -+ VCMSG_SET_CLOCK_STATE = 0x00038001, -+ VCMSG_GET_CLOCK_RATE = 0x00030002, -+ VCMSG_SET_CLOCK_RATE = 0x00038002, -+ VCMSG_GET_VOLTAGE = 0x00030003, -+ VCMSG_SET_VOLTAGE = 0x00038003, -+ VCMSG_GET_MAX_CLOCK = 0x00030004, -+ VCMSG_GET_MAX_VOLTAGE = 0x00030005, -+ VCMSG_GET_TEMPERATURE = 0x00030006, -+ VCMSG_GET_MIN_CLOCK = 0x00030007, -+ VCMSG_GET_MIN_VOLTAGE = 0x00030008, -+ VCMSG_GET_TURBO = 0x00030009, -+ VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -+ VCMSG_GET_STC = 0x0003000b, -+ VCMSG_SET_TURBO = 0x00038009, -+ VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -+ VCMSG_SET_LOCK_MEM = 0x0003000d, -+ VCMSG_SET_UNLOCK_MEM = 0x0003000e, -+ VCMSG_SET_RELEASE_MEM = 0x0003000f, -+ VCMSG_SET_EXECUTE_CODE = 0x00030010, -+ VCMSG_SET_EXECUTE_QPU = 0x00030011, -+ VCMSG_SET_ENABLE_QPU = 0x00030012, -+ VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -+ VCMSG_GET_EDID_BLOCK = 0x00030020, -+ VCMSG_GET_CUSTOMER_OTP = 0x00030021, -+ VCMSG_SET_CUSTOMER_OTP = 0x00038021, -+ VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -+ VCMSG_SET_RELEASE_BUFFER = 0x00048001, -+ VCMSG_SET_BLANK_SCREEN = 0x00040002, -+ VCMSG_TST_BLANK_SCREEN = 0x00044002, -+ VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -+ VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -+ VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -+ VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -+ VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -+ VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -+ VCMSG_GET_DEPTH = 0x00040005, -+ VCMSG_TST_DEPTH = 0x00044005, -+ VCMSG_SET_DEPTH = 0x00048005, -+ VCMSG_GET_PIXEL_ORDER = 0x00040006, -+ VCMSG_TST_PIXEL_ORDER = 0x00044006, -+ VCMSG_SET_PIXEL_ORDER = 0x00048006, -+ VCMSG_GET_ALPHA_MODE = 0x00040007, -+ VCMSG_TST_ALPHA_MODE = 0x00044007, -+ VCMSG_SET_ALPHA_MODE = 0x00048007, -+ VCMSG_GET_PITCH = 0x00040008, -+ VCMSG_TST_PITCH = 0x00044008, -+ VCMSG_SET_PITCH = 0x00048008, -+ VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -+ VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -+ VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -+ VCMSG_GET_OVERSCAN = 0x0004000a, -+ VCMSG_TST_OVERSCAN = 0x0004400a, -+ VCMSG_SET_OVERSCAN = 0x0004800a, -+ VCMSG_GET_PALETTE = 0x0004000b, -+ VCMSG_TST_PALETTE = 0x0004400b, -+ VCMSG_SET_PALETTE = 0x0004800b, -+ VCMSG_GET_LAYER = 0x0004000c, -+ VCMSG_TST_LAYER = 0x0004400c, -+ VCMSG_SET_LAYER = 0x0004800c, -+ VCMSG_GET_TRANSFORM = 0x0004000d, -+ VCMSG_TST_TRANSFORM = 0x0004400d, -+ VCMSG_SET_TRANSFORM = 0x0004800d, -+ VCMSG_TST_VSYNC = 0x0004400e, -+ VCMSG_SET_VSYNC = 0x0004800e, -+ VCMSG_SET_CURSOR_INFO = 0x00008010, -+ VCMSG_SET_CURSOR_STATE = 0x00008011, -+}; -+ -+int bcm_mailbox_read(unsigned chan, uint32_t *data28); -+int bcm_mailbox_write(unsigned chan, uint32_t data28); -+int bcm_mailbox_property(void *data, int size); -+ -+#endif - -From 1e5c7135fc145addcf195d02759a45e162f2daac Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 19:11:58 +0200 -Subject: [PATCH 144/216] BCM270x: power: Change initcall level to subsys -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Load ordering of modules are determined by the initcall used. -If it's the same initcall level, makefile ordering decides. -Now that the mailbox driver is being moved, it's no longer -placed before the power driver by the linker. -So use a later initcall level to let the mailbox driver -load first. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/power.c | 6 +++++- - arch/arm/mach-bcm2709/power.c | 6 +++++- - 2 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -index 2696be9..0db355d 100644 ---- a/arch/arm/mach-bcm2708/power.c -+++ b/arch/arm/mach-bcm2708/power.c -@@ -189,7 +189,11 @@ static void __exit bcm_power_exit(void) - bcm_mailbox_write(MBOX_CHAN_POWER, 0); - } - --arch_initcall(bcm_power_init); /* Initialize early */ -+/* -+ * Load after the mailbox driver is initialized (arch_initcall), -+ * but before depending drivers (module_init). -+ */ -+subsys_initcall(bcm_power_init); - module_exit(bcm_power_exit); - - MODULE_AUTHOR("Phil Elwell"); -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -index 3421057..88c1e28 100644 ---- a/arch/arm/mach-bcm2709/power.c -+++ b/arch/arm/mach-bcm2709/power.c -@@ -187,7 +187,11 @@ static void __exit bcm_power_exit(void) - bcm_mailbox_write(MBOX_CHAN_POWER, 0); - } - --arch_initcall(bcm_power_init); /* Initialize early */ -+/* -+ * Load after the mailbox driver is initialized (arch_initcall), -+ * but before depending drivers (module_init). -+ */ -+subsys_initcall(bcm_power_init); - module_exit(bcm_power_exit); - - MODULE_AUTHOR("Phil Elwell"); - -From 41e80f86dc78015856087cccd8e4f9a251042f9d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 2 May 2015 09:34:26 +0200 -Subject: [PATCH 145/216] BCM270x: Use bcm2708-vcio -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use bcm2708-vcio instead of the arch version. -Change affected drivers to use linux/platform_data/mailbox-bcm2708.h - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/power.c | 2 +- - arch/arm/mach-bcm2708/vc_mem.c | 2 +- - arch/arm/mach-bcm2709/Makefile | 2 +- - arch/arm/mach-bcm2709/power.c | 2 +- - arch/arm/mach-bcm2709/vc_mem.c | 2 +- - arch/arm/mach-bcm2709/vc_support.c | 2 +- - drivers/cpufreq/bcm2835-cpufreq.c | 2 +- - drivers/hwmon/bcm2835-hwmon.c | 2 +- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 2 +- - drivers/thermal/bcm2835-thermal.c | 2 +- - drivers/video/fbdev/bcm2708_fb.c | 2 +- - 14 files changed, 16 insertions(+), 12 deletions(-) - mode change 100755 => 100644 arch/arm/mach-bcm2709/vc_support.c - mode change 100755 => 100644 drivers/cpufreq/bcm2835-cpufreq.c - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 367a04a..ff87581 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1052,6 +1052,8 @@ CONFIG_FB_TFT_UPD161704=m - CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index db287f3..e339979 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1045,6 +1045,8 @@ CONFIG_FB_TFT_UPD161704=m - CONFIG_FB_TFT_WATTEROTT=m - CONFIG_FB_FLEX=m - CONFIG_FB_TFT_FBTFT_DEVICE=m -+CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXTCON=m - CONFIG_EXTCON_ARIZONA=m -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index 454408c..c1e7d41 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o vcio.o power.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -index 0db355d..796837f 100644 ---- a/arch/arm/mach-bcm2708/power.c -+++ b/arch/arm/mach-bcm2708/power.c -@@ -14,8 +14,8 @@ - #include - #include - #include -+#include - #include --#include - #include - - #define DRIVER_NAME "bcm2708_power" -diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c -index 2982af7..226b737 100644 ---- a/arch/arm/mach-bcm2708/vc_mem.c -+++ b/arch/arm/mach-bcm2708/vc_mem.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_ARCH_KONA - #include -@@ -31,7 +32,6 @@ - #endif - - #include "mach/vc_mem.h" --#include - - #define DRIVER_NAME "vc-mem" - -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index f07c38b..77b8429 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o vcio.o power.o -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o power.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -index 88c1e28..960e472 100644 ---- a/arch/arm/mach-bcm2709/power.c -+++ b/arch/arm/mach-bcm2709/power.c -@@ -14,8 +14,8 @@ - #include - #include - #include -+#include - #include --#include - #include - - #define DRIVER_NAME "bcm2708_power" -diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c -index ac578db..d2adfd1 100644 ---- a/arch/arm/mach-bcm2709/vc_mem.c -+++ b/arch/arm/mach-bcm2709/vc_mem.c -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_ARCH_KONA - #include -@@ -31,7 +32,6 @@ - #endif - - #include "mach/vc_mem.h" --#include - - #define DRIVER_NAME "vc-mem" - -diff --git a/arch/arm/mach-bcm2709/vc_support.c b/arch/arm/mach-bcm2709/vc_support.c -old mode 100755 -new mode 100644 -index 0bc41c4..c4dc7d6 ---- a/arch/arm/mach-bcm2709/vc_support.c -+++ b/arch/arm/mach-bcm2709/vc_support.c -@@ -6,7 +6,7 @@ - */ - - #include --#include -+#include - - #ifdef ECLIPSE_IGNORE - -diff --git a/drivers/cpufreq/bcm2835-cpufreq.c b/drivers/cpufreq/bcm2835-cpufreq.c -old mode 100755 -new mode 100644 -index 447ca09..6735da9 ---- a/drivers/cpufreq/bcm2835-cpufreq.c -+++ b/drivers/cpufreq/bcm2835-cpufreq.c -@@ -26,7 +26,7 @@ - #include - #include - #include --#include -+#include - - /* ---------- DEFINES ---------- */ - /*#define CPUFREQ_DEBUG_ENABLE*/ /* enable debugging */ -diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c -index 5bbed45..d14502c 100644 ---- a/drivers/hwmon/bcm2835-hwmon.c -+++ b/drivers/hwmon/bcm2835-hwmon.c -@@ -17,9 +17,9 @@ - #include - #include - #include -+#include - #include - #include --#include - #include - #include - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 8ec88bb..70e5086 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -40,13 +40,13 @@ - #include - #include - #include -+#include - #include - #include - - #include - - #include --#include - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - -diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c -index 85fceb5..0c556d1 100644 ---- a/drivers/thermal/bcm2835-thermal.c -+++ b/drivers/thermal/bcm2835-thermal.c -@@ -15,10 +15,10 @@ - #include - #include - #include -+#include - #include - #include - #include --#include - #include - - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 52e655a..345c15e 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -32,7 +33,6 @@ - - #include - #include --#include - - #include - #include - -From 5bb0a0c80fc46ae0edea87f97244f28fb167dfe0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 2 May 2015 09:35:07 +0200 -Subject: [PATCH 146/216] BCM270x: Remove arch driver vcio.c -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Remove the arch vcio.c driver and header file. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/vcio.h | 128 -------- - arch/arm/mach-bcm2708/vcio.c | 419 -------------------------- - arch/arm/mach-bcm2709/include/mach/vcio.h | 165 ---------- - arch/arm/mach-bcm2709/vcio.c | 484 ------------------------------ - 4 files changed, 1196 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/vcio.h - delete mode 100644 arch/arm/mach-bcm2708/vcio.c - delete mode 100644 arch/arm/mach-bcm2709/include/mach/vcio.h - delete mode 100644 arch/arm/mach-bcm2709/vcio.c - -diff --git a/arch/arm/mach-bcm2708/include/mach/vcio.h b/arch/arm/mach-bcm2708/include/mach/vcio.h -deleted file mode 100644 -index 95ad121..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/vcio.h -+++ /dev/null -@@ -1,128 +0,0 @@ --/* -- * arch/arm/mach-bcm2708/include/mach/vcio.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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. -- */ --#ifndef _MACH_BCM2708_VCIO_H --#define _MACH_BCM2708_VCIO_H -- --/* Routines to handle I/O via the VideoCore "ARM control" registers -- * (semaphores, doorbells, mailboxes) -- */ -- --/* Constants shared with the ARM identifying separate mailbox channels */ --#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ --#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ --#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ --#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ --#define MBOX_CHAN_COUNT 9 -- --enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 --}; -- --enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 --}; -- --/* Mailbox property tags */ --enum { -- VCMSG_PROPERTY_END = 0x00000000, -- VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -- VCMSG_GET_BOARD_MODEL = 0x00010001, -- VCMSG_GET_BOARD_REVISION = 0x00010002, -- VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -- VCMSG_GET_BOARD_SERIAL = 0x00010004, -- VCMSG_GET_ARM_MEMORY = 0x00010005, -- VCMSG_GET_VC_MEMORY = 0x00010006, -- VCMSG_GET_CLOCKS = 0x00010007, -- VCMSG_GET_COMMAND_LINE = 0x00050001, -- VCMSG_GET_DMA_CHANNELS = 0x00060001, -- VCMSG_GET_POWER_STATE = 0x00020001, -- VCMSG_GET_TIMING = 0x00020002, -- VCMSG_SET_POWER_STATE = 0x00028001, -- VCMSG_GET_CLOCK_STATE = 0x00030001, -- VCMSG_SET_CLOCK_STATE = 0x00038001, -- VCMSG_GET_CLOCK_RATE = 0x00030002, -- VCMSG_SET_CLOCK_RATE = 0x00038002, -- VCMSG_GET_VOLTAGE = 0x00030003, -- VCMSG_SET_VOLTAGE = 0x00038003, -- VCMSG_GET_MAX_CLOCK = 0x00030004, -- VCMSG_GET_MAX_VOLTAGE = 0x00030005, -- VCMSG_GET_TEMPERATURE = 0x00030006, -- VCMSG_GET_MIN_CLOCK = 0x00030007, -- VCMSG_GET_MIN_VOLTAGE = 0x00030008, -- VCMSG_GET_TURBO = 0x00030009, -- VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -- VCMSG_GET_STC = 0x0003000b, -- VCMSG_SET_TURBO = 0x00038009, -- VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -- VCMSG_SET_LOCK_MEM = 0x0003000d, -- VCMSG_SET_UNLOCK_MEM = 0x0003000e, -- VCMSG_SET_RELEASE_MEM = 0x0003000f, -- VCMSG_SET_EXECUTE_CODE = 0x00030010, -- VCMSG_SET_EXECUTE_QPU = 0x00030011, -- VCMSG_SET_ENABLE_QPU = 0x00030012, -- VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -- VCMSG_GET_EDID_BLOCK = 0x00030020, -- VCMSG_GET_CUSTOMER_OTP = 0x00030021, -- VCMSG_SET_CUSTOMER_OTP = 0x00038021, -- VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -- VCMSG_SET_RELEASE_BUFFER = 0x00048001, -- VCMSG_SET_BLANK_SCREEN = 0x00040002, -- VCMSG_TST_BLANK_SCREEN = 0x00044002, -- VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -- VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -- VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -- VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -- VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -- VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -- VCMSG_GET_DEPTH = 0x00040005, -- VCMSG_TST_DEPTH = 0x00044005, -- VCMSG_SET_DEPTH = 0x00048005, -- VCMSG_GET_PIXEL_ORDER = 0x00040006, -- VCMSG_TST_PIXEL_ORDER = 0x00044006, -- VCMSG_SET_PIXEL_ORDER = 0x00048006, -- VCMSG_GET_ALPHA_MODE = 0x00040007, -- VCMSG_TST_ALPHA_MODE = 0x00044007, -- VCMSG_SET_ALPHA_MODE = 0x00048007, -- VCMSG_GET_PITCH = 0x00040008, -- VCMSG_TST_PITCH = 0x00044008, -- VCMSG_SET_PITCH = 0x00048008, -- VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -- VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -- VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -- VCMSG_GET_OVERSCAN = 0x0004000a, -- VCMSG_TST_OVERSCAN = 0x0004400a, -- VCMSG_SET_OVERSCAN = 0x0004800a, -- VCMSG_GET_PALETTE = 0x0004000b, -- VCMSG_TST_PALETTE = 0x0004400b, -- VCMSG_SET_PALETTE = 0x0004800b, -- VCMSG_GET_LAYER = 0x0004000c, -- VCMSG_TST_LAYER = 0x0004400c, -- VCMSG_SET_LAYER = 0x0004800c, -- VCMSG_GET_TRANSFORM = 0x0004000d, -- VCMSG_TST_TRANSFORM = 0x0004400d, -- VCMSG_SET_TRANSFORM = 0x0004800d, -- VCMSG_TST_VSYNC = 0x0004400e, -- VCMSG_SET_VSYNC = 0x0004800e, -- VCMSG_SET_CURSOR_INFO = 0x00008010, -- VCMSG_SET_CURSOR_STATE = 0x00008011, --}; -- --extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); --extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); --extern int /*rc*/ bcm_mailbox_property(void *data, int size); -- --#endif -diff --git a/arch/arm/mach-bcm2708/vcio.c b/arch/arm/mach-bcm2708/vcio.c -deleted file mode 100644 -index c4c2bcd..0000000 ---- a/arch/arm/mach-bcm2708/vcio.c -+++ /dev/null -@@ -1,419 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/vcio.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for writing to the mailboxes, -- * semaphores, doorbells etc. that are shared between the ARM and the -- * VideoCore processor -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#define DRIVER_NAME "bcm2708_vcio" --#define DEVICE_FILE_NAME "vcio" -- --/* offsets from a mail box base address */ --#define MAIL0_RD 0x00 /* read - and next 4 words */ --#define MAIL0_POL 0x10 /* read without popping the fifo */ --#define MAIL0_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL0_STA 0x18 /* status */ --#define MAIL0_CNF 0x1C /* configuration */ --#define MAIL1_WRT 0x20 /* write - and next 4 words */ -- --#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) --#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) --#define MBOX_CHAN(msg) ((msg) & 0xf) --#define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -- --#define MBOX_MAGIC 0xd0d0c0de -- --#define MAJOR_NUM 100 --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) -- --static struct class *vcio_class; -- --struct vc_mailbox { -- void __iomem *regs; -- uint32_t msg[MBOX_CHAN_COUNT]; -- struct semaphore sema[MBOX_CHAN_COUNT]; -- uint32_t magic; --}; -- --static void mbox_init(struct vc_mailbox *mbox_out) --{ -- int i; -- -- for (i = 0; i < MBOX_CHAN_COUNT; i++) { -- mbox_out->msg[i] = 0; -- sema_init(&mbox_out->sema[i], 0); -- } -- -- /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->regs + MAIL0_CNF); -- -- mbox_out->magic = MBOX_MAGIC; --} -- --static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) -- cpu_relax(); -- -- writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); -- -- return 0; --} -- --static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) --{ -- if (mbox->magic != MBOX_MAGIC) -- return -EINVAL; -- -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- -- return 0; --} -- --static irqreturn_t mbox_irq_handler(int irq, void *dev_id) --{ -- /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *)dev_id; -- int status = readl(mbox->regs + MAIL0_STA); -- int ret = IRQ_NONE; -- -- while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->regs + MAIL0_RD); -- int chan = MBOX_CHAN(msg); -- -- if (chan < MBOX_CHAN_COUNT) { -- if (mbox->msg[chan]) { -- pr_err(DRIVER_NAME -- ": mbox chan %d overflow - drop %08x\n", -- chan, msg); -- } else { -- mbox->msg[chan] = (msg | 0xf); -- up(&mbox->sema[chan]); -- } -- } else { -- pr_err(DRIVER_NAME -- ": invalid channel selector (msg %08x)\n", msg); -- } -- ret = IRQ_HANDLED; -- status = readl(mbox->regs + MAIL0_STA); -- } -- return ret; --} -- --/* Mailbox Methods */ -- --static struct device *mbox_dev; /* we assume there's only one! */ -- --static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_write(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) --{ -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- int rc; -- -- device_lock(dev); -- rc = mbox_read(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --extern int bcm_mailbox_write(unsigned chan, uint32_t data28) --{ -- if (!mbox_dev) -- return -ENODEV; -- -- return dev_mbox_write(mbox_dev, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_write); -- --extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) --{ -- if (!mbox_dev) -- return -ENODEV; -- -- return dev_mbox_read(mbox_dev, chan, data28); --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -- --static int mbox_copy_from_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)src < TASK_SIZE) -- return copy_from_user(dst, src, size); -- -- memcpy(dst, src, size); -- -- return 0; --} -- --static int mbox_copy_to_user(void *dst, const void *src, int size) --{ -- if ((uint32_t)dst < TASK_SIZE) -- return copy_to_user(dst, src, size); -- -- memcpy(dst, src, size); -- -- return 0; --} -- --static DEFINE_MUTEX(mailbox_lock); --extern int bcm_mailbox_property(void *data, int size) --{ -- uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -- int s = 0; -- -- mutex_lock(&mailbox_lock); -- /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -- GFP_ATOMIC); -- if (mem_kern) { -- /* create the message */ -- mbox_copy_from_user(mem_kern, data, size); -- -- /* send the message */ -- wmb(); -- s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) -- s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- if (s == 0) { -- /* copy the response */ -- rmb(); -- mbox_copy_to_user(data, mem_kern, size); -- } -- dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -- } else { -- s = -ENOMEM; -- } -- if (s != 0) -- pr_err(DRIVER_NAME ": %s failed (%d)\n", __func__, s); -- -- mutex_unlock(&mailbox_lock); -- return s; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_property); -- --/* Platform Device for Mailbox */ -- --/* -- * Is the device open right now? Used to prevent -- * concurent access into the same device -- */ --static bool device_is_open; -- --/* This is called whenever a process attempts to open the device file */ --static int device_open(struct inode *inode, struct file *file) --{ -- /* We don't want to talk to two processes at the same time */ -- if (device_is_open) -- return -EBUSY; -- -- device_is_open = true; -- try_module_get(THIS_MODULE); -- -- return 0; --} -- --static int device_release(struct inode *inode, struct file *file) --{ -- /* We're now ready for our next caller */ -- device_is_open = false; -- -- module_put(THIS_MODULE); -- -- return 0; --} -- --/* -- * This function is called whenever a process tries to do an ioctl on our -- * device file. We get two extra parameters (additional to the inode and file -- * structures, which all device functions get): the number of the ioctl called -- * and the parameter given to the ioctl function. -- * -- * If the ioctl is write or read/write (meaning output is returned to the -- * calling process), the ioctl call returns the output of this function. -- * -- */ --static long device_ioctl(struct file *file, unsigned int ioctl_num, -- unsigned long ioctl_param) --{ -- unsigned size; -- -- switch (ioctl_num) { -- case IOCTL_MBOX_PROPERTY: -- /* -- * Receive a pointer to a message (in user space) and set that -- * to be the device's message. Get the parameter given to -- * ioctl by the process. -- */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof(size)); -- return bcm_mailbox_property((void *)ioctl_param, size); -- default: -- pr_err(DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -- return -EINVAL; -- } -- -- return 0; --} -- --/* Module Declarations */ -- --/* -- * This structure will hold the functions to be called -- * when a process does something to the device we -- * created. Since a pointer to this structure is kept in -- * the devices table, it can't be local to -- * init_module. NULL is for unimplemented functios. -- */ --const struct file_operations fops = { -- .unlocked_ioctl = device_ioctl, -- .open = device_open, -- .release = device_release, /* a.k.a. close */ --}; -- --static int bcm_vcio_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- struct device *vdev; -- struct vc_mailbox *mailbox; -- struct resource *res; -- int irq, ret; -- -- mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL); -- if (!mailbox) -- return -ENOMEM; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- mailbox->regs = devm_ioremap_resource(dev, res); -- if (IS_ERR(mailbox->regs)) -- return PTR_ERR(mailbox->regs); -- -- irq = platform_get_irq(pdev, 0); -- ret = devm_request_irq(dev, irq, mbox_irq_handler, -- IRQF_DISABLED | IRQF_IRQPOLL, -- dev_name(dev), mailbox); -- if (ret) { -- dev_err(dev, "Interrupt request failed %d\n", ret); -- return ret; -- } -- -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- if (ret < 0) { -- pr_err("Character device registration failed %d\n", ret); -- return ret; -- } -- -- vcio_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- pr_err("Class creation failed %d\n", ret); -- goto err_class; -- } -- -- vdev = device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -- if (IS_ERR(vdev)) { -- ret = PTR_ERR(vdev); -- pr_err("Device creation failed %d\n", ret); -- goto err_dev; -- } -- -- mbox_init(mailbox); -- platform_set_drvdata(pdev, mailbox); -- mbox_dev = dev; -- -- dev_info(dev, "mailbox at %p\n", mailbox->regs); -- -- return 0; -- --err_dev: -- class_destroy(vcio_class); --err_class: -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return ret; --} -- --static int bcm_vcio_remove(struct platform_device *pdev) --{ -- mbox_dev = NULL; -- platform_set_drvdata(pdev, NULL); -- device_destroy(vcio_class, MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- -- return 0; --} -- --static const struct of_device_id bcm_vcio_of_match_table[] = { -- { .compatible = "brcm,bcm2708-vcio", }, -- {}, --}; --MODULE_DEVICE_TABLE(of, bcm_vcio_of_match_table); -- --static struct platform_driver bcm_mbox_driver = { -- .probe = bcm_vcio_probe, -- .remove = bcm_vcio_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- .of_match_table = bcm_vcio_of_match_table, -- }, --}; -- --static int __init bcm_mbox_init(void) --{ -- return platform_driver_register(&bcm_mbox_driver); --} -- --static void __exit bcm_mbox_exit(void) --{ -- platform_driver_unregister(&bcm_mbox_driver); --} -- --arch_initcall(bcm_mbox_init); /* Initialize early */ --module_exit(bcm_mbox_exit); -- --MODULE_AUTHOR("Gray Girling"); --MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); --MODULE_LICENSE("GPL"); -diff --git a/arch/arm/mach-bcm2709/include/mach/vcio.h b/arch/arm/mach-bcm2709/include/mach/vcio.h -deleted file mode 100644 -index 8e11d67e..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/vcio.h -+++ /dev/null -@@ -1,165 +0,0 @@ --/* -- * arch/arm/mach-bcm2708/include/mach/vcio.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 _MACH_BCM2708_VCIO_H --#define _MACH_BCM2708_VCIO_H -- --/* Routines to handle I/O via the VideoCore "ARM control" registers -- * (semaphores, doorbells, mailboxes) -- */ -- --#define BCM_VCIO_DRIVER_NAME "bcm2708_vcio" -- --/* Constants shared with the ARM identifying separate mailbox channels */ --#define MBOX_CHAN_POWER 0 /* for use by the power management interface */ --#define MBOX_CHAN_FB 1 /* for use by the frame buffer */ --#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */ --#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */ --#define MBOX_CHAN_COUNT 9 -- --enum { -- VCMSG_PROCESS_REQUEST = 0x00000000 --}; --enum { -- VCMSG_REQUEST_SUCCESSFUL = 0x80000000, -- VCMSG_REQUEST_FAILED = 0x80000001 --}; --/* Mailbox property tags */ --enum { -- VCMSG_PROPERTY_END = 0x00000000, -- VCMSG_GET_FIRMWARE_REVISION = 0x00000001, -- VCMSG_GET_BOARD_MODEL = 0x00010001, -- VCMSG_GET_BOARD_REVISION = 0x00010002, -- VCMSG_GET_BOARD_MAC_ADDRESS = 0x00010003, -- VCMSG_GET_BOARD_SERIAL = 0x00010004, -- VCMSG_GET_ARM_MEMORY = 0x00010005, -- VCMSG_GET_VC_MEMORY = 0x00010006, -- VCMSG_GET_CLOCKS = 0x00010007, -- VCMSG_GET_COMMAND_LINE = 0x00050001, -- VCMSG_GET_DMA_CHANNELS = 0x00060001, -- VCMSG_GET_POWER_STATE = 0x00020001, -- VCMSG_GET_TIMING = 0x00020002, -- VCMSG_SET_POWER_STATE = 0x00028001, -- VCMSG_GET_CLOCK_STATE = 0x00030001, -- VCMSG_SET_CLOCK_STATE = 0x00038001, -- VCMSG_GET_CLOCK_RATE = 0x00030002, -- VCMSG_SET_CLOCK_RATE = 0x00038002, -- VCMSG_GET_VOLTAGE = 0x00030003, -- VCMSG_SET_VOLTAGE = 0x00038003, -- VCMSG_GET_MAX_CLOCK = 0x00030004, -- VCMSG_GET_MAX_VOLTAGE = 0x00030005, -- VCMSG_GET_TEMPERATURE = 0x00030006, -- VCMSG_GET_MIN_CLOCK = 0x00030007, -- VCMSG_GET_MIN_VOLTAGE = 0x00030008, -- VCMSG_GET_TURBO = 0x00030009, -- VCMSG_GET_MAX_TEMPERATURE = 0x0003000a, -- VCMSG_GET_STC = 0x0003000b, -- VCMSG_SET_TURBO = 0x00038009, -- VCMSG_SET_ALLOCATE_MEM = 0x0003000c, -- VCMSG_SET_LOCK_MEM = 0x0003000d, -- VCMSG_SET_UNLOCK_MEM = 0x0003000e, -- VCMSG_SET_RELEASE_MEM = 0x0003000f, -- VCMSG_SET_EXECUTE_CODE = 0x00030010, -- VCMSG_SET_EXECUTE_QPU = 0x00030011, -- VCMSG_SET_ENABLE_QPU = 0x00030012, -- VCMSG_GET_RESOURCE_HANDLE = 0x00030014, -- VCMSG_GET_EDID_BLOCK = 0x00030020, -- VCMSG_GET_CUSTOMER_OTP = 0x00030021, -- VCMSG_SET_CUSTOMER_OTP = 0x00038021, -- VCMSG_SET_ALLOCATE_BUFFER = 0x00040001, -- VCMSG_SET_RELEASE_BUFFER = 0x00048001, -- VCMSG_SET_BLANK_SCREEN = 0x00040002, -- VCMSG_TST_BLANK_SCREEN = 0x00044002, -- VCMSG_GET_PHYSICAL_WIDTH_HEIGHT = 0x00040003, -- VCMSG_TST_PHYSICAL_WIDTH_HEIGHT = 0x00044003, -- VCMSG_SET_PHYSICAL_WIDTH_HEIGHT = 0x00048003, -- VCMSG_GET_VIRTUAL_WIDTH_HEIGHT = 0x00040004, -- VCMSG_TST_VIRTUAL_WIDTH_HEIGHT = 0x00044004, -- VCMSG_SET_VIRTUAL_WIDTH_HEIGHT = 0x00048004, -- VCMSG_GET_DEPTH = 0x00040005, -- VCMSG_TST_DEPTH = 0x00044005, -- VCMSG_SET_DEPTH = 0x00048005, -- VCMSG_GET_PIXEL_ORDER = 0x00040006, -- VCMSG_TST_PIXEL_ORDER = 0x00044006, -- VCMSG_SET_PIXEL_ORDER = 0x00048006, -- VCMSG_GET_ALPHA_MODE = 0x00040007, -- VCMSG_TST_ALPHA_MODE = 0x00044007, -- VCMSG_SET_ALPHA_MODE = 0x00048007, -- VCMSG_GET_PITCH = 0x00040008, -- VCMSG_TST_PITCH = 0x00044008, -- VCMSG_SET_PITCH = 0x00048008, -- VCMSG_GET_VIRTUAL_OFFSET = 0x00040009, -- VCMSG_TST_VIRTUAL_OFFSET = 0x00044009, -- VCMSG_SET_VIRTUAL_OFFSET = 0x00048009, -- VCMSG_GET_OVERSCAN = 0x0004000a, -- VCMSG_TST_OVERSCAN = 0x0004400a, -- VCMSG_SET_OVERSCAN = 0x0004800a, -- VCMSG_GET_PALETTE = 0x0004000b, -- VCMSG_TST_PALETTE = 0x0004400b, -- VCMSG_SET_PALETTE = 0x0004800b, -- VCMSG_GET_LAYER = 0x0004000c, -- VCMSG_TST_LAYER = 0x0004400c, -- VCMSG_SET_LAYER = 0x0004800c, -- VCMSG_GET_TRANSFORM = 0x0004000d, -- VCMSG_TST_TRANSFORM = 0x0004400d, -- VCMSG_SET_TRANSFORM = 0x0004800d, -- VCMSG_TST_VSYNC = 0x0004400e, -- VCMSG_SET_VSYNC = 0x0004800e, -- VCMSG_SET_CURSOR_INFO = 0x00008010, -- VCMSG_SET_CURSOR_STATE = 0x00008011, --}; -- --extern int /*rc*/ bcm_mailbox_read(unsigned chan, uint32_t *data28); --extern int /*rc*/ bcm_mailbox_write(unsigned chan, uint32_t data28); --extern int /*rc*/ bcm_mailbox_property(void *data, int size); -- --#include -- --/* -- * The major device number. We can't rely on dynamic -- * registration any more, because ioctls need to know -- * it. -- */ --#define MAJOR_NUM 100 -- --/* -- * Set the message of the device driver -- */ --#define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *) --/* -- * _IOWR means that we're creating an ioctl command -- * number for passing information from a user process -- * to the kernel module and from the kernel module to user process -- * -- * The first arguments, MAJOR_NUM, is the major device -- * number we're using. -- * -- * The second argument is the number of the command -- * (there could be several with different meanings). -- * -- * The third argument is the type we want to get from -- * the process to the kernel. -- */ -- --/* -- * The name of the device file -- */ --#define DEVICE_FILE_NAME "vcio" -- --#endif -diff --git a/arch/arm/mach-bcm2709/vcio.c b/arch/arm/mach-bcm2709/vcio.c -deleted file mode 100644 -index 700bff4..0000000 ---- a/arch/arm/mach-bcm2709/vcio.c -+++ /dev/null -@@ -1,484 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/vcio.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for writing to the mailboxes, -- * semaphores, doorbells etc. that are shared between the ARM and the -- * VideoCore processor -- */ -- --#if defined(CONFIG_SERIAL_BCM_MBOX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) --#define SUPPORT_SYSRQ --#endif -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include --#include -- --#include -- -- --#define DRIVER_NAME BCM_VCIO_DRIVER_NAME -- --/* ---------------------------------------------------------------------- -- * Mailbox -- * -------------------------------------------------------------------- */ -- --/* offsets from a mail box base address */ --#define MAIL_WRT 0x00 /* write - and next 4 words */ --#define MAIL_RD 0x00 /* read - and next 4 words */ --#define MAIL_POL 0x10 /* read without popping the fifo */ --#define MAIL_SND 0x14 /* sender ID (bottom two bits) */ --#define MAIL_STA 0x18 /* status */ --#define MAIL_CNF 0x1C /* configuration */ -- --#define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) --#define MBOX_MSG_LSB(chan, data28) (((data28) << 4) | ((chan) & 0xf)) --#define MBOX_CHAN(msg) ((msg) & 0xf) --#define MBOX_DATA28(msg) ((msg) & ~0xf) --#define MBOX_DATA28_LSB(msg) (((uint32_t)msg) >> 4) -- --#define MBOX_MAGIC 0xd0d0c0de --static struct class *vcio_class = NULL; --struct vc_mailbox { -- struct device *dev; /* parent device */ -- void __iomem *status; -- void __iomem *config; -- void __iomem *read; -- void __iomem *write; -- uint32_t msg[MBOX_CHAN_COUNT]; -- struct semaphore sema[MBOX_CHAN_COUNT]; -- uint32_t magic; --}; -- --static void mbox_init(struct vc_mailbox *mbox_out, struct device *dev, -- uint32_t addr_mbox) --{ -- int i; -- -- mbox_out->dev = dev; -- mbox_out->status = __io_address(addr_mbox + MAIL_STA); -- mbox_out->config = __io_address(addr_mbox + MAIL_CNF); -- mbox_out->read = __io_address(addr_mbox + MAIL_RD); -- /* Write to the other mailbox */ -- mbox_out->write = -- __io_address((addr_mbox ^ ARM_0_MAIL0_WRT ^ ARM_0_MAIL1_WRT) + -- MAIL_WRT); -- -- for (i = 0; i < MBOX_CHAN_COUNT; i++) { -- mbox_out->msg[i] = 0; -- sema_init(&mbox_out->sema[i], 0); -- } -- -- /* Enable the interrupt on data reception */ -- writel(ARM_MC_IHAVEDATAIRQEN, mbox_out->config); -- -- mbox_out->magic = MBOX_MAGIC; --} -- --static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) --{ -- int rc; -- -- if (mbox->magic != MBOX_MAGIC) -- rc = -EINVAL; -- else { -- /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->status) & ARM_MS_FULL)) -- cpu_relax(); -- -- writel(MBOX_MSG(chan, data28), mbox->write); -- rc = 0; -- } -- return rc; --} -- --static int mbox_read(struct vc_mailbox *mbox, unsigned chan, uint32_t *data28) --{ -- int rc; -- -- if (mbox->magic != MBOX_MAGIC) -- rc = -EINVAL; -- else { -- down(&mbox->sema[chan]); -- *data28 = MBOX_DATA28(mbox->msg[chan]); -- mbox->msg[chan] = 0; -- rc = 0; -- } -- return rc; --} -- --static irqreturn_t mbox_irq(int irq, void *dev_id) --{ -- /* wait for the mailbox FIFO to have some data in it */ -- struct vc_mailbox *mbox = (struct vc_mailbox *) dev_id; -- int status = readl(mbox->status); -- int ret = IRQ_NONE; -- -- while (!(status & ARM_MS_EMPTY)) { -- uint32_t msg = readl(mbox->read); -- int chan = MBOX_CHAN(msg); -- if (chan < MBOX_CHAN_COUNT) { -- if (mbox->msg[chan]) { -- /* Overflow */ -- printk(KERN_ERR DRIVER_NAME -- ": mbox chan %d overflow - drop %08x\n", -- chan, msg); -- } else { -- mbox->msg[chan] = (msg | 0xf); -- up(&mbox->sema[chan]); -- } -- } else { -- printk(KERN_ERR DRIVER_NAME -- ": invalid channel selector (msg %08x)\n", msg); -- } -- ret = IRQ_HANDLED; -- status = readl(mbox->status); -- } -- return ret; --} -- --static struct irqaction mbox_irqaction = { -- .name = "ARM Mailbox IRQ", -- .flags = IRQF_DISABLED | IRQF_IRQPOLL, -- .handler = mbox_irq, --}; -- --/* ---------------------------------------------------------------------- -- * Mailbox Methods -- * -------------------------------------------------------------------- */ -- --static struct device *mbox_dev; /* we assume there's only one! */ -- --static int dev_mbox_write(struct device *dev, unsigned chan, uint32_t data28) --{ -- int rc; -- -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- device_lock(dev); -- rc = mbox_write(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --static int dev_mbox_read(struct device *dev, unsigned chan, uint32_t *data28) --{ -- int rc; -- -- struct vc_mailbox *mailbox = dev_get_drvdata(dev); -- device_lock(dev); -- rc = mbox_read(mailbox, chan, data28); -- device_unlock(dev); -- -- return rc; --} -- --extern int bcm_mailbox_write(unsigned chan, uint32_t data28) --{ -- if (mbox_dev) -- return dev_mbox_write(mbox_dev, chan, data28); -- else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_write); -- --extern int bcm_mailbox_read(unsigned chan, uint32_t *data28) --{ -- if (mbox_dev) -- return dev_mbox_read(mbox_dev, chan, data28); -- else -- return -ENODEV; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_read); -- --static void dev_mbox_register(const char *dev_name, struct device *dev) --{ -- mbox_dev = dev; --} -- --static int mbox_copy_from_user(void *dst, const void *src, int size) --{ -- if ( (uint32_t)src < TASK_SIZE) -- { -- return copy_from_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } --} -- --static int mbox_copy_to_user(void *dst, const void *src, int size) --{ -- if ( (uint32_t)dst < TASK_SIZE) -- { -- return copy_to_user(dst, src, size); -- } -- else -- { -- memcpy( dst, src, size ); -- return 0; -- } --} -- --static DEFINE_MUTEX(mailbox_lock); --extern int bcm_mailbox_property(void *data, int size) --{ -- uint32_t success; -- dma_addr_t mem_bus; /* the memory address accessed from videocore */ -- void *mem_kern; /* the memory address accessed from driver */ -- int s = 0; -- -- mutex_lock(&mailbox_lock); -- /* allocate some memory for the messages communicating with GPU */ -- mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, GFP_ATOMIC); -- if (mem_kern) { -- /* create the message */ -- mbox_copy_from_user(mem_kern, data, size); -- -- /* send the message */ -- wmb(); -- s = bcm_mailbox_write(MBOX_CHAN_PROPERTY, (uint32_t)mem_bus); -- if (s == 0) { -- s = bcm_mailbox_read(MBOX_CHAN_PROPERTY, &success); -- } -- if (s == 0) { -- /* copy the response */ -- rmb(); -- mbox_copy_to_user(data, mem_kern, size); -- } -- dma_free_coherent(NULL, PAGE_ALIGN(size), mem_kern, mem_bus); -- } else { -- s = -ENOMEM; -- } -- if (s != 0) -- printk(KERN_ERR DRIVER_NAME ": %s failed (%d)\n", __func__, s); -- -- mutex_unlock(&mailbox_lock); -- return s; --} --EXPORT_SYMBOL_GPL(bcm_mailbox_property); -- --/* ---------------------------------------------------------------------- -- * Platform Device for Mailbox -- * -------------------------------------------------------------------- */ -- --/* -- * Is the device open right now? Used to prevent -- * concurent access into the same device -- */ --static int Device_Open = 0; -- --/* -- * This is called whenever a process attempts to open the device file -- */ --static int device_open(struct inode *inode, struct file *file) --{ -- /* -- * We don't want to talk to two processes at the same time -- */ -- if (Device_Open) -- return -EBUSY; -- -- Device_Open++; -- /* -- * Initialize the message -- */ -- try_module_get(THIS_MODULE); -- return 0; --} -- --static int device_release(struct inode *inode, struct file *file) --{ -- /* -- * We're now ready for our next caller -- */ -- Device_Open--; -- -- module_put(THIS_MODULE); -- return 0; --} -- --/* -- * This function is called whenever a process tries to do an ioctl on our -- * device file. We get two extra parameters (additional to the inode and file -- * structures, which all device functions get): the number of the ioctl called -- * and the parameter given to the ioctl function. -- * -- * If the ioctl is write or read/write (meaning output is returned to the -- * calling process), the ioctl call returns the output of this function. -- * -- */ --static long device_ioctl(struct file *file, /* see include/linux/fs.h */ -- unsigned int ioctl_num, /* number and param for ioctl */ -- unsigned long ioctl_param) --{ -- unsigned size; -- /* -- * Switch according to the ioctl called -- */ -- switch (ioctl_num) { -- case IOCTL_MBOX_PROPERTY: -- /* -- * Receive a pointer to a message (in user space) and set that -- * to be the device's message. Get the parameter given to -- * ioctl by the process. -- */ -- mbox_copy_from_user(&size, (void *)ioctl_param, sizeof size); -- return bcm_mailbox_property((void *)ioctl_param, size); -- break; -- default: -- printk(KERN_ERR DRIVER_NAME "unknown ioctl: %d\n", ioctl_num); -- return -EINVAL; -- } -- -- return 0; --} -- --/* Module Declarations */ -- --/* -- * This structure will hold the functions to be called -- * when a process does something to the device we -- * created. Since a pointer to this structure is kept in -- * the devices table, it can't be local to -- * init_module. NULL is for unimplemented functios. -- */ --struct file_operations fops = { -- .unlocked_ioctl = device_ioctl, -- .open = device_open, -- .release = device_release, /* a.k.a. close */ --}; -- --static int bcm_vcio_probe(struct platform_device *pdev) --{ -- int ret = 0; -- struct vc_mailbox *mailbox; -- -- mailbox = kzalloc(sizeof(*mailbox), GFP_KERNEL); -- if (NULL == mailbox) { -- printk(KERN_ERR DRIVER_NAME ": failed to allocate " -- "mailbox memory\n"); -- ret = -ENOMEM; -- } else { -- struct resource *res; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (res == NULL) { -- printk(KERN_ERR DRIVER_NAME ": failed to obtain memory " -- "resource\n"); -- ret = -ENODEV; -- kfree(mailbox); -- } else { -- /* should be based on the registers from res really */ -- mbox_init(mailbox, &pdev->dev, ARM_0_MAIL0_RD); -- -- platform_set_drvdata(pdev, mailbox); -- dev_mbox_register(DRIVER_NAME, &pdev->dev); -- -- mbox_irqaction.dev_id = mailbox; -- setup_irq(IRQ_ARM_MAILBOX, &mbox_irqaction); -- printk(KERN_INFO DRIVER_NAME ": mailbox at %p\n", -- __io_address(ARM_0_MAIL0_RD)); -- } -- } -- -- if (ret == 0) { -- /* -- * Register the character device -- */ -- ret = register_chrdev(MAJOR_NUM, DEVICE_FILE_NAME, &fops); -- -- /* -- * Negative values signify an error -- */ -- if (ret < 0) { -- printk(KERN_ERR DRIVER_NAME -- "Failed registering the character device %d\n", ret); -- return ret; -- } -- vcio_class = class_create(THIS_MODULE, BCM_VCIO_DRIVER_NAME); -- if (IS_ERR(vcio_class)) { -- ret = PTR_ERR(vcio_class); -- return ret ; -- } -- device_create(vcio_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, -- "vcio"); -- } -- return ret; --} -- --static int bcm_vcio_remove(struct platform_device *pdev) --{ -- struct vc_mailbox *mailbox = platform_get_drvdata(pdev); -- -- platform_set_drvdata(pdev, NULL); -- kfree(mailbox); -- -- return 0; --} -- --static struct platform_driver bcm_mbox_driver = { -- .probe = bcm_vcio_probe, -- .remove = bcm_vcio_remove, -- -- .driver = { -- .name = DRIVER_NAME, -- .owner = THIS_MODULE, -- }, --}; -- --static int __init bcm_mbox_init(void) --{ -- int ret; -- -- printk(KERN_INFO "mailbox: Broadcom VideoCore Mailbox driver\n"); -- -- ret = platform_driver_register(&bcm_mbox_driver); -- if (ret != 0) { -- printk(KERN_ERR DRIVER_NAME ": failed to register " -- "on platform\n"); -- } -- -- return ret; --} -- --static void __exit bcm_mbox_exit(void) --{ -- device_destroy(vcio_class,MKDEV(MAJOR_NUM, 0)); -- class_destroy(vcio_class); -- unregister_chrdev(MAJOR_NUM, DEVICE_FILE_NAME); -- platform_driver_unregister(&bcm_mbox_driver); --} -- --arch_initcall(bcm_mbox_init); /* Initialize early */ --module_exit(bcm_mbox_exit); -- --MODULE_AUTHOR("Gray Girling"); --MODULE_DESCRIPTION("ARM I/O to VideoCore processor"); --MODULE_LICENSE("GPL"); --MODULE_ALIAS("platform:bcm-mbox"); - -From ca452e4734877d6b36d1a836d473b81f3d561c3f Mon Sep 17 00:00:00 2001 + CONFIG_EXT2_FS_POSIX_ACL=y +@@ -107,18 +1073,110 @@ CONFIG_EXT3_FS=y + CONFIG_EXT3_FS_POSIX_ACL=y + 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_QFMT_V1=m ++CONFIG_QFMT_V2=m ++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_NTFS_RW=y + CONFIG_TMPFS=y + CONFIG_TMPFS_POSIX_ACL=y +-# CONFIG_MISC_FILESYSTEMS is not set ++CONFIG_CONFIGFS_FS=y ++CONFIG_ECRYPT_FS=m ++CONFIG_HFS_FS=m ++CONFIG_HFSPLUS_FS=m ++CONFIG_SQUASHFS=m ++CONFIG_SQUASHFS_XATTR=y ++CONFIG_SQUASHFS_LZO=y ++CONFIG_SQUASHFS_XZ=y ++CONFIG_F2FS_FS=y + CONFIG_NFS_FS=y +-CONFIG_NFSD=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFS_FSCACHE=y ++CONFIG_NFSD=m ++CONFIG_NFSD_V3_ACL=y ++CONFIG_NFSD_V4=y ++CONFIG_CIFS=m ++CONFIG_CIFS_WEAK_PW_HASH=y ++CONFIG_CIFS_UPCALL=y ++CONFIG_CIFS_XATTR=y ++CONFIG_CIFS_POSIX=y ++CONFIG_9P_FS=m ++CONFIG_9P_FS_POSIX_ACL=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=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=y ++CONFIG_DLM=m + CONFIG_PRINTK_TIME=y + CONFIG_BOOT_PRINTK_DELAY=y + CONFIG_DYNAMIC_DEBUG=y +@@ -128,14 +1186,38 @@ CONFIG_DEBUG_INFO=y + CONFIG_UNUSED_SYMBOLS=y + CONFIG_DEBUG_MEMORY_INIT=y + CONFIG_LOCKUP_DETECTOR=y ++CONFIG_TIMER_STATS=y ++# CONFIG_DEBUG_PREEMPT is not set ++CONFIG_LATENCYTOP=y ++CONFIG_IRQSOFF_TRACER=y + CONFIG_SCHED_TRACER=y + CONFIG_STACK_TRACER=y ++CONFIG_BLK_DEV_IO_TRACE=y ++# CONFIG_KPROBE_EVENT is not set + CONFIG_FUNCTION_PROFILER=y + CONFIG_TEST_KSTRTOX=y + CONFIG_KGDB=y + CONFIG_KGDB_KDB=y ++CONFIG_KDB_KEYBOARD=y + CONFIG_STRICT_DEVMEM=y + CONFIG_DEBUG_LL=y + CONFIG_EARLY_PRINTK=y ++CONFIG_CRYPTO_USER=m ++CONFIG_CRYPTO_CRYPTD=m ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_CTS=m ++CONFIG_CRYPTO_XTS=m ++CONFIG_CRYPTO_XCBC=m ++CONFIG_CRYPTO_SHA1_ARM=m ++CONFIG_CRYPTO_SHA512=m ++CONFIG_CRYPTO_TGR192=m ++CONFIG_CRYPTO_WP512=m ++CONFIG_CRYPTO_AES_ARM=m ++CONFIG_CRYPTO_CAST5=m ++CONFIG_CRYPTO_DES=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_ITU_T=y ++CONFIG_LIBCRC32C=y + # CONFIG_XZ_DEC_ARM is not set + # CONFIG_XZ_DEC_ARMTHUMB is not set + +From 4e2ed4a7a7971ea763017bc6234d30cdc5bfb984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Fri, 1 May 2015 23:00:15 +0200 -Subject: [PATCH 147/216] BCM270x_DT: Add mailbox bcm2708-vcio +Subject: [PATCH 69/77] BCM270x_DT: Add mailbox bcm2708-vcio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -140552,193 +132264,41 @@ platform device when booting in DT mode. Signed-off-by: Noralf Trønnes --- - arch/arm/boot/dts/bcm2708_common.dtsi | 6 ++++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 3 files changed, 8 insertions(+), 2 deletions(-) + arch/arm/mach-bcm2708/bcm2708.c | 2 +- + arch/arm/mach-bcm2709/bcm2709.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 065a424..1c8c1af 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -36,6 +36,12 @@ - #interrupt-cells = <2>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - gpio: gpio { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 51f8efa..7cc47c1 100644 +index e42f5a5..de2f93a 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -908,7 +908,7 @@ void __init bcm2708_init(void) +@@ -870,7 +870,7 @@ void __init bcm2708_init(void) bcm2708_dt_init(); bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); - #endif diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 8ed88b4..2c0a664 100644 +index 95223ff..350647a 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -929,7 +929,7 @@ void __init bcm2709_init(void) +@@ -890,7 +890,7 @@ void __init bcm2709_init(void) bcm2709_dt_init(); bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vcio_device); + bcm_register_device_dt(&bcm2708_vchiq_device); #ifdef CONFIG_BCM2708_GPIO bcm_register_device_dt(&bcm2708_gpio_device); - #endif -From 8cb40db6e93540a4cf0d45ee23eb9b0441050543 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 23:00:45 +0200 -Subject: [PATCH 148/216] bcm2835: bcm2835_defconfig enable BCM2708_MBOX -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enable the mailbox driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index cf2e7a6..26b4c75 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -99,6 +99,8 @@ CONFIG_LEDS_TRIGGER_CAMERA=y - CONFIG_DMADEVICES=y - CONFIG_DMA_BCM2708=y - CONFIG_STAGING=y -+CONFIG_MAILBOX=y -+CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - -From c03f517d41d6da89f70794d6bf20974e81ac72f1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 1 May 2015 23:02:46 +0200 -Subject: [PATCH 149/216] bcm2835: Add mailbox bcm2708-vcio to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add mailbox to Device Tree. There are no kernel users yet, -but it's available to userspace. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index f2dec21..06cba29 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -60,6 +60,12 @@ - reg = <0x7e104000 0x10>; - }; - -+ mailbox: mailbox@7e00b800 { -+ compatible = "brcm,bcm2708-vcio"; -+ reg = <0x7e00b880 0x40>; -+ interrupts = <0 1>; -+ }; -+ - gpio: gpio@7e200000 { - compatible = "brcm,bcm2835-gpio"; - reg = <0x7e200000 0xb4>; - -From 2010049aa53c210156598c979fd38dc893baa049 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 12 May 2015 11:48:18 +0200 -Subject: [PATCH 150/216] mailbox: bcm2708-vcio: Allocation does not need to be - atomic -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -No need to do atomic allocation in a context that can sleep. - -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/bcm2708-vcio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index ee3e778..74a7fcb 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -212,7 +212,7 @@ extern int bcm_mailbox_property(void *data, int size) - mutex_lock(&mailbox_lock); - /* allocate some memory for the messages communicating with GPU */ - mem_kern = dma_alloc_coherent(NULL, PAGE_ALIGN(size), &mem_bus, -- GFP_ATOMIC); -+ GFP_KERNEL); - if (mem_kern) { - /* create the message */ - mbox_copy_from_user(mem_kern, data, size); - -From f86559819816a393e05426b6dac30d84582fa13d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 12 May 2015 13:45:32 +0200 -Subject: [PATCH 151/216] mailbox: bcm2708-vcio: Check the correct status - register before writing -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With the VC reader blocked and the ARM writing, MAIL0_STA reads -empty permanently while MAIL1_STA goes from empty (0x40000000) -to non-empty (0x00000001-0x00000007) to full (0x80000008). - -Suggested-by: Phil Elwell -Signed-off-by: Noralf Trønnes ---- - drivers/mailbox/bcm2708-vcio.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/mailbox/bcm2708-vcio.c b/drivers/mailbox/bcm2708-vcio.c -index 74a7fcb..19ecfe8 100644 ---- a/drivers/mailbox/bcm2708-vcio.c -+++ b/drivers/mailbox/bcm2708-vcio.c -@@ -35,6 +35,7 @@ - #define MAIL0_STA 0x18 /* status */ - #define MAIL0_CNF 0x1C /* configuration */ - #define MAIL1_WRT 0x20 /* write - and next 4 words */ -+#define MAIL1_STA 0x38 /* status */ - - /* On MACH_BCM270x these come through (arm_control.h ) */ - #ifndef ARM_MS_EMPTY -@@ -85,7 +86,7 @@ static int mbox_write(struct vc_mailbox *mbox, unsigned chan, uint32_t data28) - return -EINVAL; - - /* wait for the mailbox FIFO to have some space in it */ -- while (0 != (readl(mbox->regs + MAIL0_STA) & ARM_MS_FULL)) -+ while (0 != (readl(mbox->regs + MAIL1_STA) & ARM_MS_FULL)) - cpu_relax(); - - writel(MBOX_MSG(chan, data28), mbox->regs + MAIL1_WRT); - -From 94bbfc4066df94c006edec5a48fe4df6547a1b01 Mon Sep 17 00:00:00 2001 +From 2867da0a54803e6eb8e748b63a474877e16899b0 Mon Sep 17 00:00:00 2001 From: Gordon Hollingworth Date: Tue, 12 May 2015 14:47:56 +0100 -Subject: [PATCH 152/216] rpi-ft5406: Add touchscreen driver for pi LCD display +Subject: [PATCH 70/77] rpi-ft5406: Add touchscreen driver for pi LCD display --- drivers/input/touchscreen/Kconfig | 7 + @@ -140749,10 +132309,10 @@ Subject: [PATCH 152/216] rpi-ft5406: Add touchscreen driver for pi LCD display create mode 100644 drivers/input/touchscreen/rpi-ft5406.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig -index 6261fd6..e7e9416 100644 +index 80f6386..5848562 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig -@@ -557,6 +557,13 @@ config TOUCHSCREEN_EDT_FT5X06 +@@ -583,6 +583,13 @@ config TOUCHSCREEN_EDT_FT5X06 To compile this driver as a module, choose M here: the module will be called edt-ft5x06. @@ -140767,10 +132327,10 @@ index 6261fd6..e7e9416 100644 tristate "Renesas MIGO-R touchscreen" depends on SH_MIGOR && I2C diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile -index 0242fea..e0268f0 100644 +index 44deea7..a1be09f 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile -@@ -28,6 +28,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o +@@ -29,6 +29,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o @@ -141055,1985 +132615,10 @@ index cc284ed..d3ea839 100644 VCMSG_SET_CURSOR_STATE = 0x00008011, }; -From 7a6f093876247b186c1465ef0f45132b0c804af2 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 7 May 2015 09:22:23 +0100 -Subject: [PATCH 153/216] bcm2835-sdhost: Error handling fix, and code - clarification - ---- - drivers/mmc/host/bcm2835-sdhost.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 0c311b5..542ae12 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -1041,13 +1041,14 @@ static u32 bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask) - host->cmd->error = -EILSEQ; - - /* Use the block interrupt for writes after the first block */ -- if (!(host->data->flags & MMC_DATA_READ)) { -+ if (host->data->flags & MMC_DATA_WRITE) { - host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); - host->hcfg |= SDHCFG_BLOCK_IRPT_EN; - bcm2835_sdhost_write(host, host->hcfg, SDHCFG); - if (host->data->error) - bcm2835_sdhost_finish_data(host); -- bcm2835_sdhost_transfer_pio(host); -+ else -+ bcm2835_sdhost_transfer_pio(host); - } else { - if (!host->data->error) { - bcm2835_sdhost_transfer_pio(host); -@@ -1132,12 +1133,12 @@ static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id) - bcm2835_sdhost_dumpregs(host); - } - -- if (loops) -- early |= handled; -- - if (!handled) - break; - -+ if (loops) -+ early |= handled; -+ - result = IRQ_HANDLED; - - /* Clear all interrupts and notifications */ - -From d502512774e7121bd6787008f5956daefa3ac138 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 14 May 2015 11:48:40 +0100 -Subject: [PATCH 154/216] bcm2835-sdhost: Adding overclocking option - -Allow a different clock speed to be substitued for a requested 50MHz. -This option is exposed using the "overclock_50" DT parameter. -Note that the sdhost interface is restricted to integer divisions of -core_freq, and the highest sensible option for a core_freq of 250MHz -is 84 (250/3 = 83.3MHz), the next being 125 (250/2) which is much too -high. - -Use at your own risk. ---- - arch/arm/boot/dts/sdhost-overlay.dts | 6 ++++-- - drivers/mmc/host/bcm2835-sdhost.c | 17 +++++++++++++++-- - 2 files changed, 19 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/boot/dts/sdhost-overlay.dts b/arch/arm/boot/dts/sdhost-overlay.dts -index 33db96e..b2653e9 100644 ---- a/arch/arm/boot/dts/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/sdhost-overlay.dts -@@ -13,14 +13,15 @@ - sdhost: sdhost@7e202000 { - compatible = "brcm,bcm2835-sdhost"; - reg = <0x7e202000 0x100>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; - interrupts = <2 24>; - clocks = <&clk_sdhost>; - dmas = <&dma 13>, - <&dma 13>; - dma-names = "tx", "rx"; - brcm,delay-after-stop = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_pins>; -+ brcm,overclock-50 = <0>; - status = "okay"; - }; - -@@ -67,6 +68,7 @@ - - __overrides__ { - delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; - force_pio = <&sdhost>,"brcm,force-pio?"; - sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - }; -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 542ae12..2a9eb9f 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -184,6 +184,7 @@ struct bcm2835_host { - int max_delay; /* maximum length of time spent waiting */ - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ -+ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - }; - - -@@ -1223,6 +1224,10 @@ static irqreturn_t bcm2835_sdhost_thread_irq(int irq, void *dev_id) - void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - { - int div = 0; /* Initialized for compiler warning */ -+ unsigned int input_clock = clock; -+ -+ if (host->overclock_50 && (clock == 50000000)) -+ clock = host->overclock_50 * 1000000; - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1266,13 +1271,18 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - if (div > SDCDIV_MAX_CDIV) - div = SDCDIV_MAX_CDIV; - -- host->mmc->actual_clock = host->max_clk / (div + 2); -+ clock = host->max_clk / (div + 2); -+ host->mmc->actual_clock = clock; -+ -+ if (clock > input_clock) -+ pr_warn("%s: Overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); - - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - - pr_debug(DRIVER_NAME ": clock=%d -> max_clk=%d, cdiv=%x (actual clock %d)\n", -- clock, host->max_clk, host->cdiv, host->mmc->actual_clock); -+ input_clock, host->max_clk, host->cdiv, host->mmc->actual_clock); - } - - static void bcm2835_sdhost_request(struct mmc_host *mmc, struct mmc_request *mrq) -@@ -1572,6 +1582,9 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) - of_property_read_u32(node, - "brcm,delay-after-stop", - &host->delay_after_stop); -+ of_property_read_u32(node, -+ "brcm,overclock-50", -+ &host->overclock_50); - host->allow_dma = ALLOW_DMA && - !of_property_read_bool(node, "brcm,force-pio"); - } - -From ae7169ee054f60e3db61f1a5bb6eb1f52913886a Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 14 May 2015 11:55:57 +0100 -Subject: [PATCH 155/216] bcm2835-mmc: Adding overclocking option - -Allow a different clock speed to be substitued for a requested 50MHz. -This option is exposed using the "overclock_50" DT parameter. -Note that the mmc interface is restricted to EVEN integer divisions of -250MHz, and the highest sensible option is 63 (250/4 = 62.5), the -next being 125 (250/2) which is much too high. - -Use at your own risk. ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/mmc-overlay.dts | 19 +++++++++++++++++++ - drivers/mmc/host/bcm2835-mmc.c | 25 ++++++++++++++++++++++--- - 3 files changed, 42 insertions(+), 3 deletions(-) - create mode 100644 arch/arm/boot/dts/mmc-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 9cb5a2d..a21afc5 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -27,6 +27,7 @@ dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb -diff --git a/arch/arm/boot/dts/mmc-overlay.dts b/arch/arm/boot/dts/mmc-overlay.dts -new file mode 100644 -index 0000000..0a37cf4 ---- /dev/null -+++ b/arch/arm/boot/dts/mmc-overlay.dts -@@ -0,0 +1,19 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&mmc>; -+ -+ __overlay__ { -+ brcm,overclock-50 = <0>; -+ }; -+ }; -+ -+ __overrides__ { -+ overclock_50 = <&mmc>,"brcm,overclock-50:0"; -+ force_pio = <&mmc>,"brcm,force-pio?"; -+ }; -+}; -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index 68314d5..c7c2ca1 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -131,6 +131,8 @@ struct bcm2835_host { - #define SDHCI_AUTO_CMD12 (1<<6) /* Auto CMD12 support */ - #define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */ - #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ -+ -+ u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ - }; - - -@@ -1086,7 +1088,10 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - int real_div = div, clk_mul = 1; - u16 clk = 0; - unsigned long timeout; -+ unsigned int input_clock = clock; - -+ if (host->overclock_50 && (clock == 50000000)) -+ clock = host->overclock_50 * 1000000; - - host->mmc->actual_clock = 0; - -@@ -1110,7 +1115,12 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - div >>= 1; - - if (real_div) -- host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; -+ clock = (host->max_clk * clk_mul) / real_div; -+ host->mmc->actual_clock = clock; -+ -+ if (clock > input_clock) -+ pr_warn("%s: Overclocking to %dHz\n", -+ mmc_hostname(host->mmc), clock); - - clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; - clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) -@@ -1177,6 +1187,9 @@ static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) - u8 ctrl; - u16 clk, ctrl_2; - -+ pr_debug("bcm2835_mmc_set_ios: clock %d, pwr %d, bus_width %d, timing %d, vdd %d, drv_type %d\n", -+ ios->clock, ios->power_mode, ios->bus_width, -+ ios->timing, ios->signal_voltage, ios->drv_type); - - spin_lock_irqsave(&host->lock, flags); - -@@ -1444,10 +1457,16 @@ static int bcm2835_mmc_probe(struct platform_device *pdev) - goto err; - } - -- if (node) -+ if (node) { - mmc_of_parse(mmc); -- else -+ -+ /* Read any custom properties */ -+ of_property_read_u32(node, -+ "brcm,overclock-50", -+ &host->overclock_50); -+ } else { - mmc->caps |= MMC_CAP_4_BIT_DATA; -+ } - - ret = bcm2835_mmc_add_host(host); - if (ret) - -From 4b4b9568bc6fbfc222d59a28b2727ae5c725a92a Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Fri, 15 May 2015 14:21:32 +0200 -Subject: [PATCH 156/216] dmaengine: bcm2708: set residue_granularity field - -bcm2708-dmaengine supports residue reporting at burst level -but didn't report this via the residue_granularity field. - -Without this field set properly we get playback issues with I2S cards. ---- - drivers/dma/bcm2708-dmaengine.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/drivers/dma/bcm2708-dmaengine.c b/drivers/dma/bcm2708-dmaengine.c -index 937fd60..987ed53 100644 ---- a/drivers/dma/bcm2708-dmaengine.c -+++ b/drivers/dma/bcm2708-dmaengine.c -@@ -1112,6 +1112,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -+ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; - od->ddev.dev = &pdev->dev; - INIT_LIST_HEAD(&od->ddev.channels); - spin_lock_init(&od->lock); -@@ -1180,6 +1181,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev) - od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); - od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); -+ od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; - od->ddev.dev = &pdev->dev; - INIT_LIST_HEAD(&od->ddev.channels); - spin_lock_init(&od->lock); - -From 1ddcc631437e913995361718209077d8247c10b0 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 12 May 2015 17:26:35 +0100 -Subject: [PATCH 157/216] BCM2708_DT: Adding starter Compute Module DTS files - ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 7 +++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 30 ++++++++++++++++++++++++++++++ - 3 files changed, 38 insertions(+) - create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dts - create mode 100755 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index a21afc5..f3558df 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -3,6 +3,7 @@ ifeq ($(CONFIG_OF),y) - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb - dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb -+dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb - - # Raspberry Pi - ifeq ($(CONFIG_BCM2708_DT),y) -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -new file mode 100755 -index 0000000..45f8244 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -0,0 +1,7 @@ -+/dts-v1/; -+ -+/include/ "bcm2708-rpi-cm.dtsi" -+ -+/ { -+ model = "Raspberry Pi Compute Module"; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -new file mode 100755 -index 0000000..d0a6fb8 ---- /dev/null -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -0,0 +1,30 @@ -+/include/ "bcm2708.dtsi" -+ -+/ { -+ aliases { -+ soc = &soc; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ sound = &sound; -+ }; -+ -+ sound: sound { -+ }; -+}; -+ -+&leds { -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; -+ gpios = <&gpio 47 0>; -+ }; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ }; -+}; - -From 210157c8363fc0ac4c99273d3ed8f54ed9929b0f Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 May 2015 11:57:29 +0100 -Subject: [PATCH 158/216] bcm2835-sdhost: Round up the overclock, so 62 works - for 62.5Mhz - -Also only warn once for each overclock setting. ---- - drivers/mmc/host/bcm2835-sdhost.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c -index 2a9eb9f..eef8a24 100644 ---- a/drivers/mmc/host/bcm2835-sdhost.c -+++ b/drivers/mmc/host/bcm2835-sdhost.c -@@ -185,6 +185,7 @@ struct bcm2835_host { - struct timeval stop_time; /* when the last stop was issued */ - u32 delay_after_stop; /* minimum time between stop and subsequent data transfer */ - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -+ u32 max_overclock; /* Highest reported */ - }; - - -@@ -1227,7 +1228,7 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - unsigned int input_clock = clock; - - if (host->overclock_50 && (clock == 50000000)) -- clock = host->overclock_50 * 1000000; -+ clock = host->overclock_50 * 1000000 + 999999; - - /* The SDCDIV register has 11 bits, and holds (div - 2). - But in data mode the max is 50MHz wihout a minimum, and only the -@@ -1274,9 +1275,11 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = host->max_clk / (div + 2); - host->mmc->actual_clock = clock; - -- if (clock > input_clock) -+ if ((clock > input_clock) && (clock > host->max_overclock)) { - pr_warn("%s: Overclocking to %dHz\n", - mmc_hostname(host->mmc), clock); -+ host->max_overclock = clock; -+ } - - host->cdiv = div; - bcm2835_sdhost_write(host, host->cdiv, SDCDIV); - -From a946e70fd45a1f24f99816f72f5bbb0a7de0c1f3 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 May 2015 12:29:42 +0100 -Subject: [PATCH 159/216] bcm2835-mmc: Round up the overclock, so 62 works for - 62.5Mhz - -Also only warn once for each overclock setting. ---- - drivers/mmc/host/bcm2835-mmc.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c -index c7c2ca1..b7c4883 100644 ---- a/drivers/mmc/host/bcm2835-mmc.c -+++ b/drivers/mmc/host/bcm2835-mmc.c -@@ -133,6 +133,7 @@ struct bcm2835_host { - #define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */ - - u32 overclock_50; /* frequency to use when 50MHz is requested (in MHz) */ -+ u32 max_overclock; /* Highest reported */ - }; - - -@@ -1091,7 +1092,7 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - unsigned int input_clock = clock; - - if (host->overclock_50 && (clock == 50000000)) -- clock = host->overclock_50 * 1000000; -+ clock = host->overclock_50 * 1000000 + 999999; - - host->mmc->actual_clock = 0; - -@@ -1118,9 +1119,11 @@ void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock) - clock = (host->max_clk * clk_mul) / real_div; - host->mmc->actual_clock = clock; - -- if (clock > input_clock) -+ if ((clock > input_clock) && (clock > host->max_overclock)) { - pr_warn("%s: Overclocking to %dHz\n", - mmc_hostname(host->mmc), clock); -+ host->max_overclock = clock; -+ } - - clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; - clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) - -From f80dd3188715edaa5c23e3d99793170aa7dbd877 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 18 May 2015 13:05:27 +0100 -Subject: [PATCH 160/216] BCM2708_DT: Add missing CM aliases - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index d0a6fb8..8340c1e 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -3,6 +3,10 @@ - / { - aliases { - soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; - gpio = &gpio; - intc = &intc; - leds = &leds; - -From 90c3a2ff9838fdf619c6f391c27ce2fe02f083cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 15 May 2015 20:20:09 +0200 -Subject: [PATCH 161/216] usb: dwc_otg: Don't use dma_to_virt() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Commit 6ce0d20 changes dma_to_virt() which breaks this driver. -Open code the old dma_to_virt() implementation to work around this. - -Limit the use of __bus_to_virt() to cases where transfer_buffer_length -is set and transfer_buffer is not set. This is done to increase the -chance that this driver will also work on ARCH_BCM2835. - -transfer_buffer should not be NULL if the length is set, but the -comment in the code indicates that there are situations where this -might happen. drivers/usb/isp1760/isp1760-hcd.c also has a similar -comment pointing to a possible: 'usb storage / SCSI bug'. - -Signed-off-by: Noralf Trønnes ---- - drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -index 1d28459..6aad9c4 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_hcd_linux.c -@@ -766,16 +766,17 @@ static int dwc_otg_urb_enqueue(struct usb_hcd *hcd, - !(usb_pipein(urb->pipe)))); - - buf = urb->transfer_buffer; -- if (hcd->self.uses_dma) { -+ if (hcd->self.uses_dma && !buf && urb->transfer_buffer_length) { - /* - * Calculate virtual address from physical address, - * because some class driver may not fill transfer_buffer. - * In Buffer DMA mode virual address is used, - * when handling non DWORD aligned buffers. - */ -- //buf = phys_to_virt(urb->transfer_dma); -- // DMA addresses are bus addresses not physical addresses! -- buf = dma_to_virt(&urb->dev->dev, urb->transfer_dma); -+ buf = (void *)__bus_to_virt((unsigned long)urb->transfer_dma); -+ dev_warn_once(&urb->dev->dev, -+ "USB transfer_buffer was NULL, will use __bus_to_virt(%pad)=%p\n", -+ &urb->transfer_dma, buf); - } - - if (!(urb->transfer_flags & URB_NO_INTERRUPT)) - -From 785584eaa255550270eb4496bdc31f241561b26c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Fri, 15 May 2015 20:20:26 +0200 -Subject: [PATCH 162/216] fixup: restore dma-mapping.h -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -dwc_otg has been fixed, so no need to revert 6ce0d20: -ARM: dma: Use dma_pfn_offset for dma address translation - -The pfn_to_dma/dma_to_pfn changes that came with that commit -is needed to use the 'dma-ranges' DT property on ARCH_BCM2835. -dma-ranges is needed by bcm2708_fb and vchiq on ARCH_BCM2835. -If not the mailbox call fails to hand over the correct -bus address to videocore. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/include/asm/dma-mapping.h | 18 +++++++++++++++++- - 1 file changed, 17 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h -index f5572d9..b52101d3 100644 ---- a/arch/arm/include/asm/dma-mapping.h -+++ b/arch/arm/include/asm/dma-mapping.h -@@ -58,21 +58,37 @@ static inline int dma_set_mask(struct device *dev, u64 mask) - #ifndef __arch_pfn_to_dma - static inline dma_addr_t pfn_to_dma(struct device *dev, unsigned long pfn) - { -+ if (dev) -+ pfn -= dev->dma_pfn_offset; - return (dma_addr_t)__pfn_to_bus(pfn); - } - - static inline unsigned long dma_to_pfn(struct device *dev, dma_addr_t addr) - { -- return __bus_to_pfn(addr); -+ unsigned long pfn = __bus_to_pfn(addr); -+ -+ if (dev) -+ pfn += dev->dma_pfn_offset; -+ -+ return pfn; - } - - static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) - { -+ if (dev) { -+ unsigned long pfn = dma_to_pfn(dev, addr); -+ -+ return phys_to_virt(__pfn_to_phys(pfn)); -+ } -+ - return (void *)__bus_to_virt((unsigned long)addr); - } - - static inline dma_addr_t virt_to_dma(struct device *dev, void *addr) - { -+ if (dev) -+ return pfn_to_dma(dev, virt_to_pfn(addr)); -+ - return (dma_addr_t)__virt_to_bus((unsigned long)(addr)); - } - - -From 1b1de68277ff97f836021328e6ac6fbb24494c73 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:18:28 +0200 -Subject: [PATCH 163/216] fbdev: bcm2708_fb: Add ARCH_BCM2835 support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support. -Pass the device to dma_alloc_coherent() in order to get the -correct bus address on ARCH_BCM2835. -Use the new DMA legacy API header file. -Including is not necessary. - -Signed-off-by: Noralf Trønnes ---- - drivers/video/fbdev/bcm2708_fb.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c -index 345c15e..f6ac7da 100644 ---- a/drivers/video/fbdev/bcm2708_fb.c -+++ b/drivers/video/fbdev/bcm2708_fb.c -@@ -24,16 +24,13 @@ - #include - #include - #include -+#include - #include - #include - #include - #include - #include - #include -- --#include --#include -- - #include - #include - #include -@@ -628,7 +625,7 @@ static int bcm2708_fb_register(struct bcm2708_fb *fb) - void *mem; - - mem = -- dma_alloc_coherent(NULL, PAGE_ALIGN(sizeof(*fb->info)), &dma, -+ dma_alloc_coherent(&fb->dev->dev, PAGE_ALIGN(sizeof(*fb->info)), &dma, - GFP_KERNEL); - - if (NULL == mem) { -@@ -783,12 +780,19 @@ static int bcm2708_fb_remove(struct platform_device *dev) - return 0; - } - -+static const struct of_device_id bcm2708_fb_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-fb", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2708_fb_of_match_table); -+ - static struct platform_driver bcm2708_fb_driver = { - .probe = bcm2708_fb_probe, - .remove = bcm2708_fb_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, -+ .of_match_table = bcm2708_fb_of_match_table, - }, - }; - - -From e6d3d3d4102639777a7261d9eb6f195176fc50bb Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:20:00 +0200 -Subject: [PATCH 164/216] BCM270x: Remove header file mach/dma.h -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This header file can be removed since there are no more users. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/include/mach/dma.h | 2 -- - arch/arm/mach-bcm2709/include/mach/dma.h | 2 -- - 2 files changed, 4 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/dma.h - delete mode 100644 arch/arm/mach-bcm2709/include/mach/dma.h - -diff --git a/arch/arm/mach-bcm2708/include/mach/dma.h b/arch/arm/mach-bcm2708/include/mach/dma.h -deleted file mode 100644 -index d826705..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/dma.h -+++ /dev/null -@@ -1,2 +0,0 @@ --/* This file can be removed when all the drivers have been updated */ --#include -diff --git a/arch/arm/mach-bcm2709/include/mach/dma.h b/arch/arm/mach-bcm2709/include/mach/dma.h -deleted file mode 100644 -index d826705..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/dma.h -+++ /dev/null -@@ -1,2 +0,0 @@ --/* This file can be removed when all the drivers have been updated */ --#include - -From 11e908510cac293a92b124f36476ae7fe4c581ec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:21:31 +0200 -Subject: [PATCH 165/216] BCM270x_DT: Add bcm2708-fb device -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add bcm2708-fb to Device Tree and don't add the -platform device when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 5 +++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - 6 files changed, 19 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index f25563a..9a8fed0 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -49,6 +49,10 @@ - bus-width = <4>; - }; - -+&fb { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 17b4b8c..cf67ec9 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -49,6 +49,10 @@ - bus-width = <4>; - }; - -+&fb { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 1c8c1af..c5ed34b 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -109,6 +109,11 @@ - leds: leds { - compatible = "gpio-leds"; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ status = "disabled"; -+ }; - }; - - clocks { -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index c73249b..1c865de 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -49,6 +49,10 @@ - bus-width = <4>; - }; - -+&fb { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 7cc47c1..cde2124 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -928,7 +928,7 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&w1_device); - #endif - bcm_register_device(&bcm2708_systemtimer_device); -- bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 2c0a664..95db41ff 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -951,7 +951,7 @@ void __init bcm2709_init(void) - #ifdef SYSTEM_TIMER - bcm_register_device(&bcm2708_systemtimer_device); - #endif -- bcm_register_device(&bcm2708_fb_device); -+ bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - -From 0abe9b6fa045617f9fb0f8afe64b69072821d241 Mon Sep 17 00:00:00 2001 -From: Eric Anholt -Date: Tue, 5 May 2015 13:10:11 -0700 -Subject: [PATCH 166/216] ARM: bcm2835: Use 0x4 prefix for DMA bus addresses to - SDRAM. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There exists a tiny MMU, configurable only by the VC (running the -closed firmware), which maps from the ARM's physical addresses to bus -addresses. These bus addresses determine the caching behavior in the -VC's L1/L2 (note: separate from the ARM's L1/L2) according to the top -2 bits. The bits in the bus address mean: - -From the VideoCore processor: -0x0... L1 and L2 cache allocating and coherent -0x4... L1 non-allocating, but coherent. L2 allocating and coherent -0x8... L1 non-allocating, but coherent. L2 non-allocating, but coherent -0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent - -From the GPU peripherals (note: all peripherals bypass the L1 -cache. The ARM will see this view once through the VC MMU): -0x0... Do not use -0x4... L1 non-allocating, and incoherent. L2 allocating and coherent. -0x8... L1 non-allocating, and incoherent. L2 non-allocating, but coherent -0xc... SDRAM alias. Cache is bypassed. Not L1 or L2 allocating or coherent - -The 2835 firmware always configures the MMU to turn ARM physical -addresses with 0x0 top bits to 0x4, meaning present in L2 but -incoherent with L1. However, any bus addresses we were generating in -the kernel to be passed to a device had 0x0 bits. That would be a -reserved (possibly totally incoherent) value if sent to a GPU -peripheral like USB, or L1 allocating if sent to the VC (like a -firmware property request). By setting dma-ranges, all of the devices -below it get a dev->dma_pfn_offset, so that dma_alloc_coherent() and -friends return addresses with 0x4 bits and avoid cache incoherency. - -This matches the behavior in the downstream 2708 kernel (see -BUS_OFFSET in arch/arm/mach-bcm2708/include/mach/memory.h). - -Signed-off-by: Eric Anholt -Tested-by: Noralf Trønnes -Acked-by: Stephen Warren -Cc: popcornmix@gmail.com ---- - arch/arm/boot/dts/bcm2835.dtsi | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 06cba29..f91db90 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -14,6 +14,7 @@ - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x7e000000 0x20000000 0x02000000>; -+ dma-ranges = <0x40000000 0x00000000 0x20000000>; - - timer@7e003000 { - compatible = "brcm,bcm2835-system-timer"; - -From fabd2cdba17ab122a41957bced0c06e993b559a8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:24:13 +0200 -Subject: [PATCH 167/216] bcm2835: Add bcm2708-fb to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add framebuffer device to Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ++++ - arch/arm/boot/dts/bcm2835.dtsi | 5 +++++ - 2 files changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index 9f4ed2f..f2ce803 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -49,3 +49,7 @@ - status = "okay"; - bus-width = <4>; - }; -+ -+&fb { -+ status = "okay"; -+}; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index f91db90..f3ab9b3 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -159,6 +159,11 @@ - arm-pmu { - compatible = "arm,arm1176-pmu"; - }; -+ -+ fb: fb { -+ compatible = "brcm,bcm2708-fb"; -+ status = "disabled"; -+ }; - }; - - clocks { - -From 81530cfc1eb8c2069f7083fa2cc56b3b7470eb29 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 18 May 2015 17:24:35 +0200 -Subject: [PATCH 168/216] bcm2835: bcm2835_defconfig use FB_BCM2708 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Enable the bcm2708 framebuffer driver. -Disable the simple framebuffer driver, which matches the -device handed over by u-boot. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 26b4c75..1af6069 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -72,7 +72,7 @@ CONFIG_SPI_BCM2835=y - CONFIG_GPIO_SYSFS=y - # CONFIG_HWMON is not set - CONFIG_FB=y --CONFIG_FB_SIMPLE=y -+CONFIG_FB_BCM2708=y - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y - CONFIG_USB=y - -From 9e0da80c0836b21773e84b699f2e94e50680b485 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 19 May 2015 11:41:11 +0100 -Subject: [PATCH 169/216] BCM2708_DT: Enable mmc and fb in the CM dtsi - ---- - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 8340c1e..815a3a4 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -25,6 +25,15 @@ - }; - }; - -+&mmc { -+ status = "okay"; -+ bus-width = <4>; -+}; -+ -+&fb { -+ status = "okay"; -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; - -From c95de8db34841f61ef2cb38afb8b84973bd9aa6c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 19 May 2015 13:31:50 +0200 -Subject: [PATCH 170/216] BCM270x: Add vchiq device to platform file and Device - Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Prepare to turn the vchiq module into a driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 6 ++++++ - arch/arm/mach-bcm2708/bcm2708.c | 26 ++++++++++++++++++++++++++ - arch/arm/mach-bcm2708/include/mach/platform.h | 1 + - arch/arm/mach-bcm2709/bcm2709.c | 26 ++++++++++++++++++++++++++ - arch/arm/mach-bcm2709/include/mach/platform.h | 1 + - 5 files changed, 60 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index c5ed34b..2d9bcd8 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -114,6 +114,12 @@ - compatible = "brcm,bcm2708-fb"; - status = "disabled"; - }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ }; - }; - - clocks { -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index cde2124..81cc988 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -437,6 +437,31 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static struct resource bcm2708_vchiq_resources[] = { -+ { -+ .start = ARMCTRL_0_BELL_BASE, -+ .end = ARMCTRL_0_BELL_BASE + 16, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_DOORBELL_0, -+ .end = IRQ_ARM_DOORBELL_0, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_vchiq_device = { -+ .name = "bcm2835_vchiq", -+ .id = -1, -+ .resource = bcm2708_vchiq_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), -+ .dev = { -+ .dma_mask = &vchiq_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - #ifdef CONFIG_BCM2708_GPIO - #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" - -@@ -909,6 +934,7 @@ void __init bcm2708_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -diff --git a/arch/arm/mach-bcm2708/include/mach/platform.h b/arch/arm/mach-bcm2708/include/mach/platform.h -index bef3e5a..69674e9 100644 ---- a/arch/arm/mach-bcm2708/include/mach/platform.h -+++ b/arch/arm/mach-bcm2708/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ - #define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 95db41ff..528bf6e 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -456,6 +456,31 @@ static struct platform_device bcm2708_vcio_device = { - }, - }; - -+static struct resource bcm2708_vchiq_resources[] = { -+ { -+ .start = ARMCTRL_0_BELL_BASE, -+ .end = ARMCTRL_0_BELL_BASE + 16, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = IRQ_ARM_DOORBELL_0, -+ .end = IRQ_ARM_DOORBELL_0, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static u64 vchiq_dmamask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON); -+ -+static struct platform_device bcm2708_vchiq_device = { -+ .name = "bcm2835_vchiq", -+ .id = -1, -+ .resource = bcm2708_vchiq_resources, -+ .num_resources = ARRAY_SIZE(bcm2708_vchiq_resources), -+ .dev = { -+ .dma_mask = &vchiq_dmamask, -+ .coherent_dma_mask = DMA_BIT_MASK(DMA_MASK_BITS_COMMON), -+ }, -+}; -+ - #ifdef CONFIG_BCM2708_GPIO - #define BCM_GPIO_DRIVER_NAME "bcm2708_gpio" - -@@ -930,6 +955,7 @@ void __init bcm2709_init(void) - - bcm_register_device_dt(&bcm2708_dmaengine_device); - bcm_register_device_dt(&bcm2708_vcio_device); -+ bcm_register_device_dt(&bcm2708_vchiq_device); - #ifdef CONFIG_BCM2708_GPIO - bcm_register_device_dt(&bcm2708_gpio_device); - #endif -diff --git a/arch/arm/mach-bcm2709/include/mach/platform.h b/arch/arm/mach-bcm2709/include/mach/platform.h -index 5574bb5..be99733 100644 ---- a/arch/arm/mach-bcm2709/include/mach/platform.h -+++ b/arch/arm/mach-bcm2709/include/mach/platform.h -@@ -81,6 +81,7 @@ - #define ARMCTRL_IC_BASE (ARM_BASE + 0x200) /* ARM interrupt controller */ - #define ARMCTRL_TIMER0_1_BASE (ARM_BASE + 0x400) /* Timer 0 and 1 */ - #define ARMCTRL_0_SBM_BASE (ARM_BASE + 0x800) /* User 0 (ARM)'s Semaphores Doorbells and Mailboxes */ -+#define ARMCTRL_0_BELL_BASE (ARMCTRL_0_SBM_BASE + 0x40) /* User 0 (ARM)'s Doorbell */ - #define ARMCTRL_0_MAIL0_BASE (ARMCTRL_0_SBM_BASE + 0x80) /* User 0 (ARM)'s Mailbox 0 */ - - - -From b723b4395acda96c805d6cd382d5732efa6e449c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 19 May 2015 13:32:34 +0200 -Subject: [PATCH 171/216] bcm2708: vchiq: Add Device Tree support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Turn vchiq into a driver and stop hardcoding resources. -Use devm_* functions in probe path to simplify cleanup. -A global variable is used to hold the register address. This is done -to keep this patch as small as possible. -Also make available on ARCH_BCM2835. -Based on work by Lubomir Rintel. - -Signed-off-by: Noralf Trønnes ---- - drivers/misc/vc04_services/Kconfig | 2 +- - .../interface/vchiq_arm/vchiq_2835_arm.c | 124 +++++++++------------ - .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 44 ++++---- - .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 7 +- - 4 files changed, 79 insertions(+), 98 deletions(-) - -diff --git a/drivers/misc/vc04_services/Kconfig b/drivers/misc/vc04_services/Kconfig -index b94e6cd..b4198c2 100644 ---- a/drivers/misc/vc04_services/Kconfig -+++ b/drivers/misc/vc04_services/Kconfig -@@ -1,6 +1,6 @@ - config BCM2708_VCHIQ - tristate "Videocore VCHIQ" -- depends on MACH_BCM2708 || MACH_BCM2709 -+ depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835 - default y - help - Kernel to VideoCore communication interface for the -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 70e5086..660aad2 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -35,22 +35,17 @@ - #include - #include - #include --#include - #include - #include - #include - #include - #include -+#include - #include - #include - --#include -- --#include -- - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - --#define VCHIQ_DOORBELL_IRQ IRQ_ARM_DOORBELL_0 - #define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) - - #include "vchiq_arm.h" -@@ -60,14 +55,15 @@ - - #define MAX_FRAGMENTS (VCHIQ_NUM_CURRENT_BULKS * 2) - -+#define BELL0 0x00 -+#define BELL2 0x08 -+ - typedef struct vchiq_2835_state_struct { - int inited; - VCHIQ_ARM_STATE_T arm_state; - } VCHIQ_2835_ARM_STATE_T; - --static char *g_slot_mem; --static int g_slot_mem_size; --dma_addr_t g_slot_phys; -+static void __iomem *g_regs; - static FRAGMENTS_T *g_fragments_base; - static FRAGMENTS_T *g_free_fragments; - struct semaphore g_free_fragments_sema; -@@ -86,43 +82,40 @@ create_pagelist(char __user *buf, size_t count, unsigned short type, - static void - free_pagelist(PAGELIST_T *pagelist, int actual); - --int __init --vchiq_platform_init(VCHIQ_STATE_T *state) -+int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - { -+ struct device *dev = &pdev->dev; - VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; -- int frag_mem_size; -- int err; -- int i; -+ struct resource *res; -+ void *slot_mem; -+ dma_addr_t slot_phys; -+ int slot_mem_size, frag_mem_size; -+ int err, irq, i; - - /* Allocate space for the channels in coherent memory */ -- g_slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); -+ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); - -- g_slot_mem = dma_alloc_coherent(NULL, g_slot_mem_size + frag_mem_size, -- &g_slot_phys, GFP_KERNEL); -- -- if (!g_slot_mem) { -- vchiq_log_error(vchiq_arm_log_level, -- "Unable to allocate channel memory"); -- err = -ENOMEM; -- goto failed_alloc; -+ slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, -+ &slot_phys, GFP_KERNEL); -+ if (!slot_mem) { -+ dev_err(dev, "could not allocate DMA memory\n"); -+ return -ENOMEM; - } - -- WARN_ON(((int)g_slot_mem & (PAGE_SIZE - 1)) != 0); -+ WARN_ON(((int)slot_mem & (PAGE_SIZE - 1)) != 0); - -- vchiq_slot_zero = vchiq_init_slots(g_slot_mem, g_slot_mem_size); -- if (!vchiq_slot_zero) { -- err = -EINVAL; -- goto failed_init_slots; -- } -+ vchiq_slot_zero = vchiq_init_slots(slot_mem, slot_mem_size); -+ if (!vchiq_slot_zero) -+ return -EINVAL; - - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_OFFSET_IDX] = -- (int)g_slot_phys + g_slot_mem_size; -+ (int)slot_phys + slot_mem_size; - vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = - MAX_FRAGMENTS; - -- g_fragments_base = (FRAGMENTS_T *)(g_slot_mem + g_slot_mem_size); -- g_slot_mem_size += frag_mem_size; -+ g_fragments_base = (FRAGMENTS_T *)(slot_mem + slot_mem_size); -+ slot_mem_size += frag_mem_size; - - g_free_fragments = g_fragments_base; - for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { -@@ -132,54 +125,46 @@ vchiq_platform_init(VCHIQ_STATE_T *state) - *(FRAGMENTS_T **)&g_fragments_base[i] = NULL; - sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); - -- if (vchiq_init_state(state, vchiq_slot_zero, 0/*slave*/) != -- VCHIQ_SUCCESS) { -- err = -EINVAL; -- goto failed_vchiq_init; -+ if (vchiq_init_state(state, vchiq_slot_zero, 0) != VCHIQ_SUCCESS) -+ return -EINVAL; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ g_regs = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(g_regs)) -+ return PTR_ERR(g_regs); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq <= 0) { -+ dev_err(dev, "failed to get IRQ\n"); -+ return irq; - } - -- err = request_irq(VCHIQ_DOORBELL_IRQ, vchiq_doorbell_irq, -- IRQF_IRQPOLL, "VCHIQ doorbell", -- state); -- if (err < 0) { -- vchiq_log_error(vchiq_arm_log_level, "%s: failed to register " -- "irq=%d err=%d", __func__, -- VCHIQ_DOORBELL_IRQ, err); -- goto failed_request_irq; -+ err = devm_request_irq(dev, irq, vchiq_doorbell_irq, IRQF_IRQPOLL, -+ "VCHIQ doorbell", state); -+ if (err) { -+ dev_err(dev, "failed to register irq=%d\n", irq); -+ return err; - } - - /* Send the base address of the slots to VideoCore */ - - dsb(); /* Ensure all writes have completed */ - -- bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)g_slot_phys); -+ err = bcm_mailbox_write(MBOX_CHAN_VCHIQ, (unsigned int)slot_phys); -+ if (err) { -+ dev_err(dev, "mailbox write failed\n"); -+ return err; -+ } - - vchiq_log_info(vchiq_arm_log_level, -- "vchiq_init - done (slots %x, phys %x)", -- (unsigned int)vchiq_slot_zero, g_slot_phys); -+ "vchiq_init - done (slots %x, phys %pad)", -+ (unsigned int)vchiq_slot_zero, &slot_phys); - -- vchiq_call_connected_callbacks(); -+ vchiq_call_connected_callbacks(); - - return 0; -- --failed_request_irq: --failed_vchiq_init: --failed_init_slots: -- dma_free_coherent(NULL, g_slot_mem_size, g_slot_mem, g_slot_phys); -- --failed_alloc: -- return err; --} -- --void __exit --vchiq_platform_exit(VCHIQ_STATE_T *state) --{ -- free_irq(VCHIQ_DOORBELL_IRQ, state); -- dma_free_coherent(NULL, g_slot_mem_size, -- g_slot_mem, g_slot_phys); - } - -- - VCHIQ_STATUS_T - vchiq_platform_init_state(VCHIQ_STATE_T *state) - { -@@ -213,11 +198,8 @@ remote_event_signal(REMOTE_EVENT_T *event) - - dsb(); /* data barrier operation */ - -- if (event->armed) { -- /* trigger vc interrupt */ -- -- writel(0, __io_address(ARM_0_BELL2)); -- } -+ if (event->armed) -+ writel(0, g_regs + BELL2); /* trigger vc interrupt */ - } - - int -@@ -341,7 +323,7 @@ vchiq_doorbell_irq(int irq, void *dev_id) - unsigned int status; - - /* Read (and clear) the doorbell */ -- status = readl(__io_address(ARM_0_BELL0)); -+ status = readl(g_regs + BELL0); - - if (status & 0x4) { /* Was the doorbell rung? */ - remote_event_pollall(state); -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -index 0ad9656..31e2cba 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.c -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - #include "vchiq_core.h" - #include "vchiq_ioctl.h" -@@ -2790,15 +2791,7 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, - } - } - -- --/**************************************************************************** --* --* vchiq_init - called when the module is loaded. --* --***************************************************************************/ -- --static int __init --vchiq_init(void) -+static int vchiq_probe(struct platform_device *pdev) - { - int err; - void *ptr_err; -@@ -2835,7 +2828,7 @@ vchiq_init(void) - if (IS_ERR(ptr_err)) - goto failed_device_create; - -- err = vchiq_platform_init(&g_state); -+ err = vchiq_platform_init(pdev, &g_state); - if (err != 0) - goto failed_platform_init; - -@@ -2862,23 +2855,32 @@ vchiq_init(void) - return err; - } - --/**************************************************************************** --* --* vchiq_exit - called when the module is unloaded. --* --***************************************************************************/ -- --static void __exit --vchiq_exit(void) -+static int vchiq_remove(struct platform_device *pdev) - { -- vchiq_platform_exit(&g_state); - device_destroy(vchiq_class, vchiq_devid); - class_destroy(vchiq_class); - cdev_del(&vchiq_cdev); - unregister_chrdev_region(vchiq_devid, 1); -+ -+ return 0; - } - --module_init(vchiq_init); --module_exit(vchiq_exit); -+static const struct of_device_id vchiq_of_match[] = { -+ { .compatible = "brcm,bcm2835-vchiq", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, vchiq_of_match); -+ -+static struct platform_driver vchiq_driver = { -+ .driver = { -+ .name = "bcm2835_vchiq", -+ .owner = THIS_MODULE, -+ .of_match_table = vchiq_of_match, -+ }, -+ .probe = vchiq_probe, -+ .remove = vchiq_remove, -+}; -+module_platform_driver(vchiq_driver); -+ - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Broadcom Corporation"); -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -index d1e2741..9740e1a 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_arm.h -@@ -36,6 +36,7 @@ - #define VCHIQ_ARM_H - - #include -+#include - #include - #include - #include "vchiq_core.h" -@@ -128,11 +129,7 @@ typedef struct vchiq_arm_state_struct { - extern int vchiq_arm_log_level; - extern int vchiq_susp_log_level; - --extern int __init --vchiq_platform_init(VCHIQ_STATE_T *state); -- --extern void __exit --vchiq_platform_exit(VCHIQ_STATE_T *state); -+int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state); - - extern VCHIQ_STATE_T * - vchiq_get_state(void); - -From a368d9389c5c346a4e5b6ee63a5b28c45184aa20 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 19 May 2015 13:32:50 +0200 -Subject: [PATCH 172/216] bcm2835: Add bcm2835-vchiq to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add vchiq to Device Tree. There are no kernel users yet, -but it's available to userspace (vcgencmd). - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index f3ab9b3..72d0354 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -164,6 +164,12 @@ - compatible = "brcm,bcm2708-fb"; - status = "disabled"; - }; -+ -+ vchiq: vchiq { -+ compatible = "brcm,bcm2835-vchiq"; -+ reg = <0x7e00b840 0xf>; -+ interrupts = <0 2>; -+ }; - }; - - clocks { - -From 0bf6760b3d81238fcfac05e88f66252192c5745d Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Wed, 20 May 2015 09:29:46 +0100 -Subject: [PATCH 173/216] i2c-bcm2708: When using DT, leave the GPIO setup to - pinctrl - ---- - drivers/i2c/busses/i2c-bcm2708.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/drivers/i2c/busses/i2c-bcm2708.c b/drivers/i2c/busses/i2c-bcm2708.c -index 81e9374..8773203 100644 ---- a/drivers/i2c/busses/i2c-bcm2708.c -+++ b/drivers/i2c/busses/i2c-bcm2708.c -@@ -382,7 +382,8 @@ static int bcm2708_i2c_probe(struct platform_device *pdev) - goto out_clk_put; - } - -- bcm2708_i2c_init_pinmode(pdev->id); -+ if (!pdev->dev.of_node) -+ bcm2708_i2c_init_pinmode(pdev->id); - - bi = kzalloc(sizeof(*bi), GFP_KERNEL); - if (!bi) - -From aa0aca81361683205b07ecc895256795ea771528 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 21 May 2015 11:36:31 +0100 -Subject: [PATCH 174/216] vchiq: Change logging level for inbound data - ---- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -index 835688b..2c98da4 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_core.c -@@ -1782,7 +1782,7 @@ parse_rx_slots(VCHIQ_STATE_T *state) - service->remoteport); - break; - case VCHIQ_MSG_DATA: -- vchiq_log_trace(vchiq_core_log_level, -+ vchiq_log_info(vchiq_core_log_level, - "%d: prs DATA@%x,%x (%d->%d)", - state->id, (unsigned int)header, size, - remoteport, localport); - -From 32477cf579fd64092395855bfacf907c7da8e3d8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 21 May 2015 13:24:35 +0200 -Subject: [PATCH 175/216] BCM270x: Add onboard sound device to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support to alsa driver. -Add device to Device Tree. -Don't add platform devices when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 4 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 7 +++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - sound/arm/Kconfig | 3 +- - sound/arm/bcm2835.c | 91 ++++++++++++++++++++++++++++++++ - 9 files changed, 118 insertions(+), 3 deletions(-) - mode change 100755 => 100644 arch/arm/boot/dts/bcm2708-rpi-cm.dtsi - mode change 100755 => 100644 sound/arm/bcm2835.c - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 9a8fed0..6323c5b 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -53,6 +53,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index cf67ec9..e1fe6a4 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -53,6 +53,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -old mode 100755 -new mode 100644 -index 815a3a4..1c2cfcf ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -34,6 +34,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - / { - __overrides__ { - act_led_gpio = <&act_led>,"gpios:4"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 2d9bcd8..4bf6960 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -3,6 +3,13 @@ - / { - interrupt-parent = <&intc>; - -+ /* Onboard audio */ -+ audio: audio { -+ compatible = "brcm,bcm2835-audio"; -+ brcm,pwm-channels = <8>; -+ status = "disabled"; -+ }; -+ - soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 1c865de..921add1 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -53,6 +53,10 @@ - status = "okay"; - }; - -+&audio { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 81cc988..e451187 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -964,7 +964,7 @@ void __init bcm2708_init(void) - #endif - bcm2708_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device(&bcm2708_alsa_devices[i]); -+ bcm_register_device_dt(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 528bf6e..06c2c74 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -987,7 +987,7 @@ void __init bcm2709_init(void) - #endif - bcm2709_init_led(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) -- bcm_register_device(&bcm2708_alsa_devices[i]); -+ bcm_register_device_dt(&bcm2708_alsa_devices[i]); - - bcm_register_device_dt(&bcm2708_spi_device); - -diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig -index ada7ba2..fcbe9d7 100644 ---- a/sound/arm/Kconfig -+++ b/sound/arm/Kconfig -@@ -41,7 +41,8 @@ config SND_PXA2XX_AC97 - - config SND_BCM2835 - tristate "BCM2835 ALSA driver" -- depends on (ARCH_BCM2708 || ARCH_BCM2709) && BCM2708_VCHIQ && SND -+ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) \ -+ && BCM2708_VCHIQ && SND - select SND_PCM - help - Say Y or M if you want to support BCM2835 Alsa pcm card driver -diff --git a/sound/arm/bcm2835.c b/sound/arm/bcm2835.c -old mode 100755 -new mode 100644 -index 7ed5079..6b545e7 ---- a/sound/arm/bcm2835.c -+++ b/sound/arm/bcm2835.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - #include "bcm2835.h" - -@@ -81,6 +82,86 @@ static int snd_bcm2835_create(struct snd_card *card, - return 0; - } - -+static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ bcm2835_chip_t *chip; -+ struct snd_card *card; -+ u32 numchans; -+ int err, i; -+ -+ err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", -+ &numchans); -+ if (err) { -+ dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); -+ return err; -+ } -+ -+ if (numchans == 0 || numchans > MAX_SUBSTREAMS) { -+ numchans = MAX_SUBSTREAMS; -+ dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n", -+ numchans); -+ } -+ -+ err = snd_card_new(NULL, -1, NULL, THIS_MODULE, 0, &card); -+ if (err) { -+ dev_err(dev, "Failed to create soundcard structure\n"); -+ return err; -+ } -+ -+ snd_card_set_dev(card, dev); -+ strcpy(card->driver, "bcm2835"); -+ strcpy(card->shortname, "bcm2835 ALSA"); -+ sprintf(card->longname, "%s", card->shortname); -+ -+ err = snd_bcm2835_create(card, pdev, &chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create bcm2835 chip\n"); -+ goto err_free; -+ } -+ -+ err = snd_bcm2835_new_pcm(chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create new bcm2835 pcm device\n"); -+ goto err_free; -+ } -+ -+ err = snd_bcm2835_new_spdif_pcm(chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n"); -+ goto err_free; -+ } -+ -+ err = snd_bcm2835_new_ctl(chip); -+ if (err < 0) { -+ dev_err(dev, "Failed to create new bcm2835 ctl\n"); -+ goto err_free; -+ } -+ -+ for (i = 0; i < numchans; i++) { -+ chip->avail_substreams |= (1 << i); -+ chip->pdev[i] = pdev; -+ } -+ -+ err = snd_card_register(card); -+ if (err) { -+ dev_err(dev, "Failed to register bcm2835 ALSA card \n"); -+ goto err_free; -+ } -+ -+ g_card = card; -+ g_chip = chip; -+ platform_set_drvdata(pdev, card); -+ audio_info("bcm2835 ALSA card created with %u channels\n", numchans); -+ -+ return 0; -+ -+err_free: -+ snd_card_free(card); -+ -+ return err; -+} -+ - static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - { - static int dev; -@@ -88,6 +169,9 @@ static int snd_bcm2835_alsa_probe(struct platform_device *pdev) - struct snd_card *card; - int err; - -+ if (pdev->dev.of_node) -+ return snd_bcm2835_alsa_probe_dt(pdev); -+ - if (dev >= MAX_SUBSTREAMS) - return -ENODEV; - -@@ -224,6 +308,12 @@ static int snd_bcm2835_alsa_resume(struct platform_device *pdev) - - #endif - -+static const struct of_device_id snd_bcm2835_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-audio", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); -+ - static struct platform_driver bcm2835_alsa0_driver = { - .probe = snd_bcm2835_alsa_probe, - .remove = snd_bcm2835_alsa_remove, -@@ -234,6 +324,7 @@ static struct platform_driver bcm2835_alsa0_driver = { - .driver = { - .name = "bcm2835_AUD0", - .owner = THIS_MODULE, -+ .of_match_table = snd_bcm2835_of_match_table, - }, - }; - - -From a8d9f167700bc9fd113a303b4944272519fc40f0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 21 May 2015 13:25:32 +0200 -Subject: [PATCH 176/216] bcm2835: Add bcm2835-audio to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add onboard sound device to Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index f2ce803..f23835e 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -14,6 +14,12 @@ - linux,default-trigger = "heartbeat"; - }; - }; -+ -+ /* Onboard audio */ -+ audio: audio { -+ compatible = "brcm,bcm2835-audio"; -+ brcm,pwm-channels = <8>; -+ }; - }; - - &gpio { - -From ead779a26fcab730a6d4be4c7b48c62b22afd8a5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 May 2015 16:59:02 +0100 -Subject: [PATCH 177/216] config: Add CONFIG_CIFS_UPCALL - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index ff87581..6fdd9bb 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -1118,6 +1118,7 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_9P_FS=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index e339979..93b3de1 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -1111,6 +1111,7 @@ CONFIG_NFSD_V3_ACL=y - CONFIG_NFSD_V4=y - CONFIG_CIFS=m - CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y - CONFIG_CIFS_XATTR=y - CONFIG_CIFS_POSIX=y - CONFIG_9P_FS=m - -From 2728618d457e238f4f95d96ad9303a1d816109a9 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 18 May 2015 16:59:13 +0100 -Subject: [PATCH 178/216] config: Add CONFIG_FB_SSD1307=m - ---- - arch/arm/configs/bcm2709_defconfig | 1 + - arch/arm/configs/bcmrpi_defconfig | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 6fdd9bb..9daaeb7 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -769,6 +769,7 @@ CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 93b3de1..dc27aeb 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -762,6 +762,7 @@ CONFIG_VIDEO_OV7640=m - CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m - # CONFIG_BACKLIGHT_GENERIC is not set - CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - -From 25b5c8e286f3a2b1779c63754b8993107bb416b0 Mon Sep 17 00:00:00 2001 +From f794a0549b3a54cbe6dcfef3b37c421dda92d13a Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Mon, 13 Oct 2014 11:47:53 +0100 -Subject: [PATCH 179/216] Improve __copy_to_user and __copy_from_user - performance +Subject: [PATCH 71/77] Improve __copy_to_user and __copy_from_user performance Provide a __copy_from_user that uses memcpy. On BCM2708, use optimised memcpy/memmove/memcmp/memset implementations. @@ -143076,7 +132661,7 @@ index cf4f3aa..9fe7780 100644 #define memset(p,v,n) \ diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h -index ce0786e..b85b93d 100644 +index 74b17d0..f4ad0a1 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -475,6 +475,7 @@ do { \ @@ -144557,356 +134142,28 @@ index 3e58d71..0622891 100644 static unsigned long noinline __clear_user_memset(void __user *addr, unsigned long n) -From ee5567b6efdbf9cbdf4cacaabc7623c5f6d45064 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Tue, 19 May 2015 18:49:06 +0100 -Subject: [PATCH 180/216] vcsm: Add ioctl for custom cache flushing - ---- - arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h | 15 +++++++ - drivers/char/broadcom/vc_sm/vmcs_sm.c | 49 ++++++++++++++++++++++ - 2 files changed, 64 insertions(+) - -diff --git a/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -index 42d0eb0..334f36d 100644 ---- a/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -+++ b/arch/arm/mach-bcm2708/include/mach/vmcs_sm_ioctl.h -@@ -61,6 +61,8 @@ enum vmcs_sm_cmd_e { - VMCS_SM_CMD_HOST_WALK_PID_ALLOC, - VMCS_SM_CMD_HOST_WALK_PID_MAP, - -+ VMCS_SM_CMD_CLEAN_INVALID, -+ - VMCS_SM_CMD_LAST /* Do no delete */ - }; - -@@ -163,6 +165,16 @@ struct vmcs_sm_ioctl_cache { - unsigned int size; - }; - -+struct vmcs_sm_ioctl_clean_invalid { -+ /* user -> kernel */ -+ struct { -+ unsigned int cmd; -+ unsigned int handle; -+ unsigned int addr; -+ unsigned int size; -+ } s[8]; -+}; -+ - /* IOCTL numbers */ - #define VMCS_SM_IOCTL_MEM_ALLOC\ - _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_ALLOC,\ -@@ -191,6 +203,9 @@ struct vmcs_sm_ioctl_cache { - #define VMCS_SM_IOCTL_MEM_INVALID\ - _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\ - struct vmcs_sm_ioctl_cache) -+#define VMCS_SM_IOCTL_MEM_CLEAN_INVALID\ -+ _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_CLEAN_INVALID,\ -+ struct vmcs_sm_ioctl_clean_invalid) - - #define VMCS_SM_IOCTL_SIZE_USR_HDL\ - _IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\ -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index da1c523..39a8971 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -2732,6 +2732,55 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) - } - break; - -+ /* Flush/Invalidate the cache for a given mapping. */ -+ case VMCS_SM_CMD_CLEAN_INVALID: -+ { -+ int i; -+ struct vmcs_sm_ioctl_clean_invalid ioparam; -+ -+ /* Get parameter data. */ -+ if (copy_from_user(&ioparam, -+ (void *)arg, sizeof(ioparam)) != 0) { -+ pr_err("[%s]: failed to copy-from-user for cmd %x\n", -+ __func__, cmdnr); -+ ret = -EFAULT; -+ goto out; -+ } -+ for (i=0; ires_cached) { -+ unsigned long base = ioparam.s[i].addr & ~(PAGE_SIZE-1); -+ unsigned long end = (ioparam.s[i].addr + ioparam.s[i].size + PAGE_SIZE-1) & ~(PAGE_SIZE-1); -+ resource->res_stats[ioparam.s[i].cmd == 1 ? INVALID:FLUSH]++; -+ -+ /* L1/L2 cache flush */ -+ down_read(¤t->mm->mmap_sem); -+ vcsm_vma_cache_clean_page_range(base, end); -+ up_read(¤t->mm->mmap_sem); -+ } else if (resource == NULL) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (resource) -+ vmcs_sm_release_resource(resource, 0); -+ } -+ break; -+ } -+ } -+ } -+ break; -+ - default: - { - ret = -EINVAL; - -From 6f9e2f739661f49e2375be580025549b367444b2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 17 Mar 2015 16:07:48 +0100 -Subject: [PATCH 181/216] dts: overlay: add generic support for ads7846 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add generic support for the ADS7846 touch controller. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/ads7846-overlay.dts | 83 +++++++++++++++++++++++++++++++++++ - 2 files changed, 84 insertions(+) - create mode 100644 arch/arm/boot/dts/ads7846-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index f3558df..0e77296 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -13,6 +13,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - -+dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -diff --git a/arch/arm/boot/dts/ads7846-overlay.dts b/arch/arm/boot/dts/ads7846-overlay.dts -new file mode 100644 -index 0000000..6a92cd1 ---- /dev/null -+++ b/arch/arm/boot/dts/ads7846-overlay.dts -@@ -0,0 +1,83 @@ -+/* -+ * Generic Device Tree overlay for the ADS7846 touch controller -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ ads7846_pins: ads7846_pins { -+ brcm,pins = <255>; /* illegal default value */ -+ brcm,function = <0>; /* in */ -+ brcm,pull = <0>; /* none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ads7846: ads7846@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ads7846_pins>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <255 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 255 0>; -+ -+ /* driver defaults */ -+ ti,x-min = /bits/ 16 <0>; -+ ti,y-min = /bits/ 16 <0>; -+ ti,x-max = /bits/ 16 <0x0FFF>; -+ ti,y-max = /bits/ 16 <0x0FFF>; -+ ti,pressure-min = /bits/ 16 <0>; -+ ti,pressure-max = /bits/ 16 <0xFFFF>; -+ ti,x-plate-ohms = /bits/ 16 <400>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ cs = <&ads7846>,"reg:0"; -+ speed = <&ads7846>,"spi-max-frequency:0"; -+ penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ -+ <&ads7846>,"interrupts:0", -+ <&ads7846>,"pendown-gpio:4"; -+ penirq_pull = <&ads7846_pins>,"brcm,pull:0"; -+ swapxy = <&ads7846>,"ti,swap-xy?"; -+ xmin = <&ads7846>,"ti,x-min;0"; -+ ymin = <&ads7846>,"ti,y-min;0"; -+ xmax = <&ads7846>,"ti,x-max;0"; -+ ymax = <&ads7846>,"ti,y-max;0"; -+ pmin = <&ads7846>,"ti,pressure-min;0"; -+ pmax = <&ads7846>,"ti,pressure-max;0"; -+ xohms = <&ads7846>,"ti,x-plate-ohms;0"; -+ }; -+}; - -From beda21eb0afb05805e46419c37f1127bf35fa775 Mon Sep 17 00:00:00 2001 -From: Matthias Reichl -Date: Sun, 24 May 2015 19:12:01 +0200 -Subject: [PATCH 182/216] bcm270x: add dtparam for audio node - -The audio node is enabled by default and can be disabled -with dtparam=audio=off in config.txt ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 3 files changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 6323c5b..609d004 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -126,5 +126,7 @@ - pwr_led_gpio = <&pwr_led>,"gpios:4"; - pwr_led_activelow = <&pwr_led>,"gpios:8"; - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e1fe6a4..e601194 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -116,5 +116,7 @@ - act_led_gpio = <&act_led>,"gpios:4"; - act_led_activelow = <&act_led>,"gpios:8"; - act_led_trigger = <&act_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 921add1..fe282e4 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -126,5 +126,7 @@ - pwr_led_gpio = <&pwr_led>,"gpios:4"; - pwr_led_activelow = <&pwr_led>,"gpios:8"; - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; -+ -+ audio = <&audio>,"status"; - }; - }; - -From c40ce86818e2ccd1521b5072cfa0bc102893ca7a Mon Sep 17 00:00:00 2001 +From 5787d557e062cdac5f3e19ccd60394dc6df38aab Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Wed, 27 May 2015 17:22:15 +0100 -Subject: [PATCH 183/216] bcm2835-audio: Create the platform device if the DT +Subject: [PATCH 72/77] bcm2835-audio: Create the platform device if the DT node is disabled For backwards compatibility, allow the built-in ALSA driver to be enabled either by loading the module from /etc/modules or by enabling the "/audio" node in DT. --- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 4 ---- - arch/arm/boot/dts/bcm2708-rpi-b.dts | 4 ---- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 4 ---- - arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- - arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- - 5 files changed, 16 insertions(+), 16 deletions(-) + arch/arm/mach-bcm2708/bcm2708.c | 10 ++++++++-- + arch/arm/mach-bcm2709/bcm2709.c | 10 ++++++++-- + 2 files changed, 16 insertions(+), 4 deletions(-) -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 609d004..75df21c 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -53,10 +53,6 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e601194..df12b7d 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -53,10 +53,6 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index fe282e4..78bc756 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -53,10 +53,6 @@ - status = "okay"; - }; - --&audio { -- status = "okay"; --}; -- - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e451187..06438df 100644 +index de2f93a..cfc4f13 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -963,8 +963,14 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2835_emmc_device); +@@ -898,8 +898,14 @@ void __init bcm2708_init(void) #endif bcm2708_init_led(); + bcm2708_init_uart1(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); + @@ -144921,13 +134178,13 @@ index e451187..06438df 100644 bcm_register_device_dt(&bcm2708_spi_device); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 06c2c74..ce06b7d 100644 +index 350647a..507ff52 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -986,8 +986,14 @@ void __init bcm2709_init(void) - bcm_register_device_dt(&bcm2835_emmc_device); +@@ -918,8 +918,14 @@ void __init bcm2709_init(void) #endif bcm2709_init_led(); + bcm2709_init_uart1(); - for (i = 0; i < ARRAY_SIZE(bcm2708_alsa_devices); i++) - bcm_register_device_dt(&bcm2708_alsa_devices[i]); + @@ -144942,8640 +134199,10 @@ index 06c2c74..ce06b7d 100644 bcm_register_device_dt(&bcm2708_spi_device); -From 9f10489e52092f350c72745c2ac3d0afbbf4cd44 Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Wed, 27 May 2015 14:39:55 +0000 -Subject: [PATCH 184/216] device-tree: spi: make spi-bcm2835 the default spi - driver and prepare for dma - -* make spi-bcm2835 the default driver for spi -* add a fallback spi-bcm2708 overlay -* add dma entries to device tree for future updates -* add default cs-gpios entry showing how to extend the number of chip-selects. - -Signed-off-by: Martin Sperl ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 10 +++++++++- - arch/arm/boot/dts/spi-bcm2708-overlay.dts | 18 ++++++++++++++++++ - 3 files changed, 28 insertions(+), 1 deletion(-) - create mode 100644 arch/arm/boot/dts/spi-bcm2708-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 0e77296..9124dfb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -41,6 +41,7 @@ dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb - - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 4bf6960..3f8af85 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -84,13 +84,21 @@ - }; - - spi0: spi@7e204000 { -- compatible = "brcm,bcm2708-spi"; -+ compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; - clocks = <&clk_spi>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; -+ /* the dma channels */ -+ dmas = <&dma 6>, <&dma 7>; -+ dma-names = "tx", "rx"; -+ /* the chipselects used - <0> means native GPIO -+ * add more gpios if necessary as <&gpio 6 1> -+ * (but do not forget to make them output!) -+ */ -+ cs-gpios = <0>, <0>; - }; - - i2c0: i2c@7e205000 { -diff --git a/arch/arm/boot/dts/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/spi-bcm2708-overlay.dts -new file mode 100644 -index 0000000..e378ef1 ---- /dev/null -+++ b/arch/arm/boot/dts/spi-bcm2708-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2708-spi"; -+ }; -+ }; -+}; - -From 8c5dd3fb2ef21f3dc20a7c999fd2659354afa975 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 23 May 2015 23:30:36 +0200 -Subject: [PATCH 185/216] BCM270x: Move power module -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make the power module available on ARCH_BCM2835 by moving it. -The module turns on USB power making it possible to boot -ARCH_BCM2835 directly with the VC bootloader. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/Makefile | 2 +- - arch/arm/mach-bcm2708/include/mach/arm_power.h | 62 -------- - arch/arm/mach-bcm2708/include/mach/power.h | 26 ---- - arch/arm/mach-bcm2708/power.c | 201 ------------------------- - arch/arm/mach-bcm2709/Makefile | 2 +- - arch/arm/mach-bcm2709/include/mach/arm_power.h | 62 -------- - arch/arm/mach-bcm2709/include/mach/power.h | 26 ---- - arch/arm/mach-bcm2709/power.c | 199 ------------------------ - drivers/soc/Kconfig | 1 + - drivers/soc/Makefile | 1 + - drivers/soc/bcm2835/Kconfig | 9 ++ - drivers/soc/bcm2835/Makefile | 1 + - drivers/soc/bcm2835/bcm2708-power.c | 200 ++++++++++++++++++++++++ - include/soc/bcm2835/power.h | 61 ++++++++ - 14 files changed, 275 insertions(+), 578 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/arm_power.h - delete mode 100644 arch/arm/mach-bcm2708/include/mach/power.h - delete mode 100644 arch/arm/mach-bcm2708/power.c - delete mode 100644 arch/arm/mach-bcm2709/include/mach/arm_power.h - delete mode 100644 arch/arm/mach-bcm2709/include/mach/power.h - delete mode 100644 arch/arm/mach-bcm2709/power.c - create mode 100644 drivers/soc/bcm2835/Kconfig - create mode 100644 drivers/soc/bcm2835/Makefile - create mode 100644 drivers/soc/bcm2835/bcm2708-power.c - create mode 100644 include/soc/bcm2835/power.h - -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index c1e7d41..5552ae8 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o power.o -+obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/include/mach/arm_power.h b/arch/arm/mach-bcm2708/include/mach/arm_power.h -deleted file mode 100644 -index d3bf245..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/arm_power.h -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 _ARM_POWER_H --#define _ARM_POWER_H -- --/* Use meaningful names on each side */ --#ifdef __VIDEOCORE__ --#define PREFIX(x) ARM_##x --#else --#define PREFIX(x) BCM_##x --#endif -- --enum { -- PREFIX(POWER_SDCARD_BIT), -- PREFIX(POWER_UART_BIT), -- PREFIX(POWER_MINIUART_BIT), -- PREFIX(POWER_USB_BIT), -- PREFIX(POWER_I2C0_BIT), -- PREFIX(POWER_I2C1_BIT), -- PREFIX(POWER_I2C2_BIT), -- PREFIX(POWER_SPI_BIT), -- PREFIX(POWER_CCP2TX_BIT), -- PREFIX(POWER_DSI_BIT), -- -- PREFIX(POWER_MAX) --}; -- --enum { -- PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -- PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -- PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -- PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -- PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -- PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -- PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -- PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -- PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -- PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -- -- PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -- PREFIX(POWER_NONE) = 0 --}; -- --#endif -diff --git a/arch/arm/mach-bcm2708/include/mach/power.h b/arch/arm/mach-bcm2708/include/mach/power.h -deleted file mode 100644 -index 52b3b02..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/power.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#ifndef _MACH_BCM2708_POWER_H --#define _MACH_BCM2708_POWER_H -- --#include --#include -- --typedef unsigned int BCM_POWER_HANDLE_T; -- --extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); --extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); --extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -- --#endif -diff --git a/arch/arm/mach-bcm2708/power.c b/arch/arm/mach-bcm2708/power.c -deleted file mode 100644 -index 796837f..0000000 ---- a/arch/arm/mach-bcm2708/power.c -+++ /dev/null -@@ -1,201 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#include --#include --#include --#include --#include --#include -- --#define DRIVER_NAME "bcm2708_power" -- --#define BCM_POWER_MAXCLIENTS 4 --#define BCM_POWER_NOCLIENT (1<<31) -- --/* Some drivers expect there devices to be permanently powered */ -- --#ifdef CONFIG_USB --#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) --#endif -- --#if 1 --#define DPRINTK printk --#else --#define DPRINTK if (0) printk --#endif -- --struct state_struct { -- uint32_t global_request; -- uint32_t client_request[BCM_POWER_MAXCLIENTS]; -- struct semaphore client_mutex; -- struct semaphore mutex; --} g_state; -- --int bcm_power_open(BCM_POWER_HANDLE_T *handle) --{ -- BCM_POWER_HANDLE_T i; -- int ret = -EBUSY; -- -- down(&g_state.client_mutex); -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -- g_state.client_request[i] = BCM_POWER_NONE; -- *handle = i; -- ret = 0; -- break; -- } -- } -- -- up(&g_state.client_mutex); -- -- DPRINTK("bcm_power_open() -> %d\n", *handle); -- -- return ret; --} --EXPORT_SYMBOL_GPL(bcm_power_open); -- --int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) --{ -- int rc = 0; -- -- DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -- -- if ((handle < BCM_POWER_MAXCLIENTS) && -- (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -- if (down_interruptible(&g_state.mutex) != 0) { -- DPRINTK("bcm_power_request -> interrupted\n"); -- return -EINTR; -- } -- -- if (request != g_state.client_request[handle]) { -- uint32_t others_request = 0; -- uint32_t global_request; -- BCM_POWER_HANDLE_T i; -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (i != handle) -- others_request |= -- g_state.client_request[i]; -- } -- others_request &= ~BCM_POWER_NOCLIENT; -- -- global_request = request | others_request; -- if (global_request != g_state.global_request) { -- uint32_t actual; -- -- /* Send a request to VideoCore */ -- 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); -- DPRINTK -- ("bcm_mailbox_read -> %08x, %d\n", -- actual, rc); -- actual >>= 4; -- } else { -- rc = 0; -- actual = global_request; -- } -- -- 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", -- __func__, -- g_state.global_request, -- global_request, actual, request, others_request); -- /* A failure */ -- BUG_ON((others_request & actual) -- != others_request); -- request &= actual; -- rc = -EIO; -- } -- -- g_state.global_request = actual; -- g_state.client_request[handle] = -- request; -- } -- } -- } -- up(&g_state.mutex); -- } else { -- rc = -EINVAL; -- } -- DPRINTK("bcm_power_request -> %d\n", rc); -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_request); -- --int bcm_power_close(BCM_POWER_HANDLE_T handle) --{ -- int rc; -- -- DPRINTK("bcm_power_close(%d)\n", handle); -- -- rc = bcm_power_request(handle, BCM_POWER_NONE); -- if (rc == 0) -- g_state.client_request[handle] = BCM_POWER_NOCLIENT; -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_close); -- --static int __init bcm_power_init(void) --{ --#if defined(BCM_POWER_ALWAYS_ON) -- BCM_POWER_HANDLE_T always_on_handle; --#endif -- int rc = 0; -- 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; -- -- sema_init(&g_state.client_mutex, 1); -- sema_init(&g_state.mutex, 1); -- -- g_state.global_request = 0; -- --#if defined(BCM_POWER_ALWAYS_ON) -- if (BCM_POWER_ALWAYS_ON) { -- bcm_power_open(&always_on_handle); -- bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -- } --#endif -- -- return rc; --} -- --static void __exit bcm_power_exit(void) --{ -- bcm_mailbox_write(MBOX_CHAN_POWER, 0); --} -- --/* -- * Load after the mailbox driver is initialized (arch_initcall), -- * but before depending drivers (module_init). -- */ --subsys_initcall(bcm_power_init); --module_exit(bcm_power_exit); -- --MODULE_AUTHOR("Phil Elwell"); --MODULE_DESCRIPTION("Interface to BCM2708 power management"); --MODULE_LICENSE("GPL"); -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index 77b8429..706116f 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -2,6 +2,6 @@ - # Makefile for the linux kernel. - # - --obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o power.o -+obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o - obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/include/mach/arm_power.h b/arch/arm/mach-bcm2709/include/mach/arm_power.h -deleted file mode 100644 -index d3bf245..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/arm_power.h -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/include/mach/arm_power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 _ARM_POWER_H --#define _ARM_POWER_H -- --/* Use meaningful names on each side */ --#ifdef __VIDEOCORE__ --#define PREFIX(x) ARM_##x --#else --#define PREFIX(x) BCM_##x --#endif -- --enum { -- PREFIX(POWER_SDCARD_BIT), -- PREFIX(POWER_UART_BIT), -- PREFIX(POWER_MINIUART_BIT), -- PREFIX(POWER_USB_BIT), -- PREFIX(POWER_I2C0_BIT), -- PREFIX(POWER_I2C1_BIT), -- PREFIX(POWER_I2C2_BIT), -- PREFIX(POWER_SPI_BIT), -- PREFIX(POWER_CCP2TX_BIT), -- PREFIX(POWER_DSI_BIT), -- -- PREFIX(POWER_MAX) --}; -- --enum { -- PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -- PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -- PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -- PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -- PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -- PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -- PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -- PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -- PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -- PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -- -- PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -- PREFIX(POWER_NONE) = 0 --}; -- --#endif -diff --git a/arch/arm/mach-bcm2709/include/mach/power.h b/arch/arm/mach-bcm2709/include/mach/power.h -deleted file mode 100644 -index 52b3b02..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/power.h -+++ /dev/null -@@ -1,26 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#ifndef _MACH_BCM2708_POWER_H --#define _MACH_BCM2708_POWER_H -- --#include --#include -- --typedef unsigned int BCM_POWER_HANDLE_T; -- --extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); --extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); --extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -- --#endif -diff --git a/arch/arm/mach-bcm2709/power.c b/arch/arm/mach-bcm2709/power.c -deleted file mode 100644 -index 960e472..0000000 ---- a/arch/arm/mach-bcm2709/power.c -+++ /dev/null -@@ -1,199 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/power.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License version 2 as -- * published by the Free Software Foundation. -- * -- * This device provides a shared mechanism for controlling the power to -- * VideoCore subsystems. -- */ -- --#include --#include --#include --#include --#include --#include -- --#define DRIVER_NAME "bcm2708_power" -- --#define BCM_POWER_MAXCLIENTS 4 --#define BCM_POWER_NOCLIENT (1<<31) -- --/* Some drivers expect there devices to be permanently powered */ --#ifdef CONFIG_USB --#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) --#endif -- --#if 1 --#define DPRINTK printk --#else --#define DPRINTK if (0) printk --#endif -- --struct state_struct { -- uint32_t global_request; -- uint32_t client_request[BCM_POWER_MAXCLIENTS]; -- struct semaphore client_mutex; -- struct semaphore mutex; --} g_state; -- --int bcm_power_open(BCM_POWER_HANDLE_T *handle) --{ -- BCM_POWER_HANDLE_T i; -- int ret = -EBUSY; -- -- down(&g_state.client_mutex); -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -- g_state.client_request[i] = BCM_POWER_NONE; -- *handle = i; -- ret = 0; -- break; -- } -- } -- -- up(&g_state.client_mutex); -- -- DPRINTK("bcm_power_open() -> %d\n", *handle); -- -- return ret; --} --EXPORT_SYMBOL_GPL(bcm_power_open); -- --int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) --{ -- int rc = 0; -- -- DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -- -- if ((handle < BCM_POWER_MAXCLIENTS) && -- (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -- if (down_interruptible(&g_state.mutex) != 0) { -- DPRINTK("bcm_power_request -> interrupted\n"); -- return -EINTR; -- } -- -- if (request != g_state.client_request[handle]) { -- uint32_t others_request = 0; -- uint32_t global_request; -- BCM_POWER_HANDLE_T i; -- -- for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -- if (i != handle) -- others_request |= -- g_state.client_request[i]; -- } -- others_request &= ~BCM_POWER_NOCLIENT; -- -- global_request = request | others_request; -- if (global_request != g_state.global_request) { -- uint32_t actual; -- -- /* Send a request to VideoCore */ -- 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); -- DPRINTK -- ("bcm_mailbox_read -> %08x, %d\n", -- actual, rc); -- actual >>= 4; -- } else { -- rc = 0; -- actual = global_request; -- } -- -- 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", -- __func__, -- g_state.global_request, -- global_request, actual, request, others_request); -- /* A failure */ -- BUG_ON((others_request & actual) -- != others_request); -- request &= actual; -- rc = -EIO; -- } -- -- g_state.global_request = actual; -- g_state.client_request[handle] = -- request; -- } -- } -- } -- up(&g_state.mutex); -- } else { -- rc = -EINVAL; -- } -- DPRINTK("bcm_power_request -> %d\n", rc); -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_request); -- --int bcm_power_close(BCM_POWER_HANDLE_T handle) --{ -- int rc; -- -- DPRINTK("bcm_power_close(%d)\n", handle); -- -- rc = bcm_power_request(handle, BCM_POWER_NONE); -- if (rc == 0) -- g_state.client_request[handle] = BCM_POWER_NOCLIENT; -- -- return rc; --} --EXPORT_SYMBOL_GPL(bcm_power_close); -- --static int __init bcm_power_init(void) --{ --#if defined(BCM_POWER_ALWAYS_ON) -- BCM_POWER_HANDLE_T always_on_handle; --#endif -- int rc = 0; -- 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; -- -- sema_init(&g_state.client_mutex, 1); -- sema_init(&g_state.mutex, 1); -- -- g_state.global_request = 0; --#if defined(BCM_POWER_ALWAYS_ON) -- if (BCM_POWER_ALWAYS_ON) { -- bcm_power_open(&always_on_handle); -- bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -- } --#endif -- -- return rc; --} -- --static void __exit bcm_power_exit(void) --{ -- bcm_mailbox_write(MBOX_CHAN_POWER, 0); --} -- --/* -- * Load after the mailbox driver is initialized (arch_initcall), -- * but before depending drivers (module_init). -- */ --subsys_initcall(bcm_power_init); --module_exit(bcm_power_exit); -- --MODULE_AUTHOR("Phil Elwell"); --MODULE_DESCRIPTION("Interface to BCM2708 power management"); --MODULE_LICENSE("GPL"); -diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig -index 76d6bd4..aed58f4 100644 ---- a/drivers/soc/Kconfig -+++ b/drivers/soc/Kconfig -@@ -1,5 +1,6 @@ - menu "SOC (System On Chip) specific Drivers" - -+source "drivers/soc/bcm2835/Kconfig" - source "drivers/soc/qcom/Kconfig" - source "drivers/soc/ti/Kconfig" - source "drivers/soc/versatile/Kconfig" -diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile -index 063113d..897de0c5 100644 ---- a/drivers/soc/Makefile -+++ b/drivers/soc/Makefile -@@ -2,6 +2,7 @@ - # Makefile for the Linux Kernel SOC specific device drivers. - # - -+obj-y += bcm2835/ - obj-$(CONFIG_ARCH_QCOM) += qcom/ - obj-$(CONFIG_ARCH_TEGRA) += tegra/ - obj-$(CONFIG_SOC_TI) += ti/ -diff --git a/drivers/soc/bcm2835/Kconfig b/drivers/soc/bcm2835/Kconfig -new file mode 100644 -index 0000000..c2980f3 ---- /dev/null -+++ b/drivers/soc/bcm2835/Kconfig -@@ -0,0 +1,9 @@ -+# -+# BCM2835 Soc drivers -+# -+config BCM2708_POWER -+ tristate "BCM2708 legacy power driver" -+ depends on (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) && BCM2708_MBOX -+ default y -+ help -+ Turns on USB power and provides an API for controlling power. -diff --git a/drivers/soc/bcm2835/Makefile b/drivers/soc/bcm2835/Makefile -new file mode 100644 -index 0000000..3614ad9 ---- /dev/null -+++ b/drivers/soc/bcm2835/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_BCM2708_POWER) += bcm2708-power.o -diff --git a/drivers/soc/bcm2835/bcm2708-power.c b/drivers/soc/bcm2835/bcm2708-power.c -new file mode 100644 -index 0000000..e7931a9 ---- /dev/null -+++ b/drivers/soc/bcm2835/bcm2708-power.c -@@ -0,0 +1,200 @@ -+/* -+ * linux/arch/arm/mach-bcm2708/power.c -+ * -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define DRIVER_NAME "bcm2708_power" -+ -+#define BCM_POWER_MAXCLIENTS 4 -+#define BCM_POWER_NOCLIENT (1<<31) -+ -+/* Some drivers expect there devices to be permanently powered */ -+ -+#ifdef CONFIG_USB -+#define BCM_POWER_ALWAYS_ON (BCM_POWER_USB) -+#endif -+ -+#if 1 -+#define DPRINTK printk -+#else -+#define DPRINTK if (0) printk -+#endif -+ -+struct state_struct { -+ uint32_t global_request; -+ uint32_t client_request[BCM_POWER_MAXCLIENTS]; -+ struct semaphore client_mutex; -+ struct semaphore mutex; -+} g_state; -+ -+int bcm_power_open(BCM_POWER_HANDLE_T *handle) -+{ -+ BCM_POWER_HANDLE_T i; -+ int ret = -EBUSY; -+ -+ down(&g_state.client_mutex); -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (g_state.client_request[i] == BCM_POWER_NOCLIENT) { -+ g_state.client_request[i] = BCM_POWER_NONE; -+ *handle = i; -+ ret = 0; -+ break; -+ } -+ } -+ -+ up(&g_state.client_mutex); -+ -+ DPRINTK("bcm_power_open() -> %d\n", *handle); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(bcm_power_open); -+ -+int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request) -+{ -+ int rc = 0; -+ -+ DPRINTK("bcm_power_request(%d, %x)\n", handle, request); -+ -+ if ((handle < BCM_POWER_MAXCLIENTS) && -+ (g_state.client_request[handle] != BCM_POWER_NOCLIENT)) { -+ if (down_interruptible(&g_state.mutex) != 0) { -+ DPRINTK("bcm_power_request -> interrupted\n"); -+ return -EINTR; -+ } -+ -+ if (request != g_state.client_request[handle]) { -+ uint32_t others_request = 0; -+ uint32_t global_request; -+ BCM_POWER_HANDLE_T i; -+ -+ for (i = 0; i < BCM_POWER_MAXCLIENTS; i++) { -+ if (i != handle) -+ others_request |= -+ g_state.client_request[i]; -+ } -+ others_request &= ~BCM_POWER_NOCLIENT; -+ -+ global_request = request | others_request; -+ if (global_request != g_state.global_request) { -+ uint32_t actual; -+ -+ /* Send a request to VideoCore */ -+ 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); -+ DPRINTK -+ ("bcm_mailbox_read -> %08x, %d\n", -+ actual, rc); -+ actual >>= 4; -+ } else { -+ rc = 0; -+ actual = global_request; -+ } -+ -+ 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", -+ __func__, -+ g_state.global_request, -+ global_request, actual, request, others_request); -+ /* A failure */ -+ BUG_ON((others_request & actual) -+ != others_request); -+ request &= actual; -+ rc = -EIO; -+ } -+ -+ g_state.global_request = actual; -+ g_state.client_request[handle] = -+ request; -+ } -+ } -+ } -+ up(&g_state.mutex); -+ } else { -+ rc = -EINVAL; -+ } -+ DPRINTK("bcm_power_request -> %d\n", rc); -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_request); -+ -+int bcm_power_close(BCM_POWER_HANDLE_T handle) -+{ -+ int rc; -+ -+ DPRINTK("bcm_power_close(%d)\n", handle); -+ -+ rc = bcm_power_request(handle, BCM_POWER_NONE); -+ if (rc == 0) -+ g_state.client_request[handle] = BCM_POWER_NOCLIENT; -+ -+ return rc; -+} -+EXPORT_SYMBOL_GPL(bcm_power_close); -+ -+static int __init bcm_power_init(void) -+{ -+#if defined(BCM_POWER_ALWAYS_ON) -+ BCM_POWER_HANDLE_T always_on_handle; -+#endif -+ int rc = 0; -+ 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; -+ -+ sema_init(&g_state.client_mutex, 1); -+ sema_init(&g_state.mutex, 1); -+ -+ g_state.global_request = 0; -+ -+#if defined(BCM_POWER_ALWAYS_ON) -+ if (BCM_POWER_ALWAYS_ON) { -+ bcm_power_open(&always_on_handle); -+ bcm_power_request(always_on_handle, BCM_POWER_ALWAYS_ON); -+ } -+#endif -+ -+ return rc; -+} -+ -+static void __exit bcm_power_exit(void) -+{ -+ bcm_mailbox_write(MBOX_CHAN_POWER, 0); -+} -+ -+/* -+ * Load after the mailbox driver is initialized (arch_initcall), -+ * but before depending drivers (module_init). -+ */ -+subsys_initcall(bcm_power_init); -+module_exit(bcm_power_exit); -+ -+MODULE_AUTHOR("Phil Elwell"); -+MODULE_DESCRIPTION("Interface to BCM2708 power management"); -+MODULE_LICENSE("GPL"); -diff --git a/include/soc/bcm2835/power.h b/include/soc/bcm2835/power.h -new file mode 100644 -index 0000000..bf22b26 ---- /dev/null -+++ b/include/soc/bcm2835/power.h -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2010 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This device provides a shared mechanism for controlling the power to -+ * VideoCore subsystems. -+ */ -+ -+#ifndef _BCM2708_POWER_H -+#define _BCM2708_POWER_H -+ -+#include -+ -+/* Use meaningful names on each side */ -+#ifdef __VIDEOCORE__ -+#define PREFIX(x) ARM_##x -+#else -+#define PREFIX(x) BCM_##x -+#endif -+ -+enum { -+ PREFIX(POWER_SDCARD_BIT), -+ PREFIX(POWER_UART_BIT), -+ PREFIX(POWER_MINIUART_BIT), -+ PREFIX(POWER_USB_BIT), -+ PREFIX(POWER_I2C0_BIT), -+ PREFIX(POWER_I2C1_BIT), -+ PREFIX(POWER_I2C2_BIT), -+ PREFIX(POWER_SPI_BIT), -+ PREFIX(POWER_CCP2TX_BIT), -+ PREFIX(POWER_DSI_BIT), -+ -+ PREFIX(POWER_MAX) -+}; -+ -+enum { -+ PREFIX(POWER_SDCARD) = (1 << PREFIX(POWER_SDCARD_BIT)), -+ PREFIX(POWER_UART) = (1 << PREFIX(POWER_UART_BIT)), -+ PREFIX(POWER_MINIUART) = (1 << PREFIX(POWER_MINIUART_BIT)), -+ PREFIX(POWER_USB) = (1 << PREFIX(POWER_USB_BIT)), -+ PREFIX(POWER_I2C0) = (1 << PREFIX(POWER_I2C0_BIT)), -+ PREFIX(POWER_I2C1_MASK) = (1 << PREFIX(POWER_I2C1_BIT)), -+ PREFIX(POWER_I2C2_MASK) = (1 << PREFIX(POWER_I2C2_BIT)), -+ PREFIX(POWER_SPI_MASK) = (1 << PREFIX(POWER_SPI_BIT)), -+ PREFIX(POWER_CCP2TX_MASK) = (1 << PREFIX(POWER_CCP2TX_BIT)), -+ PREFIX(POWER_DSI) = (1 << PREFIX(POWER_DSI_BIT)), -+ -+ PREFIX(POWER_MASK) = (1 << PREFIX(POWER_MAX)) - 1, -+ PREFIX(POWER_NONE) = 0 -+}; -+ -+typedef unsigned int BCM_POWER_HANDLE_T; -+ -+extern int bcm_power_open(BCM_POWER_HANDLE_T *handle); -+extern int bcm_power_request(BCM_POWER_HANDLE_T handle, uint32_t request); -+extern int bcm_power_close(BCM_POWER_HANDLE_T handle); -+ -+#endif - -From 7ea54e2541e0445c98c3b5bb4b0e80af76c5c197 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 23 May 2015 23:31:40 +0200 -Subject: [PATCH 186/216] bcm2835: Use empty bootargs in Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The VideoCore bootloader concatenates the bootargs property together -with /boot/cmdline.txt and includes it's own set of options. -Set bootargs to an empty string to behave like BCM270x. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 72d0354..40fc759 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -6,7 +6,7 @@ - interrupt-parent = <&intc>; - - chosen { -- bootargs = "earlyprintk console=ttyAMA0"; -+ bootargs = ""; - }; - - soc { - -From b340f9126d88eafd83e2ae6e0b593bea562f92f5 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Mon, 11 May 2015 09:00:42 +0100 -Subject: [PATCH 187/216] scripts: Add mkknlimg and knlinfo scripts from tools - repo - -The Raspberry Pi firmware looks for a trailer on the kernel image to -determine whether it was compiled with Device Tree support enabled. -If the firmware finds a kernel without this trailer, or which has a -trailer indicating that it isn't DT-capable, it disables DT support -and reverts to using ATAGs. - -The mkknlimg utility adds that trailer, having first analysed the -image to look for signs of DT support and the kernel version string. - -knlinfo displays the contents of the trailer in the given kernel image. ---- - scripts/knlinfo | 167 +++++++++++++++++++++++++++++++++++ - scripts/mkknlimg | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 427 insertions(+) - create mode 100755 scripts/knlinfo - create mode 100755 scripts/mkknlimg - -diff --git a/scripts/knlinfo b/scripts/knlinfo -new file mode 100755 -index 0000000..9c9b42e3 ---- /dev/null -+++ b/scripts/knlinfo -@@ -0,0 +1,167 @@ -+#!/usr/bin/env perl -+# ---------------------------------------------------------------------- -+# knlinfo by Phil Elwell for Raspberry Pi -+# -+# (c) 2014,2015 Raspberry Pi (Trading) Limited -+# -+# Licensed under the terms of the GNU General Public License. -+# ---------------------------------------------------------------------- -+ -+use strict; -+use integer; -+ -+use Fcntl ":seek"; -+ -+my $trailer_magic = 'RPTL'; -+ -+my %atom_formats = -+( -+ 'DTOK' => \&format_bool, -+ 'KVer' => \&format_string, -+); -+ -+if (@ARGV != 1) -+{ -+ print ("Usage: knlinfo \n"); -+ exit(1); -+} -+ -+my $kernel_file = $ARGV[0]; -+ -+ -+my ($atoms, $pos) = read_trailer($kernel_file); -+ -+exit(1) if (!$atoms); -+ -+printf("Kernel trailer found at %d/0x%x:\n", $pos, $pos); -+ -+foreach my $atom (@$atoms) -+{ -+ printf(" %s: %s\n", $atom->[0], format_atom($atom)); -+} -+ -+exit(0); -+ -+sub read_trailer -+{ -+ my ($kernel_file) = @_; -+ my $fh; -+ -+ if (!open($fh, '<', $kernel_file)) -+ { -+ print ("* Failed to open '$kernel_file'\n"); -+ return undef; -+ } -+ -+ if (!seek($fh, -12, SEEK_END)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ -+ my $last_bytes; -+ sysread($fh, $last_bytes, 12); -+ -+ my ($trailer_len, $data_len, $magic) = unpack('VVa4', $last_bytes); -+ -+ if (($magic ne $trailer_magic) || ($data_len != 4)) -+ { -+ print ("* no trailer\n"); -+ return undef; -+ } -+ if (!seek($fh, -12, SEEK_END)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ -+ $trailer_len -= 12; -+ -+ while ($trailer_len > 0) -+ { -+ if ($trailer_len < 8) -+ { -+ print ("* truncated atom header in trailer\n"); -+ return undef; -+ } -+ if (!seek($fh, -8, SEEK_CUR)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ $trailer_len -= 8; -+ -+ my $atom_hdr; -+ sysread($fh, $atom_hdr, 8); -+ my ($atom_len, $atom_type) = unpack('Va4', $atom_hdr); -+ -+ if ($trailer_len < $atom_len) -+ { -+ print ("* truncated atom data in trailer\n"); -+ return undef; -+ } -+ -+ my $rounded_len = (($atom_len + 3) & ~3); -+ if (!seek($fh, -(8 + $rounded_len), SEEK_CUR)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ $trailer_len -= $rounded_len; -+ -+ my $atom_data; -+ sysread($fh, $atom_data, $atom_len); -+ -+ if (!seek($fh, -$atom_len, SEEK_CUR)) -+ { -+ print ("* seek error in '$kernel_file'\n"); -+ return undef; -+ } -+ -+ push @$atoms, [ $atom_type, $atom_data ]; -+ } -+ -+ if (($$atoms[-1][0] eq "\x00\x00\x00\x00") && -+ ($$atoms[-1][1] eq "")) -+ { -+ pop @$atoms; -+ } -+ else -+ { -+ print ("* end marker missing from trailer\n"); -+ } -+ -+ return ($atoms, tell($fh)); -+} -+ -+sub format_atom -+{ -+ my ($atom) = @_; -+ -+ my $format_func = $atom_formats{$atom->[0]} || \&format_hex; -+ return $format_func->($atom->[1]); -+} -+ -+sub format_bool -+{ -+ my ($data) = @_; -+ return unpack('V', $data) ? 'true' : 'false'; -+} -+ -+sub format_int -+{ -+ my ($data) = @_; -+ return unpack('V', $data); -+} -+ -+sub format_string -+{ -+ my ($data) = @_; -+ return '"'.$data.'"'; -+} -+ -+sub format_hex -+{ -+ my ($data) = @_; -+ return unpack('H*', $data); -+} -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -new file mode 100755 -index 0000000..ac829d0 ---- /dev/null -+++ b/scripts/mkknlimg -@@ -0,0 +1,260 @@ -+#!/usr/bin/env perl -+# ---------------------------------------------------------------------- -+# mkknlimg by Phil Elwell for Raspberry Pi -+# based on extract-ikconfig Dick Streefland -+# -+# (c) 2009,2010 Dick Streefland -+# (c) 2014,2015 Raspberry Pi (Trading) Limited -+# -+# Licensed under the terms of the GNU General Public License. -+# ---------------------------------------------------------------------- -+ -+use strict; -+use warnings; -+use integer; -+ -+my $trailer_magic = 'RPTL'; -+ -+my $tmpfile1 = "/tmp/mkknlimg_$$.1"; -+my $tmpfile2 = "/tmp/mkknlimg_$$.2"; -+ -+my $dtok = 0; -+ -+while (@ARGV && ($ARGV[0] =~ /^-/)) -+{ -+ my $arg = shift(@ARGV); -+ if ($arg eq '--dtok') -+ { -+ $dtok = 1; -+ } -+ else -+ { -+ print ("* Unknown option '$arg'\n"); -+ usage(); -+ } -+} -+ -+usage() if (@ARGV != 2); -+ -+my $kernel_file = $ARGV[0]; -+my $out_file = $ARGV[1]; -+ -+if (! -r $kernel_file) -+{ -+ print ("* File '$kernel_file' not found\n"); -+ usage(); -+} -+ -+my @wanted_config_lines = -+( -+ 'CONFIG_BCM2708_DT' -+); -+ -+my @wanted_strings = -+( -+ 'bcm2708_fb', -+ 'brcm,bcm2708-pinctrl', -+ 'brcm,bcm2835-gpio', -+ 'of_find_property' -+); -+ -+my $res = try_extract($kernel_file, $tmpfile1); -+$res = try_decompress('\037\213\010', 'xy', 'gunzip', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\3757zXZ\000', 'abcde', 'unxz --single-stream', -1, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('BZh', 'xy', 'bunzip2', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\135\0\0\0', 'xxx', 'unlzma', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\211\114\132', 'xy', 'lzop -d', 0, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+$res = try_decompress('\002\041\114\030', 'xy', 'lz4 -d', 1, -+ $kernel_file, $tmpfile1, $tmpfile2) if (!$res); -+ -+my $append_trailer; -+my $trailer; -+my $kver = '?'; -+ -+$append_trailer = $dtok; -+ -+if ($res) -+{ -+ $kver = $res->{''} || '?'; -+ print("Version: $kver\n"); -+ -+ $append_trailer = $dtok; -+ if (!$dtok) -+ { -+ if (config_bool($res, 'bcm2708_fb')) -+ { -+ $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); -+ $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); -+ $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); -+ $append_trailer = 1; -+ } -+ else -+ { -+ print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n"); -+ } -+ } -+} -+elsif (!$dtok) -+{ -+ print ("* Is this a valid kernel? In pass-through mode.\n"); -+} -+ -+if ($append_trailer) -+{ -+ printf("DT: %s\n", $dtok ? "y" : "n"); -+ -+ my @atoms; -+ -+ push @atoms, [ $trailer_magic, pack('V', 0) ]; -+ push @atoms, [ 'KVer', $kver ]; -+ push @atoms, [ 'DTOK', pack('V', $dtok) ]; -+ -+ $trailer = pack_trailer(\@atoms); -+ $atoms[0]->[1] = pack('V', length($trailer)); -+ -+ $trailer = pack_trailer(\@atoms); -+} -+ -+my $ofh; -+my $total_len = 0; -+ -+if ($out_file eq $kernel_file) -+{ -+ die "* Failed to open '$out_file' for append\n" -+ if (!open($ofh, '>>', $out_file)); -+ $total_len = tell($ofh); -+} -+else -+{ -+ die "* Failed to open '$kernel_file'\n" -+ if (!open(my $ifh, '<', $kernel_file)); -+ die "* Failed to create '$out_file'\n" -+ if (!open($ofh, '>', $out_file)); -+ -+ my $copybuf; -+ while (1) -+ { -+ my $bytes = sysread($ifh, $copybuf, 64*1024); -+ last if (!$bytes); -+ syswrite($ofh, $copybuf, $bytes); -+ $total_len += $bytes; -+ } -+ close($ifh); -+} -+ -+if ($trailer) -+{ -+ # Pad to word-alignment -+ syswrite($ofh, "\x000\x000\x000", (-$total_len & 0x3)); -+ syswrite($ofh, $trailer); -+} -+ -+close($ofh); -+ -+exit($trailer ? 0 : 1); -+ -+END { -+ unlink($tmpfile1) if ($tmpfile1); -+ unlink($tmpfile2) if ($tmpfile2); -+} -+ -+ -+sub usage -+{ -+ print ("Usage: mkknlimg [--dtok] \n"); -+ exit(1); -+} -+ -+sub try_extract -+{ -+ my ($knl, $tmp) = @_; -+ -+ my $ver = `strings "$knl" | grep -a -E "^Linux version [1-9]"`; -+ -+ return undef if (!$ver); -+ -+ chomp($ver); -+ -+ my $res = { ''=>$ver }; -+ my $string_pattern = '^('.join('|', @wanted_strings).')$'; -+ -+ my @matches = `strings \"$knl\" | grep -E \"$string_pattern\"`; -+ foreach my $match (@matches) -+ { -+ chomp($match); -+ $res->{$match} = 1; -+ } -+ -+ my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$'; -+ my $cf1 = 'IKCFG_ST\037\213\010'; -+ my $cf2 = '0123456789'; -+ -+ my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`; -+ if ($pos) -+ { -+ $pos =~ s/:.*[\r\n]*$//s; -+ $pos += 8; -+ my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8); -+ if (($err == 0) || ($err == 2)) -+ { -+ if (open(my $fh, '<', $tmp)) -+ { -+ while (my $line = <$fh>) -+ { -+ chomp($line); -+ $res->{$1} = $2 if ($line =~ /$config_pattern/); -+ } -+ -+ close($fh); -+ } -+ } -+ } -+ -+ return $res; -+} -+ -+ -+sub try_decompress -+{ -+ my ($magic, $subst, $zcat, $idx, $knl, $tmp1, $tmp2) = @_; -+ -+ my $pos = `tr "$magic\n$subst" "\n$subst=" < "$knl" | grep -abo "^$subst"`; -+ if ($pos) -+ { -+ chomp($pos); -+ $pos = (split(/[\r\n]+/, $pos))[$idx]; -+ return undef if (!defined($pos)); -+ $pos =~ s/:.*[\r\n]*$//s; -+ my $cmd = "tail -c+$pos \"$knl\" | $zcat > $tmp2 2> /dev/null"; -+ my $err = (system($cmd) >> 8); -+ return undef if (($err != 0) && ($err != 2)); -+ -+ return try_extract($tmp2, $tmp1); -+ } -+ -+ return undef; -+} -+ -+sub pack_trailer -+{ -+ my ($atoms) = @_; -+ my $trailer = pack('VV', 0, 0); -+ for (my $i = $#$atoms; $i>=0; $i--) -+ { -+ my $atom = $atoms->[$i]; -+ $trailer .= pack('a*x!4Va4', $atom->[1], length($atom->[1]), $atom->[0]); -+ } -+ return $trailer; -+} -+ -+sub config_bool -+{ -+ my ($configs, $wanted) = @_; -+ my $val = $configs->{$wanted} || 'n'; -+ return (($val eq 'y') || ($val eq '1')); -+} - -From 2ab7f22fc98a7e6f66c3924d0eff9a721b159029 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 May 2015 18:35:44 +0100 -Subject: [PATCH 188/216] scripts/mkknlimg: Add support for ARCH_BCM2835 - -Add a new trailer field indicating whether this is an ARCH_BCM2835 -build, as opposed to MACH_BCM2708/9. If the loader finds this flag -is set it changes the default base dtb file name from bcm270x... -to bcm283y... - -Also update knlinfo to show the status of the field. ---- - scripts/knlinfo | 1 + - scripts/mkknlimg | 25 ++++++++++++++++++++----- - 2 files changed, 21 insertions(+), 5 deletions(-) - -diff --git a/scripts/knlinfo b/scripts/knlinfo -index 9c9b42e3..a0e8663 100755 ---- a/scripts/knlinfo -+++ b/scripts/knlinfo -@@ -18,6 +18,7 @@ my %atom_formats = - ( - 'DTOK' => \&format_bool, - 'KVer' => \&format_string, -+ '283x' => \&format_bool, - ); - - if (@ARGV != 1) -diff --git a/scripts/mkknlimg b/scripts/mkknlimg -index ac829d0..3dff948 100755 ---- a/scripts/mkknlimg -+++ b/scripts/mkknlimg -@@ -1,7 +1,7 @@ - #!/usr/bin/env perl - # ---------------------------------------------------------------------- - # mkknlimg by Phil Elwell for Raspberry Pi --# based on extract-ikconfig Dick Streefland -+# based on extract-ikconfig by Dick Streefland - # - # (c) 2009,2010 Dick Streefland - # (c) 2014,2015 Raspberry Pi (Trading) Limited -@@ -19,6 +19,7 @@ my $tmpfile1 = "/tmp/mkknlimg_$$.1"; - my $tmpfile2 = "/tmp/mkknlimg_$$.2"; - - my $dtok = 0; -+my $is_283x = 0; - - while (@ARGV && ($ARGV[0] =~ /^-/)) - { -@@ -27,6 +28,10 @@ while (@ARGV && ($ARGV[0] =~ /^-/)) - { - $dtok = 1; - } -+ elsif ($arg eq '--283x') -+ { -+ $is_283x = 1; -+ } - else - { - print ("* Unknown option '$arg'\n"); -@@ -47,15 +52,18 @@ if (! -r $kernel_file) - - my @wanted_config_lines = - ( -- 'CONFIG_BCM2708_DT' -+ 'CONFIG_BCM2708_DT', -+ 'CONFIG_ARCH_BCM2835' - ); - - my @wanted_strings = - ( - 'bcm2708_fb', -+ 'brcm,bcm2835-mmc', -+ 'brcm,bcm2835-sdhost', - 'brcm,bcm2708-pinctrl', - 'brcm,bcm2835-gpio', -- 'of_find_property' -+ 'brcm,bcm2835-pm-wdt' - ); - - my $res = try_extract($kernel_file, $tmpfile1); -@@ -86,11 +94,16 @@ if ($res) - $append_trailer = $dtok; - if (!$dtok) - { -- if (config_bool($res, 'bcm2708_fb')) -+ if (config_bool($res, 'bcm2708_fb') || -+ config_bool($res, 'brcm,bcm2835-mmc') || -+ config_bool($res, 'brcm,bcm2835-sdhost')) - { - $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT'); -+ $dtok ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); - $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl'); - $dtok ||= config_bool($res, 'brcm,bcm2835-gpio'); -+ $is_283x ||= config_bool($res, 'CONFIG_ARCH_BCM2835'); -+ $is_283x ||= config_bool($res, 'brcm,bcm2835-pm-wdt'); - $append_trailer = 1; - } - else -@@ -107,12 +120,14 @@ elsif (!$dtok) - if ($append_trailer) - { - printf("DT: %s\n", $dtok ? "y" : "n"); -+ printf("283x: %s\n", $is_283x ? "y" : "n"); - - my @atoms; - - push @atoms, [ $trailer_magic, pack('V', 0) ]; - push @atoms, [ 'KVer', $kver ]; - push @atoms, [ 'DTOK', pack('V', $dtok) ]; -+ push @atoms, [ '283x', pack('V', $is_283x) ]; - - $trailer = pack_trailer(\@atoms); - $atoms[0]->[1] = pack('V', length($trailer)); -@@ -166,7 +181,7 @@ END { - - sub usage - { -- print ("Usage: mkknlimg [--dtok] \n"); -+ print ("Usage: mkknlimg [--dtok] [--283x] \n"); - exit(1); - } - - -From 73bb23f8980890aad84dc6b852f0aac91ab71981 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 10 Mar 2015 18:35:18 +0100 -Subject: [PATCH 189/216] config: add KEYBOARD_GPIO - ---- - arch/arm/configs/bcm2709_defconfig | 3 ++- - arch/arm/configs/bcmrpi_defconfig | 3 ++- - 2 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 9daaeb7..5ce9a01 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -520,7 +520,8 @@ 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_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m - # CONFIG_INPUT_MOUSE is not set - CONFIG_INPUT_JOYSTICK=y - CONFIG_JOYSTICK_IFORCE=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index dc27aeb..da443da 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -513,7 +513,8 @@ 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_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m - # CONFIG_INPUT_MOUSE is not set - CONFIG_INPUT_JOYSTICK=y - CONFIG_JOYSTICK_IFORCE=m - -From d7d347201d595ccc495da617ab583fdb3e282829 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 10 Mar 2015 18:35:59 +0100 -Subject: [PATCH 190/216] dts: overlay: add support for tinylcd.com 3.5" - display -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree overlay for 3.5" display by tinylcd.com - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/tinylcd35-overlay.dts | 216 ++++++++++++++++++++++++++++++++ - 2 files changed, 217 insertions(+) - create mode 100644 arch/arm/boot/dts/tinylcd35-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 9124dfb..25ea8eb 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -38,6 +38,7 @@ dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -diff --git a/arch/arm/boot/dts/tinylcd35-overlay.dts b/arch/arm/boot/dts/tinylcd35-overlay.dts -new file mode 100644 -index 0000000..f7102c8 ---- /dev/null -+++ b/arch/arm/boot/dts/tinylcd35-overlay.dts -@@ -0,0 +1,216 @@ -+/* -+ * tinylcd35-overlay.dts -+ * -+ * ------------------------------------------------- -+ * www.tinlylcd.com -+ * ------------------------------------------------- -+ * Device---Driver-----BUS GPIO's -+ * display tinylcd35 spi0.0 25 24 18 -+ * touch ads7846 spi0.1 5 -+ * rtc ds1307 i2c1-0068 -+ * rtc pcf8563 i2c1-0051 -+ * keypad gpio-keys --------- 17 22 27 23 28 -+ * -+ * -+ * TinyLCD.com 3.5 inch TFT -+ * -+ * Version 001 -+ * 5/3/2015 -- Noralf Trønnes Initial Device tree framework -+ * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ tinylcd35_pins: tinylcd35_pins { -+ brcm,pins = <25 24 18>; -+ brcm,function = <1>; /* out */ -+ }; -+ tinylcd35_ts_pins: tinylcd35_ts_pins { -+ brcm,pins = <5>; -+ brcm,function = <0>; /* in */ -+ }; -+ keypad_pins: keypad_pins { -+ brcm,pins = <4 17 22 23 27>; -+ brcm,function = <0>; /* in */ -+ brcm,pull = <1>; /* down */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tinylcd35: tinylcd35@0{ -+ compatible = "neosec,tinylcd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&tinylcd35_pins>, -+ <&tinylcd35_ts_pins>; -+ -+ spi-max-frequency = <48000000>; -+ rotate = <270>; -+ fps = <20>; -+ bgr; -+ buswidth = <8>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ -+ init = <0x10000B0 0x80 -+ 0x10000C0 0x0A 0x0A -+ 0x10000C1 0x01 0x01 -+ 0x10000C2 0x33 -+ 0x10000C5 0x00 0x42 0x80 -+ 0x10000B1 0xD0 0x11 -+ 0x10000B4 0x02 -+ 0x10000B6 0x00 0x22 0x3B -+ 0x10000B7 0x07 -+ 0x1000036 0x58 -+ 0x10000F0 0x36 0xA5 0xD3 -+ 0x10000E5 0x80 -+ 0x10000E5 0x01 -+ 0x10000B3 0x00 -+ 0x10000E5 0x00 -+ 0x10000F0 0x36 0xA5 0x53 -+ 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 -+ 0x100003A 0x55 -+ 0x1000011 -+ 0x2000001 -+ 0x1000029>; -+ }; -+ -+ tinylcd35_ts: tinylcd35_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ status = "disabled"; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <5 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 5 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ -+ /* RTC */ -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pcf8563: pcf8563@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* -+ * Values for input event code is found under the -+ * 'Keys and buttons' heading in include/uapi/linux/input.h -+ */ -+ fragment@5 { -+ target-path = "/soc"; -+ __overlay__ { -+ keypad: keypad { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&keypad_pins>; -+ status = "disabled"; -+ autorepeat; -+ -+ button@17 { -+ label = "GPIO KEY_UP"; -+ linux,code = <103>; -+ gpios = <&gpio 17 0>; -+ }; -+ button@22 { -+ label = "GPIO KEY_DOWN"; -+ linux,code = <108>; -+ gpios = <&gpio 22 0>; -+ }; -+ button@27 { -+ label = "GPIO KEY_LEFT"; -+ linux,code = <105>; -+ gpios = <&gpio 27 0>; -+ }; -+ button@23 { -+ label = "GPIO KEY_RIGHT"; -+ linux,code = <106>; -+ gpios = <&gpio 23 0>; -+ }; -+ button@4 { -+ label = "GPIO KEY_ENTER"; -+ linux,code = <28>; -+ gpios = <&gpio 4 0>; -+ }; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&tinylcd35>,"spi-max-frequency:0"; -+ rotate = <&tinylcd35>,"rotate:0"; -+ fps = <&tinylcd35>,"fps:0"; -+ debug = <&tinylcd35>,"debug:0"; -+ touch = <&tinylcd35_ts>,"status"; -+ touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", -+ <&tinylcd35_ts>,"interrupts:0", -+ <&tinylcd35_ts>,"pendown-gpio:4"; -+ xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; -+ rtc-pcf = <&i2c1>,"status", -+ <&pcf8563>,"status"; -+ rtc-ds = <&i2c1>,"status", -+ <&ds1307>,"status"; -+ keypad = <&keypad>,"status"; -+ }; -+}; - -From 4b843d5be018d8d392a4be34a7fdfe3640e3c2a7 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 29 May 2015 14:16:47 +0100 -Subject: [PATCH 191/216] BCM270X_DT: Move the overlays into a subdirectory, - adding the README - ---- - arch/arm/boot/dts/Makefile | 31 +- - arch/arm/boot/dts/ads7846-overlay.dts | 83 ---- - arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts | 23 - - arch/arm/boot/dts/ds1307-rtc-overlay.dts | 22 - - arch/arm/boot/dts/enc28j60-overlay.dts | 29 -- - arch/arm/boot/dts/hifiberry-amp-overlay.dts | 39 -- - arch/arm/boot/dts/hifiberry-dac-overlay.dts | 34 -- - arch/arm/boot/dts/hifiberry-dacplus-overlay.dts | 39 -- - arch/arm/boot/dts/hifiberry-digi-overlay.dts | 39 -- - arch/arm/boot/dts/hy28a-overlay.dts | 87 ---- - arch/arm/boot/dts/hy28b-overlay.dts | 142 ------- - arch/arm/boot/dts/i2c-rtc-overlay.dts | 43 -- - arch/arm/boot/dts/iqaudio-dac-overlay.dts | 39 -- - arch/arm/boot/dts/iqaudio-dacplus-overlay.dts | 39 -- - arch/arm/boot/dts/lirc-rpi-overlay.dts | 57 --- - arch/arm/boot/dts/mmc-overlay.dts | 19 - - arch/arm/boot/dts/mz61581-overlay.dts | 109 ----- - arch/arm/boot/dts/overlays/Makefile | 51 +++ - arch/arm/boot/dts/overlays/README | 470 +++++++++++++++++++++ - arch/arm/boot/dts/overlays/ads7846-overlay.dts | 83 ++++ - .../dts/overlays/bmp085_i2c-sensor-overlay.dts | 23 + - arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts | 22 + - arch/arm/boot/dts/overlays/enc28j60-overlay.dts | 29 ++ - .../boot/dts/overlays/hifiberry-amp-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-dac-overlay.dts | 34 ++ - .../dts/overlays/hifiberry-dacplus-overlay.dts | 39 ++ - .../boot/dts/overlays/hifiberry-digi-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/hy28a-overlay.dts | 87 ++++ - arch/arm/boot/dts/overlays/hy28b-overlay.dts | 142 +++++++ - arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts | 49 +++ - arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts | 39 ++ - .../boot/dts/overlays/iqaudio-dacplus-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts | 57 +++ - arch/arm/boot/dts/overlays/mmc-overlay.dts | 19 + - arch/arm/boot/dts/overlays/mz61581-overlay.dts | 109 +++++ - arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts | 22 + - arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts | 22 + - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 94 +++++ - .../dts/overlays/pitft28-resistive-overlay.dts | 115 +++++ - arch/arm/boot/dts/overlays/pps-gpio-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-dac-overlay.dts | 34 ++ - arch/arm/boot/dts/overlays/rpi-display-overlay.dts | 82 ++++ - arch/arm/boot/dts/overlays/rpi-proto-overlay.dts | 39 ++ - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 75 ++++ - arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts | 18 + - arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts | 18 + - arch/arm/boot/dts/overlays/tinylcd35-overlay.dts | 216 ++++++++++ - arch/arm/boot/dts/overlays/w1-gpio-overlay.dts | 39 ++ - .../boot/dts/overlays/w1-gpio-pullup-overlay.dts | 41 ++ - arch/arm/boot/dts/pcf2127-rtc-overlay.dts | 22 - - arch/arm/boot/dts/pcf8523-rtc-overlay.dts | 22 - - arch/arm/boot/dts/piscreen-overlay.dts | 94 ----- - arch/arm/boot/dts/pitft28-resistive-overlay.dts | 115 ----- - arch/arm/boot/dts/pps-gpio-overlay.dts | 34 -- - arch/arm/boot/dts/rpi-dac-overlay.dts | 34 -- - arch/arm/boot/dts/rpi-display-overlay.dts | 82 ---- - arch/arm/boot/dts/rpi-proto-overlay.dts | 39 -- - arch/arm/boot/dts/sdhost-overlay.dts | 75 ---- - arch/arm/boot/dts/spi-bcm2708-overlay.dts | 18 - - arch/arm/boot/dts/spi-bcm2835-overlay.dts | 18 - - arch/arm/boot/dts/tinylcd35-overlay.dts | 216 ---------- - arch/arm/boot/dts/w1-gpio-overlay.dts | 39 -- - arch/arm/boot/dts/w1-gpio-pullup-overlay.dts | 41 -- - 63 files changed, 2220 insertions(+), 1722 deletions(-) - delete mode 100644 arch/arm/boot/dts/ads7846-overlay.dts - delete mode 100644 arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts - delete mode 100644 arch/arm/boot/dts/ds1307-rtc-overlay.dts - delete mode 100755 arch/arm/boot/dts/enc28j60-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-amp-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-dac-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-dacplus-overlay.dts - delete mode 100644 arch/arm/boot/dts/hifiberry-digi-overlay.dts - delete mode 100644 arch/arm/boot/dts/hy28a-overlay.dts - delete mode 100644 arch/arm/boot/dts/hy28b-overlay.dts - delete mode 100644 arch/arm/boot/dts/i2c-rtc-overlay.dts - delete mode 100644 arch/arm/boot/dts/iqaudio-dac-overlay.dts - delete mode 100644 arch/arm/boot/dts/iqaudio-dacplus-overlay.dts - delete mode 100644 arch/arm/boot/dts/lirc-rpi-overlay.dts - delete mode 100644 arch/arm/boot/dts/mmc-overlay.dts - delete mode 100644 arch/arm/boot/dts/mz61581-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/Makefile - create mode 100644 arch/arm/boot/dts/overlays/README - create mode 100644 arch/arm/boot/dts/overlays/ads7846-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/enc28j60-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hy28a-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/hy28b-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/mmc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/mz61581-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/piscreen-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/pps-gpio-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/rpi-dac-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/rpi-display-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/rpi-proto-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/sdhost-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/tinylcd35-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-overlay.dts - create mode 100644 arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts - delete mode 100644 arch/arm/boot/dts/pcf2127-rtc-overlay.dts - delete mode 100644 arch/arm/boot/dts/pcf8523-rtc-overlay.dts - delete mode 100644 arch/arm/boot/dts/piscreen-overlay.dts - delete mode 100644 arch/arm/boot/dts/pitft28-resistive-overlay.dts - delete mode 100644 arch/arm/boot/dts/pps-gpio-overlay.dts - delete mode 100644 arch/arm/boot/dts/rpi-dac-overlay.dts - delete mode 100644 arch/arm/boot/dts/rpi-display-overlay.dts - delete mode 100644 arch/arm/boot/dts/rpi-proto-overlay.dts - delete mode 100644 arch/arm/boot/dts/sdhost-overlay.dts - delete mode 100644 arch/arm/boot/dts/spi-bcm2708-overlay.dts - delete mode 100644 arch/arm/boot/dts/spi-bcm2835-overlay.dts - delete mode 100644 arch/arm/boot/dts/tinylcd35-overlay.dts - delete mode 100644 arch/arm/boot/dts/w1-gpio-overlay.dts - delete mode 100644 arch/arm/boot/dts/w1-gpio-pullup-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 25ea8eb..ea93e1d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -13,36 +13,7 @@ ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif - --dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += ds1307-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pcf2127-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pcf8523-rtc-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb --dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb -+subdir-$(RPI_DT_OVERLAYS) += overlays - - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb -diff --git a/arch/arm/boot/dts/ads7846-overlay.dts b/arch/arm/boot/dts/ads7846-overlay.dts -deleted file mode 100644 -index 6a92cd1..0000000 ---- a/arch/arm/boot/dts/ads7846-overlay.dts -+++ /dev/null -@@ -1,83 +0,0 @@ --/* -- * Generic Device Tree overlay for the ADS7846 touch controller -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- ads7846_pins: ads7846_pins { -- brcm,pins = <255>; /* illegal default value */ -- brcm,function = <0>; /* in */ -- brcm,pull = <0>; /* none */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- ads7846: ads7846@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- pinctrl-names = "default"; -- pinctrl-0 = <&ads7846_pins>; -- -- spi-max-frequency = <2000000>; -- interrupts = <255 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 255 0>; -- -- /* driver defaults */ -- ti,x-min = /bits/ 16 <0>; -- ti,y-min = /bits/ 16 <0>; -- ti,x-max = /bits/ 16 <0x0FFF>; -- ti,y-max = /bits/ 16 <0x0FFF>; -- ti,pressure-min = /bits/ 16 <0>; -- ti,pressure-max = /bits/ 16 <0xFFFF>; -- ti,x-plate-ohms = /bits/ 16 <400>; -- }; -- }; -- }; -- __overrides__ { -- cs = <&ads7846>,"reg:0"; -- speed = <&ads7846>,"spi-max-frequency:0"; -- penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ -- <&ads7846>,"interrupts:0", -- <&ads7846>,"pendown-gpio:4"; -- penirq_pull = <&ads7846_pins>,"brcm,pull:0"; -- swapxy = <&ads7846>,"ti,swap-xy?"; -- xmin = <&ads7846>,"ti,x-min;0"; -- ymin = <&ads7846>,"ti,y-min;0"; -- xmax = <&ads7846>,"ti,x-max;0"; -- ymax = <&ads7846>,"ti,y-max;0"; -- pmin = <&ads7846>,"ti,pressure-min;0"; -- pmax = <&ads7846>,"ti,pressure-max;0"; -- xohms = <&ads7846>,"ti,x-plate-ohms;0"; -- }; --}; -diff --git a/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -deleted file mode 100644 -index b830bf2..0000000 ---- a/arch/arm/boot/dts/bmp085_i2c-sensor-overlay.dts -+++ /dev/null -@@ -1,23 +0,0 @@ --// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- bmp085@77 { -- compatible = "bosch,bmp085"; -- reg = <0x77>; -- default-oversampling = <3>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/ds1307-rtc-overlay.dts -deleted file mode 100644 -index 7d27044..0000000 ---- a/arch/arm/boot/dts/ds1307-rtc-overlay.dts -+++ /dev/null -@@ -1,22 +0,0 @@ --// Definitions for DS1307 Real Time Clock --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- ds1307@68 { -- compatible = "maxim,ds1307"; -- reg = <0x68>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/enc28j60-overlay.dts b/arch/arm/boot/dts/enc28j60-overlay.dts -deleted file mode 100755 -index aa9b645..0000000 ---- a/arch/arm/boot/dts/enc28j60-overlay.dts -+++ /dev/null -@@ -1,29 +0,0 @@ --// Overlay for the Microchip ENC28J60 Ethernet Controller --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- enc28j60@0{ -- compatible = "microchip,enc28j60"; -- reg = <0>; /* CE0 */ -- spi-max-frequency = <12000000>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/hifiberry-amp-overlay.dts -deleted file mode 100644 -index 2c81448..0000000 ---- a/arch/arm/boot/dts/hifiberry-amp-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for HiFiBerry Amp/Amp+ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-amp"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- tas5713@1b { -- #sound-dai-cells = <0>; -- compatible = "ti,tas5713"; -- reg = <0x1b>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/hifiberry-dac-overlay.dts -deleted file mode 100644 -index 5e7633a..0000000 ---- a/arch/arm/boot/dts/hifiberry-dac-overlay.dts -+++ /dev/null -@@ -1,34 +0,0 @@ --// Definitions for HiFiBerry DAC --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target-path = "/"; -- __overlay__ { -- pcm5102a-codec { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5102a"; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -deleted file mode 100644 -index deb9c625..0000000 ---- a/arch/arm/boot/dts/hifiberry-dacplus-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for HiFiBerry DAC+ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-dacplus"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcm5122@4d { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5122"; -- reg = <0x4d>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/hifiberry-digi-overlay.dts -deleted file mode 100644 -index d0e0d8a..0000000 ---- a/arch/arm/boot/dts/hifiberry-digi-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for HiFiBerry Digi --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "hifiberry,hifiberry-digi"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- wm8804@3b { -- #sound-dai-cells = <0>; -- compatible = "wlf,wm8804"; -- reg = <0x3b>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/hy28a-overlay.dts b/arch/arm/boot/dts/hy28a-overlay.dts -deleted file mode 100644 -index 3cd3083..0000000 ---- a/arch/arm/boot/dts/hy28a-overlay.dts -+++ /dev/null -@@ -1,87 +0,0 @@ --/* -- * Device Tree overlay for HY28A display -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- hy28a_pins: hy28a_pins { -- brcm,pins = <17 25 18>; -- brcm,function = <0 1 1>; /* in out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- hy28a: hy28a@0{ -- compatible = "ilitek,ili9320"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&hy28a_pins>; -- -- spi-max-frequency = <32000000>; -- spi-cpol; -- spi-cpha; -- rotate = <270>; -- bgr; -- fps = <50>; -- buswidth = <8>; -- startbyte = <0x70>; -- reset-gpios = <&gpio 25 0>; -- led-gpios = <&gpio 18 1>; -- debug = <0>; -- }; -- -- hy28a_ts: hy28a-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <17 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 17 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&hy28a>,"spi-max-frequency:0"; -- rotate = <&hy28a>,"rotate:0"; -- fps = <&hy28a>,"fps:0"; -- debug = <&hy28a>,"debug:0"; -- xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; -- resetgpio = <&hy28a>,"reset-gpios:4", -- <&hy28a_pins>, "brcm,pins:1"; -- ledgpio = <&hy28a>,"led-gpios:4", -- <&hy28a_pins>, "brcm,pins:2"; -- }; --}; -diff --git a/arch/arm/boot/dts/hy28b-overlay.dts b/arch/arm/boot/dts/hy28b-overlay.dts -deleted file mode 100644 -index f774c4a..0000000 ---- a/arch/arm/boot/dts/hy28b-overlay.dts -+++ /dev/null -@@ -1,142 +0,0 @@ --/* -- * Device Tree overlay for HY28b display shield by Texy -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- hy28b_pins: hy28b_pins { -- brcm,pins = <17 25 18>; -- brcm,function = <0 1 1>; /* in out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- hy28b: hy28b@0{ -- compatible = "ilitek,ili9325"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&hy28b_pins>; -- -- spi-max-frequency = <48000000>; -- spi-cpol; -- spi-cpha; -- rotate = <270>; -- bgr; -- fps = <50>; -- buswidth = <8>; -- startbyte = <0x70>; -- reset-gpios = <&gpio 25 0>; -- led-gpios = <&gpio 18 1>; -- -- gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -- -- init = <0x10000e7 0x0010 -- 0x1000000 0x0001 -- 0x1000001 0x0100 -- 0x1000002 0x0700 -- 0x1000003 0x1030 -- 0x1000004 0x0000 -- 0x1000008 0x0207 -- 0x1000009 0x0000 -- 0x100000a 0x0000 -- 0x100000c 0x0001 -- 0x100000d 0x0000 -- 0x100000f 0x0000 -- 0x1000010 0x0000 -- 0x1000011 0x0007 -- 0x1000012 0x0000 -- 0x1000013 0x0000 -- 0x2000032 -- 0x1000010 0x1590 -- 0x1000011 0x0227 -- 0x2000032 -- 0x1000012 0x009c -- 0x2000032 -- 0x1000013 0x1900 -- 0x1000029 0x0023 -- 0x100002b 0x000e -- 0x2000032 -- 0x1000020 0x0000 -- 0x1000021 0x0000 -- 0x2000032 -- 0x1000050 0x0000 -- 0x1000051 0x00ef -- 0x1000052 0x0000 -- 0x1000053 0x013f -- 0x1000060 0xa700 -- 0x1000061 0x0001 -- 0x100006a 0x0000 -- 0x1000080 0x0000 -- 0x1000081 0x0000 -- 0x1000082 0x0000 -- 0x1000083 0x0000 -- 0x1000084 0x0000 -- 0x1000085 0x0000 -- 0x1000090 0x0010 -- 0x1000092 0x0000 -- 0x1000093 0x0003 -- 0x1000095 0x0110 -- 0x1000097 0x0000 -- 0x1000098 0x0000 -- 0x1000007 0x0133 -- 0x1000020 0x0000 -- 0x1000021 0x0000 -- 0x2000064>; -- debug = <0>; -- }; -- -- hy28b_ts: hy28b-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <17 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 17 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&hy28b>,"spi-max-frequency:0"; -- rotate = <&hy28b>,"rotate:0"; -- fps = <&hy28b>,"fps:0"; -- debug = <&hy28b>,"debug:0"; -- xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; -- resetgpio = <&hy28b>,"reset-gpios:4", -- <&hy28b_pins>, "brcm,pins:1"; -- ledgpio = <&hy28b>,"led-gpios:4", -- <&hy28b_pins>, "brcm,pins:2"; -- }; --}; -diff --git a/arch/arm/boot/dts/i2c-rtc-overlay.dts b/arch/arm/boot/dts/i2c-rtc-overlay.dts -deleted file mode 100644 -index 5d5abb1..0000000 ---- a/arch/arm/boot/dts/i2c-rtc-overlay.dts -+++ /dev/null -@@ -1,43 +0,0 @@ --// Definitions for several I2C based Real Time Clocks --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -- reg = <0x68>; -- status = "disable"; -- }; -- ds3231: ds3231@68 { -- compatible = "maxim,ds3231"; -- reg = <0x68>; -- status = "disable"; -- }; -- pcf2127: pcf2127@51 { -- compatible = "nxp,pcf2127"; -- reg = <0x51>; -- status = "disable"; -- }; -- pcf8523: pcf8523@68 { -- compatible = "nxp,pcf8523"; -- reg = <0x68>; -- status = "disable"; -- }; -- }; -- }; -- __overrides__ { -- ds1307 = <&ds1307>,"status"; -- ds3231 = <&ds3231>,"status"; -- pcf2127 = <&pcf2127>,"status"; -- pcf8523 = <&pcf8523>,"status"; -- }; --}; -diff --git a/arch/arm/boot/dts/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/iqaudio-dac-overlay.dts -deleted file mode 100644 -index ea8173e..0000000 ---- a/arch/arm/boot/dts/iqaudio-dac-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for IQaudIO DAC --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "iqaudio,iqaudio-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcm5122@4c { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5122"; -- reg = <0x4c>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -deleted file mode 100644 -index 735d8ab..0000000 ---- a/arch/arm/boot/dts/iqaudio-dacplus-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for IQaudIO DAC+ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "iqaudio,iqaudio-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcm5122@4c { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm5122"; -- reg = <0x4c>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/lirc-rpi-overlay.dts b/arch/arm/boot/dts/lirc-rpi-overlay.dts -deleted file mode 100644 -index 7d5d82b..0000000 ---- a/arch/arm/boot/dts/lirc-rpi-overlay.dts -+++ /dev/null -@@ -1,57 +0,0 @@ --// Definitions for lirc-rpi module --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- lirc_rpi: lirc_rpi { -- compatible = "rpi,lirc-rpi"; -- pinctrl-names = "default"; -- pinctrl-0 = <&lirc_pins>; -- status = "okay"; -- -- // Override autodetection of IR receiver circuit -- // (0 = active high, 1 = active low, -1 = no override ) -- rpi,sense = <0xffffffff>; -- -- // Software carrier -- // (0 = off, 1 = on) -- rpi,softcarrier = <1>; -- -- // Invert output -- // (0 = off, 1 = on) -- rpi,invert = <0>; -- -- // Enable debugging messages -- // (0 = off, 1 = on) -- rpi,debug = <0>; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- lirc_pins: lirc_pins { -- brcm,pins = <17 18>; -- brcm,function = <1 0>; // out in -- brcm,pull = <0 1>; // off down -- }; -- }; -- }; -- -- __overrides__ { -- gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; -- gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; -- gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; -- -- sense = <&lirc_rpi>,"rpi,sense:0"; -- softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; -- invert = <&lirc_rpi>,"rpi,invert:0"; -- debug = <&lirc_rpi>,"rpi,debug:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/mmc-overlay.dts b/arch/arm/boot/dts/mmc-overlay.dts -deleted file mode 100644 -index 0a37cf4..0000000 ---- a/arch/arm/boot/dts/mmc-overlay.dts -+++ /dev/null -@@ -1,19 +0,0 @@ --/dts-v1/; --/plugin/; -- --/{ -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&mmc>; -- -- __overlay__ { -- brcm,overclock-50 = <0>; -- }; -- }; -- -- __overrides__ { -- overclock_50 = <&mmc>,"brcm,overclock-50:0"; -- force_pio = <&mmc>,"brcm,force-pio?"; -- }; --}; -diff --git a/arch/arm/boot/dts/mz61581-overlay.dts b/arch/arm/boot/dts/mz61581-overlay.dts -deleted file mode 100644 -index c06fe12..0000000 ---- a/arch/arm/boot/dts/mz61581-overlay.dts -+++ /dev/null -@@ -1,109 +0,0 @@ --/* -- * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- mz61581_pins: mz61581_pins { -- brcm,pins = <4 15 18 25>; -- brcm,function = <0 1 1 1>; /* in out out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- mz61581: mz61581@0{ -- compatible = "samsung,s6d02a1"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&mz61581_pins>; -- -- spi-max-frequency = <128000000>; -- spi-cpol; -- spi-cpha; -- -- width = <320>; -- height = <480>; -- rotate = <270>; -- bgr; -- fps = <30>; -- buswidth = <8>; -- -- reset-gpios = <&gpio 15 0>; -- dc-gpios = <&gpio 25 0>; -- led-gpios = <&gpio 18 0>; -- -- init = <0x10000b0 00 -- 0x1000011 -- 0x20000ff -- 0x10000b3 0x02 0x00 0x00 0x00 -- 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 -- 0x10000c1 0x08 0x16 0x08 0x08 -- 0x10000c4 0x11 0x07 0x03 0x03 -- 0x10000c6 0x00 -- 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 -- 0x1000035 0x00 -- 0x1000036 0xa0 -- 0x100003a 0x55 -- 0x1000044 0x00 0x01 -- 0x10000d0 0x07 0x07 0x1d 0x03 -- 0x10000d1 0x03 0x30 0x10 -- 0x10000d2 0x03 0x14 0x04 -- 0x1000029 -- 0x100002c>; -- -- /* This is a workaround to make sure the init sequence slows down and doesn't fail */ -- debug = <3>; -- }; -- -- mz61581_ts: mz61581_ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <4 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 4 0>; -- -- ti,x-plate-ohms = /bits/ 16 <60>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&mz61581>, "spi-max-frequency:0"; -- rotate = <&mz61581>, "rotate:0"; -- fps = <&mz61581>, "fps:0"; -- debug = <&mz61581>, "debug:0"; -- xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; -- }; --}; -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -new file mode 100644 -index 0000000..d64e6b4 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -0,0 +1,51 @@ -+ifeq ($(CONFIG_OF),y) -+ -+# Overlays for the Raspberry Pi platform -+ -+ifeq ($(CONFIG_BCM2708_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ifeq ($(CONFIG_BCM2709_DT),y) -+ RPI_DT_OVERLAYS=y -+endif -+ -+dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += enc28j60-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-amp-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hifiberry-digi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28a-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += hy28b-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pitft28-resistive-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += pps-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-dac-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-display-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += rpi-proto-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += sdhost-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2708-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += spi-bcm2835-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += tinylcd35-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb -+ -+targets += dtbs dtbs_install -+targets += $(dtb-y) -+ -+endif -+ -+always := $(dtb-y) -+clean-files := *.dtb -+ -+# Enable fixups to support overlays on BCM2708 platforms -+ifeq ($(RPI_DT_OVERLAYS),y) -+ DTC_FLAGS ?= -@ -+endif -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -new file mode 100644 -index 0000000..c260612 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/README -@@ -0,0 +1,470 @@ -+Introduction -+============ -+ -+This directory contains Device Tree overlays. Device Tree makes it possible -+to support many hardware configurations with a single kernel and without the -+need to explicitly load or blacklist kernel modules. Note that this isn't a -+"pure" Device Tree configuration (c.f. MACH_BCM2835) - some on-board devices -+are still configured by the board support code, but the intention is to -+eventually reach that goal. -+ -+On Raspberry Pi, Device Tree usage is controlled from /boot/config.txt. By -+default, the Raspberry Pi kernel boots with device tree enabled. You can -+completely disable DT usage (for now) by adding: -+ -+ device_tree= -+ -+to your config.txt, which should cause your Pi to revert to the old way of -+doing things after a reboot. -+ -+In /boot you will find a .dtb for each base platform. This describes the -+hardware that is part of the Raspberry Pi board. The loader (start.elf and its -+siblings) selects the .dtb file appropriate for the platform by name, and reads -+it into memory. At this point, all of the optional interfaces (i2c, i2s, spi) -+are disabled, but they can be enabled using Device Tree parameters: -+ -+ dtparam=i2c=on,i2s=on,spi=on -+ -+However, this shouldn't be necessary in many use cases because loading an -+overlay that requires one of those interfaces will cause it to be enabled -+automatically, and it is advisable to only enable interfaces if they are -+needed. -+ -+Configuring additional, optional hardware is done using Device Tree overlays -+(see below). -+ -+raspi-config -+============ -+ -+The Advanced Options section of the raspi-config utility can enable and disable -+Device Tree use, as well as toggling the I2C and SPI interfaces. Note that it -+is possible to both enable an interface and blacklist the driver, if for some -+reason you should want to defer the loading. -+ -+Modules -+======= -+ -+As well as describing the hardware, Device Tree also gives enough information -+to allow suitable driver modules to be located and loaded, with the corollary -+that unneeded modules are not loaded. As a result it should be possible to -+remove lines from /etc/modules, and /etc/modprobe.d/raspi-blacklist.conf can -+have its contents deleted (or commented out). -+ -+Using Overlays -+============== -+ -+Overlays are loaded using the "dtoverlay" directive. As an example, consider the -+popular lirc-rpi module, the Linux Infrared Remote Control driver. In the -+pre-DT world this would be loaded from /etc/modules, with an explicit -+"modprobe lirc-rpi" command, or programmatically by lircd. With DT enabled, -+this becomes a line in config.txt: -+ -+ dtoverlay=lirc-rpi -+ -+This causes the file /boot/overlays/lirc-rpi-overlay.dtb to be loaded. By -+default it will use GPIOs 17 (out) and 18 (in), but this can be modified using -+DT parameters: -+ -+ dtoverlay=lirc-rpi,gpio_out_pin=17,gpio_in_pin=13 -+ -+Parameters always have default values, although in some cases (e.g. "w1-gpio") -+it is necessary to provided multiple overlays in order to get the desired -+behaviour. See the list of overlays below for a description of the parameters and their defaults. -+ -+The Overlay and Parameter Reference -+=================================== -+ -+Name: -+Info: Configures the base Raspberry Pi hardware -+Load: -+Params: -+ i2c_arm Set to "on" to enable the ARM's i2c interface -+ (default "off") -+ -+ i2c_vc Set to "on" to enable the i2c interface -+ usually reserved for the VideoCore processor -+ (default "off") -+ -+ i2c An alias for i2c_arm -+ -+ i2c_arm_baudrate Set the baudrate of the ARM's i2c interface -+ (default "100000") -+ -+ i2c_vc_baudrate Set the baudrate of the VideoCore i2c interface -+ (default "100000") -+ -+ i2c_baudrate An alias for i2c_arm_baudrate -+ -+ i2s Set to "on" to enable the i2s interface -+ (default "off") -+ -+ spi Set to "on" to enable the spi interfaces -+ (default "off") -+ -+ act_led_trigger Choose which activity the LED tracks. -+ Use "heartbeat" for a nice load indicator. -+ (default "mmc") -+ -+ act_led_activelow Set to "on" to invert the sense of the LED -+ (default "off") -+ -+ act_led_gpio Set which GPIO to use for the activity LED -+ (in case you want to connect it to an external -+ device) -+ (default "16" on a non-Plus board, "47" on a -+ Plus or Pi 2) -+ -+ pwr_led_trigger -+ pwr_led_activelow -+ pwr_led_gpio -+ As for act_led_*, but using the PWR LED. -+ Not available on Model A/B boards. -+ -+ N.B. It is recommended to only enable those interfaces that are needed. -+ Leaving all interfaces enabled can lead to unwanted behaviour (i2c_vc -+ interfering with Pi Camera, I2S and SPI hogging GPIO pins, etc.) -+ Note also that i2c, i2c_arm and i2c_vc are aliases for the physical -+ interfaces i2c0 and i2c1. Use of the numeric variants is still possible -+ but deprecated because the ARM/VC assignments differ between board -+ revisions. The same board-specific mapping applies to i2c_baudrate, -+ and the other i2c baudrate parameters. -+ -+ -+Name: ads7846 -+Info: ADS7846 Touch controller -+Load: dtoverlay=ads7846,= -+Params: cs SPI bus Chip Select (default 1) -+ speed SPI bus speed (default 2Mhz, max 3.25MHz) -+ penirq GPIO used for PENIRQ. REQUIRED -+ penirq_pull Set GPIO pull (default 0=none, 2=pullup) -+ swapxy Swap x and y axis -+ xmin Minimum value on the X axis (default 0) -+ ymin Minimum value on the Y axis (default 0) -+ xmax Maximum value on the X axis (default 4095) -+ ymax Maximum value on the Y axis (default 4095) -+ pmin Minimum reported pressure value (default 0) -+ pmax Maximum reported pressure value (default 65535) -+ xohms Touchpanel sensitivity (X-plate resistance) -+ (default 400) -+ -+ penirq is required and usually xohms (60-100) has to be set as well. -+ Apart from that, pmax (255) and swapxy are also common. -+ The rest of the calibration can be done with xinput-calibrator. -+ See: github.com/notro/fbtft/wiki/FBTFT-on-Raspian -+ Device Tree binding document: -+ www.kernel.org/doc/Documentation/devicetree/bindings/input/ads7846.txt -+ -+ -+Name: bmp085_i2c-sensor -+Info: Configures the BMP085/BMP180 digital barometric pressure and temperature -+ sensors from Bosch Sensortec -+Load: dtoverlay=bmp085_i2c-sensor -+Params: -+ -+ -+[ The ds1307-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+Name: enc28j60 -+Info: Overlay for the Microchip ENC28J60 Ethernet Controller (SPI) -+Load: dtoverlay=enc28j60,= -+Params: int_pin GPIO used for INT (default 25) -+ -+ speed SPI bus speed (default 12000000) -+ -+ -+Name: hifiberry-amp -+Info: Configures the HifiBerry Amp and Amp+ audio cards -+Load: dtoverlay=hifiberry-amp -+Params: -+ -+ -+Name: hifiberry-dac -+Info: Configures the HifiBerry DAC audio card -+Load: dtoverlay=hifiberry-dac -+Params: -+ -+ -+Name: hifiberry-dacplus -+Info: Configures the HifiBerry DAC+ audio card -+Load: dtoverlay=hifiberry-dacplus -+Params: -+ -+ -+Name: hifiberry-digi -+Info: Configures the HifiBerry Digi audio card -+Load: dtoverlay=hifiberry-digi -+Params: -+ -+ -+Name: hy28a -+Info: HY28A - 2.8" TFT LCD Display Module by HAOYU Electronics -+ Default values match Texy's display shield -+Load: dtoverlay=hy28a,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ resetgpio GPIO used to reset controller -+ -+ ledgpio GPIO used to control backlight -+ -+ -+Name: hy28b -+Info: HY28B - 2.8" TFT LCD Display Module by HAOYU Electronics -+ Default values match Texy's display shield -+Load: dtoverlay=hy28b,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ resetgpio GPIO used to reset controller -+ -+ ledgpio GPIO used to control backlight -+ -+ -+Name: i2c-rtc -+Info: Adds support for a number of I2C Real Time Clock devices -+Load: dtoverlay=i2c-rtc, -+Params: ds1307 Select the DS1307 device -+ -+ ds3231 Select the DS3231 device -+ -+ pcf2127 Select the PCF2127 device -+ -+ pcf8523 Select the PCF8523 device -+ -+ pcf8563 Select the PCF8563 device -+ -+ -+Name: iqaudio-dac -+Info: Configures the IQaudio DAC audio card -+Load: dtoverlay=iqaudio-dac -+Params: -+ -+ -+Name: iqaudio-dacplus -+Info: Configures the IQaudio DAC+ audio card -+Load: dtoverlay=iqaudio-dacplus -+Params: -+ -+ -+Name: lirc-rpi -+Info: Configures lirc-rpi (Linux Infrared Remote Control for Raspberry Pi) -+ Consult the module documentation for more details. -+Load: dtoverlay=lirc-rpi,=,... -+Params: gpio_out_pin GPIO for output (default "17") -+ -+ gpio_in_pin GPIO for input (default "18") -+ -+ gpio_in_pull Pull up/down/off on the input pin -+ (default "down") -+ -+ sense Override the IR receive auto-detection logic: -+ "1" = force active high -+ "0" = force active low -+ "-1" = use auto-detection -+ (default "-1") -+ -+ softcarrier Turn the software carrier "on" or "off" -+ (default "on") -+ -+ invert "on" = invert the output pin (default "off") -+ -+ debug "on" = enable additional debug messages -+ (default "off") -+ -+ -+Name: mmc -+Info: Selects the bcm2835-mmc SD/MMC driver, optionally with overclock -+Load: dtoverlay=mmc,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support -+ -+ -+Name: mz61581 -+Info: MZ61581 display by Tontec -+Load: dtoverlay=mz61581,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ -+[ The pcf2127-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+[ The pcf8523-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+[ The pcf8563-rtc overlay has been deleted. See i2c-rtc. ] -+ -+ -+Name: piscreen -+Info: PiScreen display by OzzMaker.com -+Load: dtoverlay=piscreen,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ -+Name: pitft28-resistive -+Info: Adafruit PiTFT 2.8" resistive touch screen -+Load: dtoverlay=pitft28-resistive,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ -+Name: pps-gpio -+Info: Configures the pps-gpio (pulse-per-second time signal via GPIO). -+Load: dtoverlay=pps-gpio,= -+Params: gpiopin Input GPIO (default "18") -+ -+ -+Name: rpi-dac -+Info: Configures the RPi DAC audio card -+Load: dtoverlay=rpi-dac -+Params: -+ -+ -+Name: rpi-display -+Info: RPi-Display - 2.8" Touch Display by Watterott -+Load: dtoverlay=rpi-display,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ xohms Touchpanel sensitivity (X-plate resistance) -+ -+ -+Name: rpi-proto -+Info: Configures the RPi Proto audio card -+Load: dtoverlay=rpi-proto -+Params: -+ -+ -+Name: sdhost -+Info: Selects the bcm2835-sdhost SD/MMC driver, optionally with overclock -+Load: dtoverlay=sdhost,= -+Params: overclock_50 Clock (in MHz) to use when the MMC framework -+ requests 50MHz -+ force_pio Disable DMA support -+ -+ -+Name: spi-bcm2708 -+Info: Selects the bcm2708-spi SPI driver -+Load: dtoverlay=spi-bcm2708 -+Params: -+ -+ -+Name: spi-bcm2835 -+Info: Selects the bcm2835-spi SPI driver -+Load: dtoverlay=spi-bcm2835 -+Params: -+ -+ -+Name: tinylcd35 -+Info: 3.5" Color TFT Display by www.tinlylcd.com -+ Options: Touch, RTC, keypad -+Load: dtoverlay=tinylcd35,= -+Params: speed Display SPI bus speed -+ -+ rotate Display rotation {0,90,180,270} -+ -+ fps Delay between frame updates -+ -+ debug Debug output level {0-7} -+ -+ touch Enable touch panel -+ -+ touchgpio Touch controller IRQ GPIO -+ -+ xohms Touchpanel: Resistance of X-plate in ohms -+ -+ rtc-pcf PCF8563 Real Time Clock -+ -+ rtc-ds DS1307 Real Time Clock -+ -+ keypad Enable keypad -+ -+ Examples: -+ Display with touchpanel, PCF8563 RTC and keypad: -+ dtoverlay=tinylcd35,touch,rtc-pcf,keypad -+ Old touch display: -+ dtoverlay=tinylcd35,touch,touchgpio=3 -+ -+ -+Name: w1-gpio -+Info: Configures the w1-gpio Onewire interface module. -+ Use this overlay if you *don't* need a GPIO to drive an external pullup. -+Load: dtoverlay=w1-gpio,= -+Params: gpiopin GPIO for I/O (default "4") -+ -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature -+ -+ -+Name: w1-gpio-pullup -+Info: Configures the w1-gpio Onewire interface module. -+ Use this overlay if you *do* need a GPIO to drive an external pullup. -+Load: dtoverlay=w1-gpio-pullup,=,... -+Params: gpiopin GPIO for I/O (default "4") -+ -+ pullup Non-zero, "on", or "y" to enable the parasitic -+ power (2-wire, power-on-data) feature -+ -+ extpullup GPIO for external pullup (default "5") -+ -+ -+Troubleshooting -+=============== -+ -+If you are experiencing problems that you think are DT-related, enable DT -+diagnostic output by adding this to /boot/config.txt: -+ -+ dtdebug=on -+ -+and rebooting. Then run: -+ -+ sudo vcdbg log msg -+ -+and look for relevant messages. -+ -+Further reading -+=============== -+ -+This is only meant to be a quick introduction to the subject of Device Tree on -+Raspberry Pi. There is a more complete explanation here: -+ -+http://www.raspberrypi.org/documentation/configuration/device-tree.md -diff --git a/arch/arm/boot/dts/overlays/ads7846-overlay.dts b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -new file mode 100644 -index 0000000..6a92cd1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ads7846-overlay.dts -@@ -0,0 +1,83 @@ -+/* -+ * Generic Device Tree overlay for the ADS7846 touch controller -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ ads7846_pins: ads7846_pins { -+ brcm,pins = <255>; /* illegal default value */ -+ brcm,function = <0>; /* in */ -+ brcm,pull = <0>; /* none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ads7846: ads7846@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&ads7846_pins>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <255 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 255 0>; -+ -+ /* driver defaults */ -+ ti,x-min = /bits/ 16 <0>; -+ ti,y-min = /bits/ 16 <0>; -+ ti,x-max = /bits/ 16 <0x0FFF>; -+ ti,y-max = /bits/ 16 <0x0FFF>; -+ ti,pressure-min = /bits/ 16 <0>; -+ ti,pressure-max = /bits/ 16 <0xFFFF>; -+ ti,x-plate-ohms = /bits/ 16 <400>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ cs = <&ads7846>,"reg:0"; -+ speed = <&ads7846>,"spi-max-frequency:0"; -+ penirq = <&ads7846_pins>,"brcm,pins:0", /* REQUIRED */ -+ <&ads7846>,"interrupts:0", -+ <&ads7846>,"pendown-gpio:4"; -+ penirq_pull = <&ads7846_pins>,"brcm,pull:0"; -+ swapxy = <&ads7846>,"ti,swap-xy?"; -+ xmin = <&ads7846>,"ti,x-min;0"; -+ ymin = <&ads7846>,"ti,y-min;0"; -+ xmax = <&ads7846>,"ti,x-max;0"; -+ ymax = <&ads7846>,"ti,y-max;0"; -+ pmin = <&ads7846>,"ti,pressure-min;0"; -+ pmax = <&ads7846>,"ti,pressure-max;0"; -+ xohms = <&ads7846>,"ti,x-plate-ohms;0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -new file mode 100644 -index 0000000..b830bf2 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/bmp085_i2c-sensor-overlay.dts -@@ -0,0 +1,23 @@ -+// Definitions for BMP085/BMP180 digital barometric pressure and temperature sensors from Bosch Sensortec -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ bmp085@77 { -+ compatible = "bosch,bmp085"; -+ reg = <0x77>; -+ default-oversampling = <3>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts b/arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts -new file mode 100644 -index 0000000..7d27044 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/ds1307-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for DS1307 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/enc28j60-overlay.dts b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -new file mode 100644 -index 0000000..aa9b645 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/enc28j60-overlay.dts -@@ -0,0 +1,29 @@ -+// Overlay for the Microchip ENC28J60 Ethernet Controller -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ enc28j60@0{ -+ compatible = "microchip,enc28j60"; -+ reg = <0>; /* CE0 */ -+ spi-max-frequency = <12000000>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts -new file mode 100644 -index 0000000..2c81448 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-amp-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Amp/Amp+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-amp"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ tas5713@1b { -+ #sound-dai-cells = <0>; -+ compatible = "ti,tas5713"; -+ reg = <0x1b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts -new file mode 100644 -index 0000000..5e7633a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for HiFiBerry DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm5102a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5102a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -new file mode 100644 -index 0000000..deb9c625 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-dacplus"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4d { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4d>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts -new file mode 100644 -index 0000000..d0e0d8a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hifiberry-digi-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for HiFiBerry Digi -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "hifiberry,hifiberry-digi"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8804@3b { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8804"; -+ reg = <0x3b>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hy28a-overlay.dts b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -new file mode 100644 -index 0000000..3cd3083 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hy28a-overlay.dts -@@ -0,0 +1,87 @@ -+/* -+ * Device Tree overlay for HY28A display -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28a_pins: hy28a_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28a: hy28a@0{ -+ compatible = "ilitek,ili9320"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28a_pins>; -+ -+ spi-max-frequency = <32000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ hy28a_ts: hy28a-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28a>,"spi-max-frequency:0"; -+ rotate = <&hy28a>,"rotate:0"; -+ fps = <&hy28a>,"fps:0"; -+ debug = <&hy28a>,"debug:0"; -+ xohms = <&hy28a_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28a>,"reset-gpios:4", -+ <&hy28a_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28a>,"led-gpios:4", -+ <&hy28a_pins>, "brcm,pins:2"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/hy28b-overlay.dts b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -new file mode 100644 -index 0000000..f774c4a ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/hy28b-overlay.dts -@@ -0,0 +1,142 @@ -+/* -+ * Device Tree overlay for HY28b display shield by Texy -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ hy28b_pins: hy28b_pins { -+ brcm,pins = <17 25 18>; -+ brcm,function = <0 1 1>; /* in out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ hy28b: hy28b@0{ -+ compatible = "ilitek,ili9325"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&hy28b_pins>; -+ -+ spi-max-frequency = <48000000>; -+ spi-cpol; -+ spi-cpha; -+ rotate = <270>; -+ bgr; -+ fps = <50>; -+ buswidth = <8>; -+ startbyte = <0x70>; -+ reset-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 1>; -+ -+ gamma = "04 1F 4 7 7 0 7 7 6 0\n0F 00 1 7 4 0 0 0 6 7"; -+ -+ init = <0x10000e7 0x0010 -+ 0x1000000 0x0001 -+ 0x1000001 0x0100 -+ 0x1000002 0x0700 -+ 0x1000003 0x1030 -+ 0x1000004 0x0000 -+ 0x1000008 0x0207 -+ 0x1000009 0x0000 -+ 0x100000a 0x0000 -+ 0x100000c 0x0001 -+ 0x100000d 0x0000 -+ 0x100000f 0x0000 -+ 0x1000010 0x0000 -+ 0x1000011 0x0007 -+ 0x1000012 0x0000 -+ 0x1000013 0x0000 -+ 0x2000032 -+ 0x1000010 0x1590 -+ 0x1000011 0x0227 -+ 0x2000032 -+ 0x1000012 0x009c -+ 0x2000032 -+ 0x1000013 0x1900 -+ 0x1000029 0x0023 -+ 0x100002b 0x000e -+ 0x2000032 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000032 -+ 0x1000050 0x0000 -+ 0x1000051 0x00ef -+ 0x1000052 0x0000 -+ 0x1000053 0x013f -+ 0x1000060 0xa700 -+ 0x1000061 0x0001 -+ 0x100006a 0x0000 -+ 0x1000080 0x0000 -+ 0x1000081 0x0000 -+ 0x1000082 0x0000 -+ 0x1000083 0x0000 -+ 0x1000084 0x0000 -+ 0x1000085 0x0000 -+ 0x1000090 0x0010 -+ 0x1000092 0x0000 -+ 0x1000093 0x0003 -+ 0x1000095 0x0110 -+ 0x1000097 0x0000 -+ 0x1000098 0x0000 -+ 0x1000007 0x0133 -+ 0x1000020 0x0000 -+ 0x1000021 0x0000 -+ 0x2000064>; -+ debug = <0>; -+ }; -+ -+ hy28b_ts: hy28b-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&hy28b>,"spi-max-frequency:0"; -+ rotate = <&hy28b>,"rotate:0"; -+ fps = <&hy28b>,"fps:0"; -+ debug = <&hy28b>,"debug:0"; -+ xohms = <&hy28b_ts>,"ti,x-plate-ohms;0"; -+ resetgpio = <&hy28b>,"reset-gpios:4", -+ <&hy28b_pins>, "brcm,pins:1"; -+ ledgpio = <&hy28b>,"led-gpios:4", -+ <&hy28b_pins>, "brcm,pins:2"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -new file mode 100644 -index 0000000..6bccfdc ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/i2c-rtc-overlay.dts -@@ -0,0 +1,49 @@ -+// Definitions for several I2C based Real Time Clocks -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ ds3231: ds3231@68 { -+ compatible = "maxim,ds3231"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ pcf2127: pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "disable"; -+ }; -+ pcf8523: pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "disable"; -+ }; -+ pcf8563: pcf8563@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ status = "disable"; -+ }; -+ }; -+ }; -+ __overrides__ { -+ ds1307 = <&ds1307>,"status"; -+ ds3231 = <&ds3231>,"status"; -+ pcf2127 = <&pcf2127>,"status"; -+ pcf8523 = <&pcf8523>,"status"; -+ pcf8563 = <&pcf8563>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts -new file mode 100644 -index 0000000..ea8173e ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/iqaudio-dac-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -new file mode 100644 -index 0000000..735d8ab ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/iqaudio-dacplus-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for IQaudIO DAC+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "iqaudio,iqaudio-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcm5122@4c { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm5122"; -+ reg = <0x4c>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts -new file mode 100644 -index 0000000..7d5d82b ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/lirc-rpi-overlay.dts -@@ -0,0 +1,57 @@ -+// Definitions for lirc-rpi module -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ lirc_rpi: lirc_rpi { -+ compatible = "rpi,lirc-rpi"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&lirc_pins>; -+ status = "okay"; -+ -+ // Override autodetection of IR receiver circuit -+ // (0 = active high, 1 = active low, -1 = no override ) -+ rpi,sense = <0xffffffff>; -+ -+ // Software carrier -+ // (0 = off, 1 = on) -+ rpi,softcarrier = <1>; -+ -+ // Invert output -+ // (0 = off, 1 = on) -+ rpi,invert = <0>; -+ -+ // Enable debugging messages -+ // (0 = off, 1 = on) -+ rpi,debug = <0>; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ lirc_pins: lirc_pins { -+ brcm,pins = <17 18>; -+ brcm,function = <1 0>; // out in -+ brcm,pull = <0 1>; // off down -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpio_out_pin = <&lirc_pins>,"brcm,pins:0"; -+ gpio_in_pin = <&lirc_pins>,"brcm,pins:4"; -+ gpio_in_pull = <&lirc_pins>,"brcm,pull:4"; -+ -+ sense = <&lirc_rpi>,"rpi,sense:0"; -+ softcarrier = <&lirc_rpi>,"rpi,softcarrier:0"; -+ invert = <&lirc_rpi>,"rpi,invert:0"; -+ debug = <&lirc_rpi>,"rpi,debug:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/mmc-overlay.dts b/arch/arm/boot/dts/overlays/mmc-overlay.dts -new file mode 100644 -index 0000000..0a37cf4 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mmc-overlay.dts -@@ -0,0 +1,19 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&mmc>; -+ -+ __overlay__ { -+ brcm,overclock-50 = <0>; -+ }; -+ }; -+ -+ __overrides__ { -+ overclock_50 = <&mmc>,"brcm,overclock-50:0"; -+ force_pio = <&mmc>,"brcm,force-pio?"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/mz61581-overlay.dts b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -new file mode 100644 -index 0000000..c06fe12 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mz61581-overlay.dts -@@ -0,0 +1,109 @@ -+/* -+ * Device Tree overlay for MZ61581-PI-EXT 2014.12.28 by Tontec -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ mz61581_pins: mz61581_pins { -+ brcm,pins = <4 15 18 25>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ mz61581: mz61581@0{ -+ compatible = "samsung,s6d02a1"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mz61581_pins>; -+ -+ spi-max-frequency = <128000000>; -+ spi-cpol; -+ spi-cpha; -+ -+ width = <320>; -+ height = <480>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ -+ reset-gpios = <&gpio 15 0>; -+ dc-gpios = <&gpio 25 0>; -+ led-gpios = <&gpio 18 0>; -+ -+ init = <0x10000b0 00 -+ 0x1000011 -+ 0x20000ff -+ 0x10000b3 0x02 0x00 0x00 0x00 -+ 0x10000c0 0x13 0x3b 0x00 0x02 0x00 0x01 0x00 0x43 -+ 0x10000c1 0x08 0x16 0x08 0x08 -+ 0x10000c4 0x11 0x07 0x03 0x03 -+ 0x10000c6 0x00 -+ 0x10000c8 0x03 0x03 0x13 0x5c 0x03 0x07 0x14 0x08 0x00 0x21 0x08 0x14 0x07 0x53 0x0c 0x13 0x03 0x03 0x21 0x00 -+ 0x1000035 0x00 -+ 0x1000036 0xa0 -+ 0x100003a 0x55 -+ 0x1000044 0x00 0x01 -+ 0x10000d0 0x07 0x07 0x1d 0x03 -+ 0x10000d1 0x03 0x30 0x10 -+ 0x10000d2 0x03 0x14 0x04 -+ 0x1000029 -+ 0x100002c>; -+ -+ /* This is a workaround to make sure the init sequence slows down and doesn't fail */ -+ debug = <3>; -+ }; -+ -+ mz61581_ts: mz61581_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <4 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 4 0>; -+ -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&mz61581>, "spi-max-frequency:0"; -+ rotate = <&mz61581>, "rotate:0"; -+ fps = <&mz61581>, "fps:0"; -+ debug = <&mz61581>, "debug:0"; -+ xohms = <&mz61581_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts b/arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts -new file mode 100644 -index 0000000..01fc81d ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pcf2127-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF2127 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf2127@51 { -+ compatible = "nxp,pcf2127"; -+ reg = <0x51>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts -new file mode 100644 -index 0000000..0071f62 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pcf8523-rtc-overlay.dts -@@ -0,0 +1,22 @@ -+// Definitions for PCF8523 Real Time Clock -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ pcf8523@68 { -+ compatible = "nxp,pcf8523"; -+ reg = <0x68>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -new file mode 100644 -index 0000000..b7fd7ea ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -0,0 +1,94 @@ -+/* -+ * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ piscreen_pins: piscreen_pins { -+ brcm,pins = <17 25 24 22>; -+ brcm,function = <0 1 1 1>; /* in out out out */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ piscreen: piscreen@0{ -+ compatible = "ilitek,ili9486"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&piscreen_pins>; -+ -+ spi-max-frequency = <24000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ regwidth = <16>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 22 1>; -+ debug = <0>; -+ -+ init = <0x10000b0 0x00 -+ 0x1000011 -+ 0x20000ff -+ 0x100003a 0x55 -+ 0x1000036 0x28 -+ 0x10000c2 0x44 -+ 0x10000c5 0x00 0x00 0x00 0x00 -+ 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 -+ 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -+ 0x1000011 -+ 0x1000029>; -+ }; -+ -+ piscreen-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <17 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 17 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&piscreen>,"spi-max-frequency:0"; -+ rotate = <&piscreen>,"rotate:0"; -+ fps = <&piscreen>,"fps:0"; -+ debug = <&piscreen>,"debug:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -new file mode 100644 -index 0000000..d506eae ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pitft28-resistive-overlay.dts -@@ -0,0 +1,115 @@ -+/* -+ * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pitft_pins: pitft_pins { -+ brcm,pins = <24 25>; -+ brcm,function = <0 1>; /* in out */ -+ brcm,pull = <2 0>; /* pullup none */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pitft: pitft@0{ -+ compatible = "ilitek,ili9340"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pitft_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <90>; -+ fps = <25>; -+ bgr; -+ buswidth = <8>; -+ dc-gpios = <&gpio 25 0>; -+ debug = <0>; -+ }; -+ -+ pitft_ts@1 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "st,stmpe610"; -+ reg = <1>; -+ -+ spi-max-frequency = <500000>; -+ irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ -+ interrupts = <24 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ interrupt-controller; -+ -+ stmpe_touchscreen { -+ compatible = "st,stmpe-ts"; -+ st,sample-time = <4>; -+ st,mod-12b = <1>; -+ st,ref-sel = <0>; -+ st,adc-freq = <2>; -+ st,ave-ctrl = <3>; -+ st,touch-det-delay = <4>; -+ st,settling = <2>; -+ st,fraction-z = <7>; -+ st,i-drive = <0>; -+ }; -+ -+ stmpe_gpio: stmpe_gpio { -+ #gpio-cells = <2>; -+ compatible = "st,stmpe-gpio"; -+ /* -+ * only GPIO2 is wired/available -+ * and it is wired to the backlight -+ */ -+ st,norequest-mask = <0x7b>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/soc"; -+ __overlay__ { -+ backlight { -+ compatible = "gpio-backlight"; -+ gpios = <&stmpe_gpio 2 0>; -+ default-on; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&pitft>,"spi-max-frequency:0"; -+ rotate = <&pitft>,"rotate:0"; -+ fps = <&pitft>,"fps:0"; -+ debug = <&pitft>,"debug:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts -new file mode 100644 -index 0000000..40bf0e1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/pps-gpio-overlay.dts -@@ -0,0 +1,34 @@ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ pps: pps { -+ compatible = "pps-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pps_pins>; -+ gpios = <&gpio 18 0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ pps_pins: pps_pins { -+ brcm,pins = <18>; -+ brcm,function = <0>; // in -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&pps>,"gpios:4", -+ <&pps_pins>,"brcm,pins:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts -new file mode 100644 -index 0000000..7fc6ac9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-dac-overlay.dts -@@ -0,0 +1,34 @@ -+// Definitions for RPi DAC -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-dac"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target-path = "/"; -+ __overlay__ { -+ pcm1794a-codec { -+ #sound-dai-cells = <0>; -+ compatible = "ti,pcm1794a"; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/rpi-display-overlay.dts b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -new file mode 100644 -index 0000000..a8fa974 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-display-overlay.dts -@@ -0,0 +1,82 @@ -+/* -+ * Device Tree overlay for rpi-display by Watterott -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ rpi_display_pins: rpi_display_pins { -+ brcm,pins = <18 23 24 25>; -+ brcm,function = <1 1 1 0>; /* out out out in */ -+ brcm,pull = <0 0 0 2>; /* - - - up */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ rpidisplay: rpi-display@0{ -+ compatible = "ilitek,ili9341"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&rpi_display_pins>; -+ -+ spi-max-frequency = <32000000>; -+ rotate = <270>; -+ bgr; -+ fps = <30>; -+ buswidth = <8>; -+ reset-gpios = <&gpio 23 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ }; -+ -+ rpidisplay_ts: rpi-display-ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <25 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 25 0>; -+ ti,x-plate-ohms = /bits/ 16 <60>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ speed = <&rpidisplay>,"spi-max-frequency:0"; -+ rotate = <&rpidisplay>,"rotate:0"; -+ fps = <&rpidisplay>,"fps:0"; -+ debug = <&rpidisplay>,"debug:0"; -+ xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts -new file mode 100644 -index 0000000..2029930 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/rpi-proto-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for Rpi-Proto -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&sound>; -+ __overlay__ { -+ compatible = "rpi,rpi-proto"; -+ i2s-controller = <&i2s>; -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&i2s>; -+ __overlay__ { -+ status = "okay"; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ status = "okay"; -+ -+ wm8731@1a { -+ #sound-dai-cells = <0>; -+ compatible = "wlf,wm8731"; -+ reg = <0x1a>; -+ status = "okay"; -+ }; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -new file mode 100644 -index 0000000..b2653e9 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -0,0 +1,75 @@ -+/dts-v1/; -+/plugin/; -+ -+/{ -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target = <&soc>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ sdhost: sdhost@7e202000 { -+ compatible = "brcm,bcm2835-sdhost"; -+ reg = <0x7e202000 0x100>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&sdhost_pins>; -+ interrupts = <2 24>; -+ clocks = <&clk_sdhost>; -+ dmas = <&dma 13>, -+ <&dma 13>; -+ dma-names = "tx", "rx"; -+ brcm,delay-after-stop = <0>; -+ brcm,overclock-50 = <0>; -+ status = "okay"; -+ }; -+ -+ clocks { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ clk_sdhost: clock@3 { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; -+ }; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ sdhost_pins: sdhost_pins { -+ brcm,pins = <48 49 50 51 52 53>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&mmc>; -+ __overlay__ { -+ /* Find a way to disable the other driver */ -+ compatible = ""; -+ status = "disabled"; -+ }; -+ }; -+ -+ fragment@3 { -+ target-path = "/__overrides__"; -+ __overlay__ { -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+ }; -+ -+ __overrides__ { -+ delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -+ overclock_50 = <&sdhost>,"brcm,overclock-50:0"; -+ force_pio = <&sdhost>,"brcm,force-pio?"; -+ sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts -new file mode 100644 -index 0000000..e378ef1 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-bcm2708-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2708-spi"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts -new file mode 100644 -index 0000000..fc1e39b ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/spi-bcm2835-overlay.dts -@@ -0,0 +1,18 @@ -+/* -+ * Device tree overlay for spi-bcm2835 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ compatible = "brcm,bcm2835-spi"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -new file mode 100644 -index 0000000..f7102c8 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/tinylcd35-overlay.dts -@@ -0,0 +1,216 @@ -+/* -+ * tinylcd35-overlay.dts -+ * -+ * ------------------------------------------------- -+ * www.tinlylcd.com -+ * ------------------------------------------------- -+ * Device---Driver-----BUS GPIO's -+ * display tinylcd35 spi0.0 25 24 18 -+ * touch ads7846 spi0.1 5 -+ * rtc ds1307 i2c1-0068 -+ * rtc pcf8563 i2c1-0051 -+ * keypad gpio-keys --------- 17 22 27 23 28 -+ * -+ * -+ * TinyLCD.com 3.5 inch TFT -+ * -+ * Version 001 -+ * 5/3/2015 -- Noralf Trønnes Initial Device tree framework -+ * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. -+ * -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -+ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ -+ spidev@0{ -+ status = "disabled"; -+ }; -+ -+ spidev@1{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ tinylcd35_pins: tinylcd35_pins { -+ brcm,pins = <25 24 18>; -+ brcm,function = <1>; /* out */ -+ }; -+ tinylcd35_ts_pins: tinylcd35_ts_pins { -+ brcm,pins = <5>; -+ brcm,function = <0>; /* in */ -+ }; -+ keypad_pins: keypad_pins { -+ brcm,pins = <4 17 22 23 27>; -+ brcm,function = <0>; /* in */ -+ brcm,pull = <1>; /* down */ -+ }; -+ }; -+ }; -+ -+ fragment@2 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ tinylcd35: tinylcd35@0{ -+ compatible = "neosec,tinylcd"; -+ reg = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&tinylcd35_pins>, -+ <&tinylcd35_ts_pins>; -+ -+ spi-max-frequency = <48000000>; -+ rotate = <270>; -+ fps = <20>; -+ bgr; -+ buswidth = <8>; -+ reset-gpios = <&gpio 25 0>; -+ dc-gpios = <&gpio 24 0>; -+ led-gpios = <&gpio 18 1>; -+ debug = <0>; -+ -+ init = <0x10000B0 0x80 -+ 0x10000C0 0x0A 0x0A -+ 0x10000C1 0x01 0x01 -+ 0x10000C2 0x33 -+ 0x10000C5 0x00 0x42 0x80 -+ 0x10000B1 0xD0 0x11 -+ 0x10000B4 0x02 -+ 0x10000B6 0x00 0x22 0x3B -+ 0x10000B7 0x07 -+ 0x1000036 0x58 -+ 0x10000F0 0x36 0xA5 0xD3 -+ 0x10000E5 0x80 -+ 0x10000E5 0x01 -+ 0x10000B3 0x00 -+ 0x10000E5 0x00 -+ 0x10000F0 0x36 0xA5 0x53 -+ 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 -+ 0x100003A 0x55 -+ 0x1000011 -+ 0x2000001 -+ 0x1000029>; -+ }; -+ -+ tinylcd35_ts: tinylcd35_ts@1 { -+ compatible = "ti,ads7846"; -+ reg = <1>; -+ status = "disabled"; -+ -+ spi-max-frequency = <2000000>; -+ interrupts = <5 2>; /* high-to-low edge triggered */ -+ interrupt-parent = <&gpio>; -+ pendown-gpio = <&gpio 5 0>; -+ ti,x-plate-ohms = /bits/ 16 <100>; -+ ti,pressure-max = /bits/ 16 <255>; -+ }; -+ }; -+ }; -+ -+ /* RTC */ -+ -+ fragment@3 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ pcf8563: pcf8563@51 { -+ compatible = "nxp,pcf8563"; -+ reg = <0x51>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ fragment@4 { -+ target = <&i2c1>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ ds1307: ds1307@68 { -+ compatible = "maxim,ds1307"; -+ reg = <0x68>; -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* -+ * Values for input event code is found under the -+ * 'Keys and buttons' heading in include/uapi/linux/input.h -+ */ -+ fragment@5 { -+ target-path = "/soc"; -+ __overlay__ { -+ keypad: keypad { -+ compatible = "gpio-keys"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&keypad_pins>; -+ status = "disabled"; -+ autorepeat; -+ -+ button@17 { -+ label = "GPIO KEY_UP"; -+ linux,code = <103>; -+ gpios = <&gpio 17 0>; -+ }; -+ button@22 { -+ label = "GPIO KEY_DOWN"; -+ linux,code = <108>; -+ gpios = <&gpio 22 0>; -+ }; -+ button@27 { -+ label = "GPIO KEY_LEFT"; -+ linux,code = <105>; -+ gpios = <&gpio 27 0>; -+ }; -+ button@23 { -+ label = "GPIO KEY_RIGHT"; -+ linux,code = <106>; -+ gpios = <&gpio 23 0>; -+ }; -+ button@4 { -+ label = "GPIO KEY_ENTER"; -+ linux,code = <28>; -+ gpios = <&gpio 4 0>; -+ }; -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ speed = <&tinylcd35>,"spi-max-frequency:0"; -+ rotate = <&tinylcd35>,"rotate:0"; -+ fps = <&tinylcd35>,"fps:0"; -+ debug = <&tinylcd35>,"debug:0"; -+ touch = <&tinylcd35_ts>,"status"; -+ touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", -+ <&tinylcd35_ts>,"interrupts:0", -+ <&tinylcd35_ts>,"pendown-gpio:4"; -+ xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; -+ rtc-pcf = <&i2c1>,"status", -+ <&pcf8563>,"status"; -+ rtc-ds = <&i2c1>,"status", -+ <&ds1307>,"status"; -+ keypad = <&keypad>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -new file mode 100644 -index 0000000..29a3b48 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/w1-gpio-overlay.dts -@@ -0,0 +1,39 @@ -+// Definitions for w1-gpio module (without external pullup) -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>; -+ rpi,parasitic-power = <0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4>; -+ brcm,function = <0>; // in (initially) -+ brcm,pull = <0>; // off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -new file mode 100644 -index 0000000..66a98f6 ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/w1-gpio-pullup-overlay.dts -@@ -0,0 +1,41 @@ -+// Definitions for w1-gpio module (with external pullup) -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2708"; -+ -+ fragment@0 { -+ target-path = "/"; -+ __overlay__ { -+ -+ w1: onewire@0 { -+ compatible = "w1-gpio"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&w1_pins>; -+ gpios = <&gpio 4 0>, <&gpio 5 1>; -+ rpi,parasitic-power = <0>; -+ status = "okay"; -+ }; -+ }; -+ }; -+ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ w1_pins: w1_pins { -+ brcm,pins = <4 5>; -+ brcm,function = <0 1>; // in out -+ brcm,pull = <0 0>; // off off -+ }; -+ }; -+ }; -+ -+ __overrides__ { -+ gpiopin = <&w1>,"gpios:4", -+ <&w1_pins>,"brcm,pins:0"; -+ extpullup = <&w1>,"gpios:16", -+ <&w1_pins>,"brcm,pins:4"; -+ pullup = <&w1>,"rpi,parasitic-power:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/pcf2127-rtc-overlay.dts b/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -deleted file mode 100644 -index 01fc81d..0000000 ---- a/arch/arm/boot/dts/pcf2127-rtc-overlay.dts -+++ /dev/null -@@ -1,22 +0,0 @@ --// Definitions for PCF2127 Real Time Clock --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcf2127@51 { -- compatible = "nxp,pcf2127"; -- reg = <0x51>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts b/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -deleted file mode 100644 -index 0071f62..0000000 ---- a/arch/arm/boot/dts/pcf8523-rtc-overlay.dts -+++ /dev/null -@@ -1,22 +0,0 @@ --// Definitions for PCF8523 Real Time Clock --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- pcf8523@68 { -- compatible = "nxp,pcf8523"; -- reg = <0x68>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/piscreen-overlay.dts b/arch/arm/boot/dts/piscreen-overlay.dts -deleted file mode 100644 -index b7fd7ea..0000000 ---- a/arch/arm/boot/dts/piscreen-overlay.dts -+++ /dev/null -@@ -1,94 +0,0 @@ --/* -- * Device Tree overlay for PiScreen 3.5" display shield by Ozzmaker -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- piscreen_pins: piscreen_pins { -- brcm,pins = <17 25 24 22>; -- brcm,function = <0 1 1 1>; /* in out out out */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- piscreen: piscreen@0{ -- compatible = "ilitek,ili9486"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&piscreen_pins>; -- -- spi-max-frequency = <24000000>; -- rotate = <270>; -- bgr; -- fps = <30>; -- buswidth = <8>; -- regwidth = <16>; -- reset-gpios = <&gpio 25 0>; -- dc-gpios = <&gpio 24 0>; -- led-gpios = <&gpio 22 1>; -- debug = <0>; -- -- init = <0x10000b0 0x00 -- 0x1000011 -- 0x20000ff -- 0x100003a 0x55 -- 0x1000036 0x28 -- 0x10000c2 0x44 -- 0x10000c5 0x00 0x00 0x00 0x00 -- 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 -- 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -- 0x10000e2 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 -- 0x1000011 -- 0x1000029>; -- }; -- -- piscreen-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <17 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 17 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&piscreen>,"spi-max-frequency:0"; -- rotate = <&piscreen>,"rotate:0"; -- fps = <&piscreen>,"fps:0"; -- debug = <&piscreen>,"debug:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/pitft28-resistive-overlay.dts b/arch/arm/boot/dts/pitft28-resistive-overlay.dts -deleted file mode 100644 -index d506eae..0000000 ---- a/arch/arm/boot/dts/pitft28-resistive-overlay.dts -+++ /dev/null -@@ -1,115 +0,0 @@ --/* -- * Device Tree overlay for Adafruit PiTFT 2.8" resistive touch screen -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- pitft_pins: pitft_pins { -- brcm,pins = <24 25>; -- brcm,function = <0 1>; /* in out */ -- brcm,pull = <2 0>; /* pullup none */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- pitft: pitft@0{ -- compatible = "ilitek,ili9340"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&pitft_pins>; -- -- spi-max-frequency = <32000000>; -- rotate = <90>; -- fps = <25>; -- bgr; -- buswidth = <8>; -- dc-gpios = <&gpio 25 0>; -- debug = <0>; -- }; -- -- pitft_ts@1 { -- #address-cells = <1>; -- #size-cells = <0>; -- compatible = "st,stmpe610"; -- reg = <1>; -- -- spi-max-frequency = <500000>; -- irq-gpio = <&gpio 24 0x2>; /* IRQF_TRIGGER_FALLING */ -- interrupts = <24 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- interrupt-controller; -- -- stmpe_touchscreen { -- compatible = "st,stmpe-ts"; -- st,sample-time = <4>; -- st,mod-12b = <1>; -- st,ref-sel = <0>; -- st,adc-freq = <2>; -- st,ave-ctrl = <3>; -- st,touch-det-delay = <4>; -- st,settling = <2>; -- st,fraction-z = <7>; -- st,i-drive = <0>; -- }; -- -- stmpe_gpio: stmpe_gpio { -- #gpio-cells = <2>; -- compatible = "st,stmpe-gpio"; -- /* -- * only GPIO2 is wired/available -- * and it is wired to the backlight -- */ -- st,norequest-mask = <0x7b>; -- }; -- }; -- }; -- }; -- -- fragment@3 { -- target-path = "/soc"; -- __overlay__ { -- backlight { -- compatible = "gpio-backlight"; -- gpios = <&stmpe_gpio 2 0>; -- default-on; -- }; -- }; -- }; -- -- __overrides__ { -- speed = <&pitft>,"spi-max-frequency:0"; -- rotate = <&pitft>,"rotate:0"; -- fps = <&pitft>,"fps:0"; -- debug = <&pitft>,"debug:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/pps-gpio-overlay.dts b/arch/arm/boot/dts/pps-gpio-overlay.dts -deleted file mode 100644 -index 40bf0e1..0000000 ---- a/arch/arm/boot/dts/pps-gpio-overlay.dts -+++ /dev/null -@@ -1,34 +0,0 @@ --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- pps: pps { -- compatible = "pps-gpio"; -- pinctrl-names = "default"; -- pinctrl-0 = <&pps_pins>; -- gpios = <&gpio 18 0>; -- status = "okay"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- pps_pins: pps_pins { -- brcm,pins = <18>; -- brcm,function = <0>; // in -- brcm,pull = <0>; // off -- }; -- }; -- }; -- -- __overrides__ { -- gpiopin = <&pps>,"gpios:4", -- <&pps_pins>,"brcm,pins:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/rpi-dac-overlay.dts b/arch/arm/boot/dts/rpi-dac-overlay.dts -deleted file mode 100644 -index 7fc6ac9..0000000 ---- a/arch/arm/boot/dts/rpi-dac-overlay.dts -+++ /dev/null -@@ -1,34 +0,0 @@ --// Definitions for RPi DAC --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "rpi,rpi-dac"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target-path = "/"; -- __overlay__ { -- pcm1794a-codec { -- #sound-dai-cells = <0>; -- compatible = "ti,pcm1794a"; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/rpi-display-overlay.dts b/arch/arm/boot/dts/rpi-display-overlay.dts -deleted file mode 100644 -index a8fa974..0000000 ---- a/arch/arm/boot/dts/rpi-display-overlay.dts -+++ /dev/null -@@ -1,82 +0,0 @@ --/* -- * Device Tree overlay for rpi-display by Watterott -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- rpi_display_pins: rpi_display_pins { -- brcm,pins = <18 23 24 25>; -- brcm,function = <1 1 1 0>; /* out out out in */ -- brcm,pull = <0 0 0 2>; /* - - - up */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- rpidisplay: rpi-display@0{ -- compatible = "ilitek,ili9341"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&rpi_display_pins>; -- -- spi-max-frequency = <32000000>; -- rotate = <270>; -- bgr; -- fps = <30>; -- buswidth = <8>; -- reset-gpios = <&gpio 23 0>; -- dc-gpios = <&gpio 24 0>; -- led-gpios = <&gpio 18 1>; -- debug = <0>; -- }; -- -- rpidisplay_ts: rpi-display-ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- -- spi-max-frequency = <2000000>; -- interrupts = <25 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 25 0>; -- ti,x-plate-ohms = /bits/ 16 <60>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- __overrides__ { -- speed = <&rpidisplay>,"spi-max-frequency:0"; -- rotate = <&rpidisplay>,"rotate:0"; -- fps = <&rpidisplay>,"fps:0"; -- debug = <&rpidisplay>,"debug:0"; -- xohms = <&rpidisplay_ts>,"ti,x-plate-ohms;0"; -- }; --}; -diff --git a/arch/arm/boot/dts/rpi-proto-overlay.dts b/arch/arm/boot/dts/rpi-proto-overlay.dts -deleted file mode 100644 -index 2029930..0000000 ---- a/arch/arm/boot/dts/rpi-proto-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for Rpi-Proto --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&sound>; -- __overlay__ { -- compatible = "rpi,rpi-proto"; -- i2s-controller = <&i2s>; -- status = "okay"; -- }; -- }; -- -- fragment@1 { -- target = <&i2s>; -- __overlay__ { -- status = "okay"; -- }; -- }; -- -- fragment@2 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- status = "okay"; -- -- wm8731@1a { -- #sound-dai-cells = <0>; -- compatible = "wlf,wm8731"; -- reg = <0x1a>; -- status = "okay"; -- }; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/sdhost-overlay.dts b/arch/arm/boot/dts/sdhost-overlay.dts -deleted file mode 100644 -index b2653e9..0000000 ---- a/arch/arm/boot/dts/sdhost-overlay.dts -+++ /dev/null -@@ -1,75 +0,0 @@ --/dts-v1/; --/plugin/; -- --/{ -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target = <&soc>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <1>; -- -- sdhost: sdhost@7e202000 { -- compatible = "brcm,bcm2835-sdhost"; -- reg = <0x7e202000 0x100>; -- pinctrl-names = "default"; -- pinctrl-0 = <&sdhost_pins>; -- interrupts = <2 24>; -- clocks = <&clk_sdhost>; -- dmas = <&dma 13>, -- <&dma 13>; -- dma-names = "tx", "rx"; -- brcm,delay-after-stop = <0>; -- brcm,overclock-50 = <0>; -- status = "okay"; -- }; -- -- clocks { -- #address-cells = <1>; -- #size-cells = <0>; -- -- clk_sdhost: clock@3 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "sdhost"; -- clock-frequency = <250000000>; -- }; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- sdhost_pins: sdhost_pins { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <4>; /* alt0 */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&mmc>; -- __overlay__ { -- /* Find a way to disable the other driver */ -- compatible = ""; -- status = "disabled"; -- }; -- }; -- -- fragment@3 { -- target-path = "/__overrides__"; -- __overlay__ { -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -- }; -- }; -- -- __overrides__ { -- delay_after_stop = <&sdhost>,"brcm,delay-after-stop:0"; -- overclock_50 = <&sdhost>,"brcm,overclock-50:0"; -- force_pio = <&sdhost>,"brcm,force-pio?"; -- sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/spi-bcm2708-overlay.dts b/arch/arm/boot/dts/spi-bcm2708-overlay.dts -deleted file mode 100644 -index e378ef1..0000000 ---- a/arch/arm/boot/dts/spi-bcm2708-overlay.dts -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- * Device tree overlay for spi-bcm2835 -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -- /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- compatible = "brcm,bcm2708-spi"; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/spi-bcm2835-overlay.dts b/arch/arm/boot/dts/spi-bcm2835-overlay.dts -deleted file mode 100644 -index fc1e39b..0000000 ---- a/arch/arm/boot/dts/spi-bcm2835-overlay.dts -+++ /dev/null -@@ -1,18 +0,0 @@ --/* -- * Device tree overlay for spi-bcm2835 -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -- /* setting up compatiblity to allow loading the spi-bcm2835 driver */ -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- compatible = "brcm,bcm2835-spi"; -- }; -- }; --}; -diff --git a/arch/arm/boot/dts/tinylcd35-overlay.dts b/arch/arm/boot/dts/tinylcd35-overlay.dts -deleted file mode 100644 -index f7102c8..0000000 ---- a/arch/arm/boot/dts/tinylcd35-overlay.dts -+++ /dev/null -@@ -1,216 +0,0 @@ --/* -- * tinylcd35-overlay.dts -- * -- * ------------------------------------------------- -- * www.tinlylcd.com -- * ------------------------------------------------- -- * Device---Driver-----BUS GPIO's -- * display tinylcd35 spi0.0 25 24 18 -- * touch ads7846 spi0.1 5 -- * rtc ds1307 i2c1-0068 -- * rtc pcf8563 i2c1-0051 -- * keypad gpio-keys --------- 17 22 27 23 28 -- * -- * -- * TinyLCD.com 3.5 inch TFT -- * -- * Version 001 -- * 5/3/2015 -- Noralf Trønnes Initial Device tree framework -- * 10/3/2015 -- tinylcd@gmail.com added ds1307 support. -- * -- */ -- --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -- -- fragment@0 { -- target = <&spi0>; -- __overlay__ { -- status = "okay"; -- -- spidev@0{ -- status = "disabled"; -- }; -- -- spidev@1{ -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- tinylcd35_pins: tinylcd35_pins { -- brcm,pins = <25 24 18>; -- brcm,function = <1>; /* out */ -- }; -- tinylcd35_ts_pins: tinylcd35_ts_pins { -- brcm,pins = <5>; -- brcm,function = <0>; /* in */ -- }; -- keypad_pins: keypad_pins { -- brcm,pins = <4 17 22 23 27>; -- brcm,function = <0>; /* in */ -- brcm,pull = <1>; /* down */ -- }; -- }; -- }; -- -- fragment@2 { -- target = <&spi0>; -- __overlay__ { -- /* needed to avoid dtc warning */ -- #address-cells = <1>; -- #size-cells = <0>; -- -- tinylcd35: tinylcd35@0{ -- compatible = "neosec,tinylcd"; -- reg = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&tinylcd35_pins>, -- <&tinylcd35_ts_pins>; -- -- spi-max-frequency = <48000000>; -- rotate = <270>; -- fps = <20>; -- bgr; -- buswidth = <8>; -- reset-gpios = <&gpio 25 0>; -- dc-gpios = <&gpio 24 0>; -- led-gpios = <&gpio 18 1>; -- debug = <0>; -- -- init = <0x10000B0 0x80 -- 0x10000C0 0x0A 0x0A -- 0x10000C1 0x01 0x01 -- 0x10000C2 0x33 -- 0x10000C5 0x00 0x42 0x80 -- 0x10000B1 0xD0 0x11 -- 0x10000B4 0x02 -- 0x10000B6 0x00 0x22 0x3B -- 0x10000B7 0x07 -- 0x1000036 0x58 -- 0x10000F0 0x36 0xA5 0xD3 -- 0x10000E5 0x80 -- 0x10000E5 0x01 -- 0x10000B3 0x00 -- 0x10000E5 0x00 -- 0x10000F0 0x36 0xA5 0x53 -- 0x10000E0 0x00 0x35 0x33 0x00 0x00 0x00 0x00 0x35 0x33 0x00 0x00 0x00 -- 0x100003A 0x55 -- 0x1000011 -- 0x2000001 -- 0x1000029>; -- }; -- -- tinylcd35_ts: tinylcd35_ts@1 { -- compatible = "ti,ads7846"; -- reg = <1>; -- status = "disabled"; -- -- spi-max-frequency = <2000000>; -- interrupts = <5 2>; /* high-to-low edge triggered */ -- interrupt-parent = <&gpio>; -- pendown-gpio = <&gpio 5 0>; -- ti,x-plate-ohms = /bits/ 16 <100>; -- ti,pressure-max = /bits/ 16 <255>; -- }; -- }; -- }; -- -- /* RTC */ -- -- fragment@3 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- -- pcf8563: pcf8563@51 { -- compatible = "nxp,pcf8563"; -- reg = <0x51>; -- status = "disabled"; -- }; -- }; -- }; -- -- fragment@4 { -- target = <&i2c1>; -- __overlay__ { -- #address-cells = <1>; -- #size-cells = <0>; -- -- ds1307: ds1307@68 { -- compatible = "maxim,ds1307"; -- reg = <0x68>; -- status = "disabled"; -- }; -- }; -- }; -- -- /* -- * Values for input event code is found under the -- * 'Keys and buttons' heading in include/uapi/linux/input.h -- */ -- fragment@5 { -- target-path = "/soc"; -- __overlay__ { -- keypad: keypad { -- compatible = "gpio-keys"; -- #address-cells = <1>; -- #size-cells = <0>; -- pinctrl-names = "default"; -- pinctrl-0 = <&keypad_pins>; -- status = "disabled"; -- autorepeat; -- -- button@17 { -- label = "GPIO KEY_UP"; -- linux,code = <103>; -- gpios = <&gpio 17 0>; -- }; -- button@22 { -- label = "GPIO KEY_DOWN"; -- linux,code = <108>; -- gpios = <&gpio 22 0>; -- }; -- button@27 { -- label = "GPIO KEY_LEFT"; -- linux,code = <105>; -- gpios = <&gpio 27 0>; -- }; -- button@23 { -- label = "GPIO KEY_RIGHT"; -- linux,code = <106>; -- gpios = <&gpio 23 0>; -- }; -- button@4 { -- label = "GPIO KEY_ENTER"; -- linux,code = <28>; -- gpios = <&gpio 4 0>; -- }; -- }; -- }; -- }; -- -- __overrides__ { -- speed = <&tinylcd35>,"spi-max-frequency:0"; -- rotate = <&tinylcd35>,"rotate:0"; -- fps = <&tinylcd35>,"fps:0"; -- debug = <&tinylcd35>,"debug:0"; -- touch = <&tinylcd35_ts>,"status"; -- touchgpio = <&tinylcd35_ts_pins>,"brcm,pins:0", -- <&tinylcd35_ts>,"interrupts:0", -- <&tinylcd35_ts>,"pendown-gpio:4"; -- xohms = <&tinylcd35_ts>,"ti,x-plate-ohms;0"; -- rtc-pcf = <&i2c1>,"status", -- <&pcf8563>,"status"; -- rtc-ds = <&i2c1>,"status", -- <&ds1307>,"status"; -- keypad = <&keypad>,"status"; -- }; --}; -diff --git a/arch/arm/boot/dts/w1-gpio-overlay.dts b/arch/arm/boot/dts/w1-gpio-overlay.dts -deleted file mode 100644 -index 29a3b48..0000000 ---- a/arch/arm/boot/dts/w1-gpio-overlay.dts -+++ /dev/null -@@ -1,39 +0,0 @@ --// Definitions for w1-gpio module (without external pullup) --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- -- w1: onewire@0 { -- compatible = "w1-gpio"; -- pinctrl-names = "default"; -- pinctrl-0 = <&w1_pins>; -- gpios = <&gpio 4 0>; -- rpi,parasitic-power = <0>; -- status = "okay"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- w1_pins: w1_pins { -- brcm,pins = <4>; -- brcm,function = <0>; // in (initially) -- brcm,pull = <0>; // off -- }; -- }; -- }; -- -- __overrides__ { -- gpiopin = <&w1>,"gpios:4", -- <&w1_pins>,"brcm,pins:0"; -- pullup = <&w1>,"rpi,parasitic-power:0"; -- }; --}; -diff --git a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts b/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -deleted file mode 100644 -index 66a98f6..0000000 ---- a/arch/arm/boot/dts/w1-gpio-pullup-overlay.dts -+++ /dev/null -@@ -1,41 +0,0 @@ --// Definitions for w1-gpio module (with external pullup) --/dts-v1/; --/plugin/; -- --/ { -- compatible = "brcm,bcm2708"; -- -- fragment@0 { -- target-path = "/"; -- __overlay__ { -- -- w1: onewire@0 { -- compatible = "w1-gpio"; -- pinctrl-names = "default"; -- pinctrl-0 = <&w1_pins>; -- gpios = <&gpio 4 0>, <&gpio 5 1>; -- rpi,parasitic-power = <0>; -- status = "okay"; -- }; -- }; -- }; -- -- fragment@1 { -- target = <&gpio>; -- __overlay__ { -- w1_pins: w1_pins { -- brcm,pins = <4 5>; -- brcm,function = <0 1>; // in out -- brcm,pull = <0 0>; // off off -- }; -- }; -- }; -- -- __overrides__ { -- gpiopin = <&w1>,"gpios:4", -- <&w1_pins>,"brcm,pins:0"; -- extpullup = <&w1>,"gpios:16", -- <&w1_pins>,"brcm,pins:4"; -- pullup = <&w1>,"rpi,parasitic-power:0"; -- }; --}; - -From 9c2920928cae9f7d35cb3c0e4f677b7f266a7ae3 Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Fri, 3 Apr 2015 12:40:10 +0000 -Subject: [PATCH 192/216] Swap X Y axis of ads7846 touchscreen controller for - PiScreen TFT - ---- - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -index b7fd7ea..be1e2ec 100644 ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -80,6 +80,7 @@ - interrupts = <17 2>; /* high-to-low edge triggered */ - interrupt-parent = <&gpio>; - pendown-gpio = <&gpio 17 0>; -+ ti,swap-xy; - ti,x-plate-ohms = /bits/ 16 <100>; - ti,pressure-max = /bits/ 16 <255>; - }; - -From a4d119709c817d2bf6caea401b8266f55ad861c2 Mon Sep 17 00:00:00 2001 -From: mwilliams03 -Date: Wed, 8 Apr 2015 01:13:47 +0000 -Subject: [PATCH 193/216] Added optional parameter to set resistance of touch - plate(x-plate-ohms) - ---- - arch/arm/boot/dts/overlays/README | 2 ++ - arch/arm/boot/dts/overlays/piscreen-overlay.dts | 3 ++- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README -index c260612..9d4f283 100644 ---- a/arch/arm/boot/dts/overlays/README -+++ b/arch/arm/boot/dts/overlays/README -@@ -329,6 +329,8 @@ Params: speed Display SPI bus speed - - debug Debug output level {0-7} - -+ xohms Touchpanel sensitivity (X-plate resistance) -+ - - Name: pitft28-resistive - Info: Adafruit PiTFT 2.8" resistive touch screen -diff --git a/arch/arm/boot/dts/overlays/piscreen-overlay.dts b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -index be1e2ec..ba4ad33 100644 ---- a/arch/arm/boot/dts/overlays/piscreen-overlay.dts -+++ b/arch/arm/boot/dts/overlays/piscreen-overlay.dts -@@ -72,7 +72,7 @@ - 0x1000029>; - }; - -- piscreen-ts@1 { -+ piscreen_ts: piscreen-ts@1 { - compatible = "ti,ads7846"; - reg = <1>; - -@@ -91,5 +91,6 @@ - rotate = <&piscreen>,"rotate:0"; - fps = <&piscreen>,"fps:0"; - debug = <&piscreen>,"debug:0"; -+ xohms = <&piscreen_ts>,"ti,x-plate-ohms;0"; - }; - }; - -From df11ad948112ccee4eae40b6f4810946a8dc5019 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Thu, 28 May 2015 18:50:21 +0200 -Subject: [PATCH 194/216] BCM270x: Move vc_mem -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Make the vc_mem module available for ARCH_BCM2835 by moving it. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/Kconfig | 7 - - arch/arm/mach-bcm2708/Makefile | 1 - - arch/arm/mach-bcm2708/include/mach/vc_mem.h | 35 --- - arch/arm/mach-bcm2708/vc_mem.c | 431 ---------------------------- - arch/arm/mach-bcm2709/Kconfig | 7 - - arch/arm/mach-bcm2709/Makefile | 1 - - arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 --- - arch/arm/mach-bcm2709/vc_mem.c | 431 ---------------------------- - drivers/char/broadcom/Kconfig | 13 +- - drivers/char/broadcom/Makefile | 1 + - drivers/char/broadcom/vc_mem.c | 423 +++++++++++++++++++++++++++ - drivers/char/broadcom/vc_sm/vmcs_sm.c | 3 +- - include/linux/broadcom/vc_mem.h | 35 +++ - 13 files changed, 472 insertions(+), 951 deletions(-) - delete mode 100644 arch/arm/mach-bcm2708/include/mach/vc_mem.h - delete mode 100644 arch/arm/mach-bcm2708/vc_mem.c - delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h - delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c - create mode 100644 drivers/char/broadcom/vc_mem.c - create mode 100644 include/linux/broadcom/vc_mem.h - -diff --git a/arch/arm/mach-bcm2708/Kconfig b/arch/arm/mach-bcm2708/Kconfig -index 4cfae55..68e3706 100644 ---- a/arch/arm/mach-bcm2708/Kconfig -+++ b/arch/arm/mach-bcm2708/Kconfig -@@ -28,13 +28,6 @@ config BCM2708_GPIO - help - Include support for the Broadcom(R) BCM2708 gpio. - --config BCM2708_VCMEM -- bool "Videocore Memory" -- depends on MACH_BCM2708 -- default y -- help -- Helper for videocore memory access and total size allocation. -- - config BCM2708_NOL2CACHE - bool "Videocore L2 cache disable" - depends on MACH_BCM2708 -diff --git a/arch/arm/mach-bcm2708/Makefile b/arch/arm/mach-bcm2708/Makefile -index 5552ae8..5120994 100644 ---- a/arch/arm/mach-bcm2708/Makefile -+++ b/arch/arm/mach-bcm2708/Makefile -@@ -4,4 +4,3 @@ - - obj-$(CONFIG_MACH_BCM2708) += bcm2708.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o --obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2708/include/mach/vc_mem.h b/arch/arm/mach-bcm2708/include/mach/vc_mem.h -deleted file mode 100644 -index 4a4a338..0000000 ---- a/arch/arm/mach-bcm2708/include/mach/vc_mem.h -+++ /dev/null -@@ -1,35 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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. --*****************************************************************************/ -- --#if !defined( VC_MEM_H ) --#define VC_MEM_H -- --#include -- --#define VC_MEM_IOC_MAGIC 'v' -- --#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 ) --#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -- --#if defined( __KERNEL__ ) --#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -- --extern unsigned long mm_vc_mem_phys_addr; --extern unsigned int mm_vc_mem_size; --extern int vc_mem_get_current_size( void ); --#endif -- --#endif /* VC_MEM_H */ -diff --git a/arch/arm/mach-bcm2708/vc_mem.c b/arch/arm/mach-bcm2708/vc_mem.c -deleted file mode 100644 -index 226b737..0000000 ---- a/arch/arm/mach-bcm2708/vc_mem.c -+++ /dev/null -@@ -1,431 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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 -- --#ifdef CONFIG_ARCH_KONA --#include --#elif CONFIG_ARCH_BCM2708 --#else --#include --#endif -- --#include "mach/vc_mem.h" -- --#define DRIVER_NAME "vc-mem" -- --// Device (/dev) related variables --static dev_t vc_mem_devnum = 0; --static struct class *vc_mem_class = NULL; --static struct cdev vc_mem_cdev; --static int vc_mem_inited = 0; -- --#ifdef CONFIG_DEBUG_FS --static struct dentry *vc_mem_debugfs_entry; --#endif -- --/* -- * Videocore memory addresses and size -- * -- * Drivers that wish to know the videocore memory addresses and sizes should -- * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -- * headers. This allows the other drivers to not be tied down to a a certain -- * address/size at compile time. -- * -- * In the future, the goal is to have the videocore memory virtual address and -- * size be calculated at boot time rather than at compile time. The decision of -- * where the videocore memory resides and its size would be in the hands of the -- * bootloader (and/or kernel). When that happens, the values of these variables -- * would be calculated and assigned in the init function. -- */ --// in the 2835 VC in mapped above ARM, but ARM has full access to VC space --unsigned long mm_vc_mem_phys_addr = 0x00000000; --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); -- --static uint phys_addr = 0; --static uint mem_size = 0; --static uint mem_base = 0; -- -- --/**************************************************************************** --* --* vc_mem_open --* --***************************************************************************/ -- --static int --vc_mem_open(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_release --* --***************************************************************************/ -- --static int --vc_mem_release(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_get_size --* --***************************************************************************/ -- --static void --vc_mem_get_size(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_base --* --***************************************************************************/ -- --static void --vc_mem_get_base(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_current_size --* --***************************************************************************/ -- --int --vc_mem_get_current_size(void) --{ -- return mm_vc_mem_size; --} -- --EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -- --/**************************************************************************** --* --* vc_mem_ioctl --* --***************************************************************************/ -- --static long --vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) --{ -- int rc = 0; -- -- (void) cmd; -- (void) arg; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- switch (cmd) { -- case VC_MEM_IOC_MEM_PHYS_ADDR: -- { -- pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -- __func__, (void *) mm_vc_mem_phys_addr); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -- sizeof (mm_vc_mem_phys_addr)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_SIZE: -- { -- // Get the videocore memory size first -- vc_mem_get_size(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -- mm_vc_mem_size); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_size, -- sizeof (mm_vc_mem_size)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_BASE: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -- mm_vc_mem_base); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_base, -- sizeof (mm_vc_mem_base)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_LOAD: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -- { -- return -ENOTTY; -- } -- } -- pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -- -- return rc; --} -- --/**************************************************************************** --* --* vc_mem_mmap --* --***************************************************************************/ -- --static int --vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) --{ -- int rc = 0; -- unsigned long length = vma->vm_end - vma->vm_start; -- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -- -- pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -- __func__, (long) vma->vm_start, (long) vma->vm_end, -- (long) vma->vm_pgoff); -- -- if (offset + length > mm_vc_mem_size) { -- pr_err("%s: length %ld is too big\n", __func__, length); -- return -EINVAL; -- } -- // Do not cache the memory map -- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -- -- rc = remap_pfn_range(vma, vma->vm_start, -- (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -- vma->vm_pgoff, length, vma->vm_page_prot); -- if (rc != 0) { -- pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -- } -- -- return rc; --} -- --/**************************************************************************** --* --* File Operations for the driver. --* --***************************************************************************/ -- --static const struct file_operations vc_mem_fops = { -- .owner = THIS_MODULE, -- .open = vc_mem_open, -- .release = vc_mem_release, -- .unlocked_ioctl = vc_mem_ioctl, -- .mmap = vc_mem_mmap, --}; -- --#ifdef CONFIG_DEBUG_FS --static void vc_mem_debugfs_deinit(void) --{ -- debugfs_remove_recursive(vc_mem_debugfs_entry); -- vc_mem_debugfs_entry = NULL; --} -- -- --static int vc_mem_debugfs_init( -- struct device *dev) --{ -- vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -- if (!vc_mem_debugfs_entry) { -- dev_warn(dev, "could not create debugfs entry\n"); -- return -EFAULT; -- } -- -- if (!debugfs_create_x32("vc_mem_phys_addr", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_phys_addr)) { -- dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_size", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_size)) { -- dev_warn(dev, "%s:could not create vc_mem_size entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_base", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_base)) { -- dev_warn(dev, "%s:could not create vc_mem_base entry\n", -- __func__); -- goto fail; -- } -- -- return 0; -- --fail: -- vc_mem_debugfs_deinit(); -- return -EFAULT; --} -- --#endif /* CONFIG_DEBUG_FS */ -- -- --/**************************************************************************** --* --* vc_mem_init --* --***************************************************************************/ -- --static int __init --vc_mem_init(void) --{ -- int rc = -EFAULT; -- struct device *dev; -- -- pr_debug("%s: called\n", __func__); -- -- mm_vc_mem_phys_addr = phys_addr; -- mm_vc_mem_size = mem_size; -- mm_vc_mem_base = mem_base; -- -- vc_mem_get_size(); -- -- pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -- -- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -- pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -- __func__, rc); -- goto out_err; -- } -- -- cdev_init(&vc_mem_cdev, &vc_mem_fops); -- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -- pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -- goto out_unregister; -- } -- -- vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vc_mem_class)) { -- rc = PTR_ERR(vc_mem_class); -- pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -- goto out_cdev_del; -- } -- -- dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -- DRIVER_NAME); -- if (IS_ERR(dev)) { -- rc = PTR_ERR(dev); -- pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -- goto out_class_destroy; -- } -- --#ifdef CONFIG_DEBUG_FS -- /* don't fail if the debug entries cannot be created */ -- vc_mem_debugfs_init(dev); --#endif -- -- vc_mem_inited = 1; -- return 0; -- -- device_destroy(vc_mem_class, vc_mem_devnum); -- -- out_class_destroy: -- class_destroy(vc_mem_class); -- vc_mem_class = NULL; -- -- out_cdev_del: -- cdev_del(&vc_mem_cdev); -- -- out_unregister: -- unregister_chrdev_region(vc_mem_devnum, 1); -- -- out_err: -- return -1; --} -- --/**************************************************************************** --* --* vc_mem_exit --* --***************************************************************************/ -- --static void __exit --vc_mem_exit(void) --{ -- pr_debug("%s: called\n", __func__); -- -- if (vc_mem_inited) { --#if CONFIG_DEBUG_FS -- vc_mem_debugfs_deinit(); --#endif -- device_destroy(vc_mem_class, vc_mem_devnum); -- class_destroy(vc_mem_class); -- cdev_del(&vc_mem_cdev); -- unregister_chrdev_region(vc_mem_devnum, 1); -- } --} -- --module_init(vc_mem_init); --module_exit(vc_mem_exit); --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Broadcom Corporation"); -- --module_param(phys_addr, uint, 0644); --module_param(mem_size, uint, 0644); --module_param(mem_base, uint, 0644); -diff --git a/arch/arm/mach-bcm2709/Kconfig b/arch/arm/mach-bcm2709/Kconfig -index 4fb6e1b..d61ade0 100644 ---- a/arch/arm/mach-bcm2709/Kconfig -+++ b/arch/arm/mach-bcm2709/Kconfig -@@ -25,13 +25,6 @@ config BCM2708_GPIO - help - Include support for the Broadcom(R) BCM2709 gpio. - --config BCM2708_VCMEM -- bool "Videocore Memory" -- depends on MACH_BCM2709 -- default y -- help -- Helper for videocore memory access and total size allocation. -- - config BCM2708_NOL2CACHE - bool "Videocore L2 cache disable" - depends on MACH_BCM2709 -diff --git a/arch/arm/mach-bcm2709/Makefile b/arch/arm/mach-bcm2709/Makefile -index 706116f..1ae8b80 100644 ---- a/arch/arm/mach-bcm2709/Makefile -+++ b/arch/arm/mach-bcm2709/Makefile -@@ -4,4 +4,3 @@ - - obj-$(CONFIG_MACH_BCM2709) += bcm2709.o armctrl.o - obj-$(CONFIG_BCM2708_GPIO) += bcm2708_gpio.o --obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/arch/arm/mach-bcm2709/include/mach/vc_mem.h b/arch/arm/mach-bcm2709/include/mach/vc_mem.h -deleted file mode 100644 -index 4a4a338..0000000 ---- a/arch/arm/mach-bcm2709/include/mach/vc_mem.h -+++ /dev/null -@@ -1,35 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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. --*****************************************************************************/ -- --#if !defined( VC_MEM_H ) --#define VC_MEM_H -- --#include -- --#define VC_MEM_IOC_MAGIC 'v' -- --#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 ) --#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -- --#if defined( __KERNEL__ ) --#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -- --extern unsigned long mm_vc_mem_phys_addr; --extern unsigned int mm_vc_mem_size; --extern int vc_mem_get_current_size( void ); --#endif -- --#endif /* VC_MEM_H */ -diff --git a/arch/arm/mach-bcm2709/vc_mem.c b/arch/arm/mach-bcm2709/vc_mem.c -deleted file mode 100644 -index d2adfd1..0000000 ---- a/arch/arm/mach-bcm2709/vc_mem.c -+++ /dev/null -@@ -1,431 +0,0 @@ --/***************************************************************************** --* Copyright 2010 - 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 -- --#ifdef CONFIG_ARCH_KONA --#include --#elif defined(CONFIG_ARCH_BCM2708) || defined(CONFIG_ARCH_BCM2709) --#else --#include --#endif -- --#include "mach/vc_mem.h" -- --#define DRIVER_NAME "vc-mem" -- --// Device (/dev) related variables --static dev_t vc_mem_devnum = 0; --static struct class *vc_mem_class = NULL; --static struct cdev vc_mem_cdev; --static int vc_mem_inited = 0; -- --#ifdef CONFIG_DEBUG_FS --static struct dentry *vc_mem_debugfs_entry; --#endif -- --/* -- * Videocore memory addresses and size -- * -- * Drivers that wish to know the videocore memory addresses and sizes should -- * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -- * headers. This allows the other drivers to not be tied down to a a certain -- * address/size at compile time. -- * -- * In the future, the goal is to have the videocore memory virtual address and -- * size be calculated at boot time rather than at compile time. The decision of -- * where the videocore memory resides and its size would be in the hands of the -- * bootloader (and/or kernel). When that happens, the values of these variables -- * would be calculated and assigned in the init function. -- */ --// in the 2835 VC in mapped above ARM, but ARM has full access to VC space --unsigned long mm_vc_mem_phys_addr = 0x00000000; --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); -- --static uint phys_addr = 0; --static uint mem_size = 0; --static uint mem_base = 0; -- -- --/**************************************************************************** --* --* vc_mem_open --* --***************************************************************************/ -- --static int --vc_mem_open(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_release --* --***************************************************************************/ -- --static int --vc_mem_release(struct inode *inode, struct file *file) --{ -- (void) inode; -- (void) file; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- return 0; --} -- --/**************************************************************************** --* --* vc_mem_get_size --* --***************************************************************************/ -- --static void --vc_mem_get_size(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_base --* --***************************************************************************/ -- --static void --vc_mem_get_base(void) --{ --} -- --/**************************************************************************** --* --* vc_mem_get_current_size --* --***************************************************************************/ -- --int --vc_mem_get_current_size(void) --{ -- return mm_vc_mem_size; --} -- --EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -- --/**************************************************************************** --* --* vc_mem_ioctl --* --***************************************************************************/ -- --static long --vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) --{ -- int rc = 0; -- -- (void) cmd; -- (void) arg; -- -- pr_debug("%s: called file = 0x%p\n", __func__, file); -- -- switch (cmd) { -- case VC_MEM_IOC_MEM_PHYS_ADDR: -- { -- pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -- __func__, (void *) mm_vc_mem_phys_addr); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -- sizeof (mm_vc_mem_phys_addr)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_SIZE: -- { -- // Get the videocore memory size first -- vc_mem_get_size(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -- mm_vc_mem_size); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_size, -- sizeof (mm_vc_mem_size)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_BASE: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -- mm_vc_mem_base); -- -- if (copy_to_user((void *) arg, &mm_vc_mem_base, -- sizeof (mm_vc_mem_base)) != 0) { -- rc = -EFAULT; -- } -- break; -- } -- case VC_MEM_IOC_MEM_LOAD: -- { -- // Get the videocore memory base -- vc_mem_get_base(); -- -- pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -- { -- return -ENOTTY; -- } -- } -- pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -- -- return rc; --} -- --/**************************************************************************** --* --* vc_mem_mmap --* --***************************************************************************/ -- --static int --vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) --{ -- int rc = 0; -- unsigned long length = vma->vm_end - vma->vm_start; -- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -- -- pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -- __func__, (long) vma->vm_start, (long) vma->vm_end, -- (long) vma->vm_pgoff); -- -- if (offset + length > mm_vc_mem_size) { -- pr_err("%s: length %ld is too big\n", __func__, length); -- return -EINVAL; -- } -- // Do not cache the memory map -- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -- -- rc = remap_pfn_range(vma, vma->vm_start, -- (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -- vma->vm_pgoff, length, vma->vm_page_prot); -- if (rc != 0) { -- pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -- } -- -- return rc; --} -- --/**************************************************************************** --* --* File Operations for the driver. --* --***************************************************************************/ -- --static const struct file_operations vc_mem_fops = { -- .owner = THIS_MODULE, -- .open = vc_mem_open, -- .release = vc_mem_release, -- .unlocked_ioctl = vc_mem_ioctl, -- .mmap = vc_mem_mmap, --}; -- --#ifdef CONFIG_DEBUG_FS --static void vc_mem_debugfs_deinit(void) --{ -- debugfs_remove_recursive(vc_mem_debugfs_entry); -- vc_mem_debugfs_entry = NULL; --} -- -- --static int vc_mem_debugfs_init( -- struct device *dev) --{ -- vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -- if (!vc_mem_debugfs_entry) { -- dev_warn(dev, "could not create debugfs entry\n"); -- return -EFAULT; -- } -- -- if (!debugfs_create_x32("vc_mem_phys_addr", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_phys_addr)) { -- dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_size", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_size)) { -- dev_warn(dev, "%s:could not create vc_mem_size entry\n", -- __func__); -- goto fail; -- } -- -- if (!debugfs_create_x32("vc_mem_base", -- 0444, -- vc_mem_debugfs_entry, -- (u32 *)&mm_vc_mem_base)) { -- dev_warn(dev, "%s:could not create vc_mem_base entry\n", -- __func__); -- goto fail; -- } -- -- return 0; -- --fail: -- vc_mem_debugfs_deinit(); -- return -EFAULT; --} -- --#endif /* CONFIG_DEBUG_FS */ -- -- --/**************************************************************************** --* --* vc_mem_init --* --***************************************************************************/ -- --static int __init --vc_mem_init(void) --{ -- int rc = -EFAULT; -- struct device *dev; -- -- pr_debug("%s: called\n", __func__); -- -- mm_vc_mem_phys_addr = phys_addr; -- mm_vc_mem_size = mem_size; -- mm_vc_mem_base = mem_base; -- -- vc_mem_get_size(); -- -- pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -- mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -- -- if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -- pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -- __func__, rc); -- goto out_err; -- } -- -- cdev_init(&vc_mem_cdev, &vc_mem_fops); -- if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -- pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -- goto out_unregister; -- } -- -- vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -- if (IS_ERR(vc_mem_class)) { -- rc = PTR_ERR(vc_mem_class); -- pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -- goto out_cdev_del; -- } -- -- dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -- DRIVER_NAME); -- if (IS_ERR(dev)) { -- rc = PTR_ERR(dev); -- pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -- goto out_class_destroy; -- } -- --#ifdef CONFIG_DEBUG_FS -- /* don't fail if the debug entries cannot be created */ -- vc_mem_debugfs_init(dev); --#endif -- -- vc_mem_inited = 1; -- return 0; -- -- device_destroy(vc_mem_class, vc_mem_devnum); -- -- out_class_destroy: -- class_destroy(vc_mem_class); -- vc_mem_class = NULL; -- -- out_cdev_del: -- cdev_del(&vc_mem_cdev); -- -- out_unregister: -- unregister_chrdev_region(vc_mem_devnum, 1); -- -- out_err: -- return -1; --} -- --/**************************************************************************** --* --* vc_mem_exit --* --***************************************************************************/ -- --static void __exit --vc_mem_exit(void) --{ -- pr_debug("%s: called\n", __func__); -- -- if (vc_mem_inited) { --#if CONFIG_DEBUG_FS -- vc_mem_debugfs_deinit(); --#endif -- device_destroy(vc_mem_class, vc_mem_devnum); -- class_destroy(vc_mem_class); -- cdev_del(&vc_mem_cdev); -- unregister_chrdev_region(vc_mem_devnum, 1); -- } --} -- --module_init(vc_mem_init); --module_exit(vc_mem_exit); --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Broadcom Corporation"); -- --module_param(phys_addr, uint, 0644); --module_param(mem_size, uint, 0644); --module_param(mem_base, uint, 0644); -diff --git a/drivers/char/broadcom/Kconfig b/drivers/char/broadcom/Kconfig -index fd23e00..c310d9d 100644 ---- a/drivers/char/broadcom/Kconfig -+++ b/drivers/char/broadcom/Kconfig -@@ -7,16 +7,27 @@ menuconfig BRCM_CHAR_DRIVERS - help - Broadcom's char drivers - -+if BRCM_CHAR_DRIVERS -+ - config BCM_VC_CMA - bool "Videocore CMA" -- depends on CMA && BRCM_CHAR_DRIVERS && BCM2708_VCHIQ -+ depends on CMA && BCM2708_VCHIQ - default n - help - Helper for videocore CMA access. - - config BCM_VC_SM - bool "VMCS Shared Memory" -+ select BCM2708_VCMEM - default n - help - Support for the VC shared memory on the Broadcom reference - design. Uses the VCHIQ stack. -+ -+config BCM2708_VCMEM -+ bool "Videocore Memory" -+ default y -+ help -+ Helper for videocore memory access and total size allocation. -+ -+endif -diff --git a/drivers/char/broadcom/Makefile b/drivers/char/broadcom/Makefile -index 0bf7fdf..b4f8e39d 100644 ---- a/drivers/char/broadcom/Makefile -+++ b/drivers/char/broadcom/Makefile -@@ -1,2 +1,3 @@ - obj-$(CONFIG_BCM_VC_CMA) += vc_cma/ - obj-$(CONFIG_BCM_VC_SM) += vc_sm/ -+obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o -diff --git a/drivers/char/broadcom/vc_mem.c b/drivers/char/broadcom/vc_mem.c -new file mode 100644 -index 0000000..fcde6b1 ---- /dev/null -+++ b/drivers/char/broadcom/vc_mem.c -@@ -0,0 +1,423 @@ -+/***************************************************************************** -+* Copyright 2010 - 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 -+ -+#define DRIVER_NAME "vc-mem" -+ -+// Device (/dev) related variables -+static dev_t vc_mem_devnum = 0; -+static struct class *vc_mem_class = NULL; -+static struct cdev vc_mem_cdev; -+static int vc_mem_inited = 0; -+ -+#ifdef CONFIG_DEBUG_FS -+static struct dentry *vc_mem_debugfs_entry; -+#endif -+ -+/* -+ * Videocore memory addresses and size -+ * -+ * Drivers that wish to know the videocore memory addresses and sizes should -+ * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in -+ * headers. This allows the other drivers to not be tied down to a a certain -+ * address/size at compile time. -+ * -+ * In the future, the goal is to have the videocore memory virtual address and -+ * size be calculated at boot time rather than at compile time. The decision of -+ * where the videocore memory resides and its size would be in the hands of the -+ * bootloader (and/or kernel). When that happens, the values of these variables -+ * would be calculated and assigned in the init function. -+ */ -+// in the 2835 VC in mapped above ARM, but ARM has full access to VC space -+unsigned long mm_vc_mem_phys_addr = 0x00000000; -+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); -+ -+static uint phys_addr = 0; -+static uint mem_size = 0; -+static uint mem_base = 0; -+ -+ -+/**************************************************************************** -+* -+* vc_mem_open -+* -+***************************************************************************/ -+ -+static int -+vc_mem_open(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_release -+* -+***************************************************************************/ -+ -+static int -+vc_mem_release(struct inode *inode, struct file *file) -+{ -+ (void) inode; -+ (void) file; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ return 0; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_size -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_size(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_base -+* -+***************************************************************************/ -+ -+static void -+vc_mem_get_base(void) -+{ -+} -+ -+/**************************************************************************** -+* -+* vc_mem_get_current_size -+* -+***************************************************************************/ -+ -+int -+vc_mem_get_current_size(void) -+{ -+ return mm_vc_mem_size; -+} -+ -+EXPORT_SYMBOL_GPL(vc_mem_get_current_size); -+ -+/**************************************************************************** -+* -+* vc_mem_ioctl -+* -+***************************************************************************/ -+ -+static long -+vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ int rc = 0; -+ -+ (void) cmd; -+ (void) arg; -+ -+ pr_debug("%s: called file = 0x%p\n", __func__, file); -+ -+ switch (cmd) { -+ case VC_MEM_IOC_MEM_PHYS_ADDR: -+ { -+ pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n", -+ __func__, (void *) mm_vc_mem_phys_addr); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr, -+ sizeof (mm_vc_mem_phys_addr)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_SIZE: -+ { -+ // Get the videocore memory size first -+ vc_mem_get_size(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__, -+ mm_vc_mem_size); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_size, -+ sizeof (mm_vc_mem_size)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_BASE: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__, -+ mm_vc_mem_base); -+ -+ if (copy_to_user((void *) arg, &mm_vc_mem_base, -+ sizeof (mm_vc_mem_base)) != 0) { -+ rc = -EFAULT; -+ } -+ break; -+ } -+ case VC_MEM_IOC_MEM_LOAD: -+ { -+ // Get the videocore memory base -+ vc_mem_get_base(); -+ -+ pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __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: -+ { -+ return -ENOTTY; -+ } -+ } -+ pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc); -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_mmap -+* -+***************************************************************************/ -+ -+static int -+vc_mem_mmap(struct file *filp, struct vm_area_struct *vma) -+{ -+ int rc = 0; -+ unsigned long length = vma->vm_end - vma->vm_start; -+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; -+ -+ pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n", -+ __func__, (long) vma->vm_start, (long) vma->vm_end, -+ (long) vma->vm_pgoff); -+ -+ if (offset + length > mm_vc_mem_size) { -+ pr_err("%s: length %ld is too big\n", __func__, length); -+ return -EINVAL; -+ } -+ // Do not cache the memory map -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ -+ rc = remap_pfn_range(vma, vma->vm_start, -+ (mm_vc_mem_phys_addr >> PAGE_SHIFT) + -+ vma->vm_pgoff, length, vma->vm_page_prot); -+ if (rc != 0) { -+ pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc); -+ } -+ -+ return rc; -+} -+ -+/**************************************************************************** -+* -+* File Operations for the driver. -+* -+***************************************************************************/ -+ -+static const struct file_operations vc_mem_fops = { -+ .owner = THIS_MODULE, -+ .open = vc_mem_open, -+ .release = vc_mem_release, -+ .unlocked_ioctl = vc_mem_ioctl, -+ .mmap = vc_mem_mmap, -+}; -+ -+#ifdef CONFIG_DEBUG_FS -+static void vc_mem_debugfs_deinit(void) -+{ -+ debugfs_remove_recursive(vc_mem_debugfs_entry); -+ vc_mem_debugfs_entry = NULL; -+} -+ -+ -+static int vc_mem_debugfs_init( -+ struct device *dev) -+{ -+ vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL); -+ if (!vc_mem_debugfs_entry) { -+ dev_warn(dev, "could not create debugfs entry\n"); -+ return -EFAULT; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_phys_addr", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_phys_addr)) { -+ dev_warn(dev, "%s:could not create vc_mem_phys entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_size", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_size)) { -+ dev_warn(dev, "%s:could not create vc_mem_size entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ if (!debugfs_create_x32("vc_mem_base", -+ 0444, -+ vc_mem_debugfs_entry, -+ (u32 *)&mm_vc_mem_base)) { -+ dev_warn(dev, "%s:could not create vc_mem_base entry\n", -+ __func__); -+ goto fail; -+ } -+ -+ return 0; -+ -+fail: -+ vc_mem_debugfs_deinit(); -+ return -EFAULT; -+} -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -+ -+/**************************************************************************** -+* -+* vc_mem_init -+* -+***************************************************************************/ -+ -+static int __init -+vc_mem_init(void) -+{ -+ int rc = -EFAULT; -+ struct device *dev; -+ -+ pr_debug("%s: called\n", __func__); -+ -+ mm_vc_mem_phys_addr = phys_addr; -+ mm_vc_mem_size = mem_size; -+ mm_vc_mem_base = mem_base; -+ -+ vc_mem_get_size(); -+ -+ pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n", -+ mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024)); -+ -+ if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) { -+ pr_err("%s: alloc_chrdev_region failed (rc=%d)\n", -+ __func__, rc); -+ goto out_err; -+ } -+ -+ cdev_init(&vc_mem_cdev, &vc_mem_fops); -+ if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) { -+ pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc); -+ goto out_unregister; -+ } -+ -+ vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME); -+ if (IS_ERR(vc_mem_class)) { -+ rc = PTR_ERR(vc_mem_class); -+ pr_err("%s: class_create failed (rc=%d)\n", __func__, rc); -+ goto out_cdev_del; -+ } -+ -+ dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL, -+ DRIVER_NAME); -+ if (IS_ERR(dev)) { -+ rc = PTR_ERR(dev); -+ pr_err("%s: device_create failed (rc=%d)\n", __func__, rc); -+ goto out_class_destroy; -+ } -+ -+#ifdef CONFIG_DEBUG_FS -+ /* don't fail if the debug entries cannot be created */ -+ vc_mem_debugfs_init(dev); -+#endif -+ -+ vc_mem_inited = 1; -+ return 0; -+ -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ -+ out_class_destroy: -+ class_destroy(vc_mem_class); -+ vc_mem_class = NULL; -+ -+ out_cdev_del: -+ cdev_del(&vc_mem_cdev); -+ -+ out_unregister: -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ -+ out_err: -+ return -1; -+} -+ -+/**************************************************************************** -+* -+* vc_mem_exit -+* -+***************************************************************************/ -+ -+static void __exit -+vc_mem_exit(void) -+{ -+ pr_debug("%s: called\n", __func__); -+ -+ if (vc_mem_inited) { -+#if CONFIG_DEBUG_FS -+ vc_mem_debugfs_deinit(); -+#endif -+ device_destroy(vc_mem_class, vc_mem_devnum); -+ class_destroy(vc_mem_class); -+ cdev_del(&vc_mem_cdev); -+ unregister_chrdev_region(vc_mem_devnum, 1); -+ } -+} -+ -+module_init(vc_mem_init); -+module_exit(vc_mem_exit); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Broadcom Corporation"); -+ -+module_param(phys_addr, uint, 0644); -+module_param(mem_size, uint, 0644); -+module_param(mem_base, uint, 0644); -diff --git a/drivers/char/broadcom/vc_sm/vmcs_sm.c b/drivers/char/broadcom/vc_sm/vmcs_sm.c -index 39a8971..0bfb42e 100644 ---- a/drivers/char/broadcom/vc_sm/vmcs_sm.c -+++ b/drivers/char/broadcom/vc_sm/vmcs_sm.c -@@ -15,6 +15,7 @@ - /* ---- Include Files ----------------------------------------------------- */ - - #include -+#include - #include - #include - #include -@@ -35,8 +36,6 @@ - #include - #include - --#include -- - #include "vchiq_connected.h" - #include "vc_vchi_sm.h" - -diff --git a/include/linux/broadcom/vc_mem.h b/include/linux/broadcom/vc_mem.h -new file mode 100644 -index 0000000..20a4753 ---- /dev/null -+++ b/include/linux/broadcom/vc_mem.h -@@ -0,0 +1,35 @@ -+/***************************************************************************** -+* Copyright 2010 - 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_MEM_H -+#define _VC_MEM_H -+ -+#include -+ -+#define VC_MEM_IOC_MAGIC 'v' -+ -+#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 ) -+#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int ) -+ -+#if defined( __KERNEL__ ) -+#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF -+ -+extern unsigned long mm_vc_mem_phys_addr; -+extern unsigned int mm_vc_mem_size; -+extern int vc_mem_get_current_size( void ); -+#endif -+ -+#endif /* _VC_MEM_H */ - -From 7495f032da212d310393adf5c4d1694190e6f309 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Mon, 1 Jun 2015 20:40:11 +0200 -Subject: [PATCH 195/216] BCM270x: Add USB controller to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support to dwc_otg driver. -Add device to Device Tree. -Don't add platform devices when booting in DT mode. - -Tested on Pi1 and Pi2 with and without DT. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 8 ++++++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - drivers/usb/host/dwc_otg/dwc_otg_driver.c | 7 +++++++ - 4 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index 3f8af85..dc7df47 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -121,6 +121,14 @@ - status = "disabled"; - }; - -+ usb: usb@7e980000 { -+ compatible = "brcm,bcm2708-usb"; -+ reg = <0x7e980000 0x10000>, -+ <0x7e006000 0x1000>; -+ interrupts = <2 0>, -+ <1 9>; -+ }; -+ - leds: leds { - compatible = "gpio-leds"; - }; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 06438df..6298309 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -955,7 +955,7 @@ void __init bcm2708_init(void) - #endif - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device_dt(&bcm2708_fb_device); -- bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device_dt(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index ce06b7d..d8c2336 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -978,7 +978,7 @@ void __init bcm2709_init(void) - bcm_register_device(&bcm2708_systemtimer_device); - #endif - bcm_register_device_dt(&bcm2708_fb_device); -- bcm_register_device(&bcm2708_usb_device); -+ bcm_register_device_dt(&bcm2708_usb_device); - bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - -diff --git a/drivers/usb/host/dwc_otg/dwc_otg_driver.c b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -index dc7cd32..53307f0 100644 ---- a/drivers/usb/host/dwc_otg/dwc_otg_driver.c -+++ b/drivers/usb/host/dwc_otg/dwc_otg_driver.c -@@ -1043,9 +1043,16 @@ static struct platform_device_id platform_ids[] = { - }; - MODULE_DEVICE_TABLE(platform, platform_ids); - -+static const struct of_device_id dwc_otg_of_match_table[] = { -+ { .compatible = "brcm,bcm2708-usb", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, dwc_otg_of_match_table); -+ - static struct platform_driver dwc_otg_driver = { - .driver = { - .name = (char *)dwc_driver_name, -+ .of_match_table = dwc_otg_of_match_table, - }, - .id_table = platform_ids, - - -From da5345649e7ad4deb51692d4d969ba4a2f86974b Mon Sep 17 00:00:00 2001 -From: Martin Sperl -Date: Mon, 2 Mar 2015 17:57:30 +0000 -Subject: [PATCH 196/216] added mcp251x module to list of modules to get - compiled as well as the corresponding overlay - ---- - arch/arm/boot/dts/Makefile | 2 +- - arch/arm/boot/dts/overlays/Makefile | 1 + - .../arm/boot/dts/overlays/mcp2515-can0-overlay.dts | 69 ++++++++++++++++++++++ - arch/arm/configs/bcm2709_defconfig | 5 ++ - arch/arm/configs/bcmrpi_defconfig | 8 +++ - 5 files changed, 84 insertions(+), 1 deletion(-) - create mode 100755 arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index ea93e1d..d5b6a82 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -1,9 +1,9 @@ - ifeq ($(CONFIG_OF),y) - - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b.dtb --dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-b-plus.dtb - dtb-$(CONFIG_BCM2708_DT) += bcm2708-rpi-cm.dtb -+dtb-$(CONFIG_BCM2709_DT) += bcm2709-rpi-2-b.dtb - - # Raspberry Pi - ifeq ($(CONFIG_BCM2708_DT),y) -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d64e6b4..d18a1f2 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -22,6 +22,7 @@ dtb-$(RPI_DT_OVERLAYS) += i2c-rtc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dac-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += iqaudio-dacplus-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += lirc-rpi-overlay.dtb -+dtb-$(RPI_DT_OVERLAYS) += mcp2515-can0-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mmc-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += mz61581-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += piscreen-overlay.dtb -diff --git a/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -new file mode 100755 -index 0000000..398d59c ---- /dev/null -+++ b/arch/arm/boot/dts/overlays/mcp2515-can0-overlay.dts -@@ -0,0 +1,69 @@ -+/* -+ * Device tree overlay for mcp251x/can0 on spi0.0 -+ */ -+ -+/dts-v1/; -+/plugin/; -+ -+/ { -+ compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709"; -+ /* disable spi-dev for spi0.0 */ -+ fragment@0 { -+ target = <&spi0>; -+ __overlay__ { -+ status = "okay"; -+ spidev@0{ -+ status = "disabled"; -+ }; -+ }; -+ }; -+ -+ /* the interrupt pin of the can-controller */ -+ fragment@1 { -+ target = <&gpio>; -+ __overlay__ { -+ can0_pins: can0_pins { -+ brcm,pins = <25>; -+ brcm,function = <0>; /* input */ -+ }; -+ }; -+ }; -+ -+ /* the clock/oscillator of the can-controller */ -+ fragment@2 { -+ target-path = "/clocks"; -+ __overlay__ { -+ /* external oscillator of mcp2515 on SPI0.0 */ -+ can0_osc: can0_osc { -+ compatible = "fixed-clock"; -+ #clock-cells = <0>; -+ clock-frequency = <16000000>; -+ }; -+ }; -+ }; -+ -+ /* the spi config of the can-controller itself binding everything together */ -+ fragment@3 { -+ target = <&spi0>; -+ __overlay__ { -+ /* needed to avoid dtc warning */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ can0: mcp2515@0 { -+ reg = <0>; -+ compatible = "microchip,mcp2515"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&can0_pins>; -+ spi-max-frequency = <10000000>; -+ interrupt-parent = <&gpio>; -+ interrupts = <25 0x2>; -+ clocks = <&can0_osc>; -+ }; -+ }; -+ }; -+ __overrides__ { -+ oscillator = <&can0_osc>,"clock-frequency:0"; -+ spimaxfrequency = <&can0>,"spi-max-frequency:0"; -+ interrupt = <&can0_pins>,"brcm,pins:0",<&can0>,"interrupts:0"; -+ }; -+}; -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 5ce9a01..2a1a15a 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -344,7 +344,12 @@ CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m - CONFIG_YAM=m - CONFIG_CAN=m -+CONFIG_CAN_RAW=m -+CONFIG_CAN_BCM=m -+CONFIG_CAN_GW=m - CONFIG_CAN_VCAN=m -+CONFIG_CAN_DEV=m -+CONFIG_CAN_CALC_BITTIMING=y - CONFIG_CAN_MCP251X=m - CONFIG_IRDA=m - CONFIG_IRLAN=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index da443da..a2d7291 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -335,6 +335,14 @@ CONFIG_6PACK=m - CONFIG_BPQETHER=m - CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m -+CONFIG_CAN=m -+CONFIG_CAN_RAW=m -+CONFIG_CAN_BCM=m -+CONFIG_CAN_GW=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_DEV=m -+CONFIG_CAN_CALC_BITTIMING=y -+CONFIG_CAN_MCP251X=m - CONFIG_YAM=m - CONFIG_CAN=m - CONFIG_CAN_VCAN=m - -From 8e999dc420b342d1304fc2bcd755ab6a36d6896c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 13:55:05 +0200 -Subject: [PATCH 197/216] BCM270x: Move thermal sensor to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add Device Tree support to bcm2835-thermal driver. -Add thermal sensor device to Device Tree. -Don't add platform device when booting in DT mode. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708_common.dtsi | 4 ++++ - arch/arm/mach-bcm2708/bcm2708.c | 2 +- - arch/arm/mach-bcm2709/bcm2709.c | 2 +- - drivers/thermal/bcm2835-thermal.c | 8 +++++++- - 4 files changed, 13 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index dc7df47..fcb5828 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -143,6 +143,10 @@ - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; - }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ }; - }; - - clocks { -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 6298309..e141c0b 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -984,7 +984,7 @@ void __init bcm2708_init(void) - } - - bcm_register_device(&bcm2835_hwmon_device); -- bcm_register_device(&bcm2835_thermal_device); -+ bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) - bcm_register_device_dt(&bcm2708_i2s_device); -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index d8c2336..6dadb80 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -1007,7 +1007,7 @@ void __init bcm2709_init(void) - } - - bcm_register_device(&bcm2835_hwmon_device); -- bcm_register_device(&bcm2835_thermal_device); -+ bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) - bcm_register_device_dt(&bcm2708_i2s_device); -diff --git a/drivers/thermal/bcm2835-thermal.c b/drivers/thermal/bcm2835-thermal.c -index 0c556d1..3bc80f1 100644 ---- a/drivers/thermal/bcm2835-thermal.c -+++ b/drivers/thermal/bcm2835-thermal.c -@@ -167,13 +167,19 @@ static struct thermal_zone_device_ops ops = { - .get_mode = bcm2835_get_mode, - }; - --/* Thermal Driver */ -+static const struct of_device_id bcm2835_thermal_of_match_table[] = { -+ { .compatible = "brcm,bcm2835-thermal", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, bcm2835_thermal_of_match_table); -+ - static struct platform_driver bcm2835_thermal_driver = { - .probe = bcm2835_thermal_probe, - .remove = bcm2835_thermal_remove, - .driver = { - .name = "bcm2835_thermal", - .owner = THIS_MODULE, -+ .of_match_table = bcm2835_thermal_of_match_table, - }, - }; - - -From fd724791a4d515e8069884b72f52752501ee0f92 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 13:55:22 +0200 -Subject: [PATCH 198/216] bcm2835: Add thermal sensor to Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add the BCM2835 thermal sensor to Device Tree. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835.dtsi | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index 40fc759..efaf4df 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -170,6 +170,10 @@ - reg = <0x7e00b840 0xf>; - interrupts = <0 2>; - }; -+ -+ thermal: thermal { -+ compatible = "brcm,bcm2835-thermal"; -+ }; - }; - - clocks { - -From 34638ffefe49111b137c8b0927c47f9aab23215b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 15:51:24 +0200 -Subject: [PATCH 199/216] BCM270x: Enable bcm2835_wdt and bcm2835-rng -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Change the kconfig dependency to make bcm2835_wdt and bcm2835-rng -available on ARCH_BCM2708 and ARCH_BCM2709. -Enable them as loadable modules in bcmrpi_defconfig and -bcm2709_defconfig. - -There is a commit in linux-next that will move restart/pm_power_off -to bcm2835_wdt for ARCH_BCM2835. This will not affect ARCH_BCM270x -since arm_pm_restart (.restart = bcm2708_restart) and -pm_power_off (=bcm2708_power_off) is set in -arch/arm/mach-bcm270X/bcm270X.c and will take presedence. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2709_defconfig | 2 ++ - arch/arm/configs/bcmrpi_defconfig | 2 ++ - drivers/char/hw_random/Kconfig | 2 +- - drivers/watchdog/Kconfig | 2 +- - 4 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index 2a1a15a..d08ae51 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -561,6 +561,7 @@ CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m - CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y -@@ -603,6 +604,7 @@ CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y - CONFIG_BCM2708_WDT=m -+CONFIG_BCM2835_WDT=m - CONFIG_UCB1400_CORE=m - CONFIG_MFD_STMPE=y - CONFIG_STMPE_SPI=y -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index a2d7291..11bbfac 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -557,6 +557,7 @@ CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_TTY_PRINTK=y - CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m - CONFIG_HW_RANDOM_BCM2708=m - CONFIG_RAW_DRIVER=y - CONFIG_BRCM_CHAR_DRIVERS=y -@@ -599,6 +600,7 @@ CONFIG_THERMAL=y - CONFIG_THERMAL_BCM2835=y - CONFIG_WATCHDOG=y - CONFIG_BCM2708_WDT=m -+CONFIG_BCM2835_WDT=m - CONFIG_UCB1400_CORE=m - CONFIG_MFD_STMPE=y - CONFIG_STMPE_SPI=y -diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig -index 1c97093..0996083 100644 ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -90,7 +90,7 @@ config HW_RANDOM_BCM63XX - - config HW_RANDOM_BCM2835 - tristate "Broadcom BCM2835 Random Number Generator support" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - default HW_RANDOM - ---help--- - This driver provides kernel-side support for the Random Number -diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index ca7d6463..e010420 100644 ---- a/drivers/watchdog/Kconfig -+++ b/drivers/watchdog/Kconfig -@@ -1222,7 +1222,7 @@ config BCM63XX_WDT - - config BCM2835_WDT - tristate "Broadcom BCM2835 hardware watchdog" -- depends on ARCH_BCM2835 -+ depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709 - select WATCHDOG_CORE - help - Watchdog driver for the built in watchdog hardware in Broadcom - -From 6779bd793d41be8d73ee771b149606e13e13e0b7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Tue, 2 Jun 2015 15:51:52 +0200 -Subject: [PATCH 200/216] BCM270X_DT: Add bcm2835-pm-wdt and bcm2835-rng -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This makes it possible to use the mainline watchdog and -random generator drivers: -dtparam=watchdog=on -dtparam=random=on - -bcm2708_wdog and bcm2708-rng can still be used. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 12 ++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 4 files changed, 18 insertions(+) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 75df21c..52b1404 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -124,5 +124,7 @@ - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - - audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index df12b7d..876dfca 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -114,5 +114,7 @@ - act_led_trigger = <&act_led>,"linux,default-trigger"; - - audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index fcb5828..a80b1a8 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -43,6 +43,18 @@ - #interrupt-cells = <2>; - }; - -+ watchdog: watchdog@7e100000 { -+ compatible = "brcm,bcm2835-pm-wdt"; -+ reg = <0x7e100000 0x28>; -+ status = "disabled"; -+ }; -+ -+ random: rng@7e104000 { -+ compatible = "brcm,bcm2835-rng"; -+ reg = <0x7e104000 0x10>; -+ status = "disabled"; -+ }; -+ - mailbox: mailbox@7e00b800 { - compatible = "brcm,bcm2708-vcio"; - reg = <0x7e00b880 0x40>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 78bc756..b226dfb 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -124,5 +124,7 @@ - pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - - audio = <&audio>,"status"; -+ watchdog = <&watchdog>,"status"; -+ random = <&random>,"status"; - }; - }; - -From 493b7b5c56b4afd21bd980e38deb0f9d7d06061c Mon Sep 17 00:00:00 2001 +From 070a6f51cd5f81f635cfcccd3452ee5f252a7ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 3 Jun 2015 12:26:13 +0200 -Subject: [PATCH 201/216] ARM: bcm2835: Set Serial number and Revision +Subject: [PATCH 73/77] ARM: bcm2835: Set Serial number and Revision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -153634,3120 +134261,186 @@ index 70f2f39..f7fdacd 100644 static const char * const bcm2835_compat[] = { -From e98419e0f836f39ae77a595f0d7218ba4b0576ab Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:34:24 +0200 -Subject: [PATCH 202/216] bcm2835: Match BCM270X Device Trees -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 45 +++++++++++------ - arch/arm/boot/dts/bcm2835-rpi-b.dts | 29 +++++++---- - arch/arm/boot/dts/bcm2835-rpi.dtsi | 85 +++++++++++++++++++++++++------- - arch/arm/boot/dts/bcm2835.dtsi | 12 ++--- - 4 files changed, 122 insertions(+), 49 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -index e479515..b0fb0e8 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts -@@ -4,27 +4,40 @@ - / { - compatible = "raspberrypi,model-b-plus", "brcm,bcm2835"; - model = "Raspberry Pi Model B+"; -+}; -+ -+&gpio { -+ i2s_pins: i2s { -+ brcm,pins = <18 19 20 21>; -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; - -- leds { -- act { -- gpios = <&gpio 47 0>; -- }; -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 47 0>; -+}; - -- pwr { -- label = "PWR"; -- gpios = <&gpio 35 0>; -- default-state = "keep"; -- linux,default-trigger = "default-on"; -- }; -+&leds { -+ pwr_led: pwr { -+ label = "led1"; -+ linux,default-trigger = "input"; -+ gpios = <&gpio 35 0>; - }; - }; - --&gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>; -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - -- /* I2S interface */ -- i2s_alt0: i2s_alt0 { -- brcm,pins = <18 19 20 21>; -- brcm,function = <4>; /* alt0 */ -+ pwr_led_gpio = <&pwr_led>,"gpios:4"; -+ pwr_led_activelow = <&pwr_led>,"gpios:8"; -+ pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts -index bafa46f..b867224 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts -@@ -5,19 +5,28 @@ - compatible = "raspberrypi,model-b", "brcm,bcm2835"; - model = "Raspberry Pi Model B"; - -- leds { -- act { -- gpios = <&gpio 16 1>; -- }; -- }; - }; - - &gpio { -- pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; -- -- /* I2S interface */ -- i2s_alt2: i2s_alt2 { -+ i2s_pins: i2s { - brcm,pins = <28 29 30 31>; -- brcm,function = <6>; /* alt2 */ -+ brcm,function = <4>; /* alt0 */ -+ }; -+}; -+ -+&i2s { -+ #sound-dai-cells = <0>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2s_pins>; -+}; -+ -+&act_led { -+ gpios = <&gpio 16 1>; -+}; -+ -+/ { -+ __overrides__ { -+ act_led_gpio = <&act_led>,"gpios:4"; -+ act_led_activelow = <&act_led>,"gpios:8"; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi -index f23835e..466f02b 100644 ---- a/arch/arm/boot/dts/bcm2835-rpi.dtsi -+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi -@@ -1,17 +1,29 @@ - /include/ "bcm2835.dtsi" - - / { -+ /* This is left here in case u-boot needs it */ - memory { - reg = <0 0x10000000>; - }; - -- leds { -+ aliases { -+ soc = &soc; -+ spi0 = &spi0; -+ i2c0 = &i2c0; -+ i2c1 = &i2c1; -+ i2s = &i2s; -+ gpio = &gpio; -+ intc = &intc; -+ leds = &leds; -+ sound = &sound; -+ }; -+ -+ leds: leds { - compatible = "gpio-leds"; - -- act { -- label = "ACT"; -- default-state = "keep"; -- linux,default-trigger = "heartbeat"; -+ act_led: act { -+ label = "led0"; -+ linux,default-trigger = "mmc0"; - }; - }; - -@@ -19,35 +31,61 @@ - audio: audio { - compatible = "brcm,bcm2835-audio"; - brcm,pwm-channels = <8>; -+ status = "disabled"; -+ }; -+ -+ /* External sound card */ -+ sound: sound { - }; - }; - - &gpio { -- pinctrl-names = "default"; -+ spi0_pins: spi0_pins { -+ brcm,pins = <7 8 9 10 11>; -+ brcm,function = <4>; /* alt0 */ -+ }; - -- gpioout: gpioout { -- brcm,pins = <6>; -- brcm,function = <1>; /* GPIO out */ -+ i2c0_pins: i2c0 { -+ brcm,pins = <0 1>; -+ brcm,function = <4>; - }; - -- alt0: alt0 { -- brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>; -- brcm,function = <4>; /* alt0 */ -+ i2c1_pins: i2c1 { -+ brcm,pins = <2 3>; -+ brcm,function = <4>; - }; -+}; -+ -+&spi0 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&spi0_pins>; - -- alt3: alt3 { -- brcm,pins = <48 49 50 51 52 53>; -- brcm,function = <7>; /* alt3 */ -+ spidev@0{ -+ compatible = "spidev"; -+ reg = <0>; /* CE0 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; -+ }; -+ -+ spidev@1{ -+ compatible = "spidev"; -+ reg = <1>; /* CE1 */ -+ #address-cells = <1>; -+ #size-cells = <0>; -+ spi-max-frequency = <500000>; - }; - }; - - &i2c0 { -- status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c0_pins>; - clock-frequency = <100000>; - }; - - &i2c1 { -- status = "okay"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&i2c1_pins>; - clock-frequency = <100000>; - }; - -@@ -59,3 +97,16 @@ - &fb { - status = "okay"; - }; -+ -+/ { -+ __overrides__ { -+ i2s = <&i2s>,"status"; -+ spi = <&spi0>,"status"; -+ i2c0 = <&i2c0>,"status"; -+ i2c1 = <&i2c1>,"status"; -+ i2c0_baudrate = <&i2c0>,"clock-frequency:0"; -+ i2c1_baudrate = <&i2c1>,"clock-frequency:0"; -+ act_led_trigger = <&act_led>,"linux,default-trigger"; -+ audio = <&audio>,"status"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi -index efaf4df..4b6dd65f 100644 ---- a/arch/arm/boot/dts/bcm2835.dtsi -+++ b/arch/arm/boot/dts/bcm2835.dtsi -@@ -9,7 +9,7 @@ - bootargs = ""; - }; - -- soc { -+ soc: soc { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; -@@ -51,12 +51,12 @@ - #interrupt-cells = <2>; - }; - -- watchdog@7e100000 { -+ watchdog: watchdog@7e100000 { - compatible = "brcm,bcm2835-pm-wdt"; - reg = <0x7e100000 0x28>; - }; - -- rng@7e104000 { -+ random: rng@7e104000 { - compatible = "brcm,bcm2835-rng"; - reg = <0x7e104000 0x10>; - }; -@@ -90,7 +90,7 @@ - #interrupt-cells = <2>; - }; - -- uart@7e201000 { -+ uart0: uart@7e201000 { - compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; - reg = <0x7e201000 0x1000>; - interrupts = <2 25>; -@@ -109,7 +109,7 @@ - status = "disabled"; - }; - -- spi: spi@7e204000 { -+ spi0: spi@7e204000 { - compatible = "brcm,bcm2835-spi"; - reg = <0x7e204000 0x1000>; - interrupts = <2 22>; -@@ -150,7 +150,7 @@ - status = "disabled"; - }; - -- usb@7e980000 { -+ usb: usb@7e980000 { - compatible = "brcm,bcm2835-usb"; - reg = <0x7e980000 0x10000>; - interrupts = <1 9>; - -From 3ac358b4ca8e0b71da28992689669218e0dbbacf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:35:11 +0200 -Subject: [PATCH 203/216] dts: Enable overlays on ARCH_BCM2835 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Build Device Tree overlays on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 3 +++ - arch/arm/boot/dts/overlays/Makefile | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index d5b6a82..e7ce7c4 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -12,6 +12,9 @@ endif - ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif -+ifeq ($(CONFIG_ARCH_BCM2835),y) -+ RPI_DT_OVERLAYS=y -+endif - - subdir-$(RPI_DT_OVERLAYS) += overlays - -diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile -index d18a1f2..c449c3f 100644 ---- a/arch/arm/boot/dts/overlays/Makefile -+++ b/arch/arm/boot/dts/overlays/Makefile -@@ -8,6 +8,9 @@ endif - ifeq ($(CONFIG_BCM2709_DT),y) - RPI_DT_OVERLAYS=y - endif -+ifeq ($(CONFIG_ARCH_BCM2835),y) -+ RPI_DT_OVERLAYS=y -+endif - - dtb-$(RPI_DT_OVERLAYS) += ads7846-overlay.dtb - dtb-$(RPI_DT_OVERLAYS) += bmp085_i2c-sensor-overlay.dtb - -From 6c6321340ea33c79dbfb15441ad58db03ec94167 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:35:55 +0200 -Subject: [PATCH 204/216] bcm2835: Make camera and sound drivers available -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Change kconfig dependency to make SND_BCM2708_SOC_* and -VIDEO_BCM2835 available on ARCH_BCM2835. - -Signed-off-by: Noralf Trønnes ---- - drivers/media/platform/bcm2835/Kconfig | 2 +- - sound/soc/bcm/Kconfig | 14 +++++++------- - 2 files changed, 8 insertions(+), 8 deletions(-) - -diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig -index 2cb1a68..99a5cbc 100644 ---- a/drivers/media/platform/bcm2835/Kconfig -+++ b/drivers/media/platform/bcm2835/Kconfig -@@ -2,7 +2,7 @@ - - config VIDEO_BCM2835 - bool "Broadcom BCM2835 camera interface driver" -- depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709) -+ depends on VIDEO_V4L2 && (ARCH_BCM2708 || ARCH_BCM2709 || ARCH_BCM2835) - ---help--- - Say Y here to enable camera host interface devices for - Broadcom BCM2835 SoC. This operates over the VCHIQ interface -diff --git a/sound/soc/bcm/Kconfig b/sound/soc/bcm/Kconfig -index 003ae28..516ab9d 100644 ---- a/sound/soc/bcm/Kconfig -+++ b/sound/soc/bcm/Kconfig -@@ -21,49 +21,49 @@ config SND_BCM2708_SOC_I2S - - config SND_BCM2708_SOC_HIFIBERRY_DAC - tristate "Support for HifiBerry DAC" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM5102A - help - Say Y or M if you want to add support for HifiBerry DAC. - - config SND_BCM2708_SOC_HIFIBERRY_DACPLUS - tristate "Support for HifiBerry DAC+" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM512x - help - Say Y or M if you want to add support for HifiBerry DAC+. - - config SND_BCM2708_SOC_HIFIBERRY_DIGI - tristate "Support for HifiBerry Digi" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_WM8804 - help - Say Y or M if you want to add support for HifiBerry Digi S/PDIF output board. - - config SND_BCM2708_SOC_HIFIBERRY_AMP - tristate "Support for the HifiBerry Amp" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_TAS5713 - help - Say Y or M if you want to add support for the HifiBerry Amp amplifier board. - - config SND_BCM2708_SOC_RPI_DAC - tristate "Support for RPi-DAC" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM1794A - help - Say Y or M if you want to add support for RPi-DAC. - - config SND_BCM2708_SOC_RPI_PROTO - tristate "Support for Rpi-PROTO" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_WM8731 - help - Say Y or M if you want to add support for Audio Codec Board PROTO (WM8731). - - config SND_BCM2708_SOC_IQAUDIO_DAC - tristate "Support for IQaudIO-DAC" -- depends on SND_BCM2708_SOC_I2S -+ depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S - select SND_SOC_PCM512x_I2C - help - Say Y or M if you want to add support for IQaudIO-DAC. - -From b5b5fa6e2a877089b48daaaac9b135c95c71e24f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Wed, 3 Jun 2015 12:36:19 +0200 -Subject: [PATCH 205/216] bcm2835: Merge bcm2835_defconfig with - bcmrpi_defconfig -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These commands where used to make this commit: - -./scripts/diffconfig -m arch/arm/configs/bcm2835_defconfig arch/arm/configs/bcmrpi_defconfig > merge.cfg - -cat << EOF > filter -CONFIG_ARCH_BCM2708 -CONFIG_BCM2708_DT -CONFIG_ARM_PATCH_PHYS_VIRT -CONFIG_PHYS_OFFSET -CONFIG_CMDLINE -CONFIG_BCM2708_WDT -CONFIG_HW_RANDOM_BCM2708 -CONFIG_I2C_BCM2708 -CONFIG_SPI_BCM2708 -CONFIG_SND_BCM2708_SOC_I2S -CONFIG_USB_DWCOTG -CONFIG_LIRC_RPI -EOF - -grep -F -v -f filter merge.cfg > filtered.cfg - -cat << EOF > added.cfg -CONFIG_WATCHDOG=y -CONFIG_BCM2835_WDT=y -CONFIG_MISC_FILESYSTEMS=y -CONFIG_SND_BCM2835_SOC_I2S=m -EOF - -ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/bcm2835_defconfig filtered.cfg added.cfg -ARCH=arm make oldconfig - -ARCH=arm make savedefconfig -cp defconfig arch/arm/configs/bcm2835_defconfig - -rm merge.cfg filter filtered.cfg added.cfg defconfig - -ARCH=arm make bcm2835_defconfig -ARCH=arm make oldconfig - -Signed-off-by: Noralf Trønnes ---- - arch/arm/configs/bcm2835_defconfig | 1114 +++++++++++++++++++++++++++++++++++- - 1 file changed, 1097 insertions(+), 17 deletions(-) - -diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig -index 1af6069..2e8a95a 100644 ---- a/arch/arm/configs/bcm2835_defconfig -+++ b/arch/arm/configs/bcm2835_defconfig -@@ -1,107 +1,1071 @@ - # CONFIG_LOCALVERSION_AUTO is not set - CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y - CONFIG_FHANDLE=y - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_BSD_PROCESS_ACCT=y - CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_TASKSTATS=y -+CONFIG_TASK_DELAY_ACCT=y -+CONFIG_TASK_XACCT=y -+CONFIG_TASK_IO_ACCOUNTING=y -+CONFIG_IKCONFIG=m -+CONFIG_IKCONFIG_PROC=y - CONFIG_LOG_BUF_SHIFT=18 - CONFIG_CGROUP_FREEZER=y - CONFIG_CGROUP_DEVICE=y - CONFIG_CPUSETS=y - CONFIG_CGROUP_CPUACCT=y -+CONFIG_MEMCG=y - CONFIG_CGROUP_PERF=y - CONFIG_CFS_BANDWIDTH=y - CONFIG_RT_GROUP_SCHED=y -+CONFIG_BLK_CGROUP=y - CONFIG_NAMESPACES=y - CONFIG_SCHED_AUTOGROUP=y --CONFIG_RELAY=y - CONFIG_BLK_DEV_INITRD=y - CONFIG_CC_OPTIMIZE_FOR_SIZE=y --CONFIG_KALLSYMS_ALL=y - CONFIG_EMBEDDED=y - # CONFIG_COMPAT_BRK is not set - CONFIG_PROFILING=y --CONFIG_OPROFILE=y -+CONFIG_OPROFILE=m -+CONFIG_KPROBES=y - CONFIG_JUMP_LABEL=y - CONFIG_CC_STACKPROTECTOR_REGULAR=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+CONFIG_MODVERSIONS=y -+CONFIG_MODULE_SRCVERSION_ALL=y -+CONFIG_BLK_DEV_THROTTLING=y -+CONFIG_PARTITION_ADVANCED=y -+CONFIG_MAC_PARTITION=y -+CONFIG_CFQ_GROUP_IOSCHED=y - CONFIG_ARCH_MULTI_V6=y - # CONFIG_ARCH_MULTI_V7 is not set - CONFIG_ARCH_BCM=y - CONFIG_ARCH_BCM2835=y --CONFIG_PREEMPT_VOLUNTARY=y -+CONFIG_PREEMPT=y - CONFIG_AEABI=y -+CONFIG_OABI_COMPAT=y - CONFIG_KSM=y - CONFIG_CLEANCACHE=y -+CONFIG_FRONTSWAP=y -+CONFIG_CMA=y -+CONFIG_UACCESS_WITH_MEMCPY=y - CONFIG_SECCOMP=y -+CONFIG_ZBOOT_ROM_TEXT=0x0 -+CONFIG_ZBOOT_ROM_BSS=0x0 - CONFIG_KEXEC=y - CONFIG_CRASH_DUMP=y -+CONFIG_CPU_FREQ=y -+CONFIG_CPU_FREQ_STAT=m -+CONFIG_CPU_FREQ_STAT_DETAILS=y -+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE=y -+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -+CONFIG_CPU_FREQ_GOV_USERSPACE=y -+CONFIG_CPU_FREQ_GOV_ONDEMAND=y -+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y - CONFIG_VFP=y - # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_BINFMT_MISC=m - # CONFIG_SUSPEND is not set - 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_ADVANCED_ROUTER=y -+CONFIG_IP_MULTIPLE_TABLES=y -+CONFIG_IP_ROUTE_MULTIPATH=y -+CONFIG_IP_ROUTE_VERBOSE=y -+CONFIG_IP_PNP=y -+CONFIG_IP_PNP_DHCP=y -+CONFIG_IP_PNP_RARP=y -+CONFIG_NET_IPIP=m -+CONFIG_NET_IPGRE_DEMUX=m -+CONFIG_NET_IPGRE=m -+CONFIG_IP_MROUTE=y -+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IP_PIMSM_V1=y -+CONFIG_IP_PIMSM_V2=y -+CONFIG_SYN_COOKIES=y -+CONFIG_INET_AH=m -+CONFIG_INET_ESP=m -+CONFIG_INET_IPCOMP=m -+CONFIG_INET_XFRM_MODE_TRANSPORT=m -+CONFIG_INET_XFRM_MODE_TUNNEL=m -+CONFIG_INET_XFRM_MODE_BEET=m -+CONFIG_INET_LRO=m -+CONFIG_INET_DIAG=m -+CONFIG_INET6_AH=m -+CONFIG_INET6_ESP=m -+CONFIG_INET6_IPCOMP=m -+CONFIG_IPV6_TUNNEL=m -+CONFIG_IPV6_MULTIPLE_TABLES=y -+CONFIG_IPV6_MROUTE=y -+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -+CONFIG_IPV6_PIMSM_V2=y - CONFIG_NETWORK_SECMARK=y - CONFIG_NETFILTER=y --CONFIG_CFG80211=y --CONFIG_MAC80211=y -+CONFIG_NF_CONNTRACK=m -+CONFIG_NF_CONNTRACK_ZONES=y -+CONFIG_NF_CONNTRACK_EVENTS=y -+CONFIG_NF_CONNTRACK_TIMESTAMP=y -+CONFIG_NF_CT_PROTO_DCCP=m -+CONFIG_NF_CT_PROTO_UDPLITE=m -+CONFIG_NF_CONNTRACK_AMANDA=m -+CONFIG_NF_CONNTRACK_FTP=m -+CONFIG_NF_CONNTRACK_H323=m -+CONFIG_NF_CONNTRACK_IRC=m -+CONFIG_NF_CONNTRACK_NETBIOS_NS=m -+CONFIG_NF_CONNTRACK_SNMP=m -+CONFIG_NF_CONNTRACK_PPTP=m -+CONFIG_NF_CONNTRACK_SANE=m -+CONFIG_NF_CONNTRACK_SIP=m -+CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m -+CONFIG_NETFILTER_XT_SET=m -+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -+CONFIG_NETFILTER_XT_TARGET_DSCP=m -+CONFIG_NETFILTER_XT_TARGET_HMARK=m -+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -+CONFIG_NETFILTER_XT_TARGET_LED=m -+CONFIG_NETFILTER_XT_TARGET_LOG=m -+CONFIG_NETFILTER_XT_TARGET_MARK=m -+CONFIG_NETFILTER_XT_TARGET_NFLOG=m -+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m -+CONFIG_NETFILTER_XT_TARGET_TEE=m -+CONFIG_NETFILTER_XT_TARGET_TPROXY=m -+CONFIG_NETFILTER_XT_TARGET_TRACE=m -+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -+CONFIG_NETFILTER_XT_MATCH_BPF=m -+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m -+CONFIG_NETFILTER_XT_MATCH_COMMENT=m -+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m -+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -+CONFIG_NETFILTER_XT_MATCH_CPU=m -+CONFIG_NETFILTER_XT_MATCH_DCCP=m -+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -+CONFIG_NETFILTER_XT_MATCH_DSCP=m -+CONFIG_NETFILTER_XT_MATCH_ESP=m -+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -+CONFIG_NETFILTER_XT_MATCH_HELPER=m -+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -+CONFIG_NETFILTER_XT_MATCH_IPVS=m -+CONFIG_NETFILTER_XT_MATCH_LENGTH=m -+CONFIG_NETFILTER_XT_MATCH_LIMIT=m -+CONFIG_NETFILTER_XT_MATCH_MAC=m -+CONFIG_NETFILTER_XT_MATCH_MARK=m -+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -+CONFIG_NETFILTER_XT_MATCH_NFACCT=m -+CONFIG_NETFILTER_XT_MATCH_OSF=m -+CONFIG_NETFILTER_XT_MATCH_OWNER=m -+CONFIG_NETFILTER_XT_MATCH_POLICY=m -+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m -+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -+CONFIG_NETFILTER_XT_MATCH_QUOTA=m -+CONFIG_NETFILTER_XT_MATCH_RATEEST=m -+CONFIG_NETFILTER_XT_MATCH_REALM=m -+CONFIG_NETFILTER_XT_MATCH_RECENT=m -+CONFIG_NETFILTER_XT_MATCH_SOCKET=m -+CONFIG_NETFILTER_XT_MATCH_STATE=m -+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -+CONFIG_NETFILTER_XT_MATCH_STRING=m -+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -+CONFIG_NETFILTER_XT_MATCH_TIME=m -+CONFIG_NETFILTER_XT_MATCH_U32=m -+CONFIG_IP_SET=m -+CONFIG_IP_SET_BITMAP_IP=m -+CONFIG_IP_SET_BITMAP_IPMAC=m -+CONFIG_IP_SET_BITMAP_PORT=m -+CONFIG_IP_SET_HASH_IP=m -+CONFIG_IP_SET_HASH_IPPORT=m -+CONFIG_IP_SET_HASH_IPPORTIP=m -+CONFIG_IP_SET_HASH_IPPORTNET=m -+CONFIG_IP_SET_HASH_NET=m -+CONFIG_IP_SET_HASH_NETPORT=m -+CONFIG_IP_SET_HASH_NETIFACE=m -+CONFIG_IP_SET_LIST_SET=m -+CONFIG_IP_VS=m -+CONFIG_IP_VS_PROTO_TCP=y -+CONFIG_IP_VS_PROTO_UDP=y -+CONFIG_IP_VS_PROTO_ESP=y -+CONFIG_IP_VS_PROTO_AH=y -+CONFIG_IP_VS_PROTO_SCTP=y -+CONFIG_IP_VS_RR=m -+CONFIG_IP_VS_WRR=m -+CONFIG_IP_VS_LC=m -+CONFIG_IP_VS_WLC=m -+CONFIG_IP_VS_LBLC=m -+CONFIG_IP_VS_LBLCR=m -+CONFIG_IP_VS_DH=m -+CONFIG_IP_VS_SH=m -+CONFIG_IP_VS_SED=m -+CONFIG_IP_VS_NQ=m -+CONFIG_IP_VS_FTP=m -+CONFIG_IP_VS_PE_SIP=m -+CONFIG_NF_CONNTRACK_IPV4=m -+CONFIG_IP_NF_IPTABLES=m -+CONFIG_IP_NF_MATCH_AH=m -+CONFIG_IP_NF_MATCH_ECN=m -+CONFIG_IP_NF_MATCH_TTL=m -+CONFIG_IP_NF_FILTER=m -+CONFIG_IP_NF_TARGET_REJECT=m -+CONFIG_IP_NF_NAT=m -+CONFIG_IP_NF_TARGET_MASQUERADE=m -+CONFIG_IP_NF_TARGET_NETMAP=m -+CONFIG_IP_NF_TARGET_REDIRECT=m -+CONFIG_IP_NF_MANGLE=m -+CONFIG_IP_NF_TARGET_CLUSTERIP=m -+CONFIG_IP_NF_TARGET_ECN=m -+CONFIG_IP_NF_TARGET_TTL=m -+CONFIG_IP_NF_RAW=m -+CONFIG_IP_NF_ARPTABLES=m -+CONFIG_IP_NF_ARPFILTER=m -+CONFIG_IP_NF_ARP_MANGLE=m -+CONFIG_NF_CONNTRACK_IPV6=m -+CONFIG_IP6_NF_IPTABLES=m -+CONFIG_IP6_NF_MATCH_AH=m -+CONFIG_IP6_NF_MATCH_EUI64=m -+CONFIG_IP6_NF_MATCH_FRAG=m -+CONFIG_IP6_NF_MATCH_OPTS=m -+CONFIG_IP6_NF_MATCH_HL=m -+CONFIG_IP6_NF_MATCH_IPV6HEADER=m -+CONFIG_IP6_NF_MATCH_MH=m -+CONFIG_IP6_NF_MATCH_RT=m -+CONFIG_IP6_NF_TARGET_HL=m -+CONFIG_IP6_NF_FILTER=m -+CONFIG_IP6_NF_TARGET_REJECT=m -+CONFIG_IP6_NF_MANGLE=m -+CONFIG_IP6_NF_RAW=m -+CONFIG_IP6_NF_NAT=m -+CONFIG_IP6_NF_TARGET_MASQUERADE=m -+CONFIG_IP6_NF_TARGET_NPT=m -+CONFIG_BRIDGE_NF_EBTABLES=m -+CONFIG_BRIDGE_EBT_BROUTE=m -+CONFIG_BRIDGE_EBT_T_FILTER=m -+CONFIG_BRIDGE_EBT_T_NAT=m -+CONFIG_BRIDGE_EBT_802_3=m -+CONFIG_BRIDGE_EBT_AMONG=m -+CONFIG_BRIDGE_EBT_ARP=m -+CONFIG_BRIDGE_EBT_IP=m -+CONFIG_BRIDGE_EBT_IP6=m -+CONFIG_BRIDGE_EBT_LIMIT=m -+CONFIG_BRIDGE_EBT_MARK=m -+CONFIG_BRIDGE_EBT_PKTTYPE=m -+CONFIG_BRIDGE_EBT_STP=m -+CONFIG_BRIDGE_EBT_VLAN=m -+CONFIG_BRIDGE_EBT_ARPREPLY=m -+CONFIG_BRIDGE_EBT_DNAT=m -+CONFIG_BRIDGE_EBT_MARK_T=m -+CONFIG_BRIDGE_EBT_REDIRECT=m -+CONFIG_BRIDGE_EBT_SNAT=m -+CONFIG_BRIDGE_EBT_LOG=m -+CONFIG_BRIDGE_EBT_NFLOG=m -+CONFIG_SCTP_COOKIE_HMAC_SHA1=y -+CONFIG_ATM=m -+CONFIG_L2TP=m -+CONFIG_L2TP_V3=y -+CONFIG_L2TP_IP=m -+CONFIG_L2TP_ETH=m -+CONFIG_BRIDGE=m -+CONFIG_VLAN_8021Q=m -+CONFIG_VLAN_8021Q_GVRP=y -+CONFIG_ATALK=m -+CONFIG_6LOWPAN=m -+CONFIG_NET_SCHED=y -+CONFIG_NET_SCH_CBQ=m -+CONFIG_NET_SCH_HTB=m -+CONFIG_NET_SCH_HFSC=m -+CONFIG_NET_SCH_PRIO=m -+CONFIG_NET_SCH_MULTIQ=m -+CONFIG_NET_SCH_RED=m -+CONFIG_NET_SCH_SFB=m -+CONFIG_NET_SCH_SFQ=m -+CONFIG_NET_SCH_TEQL=m -+CONFIG_NET_SCH_TBF=m -+CONFIG_NET_SCH_GRED=m -+CONFIG_NET_SCH_DSMARK=m -+CONFIG_NET_SCH_NETEM=m -+CONFIG_NET_SCH_DRR=m -+CONFIG_NET_SCH_MQPRIO=m -+CONFIG_NET_SCH_CHOKE=m -+CONFIG_NET_SCH_QFQ=m -+CONFIG_NET_SCH_CODEL=m -+CONFIG_NET_SCH_FQ_CODEL=m -+CONFIG_NET_SCH_INGRESS=m -+CONFIG_NET_SCH_PLUG=m -+CONFIG_NET_CLS_BASIC=m -+CONFIG_NET_CLS_TCINDEX=m -+CONFIG_NET_CLS_ROUTE4=m -+CONFIG_NET_CLS_FW=m -+CONFIG_NET_CLS_U32=m -+CONFIG_CLS_U32_MARK=y -+CONFIG_NET_CLS_RSVP=m -+CONFIG_NET_CLS_RSVP6=m -+CONFIG_NET_CLS_FLOW=m -+CONFIG_NET_CLS_CGROUP=m -+CONFIG_NET_EMATCH=y -+CONFIG_NET_EMATCH_CMP=m -+CONFIG_NET_EMATCH_NBYTE=m -+CONFIG_NET_EMATCH_U32=m -+CONFIG_NET_EMATCH_META=m -+CONFIG_NET_EMATCH_TEXT=m -+CONFIG_NET_EMATCH_IPSET=m -+CONFIG_NET_CLS_ACT=y -+CONFIG_NET_ACT_POLICE=m -+CONFIG_NET_ACT_GACT=m -+CONFIG_GACT_PROB=y -+CONFIG_NET_ACT_MIRRED=m -+CONFIG_NET_ACT_IPT=m -+CONFIG_NET_ACT_NAT=m -+CONFIG_NET_ACT_PEDIT=m -+CONFIG_NET_ACT_SIMP=m -+CONFIG_NET_ACT_SKBEDIT=m -+CONFIG_NET_ACT_CSUM=m -+CONFIG_BATMAN_ADV=m -+CONFIG_OPENVSWITCH=m -+CONFIG_NET_PKTGEN=m -+CONFIG_HAMRADIO=y -+CONFIG_AX25=m -+CONFIG_NETROM=m -+CONFIG_ROSE=m -+CONFIG_MKISS=m -+CONFIG_6PACK=m -+CONFIG_BPQETHER=m -+CONFIG_BAYCOM_SER_FDX=m -+CONFIG_BAYCOM_SER_HDX=m -+CONFIG_YAM=m -+CONFIG_CAN=m -+CONFIG_CAN_VCAN=m -+CONFIG_CAN_MCP251X=m -+CONFIG_IRDA=m -+CONFIG_IRLAN=m -+CONFIG_IRNET=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_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_6LOWPAN=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_BT_WILINK=m -+CONFIG_MAC80211=m -+CONFIG_MAC80211_MESH=y -+CONFIG_WIMAX=m -+CONFIG_RFKILL=m -+CONFIG_RFKILL_INPUT=y -+CONFIG_NET_9P=m -+CONFIG_NFC=m -+CONFIG_NFC_PN533=m - CONFIG_DEVTMPFS=y - CONFIG_DEVTMPFS_MOUNT=y - # CONFIG_STANDALONE is not set -+CONFIG_DMA_CMA=y -+CONFIG_CMA_SIZE_MBYTES=5 -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_CRYPTOLOOP=m -+CONFIG_BLK_DEV_DRBD=m -+CONFIG_BLK_DEV_NBD=m -+CONFIG_BLK_DEV_RAM=y -+CONFIG_CDROM_PKTCDVD=m -+CONFIG_ATA_OVER_ETH=m -+CONFIG_EEPROM_AT24=m - CONFIG_SCSI=y -+# CONFIG_SCSI_PROC_FS is not set - CONFIG_BLK_DEV_SD=y -+CONFIG_CHR_DEV_ST=m -+CONFIG_CHR_DEV_OSST=m -+CONFIG_BLK_DEV_SR=m -+CONFIG_CHR_DEV_SG=m - CONFIG_SCSI_CONSTANTS=y - CONFIG_SCSI_SCAN_ASYNC=y -+CONFIG_SCSI_ISCSI_ATTRS=y -+CONFIG_ISCSI_TCP=m -+CONFIG_ISCSI_BOOT_SYSFS=m -+CONFIG_MD=y -+CONFIG_MD_LINEAR=m -+CONFIG_MD_RAID0=m -+CONFIG_BLK_DEV_DM=m -+CONFIG_DM_CRYPT=m -+CONFIG_DM_SNAPSHOT=m -+CONFIG_DM_MIRROR=m -+CONFIG_DM_LOG_USERSPACE=m -+CONFIG_DM_RAID=m -+CONFIG_DM_ZERO=m -+CONFIG_DM_DELAY=m - CONFIG_NETDEVICES=y -+CONFIG_BONDING=m -+CONFIG_DUMMY=m -+CONFIG_IFB=m -+CONFIG_MACVLAN=m -+CONFIG_NETCONSOLE=m -+CONFIG_TUN=m -+CONFIG_VETH=m -+CONFIG_ENC28J60=m -+CONFIG_MDIO_BITBANG=m -+CONFIG_PPP=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_FILTER=y -+CONFIG_PPP_MPPE=m -+CONFIG_PPP_MULTILINK=y -+CONFIG_PPPOATM=m -+CONFIG_PPPOE=m -+CONFIG_PPPOL2TP=m -+CONFIG_PPP_ASYNC=m -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_SLIP=m -+CONFIG_SLIP_COMPRESSED=y -+CONFIG_SLIP_SMART=y -+CONFIG_USB_CATC=m -+CONFIG_USB_KAWETH=m -+CONFIG_USB_PEGASUS=m -+CONFIG_USB_RTL8150=m -+CONFIG_USB_RTL8152=m - CONFIG_USB_USBNET=y -+CONFIG_USB_NET_AX8817X=m -+CONFIG_USB_NET_AX88179_178A=m -+CONFIG_USB_NET_CDCETHER=m -+CONFIG_USB_NET_CDC_EEM=m -+CONFIG_USB_NET_CDC_NCM=m -+CONFIG_USB_NET_HUAWEI_CDC_NCM=m -+CONFIG_USB_NET_CDC_MBIM=m -+CONFIG_USB_NET_DM9601=m -+CONFIG_USB_NET_SR9700=m -+CONFIG_USB_NET_SR9800=m -+CONFIG_USB_NET_SMSC75XX=m - CONFIG_USB_NET_SMSC95XX=y --CONFIG_ZD1211RW=y --CONFIG_INPUT_EVDEV=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_EPSON2888=y -+CONFIG_USB_KC2190=y -+CONFIG_USB_NET_ZAURUS=m -+CONFIG_USB_NET_CX82310_ETH=m -+CONFIG_USB_NET_KALMIA=m -+CONFIG_USB_NET_QMI_WWAN=m -+CONFIG_USB_HSO=m -+CONFIG_USB_NET_INT51X1=m -+CONFIG_USB_IPHETH=m -+CONFIG_USB_SIERRA_NET=m -+CONFIG_USB_VL600=m -+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_CARDS=m -+CONFIG_ATH9K=m -+CONFIG_ATH9K_HTC=m -+CONFIG_CARL9170=m -+CONFIG_ATH6KL=m -+CONFIG_ATH6KL_USB=m -+CONFIG_AR5523=m -+CONFIG_B43=m -+# CONFIG_B43_PHY_N is not set -+CONFIG_B43LEGACY=m -+CONFIG_BRCMFMAC=m -+CONFIG_BRCMFMAC_USB=y -+CONFIG_HOSTAP=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_RT3573=y -+CONFIG_RT2800USB_RT53XX=y -+CONFIG_RT2800USB_RT55XX=y -+CONFIG_RT2800USB_UNKNOWN=y -+CONFIG_RTL8192CU=m -+CONFIG_ZD1211RW=m -+CONFIG_MWIFIEX=m -+CONFIG_MWIFIEX_SDIO=m -+CONFIG_WIMAX_I2400M_USB=m -+CONFIG_INPUT_POLLDEV=m -+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -+CONFIG_INPUT_JOYDEV=m -+CONFIG_INPUT_EVDEV=m -+# CONFIG_KEYBOARD_ATKBD is not set -+CONFIG_KEYBOARD_GPIO=m -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_JOYSTICK=y -+CONFIG_JOYSTICK_IFORCE=m -+CONFIG_JOYSTICK_IFORCE_USB=y -+CONFIG_JOYSTICK_XPAD=m -+CONFIG_JOYSTICK_XPAD_FF=y -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_ADS7846=m -+CONFIG_TOUCHSCREEN_EGALAX=m -+CONFIG_TOUCHSCREEN_USB_COMPOSITE=m -+CONFIG_TOUCHSCREEN_STMPE=m -+CONFIG_INPUT_MISC=y -+CONFIG_INPUT_AD714X=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_DEVPTS_MULTIPLE_INSTANCES=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_DEVKMEM is not set - CONFIG_SERIAL_AMBA_PL011=y - CONFIG_SERIAL_AMBA_PL011_CONSOLE=y - CONFIG_TTY_PRINTK=y -+CONFIG_HW_RANDOM=y -+CONFIG_HW_RANDOM_BCM2835=m -+CONFIG_RAW_DRIVER=y -+CONFIG_BRCM_CHAR_DRIVERS=y -+CONFIG_BCM_VC_CMA=y -+CONFIG_BCM_VC_SM=y - CONFIG_I2C=y --CONFIG_I2C_CHARDEV=y -+CONFIG_I2C_CHARDEV=m - CONFIG_I2C_BCM2835=y - CONFIG_SPI=y --CONFIG_SPI_BCM2835=y -+CONFIG_SPI_BCM2835=m -+CONFIG_SPI_SPIDEV=y -+CONFIG_PPS=m -+CONFIG_PPS_CLIENT_LDISC=m -+CONFIG_PPS_CLIENT_GPIO=m - CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_ARIZONA=m -+CONFIG_GPIO_STMPE=y -+CONFIG_W1=m -+CONFIG_W1_MASTER_DS2490=m -+CONFIG_W1_MASTER_DS2482=m -+CONFIG_W1_MASTER_DS1WM=m -+CONFIG_W1_MASTER_GPIO=m -+CONFIG_W1_SLAVE_THERM=m -+CONFIG_W1_SLAVE_SMEM=m -+CONFIG_W1_SLAVE_DS2408=m -+CONFIG_W1_SLAVE_DS2413=m -+CONFIG_W1_SLAVE_DS2406=m -+CONFIG_W1_SLAVE_DS2423=m -+CONFIG_W1_SLAVE_DS2431=m -+CONFIG_W1_SLAVE_DS2433=m -+CONFIG_W1_SLAVE_DS2760=m -+CONFIG_W1_SLAVE_DS2780=m -+CONFIG_W1_SLAVE_DS2781=m -+CONFIG_W1_SLAVE_DS28E04=m -+CONFIG_W1_SLAVE_BQ27000=m -+CONFIG_BATTERY_DS2760=m - # CONFIG_HWMON is not set -+CONFIG_THERMAL=y -+CONFIG_THERMAL_BCM2835=y -+CONFIG_WATCHDOG=y -+CONFIG_BCM2835_WDT=y -+CONFIG_UCB1400_CORE=m -+CONFIG_MFD_STMPE=y -+CONFIG_STMPE_SPI=y -+CONFIG_MFD_ARIZONA_I2C=m -+CONFIG_MFD_ARIZONA_SPI=m -+CONFIG_MFD_WM5102=y -+CONFIG_MEDIA_SUPPORT=m -+CONFIG_MEDIA_CAMERA_SUPPORT=y -+CONFIG_MEDIA_ANALOG_TV_SUPPORT=y -+CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y -+CONFIG_MEDIA_RADIO_SUPPORT=y -+CONFIG_MEDIA_RC_SUPPORT=y -+CONFIG_MEDIA_CONTROLLER=y -+CONFIG_LIRC=m -+CONFIG_RC_DEVICES=y -+CONFIG_RC_ATI_REMOTE=m -+CONFIG_IR_IMON=m -+CONFIG_IR_MCEUSB=m -+CONFIG_IR_REDRAT3=m -+CONFIG_IR_STREAMZAP=m -+CONFIG_IR_IGUANA=m -+CONFIG_IR_TTUSBIR=m -+CONFIG_RC_LOOPBACK=m -+CONFIG_IR_GPIO_CIR=m -+CONFIG_MEDIA_USB_SUPPORT=y -+CONFIG_USB_VIDEO_CLASS=m -+CONFIG_USB_M5602=m -+CONFIG_USB_STV06XX=m -+CONFIG_USB_GL860=m -+CONFIG_USB_GSPCA_BENQ=m -+CONFIG_USB_GSPCA_CONEX=m -+CONFIG_USB_GSPCA_CPIA1=m -+CONFIG_USB_GSPCA_DTCS033=m -+CONFIG_USB_GSPCA_ETOMS=m -+CONFIG_USB_GSPCA_FINEPIX=m -+CONFIG_USB_GSPCA_JEILINJ=m -+CONFIG_USB_GSPCA_JL2005BCD=m -+CONFIG_USB_GSPCA_KINECT=m -+CONFIG_USB_GSPCA_KONICA=m -+CONFIG_USB_GSPCA_MARS=m -+CONFIG_USB_GSPCA_MR97310A=m -+CONFIG_USB_GSPCA_NW80X=m -+CONFIG_USB_GSPCA_OV519=m -+CONFIG_USB_GSPCA_OV534=m -+CONFIG_USB_GSPCA_OV534_9=m -+CONFIG_USB_GSPCA_PAC207=m -+CONFIG_USB_GSPCA_PAC7302=m -+CONFIG_USB_GSPCA_PAC7311=m -+CONFIG_USB_GSPCA_SE401=m -+CONFIG_USB_GSPCA_SN9C2028=m -+CONFIG_USB_GSPCA_SN9C20X=m -+CONFIG_USB_GSPCA_SONIXB=m -+CONFIG_USB_GSPCA_SONIXJ=m -+CONFIG_USB_GSPCA_SPCA500=m -+CONFIG_USB_GSPCA_SPCA501=m -+CONFIG_USB_GSPCA_SPCA505=m -+CONFIG_USB_GSPCA_SPCA506=m -+CONFIG_USB_GSPCA_SPCA508=m -+CONFIG_USB_GSPCA_SPCA561=m -+CONFIG_USB_GSPCA_SPCA1528=m -+CONFIG_USB_GSPCA_SQ905=m -+CONFIG_USB_GSPCA_SQ905C=m -+CONFIG_USB_GSPCA_SQ930X=m -+CONFIG_USB_GSPCA_STK014=m -+CONFIG_USB_GSPCA_STK1135=m -+CONFIG_USB_GSPCA_STV0680=m -+CONFIG_USB_GSPCA_SUNPLUS=m -+CONFIG_USB_GSPCA_T613=m -+CONFIG_USB_GSPCA_TOPRO=m -+CONFIG_USB_GSPCA_TV8532=m -+CONFIG_USB_GSPCA_VC032X=m -+CONFIG_USB_GSPCA_VICAM=m -+CONFIG_USB_GSPCA_XIRLINK_CIT=m -+CONFIG_USB_GSPCA_ZC3XX=m -+CONFIG_USB_PWC=m -+CONFIG_VIDEO_CPIA2=m -+CONFIG_USB_ZR364XX=m -+CONFIG_USB_STKWEBCAM=m -+CONFIG_USB_S2255=m -+CONFIG_VIDEO_USBTV=m -+CONFIG_VIDEO_PVRUSB2=m -+CONFIG_VIDEO_HDPVR=m -+CONFIG_VIDEO_USBVISION=m -+CONFIG_VIDEO_STK1160_COMMON=m -+CONFIG_VIDEO_STK1160_AC97=y -+CONFIG_VIDEO_GO7007=m -+CONFIG_VIDEO_GO7007_USB=m -+CONFIG_VIDEO_GO7007_USB_S2250_BOARD=m -+CONFIG_VIDEO_AU0828=m -+CONFIG_VIDEO_AU0828_RC=y -+CONFIG_VIDEO_CX231XX=m -+CONFIG_VIDEO_CX231XX_ALSA=m -+CONFIG_VIDEO_CX231XX_DVB=m -+CONFIG_VIDEO_TM6000=m -+CONFIG_VIDEO_TM6000_ALSA=m -+CONFIG_VIDEO_TM6000_DVB=m -+CONFIG_DVB_USB=m -+CONFIG_DVB_USB_A800=m -+CONFIG_DVB_USB_DIBUSB_MB=m -+CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y -+CONFIG_DVB_USB_DIBUSB_MC=m -+CONFIG_DVB_USB_DIB0700=m -+CONFIG_DVB_USB_UMT_010=m -+CONFIG_DVB_USB_CXUSB=m -+CONFIG_DVB_USB_M920X=m -+CONFIG_DVB_USB_DIGITV=m -+CONFIG_DVB_USB_VP7045=m -+CONFIG_DVB_USB_VP702X=m -+CONFIG_DVB_USB_GP8PSK=m -+CONFIG_DVB_USB_NOVA_T_USB2=m -+CONFIG_DVB_USB_TTUSB2=m -+CONFIG_DVB_USB_DTT200U=m -+CONFIG_DVB_USB_OPERA1=m -+CONFIG_DVB_USB_AF9005=m -+CONFIG_DVB_USB_AF9005_REMOTE=m -+CONFIG_DVB_USB_PCTV452E=m -+CONFIG_DVB_USB_DW2102=m -+CONFIG_DVB_USB_CINERGY_T2=m -+CONFIG_DVB_USB_DTV5100=m -+CONFIG_DVB_USB_FRIIO=m -+CONFIG_DVB_USB_AZ6027=m -+CONFIG_DVB_USB_TECHNISAT_USB2=m -+CONFIG_DVB_USB_V2=m -+CONFIG_DVB_USB_AF9015=m -+CONFIG_DVB_USB_AF9035=m -+CONFIG_DVB_USB_ANYSEE=m -+CONFIG_DVB_USB_AU6610=m -+CONFIG_DVB_USB_AZ6007=m -+CONFIG_DVB_USB_CE6230=m -+CONFIG_DVB_USB_EC168=m -+CONFIG_DVB_USB_GL861=m -+CONFIG_DVB_USB_LME2510=m -+CONFIG_DVB_USB_MXL111SF=m -+CONFIG_DVB_USB_RTL28XXU=m -+CONFIG_DVB_USB_DVBSKY=m -+CONFIG_SMS_USB_DRV=m -+CONFIG_DVB_B2C2_FLEXCOP_USB=m -+CONFIG_DVB_AS102=m -+CONFIG_VIDEO_EM28XX=m -+CONFIG_VIDEO_EM28XX_V4L2=m -+CONFIG_VIDEO_EM28XX_ALSA=m -+CONFIG_VIDEO_EM28XX_DVB=m -+CONFIG_V4L_PLATFORM_DRIVERS=y -+CONFIG_VIDEO_BCM2835=y -+CONFIG_VIDEO_BCM2835_MMAL=m -+CONFIG_RADIO_SI470X=y -+CONFIG_USB_SI470X=m -+CONFIG_I2C_SI470X=m -+CONFIG_RADIO_SI4713=m -+CONFIG_I2C_SI4713=m -+CONFIG_USB_MR800=m -+CONFIG_USB_DSBR=m -+CONFIG_RADIO_SHARK=m -+CONFIG_RADIO_SHARK2=m -+CONFIG_USB_KEENE=m -+CONFIG_USB_MA901=m -+CONFIG_RADIO_TEA5764=m -+CONFIG_RADIO_SAA7706H=m -+CONFIG_RADIO_TEF6862=m -+CONFIG_RADIO_WL1273=m -+CONFIG_RADIO_WL128X=m -+# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set -+CONFIG_VIDEO_UDA1342=m -+CONFIG_VIDEO_SONY_BTF_MPX=m -+CONFIG_VIDEO_TVP5150=m -+CONFIG_VIDEO_TW2804=m -+CONFIG_VIDEO_TW9903=m -+CONFIG_VIDEO_TW9906=m -+CONFIG_VIDEO_OV7640=m -+CONFIG_VIDEO_MT9V011=m - CONFIG_FB=y - CONFIG_FB_BCM2708=y -+CONFIG_FB_SSD1307=m -+# CONFIG_BACKLIGHT_GENERIC is not set -+CONFIG_BACKLIGHT_GPIO=m - CONFIG_FRAMEBUFFER_CONSOLE=y - CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=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_CAIAQ_INPUT=y -+CONFIG_SND_USB_6FIRE=m -+CONFIG_SND_SOC=m -+CONFIG_SND_BCM2835_SOC_I2S=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DAC=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DACPLUS=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_DIGI=m -+CONFIG_SND_BCM2708_SOC_HIFIBERRY_AMP=m -+CONFIG_SND_BCM2708_SOC_RPI_DAC=m -+CONFIG_SND_BCM2708_SOC_RPI_PROTO=m -+CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m -+CONFIG_SND_SIMPLE_CARD=m -+CONFIG_SOUND_PRIME=m -+CONFIG_HIDRAW=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_ELO=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_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_THINGM=m -+CONFIG_HID_THRUSTMASTER=m -+CONFIG_HID_WACOM=m -+CONFIG_HID_WIIMOTE=m -+CONFIG_HID_XINMO=m -+CONFIG_HID_ZEROPLUS=m -+CONFIG_HID_ZYDACRON=m -+CONFIG_HID_PID=y -+CONFIG_USB_HIDDEV=y - CONFIG_USB=y -+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -+CONFIG_USB_MON=m -+CONFIG_USB_PRINTER=m - 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_MDC800=m -+CONFIG_USB_MICROTEK=m -+CONFIG_USBIP_CORE=m -+CONFIG_USBIP_VHCI_HCD=m -+CONFIG_USBIP_HOST=m - CONFIG_USB_DWC2=y -+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_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_F81232=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_METRO=m -+CONFIG_USB_SERIAL_MOS7720=m -+CONFIG_USB_SERIAL_MOS7840=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_SAFE=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_XSENS_MT=m -+CONFIG_USB_SERIAL_WISHBONE=m -+CONFIG_USB_SERIAL_SSU100=m -+CONFIG_USB_SERIAL_QT2=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_USB_ATM=m -+CONFIG_USB_SPEEDTOUCH=m -+CONFIG_USB_CXACRU=m -+CONFIG_USB_UEAGLEATM=m -+CONFIG_USB_XUSBATM=m - CONFIG_MMC=y -+CONFIG_MMC_BLOCK_MINORS=32 - CONFIG_MMC_BCM2835=y - CONFIG_MMC_BCM2835_DMA=y -+CONFIG_MMC_BCM2835_SDHOST=y - CONFIG_MMC_SDHCI=y - CONFIG_MMC_SDHCI_PLTFM=y - CONFIG_MMC_SDHCI_BCM2835=y --CONFIG_NEW_LEDS=y -+CONFIG_MMC_SPI=m - CONFIG_LEDS_CLASS=y - CONFIG_LEDS_GPIO=y --CONFIG_LEDS_TRIGGERS=y - CONFIG_LEDS_TRIGGER_TIMER=y - CONFIG_LEDS_TRIGGER_ONESHOT=y - CONFIG_LEDS_TRIGGER_HEARTBEAT=y -+CONFIG_LEDS_TRIGGER_BACKLIGHT=y - CONFIG_LEDS_TRIGGER_CPU=y - CONFIG_LEDS_TRIGGER_GPIO=y - CONFIG_LEDS_TRIGGER_DEFAULT_ON=y --CONFIG_LEDS_TRIGGER_TRANSIENT=y --CONFIG_LEDS_TRIGGER_CAMERA=y -+CONFIG_LEDS_TRIGGER_TRANSIENT=m -+CONFIG_LEDS_TRIGGER_CAMERA=m -+CONFIG_LEDS_TRIGGER_INPUT=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_DS1307=m -+CONFIG_RTC_DRV_DS1374=m -+CONFIG_RTC_DRV_DS1672=m -+CONFIG_RTC_DRV_DS3232=m -+CONFIG_RTC_DRV_MAX6900=m -+CONFIG_RTC_DRV_RS5C372=m -+CONFIG_RTC_DRV_ISL1208=m -+CONFIG_RTC_DRV_ISL12022=m -+CONFIG_RTC_DRV_ISL12057=m -+CONFIG_RTC_DRV_X1205=m -+CONFIG_RTC_DRV_PCF2127=m -+CONFIG_RTC_DRV_PCF8523=m -+CONFIG_RTC_DRV_PCF8563=m -+CONFIG_RTC_DRV_PCF8583=m -+CONFIG_RTC_DRV_M41T80=m -+CONFIG_RTC_DRV_BQ32K=m -+CONFIG_RTC_DRV_S35390A=m -+CONFIG_RTC_DRV_FM3130=m -+CONFIG_RTC_DRV_RX8581=m -+CONFIG_RTC_DRV_RX8025=m -+CONFIG_RTC_DRV_EM3027=m -+CONFIG_RTC_DRV_RV3029C2=m -+CONFIG_RTC_DRV_M41T93=m -+CONFIG_RTC_DRV_M41T94=m -+CONFIG_RTC_DRV_DS1305=m -+CONFIG_RTC_DRV_DS1390=m -+CONFIG_RTC_DRV_MAX6902=m -+CONFIG_RTC_DRV_R9701=m -+CONFIG_RTC_DRV_RS5C348=m -+CONFIG_RTC_DRV_DS3234=m -+CONFIG_RTC_DRV_PCF2123=m -+CONFIG_RTC_DRV_RX4581=m - CONFIG_DMADEVICES=y - CONFIG_DMA_BCM2708=y -+CONFIG_UIO=m -+CONFIG_UIO_PDRV_GENIRQ=m - CONFIG_STAGING=y -+CONFIG_PRISM2_USB=m -+CONFIG_R8712U=m -+CONFIG_R8188EU=m -+CONFIG_R8723AU=m -+CONFIG_VT6656=m -+CONFIG_SPEAKUP=m -+CONFIG_SPEAKUP_SYNTH_SOFT=m -+CONFIG_STAGING_MEDIA=y -+CONFIG_LIRC_STAGING=y -+CONFIG_LIRC_IMON=m -+CONFIG_LIRC_SASEM=m -+CONFIG_LIRC_SERIAL=m -+CONFIG_FB_TFT=m -+CONFIG_FB_TFT_AGM1264K_FL=m -+CONFIG_FB_TFT_BD663474=m -+CONFIG_FB_TFT_HX8340BN=m -+CONFIG_FB_TFT_HX8347D=m -+CONFIG_FB_TFT_HX8353D=m -+CONFIG_FB_TFT_ILI9320=m -+CONFIG_FB_TFT_ILI9325=m -+CONFIG_FB_TFT_ILI9340=m -+CONFIG_FB_TFT_ILI9341=m -+CONFIG_FB_TFT_ILI9481=m -+CONFIG_FB_TFT_ILI9486=m -+CONFIG_FB_TFT_PCD8544=m -+CONFIG_FB_TFT_RA8875=m -+CONFIG_FB_TFT_S6D02A1=m -+CONFIG_FB_TFT_S6D1121=m -+CONFIG_FB_TFT_SSD1289=m -+CONFIG_FB_TFT_SSD1306=m -+CONFIG_FB_TFT_SSD1331=m -+CONFIG_FB_TFT_SSD1351=m -+CONFIG_FB_TFT_ST7735R=m -+CONFIG_FB_TFT_TINYLCD=m -+CONFIG_FB_TFT_TLS8204=m -+CONFIG_FB_TFT_UC1701=m -+CONFIG_FB_TFT_UPD161704=m -+CONFIG_FB_TFT_WATTEROTT=m -+CONFIG_FB_FLEX=m -+CONFIG_FB_TFT_FBTFT_DEVICE=m - CONFIG_MAILBOX=y - CONFIG_BCM2708_MBOX=y - # CONFIG_IOMMU_SUPPORT is not set -+CONFIG_EXTCON=m -+CONFIG_EXTCON_ARIZONA=m - CONFIG_EXT2_FS=y - CONFIG_EXT2_FS_XATTR=y - CONFIG_EXT2_FS_POSIX_ACL=y -@@ -109,18 +1073,110 @@ CONFIG_EXT3_FS=y - CONFIG_EXT3_FS_POSIX_ACL=y - 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_QFMT_V1=m -+CONFIG_QFMT_V2=m -+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_NTFS_RW=y - CONFIG_TMPFS=y - CONFIG_TMPFS_POSIX_ACL=y --# CONFIG_MISC_FILESYSTEMS is not set -+CONFIG_CONFIGFS_FS=y -+CONFIG_ECRYPT_FS=m -+CONFIG_HFS_FS=m -+CONFIG_HFSPLUS_FS=m -+CONFIG_SQUASHFS=m -+CONFIG_SQUASHFS_XATTR=y -+CONFIG_SQUASHFS_LZO=y -+CONFIG_SQUASHFS_XZ=y -+CONFIG_F2FS_FS=y - CONFIG_NFS_FS=y --CONFIG_NFSD=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_SWAP=y -+CONFIG_ROOT_NFS=y -+CONFIG_NFS_FSCACHE=y -+CONFIG_NFSD=m -+CONFIG_NFSD_V3_ACL=y -+CONFIG_NFSD_V4=y -+CONFIG_CIFS=m -+CONFIG_CIFS_WEAK_PW_HASH=y -+CONFIG_CIFS_UPCALL=y -+CONFIG_CIFS_XATTR=y -+CONFIG_CIFS_POSIX=y -+CONFIG_9P_FS=m -+CONFIG_9P_FS_POSIX_ACL=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=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=y -+CONFIG_DLM=m - CONFIG_PRINTK_TIME=y - CONFIG_BOOT_PRINTK_DELAY=y - CONFIG_DYNAMIC_DEBUG=y -@@ -130,14 +1186,38 @@ CONFIG_DEBUG_INFO=y - CONFIG_UNUSED_SYMBOLS=y - CONFIG_DEBUG_MEMORY_INIT=y - CONFIG_LOCKUP_DETECTOR=y -+CONFIG_TIMER_STATS=y -+# CONFIG_DEBUG_PREEMPT is not set -+CONFIG_LATENCYTOP=y -+CONFIG_IRQSOFF_TRACER=y - CONFIG_SCHED_TRACER=y - CONFIG_STACK_TRACER=y -+CONFIG_BLK_DEV_IO_TRACE=y -+# CONFIG_KPROBE_EVENT is not set - CONFIG_FUNCTION_PROFILER=y - CONFIG_TEST_KSTRTOX=y - CONFIG_KGDB=y - CONFIG_KGDB_KDB=y -+CONFIG_KDB_KEYBOARD=y - CONFIG_STRICT_DEVMEM=y - CONFIG_DEBUG_LL=y - CONFIG_EARLY_PRINTK=y -+CONFIG_CRYPTO_USER=m -+CONFIG_CRYPTO_CRYPTD=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_CTS=m -+CONFIG_CRYPTO_XTS=m -+CONFIG_CRYPTO_XCBC=m -+CONFIG_CRYPTO_SHA1_ARM=m -+CONFIG_CRYPTO_SHA512=m -+CONFIG_CRYPTO_TGR192=m -+CONFIG_CRYPTO_WP512=m -+CONFIG_CRYPTO_AES_ARM=m -+CONFIG_CRYPTO_CAST5=m -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -+CONFIG_CRC_ITU_T=y -+CONFIG_LIBCRC32C=y - # CONFIG_XZ_DEC_ARM is not set - # CONFIG_XZ_DEC_ARMTHUMB is not set - -From c712b42d06623b5410a3921f71278963a9a45209 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Tue, 24 Mar 2015 16:57:04 +0000 -Subject: [PATCH 206/216] BCM270x_DT: Configure UART using DT - -See: https://github.com/raspberrypi/firmware/issues/393 ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 7 +++++++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 7 +++++++ - arch/arm/boot/dts/bcm2708_common.dtsi | 27 +++++++++++++++++++++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 7 +++++++ - arch/arm/mach-bcm2708/bcm2708.c | 9 +++++---- - arch/arm/mach-bcm2709/bcm2709.c | 9 +++++---- - 6 files changed, 58 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 52b1404..99ab3c9 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -16,6 +16,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -@@ -53,6 +54,10 @@ - status = "okay"; - }; - -+&uart0 { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -@@ -108,6 +113,8 @@ - - / { - __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 876dfca..e8c80cd 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -16,6 +16,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -@@ -53,6 +54,10 @@ - status = "okay"; - }; - -+&uart0 { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -@@ -102,6 +107,8 @@ - - / { - __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index a80b1a8..a09a3c7 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -84,6 +84,17 @@ - status = "disabled"; - }; - -+ uart0: uart@7e201000 { -+ compatible = "arm,pl011", "arm,primecell"; -+ reg = <0x7e201000 0x1000>; -+ interrupts = <2 25>; -+ clocks = <&clk_uart0 &clk_apb_p>; -+ clock-names = "uartclk","apb_pclk"; -+ arm,primecell-periphid = <0x00241011>; // For an explanation, see -+ // https://github.com/raspberrypi/linux/commit/13731d862cf5219216533a3b0de052cee4cc5038 -+ status = "disabled"; -+ }; -+ - i2s: i2s@7e203000 { - compatible = "brcm,bcm2708-i2s"; - reg = <0x7e203000 0x20>, -@@ -188,5 +199,21 @@ - clock-output-names = "spi"; - clock-frequency = <250000000>; - }; -+ -+ clk_uart0: clock@3 { -+ compatible = "fixed-clock"; -+ reg = <3>; -+ #clock-cells = <0>; -+ clock-output-names = "uart0_pclk"; -+ clock-frequency = <3000000>; -+ }; -+ -+ clk_apb_p: clock@4 { -+ compatible = "fixed-clock"; -+ reg = <4>; -+ #clock-cells = <0>; -+ clock-output-names = "apb_pclk"; -+ clock-frequency = <126000000>; -+ }; - }; - }; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index b226dfb..39b6fd4 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -16,6 +16,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -@@ -53,6 +54,10 @@ - status = "okay"; - }; - -+&uart0 { -+ status = "okay"; -+}; -+ - &spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi0_pins>; -@@ -108,6 +113,8 @@ - - / { - __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; - i2s = <&i2s>,"status"; - spi = <&spi0>,"status"; - i2c0 = <&i2c0>,"status"; -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e141c0b..e17c1de 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -1020,10 +1020,11 @@ void __init bcm2708_init(void) - i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); - #endif - -- -- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -- struct amba_device *d = amba_devs[i]; -- amba_device_register(d, &iomem_resource); -+ if (!use_dt) { -+ 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; -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 6dadb80..8834a10 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -1043,10 +1043,11 @@ void __init bcm2709_init(void) - i2c_register_board_info_dt(1, snd_pcm512x_i2c_devices, ARRAY_SIZE(snd_pcm512x_i2c_devices)); - #endif - -- -- for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -- struct amba_device *d = amba_devs[i]; -- amba_device_register(d, &iomem_resource); -+ if (!use_dt) { -+ 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; - -From aa05d1fe61d794be63d7e6055881e36c33cdb09c Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 4 Jun 2015 16:16:08 +0100 -Subject: [PATCH 207/216] vchiq_arm: ARCH_BCM2835 compatibility - -Use virt_to_dma (not ideal, I know) to calculate the virt-to-bus -offset. This will make use of the "dma-ranges" property, if -present. ---- - drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -index 660aad2..c739083 100644 ---- a/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -+++ b/drivers/misc/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c -@@ -46,7 +46,7 @@ - - #define TOTAL_SLOTS (VCHIQ_SLOT_ZERO_SLOTS + 2 * 32) - --#define VCHIQ_ARM_ADDRESS(x) ((void *)__virt_to_bus((unsigned)x)) -+#define VCHIQ_ARM_ADDRESS(x) ((void *)((char *)x + g_virt_to_bus_offset)) - - #include "vchiq_arm.h" - #include "vchiq_2835.h" -@@ -66,7 +66,8 @@ typedef struct vchiq_2835_state_struct { - static void __iomem *g_regs; - static FRAGMENTS_T *g_fragments_base; - static FRAGMENTS_T *g_free_fragments; --struct semaphore g_free_fragments_sema; -+static struct semaphore g_free_fragments_sema; -+static unsigned long g_virt_to_bus_offset; - - extern int vchiq_arm_log_level; - -@@ -92,6 +93,8 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) - int slot_mem_size, frag_mem_size; - int err, irq, i; - -+ g_virt_to_bus_offset = virt_to_dma(dev, (void *)0); -+ - /* Allocate space for the channels in coherent memory */ - slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(sizeof(FRAGMENTS_T) * MAX_FRAGMENTS); - -From fa0a4bff157dddc6207cba9911a1581864cf2307 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Jun 2015 14:00:54 +0100 -Subject: [PATCH 208/216] BCM270x_DT: Enable UART in the example Compute Module - DTS as well +From 3add74da14e27d18ef276f66c55a69e6dc014216 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Tue, 16 Jun 2015 17:47:27 +0100 +Subject: [PATCH 74/77] platform: Add force_core command line setting to boot + from a different core number --- - arch/arm/boot/dts/bcm2708-rpi-cm.dts | 11 +++++++++++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 3 ++- - 3 files changed, 14 insertions(+), 1 deletion(-) + arch/arm/mach-bcm2709/armctrl.c | 17 ++++++++++++++++- + arch/arm/mach-bcm2709/bcm2709.c | 2 ++ + 2 files changed, 18 insertions(+), 1 deletion(-) -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dts b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -index 45f8244..238bd65 100755 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dts -@@ -5,3 +5,14 @@ - / { - model = "Raspberry Pi Compute Module"; - }; -+ -+&uart0 { -+ status = "okay"; -+}; -+ -+/ { -+ __overrides__ { -+ uart0 = <&uart0>,"status"; -+ uart0_clkrate = <&clk_uart0>,"clock-frequency:0"; -+ }; -+}; -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 1c2cfcf..43830a6 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -11,6 +11,7 @@ - intc = &intc; - leds = &leds; - sound = &sound; -+ uart0 = &uart0; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index a09a3c7..dc0346b 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -185,10 +185,11 @@ - clock-frequency = <250000000>; - }; - -- clk_i2c: i2c { -+ clk_i2c: clock@1 { - compatible = "fixed-clock"; - reg = <1>; - #clock-cells = <0>; -+ clock-output-names = "i2c"; - clock-frequency = <250000000>; - }; - - -From fae583caba82c37f9a1e0cff81fbaa4c3f768657 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Fri, 5 Jun 2015 15:59:08 +0100 -Subject: [PATCH 209/216] bcm270x defconfigs: Remove spurious entries - ---- - arch/arm/configs/bcm2709_defconfig | 5 ----- - arch/arm/configs/bcmrpi_defconfig | 8 -------- - 2 files changed, 13 deletions(-) - -diff --git a/arch/arm/configs/bcm2709_defconfig b/arch/arm/configs/bcm2709_defconfig -index d08ae51..78e1202 100644 ---- a/arch/arm/configs/bcm2709_defconfig -+++ b/arch/arm/configs/bcm2709_defconfig -@@ -344,12 +344,7 @@ CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m - CONFIG_YAM=m - CONFIG_CAN=m --CONFIG_CAN_RAW=m --CONFIG_CAN_BCM=m --CONFIG_CAN_GW=m - CONFIG_CAN_VCAN=m --CONFIG_CAN_DEV=m --CONFIG_CAN_CALC_BITTIMING=y - CONFIG_CAN_MCP251X=m - CONFIG_IRDA=m - CONFIG_IRLAN=m -diff --git a/arch/arm/configs/bcmrpi_defconfig b/arch/arm/configs/bcmrpi_defconfig -index 11bbfac..c6a5db2 100644 ---- a/arch/arm/configs/bcmrpi_defconfig -+++ b/arch/arm/configs/bcmrpi_defconfig -@@ -335,14 +335,6 @@ CONFIG_6PACK=m - CONFIG_BPQETHER=m - CONFIG_BAYCOM_SER_FDX=m - CONFIG_BAYCOM_SER_HDX=m --CONFIG_CAN=m --CONFIG_CAN_RAW=m --CONFIG_CAN_BCM=m --CONFIG_CAN_GW=m --CONFIG_CAN_VCAN=m --CONFIG_CAN_DEV=m --CONFIG_CAN_CALC_BITTIMING=y --CONFIG_CAN_MCP251X=m - CONFIG_YAM=m - CONFIG_CAN=m - CONFIG_CAN_VCAN=m - -From 549ff9d4fee2f6dc0abdeaa552754ce2197ba331 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 May 2015 09:00:01 +0100 -Subject: [PATCH 210/216] BCM270x_DT: Add a label to the clocks node, and a few - aliases - ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-b.dts | 2 ++ - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 2 ++ - arch/arm/boot/dts/bcm2708_common.dtsi | 2 +- - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 2 ++ - 5 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index 99ab3c9..c9053f8 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -15,8 +15,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index e8c80cd..32066c3 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -15,8 +15,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index 43830a6..f38a0c2 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -10,8 +10,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index dc0346b..a9f1507 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -172,7 +172,7 @@ - }; - }; - -- clocks { -+ clocks: clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index 39b6fd4..a9adaf4 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -15,8 +15,10 @@ - gpio = &gpio; - intc = &intc; - leds = &leds; -+ audio = &audio; - sound = &sound; - uart0 = &uart0; -+ clocks = &clocks; - }; - - sound: sound { - -From 1b8bcc8ef9b600f7ac5e4d40bd70b507ad02aa01 Mon Sep 17 00:00:00 2001 -From: Phil Elwell -Date: Thu, 28 May 2015 09:01:02 +0100 -Subject: [PATCH 211/216] sdhost-overlay: Move clock declaration out of /soc - ---- - arch/arm/boot/dts/overlays/sdhost-overlay.dts | 29 +++++++++++++++------------ - 1 file changed, 16 insertions(+), 13 deletions(-) - -diff --git a/arch/arm/boot/dts/overlays/sdhost-overlay.dts b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -index b2653e9..8fb28e9 100644 ---- a/arch/arm/boot/dts/overlays/sdhost-overlay.dts -+++ b/arch/arm/boot/dts/overlays/sdhost-overlay.dts -@@ -24,23 +24,26 @@ - brcm,overclock-50 = <0>; - status = "okay"; - }; -+ }; -+ }; - -- clocks { -- #address-cells = <1>; -- #size-cells = <0>; -+ fragment@1 { -+ target = <&clocks>; -+ __overlay__ { -+ #address-cells = <1>; -+ #size-cells = <0>; - -- clk_sdhost: clock@3 { -- compatible = "fixed-clock"; -- reg = <0>; -- #clock-cells = <0>; -- clock-output-names = "sdhost"; -- clock-frequency = <250000000>; -- }; -+ clk_sdhost: sdhost { -+ compatible = "fixed-clock"; -+ reg = <0>; -+ #clock-cells = <0>; -+ clock-output-names = "sdhost"; -+ clock-frequency = <250000000>; - }; - }; - }; - -- fragment@1 { -+ fragment@2 { - target = <&gpio>; - __overlay__ { - sdhost_pins: sdhost_pins { -@@ -50,7 +53,7 @@ - }; - }; - -- fragment@2 { -+ fragment@3 { - target = <&mmc>; - __overlay__ { - /* Find a way to disable the other driver */ -@@ -59,7 +62,7 @@ - }; - }; - -- fragment@3 { -+ fragment@4 { - target-path = "/__overrides__"; - __overlay__ { - sdhost_freq = <&clk_sdhost>,"clock-frequency:0"; - -From 24d8164a16fb825c4bee4a8cca87f55a68f33edf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 6 Jun 2015 23:45:32 +0200 -Subject: [PATCH 212/216] BCM270X_DT: Enable 'make clean' on overlays directory -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Always add the overlays directory to subdir so it can be -cleaned with 'make clean'. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/Makefile | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index e7ce7c4..d85583c 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -16,8 +16,6 @@ ifeq ($(CONFIG_ARCH_BCM2835),y) - RPI_DT_OVERLAYS=y - endif - --subdir-$(RPI_DT_OVERLAYS) += overlays -- - dtb-$(CONFIG_MACH_ASM9260) += \ - alphascale-asm9260-devkit.dtb - # Keep at91 dtb files sorted alphabetically for each SoC -@@ -676,3 +674,5 @@ clean-files := *.dtb - ifeq ($(RPI_DT_OVERLAYS),y) - DTC_FLAGS ?= -@ - endif -+ -+subdir-y += overlays - -From 2b53c727bbb2ba40102236f127ea6e68b1148335 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 7 Jun 2015 13:35:33 +0200 -Subject: [PATCH 213/216] hwmon: Remove bcm2835-hwmon -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -bcm2835-thermal combined with the configs HWMON=y and -THERMAL_HWMON=y, gives the same functionality. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 5 - - arch/arm/mach-bcm2709/bcm2709.c | 5 - - drivers/hwmon/Kconfig | 10 -- - drivers/hwmon/Makefile | 1 - - drivers/hwmon/bcm2835-hwmon.c | 219 ---------------------------------------- - 5 files changed, 240 deletions(-) - delete mode 100644 drivers/hwmon/bcm2835-hwmon.c - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index e17c1de..4f191d9 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -697,10 +697,6 @@ static struct platform_device bcm2708_bsc1_device = { - .resource = bcm2708_bsc1_resources, +diff --git a/arch/arm/mach-bcm2709/armctrl.c b/arch/arm/mach-bcm2709/armctrl.c +index a366275..90805a6 100644 +--- a/arch/arm/mach-bcm2709/armctrl.c ++++ b/arch/arm/mach-bcm2709/armctrl.c +@@ -45,6 +45,8 @@ static unsigned int remap_irqs[(INTERRUPT_ARASANSDIO + 1) - INTERRUPT_JPEG] = { + INTERRUPT_VC_ARASANSDIO }; --static struct platform_device bcm2835_hwmon_device = { -- .name = "bcm2835_hwmon", --}; -- - static struct platform_device bcm2835_thermal_device = { - .name = "bcm2835_thermal", - }; -@@ -983,7 +979,6 @@ void __init bcm2708_init(void) - bcm_register_device_dt(&bcm2708_bsc1_device); - } - -- bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index 8834a10..d61bb30 100644 ---- a/arch/arm/mach-bcm2709/bcm2709.c -+++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -718,10 +718,6 @@ static struct platform_device bcm2708_bsc1_device = { - .resource = bcm2708_bsc1_resources, - }; - --static struct platform_device bcm2835_hwmon_device = { -- .name = "bcm2835_hwmon", --}; -- - static struct platform_device bcm2835_thermal_device = { - .name = "bcm2835_thermal", - }; -@@ -1006,7 +1002,6 @@ void __init bcm2709_init(void) - bcm_register_device_dt(&bcm2708_bsc1_device); - } - -- bcm_register_device(&bcm2835_hwmon_device); - bcm_register_device_dt(&bcm2835_thermal_device); - - #if defined(CONFIG_SND_BCM2708_SOC_I2S) || defined(CONFIG_SND_BCM2708_SOC_I2S_MODULE) -diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig -index 8c4474d..110fade 100644 ---- a/drivers/hwmon/Kconfig -+++ b/drivers/hwmon/Kconfig -@@ -1703,16 +1703,6 @@ config SENSORS_ULTRA45 - This driver provides support for the Ultra45 workstation environmental - sensors. - --config SENSORS_BCM2835 -- depends on THERMAL_BCM2835=n -- tristate "Broadcom BCM2835 HWMON Driver" -- help -- If you say yes here you get support for the hardware -- monitoring features of the BCM2835 Chip -- -- This driver can also be built as a module. If so, the module -- will be called bcm2835-hwmon. -- - if ACPI - - comment "ACPI drivers" -diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile -index e7c60cb..6c94147 100644 ---- a/drivers/hwmon/Makefile -+++ b/drivers/hwmon/Makefile -@@ -155,7 +155,6 @@ obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o - obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o - obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o - obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o --obj-$(CONFIG_SENSORS_BCM2835) += bcm2835-hwmon.o - - obj-$(CONFIG_PMBUS) += pmbus/ - -diff --git a/drivers/hwmon/bcm2835-hwmon.c b/drivers/hwmon/bcm2835-hwmon.c -deleted file mode 100644 -index d14502c..0000000 ---- a/drivers/hwmon/bcm2835-hwmon.c -+++ /dev/null -@@ -1,219 +0,0 @@ --/***************************************************************************** --* 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 -- --#define MODULE_NAME "bcm2835_hwmon" -- --/*#define HWMON_DEBUG_ENABLE*/ -- --#ifdef HWMON_DEBUG_ENABLE --#define print_debug(fmt,...) printk(KERN_INFO "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__, __LINE__, ##__VA_ARGS__) --#else --#define print_debug(fmt,...) --#endif --#define print_err(fmt,...) printk(KERN_ERR "%s:%s:%d: "fmt"\n", MODULE_NAME, __func__,__LINE__, ##__VA_ARGS__) --#define print_info(fmt,...) printk(KERN_INFO "%s: "fmt"\n", MODULE_NAME, ##__VA_ARGS__) -- --#define VC_TAG_GET_TEMP 0x00030006 --#define VC_TAG_GET_MAX_TEMP 0x0003000A -- --/* --- STRUCTS --- */ --struct bcm2835_hwmon_data { -- struct device *hwmon_dev; --}; -- --/* tag part of the message */ --struct vc_msg_tag { -- uint32_t tag_id; /* the tag ID for the temperature */ -- uint32_t buffer_size; /* size of the buffer (should be 8) */ -- uint32_t request_code; /* identifies message as a request (should be 0) */ -- uint32_t id; /* extra ID field (should be 0) */ -- uint32_t val; /* returned value of the temperature */ --}; -- --/* message structure to be sent to videocore */ --struct vc_msg { -- uint32_t msg_size; /* simply, sizeof(struct vc_msg) */ -- uint32_t request_code; /* holds various information like the success and number of bytes returned (refer to mailboxes wiki) */ -- struct vc_msg_tag tag; /* the tag structure above to make */ -- uint32_t end_tag; /* an end identifier, should be set to NULL */ --}; -- --typedef enum { -- TEMP, -- MAX_TEMP, --} temp_type; -- --/* --- PROTOTYPES --- */ --static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf); --static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf); -- --/* --- GLOBALS --- */ -- --static struct bcm2835_hwmon_data *bcm2835_data; --static struct platform_driver bcm2835_hwmon_driver; -- --static SENSOR_DEVICE_ATTR(name, S_IRUGO,bcm2835_get_name,NULL,0); --static SENSOR_DEVICE_ATTR(temp1_input,S_IRUGO,bcm2835_get_temp,NULL,TEMP); --static SENSOR_DEVICE_ATTR(temp1_max,S_IRUGO,bcm2835_get_temp,NULL,MAX_TEMP); -- --static struct attribute* bcm2835_attributes[] = { -- &sensor_dev_attr_name.dev_attr.attr, -- &sensor_dev_attr_temp1_input.dev_attr.attr, -- &sensor_dev_attr_temp1_max.dev_attr.attr, -- NULL, --}; -- --static struct attribute_group bcm2835_attr_group = { -- .attrs = bcm2835_attributes, --}; -- --/* --- FUNCTIONS --- */ -- --static ssize_t bcm2835_get_name(struct device *dev, struct device_attribute *attr, char *buf) --{ -- return sprintf(buf,"bcm2835_hwmon\n"); --} -- --static ssize_t bcm2835_get_temp(struct device *dev, struct device_attribute *attr, char *buf) --{ -- struct vc_msg msg; -- int result; -- uint temp = 0; -- int index = ((struct sensor_device_attribute*)to_sensor_dev_attr(attr))->index; -- -- print_debug("IN"); -- -- /* wipe all previous message data */ -- memset(&msg, 0, sizeof msg); -- -- /* determine the message type */ -- if(index == TEMP) -- msg.tag.tag_id = VC_TAG_GET_TEMP; -- else if (index == MAX_TEMP) -- msg.tag.tag_id = VC_TAG_GET_MAX_TEMP; -- else -- { -- print_debug("Unknown temperature message!"); -- return -EINVAL; -- } -- -- msg.msg_size = sizeof msg; -- msg.tag.buffer_size = 8; -- -- /* send the message */ -- result = bcm_mailbox_property(&msg, sizeof msg); -- -- /* check if it was all ok and return the rate in milli degrees C */ -- if (result == 0 && (msg.request_code & 0x80000000)) -- temp = (uint)msg.tag.val; -- #ifdef HWMON_DEBUG_ENABLE -- else -- print_debug("Failed to get temperature!"); -- #endif -- print_debug("Got temperature as %u",temp); -- print_debug("OUT"); -- return sprintf(buf, "%u\n", temp); --} -- -- --static int bcm2835_hwmon_probe(struct platform_device *pdev) --{ -- int err; -- -- print_debug("IN"); -- print_debug("HWMON Driver has been probed!"); -- -- /* check that the device isn't null!*/ -- if(pdev == NULL) -- { -- print_debug("Platform device is empty!"); -- return -ENODEV; -- } -- -- /* allocate memory for neccessary data */ -- bcm2835_data = kzalloc(sizeof(struct bcm2835_hwmon_data),GFP_KERNEL); -- if(!bcm2835_data) -- { -- print_debug("Unable to allocate memory for hwmon data!"); -- err = -ENOMEM; -- goto kzalloc_error; -- } -- -- /* create the sysfs files */ -- if(sysfs_create_group(&pdev->dev.kobj, &bcm2835_attr_group)) -- { -- print_debug("Unable to create sysfs files!"); -- err = -EFAULT; -- goto sysfs_error; -- } -- -- /* register the hwmon device */ -- bcm2835_data->hwmon_dev = hwmon_device_register(&pdev->dev); -- if (IS_ERR(bcm2835_data->hwmon_dev)) -- { -- err = PTR_ERR(bcm2835_data->hwmon_dev); -- goto hwmon_error; -- } -- print_debug("OUT"); -- return 0; -- -- /* error goto's */ -- hwmon_error: -- sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -- -- sysfs_error: -- kfree(bcm2835_data); -- -- kzalloc_error: -- -- return err; -- --} -- --static int bcm2835_hwmon_remove(struct platform_device *pdev) --{ -- print_debug("IN"); -- hwmon_device_unregister(bcm2835_data->hwmon_dev); -- -- sysfs_remove_group(&pdev->dev.kobj, &bcm2835_attr_group); -- print_debug("OUT"); -- return 0; --} -- --/* Hwmon Driver */ --static struct platform_driver bcm2835_hwmon_driver = { -- .probe = bcm2835_hwmon_probe, -- .remove = bcm2835_hwmon_remove, -- .driver = { -- .name = "bcm2835_hwmon", -- .owner = THIS_MODULE, -- }, --}; -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Dorian Peake"); --MODULE_DESCRIPTION("HW Monitor driver for bcm2835 chip"); -- --module_platform_driver(bcm2835_hwmon_driver); - -From a4573f4e07996b61582f828189091bede1296d25 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sat, 6 Jun 2015 22:59:28 +0200 -Subject: [PATCH 214/216] BCM270x: Make uart1 work with Device Tree -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add uart1 to Device Tree. Enable it in AUXENB when it's used. -Remove old platform device. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/boot/dts/bcm2708-rpi-b-plus.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-b.dts | 1 + - arch/arm/boot/dts/bcm2708-rpi-cm.dtsi | 1 + - arch/arm/boot/dts/bcm2708_common.dtsi | 10 +++++++++ - arch/arm/boot/dts/bcm2709-rpi-2-b.dts | 1 + - arch/arm/mach-bcm2708/bcm2708.c | 35 +++++++++++--------------------- - arch/arm/mach-bcm2709/bcm2709.c | 34 +++++++++++-------------------- - 7 files changed, 38 insertions(+), 45 deletions(-) - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -index c9053f8..0fa2210 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b-plus.dts -@@ -18,6 +18,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-b.dts b/arch/arm/boot/dts/bcm2708-rpi-b.dts -index 32066c3..3fd49d0 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-b.dts -+++ b/arch/arm/boot/dts/bcm2708-rpi-b.dts -@@ -18,6 +18,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -index f38a0c2..3da7d3b 100644 ---- a/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -+++ b/arch/arm/boot/dts/bcm2708-rpi-cm.dtsi -@@ -13,6 +13,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/boot/dts/bcm2708_common.dtsi b/arch/arm/boot/dts/bcm2708_common.dtsi -index a9f1507..8caa234 100644 ---- a/arch/arm/boot/dts/bcm2708_common.dtsi -+++ b/arch/arm/boot/dts/bcm2708_common.dtsi -@@ -134,6 +134,16 @@ - status = "disabled"; - }; - -+ uart1: uart@7e215040 { -+ compatible = "brcm,bcm2835-aux-uart", "ns16550"; -+ reg = <0x7e215040 0x40>; -+ interrupts = <1 29>; -+ clock-frequency = <500000000>; -+ reg-shift = <2>; -+ no-loopback-test; -+ status = "disabled"; -+ }; ++extern unsigned force_core; + - i2c1: i2c@7e804000 { - compatible = "brcm,bcm2708-i2c"; - reg = <0x7e804000 0x1000>; -diff --git a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -index a9adaf4..8aaaf1f 100644 ---- a/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -+++ b/arch/arm/boot/dts/bcm2709-rpi-2-b.dts -@@ -18,6 +18,7 @@ - audio = &audio; - sound = &sound; - uart0 = &uart0; -+ uart1 = &uart1; - clocks = &clocks; - }; - -diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index 4f191d9..f1706366 100644 ---- a/arch/arm/mach-bcm2708/bcm2708.c -+++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -353,28 +353,6 @@ static struct platform_device bcm2708_fb_device = { - }, - }; - --static struct plat_serial8250_port bcm2708_uart1_platform_data[] = { -- { -- .mapbase = UART1_BASE + 0x40, -- .irq = IRQ_AUX, -- .uartclk = 500000000, -- .regshift = 2, -- .iotype = UPIO_MEM, -- .flags = UPF_SHARE_IRQ | UPF_FIXED_TYPE | UPF_FIXED_PORT | -- UPF_IOREMAP | UPF_SKIP_TEST, -- .type = PORT_16550, -- }, -- {}, --}; -- --static struct platform_device bcm2708_uart1_device = { -- .name = "serial8250", -- .id = PLAT8250_DEV_PLATFORM, -- .dev = { -- .platform_data = bcm2708_uart1_platform_data, -- }, --}; -- - static struct resource bcm2708_usb_resources[] = { - [0] = { - .start = USB_BASE, -@@ -897,6 +875,17 @@ static void bcm2708_power_off(void) - } - } - -+static void __init bcm2708_init_uart1(void) -+{ -+ struct device_node *np; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); -+ if (of_device_is_available(np)) { -+ pr_info("bcm2708: Mini UART enabled\n"); -+ writel(1, __io_address(UART1_BASE + 0x4)); -+ } -+} -+ - #ifdef CONFIG_OF - static void __init bcm2708_dt_init(void) + static void armctrl_mask_irq(struct irq_data *d) { -@@ -952,13 +941,13 @@ void __init bcm2708_init(void) - bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); + static const unsigned int disables[4] = { +@@ -92,7 +94,13 @@ static void armctrl_unmask_irq(struct irq_data *d) + int i; + if (d->irq >= FIQ_START) { + unsigned int data; +- if (num_online_cpus() > 1) { ++ if (force_core) { ++ data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ data &= ~0xc; ++ data |= ((force_core-1) << 2); ++ writel(data, __io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ } ++ else if (num_online_cpus() > 1) { + data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING)); + data &= ~0xc; + data |= (1 << 2); +@@ -119,6 +127,13 @@ static void armctrl_unmask_irq(struct irq_data *d) + } #endif - bcm2708_init_led(); -+ bcm2708_init_uart1(); - - /* Only create the platform devices for the ALSA driver in the - absence of an enabled "audio" DT node */ + } else if (d->irq >= ARM_IRQ1_BASE && d->irq < ARM_IRQ_LOCAL_BASE) { ++ if (force_core) { ++ unsigned int data; ++ data = readl(__io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ data &= ~0x3; ++ data |= ((force_core-1) << 0); ++ writel(data, __io_address(ARM_LOCAL_GPU_INT_ROUTING)); ++ } + unsigned int data = (unsigned int)irq_get_chip_data(d->irq); + writel(1 << (data & 0x1f), __io_address(enables[(data >> 5) & 0x3])); + } else if (d->irq == INTERRUPT_ARM_LOCAL_PMU_FAST) { diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index d61bb30..ffa667e 100644 +index 507ff52..c5e51e8 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -363,27 +363,6 @@ static struct platform_device bcm2708_fb_device = { - }, - }; +@@ -96,6 +96,7 @@ static unsigned w1_gpio_pin = W1_GPIO; + static unsigned w1_gpio_pullup = W1_PULLUP; + static bool vc_i2c_override = false; + static int pps_gpio_pin = -1; ++unsigned force_core; --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, -- }, -- {}, --}; -- --static struct platform_device bcm2708_uart1_device = { -- .name = "serial8250", -- .id = PLAT8250_DEV_PLATFORM, -- .dev = { -- .platform_data = bcm2708_uart1_platform_data, -- }, --}; -- - static struct resource bcm2708_usb_resources[] = { - [0] = { - .start = USB_BASE, -@@ -918,6 +897,17 @@ static void bcm2709_power_off(void) + static unsigned use_dt = 0; + +@@ -1305,6 +1306,7 @@ MACHINE_START(BCM2708, "BCM2709") + .dt_compat = bcm2709_compat, + MACHINE_END + ++module_param(force_core, uint, 0644); + module_param(boardrev, uint, 0644); + module_param(serial, uint, 0644); + module_param(uart_clock, uint, 0644); + +From a283be0c98260b1f29c8c46df7e8fb2a9cdaf5a8 Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 18 Jun 2015 17:46:17 +0100 +Subject: [PATCH 75/77] mach-bcm270x: Enable the building of pinctrl-bcm2835 + +--- + drivers/pinctrl/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile +index 6eadf04..ca6e1be 100644 +--- a/drivers/pinctrl/Makefile ++++ b/drivers/pinctrl/Makefile +@@ -38,6 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o + obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o + obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o + ++obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_MACH_BCM2709) += bcm/ + obj-$(CONFIG_ARCH_BCM) += bcm/ + obj-$(CONFIG_ARCH_BERLIN) += berlin/ + obj-y += freescale/ + +From fd08db11f15960c30449a5a2cb14d3ab7fd470ea Mon Sep 17 00:00:00 2001 +From: Phil Elwell +Date: Thu, 18 Jun 2015 18:06:28 +0100 +Subject: [PATCH 76/77] squash: Fix inconsistency in pinctrl Makefile patch + +--- + drivers/pinctrl/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile +index ca6e1be..9119513 100644 +--- a/drivers/pinctrl/Makefile ++++ b/drivers/pinctrl/Makefile +@@ -38,7 +38,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o + obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o + obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o + +-obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_MACH_BCM2709) += bcm/ ++obj-$(CONFIG_ARCH_BCM2708)$(CONFIG_ARCH_BCM2709) += bcm/ + obj-$(CONFIG_ARCH_BCM) += bcm/ + obj-$(CONFIG_ARCH_BERLIN) += berlin/ + obj-y += freescale/ + +From 05376fce25aaab4f47182a5af04928bfa06f30d6 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Thu, 18 Jun 2015 19:53:58 +0100 +Subject: [PATCH 77/77] platform: squash: Remove IRQF_DISABLED + +--- + arch/arm/mach-bcm2708/armctrl.c | 2 +- + arch/arm/mach-bcm2708/bcm2708.c | 2 +- + arch/arm/mach-bcm2708/bcm2708_gpio.c | 2 +- + arch/arm/mach-bcm2709/bcm2709.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/mach-bcm2708/armctrl.c b/arch/arm/mach-bcm2708/armctrl.c +index 74bacb3..0429225 100644 +--- a/arch/arm/mach-bcm2708/armctrl.c ++++ b/arch/arm/mach-bcm2708/armctrl.c +@@ -305,7 +305,7 @@ int __init armctrl_init(void __iomem * base, unsigned int irq_start, + irq_set_chip(irq, &armctrl_chip); + irq_set_chip_data(irq, (void *)data); + irq_set_handler(irq, handle_level_irq); +- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_DISABLED); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - } -+static void __init bcm2709_init_uart1(void) -+{ -+ struct device_node *np; -+ -+ np = of_find_compatible_node(NULL, NULL, "brcm,bcm2835-aux-uart"); -+ if (of_device_is_available(np)) { -+ pr_info("bcm2709: Mini UART enabled\n"); -+ writel(1, __io_address(UART1_BASE + 0x4)); -+ } -+} -+ - #ifdef CONFIG_OF - static void __init bcm2709_dt_init(void) - { -@@ -975,13 +965,13 @@ void __init bcm2709_init(void) - #endif - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_uart1_device); - bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); - #endif - bcm2709_init_led(); -+ bcm2709_init_uart1(); - - /* Only create the platform devices for the ALSA driver in the - absence of an enabled "audio" DT node */ - -From 31c0f40b228b657d4c8968c32768992a3bbcefb6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 7 Jun 2015 20:42:35 +0200 -Subject: [PATCH 215/216] fixup: BCM2709: Remove unused clock implementation - ---- - arch/arm/mach-bcm2709/clock.c | 61 ------------------------------------------- - arch/arm/mach-bcm2709/clock.h | 24 ----------------- - 2 files changed, 85 deletions(-) - delete mode 100644 arch/arm/mach-bcm2709/clock.c - delete mode 100644 arch/arm/mach-bcm2709/clock.h - -diff --git a/arch/arm/mach-bcm2709/clock.c b/arch/arm/mach-bcm2709/clock.c -deleted file mode 100644 -index 4fc556e..0000000 ---- a/arch/arm/mach-bcm2709/clock.c -+++ /dev/null -@@ -1,61 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.c -- * -- * Copyright (C) 2010 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2 of the License, or -- * (at your option) any later version. -- * -- * This program is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- * GNU General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- */ --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --#include "clock.h" -- --int clk_enable(struct clk *clk) --{ -- return 0; --} --EXPORT_SYMBOL(clk_enable); -- --void clk_disable(struct clk *clk) --{ --} --EXPORT_SYMBOL(clk_disable); -- --unsigned long clk_get_rate(struct clk *clk) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_get_rate); -- --long clk_round_rate(struct clk *clk, unsigned long rate) --{ -- return clk->rate; --} --EXPORT_SYMBOL(clk_round_rate); -- --int clk_set_rate(struct clk *clk, unsigned long rate) --{ -- return -EIO; --} --EXPORT_SYMBOL(clk_set_rate); -diff --git a/arch/arm/mach-bcm2709/clock.h b/arch/arm/mach-bcm2709/clock.h -deleted file mode 100644 -index 5f9d725..0000000 ---- a/arch/arm/mach-bcm2709/clock.h -+++ /dev/null -@@ -1,24 +0,0 @@ --/* -- * linux/arch/arm/mach-bcm2708/clock.h -- * -- * Copyright (C) 2010 Broadcom -- * -- * 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 -- */ --struct module; -- --struct clk { -- unsigned long rate; --}; - -From 6ae9c7a93909159bde1a92fd305e99443e4ac680 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= -Date: Sun, 7 Jun 2015 20:42:52 +0200 -Subject: [PATCH 216/216] BCM270x: Remove bcm2708_systemtimer and - bcm2708_powerman -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -These devices do not have a matching driver. - -Signed-off-by: Noralf Trønnes ---- - arch/arm/mach-bcm2708/bcm2708.c | 50 -------------------------------------- - arch/arm/mach-bcm2709/bcm2709.c | 54 ----------------------------------------- - 2 files changed, 104 deletions(-) - + armctrl_pm_register(base, irq_start, resume_sources); diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c -index f1706366..00fc5d6 100644 +index cfc4f13..937c2d3 100644 --- a/arch/arm/mach-bcm2708/bcm2708.c +++ b/arch/arm/mach-bcm2708/bcm2708.c -@@ -465,33 +465,6 @@ static struct platform_device bcm2708_gpio_device = { +@@ -1028,7 +1028,7 @@ static irqreturn_t bcm2708_timer_interrupt(int irq, void *dev_id) + + static struct irqaction bcm2708_timer_irq = { + .name = "BCM2708 Timer Tick", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2708_timer_interrupt, }; - #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, -- } -- --}; -- --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), -- }, --}; -- - #ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ - static struct resource bcm2835_emmc_resources[] = { - [0] = { -@@ -520,27 +493,6 @@ struct platform_device bcm2835_emmc_device = { +diff --git a/arch/arm/mach-bcm2708/bcm2708_gpio.c b/arch/arm/mach-bcm2708/bcm2708_gpio.c +index c1e9254..e33265d 100644 +--- a/arch/arm/mach-bcm2708/bcm2708_gpio.c ++++ b/arch/arm/mach-bcm2708/bcm2708_gpio.c +@@ -306,7 +306,7 @@ static irqreturn_t bcm2708_gpio_interrupt(int irq, void *dev_id) + + static struct irqaction bcm2708_gpio_irq = { + .name = "BCM2708 GPIO catchall handler", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2708_gpio_interrupt, }; - #endif /* CONFIG_MMC_BCM2835 */ --static struct resource bcm2708_powerman_resources[] = { -- [0] = { -- .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}, --}; -- -- - static struct platform_device bcm2708_alsa_devices[] = { - [0] = { - .name = "bcm2835_AUD0", -@@ -938,10 +890,8 @@ void __init bcm2708_init(void) - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; - bcm_register_device_dt(&w1_device); - #endif -- bcm_register_device(&bcm2708_systemtimer_device); - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device); diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c -index ffa667e..a5cac5b 100644 +index c5e51e8..fe71c50 100644 --- a/arch/arm/mach-bcm2709/bcm2709.c +++ b/arch/arm/mach-bcm2709/bcm2709.c -@@ -485,35 +485,6 @@ static struct platform_device bcm2708_gpio_device = { +@@ -1050,7 +1050,7 @@ static irqreturn_t bcm2709_timer_interrupt(int irq, void *dev_id) + + static struct irqaction bcm2709_timer_irq = { + .name = "BCM2709 Timer Tick", +- .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .flags = IRQF_TIMER | IRQF_IRQPOLL, + .handler = bcm2709_timer_interrupt, }; - #endif --#ifdef SYSTEM_TIMER --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, -- } -- --}; -- --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), -- }, --}; --#endif -- - #ifdef CONFIG_MMC_BCM2835 /* Arasan emmc SD (new) */ - static struct resource bcm2835_emmc_resources[] = { - [0] = { -@@ -542,27 +513,6 @@ struct platform_device bcm2835_emmc_device = { - }; - #endif /* CONFIG_MMC_BCM2835 */ - --static struct resource bcm2708_powerman_resources[] = { -- [0] = { -- .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}, --}; -- -- - static struct platform_device bcm2708_alsa_devices[] = { - [0] = { - .name = "bcm2835_AUD0", -@@ -960,12 +910,8 @@ void __init bcm2709_init(void) - w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup; - bcm_register_device_dt(&w1_device); - #endif --#ifdef SYSTEM_TIMER -- bcm_register_device(&bcm2708_systemtimer_device); --#endif - bcm_register_device_dt(&bcm2708_fb_device); - bcm_register_device_dt(&bcm2708_usb_device); -- bcm_register_device(&bcm2708_powerman_device); - - #ifdef CONFIG_MMC_BCM2835 - bcm_register_device_dt(&bcm2835_emmc_device);