Browse Source

fix wifi on cubox-i with patches from rmk

Waldemar Brodkorb 11 years ago
parent
commit
f0b1dabd8b
1 changed files with 569 additions and 0 deletions
  1. 569 0
      target/arm/cubox-i/patches/3.16/rmk-wifi.patch

+ 569 - 0
target/arm/cubox-i/patches/3.16/rmk-wifi.patch

@@ -0,0 +1,569 @@
+diff -Nur linux-3.16.orig/arch/arm/boot/dts/imx6qdl-microsom.dtsi linux-3.16/arch/arm/boot/dts/imx6qdl-microsom.dtsi
+--- linux-3.16.orig/arch/arm/boot/dts/imx6qdl-microsom.dtsi	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/arch/arm/boot/dts/imx6qdl-microsom.dtsi	2014-08-11 12:34:43.603892919 +0200
+@@ -2,14 +2,92 @@
+  * Copyright (C) 2013,2014 Russell King
+  */
+ 
++#include <dt-bindings/gpio/gpio.h>
++/ {
++	regulators {
++		compatible = "simple-bus";
++
++		reg_brcm_osc: brcm-osc-reg {
++			compatible = "regulator-fixed";
++			enable-active-high;
++			gpio = <&gpio5 5 0>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&pinctrl_microsom_brcm_osc_reg>;
++			regulator-name = "brcm_osc_reg";
++			regulator-min-microvolt = <3300000>;
++			regulator-max-microvolt = <3300000>;
++			regulator-always-on;
++			regulator-boot-on;
++		};
++
++		reg_brcm: brcm-reg {
++			compatible = "regulator-fixed";
++			enable-active-high;
++			gpio = <&gpio3 19 0>;
++			pinctrl-names = "default";
++			pinctrl-0 = <&pinctrl_microsom_brcm_reg>;
++			regulator-name = "brcm_reg";
++			regulator-min-microvolt = <3300000>;
++			regulator-max-microvolt = <3300000>;
++			startup-delay-us = <200000>;
++		};
++	};
++};
++
+ &iomuxc {
+ 	microsom {
++		pinctrl_microsom_brcm_bt: microsom-brcm-bt {
++			fsl,pins = <
++				MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00	0x40013070
++				MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01	0x40013070
++				MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04	0x40013070
++			>;
++		};
++
++		pinctrl_microsom_brcm_osc_reg: microsom-brcm-osc-reg {
++			fsl,pins = <
++				MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05	0x40013070
++			>;
++		};
++
++		pinctrl_microsom_brcm_reg: microsom-brcm-reg {
++			fsl,pins = <
++				MX6QDL_PAD_EIM_D19__GPIO3_IO19		0x40013070
++			>;
++		};
++
++		pinctrl_microsom_brcm_wifi: microsom-brcm-wifi {
++			fsl,pins = <
++				MX6QDL_PAD_GPIO_8__XTALOSC_REF_CLK_32K	0x1b0b0
++				MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20	0x40013070
++				MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26	0x40013070
++				MX6QDL_PAD_CSI0_DAT9__GPIO5_IO27	0x40013070
++			>;
++		};
+ 		pinctrl_microsom_uart1: microsom-uart1 {
+ 			fsl,pins = <
+ 				MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA	0x1b0b1
+ 				MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA	0x1b0b1
+ 			>;
+ 		};
++		pinctrl_microsom_uart4_1: microsom-uart4 {
++			fsl,pins = <
++				MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
++				MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
++				MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B 0x1b0b1
++				MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B 0x1b0b1
++			>;
++		};
++		pinctrl_microsom_usdhc1: microsom-usdhc1 {
++			fsl,pins = <
++				MX6QDL_PAD_SD1_CMD__SD1_CMD    0x17059
++				MX6QDL_PAD_SD1_CLK__SD1_CLK    0x10059
++				MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059
++				MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059
++				MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059
++				MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059
++			>;
++		};
+ 	};
+ };
+ 
+@@ -18,3 +96,23 @@
+ 	pinctrl-0 = <&pinctrl_microsom_uart1>;
+ 	status = "okay";
+ };
++
++/* UART4 - Connected to optional BRCM Wifi/BT/FM */
++&uart4 {
++	pinctrl-names = "default";
++	pinctrl-0 = <&pinctrl_microsom_brcm_bt &pinctrl_microsom_uart4_1>;
++	fsl,uart-has-rtscts;
++	status = "okay";
++};
++
++/* USDHC1 - Connected to optional BRCM Wifi/BT/FM */
++&usdhc1 {
++	card-external-vcc-supply = <&reg_brcm>;
++	card-reset-gpios = <&gpio5 26 GPIO_ACTIVE_LOW>, <&gpio6 0 GPIO_ACTIVE_LOW>;
++	keep-power-in-suspend;
++	non-removable;
++	pinctrl-names = "default";
++	pinctrl-0 = <&pinctrl_microsom_brcm_wifi &pinctrl_microsom_usdhc1>;
++	vmmc-supply = <&reg_brcm>;
++	status = "okay";
++};
+diff -Nur linux-3.16.orig/Documentation/devicetree/bindings/mmc/mmc.txt linux-3.16/Documentation/devicetree/bindings/mmc/mmc.txt
+--- linux-3.16.orig/Documentation/devicetree/bindings/mmc/mmc.txt	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/Documentation/devicetree/bindings/mmc/mmc.txt	2014-08-11 12:34:15.535644516 +0200
+@@ -5,6 +5,8 @@
+ Interpreted by the OF core:
+ - reg: Registers location and length.
+ - interrupts: Interrupts used by the MMC controller.
++- clocks: Clocks needed for the host controller, if any.
++- clock-names: Goes with clocks above.
+ 
+ Card detection:
+ If no property below is supplied, host native card detect is used.
+@@ -41,6 +43,15 @@
+ - mmc-hs400-1_8v: eMMC HS400 mode(1.8V I/O) is supported
+ - mmc-hs400-1_2v: eMMC HS400 mode(1.2V I/O) is supported
+ 
++Card power and reset control:
++The following properties can be specified for cases where the MMC
++peripheral needs additional reset, regulator and clock lines. It is for
++example common for WiFi/BT adapters to have these separate from the main
++MMC bus:
++  - card-reset-gpios: Specify GPIOs for card reset (reset active low)
++  - card-external-vcc-supply: Regulator to drive (independent) card VCC
++  - clock with name "card_ext_clock": External clock provided to the card
++
+ *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
+ polarity properties, we have to fix the meaning of the "normal" and "inverted"
+ line levels. We choose to follow the SDHCI standard, which specifies both those
+diff -Nur linux-3.16.orig/drivers/mmc/core/core.c linux-3.16/drivers/mmc/core/core.c
+--- linux-3.16.orig/drivers/mmc/core/core.c	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/drivers/mmc/core/core.c	2014-08-11 12:34:15.555644693 +0200
+@@ -13,11 +13,13 @@
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
++#include <linux/clk.h>
+ #include <linux/completion.h>
+ #include <linux/device.h>
+ #include <linux/delay.h>
+ #include <linux/pagemap.h>
+ #include <linux/err.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/leds.h>
+ #include <linux/scatterlist.h>
+ #include <linux/log2.h>
+@@ -1515,6 +1517,43 @@
+ 	mmc_host_clk_release(host);
+ }
+ 
++static void mmc_card_power_up(struct mmc_host *host)
++{
++	int i;
++	struct gpio_desc **gds = host->card_reset_gpios;
++
++	for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
++		if (gds[i]) {
++			dev_dbg(host->parent, "Asserting reset line %d", i);
++			gpiod_set_value(gds[i], 1);
++		}
++	}
++
++	if (host->card_regulator) {
++		dev_dbg(host->parent, "Enabling external regulator");
++		if (regulator_enable(host->card_regulator))
++			dev_err(host->parent, "Failed to enable external regulator");
++	}
++
++	if (host->card_clk) {
++		dev_dbg(host->parent, "Enabling external clock");
++		clk_prepare_enable(host->card_clk);
++	}
++
++	/* 2ms delay to let clocks and power settle */
++	mmc_delay(20);
++
++	for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
++		if (gds[i]) {
++			dev_dbg(host->parent, "Deasserting reset line %d", i);
++			gpiod_set_value(gds[i], 0);
++		}
++	}
++
++	/* 2ms delay to after reset release */
++	mmc_delay(20);
++}
++
+ /*
+  * Apply power to the MMC stack.  This is a two-stage process.
+  * First, we enable power to the card without the clock running.
+@@ -1531,6 +1570,9 @@
+ 	if (host->ios.power_mode == MMC_POWER_ON)
+ 		return;
+ 
++	/* Power up the card/module first, if needed */
++	mmc_card_power_up(host);
++
+ 	mmc_host_clk_hold(host);
+ 
+ 	host->ios.vdd = fls(ocr) - 1;
+diff -Nur linux-3.16.orig/drivers/mmc/core/host.c linux-3.16/drivers/mmc/core/host.c
+--- linux-3.16.orig/drivers/mmc/core/host.c	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/drivers/mmc/core/host.c	2014-08-11 12:34:27.995754826 +0200
+@@ -12,14 +12,18 @@
+  *  MMC host class device management
+  */
+ 
++#include <linux/kernel.h>
++#include <linux/clk.h>
+ #include <linux/device.h>
+ #include <linux/err.h>
++#include <linux/gpio/consumer.h>
+ #include <linux/idr.h>
+ #include <linux/of.h>
+ #include <linux/of_gpio.h>
+ #include <linux/pagemap.h>
+ #include <linux/export.h>
+ #include <linux/leds.h>
++#include <linux/regulator/consumer.h>
+ #include <linux/slab.h>
+ #include <linux/suspend.h>
+ 
+@@ -461,6 +465,66 @@
+ 
+ EXPORT_SYMBOL(mmc_of_parse);
+ 
++static int mmc_of_parse_child(struct mmc_host *host)
++{
++	struct device_node *np;
++	struct clk *clk;
++	int i;
++
++	if (!host->parent || !host->parent->of_node)
++		return 0;
++
++	np = host->parent->of_node;
++
++	host->card_regulator = regulator_get(host->parent, "card-external-vcc");
++	if (IS_ERR(host->card_regulator)) {
++		if (PTR_ERR(host->card_regulator) == -EPROBE_DEFER)
++			return PTR_ERR(host->card_regulator);
++		host->card_regulator = NULL;
++	}
++
++	/* Parse card power/reset/clock control */
++	if (of_find_property(np, "card-reset-gpios", NULL)) {
++		struct gpio_desc *gpd;
++		int level = 0;
++
++		/*
++		 * If the regulator is enabled, then we can hold the
++		 * card in reset with an active high resets.  Otherwise,
++		 * hold the resets low.
++		 */
++		if (host->card_regulator && regulator_is_enabled(host->card_regulator))
++			level = 1;
++
++		for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
++			gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
++			if (IS_ERR(gpd)) {
++				if (PTR_ERR(gpd) == -EPROBE_DEFER)
++					return PTR_ERR(gpd);
++				break;
++			}
++			gpiod_direction_output(gpd, gpiod_is_active_low(gpd) | level);
++			host->card_reset_gpios[i] = gpd;
++		}
++
++		gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
++		if (!IS_ERR(gpd)) {
++			dev_warn(host->parent, "More reset gpios than we can handle");
++			gpiod_put(gpd);
++		}
++	}
++
++	clk = of_clk_get_by_name(np, "card_ext_clock");
++	if (IS_ERR(clk)) {
++		if (PTR_ERR(clk) == -EPROBE_DEFER)
++			return PTR_ERR(clk);
++		clk = NULL;
++	}
++	host->card_clk = clk;
++
++	return 0;
++}
++
+ /**
+  *	mmc_alloc_host - initialise the per-host structure.
+  *	@extra: sizeof private data structure
+@@ -540,6 +604,10 @@
+ {
+ 	int err;
+ 
++	err = mmc_of_parse_child(host);
++	if (err)
++		return err;
++
+ 	WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
+ 		!host->ops->enable_sdio_irq);
+ 
+diff -Nur linux-3.16.orig/drivers/mmc/host/dw_mmc.c linux-3.16/drivers/mmc/host/dw_mmc.c
+--- linux-3.16.orig/drivers/mmc/host/dw_mmc.c	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/drivers/mmc/host/dw_mmc.c	2014-08-11 12:34:22.043702140 +0200
+@@ -2049,6 +2049,8 @@
+ 	if (!mmc)
+ 		return -ENOMEM;
+ 
++	mmc_of_parse(mmc);
++
+ 	slot = mmc_priv(mmc);
+ 	slot->id = id;
+ 	slot->mmc = mmc;
+diff -Nur linux-3.16.orig/drivers/mmc/host/Kconfig linux-3.16/drivers/mmc/host/Kconfig
+--- linux-3.16.orig/drivers/mmc/host/Kconfig	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/drivers/mmc/host/Kconfig	2014-08-11 12:34:03.391536946 +0200
+@@ -25,8 +25,7 @@
+ 	  If unsure, say N.
+ 
+ config MMC_SDHCI
+-	tristate "Secure Digital Host Controller Interface support"
+-	depends on HAS_DMA
++	tristate
+ 	help
+ 	  This selects the generic Secure Digital Host Controller Interface.
+ 	  It is used by manufacturers such as Texas Instruments(R), Ricoh(R)
+@@ -59,7 +58,8 @@
+ 
+ config MMC_SDHCI_PCI
+ 	tristate "SDHCI support on PCI bus"
+-	depends on MMC_SDHCI && PCI
++	depends on PCI && HAS_DMA
++	select MMC_SDHCI
+ 	help
+ 	  This selects the PCI Secure Digital Host Controller Interface.
+ 	  Most controllers found today are PCI devices.
+@@ -83,7 +83,8 @@
+ 
+ config MMC_SDHCI_ACPI
+ 	tristate "SDHCI support for ACPI enumerated SDHCI controllers"
+-	depends on MMC_SDHCI && ACPI
++	depends on ACPI && HAS_DMA
++	select MMC_SDHCI
+ 	help
+ 	  This selects support for ACPI enumerated SDHCI controllers,
+ 	  identified by ACPI Compatibility ID PNP0D40 or specific
+@@ -94,8 +95,8 @@
+ 	  If unsure, say N.
+ 
+ config MMC_SDHCI_PLTFM
+-	tristate "SDHCI platform and OF driver helper"
+-	depends on MMC_SDHCI
++	tristate
++	select MMC_SDHCI
+ 	help
+ 	  This selects the common helper functions support for Secure Digital
+ 	  Host Controller Interface based platform and OF drivers.
+@@ -106,8 +107,8 @@
+ 
+ config MMC_SDHCI_OF_ARASAN
+ 	tristate "SDHCI OF support for the Arasan SDHCI controllers"
+-	depends on MMC_SDHCI_PLTFM
+-	depends on OF
++	depends on OF && HAS_DMA
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Arasan Secure Digital Host Controller Interface
+ 	  (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC.
+@@ -118,9 +119,9 @@
+ 
+ config MMC_SDHCI_OF_ESDHC
+ 	tristate "SDHCI OF support for the Freescale eSDHC controller"
+-	depends on MMC_SDHCI_PLTFM
+-	depends on PPC_OF
++	depends on PPC_OF && HAS_DMA
+ 	select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Freescale eSDHC controller support.
+ 
+@@ -130,9 +131,9 @@
+ 
+ config MMC_SDHCI_OF_HLWD
+ 	tristate "SDHCI OF support for the Nintendo Wii SDHCI controllers"
+-	depends on MMC_SDHCI_PLTFM
+-	depends on PPC_OF
++	depends on PPC_OF && HAS_DMA
+ 	select MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Secure Digital Host Controller Interface (SDHCI)
+ 	  found in the "Hollywood" chipset of the Nintendo Wii video game
+@@ -144,8 +145,8 @@
+ 
+ config MMC_SDHCI_CNS3XXX
+ 	tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
+-	depends on ARCH_CNS3XXX
+-	depends on MMC_SDHCI_PLTFM
++	depends on ARCH_CNS3XXX && HAS_DMA
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the SDHCI support for CNS3xxx System-on-Chip devices.
+ 
+@@ -155,9 +156,9 @@
+ 
+ config MMC_SDHCI_ESDHC_IMX
+ 	tristate "SDHCI support for the Freescale eSDHC/uSDHC i.MX controller"
+-	depends on ARCH_MXC
+-	depends on MMC_SDHCI_PLTFM
++	depends on ARCH_MXC && HAS_DMA
+ 	select MMC_SDHCI_IO_ACCESSORS
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Freescale eSDHC/uSDHC controller support
+ 	  found on i.MX25, i.MX35 i.MX5x and i.MX6x.
+@@ -168,9 +169,9 @@
+ 
+ config MMC_SDHCI_DOVE
+ 	tristate "SDHCI support on Marvell's Dove SoC"
+-	depends on ARCH_DOVE || MACH_DOVE
+-	depends on MMC_SDHCI_PLTFM
++	depends on (ARCH_DOVE || MACH_DOVE) && HAS_DMA
+ 	select MMC_SDHCI_IO_ACCESSORS
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Secure Digital Host Controller Interface in
+ 	  Marvell's Dove SoC.
+@@ -181,9 +182,9 @@
+ 
+ config MMC_SDHCI_TEGRA
+ 	tristate "SDHCI platform support for the Tegra SD/MMC Controller"
+-	depends on ARCH_TEGRA
+-	depends on MMC_SDHCI_PLTFM
++	depends on ARCH_TEGRA && HAS_DMA
+ 	select MMC_SDHCI_IO_ACCESSORS
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Tegra SD/MMC controller. If you have a Tegra
+ 	  platform with SD or MMC devices, say Y or M here.
+@@ -192,7 +193,8 @@
+ 
+ config MMC_SDHCI_S3C
+ 	tristate "SDHCI support on Samsung S3C SoC"
+-	depends on MMC_SDHCI && PLAT_SAMSUNG
++	depends on PLAT_SAMSUNG && HAS_DMA
++	select MMC_SDHCI
+ 	help
+ 	  This selects the Secure Digital Host Controller Interface (SDHCI)
+ 	  often referrered to as the HSMMC block in some of the Samsung S3C
+@@ -204,8 +206,8 @@
+ 
+ config MMC_SDHCI_SIRF
+ 	tristate "SDHCI support on CSR SiRFprimaII and SiRFmarco SoCs"
+-	depends on ARCH_SIRF
+-	depends on MMC_SDHCI_PLTFM
++	depends on ARCH_SIRF && HAS_DMA
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the SDHCI support for SiRF System-on-Chip devices.
+ 
+@@ -215,8 +217,8 @@
+ 
+ config MMC_SDHCI_PXAV3
+ 	tristate "Marvell MMP2 SD Host Controller support (PXAV3)"
+-	depends on CLKDEV_LOOKUP
+-	depends on MMC_SDHCI_PLTFM
++	depends on CLKDEV_LOOKUP && HAS_DMA
++	select MMC_SDHCI_PLTFM
+ 	default CPU_MMP2
+ 	help
+ 	  This selects the Marvell(R) PXAV3 SD Host Controller.
+@@ -227,8 +229,8 @@
+ 
+ config MMC_SDHCI_PXAV2
+ 	tristate "Marvell PXA9XX SD Host Controller support (PXAV2)"
+-	depends on CLKDEV_LOOKUP
+-	depends on MMC_SDHCI_PLTFM
++	depends on CLKDEV_LOOKUP && HAS_DMA
++	select MMC_SDHCI_PLTFM
+ 	default CPU_PXA910
+ 	help
+ 	  This selects the Marvell(R) PXAV2 SD Host Controller.
+@@ -239,7 +241,8 @@
+ 
+ config MMC_SDHCI_SPEAR
+ 	tristate "SDHCI support on ST SPEAr platform"
+-	depends on MMC_SDHCI && PLAT_SPEAR
++	depends on PLAT_SPEAR && HAS_DMA
++	select MMC_SDHCI
+ 	help
+ 	  This selects the Secure Digital Host Controller Interface (SDHCI)
+ 	  often referrered to as the HSMMC block in some of the ST SPEAR range
+@@ -261,8 +264,8 @@
+ 
+ config MMC_SDHCI_BCM_KONA
+ 	tristate "SDHCI support on Broadcom KONA platform"
+-	depends on ARCH_BCM_MOBILE
+-	depends on MMC_SDHCI_PLTFM
++	depends on ARCH_BCM_MOBILE && HAS_DMA
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the Broadcom Kona Secure Digital Host Controller
+ 	  Interface(SDHCI) support.
+@@ -272,9 +275,9 @@
+ 
+ config MMC_SDHCI_BCM2835
+ 	tristate "SDHCI platform support for the BCM2835 SD/MMC Controller"
+-	depends on ARCH_BCM2835
+-	depends on MMC_SDHCI_PLTFM
++	depends on ARCH_BCM2835 && HAS_DMA
+ 	select MMC_SDHCI_IO_ACCESSORS
++	select MMC_SDHCI_PLTFM
+ 	help
+ 	  This selects the BCM2835 SD/MMC controller. If you have a BCM2835
+ 	  platform with SD or MMC devices, say Y or M here.
+diff -Nur linux-3.16.orig/drivers/mmc/host/sdhci.c linux-3.16/drivers/mmc/host/sdhci.c
+--- linux-3.16.orig/drivers/mmc/host/sdhci.c	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/drivers/mmc/host/sdhci.c	2014-08-11 12:34:08.763584537 +0200
+@@ -1530,7 +1530,6 @@
+ 			host->ops->set_clock(host, host->clock);
+ 		}
+ 
+-
+ 		/* Reset SD Clock Enable */
+ 		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+ 		clk &= ~SDHCI_CLOCK_CARD_EN;
+@@ -1763,9 +1762,6 @@
+ 		ctrl |= SDHCI_CTRL_VDD_180;
+ 		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ 
+-		/* Wait for 5ms */
+-		usleep_range(5000, 5500);
+-
+ 		/* 1.8V regulator output should be stable within 5 ms */
+ 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+ 		if (ctrl & SDHCI_CTRL_VDD_180)
+diff -Nur linux-3.16.orig/include/linux/mmc/host.h linux-3.16/include/linux/mmc/host.h
+--- linux-3.16.orig/include/linux/mmc/host.h	2014-08-04 00:25:02.000000000 +0200
++++ linux-3.16/include/linux/mmc/host.h	2014-08-11 12:34:15.559644729 +0200
+@@ -298,6 +298,11 @@
+ 	unsigned long           clkgate_delay;
+ #endif
+ 
++	/* card specific properties to deal with power and reset */
++	struct regulator	*card_regulator; /* External VCC needed by the card */
++	struct gpio_desc	*card_reset_gpios[2]; /* External resets, active low */
++	struct clk		*card_clk;	/* External clock needed by the card */
++
+ 	/* host specific block data */
+ 	unsigned int		max_seg_size;	/* see blk_queue_max_segment_size */
+ 	unsigned short		max_segs;	/* see blk_queue_max_segments */