linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/32] arm64: Add platform selection for BCM2835.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:49   ` Florian Fainelli
  2016-06-01 21:43 ` [PATCH 02/32] arm64: Add BCM2835 support to the defconfig Gerd Hoffmann
                   ` (30 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Gerd Hoffmann, Florian Fainelli, Ray Jui,
	Scott Branden, Russell King, Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list

From: Eric Anholt <eric@anholt.net>

Signed-off-by: Eric Anholt <eric@anholt.net>

[ kraxel: copy some selects from arm to arm64 ]
[ kraxel: add CONFIG_ARCH_BCM, needed for some "depends on ARCH_BCM" ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm/mach-bcm/Kconfig    |  2 +-
 arch/arm64/Kconfig.platforms | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
index 68ab641..21f0e43 100644
--- a/arch/arm/mach-bcm/Kconfig
+++ b/arch/arm/mach-bcm/Kconfig
@@ -136,7 +136,7 @@ comment "Other Architectures"
 
 config ARCH_BCM2835
 	bool "Broadcom BCM2835 family"
-	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
+	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 || ARM64
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
 	select ARM_ERRATA_411920 if ARCH_MULTI_V6
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7ef1d05..32aba6b 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -13,8 +13,28 @@ config ARCH_ALPINE
 	  This enables support for the Annapurna Labs Alpine
 	  Soc family.
 
+config ARCH_BCM
+	bool "Broadcom SoC Support"
+	help
+	  This enables support for Broadcom ARM based SoC chips
+
+config ARCH_BCM2835
+	bool "Broadcom BCM2835 family"
+	depends on ARCH_BCM
+	select ARCH_REQUIRE_GPIOLIB
+	select CLKSRC_OF
+	select PINCTRL
+	select PINCTRL_BCM2835
+	select ARM_AMBA
+	select ARM_TIMER_SP804
+	select HAVE_ARM_ARCH_TIMER
+	help
+	  This enables support for the Broadcom BCM2837 SoC.
+	  This SoC is used in the Raspberry Pi 3 device.
+
 config ARCH_BCM_IPROC
 	bool "Broadcom iProc SoC Family"
+	depends on ARCH_BCM
 	select COMMON_CLK_IPROC
 	select PINCTRL
 	select ARCH_REQUIRE_GPIOLIB
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 02/32] arm64: Add BCM2835 support to the defconfig.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
  2016-06-01 21:43 ` [PATCH 01/32] arm64: Add platform selection for BCM2835 Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ Gerd Hoffmann
                   ` (29 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Gerd Hoffmann, Catalin Marinas, Will Deacon,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

From: Eric Anholt <eric@anholt.net>

Made with make defconfig; make menuconfig (only saying Y to new
entries); make savedefconfig.

Signed-off-by: Eric Anholt <eric@anholt.net>

[ kraxel: quick+dirty rebase to 4.7 ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/configs/defconfig | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fd2d74d..03f246a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -31,6 +31,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_ALPINE=y
+CONFIG_ARCH_BCM2835=y
 CONFIG_ARCH_BCM_IPROC=y
 CONFIG_ARCH_BERLIN=y
 CONFIG_ARCH_EXYNOS=y
@@ -140,6 +141,9 @@ CONFIG_USB_NET_PLUSB=m
 CONFIG_USB_NET_MCS7830=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC95XX=y
+# CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_SERIO_SERPORT is not set
@@ -147,6 +151,9 @@ CONFIG_SERIO_AMBAKMI=y
 CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_MT6577=y
 CONFIG_SERIAL_8250_UNIPHIER=y
@@ -173,6 +180,7 @@ CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_DESIGNWARE_PLATFORM=y
 CONFIG_I2C_IMX=y
+CONFIG_I2C_BCM2835=y
 CONFIG_I2C_MV64XXX=y
 CONFIG_I2C_QUP=y
 CONFIG_I2C_TEGRA=y
@@ -180,6 +188,8 @@ CONFIG_I2C_UNIPHIER_F=y
 CONFIG_I2C_RCAR=y
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
+CONFIG_SPI_BCM2835=y
+CONFIG_SPI_BCM2835AUX=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_QUP=y
 CONFIG_SPI_SPIDEV=m
@@ -206,20 +216,24 @@ CONFIG_MFD_SPMI_PMIC=y
 CONFIG_MFD_SEC_CORE=y
 CONFIG_MFD_HI655X_PMIC=y
 CONFIG_REGULATOR=y
+CONFIG_BCM2835_WDT=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_SEC_CORE=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_HI655X=y
 CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_REGULATOR_S2MPS11=y
-CONFIG_FB=y
+CONFIG_DRM=y
+CONFIG_DRM_VC4=y
 CONFIG_FB_ARMCLCD=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_SOUND=y
 CONFIG_SND=y
 CONFIG_SND_SOC=y
+CONFIG_SND_BCM2835_SOC_I2S=y
 CONFIG_SND_SOC_RCAR=y
 CONFIG_SND_SOC_AK4613=y
 CONFIG_USB=y
@@ -270,6 +284,7 @@ CONFIG_RTC_DRV_SUN6I=y
 CONFIG_RTC_DRV_XGENE=y
 CONFIG_DMADEVICES=y
 CONFIG_PL330_DMA=y
+CONFIG_DMA_BCM2835=y
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_QCOM_BAM_DMA=y
 CONFIG_RCAR_DMAC=y
@@ -289,7 +304,9 @@ CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_MAILBOX=y
 CONFIG_ARM_MHU=y
 CONFIG_HI6220_MBOX=y
+CONFIG_BCM2835_MBOX=y
 CONFIG_ARM_SMMU=y
+CONFIG_RASPBERRYPI_POWER=y
 CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD=y
 CONFIG_QCOM_SMD_RPM=y
@@ -302,6 +319,7 @@ CONFIG_PHY_HI6220_USB=y
 CONFIG_PHY_XGENE=y
 CONFIG_ARM_SCPI_PROTOCOL=y
 CONFIG_ACPI=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_FANOTIFY=y
@@ -311,7 +329,6 @@ CONFIG_AUTOFS4_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=y
 CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
  2016-06-01 21:43 ` [PATCH 01/32] arm64: Add platform selection for BCM2835 Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 02/32] arm64: Add BCM2835 support to the defconfig Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-02  0:50   ` Jason Cooper
  2016-06-01 21:43 ` [PATCH 04/32] dt-bindings: Add root properties for Raspberry Pi 3 Gerd Hoffmann
                   ` (28 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Stephen Warren, Lee Jones, open list:IRQCHIP DRIVERS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

From: Eric Anholt <eric@anholt.net>

This is equivalent and works for arm64 as well.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/irqchip/irq-bcm2835.c | 3 +--
 drivers/irqchip/irq-bcm2836.c | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c
index bf9cc5f..44d7c38 100644
--- a/drivers/irqchip/irq-bcm2835.c
+++ b/drivers/irqchip/irq-bcm2835.c
@@ -52,7 +52,6 @@
 #include <linux/irqdomain.h>
 
 #include <asm/exception.h>
-#include <asm/mach/irq.h>
 
 /* Put the bank and irq (32 bits) into the hwirq */
 #define MAKE_HWIRQ(b, n)	((b << 5) | (n))
@@ -242,7 +241,7 @@ static void __exception_irq_entry bcm2835_handle_irq(
 	u32 hwirq;
 
 	while ((hwirq = get_next_armctrl_hwirq()) != ~0)
-		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		handle_domain_irq(intc.domain, hwirq, regs);
 }
 
 static void bcm2836_chained_handle_irq(struct irq_desc *desc)
diff --git a/drivers/irqchip/irq-bcm2836.c b/drivers/irqchip/irq-bcm2836.c
index 72ff1d5..2787598 100644
--- a/drivers/irqchip/irq-bcm2836.c
+++ b/drivers/irqchip/irq-bcm2836.c
@@ -180,7 +180,7 @@ __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs)
 	} else if (stat) {
 		u32 hwirq = ffs(stat) - 1;
 
-		handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs);
+		handle_domain_irq(intc.domain, hwirq, regs);
 	}
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 04/32] dt-bindings: Add root properties for Raspberry Pi 3
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (2 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 05/32] ARM: bcm2835: Add devicetree for the " Gerd Hoffmann
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

From: Eric Anholt <eric@anholt.net>

Signed-off-by: Eric Anholt <eric@anholt.net>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
index 11d3056..6ffe087 100644
--- a/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
+++ b/Documentation/devicetree/bindings/arm/bcm/brcm,bcm2835.txt
@@ -30,6 +30,10 @@ Raspberry Pi 2 Model B
 Required root node properties:
 compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
 
+Raspberry Pi 3 Model B
+Required root node properties:
+compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
+
 Raspberry Pi Compute Module
 Required root node properties:
 compatible = "raspberrypi,compute-module", "brcm,bcm2835";
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 05/32] ARM: bcm2835: Add devicetree for the Raspberry Pi 3.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (3 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 04/32] dt-bindings: Add root properties for Raspberry Pi 3 Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 06/32] arm64: Fix physical to DMA mappings Gerd Hoffmann
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Gerd Hoffmann, Florian Fainelli, Ray Jui,
	Scott Branden, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

From: Eric Anholt <eric@anholt.net>

While this devicetree also works for booting in 32-bit mode, it's
placed in arm64 since it's a 64-bit CPU (as suggested by Arnd).

v2: Move to arm64/ instead of arm/

Signed-off-by: Eric Anholt <eric@anholt.net>
Acked-by: Stephen Warren <swarren@wwwdotorg.org> (v1)

[ kraxel: drop bcm2837-rpi-3-b.dtb from arm(32) Makefile ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/boot/dts/broadcom/Makefile            |  1 +
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 29 ++++++++++
 arch/arm64/boot/dts/broadcom/bcm2837.dtsi        | 74 ++++++++++++++++++++++++
 3 files changed, 104 insertions(+)
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837.dtsi

diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile
index bec1f8b..05faf2a 100644
--- a/arch/arm64/boot/dts/broadcom/Makefile
+++ b/arch/arm64/boot/dts/broadcom/Makefile
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb
 dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb
 dtb-$(CONFIG_ARCH_VULCAN) += vulcan-eval.dtb
 
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
new file mode 100644
index 0000000..223793d
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -0,0 +1,29 @@
+/dts-v1/;
+#include "bcm2837.dtsi"
+#include "../../../../arm/boot/dts/bcm2835-rpi.dtsi"
+
+/ {
+	compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
+	model = "Raspberry Pi 3 Model B";
+
+	memory {
+		reg = <0 0x40000000>;
+	};
+
+	leds {
+		act {
+			gpios = <&gpio 47 0>;
+		};
+
+		pwr {
+			label = "PWR";
+			gpios = <&gpio 35 0>;
+			default-state = "keep";
+			linux,default-trigger = "default-on";
+		};
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837.dtsi b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
new file mode 100644
index 0000000..2320f8d
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm2837.dtsi
@@ -0,0 +1,74 @@
+#include "../../../../arm/boot/dts/bcm283x.dtsi"
+
+/ {
+	compatible = "brcm,bcm2836";
+
+	soc {
+		ranges = <0x7e000000 0x3f000000 0x1000000>,
+			 <0x40000000 0x40000000 0x00001000>;
+		dma-ranges = <0xc0000000 0x00000000 0x3f000000>;
+
+		local_intc: local_intc {
+			compatible = "brcm,bcm2836-l1-intc";
+			reg = <0x40000000 0x100>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			interrupt-parent = <&local_intc>;
+		};
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&local_intc>;
+		interrupts = <0>, // PHYS_SECURE_PPI
+			     <1>, // PHYS_NONSECURE_PPI
+			     <3>, // VIRT_PPI
+			     <2>; // HYP_PPI
+		always-on;
+	};
+
+	cpus: cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <1>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x000000e0>;
+		};
+
+		cpu2: cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <2>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x000000e8>;
+		};
+
+		cpu3: cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <3>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x000000f0>;
+		};
+	};
+};
+
+/* Make the BCM2835-style global interrupt controller be a child of the
+ * CPU-local interrupt controller.
+ */
+&intc {
+	compatible = "brcm,bcm2836-armctrl-ic";
+	reg = <0x7e00b200 0x200>;
+	interrupt-parent = <&local_intc>;
+	interrupts = <8>;
+};
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 06/32] arm64: Fix physical to DMA mappings.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (4 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 05/32] ARM: bcm2835: Add devicetree for the " Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-02 17:20   ` Catalin Marinas
  2016-06-01 21:43 ` [PATCH 07/32] ARM: bcm2835: dt: Add the ethernet to the device trees Gerd Hoffmann
                   ` (25 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: mzoran, Gerd Hoffmann, Catalin Marinas, Will Deacon,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

From: mzoran <mzoran@crowfest.net>

Gets USB and networking to work on Raspberry Pi 3 in 64 bit.

created by mzoran@crowfest.net

[ kraxel: some cleanups ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/include/asm/dma-mapping.h | 73 ++++++++++++++++++++++++++++++++++--
 arch/arm64/include/asm/memory.h      |  8 ++++
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/dma-mapping.h b/arch/arm64/include/asm/dma-mapping.h
index 7dbea6c..48e8856 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -19,7 +19,11 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
-#include <linux/vmalloc.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-attrs.h>
+#include <linux/dma-debug.h>
+
+#include <asm/memory.h>
 
 #include <xen/xen.h>
 #include <asm/xen/hypervisor.h>
@@ -56,6 +60,54 @@ void arch_teardown_dma_ops(struct device *dev);
 #define arch_teardown_dma_ops	arch_teardown_dma_ops
 #endif
 
+/*
+ * dma_to_pfn/pfn_to_dma/dma_to_virt/virt_to_dma are architecture private
+ * functions used internally by the DMA-mapping API to provide DMA
+ * addresses. They must not be used by drivers.
+ */
+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;
+}
+
+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));
+}
+
+/* The ARM override for dma_max_pfn() */
+static inline unsigned long dma_max_pfn(struct device *dev)
+{
+	return PHYS_PFN_OFFSET + dma_to_pfn(dev, *dev->dma_mask);
+}
+#define dma_max_pfn(dev) dma_max_pfn(dev)
+
 /* do not use this function in a driver */
 static inline bool is_device_dma_coherent(struct device *dev)
 {
@@ -66,20 +118,33 @@ static inline bool is_device_dma_coherent(struct device *dev)
 
 static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
 {
-	return (dma_addr_t)paddr;
+	unsigned int offset = paddr & ~PAGE_MASK;
+	return pfn_to_dma(dev, __phys_to_pfn(paddr)) + offset;
 }
 
 static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
 {
-	return (phys_addr_t)dev_addr;
+	unsigned int offset = dev_addr & ~PAGE_MASK;
+	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
 }
 
 static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
 {
+	u64 limit, mask;
+
 	if (!dev->dma_mask)
 		return false;
 
-	return addr + size - 1 <= *dev->dma_mask;
+	mask = *dev->dma_mask;
+
+	limit = (mask + 1) & ~mask;
+	if (limit && size > limit)
+		return false;
+
+	if ((addr | (addr + size - 1)) & ~mask)
+		return false;
+
+	return true;
 }
 
 static inline void dma_mark_clean(void *addr, size_t size)
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 72a3025..ab4c65e 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -226,6 +226,14 @@ static inline void *phys_to_virt(phys_addr_t x)
 #endif
 #endif
 
+#ifndef __virt_to_bus
+#define __virt_to_bus	__virt_to_phys
+#define __bus_to_virt	__phys_to_virt
+#define __pfn_to_bus(x)	__pfn_to_phys(x)
+#define __bus_to_pfn(x)	__phys_to_pfn(x)
+#endif
+
+
 #include <asm-generic/memory_model.h>
 
 #endif
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 07/32] ARM: bcm2835: dt: Add the ethernet to the device trees
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (5 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 06/32] arm64: Fix physical to DMA mappings Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 08/32] ARM: bcm2837: " Gerd Hoffmann
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Lubomir Rintel, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Russell King, Stephen Warren,
	Lee Jones, Eric Anholt,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Lubomir Rintel <lkundrak@v3.sk>

The hub and the ethernet in its port 1 are hardwired on the board.

Compared to the adapters that can be plugged into the USB ports, this
one has no serial EEPROM to store its MAC. Nevertheless, the Raspberry Pi
has the MAC address for this adapter in its ROM, accessible from its
firmware.

U-Boot can read out the address and set the local-mac-address property of the
node with "ethernet" alias. Let's add the node so that U-Boot can do its
business.

Model B rev2 and Model B+ entries were verified by me, the hierarchy and
pid/vid pair for the Version 2 was provided by Peter Chen. Original
Model B is a blind shot, though very likely correct.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
---
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts    |  1 +
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts    |  1 +
 arch/arm/boot/dts/bcm2835-rpi-b.dts         |  1 +
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts       |  1 +
 arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi | 19 +++++++++++++++++++
 arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi | 19 +++++++++++++++++++
 arch/arm/boot/dts/bcm283x.dtsi              |  2 ++
 7 files changed, 44 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi

diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 57d313b..d5fdb8e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 #include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
+#include "bcm283x-rpi-smsc9514.dtsi"
 
 / {
 	compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index cf2774e..bfc4bd9 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 #include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
+#include "bcm283x-rpi-smsc9512.dtsi"
 
 / {
 	compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835";
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 8b15f9c..0371bb7 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 #include "bcm2835.dtsi"
 #include "bcm2835-rpi.dtsi"
+#include "bcm283x-rpi-smsc9512.dtsi"
 
 / {
 	compatible = "raspberrypi,model-b", "brcm,bcm2835";
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index c4743f4..29e1cfe 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 #include "bcm2836.dtsi"
 #include "bcm2835-rpi.dtsi"
+#include "bcm283x-rpi-smsc9514.dtsi"
 
 / {
 	compatible = "raspberrypi,2-model-b", "brcm,bcm2836";
diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi
new file mode 100644
index 0000000..12c981e
--- /dev/null
+++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9512.dtsi
@@ -0,0 +1,19 @@
+/ {
+	aliases {
+		ethernet = &ethernet;
+	};
+};
+
+&usb {
+	usb1@1 {
+		compatible = "usb424,9512";
+		reg = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethernet: usbether@1 {
+			compatible = "usb424,ec00";
+			reg = <1>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi b/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi
new file mode 100644
index 0000000..3f0a56e
--- /dev/null
+++ b/arch/arm/boot/dts/bcm283x-rpi-smsc9514.dtsi
@@ -0,0 +1,19 @@
+/ {
+	aliases {
+		ethernet = &ethernet;
+	};
+};
+
+&usb {
+	usb1@1 {
+		compatible = "usb424,9514";
+		reg = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethernet: usbether@1 {
+			compatible = "usb424,ec00";
+			reg = <1>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 10b27b9..b982522 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -287,6 +287,8 @@
 			compatible = "brcm,bcm2835-usb";
 			reg = <0x7e980000 0x10000>;
 			interrupts = <1 9>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 		};
 
 		v3d: v3d@7ec00000 {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 08/32] ARM: bcm2837: dt: Add the ethernet to the device trees
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (6 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 07/32] ARM: bcm2835: dt: Add the ethernet to the device trees Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm Gerd Hoffmann
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Gerd Hoffmann, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 223793d..6f47dd2 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -1,6 +1,7 @@
 /dts-v1/;
 #include "bcm2837.dtsi"
 #include "../../../../arm/boot/dts/bcm2835-rpi.dtsi"
+#include "../../../../arm/boot/dts/bcm283x-rpi-smsc9514.dtsi"
 
 / {
 	compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (7 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 08/32] ARM: bcm2837: " Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 22:00   ` Arnd Bergmann
  2016-06-01 21:43 ` [PATCH 10/32] don't force serial pins to uart0 Gerd Hoffmann
                   ` (22 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Gerd Hoffmann, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

---
 arch/arm/boot/dts/Makefile            | 3 ++-
 arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3-b.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 06b6c2d..16de98f 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -66,7 +66,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
 	bcm2835-rpi-b-rev2.dtb \
 	bcm2835-rpi-b-plus.dtb \
 	bcm2835-rpi-a-plus.dtb \
-	bcm2836-rpi-2-b.dtb
+	bcm2836-rpi-2-b.dtb \
+	bcm2837-rpi-3-b.dtb
 dtb-$(CONFIG_ARCH_BCM_5301X) += \
 	bcm4708-asus-rt-ac56u.dtb \
 	bcm4708-asus-rt-ac68u.dtb \
diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
new file mode 100644
index 0000000..36178a6
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
@@ -0,0 +1 @@
+#include "../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts"
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 10/32] don't force serial pins to uart0
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (8 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 22:19   ` Arnd Bergmann
  2016-06-01 21:43 ` [PATCH 11/32] ARM: bcm2835: Define standard pinctrl groups in the gpio node Gerd Hoffmann
                   ` (21 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index caf2707..88bcd0c 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -38,7 +38,7 @@
 	};
 
 	alt0: alt0 {
-		brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 14 15 40 45>;
+		brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 40 45>;
 		brcm,function = <BCM2835_FSEL_ALT0>;
 	};
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 11/32] ARM: bcm2835: Define standard pinctrl groups in the gpio node.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (9 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 10/32] don't force serial pins to uart0 Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 12/32] ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups Gerd Hoffmann
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

The BCM2835-ARM-Peripherals.pdf documentation specifies what the
function selects do for the pins, and there are a bunch of obvious
groupings to be made.  With these created, we'll be able to replace
bcm2835-rpi.dtsi's main "set all of these pins to alt0" with
references to specific groups we want enabled.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm283x.dtsi | 170 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index b982522..9aefb65 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -131,6 +131,176 @@
 
 			interrupt-controller;
 			#interrupt-cells = <2>;
+
+			/* Defines pin muxing groups according to
+			 * BCM2835-ARM-Peripherals.pdf page 102.
+			 *
+			 * While each pin can have its mux selected
+			 * for various functions individually, some
+			 * groups only make sense to switch to a
+			 * particular function together.
+			 */
+			i2c0_gpio0: i2c0_gpio0 {
+				brcm,pins = <0 1>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			i2c1_gpio2: i2c1_gpio2 {
+				brcm,pins = <2 3>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			gpclk0_gpio4: gpclk0_gpio4 {
+				brcm,pins = <4>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			gpclk1_gpio5: gpclk1_gpio5 {
+				brcm,pins = <5>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			gpclk2_gpio6: gpclk2_gpio6 {
+				brcm,pins = <6>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			spi0_gpio7: spi0_gpio7 {
+				brcm,pins = <7 8 9 10 11>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			pwm0_gpio12: pwm0_gpio12 {
+				brcm,pins = <12>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			pwm1_gpio13: pwm1_gpio13 {
+				brcm,pins = <13>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			uart0_gpio14: uart0_gpio14 {
+				brcm,pins = <14 15>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			pcm_gpio18: pcm_gpio18 {
+				brcm,pins = <18 19 20 21>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			i2c0_gpio32: i2c0_gpio32 {
+				brcm,pins = <32 34>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			spio0_gpio35: spio0_gpio35 {
+				brcm,pins = <35 36 37 38 39>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			pwm0_gpio40: pwm0_gpio40 {
+				brcm,pins = <40>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			pwm1_gpio41: pwm1_gpio41 {
+				brcm,pins = <41>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			gpclk1_gpio42: gpclk1_gpio42 {
+				brcm,pins = <42>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			gpclk2_gpio43: gpclk2_gpio43 {
+				brcm,pins = <43>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			gpclk1_gpio44: gpclk1_gpio44 {
+				brcm,pins = <44>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			pwm1_gpio45: pwm1_gpio45 {
+				brcm,pins = <45>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
+			i2c0_gpio44: i2c0_gpio44 {
+				brcm,pins = <44 45>;
+				brcm,function = <BCM2835_FSEL_ALT1>;
+			};
+			pcm_gpio28: pcm_gpio28 {
+				brcm,pins = <28 29 30 31>;
+				brcm,function = <BCM2835_FSEL_ALT2>;
+			};
+			uart1_gpio36: uart1_gpio36 {
+				brcm,pins = <36 37 38 39>;
+				brcm,function = <BCM2835_FSEL_ALT2>;
+			};
+			i2c1_gpio44: i2c1_gpio44 {
+				brcm,pins = <44 45>;
+				brcm,function = <BCM2835_FSEL_ALT2>;
+			};
+			/* Separate from the uart0_gpio14 group
+			 * because it conflicts with spi1_gpio16, and
+			 * people often run uart0 on the two pins
+			 * without flow contrl.
+			 */
+			uart0_ctsrts_gpio16: uart0_ctsrts_gpio16 {
+				brcm,pins = <16 17>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+			};
+			i2c_slave_gpio18: i2c_slave_gpio18 {
+				brcm,pins = <18 19 20 21>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+			};
+			emmc_gpio22: emmc_gpio22 {
+				brcm,pins = <22 23 24 25 26 27>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+			};
+			uart0_gpio30: uart0_gpio30 {
+				brcm,pins = <30 31>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+			};
+			uart0_ctsrts_gpio32: uart0_ctsrts_gpio32 {
+				brcm,pins = <32 33>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+			};
+			spi1_gpio16: spi1_gpio16 {
+				brcm,pins = <16 17 18 19 20 21>;
+				brcm,function = <BCM2835_FSEL_ALT4>;
+			};
+			jtag_gpio22: jtag_gpio22 {
+				brcm,pins = <22 23 24 25 26 27>;
+				brcm,function = <BCM2835_FSEL_ALT4>;
+			};
+			spi2_gpio40: spi2_gpio40 {
+				brcm,pins = <40 41 42 43 44 45>;
+				brcm,function = <BCM2835_FSEL_ALT4>;
+			};
+			jtag_gpio4: jtag_gpio4 {
+				brcm,pins = <4 5 6 12 13>;
+				brcm,function = <BCM2835_FSEL_ALT4>;
+			};
+			uart1_gpio14: uart1_gpio14 {
+				brcm,pins = <14 15>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			uart1_ctsrts_gpio16: uart1_ctsrts_gpio16 {
+				brcm,pins = <16 17>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			pwm0_gpio18: pwm0_gpio18 {
+				brcm,pins = <18>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			pwm1_gpio19: pwm1_gpio19 {
+				brcm,pins = <19>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			uart1_gpio30: uart1_gpio30 {
+				brcm,pins = <30 31>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			uart1_ctsrts_gpio32: uart1_ctsrts_gpio32 {
+				brcm,pins = <32 33>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			uart1_gpio40: uart1_gpio40 {
+				brcm,pins = <40 41>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
+			uart1_ctsrts_gpio42: uart1_ctsrts_gpio42 {
+				brcm,pins = <42 43>;
+				brcm,function = <BCM2835_FSEL_ALT5>;
+			};
 		};
 
 		uart0: serial@7e201000 {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 12/32] ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (10 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 11/32] ARM: bcm2835: Define standard pinctrl groups in the gpio node Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 13/32] bcm2837-rpi-3-b.dts: add gpio Gerd Hoffmann
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

Since all of these pins were documented, we can use their names to
explain what's going on.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 17 ++++++++++-------
 arch/arm/boot/dts/bcm2835-rpi-a.dts      | 17 ++++++++++-------
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 17 ++++++++++-------
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 17 ++++++++++-------
 arch/arm/boot/dts/bcm2835-rpi-b.dts      | 10 +++++++++-
 arch/arm/boot/dts/bcm2835-rpi.dtsi       |  5 -----
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts    | 17 ++++++++++-------
 7 files changed, 59 insertions(+), 41 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 35ff4e7a..e90f870 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -21,13 +21,16 @@
 };
 
 &gpio {
-	pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-	/* I2S interface */
-	i2s_alt0: i2s_alt0 {
-		brcm,pins = <18 19 20 21>;
-		brcm,function = <BCM2835_FSEL_ALT0>;
-	};
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pcm_gpio18
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 306a84e..2de38c3 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -14,13 +14,16 @@
 };
 
 &gpio {
-	pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
-	/* I2S interface */
-	i2s_alt2: i2s_alt2 {
-		brcm,pins = <28 29 30 31>;
-		brcm,function = <BCM2835_FSEL_ALT2>;
-	};
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pcm_gpio28
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index d5fdb8e..9ad3125 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -22,13 +22,16 @@
 };
 
 &gpio {
-	pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-	/* I2S interface */
-	i2s_alt0: i2s_alt0 {
-		brcm,pins = <18 19 20 21>;
-		brcm,function = <BCM2835_FSEL_ALT0>;
-	};
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pcm_gpio18
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index bfc4bd9..1bec67f 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -15,13 +15,16 @@
 };
 
 &gpio {
-	pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>;
-
-	/* I2S interface */
-	i2s_alt2: i2s_alt2 {
-		brcm,pins = <28 29 30 31>;
-		brcm,function = <BCM2835_FSEL_ALT2>;
-	};
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pcm_gpio28
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 0371bb7..0e9f566 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -15,7 +15,15 @@
 };
 
 &gpio {
-	pinctrl-0 = <&gpioout &alt0 &alt3>;
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 88bcd0c..e9ab80a 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -37,11 +37,6 @@
 		brcm,function = <BCM2835_FSEL_GPIO_OUT>;
 	};
 
-	alt0: alt0 {
-		brcm,pins = <0 1 2 3 4 5 7 8 9 10 11 40 45>;
-		brcm,function = <BCM2835_FSEL_ALT0>;
-	};
-
 	alt3: alt3 {
 		brcm,pins = <48 49 50 51 52 53>;
 		brcm,function = <BCM2835_FSEL_ALT3>;
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 29e1cfe..348e3e1 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -26,13 +26,16 @@
 };
 
 &gpio {
-	pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
-
-	/* I2S interface */
-	i2s_alt0: i2s_alt0 {
-		brcm,pins = <18 19 20 21>;
-		brcm,function = <BCM2835_FSEL_ALT0>;
-	};
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pcm_gpio18
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
 };
 
 &hdmi {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 13/32] bcm2837-rpi-3-b.dts: add gpio
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (11 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 12/32] ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 14/32] bcm2837-rpi-3-b.dts: vc4 hdmi fixup Gerd Hoffmann
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Gerd Hoffmann, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 6f47dd2..e0f429b 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -25,6 +25,19 @@
 	};
 };
 
+&gpio {
+	pinctrl-0 = <&i2c0_gpio0
+		     &i2c1_gpio2
+		     &gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &spi0_gpio7
+		     &pcm_gpio18
+		     &pwm0_gpio40
+		     &pwm1_gpio45
+		     &gpioout
+		     &alt3>;
+};
+
 &uart1 {
 	status = "okay";
 };
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 14/32] bcm2837-rpi-3-b.dts: vc4 hdmi fixup
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (12 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 13/32] bcm2837-rpi-3-b.dts: add gpio Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 15/32] ARM: bcm2835: Move the emmc pin group to bcm283x.dtsi Gerd Hoffmann
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Gerd Hoffmann, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index e0f429b..a523bd7 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -41,3 +41,7 @@
 &uart1 {
 	status = "okay";
 };
+
+&hdmi {
+	hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+};
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 15/32] ARM: bcm2835: Move the emmc pin group to bcm283x.dtsi.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (13 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 14/32] bcm2837-rpi-3-b.dts: vc4 hdmi fixup Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 16/32] bcm2837-rpi-3-b.dts: move the emmc pin group Gerd Hoffmann
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

While it's not documented in the public PDF, it is internally.  This
is a standard pin group for the 283x, not rpi-specific.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-a.dts      | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi-b.dts      | 4 ++--
 arch/arm/boot/dts/bcm2835-rpi.dtsi       | 5 -----
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts    | 4 ++--
 arch/arm/boot/dts/bcm283x.dtsi           | 4 ++++
 8 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index e90f870..5bd0bfe 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -29,8 +29,8 @@
 		     &pcm_gpio18
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index 2de38c3..ba1b0ac 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -22,8 +22,8 @@
 		     &pcm_gpio28
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 9ad3125..609a5e8 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -30,8 +30,8 @@
 		     &pcm_gpio18
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index 1bec67f..97de2d5 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -23,8 +23,8 @@
 		     &pcm_gpio28
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index 0e9f566..bc59f7e 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -22,8 +22,8 @@
 		     &spi0_gpio7
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index e9ab80a..7e65d16 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -36,11 +36,6 @@
 		brcm,pins = <6>;
 		brcm,function = <BCM2835_FSEL_GPIO_OUT>;
 	};
-
-	alt3: alt3 {
-		brcm,pins = <48 49 50 51 52 53>;
-		brcm,function = <BCM2835_FSEL_ALT3>;
-	};
 };
 
 &i2c0 {
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index 348e3e1..b4cbffe 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -34,8 +34,8 @@
 		     &pcm_gpio18
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 9aefb65..28ed77f 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -253,6 +253,10 @@
 				brcm,pins = <32 33>;
 				brcm,function = <BCM2835_FSEL_ALT3>;
 			};
+			emmc_gpio48: emmc_gpio48 {
+				brcm,pins = <48 49 50 51 52 53>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+			};
 			spi1_gpio16: spi1_gpio16 {
 				brcm,pins = <16 17 18 19 20 21>;
 				brcm,function = <BCM2835_FSEL_ALT4>;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 16/32] bcm2837-rpi-3-b.dts: move the emmc pin group
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (14 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 15/32] ARM: bcm2835: Move the emmc pin group to bcm283x.dtsi Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 17/32] ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost Gerd Hoffmann
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Gerd Hoffmann, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index a523bd7..8579df3 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -34,8 +34,8 @@
 		     &pcm_gpio18
 		     &pwm0_gpio40
 		     &pwm1_gpio45
-		     &gpioout
-		     &alt3>;
+		     &emmc_gpio48
+		     &gpioout>;
 };
 
 &uart1 {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 17/32] ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (15 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 16/32] bcm2837-rpi-3-b.dts: move the emmc pin group Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 18/32] ARM: bcm2835: Move most RPi default pin groups to their devices Gerd Hoffmann
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

This pin group definition comes from downstream.  We don't have a
driver for sdhost integrated yet, but they've been experimenting with
it and it sounds useful to bring over.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm283x.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 28ed77f..3866fc7a 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -212,6 +212,10 @@
 				brcm,pins = <45>;
 				brcm,function = <BCM2835_FSEL_ALT0>;
 			};
+			sdhost_gpio48: sdhost_gpio48 {
+				brcm,pins = <48 49 50 51 52 53>;
+				brcm,function = <BCM2835_FSEL_ALT0>;
+			};
 			i2c0_gpio44: i2c0_gpio44 {
 				brcm,pins = <44 45>;
 				brcm,function = <BCM2835_FSEL_ALT1>;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 18/32] ARM: bcm2835: Move most RPi default pin groups to their devices.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (16 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 17/32] ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 19/32] bcm2837-rpi-3-b.dts: move " Gerd Hoffmann
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

This way we can get the duplicated pin group definitions out of each
RPi board file, and just leave the i2s variations in them.

Signed-off-by: Eric Anholt <eric@anholt.net>

Conflicts:
	arch/arm/boot/dts/bcm2835-rpi-b.dts
	arch/arm/boot/dts/bcm2835-rpi.dtsi
---
 arch/arm/boot/dts/bcm2835-rpi-a-plus.dts | 14 +++-----------
 arch/arm/boot/dts/bcm2835-rpi-a.dts      | 14 +++-----------
 arch/arm/boot/dts/bcm2835-rpi-b-plus.dts | 14 +++-----------
 arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts | 14 +++-----------
 arch/arm/boot/dts/bcm2835-rpi-b.dts      | 12 ------------
 arch/arm/boot/dts/bcm2835-rpi.dtsi       | 20 ++++++++++++++++++++
 arch/arm/boot/dts/bcm2836-rpi-2-b.dts    | 14 +++-----------
 7 files changed, 35 insertions(+), 67 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
index 5bd0bfe..670ae70 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
@@ -20,17 +20,9 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pcm_gpio18
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_gpio18>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts
index ba1b0ac..e980637 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-a.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts
@@ -13,17 +13,9 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pcm_gpio28
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_gpio28>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
index 609a5e8..312d977 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
@@ -21,17 +21,9 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pcm_gpio18
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_gpio18>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
index 97de2d5..3d1d061 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
@@ -14,17 +14,9 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pcm_gpio28
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_gpio28>;
 };
 
 &hdmi {
diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts
index bc59f7e..0f96582 100644
--- a/arch/arm/boot/dts/bcm2835-rpi-b.dts
+++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts
@@ -14,18 +14,6 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
-};
-
 &hdmi {
 	hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
 };
diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index 7e65d16..a207693 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -31,6 +31,9 @@
 
 &gpio {
 	pinctrl-names = "default";
+	pinctrl-0 = <&gpclk0_gpio4
+		     &gpclk1_gpio5
+		     &gpioout>;
 
 	gpioout: gpioout {
 		brcm,pins = <6>;
@@ -39,11 +42,17 @@
 };
 
 &i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_gpio0>;
+
 	status = "okay";
 	clock-frequency = <100000>;
 };
 
 &i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_gpio2>;
+
 	status = "okay";
 	clock-frequency = <100000>;
 };
@@ -53,11 +62,17 @@
 };
 
 &sdhci {
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_gpio48>;
+
 	status = "okay";
 	bus-width = <4>;
 };
 
 &pwm {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio45>;
+
 	status = "okay";
 };
 
@@ -73,3 +88,8 @@
 	power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
 	status = "okay";
 };
+
+&spi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi0_gpio7>;
+};
diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
index b4cbffe..e6e1791 100644
--- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
+++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts
@@ -25,17 +25,9 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pcm_gpio18
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_gpio18>;
 };
 
 &hdmi {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 19/32] bcm2837-rpi-3-b.dts: move most RPi default pin groups to their devices
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (17 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 18/32] ARM: bcm2835: Move most RPi default pin groups to their devices Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 20/32] dt-bindings: Add binding for brcm,bcm2835-sdhost Gerd Hoffmann
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Gerd Hoffmann, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 8579df3..4636c16 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -25,17 +25,9 @@
 	};
 };
 
-&gpio {
-	pinctrl-0 = <&i2c0_gpio0
-		     &i2c1_gpio2
-		     &gpclk0_gpio4
-		     &gpclk1_gpio5
-		     &spi0_gpio7
-		     &pcm_gpio18
-		     &pwm0_gpio40
-		     &pwm1_gpio45
-		     &emmc_gpio48
-		     &gpioout>;
+&i2s {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcm_gpio18>;
 };
 
 &uart1 {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 20/32] dt-bindings: Add binding for brcm,bcm2835-sdhost.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (18 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 19/32] bcm2837-rpi-3-b.dts: move " Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-06 13:12   ` Rob Herring
  2016-06-01 21:43 ` [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller Gerd Hoffmann
                   ` (11 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

From: Eric Anholt <eric@anholt.net>

This is the other SD controller on the platform, which can be swapped
to the role of SD card host using pin muxing.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 .../devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt |  3 +++
 .../bindings/mmc/brcm,bcm2835-sdhost.txt           | 24 ++++++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt

diff --git a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt
index 59476fb..3cc74e2 100644
--- a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt
@@ -15,4 +15,7 @@ sdhci: sdhci {
 	interrupts = <2 30>;
 	clocks = <&clk_mmc>;
 	bus-width = <4>;
+	dmas = <&dma 13>,
+	       <&dma 13>;
+	dma-names = "tx", "rx";
 };
diff --git a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
new file mode 100644
index 0000000..074992c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
@@ -0,0 +1,24 @@
+Broadcom BCM2835 SDHOST controller
+
+This file documents differences between the core properties described
+by mmc.txt and the properties that represent the BCM2835 controller.
+
+Required properties:
+- compatible: Should be "brcm,bcm2835-sdhci".
+- clocks: The clock feeding the SDHOST controller.
+
+Optional properties:
+- dmas: DMA channels for read and write.
+          See Documentation/devicetree/bindings/dma/dma.txt for details
+
+Example:
+
+sdhost: sdhost@7e202000 {
+	compatible = "brcm,bcm2835-sdhost";
+	reg = <0x7e202000 0x100>;
+	interrupts = <2 24>;
+	clocks = <&clocks BCM2835_CLOCK_VPU>;
+	dmas = <&dma 13>,
+	       <&dma 13>;
+	dma-names = "tx", "rx";
+};
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (19 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 20/32] dt-bindings: Add binding for brcm,bcm2835-sdhost Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 22:18   ` Arnd Bergmann
  2016-06-01 21:43 ` [PATCH 22/32] ARM: bcm2835: Include SDHOST in the device tree Gerd Hoffmann
                   ` (10 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Ulf Hansson, Stephen Warren, Lee Jones, open list,
	open list:MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND...,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

From: Eric Anholt <eric@anholt.net>

The 2835 has two SD controllers: The Arasan SDHCI controller that we
currently use, and a custom SD controller.  The custom one runs faster

The code was originally written by Phil Elwell in the downstream
Rasbperry Pi tree, and I did a major cleanup on it (+319, -707 lines
out of the original 2055) for inclusion.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/mmc/host/Kconfig          |    9 +
 drivers/mmc/host/Makefile         |    1 +
 drivers/mmc/host/bcm2835-sdhost.c | 1666 +++++++++++++++++++++++++++++++++++++
 3 files changed, 1676 insertions(+)
 create mode 100644 drivers/mmc/host/bcm2835-sdhost.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 0aa484c..67efe28 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -779,6 +779,15 @@ config MMC_TOSHIBA_PCI
 	depends on PCI
 	help
 
+config MMC_BCM2835_SDHOST
+	tristate "platform support for the BCM2835 SDHOST MMC Controller"
+	depends on ARCH_BCM2835 || COMPILE_TEST
+	help
+	  This selects the BCM2835 SDHOST MMC controller. If you have a BCM2835
+	  platform with SD or MMC devices, say Y or M here.
+
+	  If unsure, say N.
+
 config MMC_MTK
 	tristate "MediaTek SD/MMC Card Interface support"
 	depends on HAS_DMA
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index af918d2..1e1b42b 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_MMC_MOXART)	+= moxart-mmc.o
 obj-$(CONFIG_MMC_SUNXI)		+= sunxi-mmc.o
 obj-$(CONFIG_MMC_USDHI6ROL0)	+= usdhi6rol0.o
 obj-$(CONFIG_MMC_TOSHIBA_PCI)	+= toshsd.o
+obj-$(CONFIG_MMC_BCM2835_SDHOST)	+= bcm2835-sdhost.o
 
 obj-$(CONFIG_MMC_REALTEK_PCI)	+= rtsx_pci_sdmmc.o
 obj-$(CONFIG_MMC_REALTEK_USB)	+= rtsx_usb_sdmmc.o
diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c
new file mode 100644
index 0000000..cafe6ad
--- /dev/null
+++ b/drivers/mmc/host/bcm2835-sdhost.c
@@ -0,0 +1,1666 @@
+/*
+ * BCM2835 SD host driver.
+ *
+ * Author:      Phil Elwell <phil@raspberrypi.org>
+ *              Copyright (C) 2015-2016 Raspberry Pi (Trading) Ltd.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sd.h>
+#include <linux/scatterlist.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/blkdev.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_dma.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+
+#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_CRC7_ERROR | \
+					 SDHSTS_CRC16_ERROR | \
+					 SDHSTS_REW_TIME_OUT | \
+					 SDHSTS_FIFO_ERROR)
+
+#define SDHSTS_ERROR_MASK               (SDHSTS_CMD_TIME_OUT | \
+					 SDHSTS_TRANSFER_ERROR_MASK)
+
+#define SDHCFG_BUSY_IRPT_EN     BIT(10)
+#define SDHCFG_BLOCK_IRPT_EN    BIT(8)
+#define SDHCFG_SDIO_IRPT_EN     BIT(5)
+#define SDHCFG_DATA_IRPT_EN     BIT(4)
+#define SDHCFG_SLOW_CARD        BIT(3)
+#define SDHCFG_WIDE_EXT_BUS     BIT(2)
+#define SDHCFG_WIDE_INT_BUS     BIT(1)
+#define SDHCFG_REL_CMD_LINE     BIT(0)
+
+#define SDEDM_FORCE_DATA_MODE   BIT(19)
+#define SDEDM_CLOCK_PULSE       BIT(20)
+#define SDEDM_BYPASS            BIT(21)
+
+#define SDEDM_WRITE_THRESHOLD_SHIFT 9
+#define SDEDM_READ_THRESHOLD_SHIFT 14
+#define SDEDM_THRESHOLD_MASK     0x1f
+
+#define SDEDM_FSM_MASK           0xf
+#define SDEDM_FSM_IDENTMODE      0x0
+#define SDEDM_FSM_DATAMODE       0x1
+#define SDEDM_FSM_READDATA       0x2
+#define SDEDM_FSM_WRITEDATA      0x3
+#define SDEDM_FSM_READWAIT       0x4
+#define SDEDM_FSM_READCRC        0x5
+#define SDEDM_FSM_WRITECRC       0x6
+#define SDEDM_FSM_WRITEWAIT1     0x7
+#define SDEDM_FSM_POWERDOWN      0x8
+#define SDEDM_FSM_POWERUP        0x9
+#define SDEDM_FSM_WRITESTART1    0xa
+#define SDEDM_FSM_WRITESTART2    0xb
+#define SDEDM_FSM_GENPULSES      0xc
+#define SDEDM_FSM_WRITEWAIT2     0xd
+#define SDEDM_FSM_STARTPOWDOWN   0xf
+
+#define SDDATA_FIFO_WORDS        16
+
+#define FIFO_READ_THRESHOLD     4
+#define FIFO_WRITE_THRESHOLD    4
+#define SDDATA_FIFO_PIO_BURST   8
+#define CMD_DALLY_US            1
+
+struct bcm2835_host {
+	spinlock_t		lock;
+
+	void __iomem		*ioaddr;
+	u32			phys_addr;
+
+	struct mmc_host		*mmc;
+
+	u32			pio_timeout;	/* In jiffies */
+
+	int			clock;		/* Current clock speed */
+
+	unsigned int		max_clk;	/* Max possible freq */
+
+	struct tasklet_struct	finish_tasklet;	/* Tasklet structures */
+
+	struct work_struct	cmd_wait_wq;	/* Workqueue function */
+
+	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 */
+
+	u32			cmd_quick_poll_retries;
+	u32			ns_per_fifo_word;
+
+	/* cached registers */
+	u32			hcfg;
+	u32			cdiv;
+
+	/* Current request */
+	struct mmc_request		*mrq;
+	/* Current command */
+	struct mmc_command		*cmd;
+	/* Current data request */
+	struct mmc_data			*data;
+	/* Data finished before cmd */
+	bool				data_complete:1;
+	/* Drain the fifo when finishing */
+	bool				flush_fifo:1;
+	/* Wait for busy interrupt */
+	bool				use_busy:1;
+	/* Send CMD23 */
+	bool				use_sbc:1;
+
+	/*DMA part*/
+	struct dma_chan			*dma_chan_rx;
+	struct dma_chan			*dma_chan_tx;
+	/* Channel in use */
+	struct dma_chan			*dma_chan;
+	struct dma_async_tx_descriptor	*dma_desc;
+	u32				dma_dir;
+	u32				drain_words;
+	struct page			*drain_page;
+	u32				drain_offset;
+
+	bool				use_dma;
+	/*end of DMA part*/
+	/* maximum length of time spent waiting */
+	int				max_delay;
+	/* Maximum block count for PIO (0 = always DMA) */
+	u32				pio_limit;
+};
+
+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_dumpcmd(struct bcm2835_host *host,
+				   struct mmc_command *cmd,
+				   const char *label)
+{
+	if (!cmd)
+		return;
+
+	pr_err("%s:%c%s op %d arg 0x%x flags 0x%x - resp %08x %08x %08x %08x, err %d\n",
+	       mmc_hostname(host->mmc),
+	       (cmd == host->cmd) ? '>' : ' ',
+	       label, cmd->opcode, cmd->arg, cmd->flags,
+	       cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3],
+	       cmd->error);
+}
+
+static void bcm2835_sdhost_dumpregs(struct bcm2835_host *host)
+{
+	if (host->mrq) {
+		bcm2835_sdhost_dumpcmd(host, host->mrq->sbc, "sbc");
+		bcm2835_sdhost_dumpcmd(host, host->mrq->cmd, "cmd");
+		if (host->mrq->data) {
+			pr_err("%s: data blocks %x blksz %x - err %d\n",
+			       mmc_hostname(host->mmc),
+			       host->mrq->data->blocks,
+			       host->mrq->data->blksz,
+			       host->mrq->data->error);
+		}
+		bcm2835_sdhost_dumpcmd(host, host->mrq->stop, "stop");
+	}
+
+	pr_err("%s: =========== REGISTER DUMP ===========\n",
+	       mmc_hostname(host->mmc));
+
+	pr_err("%s: SDCMD  0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDCMD));
+	pr_err("%s: SDARG  0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDARG));
+	pr_err("%s: SDTOUT 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDTOUT));
+	pr_err("%s: SDCDIV 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDCDIV));
+	pr_err("%s: SDRSP0 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDRSP0));
+	pr_err("%s: SDRSP1 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDRSP1));
+	pr_err("%s: SDRSP2 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDRSP2));
+	pr_err("%s: SDRSP3 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDRSP3));
+	pr_err("%s: SDHSTS 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDHSTS));
+	pr_err("%s: SDVDD  0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDVDD));
+	pr_err("%s: SDEDM  0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDEDM));
+	pr_err("%s: SDHCFG 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDHCFG));
+	pr_err("%s: SDHBCT 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDHBCT));
+	pr_err("%s: SDHBLC 0x%08x\n",
+	       mmc_hostname(host->mmc),
+	       bcm2835_sdhost_read(host, SDHBLC));
+
+	pr_err("%s: ===========================================\n",
+	       mmc_hostname(host->mmc));
+}
+
+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_internal(struct bcm2835_host *host)
+{
+	u32 temp;
+
+	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 << SDEDM_READ_THRESHOLD_SHIFT) |
+		  (SDEDM_THRESHOLD_MASK << SDEDM_WRITE_THRESHOLD_SHIFT));
+	temp |= (FIFO_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
+		(FIFO_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
+	bcm2835_sdhost_write(host, temp, SDEDM);
+	mdelay(10);
+	bcm2835_sdhost_set_power(host, true);
+	mdelay(10);
+	host->clock = 0;
+	bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
+	bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
+	mmiowb();
+}
+
+static void bcm2835_sdhost_reset(struct mmc_host *mmc)
+{
+	struct bcm2835_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	bcm2835_sdhost_reset_internal(host);
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+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_internal(host);
+
+	if (soft) {
+		/* force clock reconfiguration */
+		host->clock = 0;
+		bcm2835_sdhost_set_ios(host->mmc, &host->mmc->ios);
+	}
+}
+
+static void bcm2835_sdhost_wait_transfer_complete(struct bcm2835_host *host)
+{
+	int timediff;
+	u32 alternate_idle;
+	u32 edm;
+
+	alternate_idle = (host->mrq->data->flags & MMC_DATA_READ) ?
+		SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1;
+
+	edm = bcm2835_sdhost_read(host, SDEDM);
+
+	timediff = 0;
+
+	while (1) {
+		u32 fsm = edm & SDEDM_FSM_MASK;
+
+		if ((fsm == SDEDM_FSM_IDENTMODE) ||
+		    (fsm == SDEDM_FSM_DATAMODE))
+			break;
+		if (fsm == alternate_idle) {
+			bcm2835_sdhost_write(host,
+					     edm | SDEDM_FORCE_DATA_MODE,
+					     SDEDM);
+			break;
+		}
+
+		timediff++;
+		if (timediff == 100000) {
+			pr_err("%s: wait_transfer_complete - still waiting after %d retries\n",
+			       mmc_hostname(host->mmc),
+			       timediff);
+			bcm2835_sdhost_dumpregs(host);
+			host->mrq->data->error = -ETIMEDOUT;
+			return;
+		}
+		cpu_relax();
+		edm = bcm2835_sdhost_read(host, SDEDM);
+	}
+}
+
+static void bcm2835_sdhost_finish_data(struct bcm2835_host *host);
+
+static void bcm2835_sdhost_dma_complete(void *param)
+{
+	struct bcm2835_host *host = param;
+	struct mmc_data *data = host->data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->dma_chan) {
+		dma_unmap_sg(host->dma_chan->device->dev,
+			     data->sg, data->sg_len,
+			     host->dma_dir);
+
+		host->dma_chan = NULL;
+	}
+
+	if (host->drain_words) {
+		void *page;
+		u32 *buf;
+
+		page = kmap_atomic(host->drain_page);
+		buf = page + host->drain_offset;
+
+		while (host->drain_words) {
+			u32 edm = bcm2835_sdhost_read(host, SDEDM);
+
+			if ((edm >> 4) & 0x1f)
+				*(buf++) = bcm2835_sdhost_read(host,
+							       SDDATA);
+			host->drain_words--;
+		}
+
+		kunmap_atomic(page);
+	}
+
+	bcm2835_sdhost_finish_data(host);
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void bcm2835_sdhost_transfer_block_pio(struct bcm2835_host *host,
+					      bool is_read)
+{
+	unsigned long flags;
+	size_t blksize, len;
+	u32 *buf;
+	unsigned long wait_max;
+
+	blksize = host->data->blksz;
+
+	wait_max = jiffies + msecs_to_jiffies(host->pio_timeout);
+
+	local_irq_save(flags);
+
+	while (blksize) {
+		int copy_words;
+		u32 hsts = 0;
+
+		if (!sg_miter_next(&host->sg_miter)) {
+			host->data->error = -EINVAL;
+			break;
+		}
+
+		len = min(host->sg_miter.length, blksize);
+		if (len % 4) {
+			host->data->error = -EINVAL;
+			break;
+		}
+
+		blksize -= len;
+		host->sg_miter.consumed = len;
+
+		buf = (u32 *)host->sg_miter.addr;
+
+		copy_words = len / 4;
+
+		while (copy_words) {
+			int burst_words, words;
+			u32 edm;
+
+			burst_words = SDDATA_FIFO_PIO_BURST;
+			if (burst_words > copy_words)
+				burst_words = copy_words;
+			edm = bcm2835_sdhost_read(host, SDEDM);
+			if (is_read)
+				words = ((edm >> 4) & 0x1f);
+			else
+				words = SDDATA_FIFO_WORDS - ((edm >> 4) & 0x1f);
+
+			if (words < burst_words) {
+				int fsm_state = (edm & SDEDM_FSM_MASK);
+
+				if ((is_read &&
+				     (fsm_state != SDEDM_FSM_READDATA &&
+				      fsm_state != SDEDM_FSM_READWAIT &&
+				      fsm_state != SDEDM_FSM_READCRC)) ||
+				    (!is_read &&
+				     (fsm_state != SDEDM_FSM_WRITEDATA &&
+				      fsm_state != SDEDM_FSM_WRITESTART1 &&
+				      fsm_state != SDEDM_FSM_WRITESTART2))) {
+					hsts = bcm2835_sdhost_read(host,
+								   SDHSTS);
+					pr_err("%s: fsm %x, hsts %x\n",
+					       mmc_hostname(host->mmc),
+					       fsm_state, hsts);
+					if (hsts & SDHSTS_ERROR_MASK)
+						break;
+				}
+
+				if (time_after(jiffies, wait_max)) {
+					pr_err("%s: PIO %s timeout - EDM %x\n",
+					       is_read ? "read" : "write",
+					       mmc_hostname(host->mmc),
+					       edm);
+					hsts = SDHSTS_REW_TIME_OUT;
+					break;
+				}
+				ndelay((burst_words - words) *
+				       host->ns_per_fifo_word);
+				continue;
+			} else if (words > copy_words) {
+				words = copy_words;
+			}
+
+			copy_words -= words;
+
+			while (words) {
+				if (is_read) {
+					*(buf++) = bcm2835_sdhost_read(host,
+								       SDDATA);
+				} else {
+					bcm2835_sdhost_write(host, *(buf++),
+							     SDDATA);
+				}
+				words--;
+			}
+		}
+
+		if (hsts & SDHSTS_ERROR_MASK)
+			break;
+	}
+
+	sg_miter_stop(&host->sg_miter);
+
+	local_irq_restore(flags);
+}
+
+static void bcm2835_sdhost_transfer_pio(struct bcm2835_host *host)
+{
+	u32 sdhsts;
+	bool is_read;
+
+	is_read = (host->data->flags & MMC_DATA_READ) != 0;
+	bcm2835_sdhost_transfer_block_pio(host, is_read);
+
+	sdhsts = bcm2835_sdhost_read(host, SDHSTS);
+	if (sdhsts & (SDHSTS_CRC16_ERROR |
+		      SDHSTS_CRC7_ERROR |
+		      SDHSTS_FIFO_ERROR)) {
+		pr_err("%s: %s transfer error - HSTS %x\n",
+		       mmc_hostname(host->mmc),
+		       is_read ? "read" : "write",
+		       sdhsts);
+		host->data->error = -EILSEQ;
+	} else if ((sdhsts & (SDHSTS_CMD_TIME_OUT |
+			      SDHSTS_REW_TIME_OUT))) {
+		pr_err("%s: %s timeout error - HSTS %x\n",
+		       mmc_hostname(host->mmc),
+		       is_read ? "read" : "write",
+		       sdhsts);
+		host->data->error = -ETIMEDOUT;
+	}
+}
+
+static void bcm2835_sdhost_prepare_dma(struct bcm2835_host *host,
+				       struct mmc_data *data)
+{
+	int len, dir_data, dir_slave;
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct dma_chan *dma_chan;
+
+	pr_debug("bcm2835_sdhost_prepare_dma()\n");
+
+	if (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;
+	}
+
+	/* The block doesn't manage the FIFO DREQs properly for
+	 * multi-block transfers, so don't attempt to DMA the final
+	 * few words.  Unfortunately this requires the final sg entry
+	 * to be trimmed.  N.B. This code demands that the overspill
+	 * is contained in a single sg entry.
+	 */
+
+	host->drain_words = 0;
+	if ((data->blocks > 1) && (dir_data == DMA_FROM_DEVICE)) {
+		struct scatterlist *sg;
+		u32 len;
+		int i;
+
+		len = min((u32)(FIFO_READ_THRESHOLD - 1) * 4,
+			  (u32)data->blocks * data->blksz);
+
+		for_each_sg(data->sg, sg, data->sg_len, i) {
+			if (sg_is_last(sg)) {
+				WARN_ON(sg->length < len);
+				sg->length -= len;
+				host->drain_page = (struct page *)sg->page_link;
+				host->drain_offset = sg->offset + sg->length;
+			}
+		}
+		host->drain_words = len / 4;
+	}
+
+	len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
+			 dir_data);
+
+	if (len > 0) {
+		desc = dmaengine_prep_slave_sg(dma_chan, data->sg,
+					       len, dir_slave,
+					       DMA_PREP_INTERRUPT |
+					       DMA_CTRL_ACK);
+	}
+
+	if (desc) {
+		desc->callback = bcm2835_sdhost_dma_complete;
+		desc->callback_param = host;
+		host->dma_desc = desc;
+		host->dma_chan = dma_chan;
+		host->dma_dir = dir_data;
+	}
+}
+
+static void bcm2835_sdhost_start_dma(struct bcm2835_host *host)
+{
+	dmaengine_submit(host->dma_desc);
+	dma_async_issue_pending(host->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->dma_desc) {
+		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);
+
+	host->data = data;
+	if (!data)
+		return;
+
+	/* Sanity checks */
+	WARN_ON(data->blksz * data->blocks > 524288);
+	WARN_ON(data->blksz > host->mmc->max_blk_size);
+	WARN_ON(data->blocks > 65535);
+
+	host->data_complete = false;
+	host->flush_fifo = false;
+	host->data->bytes_xfered = 0;
+
+	if (!host->dma_desc) {
+		/* Use PIO */
+		int 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;
+	}
+
+	bcm2835_sdhost_set_transfer_irqs(host);
+
+	bcm2835_sdhost_write(host, data->blksz, SDHBCT);
+	bcm2835_sdhost_write(host, data->blocks, SDHBLC);
+}
+
+bool bcm2835_sdhost_send_command(struct bcm2835_host *host,
+				 struct mmc_command *cmd)
+{
+	u32 sdcmd, sdhsts;
+	unsigned long timeout;
+	int delay;
+
+	WARN_ON(host->cmd);
+
+	if (cmd->data) {
+		pr_debug("%s: send_command %d 0x%x (flags 0x%x) - %s %d*%d\n",
+			 mmc_hostname(host->mmc),
+			 cmd->opcode, cmd->arg, cmd->flags,
+			 (cmd->data->flags & MMC_DATA_READ) ?
+			 "read" : "write", cmd->data->blocks,
+			 cmd->data->blksz);
+	} else {
+		pr_debug("%s: send_command %d 0x%x (flags 0x%x)\n",
+			 mmc_hostname(host->mmc),
+			 cmd->opcode, cmd->arg, cmd->flags);
+	}
+
+	/* Wait max 100 ms */
+	timeout = 10000;
+
+	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 = -EILSEQ;
+			tasklet_schedule(&host->finish_tasklet);
+			return false;
+		}
+		timeout--;
+		udelay(10);
+	}
+
+	delay = (10000 - timeout) / 100;
+	if (delay > host->max_delay) {
+		host->max_delay = delay;
+		pr_warn("%s: controller hung for %d ms\n",
+			mmc_hostname(host->mmc),
+			host->max_delay);
+	}
+
+	timeout = jiffies;
+	if (!cmd->data && cmd->busy_timeout > 9000)
+		timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ;
+	else
+		timeout += 10 * HZ;
+	mod_timer(&host->timer, timeout);
+
+	host->cmd = cmd;
+
+	/* Clear any error flags */
+	sdhsts = bcm2835_sdhost_read(host, SDHSTS);
+	if (sdhsts & SDHSTS_ERROR_MASK)
+		bcm2835_sdhost_write(host, sdhsts, SDHSTS);
+
+	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 false;
+	}
+
+	bcm2835_sdhost_prepare_data(host, cmd);
+
+	bcm2835_sdhost_write(host, cmd->arg, SDARG);
+
+	sdcmd = cmd->opcode & SDCMD_CMD_MASK;
+
+	host->use_busy = false;
+	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 = true;
+		}
+	}
+
+	if (cmd->data) {
+		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);
+
+	return true;
+}
+
+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host,
+					  unsigned long *irq_flags);
+
+static void bcm2835_sdhost_transfer_complete(struct bcm2835_host *host)
+{
+	struct mmc_data *data;
+
+	WARN_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);
+
+	/* Need to send CMD12 if -
+	 * a) open-ended multiblock transfer (no CMD23)
+	 * b) error in multiblock transfer
+	 */
+	if (host->mrq->stop && (data->error || !host->use_sbc)) {
+		if (bcm2835_sdhost_send_command(host, host->mrq->stop)) {
+			/* No busy, so poll for completion */
+			if (!host->use_busy)
+				bcm2835_sdhost_finish_command(host, NULL);
+		}
+	} else {
+		bcm2835_sdhost_wait_transfer_complete(host);
+		tasklet_schedule(&host->finish_tasklet);
+	}
+}
+
+static void bcm2835_sdhost_finish_data(struct bcm2835_host *host)
+{
+	struct mmc_data *data;
+
+	data = host->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);
+
+	data->bytes_xfered = data->error ? 0 : (data->blksz * data->blocks);
+
+	host->data_complete = true;
+
+	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);
+	}
+}
+
+/* If irq_flags is valid, the caller is in a thread context and is
+ * allowed to sleep
+ */
+static void bcm2835_sdhost_finish_command(struct bcm2835_host *host,
+					  unsigned long *irq_flags)
+{
+	u32 sdcmd;
+	u32 retries;
+
+	pr_debug("finish_command(%x)\n", bcm2835_sdhost_read(host, SDCMD));
+
+	/* Poll quickly at first */
+
+	retries = host->cmd_quick_poll_retries;
+	if (!retries) {
+		/* Work out how many polls take 1us by timing 10us */
+		struct timeval start, now;
+		int us_diff;
+
+		retries = 1;
+		do {
+			int i;
+
+			retries *= 2;
+
+			do_gettimeofday(&start);
+
+			for (i = 0; i < retries; i++) {
+				cpu_relax();
+				sdcmd = bcm2835_sdhost_read(host, SDCMD);
+			}
+
+			do_gettimeofday(&now);
+			us_diff = (now.tv_sec - start.tv_sec) * 1000000 +
+				(now.tv_usec - start.tv_usec);
+		} while (us_diff < 10);
+
+		host->cmd_quick_poll_retries =
+			((retries * us_diff + 9) * CMD_DALLY_US) / 10 + 1;
+		retries = 1; /* We've already waited long enough this time */
+	}
+
+	retries = host->cmd_quick_poll_retries;
+	for (sdcmd = bcm2835_sdhost_read(host, SDCMD);
+	     (sdcmd & SDCMD_NEW_FLAG) && !(sdcmd & SDCMD_FAIL_FLAG) && retries;
+	     retries--) {
+		cpu_relax();
+		sdcmd = bcm2835_sdhost_read(host, SDCMD);
+	}
+
+	if (!retries) {
+		unsigned long wait_max;
+
+		if (!irq_flags) {
+			/* Schedule the work */
+			schedule_work(&host->cmd_wait_wq);
+			return;
+		}
+
+		/* Wait max 100 ms */
+		wait_max = jiffies + msecs_to_jiffies(100);
+		while (time_before(jiffies, wait_max)) {
+			spin_unlock_irqrestore(&host->lock, *irq_flags);
+			usleep_range(1, 10);
+			spin_lock_irqsave(&host->lock, *irq_flags);
+			sdcmd = bcm2835_sdhost_read(host, SDCMD);
+			if (!(sdcmd & SDCMD_NEW_FLAG) ||
+			    (sdcmd & SDCMD_FAIL_FLAG))
+				break;
+		}
+	}
+
+	/* Check for errors */
+	if (sdcmd & SDCMD_NEW_FLAG) {
+		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;
+	} else if (sdcmd & SDCMD_FAIL_FLAG) {
+		u32 sdhsts = bcm2835_sdhost_read(host, SDHSTS);
+
+		/* Clear the errors */
+		bcm2835_sdhost_write(host, SDHSTS_ERROR_MASK, SDHSTS);
+
+		if (!(sdhsts & SDHSTS_CRC7_ERROR) ||
+		    (host->cmd->opcode != 1)) {
+			if (sdhsts & SDHSTS_CMD_TIME_OUT) {
+				host->cmd->error = -ETIMEDOUT;
+			} else {
+				pr_err("%s: unexpected command %d error\n",
+				       mmc_hostname(host->mmc),
+				       host->cmd->opcode);
+				bcm2835_sdhost_dumpregs(host);
+				host->cmd->error = -EILSEQ;
+			}
+			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("%s: finish_command %08x %08x %08x %08x\n",
+				 mmc_hostname(host->mmc),
+				 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("%s: finish_command %08x\n",
+				 mmc_hostname(host->mmc),
+				 host->cmd->resp[0]);
+		}
+	}
+
+	if (host->cmd == host->mrq->sbc) {
+		/* Finished CMD23, now send actual command. */
+		host->cmd = NULL;
+		if (bcm2835_sdhost_send_command(host, host->mrq->cmd)) {
+			if (host->data && host->dma_desc)
+				/* DMA transfer starts now, PIO starts
+				 * after irq
+				 */
+				bcm2835_sdhost_start_dma(host);
+
+			if (!host->use_busy)
+				bcm2835_sdhost_finish_command(host, NULL);
+		}
+	} 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(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_busy_irq(struct bcm2835_host *host, u32 intmask)
+{
+	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;
+	}
+
+	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;
+	}
+	host->use_busy = false;
+
+	if (intmask & SDHSTS_ERROR_MASK) {
+		pr_err("sdhost_busy_irq: intmask %x, data %p\n",
+		       intmask, host->mrq->data);
+		if (intmask & SDHSTS_CRC7_ERROR) {
+			host->cmd->error = -EILSEQ;
+		} else if (intmask & (SDHSTS_CRC16_ERROR |
+				    SDHSTS_FIFO_ERROR)) {
+			if (host->mrq->data)
+				host->mrq->data->error = -EILSEQ;
+			else
+				host->cmd->error = -EILSEQ;
+		} else if (intmask & SDHSTS_REW_TIME_OUT) {
+			if (host->mrq->data)
+				host->mrq->data->error = -ETIMEDOUT;
+			else
+				host->cmd->error = -ETIMEDOUT;
+		} else if (intmask & SDHSTS_CMD_TIME_OUT) {
+			host->cmd->error = -ETIMEDOUT;
+		}
+
+		bcm2835_sdhost_dumpregs(host);
+	} else {
+		bcm2835_sdhost_finish_command(host, NULL);
+	}
+}
+
+static void bcm2835_sdhost_data_irq(struct bcm2835_host *host, u32 intmask)
+{
+	/* 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;
+
+	if (intmask & (SDHSTS_CRC16_ERROR |
+		       SDHSTS_FIFO_ERROR |
+		       SDHSTS_REW_TIME_OUT)) {
+		if (intmask & (SDHSTS_CRC16_ERROR |
+			       SDHSTS_FIFO_ERROR))
+			host->data->error = -EILSEQ;
+		else
+			host->data->error = -ETIMEDOUT;
+	}
+
+	if (host->data->error) {
+		bcm2835_sdhost_finish_data(host);
+	} else if (host->data->flags & MMC_DATA_WRITE) {
+		/* Use the block interrupt for writes after the first block */
+		host->hcfg &= ~(SDHCFG_DATA_IRPT_EN);
+		host->hcfg |= SDHCFG_BLOCK_IRPT_EN;
+		bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
+		bcm2835_sdhost_transfer_pio(host);
+	} else {
+		bcm2835_sdhost_transfer_pio(host);
+		host->blocks--;
+		if ((host->blocks == 0) || host->data->error)
+			bcm2835_sdhost_finish_data(host);
+	}
+}
+
+static void bcm2835_sdhost_block_irq(struct bcm2835_host *host, u32 intmask)
+{
+	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;
+	}
+
+	if (intmask & (SDHSTS_CRC16_ERROR |
+		       SDHSTS_FIFO_ERROR |
+		       SDHSTS_REW_TIME_OUT)) {
+		if (intmask & (SDHSTS_CRC16_ERROR |
+			       SDHSTS_FIFO_ERROR))
+			host->data->error = -EILSEQ;
+		else
+			host->data->error = -ETIMEDOUT;
+	}
+
+	if (!host->dma_desc) {
+		WARN_ON(!host->blocks);
+		if (host->data->error || (--host->blocks == 0))
+			bcm2835_sdhost_finish_data(host);
+		else
+			bcm2835_sdhost_transfer_pio(host);
+	} else if (host->data->flags & MMC_DATA_WRITE) {
+		bcm2835_sdhost_finish_data(host);
+	}
+}
+
+static irqreturn_t bcm2835_sdhost_irq(int irq, void *dev_id)
+{
+	irqreturn_t result = IRQ_NONE;
+	struct bcm2835_host *host = dev_id;
+	u32 intmask;
+
+	spin_lock(&host->lock);
+
+	intmask = bcm2835_sdhost_read(host, SDHSTS);
+
+	bcm2835_sdhost_write(host,
+			     SDHSTS_BUSY_IRPT |
+			     SDHSTS_BLOCK_IRPT |
+			     SDHSTS_SDIO_IRPT |
+			     SDHSTS_DATA_FLAG,
+			     SDHSTS);
+
+	if (intmask & SDHSTS_BLOCK_IRPT) {
+		bcm2835_sdhost_block_irq(host, intmask);
+		result = IRQ_HANDLED;
+	}
+
+	if (intmask & SDHSTS_BUSY_IRPT) {
+		bcm2835_sdhost_busy_irq(host, intmask);
+		result = IRQ_HANDLED;
+	}
+
+	/* 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)) {
+		bcm2835_sdhost_data_irq(host, intmask);
+		result = IRQ_HANDLED;
+	}
+
+	mmiowb();
+
+	spin_unlock(&host->lock);
+
+	return result;
+}
+
+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;
+
+	clock = host->max_clk / (div + 2);
+	host->mmc->actual_clock = clock;
+
+	/* Calibrate some delays */
+
+	host->ns_per_fifo_word = (1000000000 / clock) *
+		((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32);
+
+	host->cdiv = div;
+	bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
+
+	/* Set the timeout to 500ms */
+	bcm2835_sdhost_write(host, host->mmc->actual_clock / 2, SDTOUT);
+}
+
+static void bcm2835_sdhost_request(struct mmc_host *mmc,
+				   struct mmc_request *mrq)
+{
+	struct bcm2835_host *host;
+	unsigned long flags;
+	u32 edm, fsm;
+
+	host = mmc_priv(mmc);
+
+	/* Reset the error statuses in case this is a retry */
+	if (mrq->sbc)
+		mrq->sbc->error = 0;
+	if (mrq->cmd)
+		mrq->cmd->error = 0;
+	if (mrq->data)
+		mrq->data->error = 0;
+	if (mrq->stop)
+		mrq->stop->error = 0;
+
+	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;
+	}
+
+	if (host->use_dma && mrq->data &&
+	    (mrq->data->blocks > host->pio_limit))
+		bcm2835_sdhost_prepare_dma(host, mrq->data);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	WARN_ON(host->mrq);
+	host->mrq = mrq;
+
+	edm = bcm2835_sdhost_read(host, SDEDM);
+	fsm = edm & SDEDM_FSM_MASK;
+
+	if ((fsm != SDEDM_FSM_IDENTMODE) &&
+	    (fsm != SDEDM_FSM_DATAMODE)) {
+		pr_err("%s: previous command (%d) not complete (EDM %x)\n",
+		       mmc_hostname(host->mmc),
+		       bcm2835_sdhost_read(host, SDCMD) & SDCMD_CMD_MASK,
+		       edm);
+		bcm2835_sdhost_dumpregs(host);
+		mrq->cmd->error = -EILSEQ;
+		tasklet_schedule(&host->finish_tasklet);
+		mmiowb();
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+
+	host->use_sbc = !!mrq->sbc && (host->mrq->data->flags & MMC_DATA_READ);
+	if (host->use_sbc) {
+		if (bcm2835_sdhost_send_command(host, mrq->sbc)) {
+			if (!host->use_busy)
+				bcm2835_sdhost_finish_command(host, &flags);
+		}
+	} else if (bcm2835_sdhost_send_command(host, mrq->cmd)) {
+		if (host->data && host->dma_desc) {
+			/* DMA transfer starts now, PIO starts after irq */
+			bcm2835_sdhost_start_dma(host);
+		}
+
+		if (!host->use_busy)
+			bcm2835_sdhost_finish_command(host, &flags);
+	}
+
+	mmiowb();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct bcm2835_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	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 struct mmc_host_ops bcm2835_sdhost_ops = {
+	.request = bcm2835_sdhost_request,
+	.set_ios = bcm2835_sdhost_set_ios,
+	.hw_reset = bcm2835_sdhost_reset,
+};
+
+static void bcm2835_sdhost_cmd_wait_work(struct work_struct *work)
+{
+	struct bcm2835_host *host;
+	unsigned long flags;
+
+	host = container_of(work, struct bcm2835_host, cmd_wait_wq);
+
+	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;
+	}
+
+	bcm2835_sdhost_finish_command(host, &flags);
+
+	mmiowb();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void bcm2835_sdhost_tasklet_finish(unsigned long param)
+{
+	struct bcm2835_host *host;
+	unsigned long flags;
+	struct mmc_request *mrq;
+	struct dma_chan *terminate_chan = NULL;
+
+	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;
+
+	host->mrq = NULL;
+	host->cmd = NULL;
+	host->data = NULL;
+
+	mmiowb();
+
+	host->dma_desc = NULL;
+	terminate_chan = host->dma_chan;
+	host->dma_chan = NULL;
+
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (terminate_chan) {
+		int err = dmaengine_terminate_all(terminate_chan);
+
+		if (err)
+			pr_err("%s: failed to terminate DMA (%d)\n",
+			       mmc_hostname(host->mmc), err);
+	}
+
+	mmc_request_done(host->mmc, mrq);
+}
+
+int bcm2835_sdhost_add_host(struct bcm2835_host *host)
+{
+	struct mmc_host *mmc;
+	struct dma_slave_config cfg;
+	char pio_limit_string[20];
+	int ret;
+
+	mmc = host->mmc;
+
+	bcm2835_sdhost_reset_internal(host);
+
+	mmc->f_max = host->max_clk;
+	mmc->f_min = host->max_clk / SDCDIV_MAX_CDIV;
+
+	mmc->max_busy_timeout = ~0 / (mmc->f_max / 1000);
+
+	pr_debug("f_max %d, f_min %d, max_busy_timeout %d\n",
+		 mmc->f_max, mmc->f_min, mmc->max_busy_timeout);
+
+	/* host controller capabilities */
+	mmc->caps |=
+		MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
+		MMC_CAP_NEEDS_POLL | MMC_CAP_HW_RESET | MMC_CAP_ERASE |
+		MMC_CAP_CMD23;
+
+	spin_lock_init(&host->lock);
+
+	if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
+	    IS_ERR_OR_NULL(host->dma_chan_rx)) {
+		pr_err("%s: unable to initialise DMA channels. Falling back to PIO\n",
+		       mmc_hostname(mmc));
+		host->use_dma = false;
+	} else {
+		host->use_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);
+		if (ret)
+			host->use_dma = false;
+
+		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);
+		if (ret)
+			host->use_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);
+
+	INIT_WORK(&host->cmd_wait_wq, bcm2835_sdhost_cmd_wait_work);
+
+	setup_timer(&host->timer, bcm2835_sdhost_timeout,
+		    (unsigned long)host);
+
+	bcm2835_sdhost_init(host, 0);
+
+	ret = request_irq(host->irq, bcm2835_sdhost_irq, 0 /*IRQF_SHARED*/,
+			  mmc_hostname(mmc), host);
+	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);
+
+	pio_limit_string[0] = '\0';
+	if (host->use_dma && (host->pio_limit > 0))
+		sprintf(pio_limit_string, " (>%d)", host->pio_limit);
+	pr_info("%s: loaded - DMA %s%s\n",
+		mmc_hostname(mmc),
+		host->use_dma ? "enabled" : "disabled",
+		pio_limit_string);
+
+	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 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->cmd_quick_poll_retries = 0;
+	host->pio_timeout = msecs_to_jiffies(500);
+	host->pio_limit = 1;
+	host->max_delay = 1; /* Warn if over 1ms */
+	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;
+	}
+
+	/* Parse OF address directly to get the physical address for
+	 * DMA to our registers.
+	 */
+	host->phys_addr = be32_to_cpup(of_get_address(pdev->dev.of_node, 0,
+						      NULL, NULL));
+
+	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->dma_chan = NULL;
+	host->dma_desc = NULL;
+
+	host->dma_chan_tx = dma_request_slave_channel(dev, "tx");
+	host->dma_chan_rx = dma_request_slave_channel(dev, "rx");
+
+	clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "could not get clk: %d\n", ret);
+		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);
+
+	mmc_of_parse(mmc);
+
+	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		= "sdhost-bcm2835",
+		.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");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 22/32] ARM: bcm2835: Include SDHOST in the device tree.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (20 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 23/32] ARM: bcm2835: Enable SDHOST by default Gerd Hoffmann
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

It's disabled by default, and will be enabled by a particular board's
DT.  The DMA channels are also currently left out, because our DMA
engine support doesn't yet include slave SG, and there doesn't appear
to be a clean way to include "does slave SG" in the channel
request/config process.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm283x.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 3866fc7a..170d620 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -399,6 +399,14 @@
 			status = "disabled";
 		};
 
+		sdhost: sdhost@7e202000 {
+			compatible = "brcm,bcm2835-sdhost";
+			reg = <0x7e202000 0x100>;
+			interrupts = <2 24>;
+			clocks = <&clocks BCM2835_CLOCK_VPU>;
+			status = "disabled";
+		};
+
 		pwm: pwm@7e20c000 {
 			compatible = "brcm,bcm2835-pwm";
 			reg = <0x7e20c000 0x28>;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 23/32] ARM: bcm2835: Enable SDHOST by default.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (21 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 22/32] ARM: bcm2835: Include SDHOST in the device tree Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 24/32] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock Gerd Hoffmann
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

This improves read speed on my SD card (as reported by hdparm -t) from
10.15MB/sec to 16.70MB/sec.  Once we add slave DMA, we can get to
18.45MB/sec.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm2835-rpi.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi
index a207693..97496cd 100644
--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
+++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
@@ -65,8 +65,16 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_gpio48>;
 
+	bus-width = <4>;
+};
+
+&sdhost {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdhost_gpio48>;
+
+	bus-width = <4>;
+
 	status = "okay";
-	bus-width = <4>;
 };
 
 &pwm {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 24/32] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (22 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 23/32] ARM: bcm2835: Enable SDHOST by default Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-07-22  7:26   ` Wolfram Sang
  2016-06-01 21:43 ` [PATCH 25/32] dt-gpio-fix Gerd Hoffmann
                   ` (7 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Wolfram Sang, Stephen Warren, Lee Jones,
	open list:I2C SUBSYSTEM,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

From: Eric Anholt <eric@anholt.net>

Fixes dmesg spam when we just need to wait a moment for the clock
driver to probe.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/i2c/busses/i2c-bcm2835.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index 818b051..d4f3239 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -253,7 +253,8 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 
 	i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(i2c_dev->clk)) {
-		dev_err(&pdev->dev, "Could not get clock\n");
+		if (PTR_ERR(i2c_dev->clk) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Could not get clock\n");
 		return PTR_ERR(i2c_dev->clk);
 	}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 25/32] dt-gpio-fix
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (23 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 24/32] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 26/32] enable uart1 on the BT pins Gerd Hoffmann
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

---
 arch/arm/boot/dts/bcm283x.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 170d620..30e6f46 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -293,12 +293,12 @@
 				brcm,pins = <19>;
 				brcm,function = <BCM2835_FSEL_ALT5>;
 			};
-			uart1_gpio30: uart1_gpio30 {
-				brcm,pins = <30 31>;
+			uart1_gpio32: uart1_gpio32 {
+				brcm,pins = <32 33>;
 				brcm,function = <BCM2835_FSEL_ALT5>;
 			};
-			uart1_ctsrts_gpio32: uart1_ctsrts_gpio32 {
-				brcm,pins = <32 33>;
+			uart1_ctsrts_gpio30: uart1_ctsrts_gpio30 {
+				brcm,pins = <30 31>;
 				brcm,function = <BCM2835_FSEL_ALT5>;
 			};
 			uart1_gpio40: uart1_gpio40 {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 26/32] enable uart1 on the BT pins
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (24 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 25/32] dt-gpio-fix Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander Gerd Hoffmann
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

From: Eric Anholt <eric@anholt.net>

---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 4636c16..099dd48d 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -31,6 +31,8 @@
 };
 
 &uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_gpio32>;
 	status = "okay";
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (25 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 26/32] enable uart1 on the BT pins Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-06 23:50   ` Eric Anholt
                     ` (2 more replies)
  2016-06-01 21:43 ` [PATCH 28/32] i2c: bcm2835: Set up the rising/falling edge delays Gerd Hoffmann
                   ` (4 subsequent siblings)
  31 siblings, 3 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon, Linus Walleij, Alexandre Courbot,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list, open list:GPIO SUBSYSTEM

From: Eric Anholt <eric@anholt.net>

This commit needs to be split up and cleaned up.  Also we should add
interrupt support before pushing upstream.

Signed-off-by: Eric Anholt <eric@anholt.net>

Conflicts:
	arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts |  16 ++
 drivers/gpio/Kconfig                             |   6 +
 drivers/gpio/Makefile                            |   1 +
 drivers/gpio/gpio-fxl6408.c                      | 244 +++++++++++++++++++++++
 4 files changed, 267 insertions(+)
 create mode 100644 drivers/gpio/gpio-fxl6408.c

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 099dd48d..4bc191e 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -39,3 +39,19 @@
 &hdmi {
 	hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
 };
+
+/* Connect the GPIO expander to I2C1 */
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_gpio44>;
+
+	gpio_expander: gpio@43 {
+		gpio-controller;
+		#gpio-cells = <2>;
+		reg = <0x43>;
+		compatible = "fcs,fxl6408";
+	};
+};
+
+bt {
+};
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 48da857..34056cd 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -665,6 +665,12 @@ config GPIO_ADNP
 	  enough to represent all pins, but the driver will assume a
 	  register layout for 64 pins (8 registers).
 
+config GPIO_FXL6408
+	tristate "FXL6408 I2C GPIO expander"
+	help
+	  This option enables support for 8 GPIOs found
+	  on the Fairchild Semiconductor FXL6408.
+
 config GPIO_MAX7300
 	tristate "Maxim MAX7300 GPIO expander"
 	select GPIO_MAX730X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..59a25ef 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_GPIO_EM)		+= gpio-em.o
 obj-$(CONFIG_GPIO_EP93XX)	+= gpio-ep93xx.o
 obj-$(CONFIG_GPIO_ETRAXFS)	+= gpio-etraxfs.o
 obj-$(CONFIG_GPIO_F7188X)	+= gpio-f7188x.o
+obj-$(CONFIG_GPIO_FXL6408)	+= gpio-fxl6408.o
 obj-$(CONFIG_GPIO_GE_FPGA)	+= gpio-ge.o
 obj-$(CONFIG_GPIO_GRGPIO)	+= gpio-grgpio.o
 obj-$(CONFIG_GPIO_ICH)		+= gpio-ich.o
diff --git a/drivers/gpio/gpio-fxl6408.c b/drivers/gpio/gpio-fxl6408.c
new file mode 100644
index 0000000..02b2816
--- /dev/null
+++ b/drivers/gpio/gpio-fxl6408.c
@@ -0,0 +1,244 @@
+/*
+ *  Copyright (C) 2016 Broadcom Limited.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ */
+
+/**
+ * DOC: FXL6408 I2C to GPIO expander.
+ *
+ * This chip has has 8 GPIO lines out of it, and is controlled by an
+ * I2C bus (a pair of lines), providing 4x expansion of GPIO lines.
+ * It also provides an interrupt line out for notifying of
+ * statechanges.
+ *
+ * Any preconfigured state will be left in place until the GPIO lines
+ * get activated.  At power on, everything is treated as an input.
+ *
+ * Documentation can be found at:
+ * https://www.fairchildsemi.com/datasheets/FX/FXL6408.pdf
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/of_platform.h>
+
+#define FXL6408_DEVICE_ID		0x01
+# define FXL6408_RST_INT		BIT(1)
+# define FXL6408_SW_RST			BIT(0)
+
+/* Bits set here indicate that the GPIO is an output. */
+#define FXL6408_IO_DIR			0x03
+/* Bits set here, when the corresponding bit of IO_DIR is set, drive
+ * the output high instead of low.
+ */
+#define FXL6408_OUTPUT			0x05
+/* Bits here make the output High-Z, instead of the OUTPUT value. */
+#define FXL6408_OUTPUT_HIGH_Z		0x07
+/* Bits here define the expected input state of the GPIO.
+ * INTERRUPT_STAT bits will be set when the INPUT transitions away
+ * from this value.
+ */
+#define FXL6408_INPUT_DEFAULT_STATE	0x09
+/* Bits here enable either pull up or pull down according to
+ * FXL6408_PULL_DOWN.
+ */
+#define FXL6408_PULL_ENABLE		0x0b
+/* Bits set here (when the corresponding PULL_ENABLE is set) enable a
+ * pull-up instead of a pull-down.
+ */
+#define FXL6408_PULL_UP			0x0d
+/* Returns the current status (1 = HIGH) of the input pins. */
+#define FXL6408_INPUT_STATUS		0x0f
+/* Mask of pins which can generate interrupts. */
+#define FXL6408_INTERRUPT_MASK		0x11
+/* Mask of pins which have generated an interrupt.  Cleared on read. */
+#define FXL6408_INTERRUPT_STAT		0x13
+
+struct fxl6408_chip {
+	struct gpio_chip gpio_chip;
+	struct i2c_client *client;
+	struct mutex i2c_lock;
+
+	/* Caches of register values so we don't have to read-modify-write. */
+	u8 reg_io_dir;
+	u8 reg_output;
+};
+
+static int fxl6408_gpio_direction_input(struct gpio_chip *gc, unsigned off)
+{
+	struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+	mutex_lock(&chip->i2c_lock);
+	chip->reg_io_dir &= ~BIT(off);
+	i2c_smbus_write_byte_data(chip->client, FXL6408_IO_DIR,
+				  chip->reg_io_dir);
+	mutex_unlock(&chip->i2c_lock);
+
+	return 0;
+}
+
+static int fxl6408_gpio_direction_output(struct gpio_chip *gc,
+		unsigned off, int val)
+{
+	struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+	mutex_lock(&chip->i2c_lock);
+	chip->reg_io_dir |= BIT(off);
+	i2c_smbus_write_byte_data(chip->client, FXL6408_IO_DIR,
+				  chip->reg_io_dir);
+	mutex_unlock(&chip->i2c_lock);
+
+	return 0;
+}
+
+static int fxl6408_gpio_get_direction(struct gpio_chip *gc, unsigned off)
+{
+	struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+	return (chip->reg_io_dir & BIT(off)) == 0;
+}
+
+static int fxl6408_gpio_get_value(struct gpio_chip *gc, unsigned off)
+{
+	struct fxl6408_chip *chip = gpiochip_get_data(gc);
+	u8 reg;
+
+	mutex_lock(&chip->i2c_lock);
+	reg = i2c_smbus_read_byte_data(chip->client, FXL6408_INPUT_STATUS);
+	mutex_unlock(&chip->i2c_lock);
+
+	return (reg & BIT(off)) != 0;
+}
+
+static void fxl6408_gpio_set_value(struct gpio_chip *gc, unsigned off, int val)
+{
+	struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+	mutex_lock(&chip->i2c_lock);
+
+	if (val)
+		chip->reg_output |= BIT(off);
+	else
+		chip->reg_output &= BIT(off);
+
+	i2c_smbus_write_byte_data(chip->client, FXL6408_OUTPUT,
+				  chip->reg_output);
+	mutex_unlock(&chip->i2c_lock);
+}
+
+
+static void fxl6408_gpio_set_multiple(struct gpio_chip *gc,
+		unsigned long *mask, unsigned long *bits)
+{
+	struct fxl6408_chip *chip = gpiochip_get_data(gc);
+
+	mutex_lock(&chip->i2c_lock);
+	chip->reg_output = (chip->reg_output & ~mask[0]) | bits[0];
+	i2c_smbus_write_byte_data(chip->client, FXL6408_OUTPUT,
+				  chip->reg_output);
+	mutex_unlock(&chip->i2c_lock);
+}
+
+static int fxl6408_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct fxl6408_chip *chip;
+	struct gpio_chip *gc;
+	int ret;
+	u8 device_id;
+
+	/* Check the device ID register to see if it's responding.
+	 * This also clears RST_INT as a side effect, so we won't get
+	 * the "we've been power cycled" interrupt once we enable
+	 * interrupts.
+	 */
+	device_id = i2c_smbus_read_byte_data(client, FXL6408_DEVICE_ID);
+	if (device_id < 0) {
+		dev_err(dev, "FXL6408 probe returned %d\n", device_id);
+		return device_id;
+	} else if (device_id >> 5 != 5) {
+		dev_err(dev, "FXL6408 probe returned DID: 0x%02x\n", device_id);
+		return -ENODEV;
+	}
+
+	/* Disable High-Z of outputs, so that our OUTPUT updates
+	 * actually take effect.
+	 */
+	i2c_smbus_write_byte_data(client, FXL6408_OUTPUT_HIGH_Z, 0);
+
+	chip = devm_kzalloc(dev, sizeof(struct fxl6408_chip), GFP_KERNEL);
+	if (chip == NULL)
+		return -ENOMEM;
+
+	chip->client = client;
+	mutex_init(&chip->i2c_lock);
+	chip->reg_io_dir = i2c_smbus_read_byte_data(client, FXL6408_IO_DIR);
+	chip->reg_output = i2c_smbus_read_byte_data(client, FXL6408_OUTPUT);
+
+	gc = &chip->gpio_chip;
+	gc->direction_input  = fxl6408_gpio_direction_input;
+	gc->direction_output = fxl6408_gpio_direction_output;
+	gc->get_direction = fxl6408_gpio_get_direction;
+	gc->get = fxl6408_gpio_get_value;
+	gc->set = fxl6408_gpio_set_value;
+	gc->set_multiple = fxl6408_gpio_set_multiple;
+	gc->can_sleep = true;
+
+	gc->base =-1;
+	gc->ngpio = 8;
+	gc->label = chip->client->name;
+	gc->parent = dev;
+	gc->owner = THIS_MODULE;
+
+	ret = gpiochip_add_data(gc, chip);
+	if (ret)
+		return ret;
+
+	i2c_set_clientdata(client, chip);
+	return 0;
+}
+
+static int fxl6408_remove(struct i2c_client *client)
+{
+	struct fxl6408_chip *chip = i2c_get_clientdata(client);
+
+	gpiochip_remove(&chip->gpio_chip);
+
+	return 0;
+}
+
+static const struct of_device_id fxl6408_dt_ids[] = {
+	{ .compatible = "fcs,fxl6408" },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, fxl6408_dt_ids);
+
+static const struct i2c_device_id fxl6408_id[] = {
+	{ "fxl6408", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, fxl6408_id);
+
+static struct i2c_driver fxl6408_driver = {
+	.driver = {
+		.name	= "fxl6408",
+		.of_match_table = fxl6408_dt_ids,
+	},
+	.probe		= fxl6408_probe,
+	.remove		= fxl6408_remove,
+	.id_table	= fxl6408_id,
+};
+
+module_i2c_driver(fxl6408_driver);
+
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("GPIO expander driver for FXL6408");
+MODULE_LICENSE("GPL");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 28/32] i2c: bcm2835: Set up the rising/falling edge delays.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (26 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-07-22  7:26   ` Wolfram Sang
  2016-06-01 21:43 ` [PATCH 29/32] ARM: bcm2835: Use i2c-gpio for the expander, instead Gerd Hoffmann
                   ` (3 subsequent siblings)
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Wolfram Sang, Stephen Warren, Lee Jones,
	open list:I2C SUBSYSTEM,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

From: Eric Anholt <eric@anholt.net>

We were leaving them in the power on state (or the state the firmware
had set up for some client, if we were taking over from them).  The
boot state was 30 core clocks, when we actually want to sample some
time after (to make sure that the new input bit has actually arrived).

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 drivers/i2c/busses/i2c-bcm2835.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index d4f3239..d1d17e4 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -50,6 +50,9 @@
 #define BCM2835_I2C_S_CLKT	BIT(9)
 #define BCM2835_I2C_S_LEN	BIT(10) /* Fake bit for SW error reporting */
 
+#define BCM2835_I2C_FEDL_SHIFT	16
+#define BCM2835_I2C_REDL_SHIFT	0
+
 #define BCM2835_I2C_BITMSK_S	0x03FF
 
 #define BCM2835_I2C_CDIV_MIN	0x0002
@@ -235,7 +238,7 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 {
 	struct bcm2835_i2c_dev *i2c_dev;
 	struct resource *mem, *irq;
-	u32 bus_clk_rate, divider;
+	u32 bus_clk_rate, divider, redl, fedl;
 	int ret;
 	struct i2c_adapter *adap;
 
@@ -281,6 +284,20 @@ static int bcm2835_i2c_probe(struct platform_device *pdev)
 	}
 	bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
 
+	/* Number of core clocks to wait after falling edge before
+	 * outputting the next data bit.  Note that both FEDL and REDL
+	 * can't be greater than CDIV/2.
+	 */
+	fedl = max(divider / 16, 1u);
+	/* Number of core clocks to wait after rising edge before
+	 * sampling the next incoming data bit.
+	 */
+	redl = max(divider / 4, 1u);
+
+	bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DEL,
+			   (fedl << BCM2835_I2C_FEDL_SHIFT) |
+			   (redl << BCM2835_I2C_REDL_SHIFT));
+
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!irq) {
 		dev_err(&pdev->dev, "No IRQ resource\n");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 29/32] ARM: bcm2835: Use i2c-gpio for the expander, instead.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (27 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 28/32] i2c: bcm2835: Set up the rising/falling edge delays Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 30/32] ARM: bcm2835: Add a new EMMC pin group from the downstream tree Gerd Hoffmann
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

From: Eric Anholt <eric@anholt.net>

I'm seeing a ton of CLKT errors from i2c-bcm2835.c, and haven't
figured out a cause.

Signed-off-by: Eric Anholt <eric@anholt.net>

Conflicts:
	arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 32 ++++++++++++------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 4bc191e..202e8c3 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -23,6 +23,22 @@
 			linux,default-trigger = "default-on";
 		};
 	};
+
+	i2c_gpio {
+		compatible = "i2c-gpio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		gpios = <&gpio 44 0
+			 &gpio 45 0>;
+
+		gpio_expander: gpio@43 {
+			gpio-controller;
+			#gpio-cells = <2>;
+			reg = <0x43>;
+			compatible = "fcs,fxl6408";
+		};
+	};
 };
 
 &i2s {
@@ -39,19 +55,3 @@
 &hdmi {
 	hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
 };
-
-/* Connect the GPIO expander to I2C1 */
-&i2c0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2c0_gpio44>;
-
-	gpio_expander: gpio@43 {
-		gpio-controller;
-		#gpio-cells = <2>;
-		reg = <0x43>;
-		compatible = "fcs,fxl6408";
-	};
-};
-
-bt {
-};
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 30/32] ARM: bcm2835: Add a new EMMC pin group from the downstream tree.
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (28 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 29/32] ARM: bcm2835: Use i2c-gpio for the expander, instead Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 31/32] enable wireless Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it Gerd Hoffmann
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

From: Eric Anholt <eric@anholt.net>

This will be used for having EMMC (sdhci-bcm2835.c) drive the
wireless.

Signed-off-by: Eric Anholt <eric@anholt.net>
---
 arch/arm/boot/dts/bcm283x.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 30e6f46..f186ef9 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -257,6 +257,11 @@
 				brcm,pins = <32 33>;
 				brcm,function = <BCM2835_FSEL_ALT3>;
 			};
+			emmc_gpio34: emmc_gpio34 {
+				brcm,pins = <34 35 36 37 38 39>;
+				brcm,function = <BCM2835_FSEL_ALT3>;
+				brcm,pull = <0 2 2 2 2 2>;
+			};
 			emmc_gpio48: emmc_gpio48 {
 				brcm,pins = <48 49 50 51 52 53>;
 				brcm,function = <BCM2835_FSEL_ALT3>;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 31/32] enable wireless
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (29 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 30/32] ARM: bcm2835: Add a new EMMC pin group from the downstream tree Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-01 21:43 ` [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it Gerd Hoffmann
  31 siblings, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list

From: Eric Anholt <eric@anholt.net>

Signed-off-by: Eric Anholt <eric@anholt.net>

Conflicts:
	arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
---
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
index 202e8c3..8d24a39 100644
--- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
@@ -55,3 +55,18 @@
 &hdmi {
 	hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
 };
+
+/* SDHOST is used to drive the SD card */
+&sdhost {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdhost_gpio48>;
+	status = "okay";
+};
+
+/* SDHCI is used to control the SDIO for wireless */
+&sdhci {
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_gpio34>;
+	status = "okay";
+	non-removable;
+};
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it
       [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
                   ` (30 preceding siblings ...)
  2016-06-01 21:43 ` [PATCH 31/32] enable wireless Gerd Hoffmann
@ 2016-06-01 21:43 ` Gerd Hoffmann
  2016-06-02 16:52   ` Stefan Wahren
  31 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-01 21:43 UTC (permalink / raw)
  To: linux-rpi-kernel
  Cc: Eric Anholt, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Russell King, Ulf Hansson, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list,
	open list:MULTIMEDIA CARD (MMC), SECURE DIGITAL (SD) AND...

From: Eric Anholt <eric@anholt.net>

With this we can get wifi (brcmfmac) to probe.  Without it we're stuck
with timeouts from sdio.c when it tries to set the bus width to 4.
---
 arch/arm/boot/dts/bcm283x.dtsi |    2 +-
 drivers/mmc/host/Makefile      |    1 +
 drivers/mmc/host/bcm2835-mmc.c | 1559 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1561 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mmc/host/bcm2835-mmc.c

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index f186ef9..2d8ca87 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -423,7 +423,7 @@
 		};
 
 		sdhci: sdhci@7e300000 {
-			compatible = "brcm,bcm2835-sdhci";
+			compatible = "brcm,bcm2835-mmc";
 			reg = <0x7e300000 0x100>;
 			interrupts = <2 30>;
 			clocks = <&clocks BCM2835_CLOCK_EMMC>;
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 1e1b42b..3e666d0 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_MMC_SUNXI)		+= sunxi-mmc.o
 obj-$(CONFIG_MMC_USDHI6ROL0)	+= usdhi6rol0.o
 obj-$(CONFIG_MMC_TOSHIBA_PCI)	+= toshsd.o
 obj-$(CONFIG_MMC_BCM2835_SDHOST)	+= bcm2835-sdhost.o
+obj-$(CONFIG_MMC_BCM2835_SDHOST)	+= bcm2835-mmc.o
 
 obj-$(CONFIG_MMC_REALTEK_PCI)	+= rtsx_pci_sdmmc.o
 obj-$(CONFIG_MMC_REALTEK_USB)	+= rtsx_usb_sdmmc.o
diff --git a/drivers/mmc/host/bcm2835-mmc.c b/drivers/mmc/host/bcm2835-mmc.c
new file mode 100644
index 0000000..db6617d
--- /dev/null
+++ b/drivers/mmc/host/bcm2835-mmc.c
@@ -0,0 +1,1559 @@
+/*
+ * BCM2835 MMC host driver.
+ *
+ * Author:      Gellert Weisz <gellert@raspberrypi.org>
+ *              Copyright 2014
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sd.h>
+#include <linux/scatterlist.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/blkdev.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_dma.h>
+
+#include "sdhci.h"
+
+
+#define DRIVER_NAME "mmc-bcm2835"
+
+#define DBG(f, x...) \
+pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x)
+
+#ifndef CONFIG_MMC_BCM2835_DMA
+ #define FORCE_PIO
+#endif
+
+
+/* the inclusive limit in bytes under which PIO will be used instead of DMA */
+#ifdef CONFIG_MMC_BCM2835_PIO_DMA_BARRIER
+#define PIO_DMA_BARRIER CONFIG_MMC_BCM2835_PIO_DMA_BARRIER
+#else
+#define PIO_DMA_BARRIER 00
+#endif
+
+#define MIN_FREQ 400000
+#define TIMEOUT_VAL 0xE
+#define BCM2835_SDHCI_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)
+
+
+unsigned mmc_debug;
+unsigned mmc_debug2;
+
+struct bcm2835_host {
+	spinlock_t				lock;
+
+	void __iomem			*ioaddr;
+	u32						phys_addr;
+
+	struct mmc_host			*mmc;
+
+	u32						timeout;
+
+	int						clock;	/* Current clock speed */
+	u8						pwr;	/* Current voltage */
+
+	unsigned int			max_clk;		/* Max possible freq */
+	unsigned int			timeout_clk;	/* Timeout freq (KHz) */
+	unsigned int			clk_mul;		/* Clock Muliplier value */
+
+	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 */
+
+
+	u32						ier;			/* cached registers */
+
+	struct mmc_request		*mrq;			/* Current request */
+	struct mmc_command		*cmd;			/* Current command */
+	struct mmc_data			*data;			/* Current data request */
+	unsigned int			data_early:1;		/* Data finished before cmd */
+
+	wait_queue_head_t		buf_ready_int;		/* Waitqueue for Buffer Read Ready interrupt */
+
+	u32						thread_isr;
+
+	u32						shadow;
+
+	/*DMA part*/
+	struct dma_chan			*dma_chan_rx;		/* DMA channel for reads */
+	struct dma_chan			*dma_chan_tx;		/* DMA channel for writes */
+	struct dma_async_tx_descriptor	*tx_desc;	/* descriptor */
+
+	bool					have_dma;
+	bool					use_dma;
+	/*end of DMA part*/
+
+	int						max_delay;	/* maximum length of time spent waiting */
+
+	int						flags;				/* Host attributes */
+#define SDHCI_REQ_USE_DMA	(1<<2)	/* Use DMA for this req. */
+#define SDHCI_DEVICE_DEAD	(1<<3)	/* Device unresponsive */
+#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, 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<<from) & mmc_debug2))
+		udelay(delay);
+}
+
+static inline void mmc_raw_writel(struct bcm2835_host *host, u32 val, int reg)
+{
+	unsigned delay;
+	lockdep_assert_held_once(&host->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);
+}
+
+static inline void bcm2835_mmc_writew(struct bcm2835_host *host, u16 val, int reg)
+{
+	u32 oldval = (reg == SDHCI_COMMAND) ? host->shadow :
+		bcm2835_mmc_readl(host, reg & ~3);
+	u32 word_num = (reg >> 1) & 1;
+	u32 word_shift = word_num * 16;
+	u32 mask = 0xffff << word_shift;
+	u32 newval = (oldval & ~mask) | (val << word_shift);
+
+	if (reg == SDHCI_TRANSFER_MODE)
+		host->shadow = newval;
+	else
+		bcm2835_mmc_writel(host, newval, reg & ~3, 0);
+
+}
+
+static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg)
+{
+	u32 oldval = bcm2835_mmc_readl(host, reg & ~3);
+	u32 byte_num = reg & 3;
+	u32 byte_shift = byte_num * 8;
+	u32 mask = 0xff << byte_shift;
+	u32 newval = (oldval & ~mask) | (val << byte_shift);
+
+	bcm2835_mmc_writel(host, newval, reg & ~3, 1);
+}
+
+
+static inline u16 bcm2835_mmc_readw(struct bcm2835_host *host, int reg)
+{
+	u32 val = bcm2835_mmc_readl(host, (reg & ~3));
+	u32 word_num = (reg >> 1) & 1;
+	u32 word_shift = word_num * 16;
+	u32 word = (val >> word_shift) & 0xffff;
+
+	return word;
+}
+
+static inline u8 bcm2835_mmc_readb(struct bcm2835_host *host, int reg)
+{
+	u32 val = bcm2835_mmc_readl(host, (reg & ~3));
+	u32 byte_num = reg & 3;
+	u32 byte_shift = byte_num * 8;
+	u32 byte = (val >> byte_shift) & 0xff;
+
+	return byte;
+}
+
+static void bcm2835_mmc_unsignal_irqs(struct bcm2835_host *host, u32 clear)
+{
+	u32 ier;
+
+	ier = bcm2835_mmc_readl(host, SDHCI_SIGNAL_ENABLE);
+	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, 2);
+}
+
+
+static void bcm2835_mmc_dumpregs(struct bcm2835_host *host)
+{
+	pr_debug(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n",
+		mmc_hostname(host->mmc));
+
+	pr_debug(DRIVER_NAME ": Sys addr: 0x%08x | Version:  0x%08x\n",
+		bcm2835_mmc_readl(host, SDHCI_DMA_ADDRESS),
+		bcm2835_mmc_readw(host, SDHCI_HOST_VERSION));
+	pr_debug(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt:  0x%08x\n",
+		bcm2835_mmc_readw(host, SDHCI_BLOCK_SIZE),
+		bcm2835_mmc_readw(host, SDHCI_BLOCK_COUNT));
+	pr_debug(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
+		bcm2835_mmc_readl(host, SDHCI_ARGUMENT),
+		bcm2835_mmc_readw(host, SDHCI_TRANSFER_MODE));
+	pr_debug(DRIVER_NAME ": Present:  0x%08x | Host ctl: 0x%08x\n",
+		bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE),
+		bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL));
+	pr_debug(DRIVER_NAME ": Power:    0x%08x | Blk gap:  0x%08x\n",
+		bcm2835_mmc_readb(host, SDHCI_POWER_CONTROL),
+		bcm2835_mmc_readb(host, SDHCI_BLOCK_GAP_CONTROL));
+	pr_debug(DRIVER_NAME ": Wake-up:  0x%08x | Clock:    0x%08x\n",
+		bcm2835_mmc_readb(host, SDHCI_WAKE_UP_CONTROL),
+		bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL));
+	pr_debug(DRIVER_NAME ": Timeout:  0x%08x | Int stat: 0x%08x\n",
+		bcm2835_mmc_readb(host, SDHCI_TIMEOUT_CONTROL),
+		bcm2835_mmc_readl(host, SDHCI_INT_STATUS));
+	pr_debug(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
+		bcm2835_mmc_readl(host, SDHCI_INT_ENABLE),
+		bcm2835_mmc_readl(host, SDHCI_SIGNAL_ENABLE));
+	pr_debug(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
+		bcm2835_mmc_readw(host, SDHCI_ACMD12_ERR),
+		bcm2835_mmc_readw(host, SDHCI_SLOT_INT_STATUS));
+	pr_debug(DRIVER_NAME ": Caps:     0x%08x | Caps_1:   0x%08x\n",
+		bcm2835_mmc_readl(host, SDHCI_CAPABILITIES),
+		bcm2835_mmc_readl(host, SDHCI_CAPABILITIES_1));
+	pr_debug(DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
+		bcm2835_mmc_readw(host, SDHCI_COMMAND),
+		bcm2835_mmc_readl(host, SDHCI_MAX_CURRENT));
+	pr_debug(DRIVER_NAME ": Host ctl2: 0x%08x\n",
+		bcm2835_mmc_readw(host, SDHCI_HOST_CONTROL2));
+
+	pr_debug(DRIVER_NAME ": ===========================================\n");
+}
+
+
+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)
+		host->clock = 0;
+
+	/* Wait max 100 ms */
+	timeout = 100;
+
+	/* hw clears the bit when it's done */
+	while (bcm2835_mmc_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
+		if (timeout == 0) {
+			pr_err("%s: Reset 0x%x never completed.\n",
+				mmc_hostname(host->mmc), (int)mask);
+			bcm2835_mmc_dumpregs(host);
+			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
+		bcm2835_mmc_reset(host, SDHCI_RESET_ALL);
+
+	host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
+		    SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
+		    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, 3);
+	bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 3);
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (soft) {
+		/* force clock reconfiguration */
+		host->clock = 0;
+		bcm2835_mmc_set_ios(host->mmc, &host->mmc->ios);
+	}
+}
+
+
+
+static void bcm2835_mmc_finish_data(struct bcm2835_host *host);
+
+static void bcm2835_mmc_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 && !(host->data->flags & MMC_DATA_WRITE)) {
+		/* otherwise handled in SDHCI IRQ */
+		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_mmc_finish_data(host);
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void bcm2835_bcm2835_mmc_read_block_pio(struct bcm2835_host *host)
+{
+	unsigned long flags;
+	size_t blksize, len, chunk;
+
+	u32 uninitialized_var(scratch);
+	u8 *buf;
+
+	blksize = host->data->blksz;
+	chunk = 0;
+
+	local_irq_save(flags);
+
+	while (blksize) {
+		if (!sg_miter_next(&host->sg_miter))
+			BUG();
+
+		len = min(host->sg_miter.length, blksize);
+
+		blksize -= len;
+		host->sg_miter.consumed = len;
+
+		buf = host->sg_miter.addr;
+
+		while (len) {
+			if (chunk == 0) {
+				scratch = bcm2835_mmc_readl(host, SDHCI_BUFFER);
+				chunk = 4;
+			}
+
+			*buf = scratch & 0xFF;
+
+			buf++;
+			scratch >>= 8;
+			chunk--;
+			len--;
+		}
+	}
+
+	sg_miter_stop(&host->sg_miter);
+
+	local_irq_restore(flags);
+}
+
+static void bcm2835_bcm2835_mmc_write_block_pio(struct bcm2835_host *host)
+{
+	unsigned long flags;
+	size_t blksize, len, chunk;
+	u32 scratch;
+	u8 *buf;
+
+	blksize = host->data->blksz;
+	chunk = 0;
+	chunk = 0;
+	scratch = 0;
+
+	local_irq_save(flags);
+
+	while (blksize) {
+		if (!sg_miter_next(&host->sg_miter))
+			BUG();
+
+		len = min(host->sg_miter.length, blksize);
+
+		blksize -= len;
+		host->sg_miter.consumed = len;
+
+		buf = host->sg_miter.addr;
+
+		while (len) {
+			scratch |= (u32)*buf << (chunk * 8);
+
+			buf++;
+			chunk++;
+			len--;
+
+			if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
+				mmc_raw_writel(host, scratch, SDHCI_BUFFER);
+				chunk = 0;
+				scratch = 0;
+			}
+		}
+	}
+
+	sg_miter_stop(&host->sg_miter);
+
+	local_irq_restore(flags);
+}
+
+
+static void bcm2835_mmc_transfer_pio(struct bcm2835_host *host)
+{
+	u32 mask;
+
+	BUG_ON(!host->data);
+
+	if (host->blocks == 0)
+		return;
+
+	if (host->data->flags & MMC_DATA_READ)
+		mask = SDHCI_DATA_AVAILABLE;
+	else
+		mask = SDHCI_SPACE_AVAILABLE;
+
+	while (bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE) & mask) {
+
+		if (host->data->flags & MMC_DATA_READ)
+			bcm2835_bcm2835_mmc_read_block_pio(host);
+		else
+			bcm2835_bcm2835_mmc_write_block_pio(host);
+
+		host->blocks--;
+
+		/* QUIRK used in sdhci.c removes the 'if' */
+		/* but it seems this is unnecessary */
+		if (host->blocks == 0)
+			break;
+
+
+	}
+}
+
+
+static void bcm2835_mmc_transfer_dma(struct bcm2835_host *host)
+{
+	u32 len, dir_data, dir_slave;
+	struct dma_async_tx_descriptor *desc = NULL;
+	struct dma_chan *dma_chan;
+
+
+	WARN_ON(!host->data);
+
+	if (!host->data)
+		return;
+
+	if (host->blocks == 0)
+		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) {
+		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);
+	}
+
+}
+
+
+
+static void bcm2835_mmc_set_transfer_irqs(struct bcm2835_host *host)
+{
+	u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
+	u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
+
+	if (host->use_dma)
+		host->ier = (host->ier & ~pio_irqs) | dma_irqs;
+	else
+		host->ier = (host->ier & ~dma_irqs) | pio_irqs;
+
+	bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 4);
+	bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 4);
+}
+
+
+static void bcm2835_mmc_prepare_data(struct bcm2835_host *host, struct mmc_command *cmd)
+{
+	u8 count;
+	struct mmc_data *data = cmd->data;
+
+	WARN_ON(host->data);
+
+	if (data || (cmd->flags & MMC_RSP_BUSY)) {
+		count = TIMEOUT_VAL;
+		bcm2835_mmc_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
+	}
+
+	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_early = 0;
+	host->data->bytes_xfered = 0;
+
+
+	if (!(host->flags & SDHCI_REQ_USE_DMA)) {
+		int flags;
+
+		flags = SG_MITER_ATOMIC;
+		if (host->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_mmc_set_transfer_irqs(host);
+
+	/* Set the DMA boundary value and block size */
+	bcm2835_mmc_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+		data->blksz), SDHCI_BLOCK_SIZE);
+	bcm2835_mmc_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
+
+	BUG_ON(!host->data);
+}
+
+static void bcm2835_mmc_set_transfer_mode(struct bcm2835_host *host,
+	struct mmc_command *cmd)
+{
+	u16 mode;
+	struct mmc_data *data = cmd->data;
+
+	if (data == NULL) {
+		/* clear Auto CMD settings for no data CMDs */
+		mode = bcm2835_mmc_readw(host, SDHCI_TRANSFER_MODE);
+		bcm2835_mmc_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 |
+				SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE);
+		return;
+	}
+
+	WARN_ON(!host->data);
+
+	mode = SDHCI_TRNS_BLK_CNT_EN;
+
+	if ((mmc_op_multi(cmd->opcode) || data->blocks > 1)) {
+		mode |= SDHCI_TRNS_MULTI;
+
+		/*
+		 * If we are sending CMD23, CMD12 never gets sent
+		 * on successful completion (so no Auto-CMD12).
+		 */
+		if (!host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD12))
+			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, 5);
+		}
+	}
+
+	if (data->flags & MMC_DATA_READ)
+		mode |= SDHCI_TRNS_READ;
+	if (host->flags & SDHCI_REQ_USE_DMA)
+		mode |= SDHCI_TRNS_DMA;
+
+	bcm2835_mmc_writew(host, mode, SDHCI_TRANSFER_MODE);
+}
+
+void bcm2835_mmc_send_command(struct bcm2835_host *host, struct mmc_command *cmd)
+{
+	int flags;
+	u32 mask;
+	unsigned long timeout;
+
+	WARN_ON(host->cmd);
+
+	/* Wait max 10 ms */
+	timeout = 1000;
+
+	mask = SDHCI_CMD_INHIBIT;
+	if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY))
+		mask |= SDHCI_DATA_INHIBIT;
+
+	/* We shouldn't wait for data inihibit for stop commands, even
+	   though they might use busy signaling */
+	if (host->mrq->data && (cmd == host->mrq->data->stop))
+		mask &= ~SDHCI_DATA_INHIBIT;
+
+	while (bcm2835_mmc_readl(host, SDHCI_PRESENT_STATE) & mask) {
+		if (timeout == 0) {
+			pr_err("%s: Controller never released inhibit bit(s).\n",
+				mmc_hostname(host->mmc));
+			bcm2835_mmc_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: MMC 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_mmc_prepare_data(host, cmd);
+
+	bcm2835_mmc_writel(host, cmd->arg, SDHCI_ARGUMENT, 6);
+
+	bcm2835_mmc_set_transfer_mode(host, cmd);
+
+	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;
+	}
+
+	if (!(cmd->flags & MMC_RSP_PRESENT))
+		flags = SDHCI_CMD_RESP_NONE;
+	else if (cmd->flags & MMC_RSP_136)
+		flags = SDHCI_CMD_RESP_LONG;
+	else if (cmd->flags & MMC_RSP_BUSY)
+		flags = SDHCI_CMD_RESP_SHORT_BUSY;
+	else
+		flags = SDHCI_CMD_RESP_SHORT;
+
+	if (cmd->flags & MMC_RSP_CRC)
+		flags |= SDHCI_CMD_CRC;
+	if (cmd->flags & MMC_RSP_OPCODE)
+		flags |= SDHCI_CMD_INDEX;
+
+	if (cmd->data)
+		flags |= SDHCI_CMD_DATA;
+
+	bcm2835_mmc_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
+}
+
+
+static void bcm2835_mmc_finish_data(struct bcm2835_host *host)
+{
+	struct mmc_data *data;
+
+	BUG_ON(!host->data);
+
+	data = host->data;
+	host->data = NULL;
+
+	if (data->error)
+		data->bytes_xfered = 0;
+	else
+		data->bytes_xfered = data->blksz * data->blocks;
+
+	/*
+	 * 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)) {
+
+		/*
+		 * The controller needs a reset of internal state machines
+		 * upon error conditions.
+		 */
+		if (data->error) {
+			bcm2835_mmc_reset(host, SDHCI_RESET_CMD);
+			bcm2835_mmc_reset(host, SDHCI_RESET_DATA);
+		}
+
+		bcm2835_mmc_send_command(host, data->stop);
+	} else
+		tasklet_schedule(&host->finish_tasklet);
+}
+
+static void bcm2835_mmc_finish_command(struct bcm2835_host *host)
+{
+	int i;
+
+	BUG_ON(host->cmd == NULL);
+
+	if (host->cmd->flags & MMC_RSP_PRESENT) {
+		if (host->cmd->flags & MMC_RSP_136) {
+			/* CRC is stripped so we need to do some shifting. */
+			for (i = 0; i < 4; i++) {
+				host->cmd->resp[i] = bcm2835_mmc_readl(host,
+					SDHCI_RESPONSE + (3-i)*4) << 8;
+				if (i != 3)
+					host->cmd->resp[i] |=
+						bcm2835_mmc_readb(host,
+						SDHCI_RESPONSE + (3-i)*4-1);
+			}
+		} else {
+			host->cmd->resp[0] = bcm2835_mmc_readl(host, SDHCI_RESPONSE);
+		}
+	}
+
+	host->cmd->error = 0;
+
+	/* Finished CMD23, now send actual command. */
+	if (host->cmd == host->mrq->sbc) {
+		host->cmd = NULL;
+		bcm2835_mmc_send_command(host, host->mrq->cmd);
+
+		if (host->mrq->cmd->data && host->use_dma) {
+			/* DMA transfer starts now, PIO starts after interrupt */
+			bcm2835_mmc_transfer_dma(host);
+		}
+	} else {
+
+		/* Processed actual command. */
+		if (host->data && host->data_early)
+			bcm2835_mmc_finish_data(host);
+
+		if (!host->cmd->data)
+			tasklet_schedule(&host->finish_tasklet);
+
+		host->cmd = NULL;
+	}
+}
+
+
+static void bcm2835_mmc_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_mmc_dumpregs(host);
+
+		if (host->data) {
+			host->data->error = -ETIMEDOUT;
+			bcm2835_mmc_finish_data(host);
+		} else {
+			if (host->cmd)
+				host->cmd->error = -ETIMEDOUT;
+			else
+				host->mrq->cmd->error = -ETIMEDOUT;
+
+			tasklet_schedule(&host->finish_tasklet);
+		}
+	}
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+
+static void bcm2835_mmc_enable_sdio_irq_nolock(struct bcm2835_host *host, int enable)
+{
+	if (!(host->flags & SDHCI_DEVICE_DEAD)) {
+		if (enable)
+			host->ier |= SDHCI_INT_CARD_INT;
+		else
+			host->ier &= ~SDHCI_INT_CARD_INT;
+
+		bcm2835_mmc_writel(host, host->ier, SDHCI_INT_ENABLE, 7);
+		bcm2835_mmc_writel(host, host->ier, SDHCI_SIGNAL_ENABLE, 7);
+		mmiowb();
+	}
+}
+
+static void bcm2835_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct bcm2835_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (enable)
+		host->flags |= SDHCI_SDIO_IRQ_ENABLED;
+	else
+		host->flags &= ~SDHCI_SDIO_IRQ_ENABLED;
+
+	bcm2835_mmc_enable_sdio_irq_nolock(host, enable);
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void bcm2835_mmc_cmd_irq(struct bcm2835_host *host, u32 intmask)
+{
+
+	BUG_ON(intmask == 0);
+
+	if (!host->cmd) {
+		pr_err("%s: Got command interrupt 0x%08x even "
+			"though no command operation was in progress.\n",
+			mmc_hostname(host->mmc), (unsigned)intmask);
+		bcm2835_mmc_dumpregs(host);
+		return;
+	}
+
+	if (intmask & SDHCI_INT_TIMEOUT)
+		host->cmd->error = -ETIMEDOUT;
+	else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT |
+			SDHCI_INT_INDEX)) {
+			host->cmd->error = -EILSEQ;
+	}
+
+	if (host->cmd->error) {
+		tasklet_schedule(&host->finish_tasklet);
+		return;
+	}
+
+	if (intmask & SDHCI_INT_RESPONSE)
+		bcm2835_mmc_finish_command(host);
+
+}
+
+static void bcm2835_mmc_data_irq(struct bcm2835_host *host, u32 intmask)
+{
+	struct dma_chan *dma_chan;
+	u32 dir_data;
+
+	BUG_ON(intmask == 0);
+
+	if (!host->data) {
+		/*
+		 * The "data complete" interrupt is also used to
+		 * indicate that a busy state has ended. See comment
+		 * above in sdhci_cmd_irq().
+		 */
+		if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) {
+			if (intmask & SDHCI_INT_DATA_END) {
+				bcm2835_mmc_finish_command(host);
+				return;
+			}
+		}
+
+		pr_debug("%s: Got data interrupt 0x%08x even "
+			"though no data operation was in progress.\n",
+			mmc_hostname(host->mmc), (unsigned)intmask);
+		bcm2835_mmc_dumpregs(host);
+
+		return;
+	}
+
+	if (intmask & SDHCI_INT_DATA_TIMEOUT)
+		host->data->error = -ETIMEDOUT;
+	else if (intmask & SDHCI_INT_DATA_END_BIT)
+		host->data->error = -EILSEQ;
+	else if ((intmask & SDHCI_INT_DATA_CRC) &&
+		SDHCI_GET_CMD(bcm2835_mmc_readw(host, SDHCI_COMMAND))
+			!= MMC_BUS_TEST_R)
+		host->data->error = -EILSEQ;
+
+	if (host->use_dma) {
+		if  (host->data->flags & MMC_DATA_WRITE) {
+			/* IRQ handled here */
+
+			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_mmc_finish_data(host);
+		}
+
+	} else {
+		if (host->data->error)
+			bcm2835_mmc_finish_data(host);
+		else {
+			if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
+				bcm2835_mmc_transfer_pio(host);
+
+			if (intmask & SDHCI_INT_DATA_END) {
+				if (host->cmd) {
+					/*
+					 * Data managed to finish before the
+					 * command completed. Make sure we do
+					 * things in the proper order.
+					 */
+					host->data_early = 1;
+				} else {
+					bcm2835_mmc_finish_data(host);
+				}
+			}
+		}
+	}
+}
+
+
+static irqreturn_t bcm2835_mmc_irq(int irq, void *dev_id)
+{
+	irqreturn_t result = IRQ_NONE;
+	struct bcm2835_host *host = dev_id;
+	u32 intmask, mask, unexpected = 0;
+	int max_loops = 16;
+#ifndef CONFIG_ARCH_BCM2835
+	int cardint = 0;
+#endif
+
+	spin_lock(&host->lock);
+
+	intmask = bcm2835_mmc_readl(host, SDHCI_INT_STATUS);
+
+	if (!intmask || intmask == 0xffffffff) {
+		result = IRQ_NONE;
+		goto out;
+	}
+
+	do {
+		/* 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, 8);
+
+
+		if (intmask & SDHCI_INT_CMD_MASK)
+			bcm2835_mmc_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
+
+		if (intmask & SDHCI_INT_DATA_MASK)
+			bcm2835_mmc_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
+
+		if (intmask & SDHCI_INT_BUS_POWER)
+			pr_err("%s: Card is consuming too much power!\n",
+				mmc_hostname(host->mmc));
+
+		if (intmask & SDHCI_INT_CARD_INT) {
+#ifndef CONFIG_ARCH_BCM2835
+			cardint = 1;
+#else
+			bcm2835_mmc_enable_sdio_irq_nolock(host, false);
+			host->thread_isr |= SDHCI_INT_CARD_INT;
+			result = IRQ_WAKE_THREAD;
+#endif
+		}
+
+		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
+			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
+			     SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
+			     SDHCI_INT_CARD_INT);
+
+		if (intmask) {
+			unexpected |= intmask;
+			bcm2835_mmc_writel(host, intmask, SDHCI_INT_STATUS, 9);
+		}
+
+		if (result == IRQ_NONE)
+			result = IRQ_HANDLED;
+
+		intmask = bcm2835_mmc_readl(host, SDHCI_INT_STATUS);
+	} while (intmask && --max_loops);
+out:
+	spin_unlock(&host->lock);
+
+	if (unexpected) {
+		pr_err("%s: Unexpected interrupt 0x%08x.\n",
+			   mmc_hostname(host->mmc), unexpected);
+		bcm2835_mmc_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_mmc_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 & SDHCI_INT_CARD_INT) {
+		sdio_run_irqs(host->mmc);
+
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->flags & SDHCI_SDIO_IRQ_ENABLED)
+			bcm2835_mmc_enable_sdio_irq_nolock(host, true);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
+
+	return isr ? IRQ_HANDLED : IRQ_NONE;
+}
+#endif
+
+
+
+void bcm2835_mmc_set_clock(struct bcm2835_host *host, unsigned int clock)
+{
+	int div = 0; /* Initialized for compiler warning */
+	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;
+
+	bcm2835_mmc_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+	if (clock == 0)
+		return;
+
+	/* Version 3.00 divisors must be a multiple of 2. */
+	if (host->max_clk <= clock)
+		div = 1;
+	else {
+		for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
+			 div += 2) {
+			if ((host->max_clk / div) <= clock)
+				break;
+		}
+	}
+
+	real_div = div;
+	div >>= 1;
+
+	if (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)
+		<< SDHCI_DIVIDER_HI_SHIFT;
+	clk |= SDHCI_CLOCK_INT_EN;
+	bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+	/* Wait max 20 ms */
+	timeout = 20;
+	while (!((clk = bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL))
+		& SDHCI_CLOCK_INT_STABLE)) {
+		if (timeout == 0) {
+			pr_err("%s: Internal clock never "
+				"stabilised.\n", mmc_hostname(host->mmc));
+			bcm2835_mmc_dumpregs(host);
+			return;
+		}
+		timeout--;
+		mdelay(1);
+	}
+
+	if (20-timeout > 10 && 20-timeout > host->max_delay) {
+		host->max_delay = 20-timeout;
+		pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay);
+	}
+
+	clk |= SDHCI_CLOCK_CARD_EN;
+	bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL);
+}
+
+static void bcm2835_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct bcm2835_host *host;
+	unsigned long flags;
+
+	host = mmc_priv(mmc);
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	WARN_ON(host->mrq != NULL);
+
+	host->mrq = mrq;
+
+	if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
+		bcm2835_mmc_send_command(host, mrq->sbc);
+	else
+		bcm2835_mmc_send_command(host, mrq->cmd);
+
+	mmiowb();
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	if (!(mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) && mrq->cmd->data && host->use_dma) {
+		/* DMA transfer starts now, PIO starts after interrupt */
+		bcm2835_mmc_transfer_dma(host);
+	}
+}
+
+
+static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+
+	struct bcm2835_host *host = mmc_priv(mmc);
+	unsigned long flags;
+	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);
+
+	if (!ios->clock || ios->clock != host->clock) {
+		bcm2835_mmc_set_clock(host, ios->clock);
+		host->clock = ios->clock;
+	}
+
+	if (host->pwr != SDHCI_POWER_330) {
+		host->pwr = SDHCI_POWER_330;
+		bcm2835_mmc_writeb(host, SDHCI_POWER_330 | SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
+	}
+
+	ctrl = bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL);
+
+	/* set bus width */
+	ctrl &= ~SDHCI_CTRL_8BITBUS;
+	if (ios->bus_width == MMC_BUS_WIDTH_4)
+		ctrl |= SDHCI_CTRL_4BITBUS;
+	else
+		ctrl &= ~SDHCI_CTRL_4BITBUS;
+
+	ctrl &= ~SDHCI_CTRL_HISPD; /* NO_HISPD_BIT */
+
+
+	bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+	/*
+	 * We only need to set Driver Strength if the
+	 * preset value enable is not set.
+	 */
+	ctrl_2 = bcm2835_mmc_readw(host, SDHCI_HOST_CONTROL2);
+	ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
+	if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
+		ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
+	else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C)
+		ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
+
+	bcm2835_mmc_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+
+	/* Reset SD Clock Enable */
+	clk = bcm2835_mmc_readw(host, SDHCI_CLOCK_CONTROL);
+	clk &= ~SDHCI_CLOCK_CARD_EN;
+	bcm2835_mmc_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+	/* Re-enable SD Clock */
+	bcm2835_mmc_set_clock(host, host->clock);
+	bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
+	mmiowb();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+
+static struct mmc_host_ops bcm2835_ops = {
+	.request = bcm2835_mmc_request,
+	.set_ios = bcm2835_mmc_set_ios,
+	.enable_sdio_irq = bcm2835_mmc_enable_sdio_irq,
+};
+
+
+static void bcm2835_mmc_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 (!(host->flags & SDHCI_DEVICE_DEAD) &&
+	    ((mrq->cmd && mrq->cmd->error) ||
+		 (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;
+	host->cmd = NULL;
+	host->data = NULL;
+
+	mmiowb();
+
+	spin_unlock_irqrestore(&host->lock, flags);
+	mmc_request_done(host->mmc, mrq);
+}
+
+
+
+static int bcm2835_mmc_add_host(struct bcm2835_host *host)
+{
+	struct mmc_host *mmc = host->mmc;
+	struct device *dev = mmc->parent;
+#ifndef FORCE_PIO
+	struct dma_slave_config cfg;
+#endif
+	int ret;
+
+	bcm2835_mmc_reset(host, SDHCI_RESET_ALL);
+
+	host->clk_mul = 0;
+
+	mmc->f_max = host->max_clk;
+	mmc->f_max = host->max_clk;
+	mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
+
+	/* 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_CMD23 | MMC_CAP_ERASE | MMC_CAP_NEEDS_POLL |
+		MMC_CAP_SDIO_IRQ | MMC_CAP_SD_HIGHSPEED |
+		MMC_CAP_MMC_HIGHSPEED;
+
+	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;
+#else
+	if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
+	    IS_ERR_OR_NULL(host->dma_chan_rx)) {
+		dev_err(dev, "%s: Unable to initialise DMA channels. Falling back to PIO\n",
+			DRIVER_NAME);
+		host->have_dma = false;
+	} else {
+		dev_info(dev, "DMA channels allocated");
+		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 = 11;		/* DREQ channel */
+
+		cfg.direction = DMA_MEM_TO_DEV;
+		cfg.src_addr = 0;
+		cfg.dst_addr = host->phys_addr + SDHCI_BUFFER;
+		ret = dmaengine_slave_config(host->dma_chan_tx, &cfg);
+
+		cfg.direction = DMA_DEV_TO_MEM;
+		cfg.src_addr = host->phys_addr + SDHCI_BUFFER;
+		cfg.dst_addr = 0;
+		ret = dmaengine_slave_config(host->dma_chan_rx, &cfg);
+	}
+#endif
+	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_mmc_tasklet_finish, (unsigned long)host);
+
+	setup_timer(&host->timer, bcm2835_mmc_timeout_timer, (unsigned long)host);
+	init_waitqueue_head(&host->buf_ready_int);
+
+	bcm2835_mmc_init(host, 0);
+#ifndef CONFIG_ARCH_BCM2835
+	ret = devm_request_irq(dev, host->irq, bcm2835_mmc_irq, 0,
+			       mmc_hostname(mmc), host);
+#else
+	ret = devm_request_threaded_irq(dev, host->irq, bcm2835_mmc_irq,
+					bcm2835_mmc_thread_irq, IRQF_SHARED,
+					mmc_hostname(mmc), host);
+#endif
+	if (ret) {
+		dev_err(dev, "Failed to request IRQ %d: %d\n", host->irq, ret);
+		goto untasklet;
+	}
+
+	mmiowb();
+	mmc_add_host(mmc);
+
+	return 0;
+
+untasklet:
+	tasklet_kill(&host->finish_tasklet);
+
+	return ret;
+}
+
+static int bcm2835_mmc_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;
+
+	mmc = mmc_alloc_host(sizeof(*host), dev);
+	if (!mmc)
+		return -ENOMEM;
+
+	mmc->ops = &bcm2835_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;
+
+#ifndef FORCE_PIO
+	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);
+	}
+#endif
+	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;
+	}
+
+	if (node) {
+		mmc_of_parse(mmc);
+
+		/* 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)
+		goto err;
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+err:
+	mmc_free_host(mmc);
+
+	return ret;
+}
+
+static int bcm2835_mmc_remove(struct platform_device *pdev)
+{
+	struct bcm2835_host *host = platform_get_drvdata(pdev);
+	unsigned long flags;
+	int dead;
+	u32 scratch;
+
+	dead = 0;
+	scratch = bcm2835_mmc_readl(host, SDHCI_INT_STATUS);
+	if (scratch == (u32)-1)
+		dead = 1;
+
+
+	if (dead) {
+		spin_lock_irqsave(&host->lock, flags);
+
+		host->flags |= SDHCI_DEVICE_DEAD;
+
+		if (host->mrq) {
+			pr_err("%s: Controller removed during "
+				" transfer!\n", mmc_hostname(host->mmc));
+
+			host->mrq->cmd->error = -ENOMEDIUM;
+			tasklet_schedule(&host->finish_tasklet);
+		}
+
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
+
+	mmc_remove_host(host->mmc);
+
+	if (!dead)
+		bcm2835_mmc_reset(host, SDHCI_RESET_ALL);
+
+	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);
+
+	return 0;
+}
+
+
+static const struct of_device_id bcm2835_mmc_match[] = {
+	{ .compatible = "brcm,bcm2835-mmc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bcm2835_mmc_match);
+
+
+
+static struct platform_driver bcm2835_mmc_driver = {
+	.probe      = bcm2835_mmc_probe,
+	.remove     = bcm2835_mmc_remove,
+	.driver     = {
+		.name		= DRIVER_NAME,
+		.owner		= THIS_MODULE,
+		.of_match_table	= bcm2835_mmc_match,
+	},
+};
+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");
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-01 21:43 ` [PATCH 01/32] arm64: Add platform selection for BCM2835 Gerd Hoffmann
@ 2016-06-01 21:49   ` Florian Fainelli
  2016-06-02  6:45     ` Gerd Hoffmann
  0 siblings, 1 reply; 70+ messages in thread
From: Florian Fainelli @ 2016-06-01 21:49 UTC (permalink / raw)
  To: Gerd Hoffmann, linux-rpi-kernel
  Cc: Eric Anholt, Florian Fainelli, Ray Jui, Scott Branden,
	Russell King, Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list

On 06/01/2016 02:43 PM, Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> 
> [ kraxel: copy some selects from arm to arm64 ]
> [ kraxel: add CONFIG_ARCH_BCM, needed for some "depends on ARCH_BCM" ]
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  arch/arm/mach-bcm/Kconfig    |  2 +-
>  arch/arm64/Kconfig.platforms | 20 ++++++++++++++++++++
>  2 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig
> index 68ab641..21f0e43 100644
> --- a/arch/arm/mach-bcm/Kconfig
> +++ b/arch/arm/mach-bcm/Kconfig
> @@ -136,7 +136,7 @@ comment "Other Architectures"
>  
>  config ARCH_BCM2835
>  	bool "Broadcom BCM2835 family"
> -	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
> +	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 || ARM64

Humm, what does that achieve?

>  	select ARCH_REQUIRE_GPIOLIB
>  	select ARM_AMBA
>  	select ARM_ERRATA_411920 if ARCH_MULTI_V6
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 7ef1d05..32aba6b 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -13,8 +13,28 @@ config ARCH_ALPINE
>  	  This enables support for the Annapurna Labs Alpine
>  	  Soc family.
>  
> +config ARCH_BCM
> +	bool "Broadcom SoC Support"
> +	help
> +	  This enables support for Broadcom ARM based SoC chips

menuconfig maybe?

> +
> +config ARCH_BCM2835
> +	bool "Broadcom BCM2835 family"
> +	depends on ARCH_BCM
> +	select ARCH_REQUIRE_GPIOLIB
> +	select CLKSRC_OF
> +	select PINCTRL
> +	select PINCTRL_BCM2835
> +	select ARM_AMBA
> +	select ARM_TIMER_SP804
> +	select HAVE_ARM_ARCH_TIMER
> +	help
> +	  This enables support for the Broadcom BCM2837 SoC.
> +	  This SoC is used in the Raspberry Pi 3 device.
> +
>  config ARCH_BCM_IPROC
>  	bool "Broadcom iProc SoC Family"
> +	depends on ARCH_BCM

Does not seem necessary nor adding anything here.
-- 
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-01 21:43 ` [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm Gerd Hoffmann
@ 2016-06-01 22:00   ` Arnd Bergmann
  2016-06-01 22:30     ` Eric Anholt
  0 siblings, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-01 22:00 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

On Wednesday, June 1, 2016 11:43:18 PM CEST Gerd Hoffmann wrote:
> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> new file mode 100644
> index 0000000..36178a6
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> @@ -0,0 +1 @@
> +#include "../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts"
> -- 
> 1.8.3.1
> 

What does this gain you?

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller.
  2016-06-01 21:43 ` [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller Gerd Hoffmann
@ 2016-06-01 22:18   ` Arnd Bergmann
  2016-06-02 18:12     ` Eric Anholt
  2016-06-21 12:33     ` Gerd Hoffmann
  0 siblings, 2 replies; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-01 22:18 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Eric Anholt, Ulf Hansson, Stephen Warren,
	Lee Jones, open list, open list:MULTIMEDIA CARD (MMC),
	SECURE DIGITAL (SD) AND...,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

On Wednesday, June 1, 2016 11:43:30 PM CEST Gerd Hoffmann wrote:

> +static void bcm2835_sdhost_reset_internal(struct bcm2835_host *host)
> +{
> +	u32 temp;
> +
> +	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 << SDEDM_READ_THRESHOLD_SHIFT) |
> +		  (SDEDM_THRESHOLD_MASK << SDEDM_WRITE_THRESHOLD_SHIFT));
> +	temp |= (FIFO_READ_THRESHOLD << SDEDM_READ_THRESHOLD_SHIFT) |
> +		(FIFO_WRITE_THRESHOLD << SDEDM_WRITE_THRESHOLD_SHIFT);
> +	bcm2835_sdhost_write(host, temp, SDEDM);
> +	mdelay(10);
> +	bcm2835_sdhost_set_power(host, true);
> +	mdelay(10);

Are you sure you cannot use msleep() here?

> +	host->clock = 0;
> +	bcm2835_sdhost_write(host, host->hcfg, SDHCFG);
> +	bcm2835_sdhost_write(host, host->cdiv, SDCDIV);
> +	mmiowb();
> +}

What is the barrier for? Same question for all the other instances

> +
> +static void bcm2835_sdhost_reset(struct mmc_host *mmc)
> +{
> +	struct bcm2835_host *host = mmc_priv(mmc);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&host->lock, flags);
> +	bcm2835_sdhost_reset_internal(host);
> +	spin_unlock_irqrestore(&host->lock, flags);
> +}

The spinlock seems to only protect the reset from happening concurrently
with bcm2835_sdhost_dma_complete() here. So if you ensure that this
function is no longer pending, you can probably use msleep() above.

> +static void bcm2835_sdhost_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);

Maybe rearrange the order of the functions to avoid forward declarations?

> +	spin_lock_init(&host->lock);
> +
> +	if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
> +	    IS_ERR_OR_NULL(host->dma_chan_rx)) {
> +		pr_err("%s: unable to initialise DMA channels. Falling back to PIO\n",
> +		       mmc_hostname(mmc));

When are these ever NULL?

> +	/* Parse OF address directly to get the physical address for
> +	 * DMA to our registers.
> +	 */
> +	host->phys_addr = be32_to_cpup(of_get_address(pdev->dev.of_node, 0,
> +						      NULL, NULL));

This looks broken on 64-bit systems when #address-cells=<2>, or if there
is an intermediate bus with a non-empty ranges property.

What's wrong with platform_get_resource(pdev, IORESOURCE_MEM, 0)?

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/32] don't force serial pins to uart0
  2016-06-01 21:43 ` [PATCH 10/32] don't force serial pins to uart0 Gerd Hoffmann
@ 2016-06-01 22:19   ` Arnd Bergmann
  2016-06-02 18:19     ` Eric Anholt
  0 siblings, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-01 22:19 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Gerd Hoffmann, linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Lee Jones, Pawel Moll, Ian Campbell, Stephen Warren,
	Russell King, open list, Eric Anholt, Rob Herring, Kumar Gala

On Wednesday, June 1, 2016 11:43:19 PM CEST Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> ---
> 

No signoff or description?

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-01 22:00   ` Arnd Bergmann
@ 2016-06-01 22:30     ` Eric Anholt
  2016-06-01 22:39       ` Arnd Bergmann
  0 siblings, 1 reply; 70+ messages in thread
From: Eric Anholt @ 2016-06-01 22:30 UTC (permalink / raw)
  To: Arnd Bergmann, Gerd Hoffmann
  Cc: linux-rpi-kernel, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

[-- Attachment #1: Type: text/plain, Size: 653 bytes --]

Arnd Bergmann <arnd@arndb.de> writes:

> On Wednesday, June 1, 2016 11:43:18 PM CEST Gerd Hoffmann wrote:
>> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
>> new file mode 100644
>> index 0000000..36178a6
>> --- /dev/null
>> +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
>> @@ -0,0 +1 @@
>> +#include "../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts"
>> -- 
>> 1.8.3.1
>> 
>
> What does this gain you?

Many Raspberry Pi users use a small set of SD cards that they swap
between various versions of the hardware.  It would be good to have
their 32-bit OS images work on the Pi3 as well.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-01 22:30     ` Eric Anholt
@ 2016-06-01 22:39       ` Arnd Bergmann
  2016-06-02  6:56         ` Gerd Hoffmann
  0 siblings, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-01 22:39 UTC (permalink / raw)
  To: Eric Anholt
  Cc: Gerd Hoffmann, linux-rpi-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

On Wednesday, June 1, 2016 3:30:35 PM CEST Eric Anholt wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> 
> > On Wednesday, June 1, 2016 11:43:18 PM CEST Gerd Hoffmann wrote:
> >> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> >> new file mode 100644
> >> index 0000000..36178a6
> >> --- /dev/null
> >> +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> >> @@ -0,0 +1 @@
> >> +#include "../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts"
> >> -- 
> >> 1.8.3.1
> >> 
> >
> > What does this gain you?
> 
> Many Raspberry Pi users use a small set of SD cards that they swap
> between various versions of the hardware.  It would be good to have
> their 32-bit OS images work on the Pi3 as well.

Sure, but you already have the dts file in the other directory,
and the dtb is the same.

According to the comment in the other patch, the idea was to have
the file in the arm64 directory because it's a 64-bit platform,
but now you have it here as well.

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ.
  2016-06-01 21:43 ` [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ Gerd Hoffmann
@ 2016-06-02  0:50   ` Jason Cooper
  2016-06-02 18:06     ` Eric Anholt
  0 siblings, 1 reply; 70+ messages in thread
From: Jason Cooper @ 2016-06-02  0:50 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Eric Anholt, Thomas Gleixner, Marc Zyngier,
	Stephen Warren, Lee Jones, open list:IRQCHIP DRIVERS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

Hey Gerd,

On Wed, Jun 01, 2016 at 11:43:12PM +0200, Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> This is equivalent and works for arm64 as well.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---

I don't mind taking this, or Eric's V2 resend.  However, the commit
message needs a rewrite.

thx,

Jason.

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-01 21:49   ` Florian Fainelli
@ 2016-06-02  6:45     ` Gerd Hoffmann
  2016-06-02 16:25       ` Ray Jui
  2016-06-02 17:30       ` Catalin Marinas
  0 siblings, 2 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-02  6:45 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-rpi-kernel, Eric Anholt, Ray Jui, Scott Branden,
	Russell King, Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list

> >  config ARCH_BCM2835
> >  	bool "Broadcom BCM2835 family"
> > -	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
> > +	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 || ARM64
> 
> Humm, what does that achieve?

Nothing ;)

Slipped through unnoticed, I'll drop it.

> > +config ARCH_BCM
> > +	bool "Broadcom SoC Support"
> > +	help
> > +	  This enables support for Broadcom ARM based SoC chips
> 
> menuconfig maybe?

There isn't any in arch/arm64/Kconfig.platforms right now, so I didn't
feel like introducing one.  Also the dependency should have pretty much
the same effect ...

> > +config ARCH_BCM2835
> > +	bool "Broadcom BCM2835 family"
> > +	depends on ARCH_BCM
> > +	select ARCH_REQUIRE_GPIOLIB
> > +	select CLKSRC_OF
> > +	select PINCTRL
> > +	select PINCTRL_BCM2835
> > +	select ARM_AMBA
> > +	select ARM_TIMER_SP804
> > +	select HAVE_ARM_ARCH_TIMER
> > +	help
> > +	  This enables support for the Broadcom BCM2837 SoC.
> > +	  This SoC is used in the Raspberry Pi 3 device.
> > +
> >  config ARCH_BCM_IPROC
> >  	bool "Broadcom iProc SoC Family"
> > +	depends on ARCH_BCM
> 
> Does not seem necessary nor adding anything here.

Added for consistency.  When we add ARCH_BCM all ARCH_BCM_* should
depend on it ...

We could also do it the other way around: make ARCH_BCM a hidden bool
and have ARCH_BCM_* select it.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-01 22:39       ` Arnd Bergmann
@ 2016-06-02  6:56         ` Gerd Hoffmann
  2016-06-02  7:24           ` Arnd Bergmann
  0 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-02  6:56 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Eric Anholt, linux-rpi-kernel, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM PORT, open list

On Do, 2016-06-02 at 00:39 +0200, Arnd Bergmann wrote:
> On Wednesday, June 1, 2016 3:30:35 PM CEST Eric Anholt wrote:
> > Arnd Bergmann <arnd@arndb.de> writes:
> > 
> > > On Wednesday, June 1, 2016 11:43:18 PM CEST Gerd Hoffmann wrote:
> > >> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> > >> new file mode 100644
> > >> index 0000000..36178a6
> > >> --- /dev/null
> > >> +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> > >> @@ -0,0 +1 @@
> > >> +#include "../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts"
> > >> -- 
> > >> 1.8.3.1
> > >> 
> > >
> > > What does this gain you?
> > 
> > Many Raspberry Pi users use a small set of SD cards that they swap
> > between various versions of the hardware.  It would be good to have
> > their 32-bit OS images work on the Pi3 as well.
> 
> Sure, but you already have the dts file in the other directory,
> and the dtb is the same.
> 
> According to the comment in the other patch, the idea was to have
> the file in the arm64 directory because it's a 64-bit platform,
> but now you have it here as well.

Well, it just includes the arm64 version as-is, so we don't have
duplication.  I'm open to suggestions to how handle this better.  

Symbolic link?

Reference to ../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
directly in the Makefile?

I've seen arch/arm/boot/dts/Makefile uses globs on *.dts, so I suspect
the later wouldn't be that straight forward.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-02  6:56         ` Gerd Hoffmann
@ 2016-06-02  7:24           ` Arnd Bergmann
  2016-06-02  9:14             ` Gerd Hoffmann
  0 siblings, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-02  7:24 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Gerd Hoffmann, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Pawel Moll, Ian Campbell, Russell King, open list, Eric Anholt,
	Rob Herring, linux-rpi-kernel, Kumar Gala

On Thursday, June 2, 2016 8:56:05 AM CEST Gerd Hoffmann wrote:
> On Do, 2016-06-02 at 00:39 +0200, Arnd Bergmann wrote:
> > On Wednesday, June 1, 2016 3:30:35 PM CEST Eric Anholt wrote:
> > > Arnd Bergmann <arnd@arndb.de> writes:
> > > 
> > > > On Wednesday, June 1, 2016 11:43:18 PM CEST Gerd Hoffmann wrote:
> > > >> diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> > > >> new file mode 100644
> > > >> index 0000000..36178a6
> > > >> --- /dev/null
> > > >> +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts
> > > >> @@ -0,0 +1 @@
> > > >> +#include "../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts"
> > > >> -- 
> > > >> 1.8.3.1
> > > >> 
> > > >
> > > > What does this gain you?
> > > 
> > > Many Raspberry Pi users use a small set of SD cards that they swap
> > > between various versions of the hardware.  It would be good to have
> > > their 32-bit OS images work on the Pi3 as well.
> > 
> > Sure, but you already have the dts file in the other directory,
> > and the dtb is the same.
> > 
> > According to the comment in the other patch, the idea was to have
> > the file in the arm64 directory because it's a 64-bit platform,
> > but now you have it here as well.
> 
> Well, it just includes the arm64 version as-is, so we don't have
> duplication.  I'm open to suggestions to how handle this better.  
> 
> Symbolic link?
> 
> Reference to ../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> directly in the Makefile?
> 
> I've seen arch/arm/boot/dts/Makefile uses globs on *.dts, so I suspect
> the later wouldn't be that straight forward.

It's just weird that the arm64 file includes the .dtsi files from arch/arm/
and is then again included back from another file there.

I can see two possible ways to handle this better:

- leave the complete set of bcm2837 files in arch/arm and then have one
  reference from arch/arm64 per .dts that refers to just that file.

- come up with a rule to also build the .dtb files in arch/arm64 when
  we run 'make dtbs' for arch/arm and leave this file there. The argument
  that one could use the same dtb with a 32-bit kernel should basically
  hold true for any arm64 system, it's not specific to rpi-3 really.
  We don't normally test 32-bit kernels on 64-bit SoCs because 64-bit
  kernels are more efficient in a number of ways, and I'm sure there
  are bugs that prevent some systems from working (aside from how some
  machines cannot work because they don't have RAM below 4GB), but if
  this is now something that users are interested in, making it just
  work seems nicer than having a couple of board specific hacks.

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-02  7:24           ` Arnd Bergmann
@ 2016-06-02  9:14             ` Gerd Hoffmann
  2016-06-02  9:53               ` Arnd Bergmann
  0 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-02  9:14 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Pawel Moll, Ian Campbell, Russell King, open list, Eric Anholt,
	Rob Herring, linux-rpi-kernel, Kumar Gala

  Hi,

> > Well, it just includes the arm64 version as-is, so we don't have
> > duplication.  I'm open to suggestions to how handle this better.  
> > 
> > Symbolic link?
> > 
> > Reference to ../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> > directly in the Makefile?
> > 
> > I've seen arch/arm/boot/dts/Makefile uses globs on *.dts, so I suspect
> > the later wouldn't be that straight forward.
> 
> It's just weird that the arm64 file includes the .dtsi files from arch/arm/
> and is then again included back from another file there.
> 
> I can see two possible ways to handle this better:
> 
> - leave the complete set of bcm2837 files in arch/arm and then have one
>   reference from arch/arm64 per .dts that refers to just that file.

So basically do it the other way around.  Would be a bit less messy
indeed.

> - come up with a rule to also build the .dtb files in arch/arm64 when
>   we run 'make dtbs' for arch/arm and leave this file there. The argument
>   that one could use the same dtb with a 32-bit kernel should basically
>   hold true for any arm64 system, it's not specific to rpi-3 really.

Yes, in theory.  No, in practice.  As far I know the rpi3 is the only
64bit soc where a almost identical 32bit version exists, so running
32bit kernels on a 64bit processor actually happens in practice and I
expect this to continue.  If you want create sdcard images which run on
any rpi variant this is pretty much the only reasonable way to do it.

>   We don't normally test 32-bit kernels on 64-bit SoCs because 64-bit
>   kernels are more efficient in a number of ways, and I'm sure there
>   are bugs that prevent some systems from working (aside from how some
>   machines cannot work because they don't have RAM below 4GB), but if
>   this is now something that users are interested in, making it just
>   work seems nicer than having a couple of board specific hacks.

See above, I have my doubts that the user interest in this expands to
other boards.  So I'd tend to pick the first option.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-02  9:14             ` Gerd Hoffmann
@ 2016-06-02  9:53               ` Arnd Bergmann
  2016-06-02 15:11                 ` Gerd Hoffmann
  0 siblings, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-02  9:53 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-arm-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Pawel Moll, Ian Campbell, Russell King, open list, Eric Anholt,
	Rob Herring, linux-rpi-kernel, Kumar Gala

On Thursday, June 2, 2016 11:14:30 AM CEST Gerd Hoffmann wrote:
>   Hi,
> 
> > > Well, it just includes the arm64 version as-is, so we don't have
> > > duplication.  I'm open to suggestions to how handle this better.  
> > > 
> > > Symbolic link?
> > > 
> > > Reference to ../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> > > directly in the Makefile?
> > > 
> > > I've seen arch/arm/boot/dts/Makefile uses globs on *.dts, so I suspect
> > > the later wouldn't be that straight forward.
> > 
> > It's just weird that the arm64 file includes the .dtsi files from arch/arm/
> > and is then again included back from another file there.
> > 
> > I can see two possible ways to handle this better:
> > 
> > - leave the complete set of bcm2837 files in arch/arm and then have one
> >   reference from arch/arm64 per .dts that refers to just that file.
> 
> So basically do it the other way around.  Would be a bit less messy
> indeed.
> 
> > - come up with a rule to also build the .dtb files in arch/arm64 when
> >   we run 'make dtbs' for arch/arm and leave this file there. The argument
> >   that one could use the same dtb with a 32-bit kernel should basically
> >   hold true for any arm64 system, it's not specific to rpi-3 really.
> 
> Yes, in theory.  No, in practice.  As far I know the rpi3 is the only
> 64bit soc where a almost identical 32bit version exists, so running
> 32bit kernels on a 64bit processor actually happens in practice and I
> expect this to continue.  If you want create sdcard images which run on
> any rpi variant this is pretty much the only reasonable way to do it.

I think the Allwinner A64 and the Samsung s5p6818 are other examples
for this, where the initial run of boards all run 32-bit kernels
for much of the same reasons. If users want to run a 32-bit distro
on rpi-3 and on e.g. orange-pi, I don't see why they wouldn't also run
the same binary on A64.

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-02  9:53               ` Arnd Bergmann
@ 2016-06-02 15:11                 ` Gerd Hoffmann
  2016-06-02 15:23                   ` Arnd Bergmann
  0 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-02 15:11 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Pawel Moll, Ian Campbell, Russell King, open list, Eric Anholt,
	Rob Herring, linux-rpi-kernel, Kumar Gala

  Hi,

> > > > Reference to ../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> > > > directly in the Makefile?

Actually tried that, and to my surprise this worked fine for both "make
dtbs" and "make dtbs_install".

So we should just do that I guess ...

> > Yes, in theory.  No, in practice.  As far I know the rpi3 is the only
> > 64bit soc where a almost identical 32bit version exists, so running
> > 32bit kernels on a 64bit processor actually happens in practice and I
> > expect this to continue.  If you want create sdcard images which run on
> > any rpi variant this is pretty much the only reasonable way to do it.
> 
> I think the Allwinner A64 and the Samsung s5p6818 are other examples
> for this, where the initial run of boards all run 32-bit kernels
> for much of the same reasons. If users want to run a 32-bit distro
> on rpi-3 and on e.g. orange-pi, I don't see why they wouldn't also run
> the same binary on A64.

... and others can join the party on a case-by-case basis.

I still expect for the majority of arm64 boards it is not very useful,
so I don't think we should build all of them unconditionally.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm
  2016-06-02 15:11                 ` Gerd Hoffmann
@ 2016-06-02 15:23                   ` Arnd Bergmann
  0 siblings, 0 replies; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-02 15:23 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-arm-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Pawel Moll, Ian Campbell, Russell King, open list, Eric Anholt,
	Rob Herring, linux-rpi-kernel, Kumar Gala

On Thursday, June 2, 2016 5:11:31 PM CEST Gerd Hoffmann wrote:
> 
> > > > > Reference to ../../../arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> > > > > directly in the Makefile?
> 
> Actually tried that, and to my surprise this worked fine for both "make
> dtbs" and "make dtbs_install".
> 
> So we should just do that I guess ...

Right.

> > > Yes, in theory.  No, in practice.  As far I know the rpi3 is the only
> > > 64bit soc where a almost identical 32bit version exists, so running
> > > 32bit kernels on a 64bit processor actually happens in practice and I
> > > expect this to continue.  If you want create sdcard images which run on
> > > any rpi variant this is pretty much the only reasonable way to do it.
> > 
> > I think the Allwinner A64 and the Samsung s5p6818 are other examples
> > for this, where the initial run of boards all run 32-bit kernels
> > for much of the same reasons. If users want to run a 32-bit distro
> > on rpi-3 and on e.g. orange-pi, I don't see why they wouldn't also run
> > the same binary on A64.
> 
> ... and others can join the party on a case-by-case basis.
> 
> I still expect for the majority of arm64 boards it is not very useful,
> so I don't think we should build all of them unconditionally.

Well, they are still controlled by Kconfig symbols. Some of them
are shared between arm and arm64 and you would just get all dtbs in that
case, while other symbols are specific to one of the two.

Just for fun, which machines do we actually get if we decide to
just enter the arch/arm64/boot/dts/ directory in an allmodconfig
build?

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-02  6:45     ` Gerd Hoffmann
@ 2016-06-02 16:25       ` Ray Jui
  2016-06-02 16:48         ` Scott Branden
  2016-06-02 17:30       ` Catalin Marinas
  1 sibling, 1 reply; 70+ messages in thread
From: Ray Jui @ 2016-06-02 16:25 UTC (permalink / raw)
  To: Gerd Hoffmann, Florian Fainelli
  Cc: linux-rpi-kernel, Eric Anholt, Ray Jui, Scott Branden,
	Russell King, Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list



On 6/1/2016 11:45 PM, Gerd Hoffmann wrote:
>>>  config ARCH_BCM2835
>>>  	bool "Broadcom BCM2835 family"
>>> -	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
>>> +	depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 || ARM64
>>
>> Humm, what does that achieve?
>
> Nothing ;)
>
> Slipped through unnoticed, I'll drop it.
>
>>> +config ARCH_BCM
>>> +	bool "Broadcom SoC Support"
>>> +	help
>>> +	  This enables support for Broadcom ARM based SoC chips
>>
>> menuconfig maybe?
>
> There isn't any in arch/arm64/Kconfig.platforms right now, so I didn't
> feel like introducing one.  Also the dependency should have pretty much
> the same effect ...
>
>>> +config ARCH_BCM2835
>>> +	bool "Broadcom BCM2835 family"
>>> +	depends on ARCH_BCM
>>> +	select ARCH_REQUIRE_GPIOLIB
>>> +	select CLKSRC_OF
>>> +	select PINCTRL
>>> +	select PINCTRL_BCM2835
>>> +	select ARM_AMBA
>>> +	select ARM_TIMER_SP804
>>> +	select HAVE_ARM_ARCH_TIMER
>>> +	help
>>> +	  This enables support for the Broadcom BCM2837 SoC.
>>> +	  This SoC is used in the Raspberry Pi 3 device.
>>> +
>>>  config ARCH_BCM_IPROC
>>>  	bool "Broadcom iProc SoC Family"
>>> +	depends on ARCH_BCM
>>
>> Does not seem necessary nor adding anything here.
>
> Added for consistency.  When we add ARCH_BCM all ARCH_BCM_* should
> depend on it ...
>
> We could also do it the other way around: make ARCH_BCM a hidden bool
> and have ARCH_BCM_* select it.

Yes, this is probably better.

ARCH_BCM_IPROC is currently enabled in arch/arm64/configs/defconfig. By 
adding a dependency here without enabling ARCH_BCM in arm64 defconfig, 
this effectively disables ARCH_BCM_IPROC from arm64 defconfig.

>
> cheers,
>   Gerd
>

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-02 16:25       ` Ray Jui
@ 2016-06-02 16:48         ` Scott Branden
  2016-06-02 17:12           ` Gerd Hoffmann
  0 siblings, 1 reply; 70+ messages in thread
From: Scott Branden @ 2016-06-02 16:48 UTC (permalink / raw)
  To: Ray Jui, Gerd Hoffmann, Florian Fainelli
  Cc: linux-rpi-kernel, Eric Anholt, Ray Jui, Scott Branden,
	Russell King, Catalin Marinas, Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list

Reply inline.

On 16-06-02 09:25 AM, Ray Jui wrote:
>
>
> On 6/1/2016 11:45 PM, Gerd Hoffmann wrote:
>>>>  config ARCH_BCM2835
>>>>      bool "Broadcom BCM2835 family"
>>>> -    depends on ARCH_MULTI_V6 || ARCH_MULTI_V7
>>>> +    depends on ARCH_MULTI_V6 || ARCH_MULTI_V7 || ARM64
>>>
>>> Humm, what does that achieve?
>>
>> Nothing ;)
>>
>> Slipped through unnoticed, I'll drop it.
>>
>>>> +config ARCH_BCM
>>>> +    bool "Broadcom SoC Support"
>>>> +    help
>>>> +      This enables support for Broadcom ARM based SoC chips
>>>
>>> menuconfig maybe?
>>
>> There isn't any in arch/arm64/Kconfig.platforms right now, so I didn't
>> feel like introducing one.  Also the dependency should have pretty much
>> the same effect .

No need to add ARCH_BCM
.
>>
>>>> +config ARCH_BCM2835
>>>> +    bool "Broadcom BCM2835 family"
>>>> +    depends on ARCH_BCM
>>>> +    select ARCH_REQUIRE_GPIOLIB
>>>> +    select CLKSRC_OF
>>>> +    select PINCTRL
>>>> +    select PINCTRL_BCM2835
>>>> +    select ARM_AMBA
>>>> +    select ARM_TIMER_SP804
>>>> +    select HAVE_ARM_ARCH_TIMER
>>>> +    help
>>>> +      This enables support for the Broadcom BCM2837 SoC.
>>>> +      This SoC is used in the Raspberry Pi 3 device.
>>>> +
>>>>  config ARCH_BCM_IPROC
>>>>      bool "Broadcom iProc SoC Family"
>>>> +    depends on ARCH_BCM
>>>
>>> Does not seem necessary nor adding anything here.
>>
>> Added for consistency.  When we add ARCH_BCM all ARCH_BCM_* should
>> depend on it ...
>>
>> We could also do it the other way around: make ARCH_BCM a hidden bool
>> and have ARCH_BCM_* select it.
>
> Yes, this is probably better.
>
> ARCH_BCM_IPROC is currently enabled in arch/arm64/configs/defconfig. By
> adding a dependency here without enabling ARCH_BCM in arm64 defconfig,
> this effectively disables ARCH_BCM_IPROC from arm64 defconfig.

There is no need to add ARCH_BCM though?

>
>>
>> cheers,
>>   Gerd
>>

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it
  2016-06-01 21:43 ` [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it Gerd Hoffmann
@ 2016-06-02 16:52   ` Stefan Wahren
  2016-06-02 18:18     ` Eric Anholt
  0 siblings, 1 reply; 70+ messages in thread
From: Stefan Wahren @ 2016-06-02 16:52 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Ulf Hansson, Lee Jones, Pawel Moll, Ian Campbell, Stephen Warren,
	open list:MULTIMEDIA CARD MMC, SECURE DIGITAL SD AND...,
	Russell King, open list, Eric Anholt, Rob Herring, Kumar Gala,
	moderated list:ARM PORT

Hi Gerd,

Am 01.06.2016 um 23:43 schrieb Gerd Hoffmann:
> From: Eric Anholt <eric@anholt.net>
>
> With this we can get wifi (brcmfmac) to probe.  Without it we're stuck
> with timeouts from sdio.c when it tries to set the bus width to 4.

adding a new MMC driver to fix a wifi issue is really weird.

Beside that there are already two MMC drivers (sdhci-bcm2835.c and
sdhci-iproc.c) in the Kernel which are compatible to BCM2835. Why should
we add two new ones?

Stefan

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-02 16:48         ` Scott Branden
@ 2016-06-02 17:12           ` Gerd Hoffmann
  2016-06-02 17:21             ` Scott Branden
  0 siblings, 1 reply; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-02 17:12 UTC (permalink / raw)
  To: Scott Branden
  Cc: Ray Jui, Florian Fainelli, linux-rpi-kernel, Eric Anholt,
	Ray Jui, Scott Branden, Russell King, Catalin Marinas,
	Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list

> There is no need to add ARCH_BCM though?

There are Makefile(s) with

obj-$(CONFIG_ARCH_BCM)          += bcm/

in drivers/pinctrl for example, maybe more, didn't check the whole tree.

So without ARCH_BCM some drivers are dropped from the build ...

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 06/32] arm64: Fix physical to DMA mappings.
  2016-06-01 21:43 ` [PATCH 06/32] arm64: Fix physical to DMA mappings Gerd Hoffmann
@ 2016-06-02 17:20   ` Catalin Marinas
  0 siblings, 0 replies; 70+ messages in thread
From: Catalin Marinas @ 2016-06-02 17:20 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Will Deacon, open list, mzoran,
	moderated list:ARM64 PORT AARCH64 ARCHITECTURE

On Wed, Jun 01, 2016 at 11:43:15PM +0200, Gerd Hoffmann wrote:
> From: mzoran <mzoran@crowfest.net>
> 
> Gets USB and networking to work on Raspberry Pi 3 in 64 bit.
> 
> created by mzoran@crowfest.net
> 
> [ kraxel: some cleanups ]
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  arch/arm64/include/asm/dma-mapping.h | 73 ++++++++++++++++++++++++++++++++++--
>  arch/arm64/include/asm/memory.h      |  8 ++++

We had a similar patch already here:

http://article.gmane.org/gmane.linux.ports.arm.kernel/500565

Maybe you need some alignment with other contributing RPi3 patches.

> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 72a3025..ab4c65e 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -226,6 +226,14 @@ static inline void *phys_to_virt(phys_addr_t x)
>  #endif
>  #endif
>  
> +#ifndef __virt_to_bus
> +#define __virt_to_bus	__virt_to_phys
> +#define __bus_to_virt	__phys_to_virt
> +#define __pfn_to_bus(x)	__pfn_to_phys(x)
> +#define __bus_to_pfn(x)	__phys_to_pfn(x)
> +#endif

Do you really need these macros? What's with the #ifndef, anything going
to override them?

-- 
Catalin

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-02 17:12           ` Gerd Hoffmann
@ 2016-06-02 17:21             ` Scott Branden
  2016-06-02 17:36               ` Florian Fainelli
  0 siblings, 1 reply; 70+ messages in thread
From: Scott Branden @ 2016-06-02 17:21 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Ray Jui, Florian Fainelli, linux-rpi-kernel, Eric Anholt,
	Ray Jui, Scott Branden, Russell King, Catalin Marinas,
	Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list



On 16-06-02 10:12 AM, Gerd Hoffmann wrote:
>> There is no need to add ARCH_BCM though?
>
> There are Makefile(s) with
>
> obj-$(CONFIG_ARCH_BCM)          += bcm/
>
> in drivers/pinctrl for example, maybe more, didn't check the whole tree.
>
> So without ARCH_BCM some drivers are dropped from the build ...

I see that now.  Quite bizarre how the NS2 pinctl driver (used on a 
arm64 SoC) gets built right now....

Yes, adding the select with hidden option seems like what needs to be 
done.  The ARM Maintainers did not like multi-level ARCH_BCM being added 
in the arm64 Kconfig previously so we dropped it.

>
> cheers,
>    Gerd
>
Thanks,
  Scott

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-02  6:45     ` Gerd Hoffmann
  2016-06-02 16:25       ` Ray Jui
@ 2016-06-02 17:30       ` Catalin Marinas
  1 sibling, 0 replies; 70+ messages in thread
From: Catalin Marinas @ 2016-06-02 17:30 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: Florian Fainelli, Scott Branden, Will Deacon, Russell King,
	open list, Eric Anholt,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	linux-rpi-kernel, Ray Jui, moderated list:ARM SUB-ARCHITECTURES

On Thu, Jun 02, 2016 at 08:45:36AM +0200, Gerd Hoffmann wrote:
> > > +config ARCH_BCM2835
> > > +	bool "Broadcom BCM2835 family"
> > > +	depends on ARCH_BCM
> > > +	select ARCH_REQUIRE_GPIOLIB
> > > +	select CLKSRC_OF
> > > +	select PINCTRL
> > > +	select PINCTRL_BCM2835
> > > +	select ARM_AMBA
> > > +	select ARM_TIMER_SP804
> > > +	select HAVE_ARM_ARCH_TIMER
> > > +	help
> > > +	  This enables support for the Broadcom BCM2837 SoC.
> > > +	  This SoC is used in the Raspberry Pi 3 device.
> > > +
> > >  config ARCH_BCM_IPROC
> > >  	bool "Broadcom iProc SoC Family"
> > > +	depends on ARCH_BCM
> > 
> > Does not seem necessary nor adding anything here.
> 
> Added for consistency.  When we add ARCH_BCM all ARCH_BCM_* should
> depend on it ...

For arm64, I prefer to keep Kconfig.platforms to SoC families only. I
don't think we have any single-SoC Kconfig entry left now.

-- 
Catalin

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 01/32] arm64: Add platform selection for BCM2835.
  2016-06-02 17:21             ` Scott Branden
@ 2016-06-02 17:36               ` Florian Fainelli
  0 siblings, 0 replies; 70+ messages in thread
From: Florian Fainelli @ 2016-06-02 17:36 UTC (permalink / raw)
  To: Scott Branden, Gerd Hoffmann
  Cc: Ray Jui, Florian Fainelli, linux-rpi-kernel, Eric Anholt,
	Ray Jui, Scott Branden, Russell King, Catalin Marinas,
	Will Deacon,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	moderated list:ARM SUB-ARCHITECTURES, open list

On 06/02/2016 10:21 AM, Scott Branden wrote:
> 
> 
> On 16-06-02 10:12 AM, Gerd Hoffmann wrote:
>>> There is no need to add ARCH_BCM though?
>>
>> There are Makefile(s) with
>>
>> obj-$(CONFIG_ARCH_BCM)          += bcm/
>>
>> in drivers/pinctrl for example, maybe more, didn't check the whole tree.
>>
>> So without ARCH_BCM some drivers are dropped from the build ...
> 
> I see that now.  Quite bizarre how the NS2 pinctl driver (used on a
> arm64 SoC) gets built right now....
> 
> Yes, adding the select with hidden option seems like what needs to be
> done.  The ARM Maintainers did not like multi-level ARCH_BCM being added
> in the arm64 Kconfig previously so we dropped it.

We should always recusrse into that directory and build the respective
pinctrl drivers within drivers/pinctrl/bcm, only for the enabled
platforms, it makes no sense to have this kind of config symbol gating that.

I can submit a patch doing just that unless somebody wants to do it as
part of this patch series.
-- 
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ.
  2016-06-02  0:50   ` Jason Cooper
@ 2016-06-02 18:06     ` Eric Anholt
  0 siblings, 0 replies; 70+ messages in thread
From: Eric Anholt @ 2016-06-02 18:06 UTC (permalink / raw)
  To: Jason Cooper, Gerd Hoffmann
  Cc: linux-rpi-kernel, Thomas Gleixner, Marc Zyngier, Stephen Warren,
	Lee Jones, open list:IRQCHIP DRIVERS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

[-- Attachment #1: Type: text/plain, Size: 509 bytes --]

Jason Cooper <jason@lakedaemon.net> writes:

> Hey Gerd,
>
> On Wed, Jun 01, 2016 at 11:43:12PM +0200, Gerd Hoffmann wrote:
>> From: Eric Anholt <eric@anholt.net>
>> 
>> This is equivalent and works for arm64 as well.
>> 
>> Signed-off-by: Eric Anholt <eric@anholt.net>
>> ---
>
> I don't mind taking this, or Eric's V2 resend.  However, the commit
> message needs a rewrite.

Can you clarify what you don't like about it or suggest replacement
wording?  This is the first concern I've seen.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller.
  2016-06-01 22:18   ` Arnd Bergmann
@ 2016-06-02 18:12     ` Eric Anholt
  2016-06-03  8:42       ` Arnd Bergmann
  2016-06-21 12:33     ` Gerd Hoffmann
  1 sibling, 1 reply; 70+ messages in thread
From: Eric Anholt @ 2016-06-02 18:12 UTC (permalink / raw)
  To: Arnd Bergmann, Gerd Hoffmann
  Cc: linux-rpi-kernel, Ulf Hansson, Stephen Warren, Lee Jones,
	open list, open list:MULTIMEDIA CARD (MMC),
	SECURE DIGITAL (SD) AND...,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

[-- Attachment #1: Type: text/plain, Size: 850 bytes --]

Arnd Bergmann <arnd@arndb.de> writes:

> On Wednesday, June 1, 2016 11:43:30 PM CEST Gerd Hoffmann wrote:
>> +	/* Parse OF address directly to get the physical address for
>> +	 * DMA to our registers.
>> +	 */
>> +	host->phys_addr = be32_to_cpup(of_get_address(pdev->dev.of_node, 0,
>> +						      NULL, NULL));
>
> This looks broken on 64-bit systems when #address-cells=<2>, or if there
> is an intermediate bus with a non-empty ranges property.
>
> What's wrong with platform_get_resource(pdev, IORESOURCE_MEM, 0)?

I'll get to the rest of the review later, but this is a weird pattern
that we have in several bcm2835-related drivers.

We need the address as seen by the DMA controller, not the address from
the ARM's perspective (which is offset by the dma-ranges DT property).
This is the way that people have figured out to get that address.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it
  2016-06-02 16:52   ` Stefan Wahren
@ 2016-06-02 18:18     ` Eric Anholt
  2016-06-02 19:09       ` Stefan Wahren
  0 siblings, 1 reply; 70+ messages in thread
From: Eric Anholt @ 2016-06-02 18:18 UTC (permalink / raw)
  To: Stefan Wahren, Gerd Hoffmann
  Cc: linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Ulf Hansson, Lee Jones, Pawel Moll, Ian Campbell, Stephen Warren,
	open list:MULTIMEDIA CARD MMC, SECURE DIGITAL SD AND...,
	Russell King, open list, Rob Herring, Kumar Gala,
	moderated list:ARM PORT

[-- Attachment #1: Type: text/plain, Size: 670 bytes --]

Stefan Wahren <stefan.wahren@i2se.com> writes:

> Hi Gerd,
>
> Am 01.06.2016 um 23:43 schrieb Gerd Hoffmann:
>> From: Eric Anholt <eric@anholt.net>
>>
>> With this we can get wifi (brcmfmac) to probe.  Without it we're stuck
>> with timeouts from sdio.c when it tries to set the bus width to 4.
>
> adding a new MMC driver to fix a wifi issue is really weird.
>
> Beside that there are already two MMC drivers (sdhci-bcm2835.c and
> sdhci-iproc.c) in the Kernel which are compatible to BCM2835. Why should
> we add two new ones?

Despite the fact that this is my commit, I don't think it should be
merged.  We should figure out why sdhci-iproc.c isn't working, instead.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 10/32] don't force serial pins to uart0
  2016-06-01 22:19   ` Arnd Bergmann
@ 2016-06-02 18:19     ` Eric Anholt
  0 siblings, 0 replies; 70+ messages in thread
From: Eric Anholt @ 2016-06-02 18:19 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Gerd Hoffmann, linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Lee Jones, Pawel Moll, Ian Campbell, Stephen Warren,
	Russell King, open list, Rob Herring, Kumar Gala

[-- Attachment #1: Type: text/plain, Size: 548 bytes --]

Arnd Bergmann <arnd@arndb.de> writes:

> On Wednesday, June 1, 2016 11:43:19 PM CEST Gerd Hoffmann wrote:
>> From: Eric Anholt <eric@anholt.net>
>> 
>> ---
>> 
>
> No signoff or description?

This commit should not have been sent out as is.  Gerd took a bunch of
messy commits from my trees that were intended to be squashed (or never
sent out at all!) and picked them and sent them out.

It's nice though that people are paying attention to this series now.
Several of these patches had been sent before and got basically silence.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it
  2016-06-02 18:18     ` Eric Anholt
@ 2016-06-02 19:09       ` Stefan Wahren
  2016-06-02 20:03         ` Gerd Hoffmann
  2016-06-02 21:40         ` Eric Anholt
  0 siblings, 2 replies; 70+ messages in thread
From: Stefan Wahren @ 2016-06-02 19:09 UTC (permalink / raw)
  To: Gerd Hoffmann, Eric Anholt
  Cc: Russell King, Lee Jones, Pawel Moll, Kumar Gala, Rob Herring,
	Ian Campbell, moderated list:ARM PORT, Ulf Hansson, open list,
	open list:MULTIMEDIA CARD MMC, SECURE DIGITAL SD AND...,
	Stephen Warren, linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

Hi Eric,

> Eric Anholt <eric@anholt.net> hat am 2. Juni 2016 um 20:18 geschrieben:
> 
> 
> Stefan Wahren <stefan.wahren@i2se.com> writes:
> 
> > Hi Gerd,
> >
> > Am 01.06.2016 um 23:43 schrieb Gerd Hoffmann:
> >> From: Eric Anholt <eric@anholt.net>
> >>
> >> With this we can get wifi (brcmfmac) to probe.  Without it we're stuck
> >> with timeouts from sdio.c when it tries to set the bus width to 4.
> >
> > adding a new MMC driver to fix a wifi issue is really weird.
> >
> > Beside that there are already two MMC drivers (sdhci-bcm2835.c and
> > sdhci-iproc.c) in the Kernel which are compatible to BCM2835. Why should
> > we add two new ones?
> 
> Despite the fact that this is my commit, I don't think it should be
> merged.  We should figure out why sdhci-iproc.c isn't working, instead.

so it doesn't work with sdhci-bcm2835 on RPi 3, too?

I plan to send a patch series to remove sdhci-bcm2835.

Stefan

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it
  2016-06-02 19:09       ` Stefan Wahren
@ 2016-06-02 20:03         ` Gerd Hoffmann
  2016-06-02 21:40         ` Eric Anholt
  1 sibling, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-02 20:03 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Eric Anholt, Russell King, Lee Jones, Pawel Moll, Kumar Gala,
	Rob Herring, Ian Campbell, moderated list:ARM PORT, Ulf Hansson,
	open list, open list:MULTIMEDIA CARD MMC,
	SECURE DIGITAL SD AND...,
	Stephen Warren, linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

  Hi,

> > Despite the fact that this is my commit, I don't think it should be
> > merged.  We should figure out why sdhci-iproc.c isn't working, instead.
> 
> so it doesn't work with sdhci-bcm2835 on RPi 3, too?

With sdhci-bcm2835 rpi3 wifi doesn't work for me.
I didn't try sdhci-iproc yet.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it
  2016-06-02 19:09       ` Stefan Wahren
  2016-06-02 20:03         ` Gerd Hoffmann
@ 2016-06-02 21:40         ` Eric Anholt
  1 sibling, 0 replies; 70+ messages in thread
From: Eric Anholt @ 2016-06-02 21:40 UTC (permalink / raw)
  To: Stefan Wahren, Gerd Hoffmann
  Cc: Russell King, Lee Jones, Pawel Moll, Kumar Gala, Rob Herring,
	Ian Campbell, moderated list:ARM PORT, Ulf Hansson, open list,
	open list:MULTIMEDIA CARD MMC, SECURE DIGITAL SD AND...,
	Stephen Warren, linux-rpi-kernel, Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS

[-- Attachment #1: Type: text/plain, Size: 964 bytes --]

Stefan Wahren <stefan.wahren@i2se.com> writes:

> Hi Eric,
>
>> Eric Anholt <eric@anholt.net> hat am 2. Juni 2016 um 20:18 geschrieben:
>> 
>> 
>> Stefan Wahren <stefan.wahren@i2se.com> writes:
>> 
>> > Hi Gerd,
>> >
>> > Am 01.06.2016 um 23:43 schrieb Gerd Hoffmann:
>> >> From: Eric Anholt <eric@anholt.net>
>> >>
>> >> With this we can get wifi (brcmfmac) to probe.  Without it we're stuck
>> >> with timeouts from sdio.c when it tries to set the bus width to 4.
>> >
>> > adding a new MMC driver to fix a wifi issue is really weird.
>> >
>> > Beside that there are already two MMC drivers (sdhci-bcm2835.c and
>> > sdhci-iproc.c) in the Kernel which are compatible to BCM2835. Why should
>> > we add two new ones?
>> 
>> Despite the fact that this is my commit, I don't think it should be
>> merged.  We should figure out why sdhci-iproc.c isn't working, instead.
>
> so it doesn't work with sdhci-bcm2835 on RPi 3, too?

Correct.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller.
  2016-06-02 18:12     ` Eric Anholt
@ 2016-06-03  8:42       ` Arnd Bergmann
  0 siblings, 0 replies; 70+ messages in thread
From: Arnd Bergmann @ 2016-06-03  8:42 UTC (permalink / raw)
  To: Eric Anholt
  Cc: Gerd Hoffmann, linux-rpi-kernel, Ulf Hansson, Stephen Warren,
	Lee Jones, open list, open list:MULTIMEDIA CARD (MMC),
	SECURE DIGITAL (SD) AND...,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE

On Thursday, June 2, 2016 11:12:38 AM CEST Eric Anholt wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
> 
> > On Wednesday, June 1, 2016 11:43:30 PM CEST Gerd Hoffmann wrote:
> >> +    /* Parse OF address directly to get the physical address for
> >> +     * DMA to our registers.
> >> +     */
> >> +    host->phys_addr = be32_to_cpup(of_get_address(pdev->dev.of_node, 0,
> >> +                                                  NULL, NULL));
> >
> > This looks broken on 64-bit systems when #address-cells=<2>, or if there
> > is an intermediate bus with a non-empty ranges property.
> >
> > What's wrong with platform_get_resource(pdev, IORESOURCE_MEM, 0)?
> 
> I'll get to the rest of the review later, but this is a weird pattern
> that we have in several bcm2835-related drivers.
> 
> We need the address as seen by the DMA controller, not the address from
> the ARM's perspective (which is offset by the dma-ranges DT property).
> This is the way that people have figured out to get that address.

I see. This is indeed a bit tricky, as there is no easy way to know
how the dmaengine is wired up to the slave. A correct solution is
probably to follow the 'dma-ranges' up from the master to the common
parent and then follow the 'ranges' back to the slave, but that
requires coming up with a new exported function.

It's perhaps good enough in the meantime to read out the address from
the slave directly, but you should not assume that the first
cell has the complete information and instead should at least
evaluate #address-cells.

	Arnd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 20/32] dt-bindings: Add binding for brcm,bcm2835-sdhost.
  2016-06-01 21:43 ` [PATCH 20/32] dt-bindings: Add binding for brcm,bcm2835-sdhost Gerd Hoffmann
@ 2016-06-06 13:12   ` Rob Herring
  0 siblings, 0 replies; 70+ messages in thread
From: Rob Herring @ 2016-06-06 13:12 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Eric Anholt, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Stephen Warren, Lee Jones,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

On Wed, Jun 01, 2016 at 11:43:29PM +0200, Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> This is the other SD controller on the platform, which can be swapped
> to the role of SD card host using pin muxing.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> ---
>  .../devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt |  3 +++
>  .../bindings/mmc/brcm,bcm2835-sdhost.txt           | 24 ++++++++++++++++++++++
>  2 files changed, 27 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
> 
> diff --git a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt
> index 59476fb..3cc74e2 100644
> --- a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt
> +++ b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhci.txt
> @@ -15,4 +15,7 @@ sdhci: sdhci {
>  	interrupts = <2 30>;
>  	clocks = <&clk_mmc>;
>  	bus-width = <4>;
> +	dmas = <&dma 13>,
> +	       <&dma 13>;
> +	dma-names = "tx", "rx";

This looks unrelated. Plus SDHCI implies internal DMA master generally, 
so is external DMA really supported?

>  };
> diff --git a/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
> new file mode 100644
> index 0000000..074992c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/brcm,bcm2835-sdhost.txt
> @@ -0,0 +1,24 @@
> +Broadcom BCM2835 SDHOST controller
> +
> +This file documents differences between the core properties described
> +by mmc.txt and the properties that represent the BCM2835 controller.
> +
> +Required properties:
> +- compatible: Should be "brcm,bcm2835-sdhci".

sdhost?

> +- clocks: The clock feeding the SDHOST controller.

reg, interrupts missing.

> +
> +Optional properties:
> +- dmas: DMA channels for read and write.
> +          See Documentation/devicetree/bindings/dma/dma.txt for details

dma-names?

> +
> +Example:
> +
> +sdhost: sdhost@7e202000 {
> +	compatible = "brcm,bcm2835-sdhost";
> +	reg = <0x7e202000 0x100>;
> +	interrupts = <2 24>;
> +	clocks = <&clocks BCM2835_CLOCK_VPU>;
> +	dmas = <&dma 13>,
> +	       <&dma 13>;
> +	dma-names = "tx", "rx";
> +};
> -- 
> 1.8.3.1
> 

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander.
  2016-06-01 21:43 ` [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander Gerd Hoffmann
@ 2016-06-06 23:50   ` Eric Anholt
  2016-06-07  0:02   ` Florian Fainelli
  2016-06-08  9:10   ` Linus Walleij
  2 siblings, 0 replies; 70+ messages in thread
From: Eric Anholt @ 2016-06-06 23:50 UTC (permalink / raw)
  To: Gerd Hoffmann, linux-rpi-kernel
  Cc: Florian Fainelli, Ray Jui, Scott Branden, Rob Herring,
	Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon, Linus Walleij, Alexandre Courbot,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list, open list:GPIO SUBSYSTEM

[-- Attachment #1: Type: text/plain, Size: 744 bytes --]

Gerd Hoffmann <kraxel@redhat.com> writes:

> From: Eric Anholt <eric@anholt.net>
>
> This commit needs to be split up and cleaned up.  Also we should add
> interrupt support before pushing upstream.
>
> Signed-off-by: Eric Anholt <eric@anholt.net>

OK, I've confirmed with the firmware maintainers: We really can't drive
this natively from Linux.  The firmware is polling one of the fxl6408's
pins 10 times a second for detecting under-voltage, so if we also try to
drive it we'll end up smashing each others' I2C transactions.  We'll
need to do a GPIO driver using the GET/SET_GPIO_STATE firmware calls,
instead.  Unfortunately, we don't have a direction-setting API for that
at the moment, but it'll at least let us read the HDMI HPD signal.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander.
  2016-06-01 21:43 ` [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander Gerd Hoffmann
  2016-06-06 23:50   ` Eric Anholt
@ 2016-06-07  0:02   ` Florian Fainelli
  2016-06-08  9:10   ` Linus Walleij
  2 siblings, 0 replies; 70+ messages in thread
From: Florian Fainelli @ 2016-06-07  0:02 UTC (permalink / raw)
  To: Gerd Hoffmann, linux-rpi-kernel
  Cc: Eric Anholt, Ray Jui, Scott Branden, Rob Herring, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Catalin Marinas,
	Will Deacon, Linus Walleij, Alexandre Courbot,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list, open list:GPIO SUBSYSTEM

On 06/01/2016 02:43 PM, Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> This commit needs to be split up and cleaned up.  Also we should add
> interrupt support before pushing upstream.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>
> 
> Conflicts:
> 	arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> ---
>  arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts |  16 ++
>  drivers/gpio/Kconfig                             |   6 +
>  drivers/gpio/Makefile                            |   1 +
>  drivers/gpio/gpio-fxl6408.c                      | 244 +++++++++++++++++++++++
>  4 files changed, 267 insertions(+)
>  create mode 100644 drivers/gpio/gpio-fxl6408.c
> 
> diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> index 099dd48d..4bc191e 100644
> --- a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> +++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b.dts
> @@ -39,3 +39,19 @@
>  &hdmi {
>  	hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
>  };
> +
> +/* Connect the GPIO expander to I2C1 */
> +&i2c0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&i2c0_gpio44>;
> +
> +	gpio_expander: gpio@43 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +		reg = <0x43>;
> +		compatible = "fcs,fxl6408";
> +	};
> +};
> +
> +bt {
> +};
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 48da857..34056cd 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -665,6 +665,12 @@ config GPIO_ADNP
>  	  enough to represent all pins, but the driver will assume a
>  	  register layout for 64 pins (8 registers).
>  
> +config GPIO_FXL6408
> +	tristate "FXL6408 I2C GPIO expander"
> +	help
> +	  This option enables support for 8 GPIOs found
> +	  on the Fairchild Semiconductor FXL6408.
> +
>  config GPIO_MAX7300
>  	tristate "Maxim MAX7300 GPIO expander"
>  	select GPIO_MAX730X
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index 991598e..59a25ef 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -43,6 +43,7 @@ obj-$(CONFIG_GPIO_EM)		+= gpio-em.o
>  obj-$(CONFIG_GPIO_EP93XX)	+= gpio-ep93xx.o
>  obj-$(CONFIG_GPIO_ETRAXFS)	+= gpio-etraxfs.o
>  obj-$(CONFIG_GPIO_F7188X)	+= gpio-f7188x.o
> +obj-$(CONFIG_GPIO_FXL6408)	+= gpio-fxl6408.o
>  obj-$(CONFIG_GPIO_GE_FPGA)	+= gpio-ge.o
>  obj-$(CONFIG_GPIO_GRGPIO)	+= gpio-grgpio.o
>  obj-$(CONFIG_GPIO_ICH)		+= gpio-ich.o
> diff --git a/drivers/gpio/gpio-fxl6408.c b/drivers/gpio/gpio-fxl6408.c
> new file mode 100644
> index 0000000..02b2816
> --- /dev/null
> +++ b/drivers/gpio/gpio-fxl6408.c
> @@ -0,0 +1,244 @@
> +/*
> + *  Copyright (C) 2016 Broadcom Limited.

BTW, since you need to resubmit that, the new Copyright should be
without the "Limited", just Broadcom, which covers all entities.
-- 
Florian

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander.
  2016-06-01 21:43 ` [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander Gerd Hoffmann
  2016-06-06 23:50   ` Eric Anholt
  2016-06-07  0:02   ` Florian Fainelli
@ 2016-06-08  9:10   ` Linus Walleij
  2016-06-09 17:22     ` Eric Anholt
  2 siblings, 1 reply; 70+ messages in thread
From: Linus Walleij @ 2016-06-08  9:10 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Eric Anholt, Florian Fainelli, Ray Jui,
	Scott Branden, Rob Herring, Pawel Moll, Mark Rutland,
	Ian Campbell, Kumar Gala, Catalin Marinas, Will Deacon,
	Alexandre Courbot,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list, open list:GPIO SUBSYSTEM

On Wed, Jun 1, 2016 at 11:43 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:

> +#define FXL6408_OUTPUT                 0x05
> +/* Bits here make the output High-Z, instead of the OUTPUT value. */
> +#define FXL6408_OUTPUT_HIGH_Z          0x07
(...)
> +       /* Disable High-Z of outputs, so that our OUTPUT updates
> +        * actually take effect.
> +        */
> +       i2c_smbus_write_byte_data(client, FXL6408_OUTPUT_HIGH_Z, 0);

High-Z is probably the same as open drain right? And if not open drain,
it is push-pull.

So you want to implement .set_single_ended() for configuring the lines in
"high-z", i.e. open drain output mode.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander.
  2016-06-08  9:10   ` Linus Walleij
@ 2016-06-09 17:22     ` Eric Anholt
  0 siblings, 0 replies; 70+ messages in thread
From: Eric Anholt @ 2016-06-09 17:22 UTC (permalink / raw)
  To: Linus Walleij, Gerd Hoffmann
  Cc: linux-rpi-kernel, Florian Fainelli, Ray Jui, Scott Branden,
	Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Catalin Marinas, Will Deacon, Alexandre Courbot,
	open list:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM64 PORT (AARCH64 ARCHITECTURE),
	open list, open list:GPIO SUBSYSTEM

[-- Attachment #1: Type: text/plain, Size: 868 bytes --]

Linus Walleij <linus.walleij@linaro.org> writes:

> On Wed, Jun 1, 2016 at 11:43 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
>> +#define FXL6408_OUTPUT                 0x05
>> +/* Bits here make the output High-Z, instead of the OUTPUT value. */
>> +#define FXL6408_OUTPUT_HIGH_Z          0x07
> (...)
>> +       /* Disable High-Z of outputs, so that our OUTPUT updates
>> +        * actually take effect.
>> +        */
>> +       i2c_smbus_write_byte_data(client, FXL6408_OUTPUT_HIGH_Z, 0);
>
> High-Z is probably the same as open drain right? And if not open drain,
> it is push-pull.
>
> So you want to implement .set_single_ended() for configuring the lines in
> "high-z", i.e. open drain output mode.

I'll keep this in mind for whenever I end up writing my next GPIO
driver, but this one is dead for now (not actually usable because of the
closed firmware).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller.
  2016-06-01 22:18   ` Arnd Bergmann
  2016-06-02 18:12     ` Eric Anholt
@ 2016-06-21 12:33     ` Gerd Hoffmann
  1 sibling, 0 replies; 70+ messages in thread
From: Gerd Hoffmann @ 2016-06-21 12:33 UTC (permalink / raw)
  To: linux-kernel

  Hi,

> > +	mmiowb();
> > +}
> 
> What is the barrier for? Same question for all the other instances

No idea.  Removed them all, seems to work fine still.
Guess writel() & friends have the needed barriers on arm?

> > +
> > +static void bcm2835_sdhost_reset(struct mmc_host *mmc)
> > +{
> > +	struct bcm2835_host *host = mmc_priv(mmc);
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&host->lock, flags);
> > +	bcm2835_sdhost_reset_internal(host);
> > +	spin_unlock_irqrestore(&host->lock, flags);
> > +}
> 
> The spinlock seems to only protect the reset from happening concurrently
> with bcm2835_sdhost_dma_complete() here. So if you ensure that this
> function is no longer pending, you can probably use msleep() above.

There is also a tasklet.  And IRQs.  But bcm2835_sdhost_reset_internal
clears hcfg (temporately), so IRQs shouldn't be a problem I think.  So how
about this?

@@ -334,9 +334,10 @@ static void bcm2835_sdhost_reset(struct mmc_host *mmc)
        struct bcm2835_host *host = mmc_priv(mmc);
        unsigned long flags;
 
-       spin_lock_irqsave(&host->lock, flags);
+       if (host->dma_chan)
+               dmaengine_terminate_sync(host->dma_chan);
+       tasklet_kill(&host->finish_tasklet);
        bcm2835_sdhost_reset_internal(host);
-       spin_unlock_irqrestore(&host->lock, flags);
 }
 

> > +	if (IS_ERR_OR_NULL(host->dma_chan_tx) ||
> > +	    IS_ERR_OR_NULL(host->dma_chan_rx)) {
> > +		pr_err("%s: unable to initialise DMA channels. Falling back to PIO\n",
> > +		       mmc_hostname(mmc));
> 
> When are these ever NULL?

When there are no dma channels configured in the device tree.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 28/32] i2c: bcm2835: Set up the rising/falling edge delays.
  2016-06-01 21:43 ` [PATCH 28/32] i2c: bcm2835: Set up the rising/falling edge delays Gerd Hoffmann
@ 2016-07-22  7:26   ` Wolfram Sang
  0 siblings, 0 replies; 70+ messages in thread
From: Wolfram Sang @ 2016-07-22  7:26 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Eric Anholt, Stephen Warren, Lee Jones,
	open list:I2C SUBSYSTEM,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

[-- Attachment #1: Type: text/plain, Size: 492 bytes --]

On Wed, Jun 01, 2016 at 11:43:37PM +0200, Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> We were leaving them in the power on state (or the state the firmware
> had set up for some client, if we were taking over from them).  The
> boot state was 30 core clocks, when we actually want to sample some
> time after (to make sure that the new input bit has actually arrived).
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>

Gerd, your Signed-off is missing here.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

* Re: [PATCH 24/32] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock
  2016-06-01 21:43 ` [PATCH 24/32] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock Gerd Hoffmann
@ 2016-07-22  7:26   ` Wolfram Sang
  0 siblings, 0 replies; 70+ messages in thread
From: Wolfram Sang @ 2016-07-22  7:26 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: linux-rpi-kernel, Eric Anholt, Stephen Warren, Lee Jones,
	open list:I2C SUBSYSTEM,
	moderated list:BROADCOM BCM2835 ARM ARCHITECTURE, open list

[-- Attachment #1: Type: text/plain, Size: 290 bytes --]

On Wed, Jun 01, 2016 at 11:43:33PM +0200, Gerd Hoffmann wrote:
> From: Eric Anholt <eric@anholt.net>
> 
> Fixes dmesg spam when we just need to wait a moment for the clock
> driver to probe.
> 
> Signed-off-by: Eric Anholt <eric@anholt.net>

I applied Eric's original patch now.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 70+ messages in thread

end of thread, other threads:[~2016-07-22  7:26 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1464817421-8519-1-git-send-email-kraxel@redhat.com>
2016-06-01 21:43 ` [PATCH 01/32] arm64: Add platform selection for BCM2835 Gerd Hoffmann
2016-06-01 21:49   ` Florian Fainelli
2016-06-02  6:45     ` Gerd Hoffmann
2016-06-02 16:25       ` Ray Jui
2016-06-02 16:48         ` Scott Branden
2016-06-02 17:12           ` Gerd Hoffmann
2016-06-02 17:21             ` Scott Branden
2016-06-02 17:36               ` Florian Fainelli
2016-06-02 17:30       ` Catalin Marinas
2016-06-01 21:43 ` [PATCH 02/32] arm64: Add BCM2835 support to the defconfig Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 03/32] irqchip: bcm2835: Avoid arch/arm-specific handle_IRQ Gerd Hoffmann
2016-06-02  0:50   ` Jason Cooper
2016-06-02 18:06     ` Eric Anholt
2016-06-01 21:43 ` [PATCH 04/32] dt-bindings: Add root properties for Raspberry Pi 3 Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 05/32] ARM: bcm2835: Add devicetree for the " Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 06/32] arm64: Fix physical to DMA mappings Gerd Hoffmann
2016-06-02 17:20   ` Catalin Marinas
2016-06-01 21:43 ` [PATCH 07/32] ARM: bcm2835: dt: Add the ethernet to the device trees Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 08/32] ARM: bcm2837: " Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 09/32] bcm2837-rpi-3-b.dts for 32bit arm Gerd Hoffmann
2016-06-01 22:00   ` Arnd Bergmann
2016-06-01 22:30     ` Eric Anholt
2016-06-01 22:39       ` Arnd Bergmann
2016-06-02  6:56         ` Gerd Hoffmann
2016-06-02  7:24           ` Arnd Bergmann
2016-06-02  9:14             ` Gerd Hoffmann
2016-06-02  9:53               ` Arnd Bergmann
2016-06-02 15:11                 ` Gerd Hoffmann
2016-06-02 15:23                   ` Arnd Bergmann
2016-06-01 21:43 ` [PATCH 10/32] don't force serial pins to uart0 Gerd Hoffmann
2016-06-01 22:19   ` Arnd Bergmann
2016-06-02 18:19     ` Eric Anholt
2016-06-01 21:43 ` [PATCH 11/32] ARM: bcm2835: Define standard pinctrl groups in the gpio node Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 12/32] ARM: bcm2835: Replace alt0/i2s_alt[02] with standard groups Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 13/32] bcm2837-rpi-3-b.dts: add gpio Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 14/32] bcm2837-rpi-3-b.dts: vc4 hdmi fixup Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 15/32] ARM: bcm2835: Move the emmc pin group to bcm283x.dtsi Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 16/32] bcm2837-rpi-3-b.dts: move the emmc pin group Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 17/32] ARM: bcm2835: Add a group for mapping pins 48-53 to sdhost Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 18/32] ARM: bcm2835: Move most RPi default pin groups to their devices Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 19/32] bcm2837-rpi-3-b.dts: move " Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 20/32] dt-bindings: Add binding for brcm,bcm2835-sdhost Gerd Hoffmann
2016-06-06 13:12   ` Rob Herring
2016-06-01 21:43 ` [PATCH 21/32] mmc: bcm2835-sdhost: Add new driver for the internal SD controller Gerd Hoffmann
2016-06-01 22:18   ` Arnd Bergmann
2016-06-02 18:12     ` Eric Anholt
2016-06-03  8:42       ` Arnd Bergmann
2016-06-21 12:33     ` Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 22/32] ARM: bcm2835: Include SDHOST in the device tree Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 23/32] ARM: bcm2835: Enable SDHOST by default Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 24/32] i2c: bcm2835: Don't complain on -EPROBE_DEFER from getting our clock Gerd Hoffmann
2016-07-22  7:26   ` Wolfram Sang
2016-06-01 21:43 ` [PATCH 25/32] dt-gpio-fix Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 26/32] enable uart1 on the BT pins Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 27/32] gpio: Add support for the FXL6408 GPIO expander Gerd Hoffmann
2016-06-06 23:50   ` Eric Anholt
2016-06-07  0:02   ` Florian Fainelli
2016-06-08  9:10   ` Linus Walleij
2016-06-09 17:22     ` Eric Anholt
2016-06-01 21:43 ` [PATCH 28/32] i2c: bcm2835: Set up the rising/falling edge delays Gerd Hoffmann
2016-07-22  7:26   ` Wolfram Sang
2016-06-01 21:43 ` [PATCH 29/32] ARM: bcm2835: Use i2c-gpio for the expander, instead Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 30/32] ARM: bcm2835: Add a new EMMC pin group from the downstream tree Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 31/32] enable wireless Gerd Hoffmann
2016-06-01 21:43 ` [PATCH 32/32] mmc: bcm2835: Import bcm2835-mmc and switch to it Gerd Hoffmann
2016-06-02 16:52   ` Stefan Wahren
2016-06-02 18:18     ` Eric Anholt
2016-06-02 19:09       ` Stefan Wahren
2016-06-02 20:03         ` Gerd Hoffmann
2016-06-02 21:40         ` Eric Anholt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).