浏览代码

Merge tag 'mmc-v3.16-1' of git://git.linaro.org/people/ulf.hansson/mmc into next

Pull MMC update from Ulf Hansson:
 "These patches are mainly updates for the mmci driver and have been
  tested in linux-next.

  Some ARM SoC related patches are also included and those have been
  acked from the corresponding maintainers to go through my mmc tree.

  Updates for mmci driver:
   - Put the device into low power state at system suspend.
   - Convert to the common mmc DT parser.
   - Add missing DT bindings needed for ux500.

  Updates for ARM ux500|u300:
   - Convert to the common mmc DT bindings.
   - Remove redundant board file for mmci platform data"

* tag 'mmc-v3.16-1' of git://git.linaro.org/people/ulf.hansson/mmc: (22 commits)
  mmc: mmci: Enforce DMA configuration through DT
  mmc: mmci: Enforce max frequency configuration through DT
  mmc: mmci: Enforce mmc capabilities through DT
  mmc: mmci: Enforce DT for signal direction and feedback clock
  ARM: ux500: Remove redundant board file for mmci platform data
  ARM: ux500: Add a vmmc regulator through DT for the poped eMMC for href
  ARM: ux500: Add the mmc capabilities flags to DT
  mmc: mmci: Enable MMC_CAP_CMD23
  mmc: mmci: Mark the DT bindings for highspeed mode as deprecated
  ARM: u300: Convert to the common mmc DT bindings for highspeed mode
  ARM: nomadik: Convert to the common mmc DT bindings for highspeed mode
  ARM: ux500: Convert to the common mmc DT bindings for highspeed mode
  ARM: ux500: Add mmci signal directions and feeback clock in DT for href
  mmc: mmci: Use the common mmc DT parser
  mmc: mmci: Add DT bindings for feedback clock pin
  mmc: mmci: Add DT bindings for signal direction
  mmc: mmci: Update DT documentation
  mmc: mmci: Convert to devm functions
  mmc: mmci: Convert to the mmc gpio API
  mmc: mmci: Put the device into low power state at system suspend
  ...
Linus Torvalds 11 年之前
父节点
当前提交
6c52486ded

+ 50 - 4
Documentation/devicetree/bindings/mmc/mmci.txt

@@ -4,12 +4,58 @@ The ARM PrimeCell MMCI PL180 and PL181 provides an interface for
 reading and writing to MultiMedia and SD cards alike.
 reading and writing to MultiMedia and SD cards alike.
 
 
 This file documents differences between the core properties described
 This file documents differences between the core properties described
-by mmc.txt and the properties used by the mmci driver.
+by mmc.txt and the properties used by the mmci driver. Using "st" as
+the prefix for a property, indicates support by the ST Micro variant.
 
 
 Required properties:
 Required properties:
 - compatible             : contains "arm,pl18x", "arm,primecell".
 - compatible             : contains "arm,pl18x", "arm,primecell".
-- arm,primecell-periphid : contains the PrimeCell Peripheral ID.
+- vmmc-supply            : phandle to the regulator device tree node, mentioned
+                           as the VCC/VDD supply in the eMMC/SD specs.
 
 
 Optional properties:
 Optional properties:
-- mmc-cap-mmc-highspeed  : indicates whether MMC is high speed capable
-- mmc-cap-sd-highspeed   : indicates whether SD is high speed capable
+- arm,primecell-periphid : contains the PrimeCell Peripheral ID, it overrides
+                           the ID provided by the HW
+- vqmmc-supply           : phandle to the regulator device tree node, mentioned
+                           as the VCCQ/VDD_IO supply in the eMMC/SD specs.
+- st,sig-dir-dat0        : bus signal direction pin used for DAT[0].
+- st,sig-dir-dat2        : bus signal direction pin used for DAT[2].
+- st,sig-dir-dat31       : bus signal direction pin used for DAT[3] and DAT[1].
+- st,sig-dir-dat74       : bus signal direction pin used for DAT[4] to DAT[7].
+- st,sig-dir-cmd         : cmd signal direction pin used for CMD.
+- st,sig-pin-fbclk       : feedback clock signal pin used.
+
+Deprecated properties:
+- mmc-cap-mmc-highspeed  : indicates whether MMC is high speed capable.
+- mmc-cap-sd-highspeed   : indicates whether SD is high speed capable.
+
+Example:
+
+sdi0_per1@80126000 {
+	compatible = "arm,pl18x", "arm,primecell";
+	reg = <0x80126000 0x1000>;
+	interrupts = <0 60 IRQ_TYPE_LEVEL_HIGH>;
+
+	dmas = <&dma 29 0 0x2>, /* Logical - DevToMem */
+	       <&dma 29 0 0x0>; /* Logical - MemToDev */
+	dma-names = "rx", "tx";
+
+	clocks = <&prcc_kclk 1 5>, <&prcc_pclk 1 5>;
+	clock-names = "sdi", "apb_pclk";
+
+	max-frequency = <100000000>;
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-mmc-highspeed;
+	cd-gpios  = <&gpio2 31 0x4>; // 95
+	st,sig-dir-dat0;
+	st,sig-dir-dat2;
+	st,sig-dir-cmd;
+	st,sig-pin-fbclk;
+
+	vmmc-supply = <&ab8500_ldo_aux3_reg>;
+	vqmmc-supply = <&vmmci>;
+
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&sdi0_default_mode>;
+	pinctrl-1 = <&sdi0_sleep_mode>;
+};

+ 3 - 3
arch/arm/boot/dts/ste-ccu9540.dts

@@ -38,8 +38,8 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <100000000>;
 			max-frequency = <100000000>;
 			bus-width = <4>;
 			bus-width = <4>;
-			mmc-cap-sd-highspeed;
-			mmc-cap-mmc-highspeed;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 
 
 			cd-gpios  = <&gpio7 6 0x4>; // 230
 			cd-gpios  = <&gpio7 6 0x4>; // 230
@@ -63,7 +63,7 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 		        max-frequency = <100000000>;
 		        max-frequency = <100000000>;
 			bus-width = <8>;
 			bus-width = <8>;
-			mmc-cap-mmc-highspeed;
+			cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 
 
 			status = "okay";
 			status = "okay";

+ 15 - 4
arch/arm/boot/dts/ste-href.dtsi

@@ -116,8 +116,15 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <100000000>;
 			max-frequency = <100000000>;
 			bus-width = <4>;
 			bus-width = <4>;
-			mmc-cap-sd-highspeed;
-			mmc-cap-mmc-highspeed;
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			sd-uhs-sdr12;
+			sd-uhs-sdr25;
+			full-pwr-cycle;
+			st,sig-dir-dat0;
+			st,sig-dir-dat2;
+			st,sig-dir-cmd;
+			st,sig-pin-fbclk;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 			vqmmc-supply = <&vmmci>;
 			vqmmc-supply = <&vmmci>;
 			pinctrl-names = "default", "sleep";
 			pinctrl-names = "default", "sleep";
@@ -132,6 +139,7 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <100000000>;
 			max-frequency = <100000000>;
 			bus-width = <4>;
 			bus-width = <4>;
+			non-removable;
 			pinctrl-names = "default", "sleep";
 			pinctrl-names = "default", "sleep";
 			pinctrl-0 = <&sdi1_default_mode>;
 			pinctrl-0 = <&sdi1_default_mode>;
 			pinctrl-1 = <&sdi1_sleep_mode>;
 			pinctrl-1 = <&sdi1_sleep_mode>;
@@ -144,7 +152,9 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <100000000>;
 			max-frequency = <100000000>;
 			bus-width = <8>;
 			bus-width = <8>;
-			mmc-cap-mmc-highspeed;
+			cap-mmc-highspeed;
+			non-removable;
+			vmmc-supply = <&db8500_vsmps2_reg>;
 			pinctrl-names = "default", "sleep";
 			pinctrl-names = "default", "sleep";
 			pinctrl-0 = <&sdi2_default_mode>;
 			pinctrl-0 = <&sdi2_default_mode>;
 			pinctrl-1 = <&sdi2_sleep_mode>;
 			pinctrl-1 = <&sdi2_sleep_mode>;
@@ -157,7 +167,8 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 		        max-frequency = <100000000>;
 		        max-frequency = <100000000>;
 			bus-width = <8>;
 			bus-width = <8>;
-			mmc-cap-mmc-highspeed;
+			cap-mmc-highspeed;
+			non-removable;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 			pinctrl-names = "default", "sleep";
 			pinctrl-names = "default", "sleep";
 			pinctrl-0 = <&sdi4_default_mode>;
 			pinctrl-0 = <&sdi4_default_mode>;

+ 2 - 2
arch/arm/boot/dts/ste-nomadik-stn8815.dtsi

@@ -840,8 +840,8 @@
 			interrupts = <22>;
 			interrupts = <22>;
 			max-frequency = <48000000>;
 			max-frequency = <48000000>;
 			bus-width = <4>;
 			bus-width = <4>;
-			mmc-cap-mmc-highspeed;
-			mmc-cap-sd-highspeed;
+			cap-mmc-highspeed;
+			cap-sd-highspeed;
 			cd-gpios = <&gpio3 15 0x1>;
 			cd-gpios = <&gpio3 15 0x1>;
 			cd-inverted;
 			cd-inverted;
 			pinctrl-names = "default";
 			pinctrl-names = "default";

+ 2 - 2
arch/arm/boot/dts/ste-snowball.dts

@@ -156,7 +156,7 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 			max-frequency = <100000000>;
 			max-frequency = <100000000>;
 			bus-width = <4>;
 			bus-width = <4>;
-			mmc-cap-mmc-highspeed;
+			cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
 			vqmmc-supply = <&vmmci>;
 			vqmmc-supply = <&vmmci>;
 			pinctrl-names = "default", "sleep";
 			pinctrl-names = "default", "sleep";
@@ -195,7 +195,7 @@
 			arm,primecell-periphid = <0x10480180>;
 			arm,primecell-periphid = <0x10480180>;
 		        max-frequency = <100000000>;
 		        max-frequency = <100000000>;
 			bus-width = <8>;
 			bus-width = <8>;
-			mmc-cap-mmc-highspeed;
+			cap-mmc-highspeed;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 			vmmc-supply = <&ab8500_ldo_aux2_reg>;
 			pinctrl-names = "default", "sleep";
 			pinctrl-names = "default", "sleep";
 			pinctrl-0 = <&sdi4_default_mode>;
 			pinctrl-0 = <&sdi4_default_mode>;

+ 2 - 2
arch/arm/boot/dts/ste-u300.dts

@@ -442,8 +442,8 @@
 			clock-names = "apb_pclk", "mclk";
 			clock-names = "apb_pclk", "mclk";
 			max-frequency = <24000000>;
 			max-frequency = <24000000>;
 			bus-width = <4>; // SD-card slot
 			bus-width = <4>; // SD-card slot
-			mmc-cap-mmc-highspeed;
-			mmc-cap-sd-highspeed;
+			cap-mmc-highspeed;
+			cap-sd-highspeed;
 			cd-gpios = <&gpio 12 0x4>;
 			cd-gpios = <&gpio 12 0x4>;
 			cd-inverted;
 			cd-inverted;
 			vmmc-supply = <&ab3100_ldo_g_reg>;
 			vmmc-supply = <&ab3100_ldo_g_reg>;

+ 0 - 3
arch/arm/mach-lpc32xx/phy3250.c

@@ -202,9 +202,6 @@ static struct mmci_platform_data lpc32xx_mmci_data = {
 	.ocr_mask	= MMC_VDD_30_31 | MMC_VDD_31_32 |
 	.ocr_mask	= MMC_VDD_30_31 | MMC_VDD_31_32 |
 			  MMC_VDD_32_33 | MMC_VDD_33_34,
 			  MMC_VDD_32_33 | MMC_VDD_33_34,
 	.ios_handler	= mmc_handle_ios,
 	.ios_handler	= mmc_handle_ios,
-	.dma_filter	= NULL,
-	/* No DMA for now since AMBA PL080 dmaengine driver only does scatter
-	 * gather, and the MMCI driver doesn't do it this way */
 };
 };
 
 
 static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {
 static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {

+ 1 - 2
arch/arm/mach-ux500/Makefile

@@ -5,8 +5,7 @@
 obj-y				:= cpu.o id.o timer.o pm.o
 obj-y				:= cpu.o id.o timer.o pm.o
 obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_CACHE_L2X0)	+= cache-l2x0.o
 obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o
 obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o
-obj-$(CONFIG_MACH_MOP500)	+= board-mop500-sdi.o \
-				board-mop500-regulators.o \
+obj-$(CONFIG_MACH_MOP500)	+= board-mop500-regulators.o \
 				board-mop500-audio.o
 				board-mop500-audio.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o

+ 0 - 166
arch/arm/mach-ux500/board-mop500-sdi.c

@@ -1,166 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Hanumath Prasad <hanumath.prasad@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/mmci.h>
-#include <linux/mmc/host.h>
-#include <linux/platform_device.h>
-#include <linux/platform_data/dma-ste-dma40.h>
-
-#include <asm/mach-types.h>
-
-#include "db8500-regs.h"
-#include "board-mop500.h"
-#include "ste-dma40-db8500.h"
-
-/*
- * v2 has a new version of this block that need to be forced, the number found
- * in hardware is incorrect
- */
-#define U8500_SDI_V2_PERIPHID 0x10480180
-
-/*
- * SDI 0 (MicroSD slot)
- */
-
-#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg mop500_sdi0_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type = DB8500_DMA_DEV29_SD_MM0,
-};
-
-static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV29_SD_MM0,
-};
-#endif
-
-struct mmci_platform_data mop500_sdi0_data = {
-	.f_max		= 100000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_SD_HIGHSPEED |
-				MMC_CAP_MMC_HIGHSPEED |
-				MMC_CAP_ERASE |
-				MMC_CAP_UHS_SDR12 |
-				MMC_CAP_UHS_SDR25,
-	.gpio_wp	= -1,
-	.sigdir		= MCI_ST_FBCLKEN |
-				MCI_ST_CMDDIREN |
-				MCI_ST_DATA0DIREN |
-				MCI_ST_DATA2DIREN,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &mop500_sdi0_dma_cfg_rx,
-	.dma_tx_param	= &mop500_sdi0_dma_cfg_tx,
-#endif
-};
-
-/*
- * SDI1 (SDIO WLAN)
- */
-#ifdef CONFIG_STE_DMA40
-static struct stedma40_chan_cfg sdi1_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type = DB8500_DMA_DEV32_SD_MM1,
-};
-
-static struct stedma40_chan_cfg sdi1_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV32_SD_MM1,
-};
-#endif
-
-struct mmci_platform_data mop500_sdi1_data = {
-	.ocr_mask	= MMC_VDD_29_30,
-	.f_max		= 100000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_NONREMOVABLE,
-	.gpio_cd	= -1,
-	.gpio_wp	= -1,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &sdi1_dma_cfg_rx,
-	.dma_tx_param	= &sdi1_dma_cfg_tx,
-#endif
-};
-
-/*
- * SDI 2 (POP eMMC, not on DB8500ed)
- */
-
-#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg mop500_sdi2_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type =  DB8500_DMA_DEV28_SD_MM2,
-};
-
-static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV28_SD_MM2,
-};
-#endif
-
-struct mmci_platform_data mop500_sdi2_data = {
-	.ocr_mask	= MMC_VDD_165_195,
-	.f_max		= 100000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_8_BIT_DATA |
-				MMC_CAP_NONREMOVABLE |
-				MMC_CAP_MMC_HIGHSPEED |
-				MMC_CAP_ERASE |
-				MMC_CAP_CMD23,
-	.gpio_cd	= -1,
-	.gpio_wp	= -1,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &mop500_sdi2_dma_cfg_rx,
-	.dma_tx_param	= &mop500_sdi2_dma_cfg_tx,
-#endif
-};
-
-/*
- * SDI 4 (on-board eMMC)
- */
-
-#ifdef CONFIG_STE_DMA40
-struct stedma40_chan_cfg mop500_sdi4_dma_cfg_rx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_DEV_TO_MEM,
-	.dev_type =  DB8500_DMA_DEV42_SD_MM4,
-};
-
-static struct stedma40_chan_cfg mop500_sdi4_dma_cfg_tx = {
-	.mode = STEDMA40_MODE_LOGICAL,
-	.dir = DMA_MEM_TO_DEV,
-	.dev_type = DB8500_DMA_DEV42_SD_MM4,
-};
-#endif
-
-struct mmci_platform_data mop500_sdi4_data = {
-	.f_max		= 100000000,
-	.capabilities	= MMC_CAP_4_BIT_DATA |
-				MMC_CAP_8_BIT_DATA |
-				MMC_CAP_NONREMOVABLE |
-				MMC_CAP_MMC_HIGHSPEED |
-				MMC_CAP_ERASE |
-				MMC_CAP_CMD23,
-	.gpio_cd	= -1,
-	.gpio_wp	= -1,
-#ifdef CONFIG_STE_DMA40
-	.dma_filter	= stedma40_filter,
-	.dma_rx_param	= &mop500_sdi4_dma_cfg_rx,
-	.dma_tx_param	= &mop500_sdi4_dma_cfg_tx,
-#endif
-};

+ 0 - 5
arch/arm/mach-ux500/board-mop500.h

@@ -8,12 +8,7 @@
 #define __BOARD_MOP500_H
 #define __BOARD_MOP500_H
 
 
 #include <linux/platform_data/asoc-ux500-msp.h>
 #include <linux/platform_data/asoc-ux500-msp.h>
-#include <linux/amba/mmci.h>
 
 
-extern struct mmci_platform_data mop500_sdi0_data;
-extern struct mmci_platform_data mop500_sdi1_data;
-extern struct mmci_platform_data mop500_sdi2_data;
-extern struct mmci_platform_data mop500_sdi4_data;
 extern struct msp_i2s_platform_data msp0_platform_data;
 extern struct msp_i2s_platform_data msp0_platform_data;
 extern struct msp_i2s_platform_data msp1_platform_data;
 extern struct msp_i2s_platform_data msp1_platform_data;
 extern struct msp_i2s_platform_data msp2_platform_data;
 extern struct msp_i2s_platform_data msp2_platform_data;

+ 0 - 4
arch/arm/mach-ux500/cpu-db8500.c

@@ -146,10 +146,6 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = {
 	/* Requires call-back bindings. */
 	/* Requires call-back bindings. */
 	OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
 	OF_DEV_AUXDATA("arm,cortex-a9-pmu", 0, "arm-pmu", &db8500_pmu_platdata),
 	/* Requires DMA bindings. */
 	/* Requires DMA bindings. */
-	OF_DEV_AUXDATA("arm,pl18x", 0x80126000, "sdi0",  &mop500_sdi0_data),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80118000, "sdi1",  &mop500_sdi1_data),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80005000, "sdi2",  &mop500_sdi2_data),
-	OF_DEV_AUXDATA("arm,pl18x", 0x80114000, "sdi4",  &mop500_sdi4_data),
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80123000,
 		       "ux500-msp-i2s.0", &msp0_platform_data),
 		       "ux500-msp-i2s.0", &msp0_platform_data),
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,
 	OF_DEV_AUXDATA("stericsson,ux500-msp-i2s", 0x80124000,

+ 83 - 241
drivers/mmc/host/mmci.c

@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/device.h>
+#include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
@@ -23,6 +24,7 @@
 #include <linux/mmc/pm.h>
 #include <linux/mmc/pm.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
 #include <linux/scatterlist.h>
@@ -364,7 +366,6 @@ static void mmci_init_sg(struct mmci_host *host, struct mmc_data *data)
 #ifdef CONFIG_DMA_ENGINE
 #ifdef CONFIG_DMA_ENGINE
 static void mmci_dma_setup(struct mmci_host *host)
 static void mmci_dma_setup(struct mmci_host *host)
 {
 {
-	struct mmci_platform_data *plat = host->plat;
 	const char *rxname, *txname;
 	const char *rxname, *txname;
 	dma_cap_mask_t mask;
 	dma_cap_mask_t mask;
 
 
@@ -378,25 +379,6 @@ static void mmci_dma_setup(struct mmci_host *host)
 	dma_cap_zero(mask);
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
 	dma_cap_set(DMA_SLAVE, mask);
 
 
-	if (plat && plat->dma_filter) {
-		if (!host->dma_rx_channel && plat->dma_rx_param) {
-			host->dma_rx_channel = dma_request_channel(mask,
-							   plat->dma_filter,
-							   plat->dma_rx_param);
-			/* E.g if no DMA hardware is present */
-			if (!host->dma_rx_channel)
-				dev_err(mmc_dev(host->mmc), "no RX DMA channel\n");
-		}
-
-		if (!host->dma_tx_channel && plat->dma_tx_param) {
-			host->dma_tx_channel = dma_request_channel(mask,
-							   plat->dma_filter,
-							   plat->dma_tx_param);
-			if (!host->dma_tx_channel)
-				dev_warn(mmc_dev(host->mmc), "no TX DMA channel\n");
-		}
-	}
-
 	/*
 	/*
 	 * If only an RX channel is specified, the driver will
 	 * If only an RX channel is specified, the driver will
 	 * attempt to use it bidirectionally, however if it is
 	 * attempt to use it bidirectionally, however if it is
@@ -444,11 +426,9 @@ static void mmci_dma_setup(struct mmci_host *host)
  */
  */
 static inline void mmci_dma_release(struct mmci_host *host)
 static inline void mmci_dma_release(struct mmci_host *host)
 {
 {
-	struct mmci_platform_data *plat = host->plat;
-
 	if (host->dma_rx_channel)
 	if (host->dma_rx_channel)
 		dma_release_channel(host->dma_rx_channel);
 		dma_release_channel(host->dma_rx_channel);
-	if (host->dma_tx_channel && plat->dma_tx_param)
+	if (host->dma_tx_channel)
 		dma_release_channel(host->dma_tx_channel);
 		dma_release_channel(host->dma_tx_channel);
 	host->dma_rx_channel = host->dma_tx_channel = NULL;
 	host->dma_rx_channel = host->dma_tx_channel = NULL;
 }
 }
@@ -1285,7 +1265,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 		 * indicating signal direction for the signals in
 		 * indicating signal direction for the signals in
 		 * the SD/MMC bus and feedback-clock usage.
 		 * the SD/MMC bus and feedback-clock usage.
 		 */
 		 */
-		pwr |= host->plat->sigdir;
+		pwr |= host->pwr_reg_add;
 
 
 		if (ios->bus_width == MMC_BUS_WIDTH_4)
 		if (ios->bus_width == MMC_BUS_WIDTH_4)
 			pwr &= ~MCI_ST_DATA74DIREN;
 			pwr &= ~MCI_ST_DATA74DIREN;
@@ -1326,35 +1306,18 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	pm_runtime_put_autosuspend(mmc_dev(mmc));
 	pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 }
 
 
-static int mmci_get_ro(struct mmc_host *mmc)
-{
-	struct mmci_host *host = mmc_priv(mmc);
-
-	if (host->gpio_wp == -ENOSYS)
-		return -ENOSYS;
-
-	return gpio_get_value_cansleep(host->gpio_wp);
-}
-
 static int mmci_get_cd(struct mmc_host *mmc)
 static int mmci_get_cd(struct mmc_host *mmc)
 {
 {
 	struct mmci_host *host = mmc_priv(mmc);
 	struct mmci_host *host = mmc_priv(mmc);
 	struct mmci_platform_data *plat = host->plat;
 	struct mmci_platform_data *plat = host->plat;
-	unsigned int status;
+	unsigned int status = mmc_gpio_get_cd(mmc);
 
 
-	if (host->gpio_cd == -ENOSYS) {
+	if (status == -ENOSYS) {
 		if (!plat->status)
 		if (!plat->status)
 			return 1; /* Assume always present */
 			return 1; /* Assume always present */
 
 
 		status = plat->status(mmc_dev(host->mmc));
 		status = plat->status(mmc_dev(host->mmc));
-	} else
-		status = !!gpio_get_value_cansleep(host->gpio_cd)
-			^ plat->cd_invert;
-
-	/*
-	 * Use positive logic throughout - status is zero for no card,
-	 * non-zero for card inserted.
-	 */
+	}
 	return status;
 	return status;
 }
 }
 
 
@@ -1391,70 +1354,44 @@ static int mmci_sig_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
 	return ret;
 	return ret;
 }
 }
 
 
-static irqreturn_t mmci_cd_irq(int irq, void *dev_id)
-{
-	struct mmci_host *host = dev_id;
-
-	mmc_detect_change(host->mmc, msecs_to_jiffies(500));
-
-	return IRQ_HANDLED;
-}
-
 static struct mmc_host_ops mmci_ops = {
 static struct mmc_host_ops mmci_ops = {
 	.request	= mmci_request,
 	.request	= mmci_request,
 	.pre_req	= mmci_pre_request,
 	.pre_req	= mmci_pre_request,
 	.post_req	= mmci_post_request,
 	.post_req	= mmci_post_request,
 	.set_ios	= mmci_set_ios,
 	.set_ios	= mmci_set_ios,
-	.get_ro		= mmci_get_ro,
+	.get_ro		= mmc_gpio_get_ro,
 	.get_cd		= mmci_get_cd,
 	.get_cd		= mmci_get_cd,
 	.start_signal_voltage_switch = mmci_sig_volt_switch,
 	.start_signal_voltage_switch = mmci_sig_volt_switch,
 };
 };
 
 
-#ifdef CONFIG_OF
-static void mmci_dt_populate_generic_pdata(struct device_node *np,
-					struct mmci_platform_data *pdata)
+static int mmci_of_parse(struct device_node *np, struct mmc_host *mmc)
 {
 {
-	int bus_width = 0;
-
-	pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0);
-	pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0);
+	struct mmci_host *host = mmc_priv(mmc);
+	int ret = mmc_of_parse(mmc);
 
 
-	if (of_get_property(np, "cd-inverted", NULL))
-		pdata->cd_invert = true;
-	else
-		pdata->cd_invert = false;
+	if (ret)
+		return ret;
 
 
-	of_property_read_u32(np, "max-frequency", &pdata->f_max);
-	if (!pdata->f_max)
-		pr_warn("%s has no 'max-frequency' property\n", np->full_name);
+	if (of_get_property(np, "st,sig-dir-dat0", NULL))
+		host->pwr_reg_add |= MCI_ST_DATA0DIREN;
+	if (of_get_property(np, "st,sig-dir-dat2", NULL))
+		host->pwr_reg_add |= MCI_ST_DATA2DIREN;
+	if (of_get_property(np, "st,sig-dir-dat31", NULL))
+		host->pwr_reg_add |= MCI_ST_DATA31DIREN;
+	if (of_get_property(np, "st,sig-dir-dat74", NULL))
+		host->pwr_reg_add |= MCI_ST_DATA74DIREN;
+	if (of_get_property(np, "st,sig-dir-cmd", NULL))
+		host->pwr_reg_add |= MCI_ST_CMDDIREN;
+	if (of_get_property(np, "st,sig-pin-fbclk", NULL))
+		host->pwr_reg_add |= MCI_ST_FBCLKEN;
 
 
 	if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL))
 	if (of_get_property(np, "mmc-cap-mmc-highspeed", NULL))
-		pdata->capabilities |= MMC_CAP_MMC_HIGHSPEED;
+		mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
 	if (of_get_property(np, "mmc-cap-sd-highspeed", NULL))
 	if (of_get_property(np, "mmc-cap-sd-highspeed", NULL))
-		pdata->capabilities |= MMC_CAP_SD_HIGHSPEED;
+		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
 
 
-	of_property_read_u32(np, "bus-width", &bus_width);
-	switch (bus_width) {
-	case 0 :
-		/* No bus-width supplied. */
-		break;
-	case 4 :
-		pdata->capabilities |= MMC_CAP_4_BIT_DATA;
-		break;
-	case 8 :
-		pdata->capabilities |= MMC_CAP_8_BIT_DATA;
-		break;
-	default :
-		pr_warn("%s: Unsupported bus width\n", np->full_name);
-	}
-}
-#else
-static void mmci_dt_populate_generic_pdata(struct device_node *np,
-					struct mmci_platform_data *pdata)
-{
-	return;
+	return 0;
 }
 }
-#endif
 
 
 static int mmci_probe(struct amba_device *dev,
 static int mmci_probe(struct amba_device *dev,
 	const struct amba_id *id)
 	const struct amba_id *id)
@@ -1478,26 +1415,17 @@ static int mmci_probe(struct amba_device *dev,
 			return -ENOMEM;
 			return -ENOMEM;
 	}
 	}
 
 
-	if (np)
-		mmci_dt_populate_generic_pdata(np, plat);
+	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
+	if (!mmc)
+		return -ENOMEM;
 
 
-	ret = amba_request_regions(dev, DRIVER_NAME);
+	ret = mmci_of_parse(np, mmc);
 	if (ret)
 	if (ret)
-		goto out;
-
-	mmc = mmc_alloc_host(sizeof(struct mmci_host), &dev->dev);
-	if (!mmc) {
-		ret = -ENOMEM;
-		goto rel_regions;
-	}
+		goto host_free;
 
 
 	host = mmc_priv(mmc);
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
 	host->mmc = mmc;
 
 
-	host->gpio_wp = -ENOSYS;
-	host->gpio_cd = -ENOSYS;
-	host->gpio_cd_irq = -1;
-
 	host->hw_designer = amba_manf(dev);
 	host->hw_designer = amba_manf(dev);
 	host->hw_revision = amba_rev(dev);
 	host->hw_revision = amba_rev(dev);
 	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
 	dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
@@ -1529,10 +1457,11 @@ static int mmci_probe(struct amba_device *dev,
 		dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
 		dev_dbg(mmc_dev(mmc), "eventual mclk rate: %u Hz\n",
 			host->mclk);
 			host->mclk);
 	}
 	}
+
 	host->phybase = dev->res.start;
 	host->phybase = dev->res.start;
-	host->base = ioremap(dev->res.start, resource_size(&dev->res));
-	if (!host->base) {
-		ret = -ENOMEM;
+	host->base = devm_ioremap_resource(&dev->dev, &dev->res);
+	if (IS_ERR(host->base)) {
+		ret = PTR_ERR(host->base);
 		goto clk_disable;
 		goto clk_disable;
 	}
 	}
 
 
@@ -1546,15 +1475,13 @@ static int mmci_probe(struct amba_device *dev,
 	else
 	else
 		mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
 		mmc->f_min = DIV_ROUND_UP(host->mclk, 512);
 	/*
 	/*
-	 * If the platform data supplies a maximum operating
-	 * frequency, this takes precedence. Else, we fall back
-	 * to using the module parameter, which has a (low)
-	 * default value in case it is not specified. Either
-	 * value must not exceed the clock rate into the block,
-	 * of course.
+	 * If no maximum operating frequency is supplied, fall back to use
+	 * the module parameter, which has a (low) default value in case it
+	 * is not specified. Either value must not exceed the clock rate into
+	 * the block, of course.
 	 */
 	 */
-	if (plat->f_max)
-		mmc->f_max = min(host->mclk, plat->f_max);
+	if (mmc->f_max)
+		mmc->f_max = min(host->mclk, mmc->f_max);
 	else
 	else
 		mmc->f_max = min(host->mclk, fmax);
 		mmc->f_max = min(host->mclk, fmax);
 	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
 	dev_dbg(mmc_dev(mmc), "clocking block at %u Hz\n", mmc->f_max);
@@ -1566,8 +1493,15 @@ static int mmci_probe(struct amba_device *dev,
 	else if (plat->ocr_mask)
 	else if (plat->ocr_mask)
 		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
 		dev_warn(mmc_dev(mmc), "Platform OCR mask is ignored\n");
 
 
-	mmc->caps = plat->capabilities;
-	mmc->caps2 = plat->capabilities2;
+	/* DT takes precedence over platform data. */
+	if (!np) {
+		if (!plat->cd_invert)
+			mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+		mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+	}
+
+	/* We support these capabilities. */
+	mmc->caps |= MMC_CAP_CMD23;
 
 
 	if (variant->busy_detect) {
 	if (variant->busy_detect) {
 		mmci_ops.card_busy = mmci_card_busy;
 		mmci_ops.card_busy = mmci_card_busy;
@@ -1579,7 +1513,7 @@ static int mmci_probe(struct amba_device *dev,
 	mmc->ops = &mmci_ops;
 	mmc->ops = &mmci_ops;
 
 
 	/* We support these PM capabilities. */
 	/* We support these PM capabilities. */
-	mmc->pm_caps = MMC_PM_KEEP_POWER;
+	mmc->pm_caps |= MMC_PM_KEEP_POWER;
 
 
 	/*
 	/*
 	 * We can do SGIO
 	 * We can do SGIO
@@ -1616,62 +1550,30 @@ static int mmci_probe(struct amba_device *dev,
 	writel(0, host->base + MMCIMASK1);
 	writel(0, host->base + MMCIMASK1);
 	writel(0xfff, host->base + MMCICLEAR);
 	writel(0xfff, host->base + MMCICLEAR);
 
 
-	if (plat->gpio_cd == -EPROBE_DEFER) {
-		ret = -EPROBE_DEFER;
-		goto err_gpio_cd;
-	}
-	if (gpio_is_valid(plat->gpio_cd)) {
-		ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
-		if (ret == 0)
-			ret = gpio_direction_input(plat->gpio_cd);
-		if (ret == 0)
-			host->gpio_cd = plat->gpio_cd;
-		else if (ret != -ENOSYS)
-			goto err_gpio_cd;
-
-		/*
-		 * A gpio pin that will detect cards when inserted and removed
-		 * will most likely want to trigger on the edges if it is
-		 * 0 when ejected and 1 when inserted (or mutatis mutandis
-		 * for the inverted case) so we request triggers on both
-		 * edges.
-		 */
-		ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd),
-				mmci_cd_irq,
-				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				DRIVER_NAME " (cd)", host);
-		if (ret >= 0)
-			host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
-	}
-	if (plat->gpio_wp == -EPROBE_DEFER) {
-		ret = -EPROBE_DEFER;
-		goto err_gpio_wp;
+	/* If DT, cd/wp gpios must be supplied through it. */
+	if (!np && gpio_is_valid(plat->gpio_cd)) {
+		ret = mmc_gpio_request_cd(mmc, plat->gpio_cd, 0);
+		if (ret)
+			goto clk_disable;
 	}
 	}
-	if (gpio_is_valid(plat->gpio_wp)) {
-		ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)");
-		if (ret == 0)
-			ret = gpio_direction_input(plat->gpio_wp);
-		if (ret == 0)
-			host->gpio_wp = plat->gpio_wp;
-		else if (ret != -ENOSYS)
-			goto err_gpio_wp;
+	if (!np && gpio_is_valid(plat->gpio_wp)) {
+		ret = mmc_gpio_request_ro(mmc, plat->gpio_wp);
+		if (ret)
+			goto clk_disable;
 	}
 	}
 
 
-	if ((host->plat->status || host->gpio_cd != -ENOSYS)
-	    && host->gpio_cd_irq < 0)
-		mmc->caps |= MMC_CAP_NEEDS_POLL;
-
-	ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
+	ret = devm_request_irq(&dev->dev, dev->irq[0], mmci_irq, IRQF_SHARED,
+			DRIVER_NAME " (cmd)", host);
 	if (ret)
 	if (ret)
-		goto unmap;
+		goto clk_disable;
 
 
 	if (!dev->irq[1])
 	if (!dev->irq[1])
 		host->singleirq = true;
 		host->singleirq = true;
 	else {
 	else {
-		ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
-				  DRIVER_NAME " (pio)", host);
+		ret = devm_request_irq(&dev->dev, dev->irq[1], mmci_pio_irq,
+				IRQF_SHARED, DRIVER_NAME " (pio)", host);
 		if (ret)
 		if (ret)
-			goto irq0_free;
+			goto clk_disable;
 	}
 	}
 
 
 	writel(MCI_IRQENABLE, host->base + MMCIMASK0);
 	writel(MCI_IRQENABLE, host->base + MMCIMASK0);
@@ -1693,25 +1595,10 @@ static int mmci_probe(struct amba_device *dev,
 
 
 	return 0;
 	return 0;
 
 
- irq0_free:
-	free_irq(dev->irq[0], host);
- unmap:
-	if (host->gpio_wp != -ENOSYS)
-		gpio_free(host->gpio_wp);
- err_gpio_wp:
-	if (host->gpio_cd_irq >= 0)
-		free_irq(host->gpio_cd_irq, host);
-	if (host->gpio_cd != -ENOSYS)
-		gpio_free(host->gpio_cd);
- err_gpio_cd:
-	iounmap(host->base);
  clk_disable:
  clk_disable:
 	clk_disable_unprepare(host->clk);
 	clk_disable_unprepare(host->clk);
  host_free:
  host_free:
 	mmc_free_host(mmc);
 	mmc_free_host(mmc);
- rel_regions:
-	amba_release_regions(dev);
- out:
 	return ret;
 	return ret;
 }
 }
 
 
@@ -1737,92 +1624,46 @@ static int mmci_remove(struct amba_device *dev)
 		writel(0, host->base + MMCIDATACTRL);
 		writel(0, host->base + MMCIDATACTRL);
 
 
 		mmci_dma_release(host);
 		mmci_dma_release(host);
-		free_irq(dev->irq[0], host);
-		if (!host->singleirq)
-			free_irq(dev->irq[1], host);
-
-		if (host->gpio_wp != -ENOSYS)
-			gpio_free(host->gpio_wp);
-		if (host->gpio_cd_irq >= 0)
-			free_irq(host->gpio_cd_irq, host);
-		if (host->gpio_cd != -ENOSYS)
-			gpio_free(host->gpio_cd);
-
-		iounmap(host->base);
 		clk_disable_unprepare(host->clk);
 		clk_disable_unprepare(host->clk);
-
 		mmc_free_host(mmc);
 		mmc_free_host(mmc);
-
-		amba_release_regions(dev);
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_SUSPEND
-static int mmci_suspend(struct device *dev)
-{
-	struct amba_device *adev = to_amba_device(dev);
-	struct mmc_host *mmc = amba_get_drvdata(adev);
-
-	if (mmc) {
-		struct mmci_host *host = mmc_priv(mmc);
-		pm_runtime_get_sync(dev);
-		writel(0, host->base + MMCIMASK0);
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 
 
-static int mmci_resume(struct device *dev)
-{
-	struct amba_device *adev = to_amba_device(dev);
-	struct mmc_host *mmc = amba_get_drvdata(adev);
-
-	if (mmc) {
-		struct mmci_host *host = mmc_priv(mmc);
-		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
-		pm_runtime_put(dev);
-	}
-
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_PM_RUNTIME
+#ifdef CONFIG_PM
 static void mmci_save(struct mmci_host *host)
 static void mmci_save(struct mmci_host *host)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 
 
-	if (host->variant->pwrreg_nopower) {
-		spin_lock_irqsave(&host->lock, flags);
+	spin_lock_irqsave(&host->lock, flags);
 
 
-		writel(0, host->base + MMCIMASK0);
+	writel(0, host->base + MMCIMASK0);
+	if (host->variant->pwrreg_nopower) {
 		writel(0, host->base + MMCIDATACTRL);
 		writel(0, host->base + MMCIDATACTRL);
 		writel(0, host->base + MMCIPOWER);
 		writel(0, host->base + MMCIPOWER);
 		writel(0, host->base + MMCICLOCK);
 		writel(0, host->base + MMCICLOCK);
-		mmci_reg_delay(host);
-
-		spin_unlock_irqrestore(&host->lock, flags);
 	}
 	}
+	mmci_reg_delay(host);
 
 
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 }
 
 
 static void mmci_restore(struct mmci_host *host)
 static void mmci_restore(struct mmci_host *host)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 
 
-	if (host->variant->pwrreg_nopower) {
-		spin_lock_irqsave(&host->lock, flags);
+	spin_lock_irqsave(&host->lock, flags);
 
 
+	if (host->variant->pwrreg_nopower) {
 		writel(host->clk_reg, host->base + MMCICLOCK);
 		writel(host->clk_reg, host->base + MMCICLOCK);
 		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
 		writel(host->datactrl_reg, host->base + MMCIDATACTRL);
 		writel(host->pwr_reg, host->base + MMCIPOWER);
 		writel(host->pwr_reg, host->base + MMCIPOWER);
-		writel(MCI_IRQENABLE, host->base + MMCIMASK0);
-		mmci_reg_delay(host);
-
-		spin_unlock_irqrestore(&host->lock, flags);
 	}
 	}
+	writel(MCI_IRQENABLE, host->base + MMCIMASK0);
+	mmci_reg_delay(host);
+
+	spin_unlock_irqrestore(&host->lock, flags);
 }
 }
 
 
 static int mmci_runtime_suspend(struct device *dev)
 static int mmci_runtime_suspend(struct device *dev)
@@ -1857,8 +1698,9 @@ static int mmci_runtime_resume(struct device *dev)
 #endif
 #endif
 
 
 static const struct dev_pm_ops mmci_dev_pm_ops = {
 static const struct dev_pm_ops mmci_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume)
-	SET_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+	SET_PM_RUNTIME_PM_OPS(mmci_runtime_suspend, mmci_runtime_resume, NULL)
 };
 };
 
 
 static struct amba_id mmci_ids[] = {
 static struct amba_id mmci_ids[] = {

+ 11 - 3
drivers/mmc/host/mmci.h

@@ -13,6 +13,16 @@
 #define MCI_PWR_ON		0x03
 #define MCI_PWR_ON		0x03
 #define MCI_OD			(1 << 6)
 #define MCI_OD			(1 << 6)
 #define MCI_ROD			(1 << 7)
 #define MCI_ROD			(1 << 7)
+/*
+ * The ST Micro version does not have ROD and reuse the voltage registers for
+ * direction settings.
+ */
+#define MCI_ST_DATA2DIREN	(1 << 2)
+#define MCI_ST_CMDDIREN		(1 << 3)
+#define MCI_ST_DATA0DIREN	(1 << 4)
+#define MCI_ST_DATA31DIREN	(1 << 5)
+#define MCI_ST_FBCLKEN		(1 << 7)
+#define MCI_ST_DATA74DIREN	(1 << 8)
 
 
 #define MMCICLOCK		0x004
 #define MMCICLOCK		0x004
 #define MCI_CLK_ENABLE		(1 << 8)
 #define MCI_CLK_ENABLE		(1 << 8)
@@ -176,9 +186,6 @@ struct mmci_host {
 	struct mmc_data		*data;
 	struct mmc_data		*data;
 	struct mmc_host		*mmc;
 	struct mmc_host		*mmc;
 	struct clk		*clk;
 	struct clk		*clk;
-	int			gpio_cd;
-	int			gpio_wp;
-	int			gpio_cd_irq;
 	bool			singleirq;
 	bool			singleirq;
 
 
 	spinlock_t		lock;
 	spinlock_t		lock;
@@ -186,6 +193,7 @@ struct mmci_host {
 	unsigned int		mclk;
 	unsigned int		mclk;
 	unsigned int		cclk;
 	unsigned int		cclk;
 	u32			pwr_reg;
 	u32			pwr_reg;
+	u32			pwr_reg_add;
 	u32			clk_reg;
 	u32			clk_reg;
 	u32			datactrl_reg;
 	u32			datactrl_reg;
 	u32			busy_status;
 	u32			busy_status;

+ 0 - 42
include/linux/amba/mmci.h

@@ -6,28 +6,9 @@
 
 
 #include <linux/mmc/host.h>
 #include <linux/mmc/host.h>
 
 
-
-/*
- * These defines is places here due to access is needed from machine
- * configuration files. The ST Micro version does not have ROD and
- * reuse the voltage registers for direction settings.
- */
-#define MCI_ST_DATA2DIREN	(1 << 2)
-#define MCI_ST_CMDDIREN		(1 << 3)
-#define MCI_ST_DATA0DIREN	(1 << 4)
-#define MCI_ST_DATA31DIREN	(1 << 5)
-#define MCI_ST_FBCLKEN		(1 << 7)
-#define MCI_ST_DATA74DIREN	(1 << 8)
-
-/* Just some dummy forwarding */
-struct dma_chan;
-
 /**
 /**
  * struct mmci_platform_data - platform configuration for the MMCI
  * struct mmci_platform_data - platform configuration for the MMCI
  * (also known as PL180) block.
  * (also known as PL180) block.
- * @f_max: the maximum operational frequency for this host in this
- * platform configuration. When this is specified it takes precedence
- * over the module parameter for the same frequency.
  * @ocr_mask: available voltages on the 4 pins from the block, this
  * @ocr_mask: available voltages on the 4 pins from the block, this
  * is ignored if a regulator is used, see the MMC_VDD_* masks in
  * is ignored if a regulator is used, see the MMC_VDD_* masks in
  * mmc/host.h
  * mmc/host.h
@@ -42,37 +23,14 @@ struct dma_chan;
  * @gpio_wp: read this GPIO pin to see if the card is write protected
  * @gpio_wp: read this GPIO pin to see if the card is write protected
  * @gpio_cd: read this GPIO pin to detect card insertion
  * @gpio_cd: read this GPIO pin to detect card insertion
  * @cd_invert: true if the gpio_cd pin value is active low
  * @cd_invert: true if the gpio_cd pin value is active low
- * @capabilities: the capabilities of the block as implemented in
- * this platform, signify anything MMC_CAP_* from mmc/host.h
- * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h
- * @sigdir: a bit field indicating for what bits in the MMC bus the host
- * should enable signal direction indication.
- * @dma_filter: function used to select an appropriate RX and TX
- * DMA channel to be used for DMA, if and only if you're deploying the
- * generic DMA engine
- * @dma_rx_param: parameter passed to the DMA allocation
- * filter in order to select an appropriate RX channel. If
- * there is a bidirectional RX+TX channel, then just specify
- * this and leave dma_tx_param set to NULL
- * @dma_tx_param: parameter passed to the DMA allocation
- * filter in order to select an appropriate TX channel. If this
- * is NULL the driver will attempt to use the RX channel as a
- * bidirectional channel
  */
  */
 struct mmci_platform_data {
 struct mmci_platform_data {
-	unsigned int f_max;
 	unsigned int ocr_mask;
 	unsigned int ocr_mask;
 	int (*ios_handler)(struct device *, struct mmc_ios *);
 	int (*ios_handler)(struct device *, struct mmc_ios *);
 	unsigned int (*status)(struct device *);
 	unsigned int (*status)(struct device *);
 	int	gpio_wp;
 	int	gpio_wp;
 	int	gpio_cd;
 	int	gpio_cd;
 	bool	cd_invert;
 	bool	cd_invert;
-	unsigned long capabilities;
-	unsigned long capabilities2;
-	u32 sigdir;
-	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
-	void *dma_rx_param;
-	void *dma_tx_param;
 };
 };
 
 
 #endif
 #endif