Merge tag 'mmc-merge-for-3.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Mar 2012 03:59:45 +0000 (20:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 29 Mar 2012 03:59:45 +0000 (20:59 -0700)
Pull MMC updates from Chris Ball:

Core:
 * Support for MMC 4.5 Data Tag feature -- we tag REQ_META, so devices
   that support Data Tag will provide increased throughput for metadata.
 * Faster detection of card removal on I/O errors.

Drivers:
 * dw_mmc now supports eMMC Power Off Notify, has PCI support, and
   implements pre_req and post_req for asynchronous requests.
 * omap_hsmmc now supports device tree.
 * esdhc now has power management support.
 * sdhci-tegra now supports Tegra30 devices.
 * sdhci-spear now supports hibernation.
 * tmio_mmc now supports using a GPIO for card detection.
 * Intel PCH now supports 8-bit bus transfers.

* tag 'mmc-merge-for-3.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (53 commits)
  mmc: sh_mmcif: simplify bitmask macros
  mmc: sh_mobile_sdhi: support modular mmc-core with non-standard hotplug
  mmc: sh_mobile_sdhi: add a callback for board specific init code
  mmc: tmio: cosmetic: prettify the tmio_mmc_set_ios() function
  mmc: sh_mobile_sdhi: do not manage PM clocks manually
  mmc: tmio_mmc: remove unused sdio_irq_enabled flag
  mmc: tmio_mmc: power status flag doesn't have to be exposed in platform data
  mmc: sh_mobile_sdhi: pass card hotplug GPIO number to TMIO MMC
  mmc: tmio_mmc: support the generic MMC GPIO card hotplug helper
  mmc: tmio: calculate the native hotplug condition only once
  mmc: simplify mmc_cd_gpio_request() by removing two parameters
  mmc: sdhci-pci: allow 8-bit bus width for Intel PCH
  mmc: sdhci: check interrupt flags in ISR again
  mmc: sdhci-pci: Add MSI support
  mmc: core: warn when card doesn't support HPI
  mmc: davinci: Poll status for small size transfers
  mmc: davinci: Eliminate spurious interrupts
  mmc: omap_hsmmc: Avoid a regulator voltage change with dt
  mmc: omap_hsmmc: Convert hsmmc driver to use device tree
  mmc: sdhci-pci: add SDHCI_QUIRK2_HOST_OFF_CARD_ON for Medfield SDIO
  ...

1  2 
arch/arm/mach-exynos/mach-nuri.c
arch/arm/mach-exynos/mach-universal_c210.c
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/hsmmc.h
drivers/mmc/card/block.c
drivers/mmc/host/Kconfig
drivers/mmc/host/sdhci-tegra.c
include/linux/mmc/card.h
include/linux/mmc/core.h
include/linux/mmc/host.h

@@@ -28,7 -28,6 +28,7 @@@
  
  #include <video/platform_lcd.h>
  #include <media/m5mols.h>
 +#include <media/s5k6aa.h>
  #include <media/s5p_fimc.h>
  #include <media/v4l2-mediabus.h>
  
@@@ -76,7 -75,6 +76,7 @@@ enum fixed_regulator_id 
        FIXED_REG_ID_MAX8903,
        FIXED_REG_ID_CAM_A28V,
        FIXED_REG_ID_CAM_12V,
 +      FIXED_REG_ID_CAM_VT_15V,
  };
  
  static struct s3c2410_uartcfg nuri_uartcfgs[] __initdata = {
@@@ -111,13 -109,13 +111,13 @@@ static struct s3c_sdhci_platdata nuri_h
        .max_width              = 8,
        .host_caps              = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
                                MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE | MMC_CAP_ERASE),
+                               MMC_CAP_ERASE),
        .cd_type                = S3C_SDHCI_CD_PERMANENT,
        .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
  };
  
  static struct regulator_consumer_supply emmc_supplies[] = {
 -      REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
 +      REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"),
        REGULATOR_SUPPLY("vmmc", "dw_mmc"),
  };
  
@@@ -150,8 -148,7 +150,7 @@@ static struct platform_device emmc_fixe
  static struct s3c_sdhci_platdata nuri_hsmmc2_data __initdata = {
        .max_width              = 4,
        .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE,
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
        .ext_cd_gpio            = EXYNOS4_GPX3(3),      /* XEINT_27 */
        .ext_cd_gpio_invert     = 1,
        .cd_type                = S3C_SDHCI_CD_GPIO,
@@@ -401,9 -398,6 +400,9 @@@ static struct regulator_consumer_suppl
  static struct regulator_consumer_supply __initdata max8997_ldo5_[] = {
        REGULATOR_SUPPLY("vhsic", "modemctl"), /* MODEM */
  };
 +static struct regulator_consumer_supply nuri_max8997_ldo6_consumer[] = {
 +      REGULATOR_SUPPLY("vdd_reg", "6-003c"), /* S5K6AA camera */
 +};
  static struct regulator_consumer_supply __initdata max8997_ldo7_[] = {
        REGULATOR_SUPPLY("dig_18", "0-001f"), /* HCD803 */
  };
@@@ -418,7 -412,7 +417,7 @@@ static struct regulator_consumer_suppl
        REGULATOR_SUPPLY("vddio", "6-003c"), /* HDC802 */
  };
  static struct regulator_consumer_supply __initdata max8997_ldo13_[] = {
 -      REGULATOR_SUPPLY("vmmc", "s3c-sdhci.2"), /* TFLASH */
 +      REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.2"), /* TFLASH */
  };
  static struct regulator_consumer_supply __initdata max8997_ldo14_[] = {
        REGULATOR_SUPPLY("inmotor", "max8997-haptic"),
@@@ -436,7 -430,7 +435,7 @@@ static struct regulator_consumer_suppl
        REGULATOR_SUPPLY("vdd_arm", NULL), /* CPUFREQ */
  };
  static struct regulator_consumer_supply __initdata max8997_buck2_[] = {
 -      REGULATOR_SUPPLY("vdd_int", NULL), /* CPUFREQ */
 +      REGULATOR_SUPPLY("vdd_int", "exynos4210-busfreq.0"), /* CPUFREQ */
  };
  static struct regulator_consumer_supply __initdata max8997_buck3_[] = {
        REGULATOR_SUPPLY("vdd", "mali_dev.0"), /* G3D of Exynos 4 */
@@@ -551,8 -545,6 +550,8 @@@ static struct regulator_init_data __ini
                        .enabled        = 1,
                },
        },
 +      .num_consumer_supplies  = ARRAY_SIZE(nuri_max8997_ldo6_consumer),
 +      .consumer_supplies      = nuri_max8997_ldo6_consumer,
  };
  
  static struct regulator_init_data __initdata max8997_ldo7_data = {
@@@ -749,7 -741,7 +748,7 @@@ static struct regulator_init_data __ini
        .constraints    = {
                .name           = "VINT_1.1V_C210",
                .min_uV         = 900000,
 -              .max_uV         = 1100000,
 +              .max_uV         = 1200000,
                .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
                .always_on      = 1,
                .state_mem      = {
@@@ -964,6 -956,7 +963,6 @@@ static struct max8997_platform_data __i
        .regulators             = nuri_max8997_regulators,
  
        .buck125_gpios = { EXYNOS4_GPX0(5), EXYNOS4_GPX0(6), EXYNOS4_GPL0(0) },
 -      .buck2_gpiodvs = true,
  
        .buck1_voltage[0] = 1350000, /* 1.35V */
        .buck1_voltage[1] = 1300000, /* 1.3V */
@@@ -1122,30 -1115,7 +1121,30 @@@ static void __init nuri_ehci_init(void
  }
  
  /* CAMERA */
 +static struct regulator_consumer_supply cam_vt_cam15_supply =
 +      REGULATOR_SUPPLY("vdd_core", "6-003c");
 +
 +static struct regulator_init_data cam_vt_cam15_reg_init_data = {
 +      .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
 +      .num_consumer_supplies = 1,
 +      .consumer_supplies = &cam_vt_cam15_supply,
 +};
 +
 +static struct fixed_voltage_config cam_vt_cam15_fixed_voltage_cfg = {
 +      .supply_name    = "VT_CAM_1.5V",
 +      .microvolts     = 1500000,
 +      .gpio           = EXYNOS4_GPE2(2), /* VT_CAM_1.5V_EN */
 +      .enable_high    = 1,
 +      .init_data      = &cam_vt_cam15_reg_init_data,
 +};
 +
 +static struct platform_device cam_vt_cam15_fixed_rdev = {
 +      .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_15V,
 +      .dev = { .platform_data = &cam_vt_cam15_fixed_voltage_cfg },
 +};
 +
  static struct regulator_consumer_supply cam_vdda_supply[] = {
 +      REGULATOR_SUPPLY("vdda", "6-003c"),
        REGULATOR_SUPPLY("a_sensor", "0-001f"),
  };
  
@@@ -1202,21 -1172,6 +1201,21 @@@ static struct s5p_platform_mipi_csis mi
  
  #define GPIO_CAM_MEGA_RST     EXYNOS4_GPY3(7) /* ISP_RESET */
  #define GPIO_CAM_8M_ISP_INT   EXYNOS4_GPL2(5)
 +#define GPIO_CAM_VT_NSTBY     EXYNOS4_GPL2(0)
 +#define GPIO_CAM_VT_NRST      EXYNOS4_GPL2(1)
 +
 +static struct s5k6aa_platform_data s5k6aa_pldata = {
 +      .mclk_frequency = 24000000UL,
 +      .gpio_reset     = { GPIO_CAM_VT_NRST, 0 },
 +      .gpio_stby      = { GPIO_CAM_VT_NSTBY, 0 },
 +      .bus_type       = V4L2_MBUS_PARALLEL,
 +      .horiz_flip     = 1,
 +};
 +
 +static struct i2c_board_info s5k6aa_board_info = {
 +      I2C_BOARD_INFO("S5K6AA", 0x3c),
 +      .platform_data = &s5k6aa_pldata,
 +};
  
  static struct m5mols_platform_data m5mols_platdata = {
        .gpio_reset = GPIO_CAM_MEGA_RST,
@@@ -1229,13 -1184,6 +1228,13 @@@ static struct i2c_board_info m5mols_boa
  
  static struct s5p_fimc_isp_info nuri_camera_sensors[] = {
        {
 +              .flags          = V4L2_MBUS_PCLK_SAMPLE_RISING |
 +                                V4L2_MBUS_VSYNC_ACTIVE_LOW,
 +              .bus_type       = FIMC_ITU_601,
 +              .board_info     = &s5k6aa_board_info,
 +              .clk_frequency  = 24000000UL,
 +              .i2c_bus_num    = 6,
 +      }, {
                .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
                                  V4L2_MBUS_VSYNC_ACTIVE_LOW,
                .bus_type       = FIMC_MIPI_CSI2,
@@@ -1251,13 -1199,11 +1250,13 @@@ static struct s5p_platform_fimc fimc_md
  };
  
  static struct gpio nuri_camera_gpios[] = {
 +      { GPIO_CAM_VT_NSTBY,    GPIOF_OUT_INIT_LOW, "CAM_VGA_NSTBY" },
 +      { GPIO_CAM_VT_NRST,     GPIOF_OUT_INIT_LOW, "CAM_VGA_NRST"  },
        { GPIO_CAM_8M_ISP_INT,  GPIOF_IN,           "8M_ISP_INT"  },
        { GPIO_CAM_MEGA_RST,    GPIOF_OUT_INIT_LOW, "CAM_8M_NRST" },
  };
  
 -static void nuri_camera_init(void)
 +static void __init nuri_camera_init(void)
  {
        s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
                         &s5p_device_mipi_csis0);
                pr_err("%s: Failed to configure 8M_ISP_INT GPIO\n", __func__);
  
        /* Free GPIOs controlled directly by the sensor drivers. */
 +      gpio_free(GPIO_CAM_VT_NRST);
 +      gpio_free(GPIO_CAM_VT_NSTBY);
        gpio_free(GPIO_CAM_MEGA_RST);
  
        if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A)) {
        s5p_gpio_set_drvstr(EXYNOS4_GPJ1(3), S5P_GPIO_DRVSTR_LV4);
  }
  
 +static struct s3c2410_platform_i2c nuri_i2c6_platdata __initdata = {
 +      .frequency      = 400000U,
 +      .sda_delay      = 200,
 +      .bus_num        = 6,
 +};
 +
  static struct s3c2410_platform_i2c nuri_i2c0_platdata __initdata = {
        .frequency      = 400000U,
        .sda_delay      = 200,
  };
  
 +/* DEVFREQ controlling memory/bus */
 +static struct platform_device exynos4_bus_devfreq = {
 +      .name                   = "exynos4210-busfreq",
 +};
 +
  static struct platform_device *nuri_devices[] __initdata = {
        /* Samsung Platform Devices */
        &s3c_device_i2c5, /* PMIC should initialize first */
        &s3c_device_i2c0,
 +      &s3c_device_i2c6,
        &emmc_fixed_voltage,
        &s5p_device_mipi_csis0,
        &s5p_device_fimc0,
        &s3c_device_i2c3,
        &i2c9_gpio,
        &s3c_device_adc,
 +      &s5p_device_g2d,
 +      &s5p_device_jpeg,
        &s3c_device_rtc,
        &s5p_device_mfc,
        &s5p_device_mfc_l,
        &nuri_backlight_device,
        &max8903_fixed_reg_dev,
        &nuri_max8903_device,
 +      &cam_vt_cam15_fixed_rdev,
        &cam_vdda_fixed_rdev,
        &cam_8m_12v_fixed_rdev,
 +      &exynos4_bus_devfreq,
  };
  
  static void __init nuri_map_io(void)
@@@ -1373,7 -1301,6 +1372,7 @@@ static void __init nuri_machine_init(vo
        i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
        i2c9_devs[I2C9_MAX17042].irq = gpio_to_irq(EXYNOS4_GPX2(3));
        i2c_register_board_info(9, i2c9_devs, ARRAY_SIZE(i2c9_devs));
 +      s3c_i2c6_set_platdata(&nuri_i2c6_platdata);
  
        s5p_fimd0_set_platdata(&nuri_fb_pdata);
  
@@@ -47,7 -47,6 +47,7 @@@
  #include <media/v4l2-mediabus.h>
  #include <media/s5p_fimc.h>
  #include <media/m5mols.h>
 +#include <media/s5k6aa.h>
  
  #include "common.h"
  
@@@ -124,10 -123,8 +124,10 @@@ static struct regulator_consumer_suppl
  static struct regulator_consumer_supply lp3974_buck2_consumer =
        REGULATOR_SUPPLY("vddg3d", NULL);
  
 -static struct regulator_consumer_supply lp3974_buck3_consumer =
 -      REGULATOR_SUPPLY("vdet", "s5p-sdo");
 +static struct regulator_consumer_supply lp3974_buck3_consumer[] = {
 +      REGULATOR_SUPPLY("vdet", "s5p-sdo"),
 +      REGULATOR_SUPPLY("vdd_reg", "0-003c"),
 +};
  
  static struct regulator_init_data lp3974_buck1_data = {
        .constraints    = {
@@@ -172,8 -169,8 +172,8 @@@ static struct regulator_init_data lp397
                        .enabled        = 1,
                },
        },
 -      .num_consumer_supplies = 1,
 -      .consumer_supplies = &lp3974_buck3_consumer,
 +      .num_consumer_supplies = ARRAY_SIZE(lp3974_buck3_consumer),
 +      .consumer_supplies = lp3974_buck3_consumer,
  };
  
  static struct regulator_init_data lp3974_buck4_data = {
@@@ -306,9 -303,6 +306,9 @@@ static struct regulator_init_data lp397
        .consumer_supplies = lp3974_ldo8_consumer,
  };
  
 +static struct regulator_consumer_supply lp3974_ldo9_consumer =
 +      REGULATOR_SUPPLY("vddio", "0-003c");
 +
  static struct regulator_init_data lp3974_ldo9_data = {
        .constraints    = {
                .name           = "VCC_2.8V",
                        .enabled        = 1,
                },
        },
 +      .num_consumer_supplies  = 1,
 +      .consumer_supplies      = &lp3974_ldo9_consumer,
  };
  
  static struct regulator_init_data lp3974_ldo10_data = {
@@@ -420,7 -412,6 +420,7 @@@ static struct regulator_init_data lp397
  };
  
  static struct regulator_consumer_supply lp3974_ldo16_consumer[] = {
 +      REGULATOR_SUPPLY("vdda", "0-003c"),
        REGULATOR_SUPPLY("a_sensor", "0-001f"),
  };
  
@@@ -745,14 -736,13 +745,13 @@@ static struct platform_device universal
  static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = {
        .max_width              = 8,
        .host_caps              = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE),
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
        .cd_type                = S3C_SDHCI_CD_PERMANENT,
        .clk_type               = S3C_SDHCI_CLK_DIV_EXTERNAL,
  };
  
  static struct regulator_consumer_supply mmc0_supplies[] = {
 -      REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
 +      REGULATOR_SUPPLY("vmmc", "exynos4-sdhci.0"),
  };
  
  static struct regulator_init_data mmc0_fixed_voltage_init_data = {
@@@ -784,8 -774,7 +783,7 @@@ static struct platform_device mmc0_fixe
  static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = {
        .max_width              = 4,
        .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE,
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
        .ext_cd_gpio            = EXYNOS4_GPX3(4),      /* XEINT_28 */
        .ext_cd_gpio_invert     = 1,
        .cd_type                = S3C_SDHCI_CD_GPIO,
  static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = {
        .max_width              = 4,
        .host_caps              = MMC_CAP_4_BIT_DATA |
-                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
-                               MMC_CAP_DISABLE,
+                               MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
        .cd_type                = S3C_SDHCI_CD_EXTERNAL,
  };
  
@@@ -828,8 -816,6 +825,8 @@@ static struct s3c_fb_pd_win universal_f
        },
        .max_bpp        = 32,
        .default_bpp    = 16,
 +      .virtual_x      = 480,
 +      .virtual_y      = 2 * 800,
  };
  
  static struct s3c_fb_platdata universal_lcd_pdata __initdata = {
        .setup_gpio     = exynos4_fimd0_gpio_setup_24bpp,
  };
  
 +static struct regulator_consumer_supply cam_vt_dio_supply =
 +      REGULATOR_SUPPLY("vdd_core", "0-003c");
 +
 +static struct regulator_init_data cam_vt_dio_reg_init_data = {
 +      .constraints = { .valid_ops_mask = REGULATOR_CHANGE_STATUS },
 +      .num_consumer_supplies = 1,
 +      .consumer_supplies = &cam_vt_dio_supply,
 +};
 +
 +static struct fixed_voltage_config cam_vt_dio_fixed_voltage_cfg = {
 +      .supply_name    = "CAM_VT_D_IO",
 +      .microvolts     = 2800000,
 +      .gpio           = EXYNOS4_GPE2(1), /* CAM_PWR_EN2 */
 +      .enable_high    = 1,
 +      .init_data      = &cam_vt_dio_reg_init_data,
 +};
 +
 +static struct platform_device cam_vt_dio_fixed_reg_dev = {
 +      .name = "reg-fixed-voltage", .id = FIXED_REG_ID_CAM_VT_DIO,
 +      .dev = { .platform_data = &cam_vt_dio_fixed_voltage_cfg },
 +};
 +
  static struct regulator_consumer_supply cam_i_core_supply =
        REGULATOR_SUPPLY("core", "0-001f");
  
@@@ -918,28 -882,6 +915,28 @@@ static struct s5p_platform_mipi_csis mi
  #define GPIO_CAM_LEVEL_EN(n)  EXYNOS4_GPE4(n + 3)
  #define GPIO_CAM_8M_ISP_INT   EXYNOS4_GPX1(5) /* XEINT_13 */
  #define GPIO_CAM_MEGA_nRST    EXYNOS4_GPE2(5)
 +#define GPIO_CAM_VGA_NRST     EXYNOS4_GPE4(7)
 +#define GPIO_CAM_VGA_NSTBY    EXYNOS4_GPE4(6)
 +
 +static int s5k6aa_set_power(int on)
 +{
 +      gpio_set_value(GPIO_CAM_LEVEL_EN(2), !!on);
 +      return 0;
 +}
 +
 +static struct s5k6aa_platform_data s5k6aa_platdata = {
 +      .mclk_frequency = 21600000UL,
 +      .gpio_reset     = { GPIO_CAM_VGA_NRST, 0 },
 +      .gpio_stby      = { GPIO_CAM_VGA_NSTBY, 0 },
 +      .bus_type       = V4L2_MBUS_PARALLEL,
 +      .horiz_flip     = 1,
 +      .set_power      = s5k6aa_set_power,
 +};
 +
 +static struct i2c_board_info s5k6aa_board_info = {
 +      I2C_BOARD_INFO("S5K6AA", 0x3C),
 +      .platform_data = &s5k6aa_platdata,
 +};
  
  static int m5mols_set_power(struct device *dev, int on)
  {
@@@ -964,14 -906,6 +961,14 @@@ static struct s5p_fimc_isp_info univers
                .mux_id         = 0,
                .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
                                  V4L2_MBUS_VSYNC_ACTIVE_LOW,
 +              .bus_type       = FIMC_ITU_601,
 +              .board_info     = &s5k6aa_board_info,
 +              .i2c_bus_num    = 0,
 +              .clk_frequency  = 24000000UL,
 +      }, {
 +              .mux_id         = 0,
 +              .flags          = V4L2_MBUS_PCLK_SAMPLE_FALLING |
 +                                V4L2_MBUS_VSYNC_ACTIVE_LOW,
                .bus_type       = FIMC_MIPI_CSI2,
                .board_info     = &m5mols_board_info,
                .i2c_bus_num    = 0,
@@@ -990,11 -924,9 +987,11 @@@ static struct gpio universal_camera_gpi
        { GPIO_CAM_LEVEL_EN(2), GPIOF_OUT_INIT_LOW,  "CAM_LVL_EN2" },
        { GPIO_CAM_8M_ISP_INT,  GPIOF_IN,            "8M_ISP_INT"  },
        { GPIO_CAM_MEGA_nRST,   GPIOF_OUT_INIT_LOW,  "CAM_8M_NRST" },
 +      { GPIO_CAM_VGA_NRST,    GPIOF_OUT_INIT_LOW,  "CAM_VGA_NRST"  },
 +      { GPIO_CAM_VGA_NSTBY,   GPIOF_OUT_INIT_LOW,  "CAM_VGA_NSTBY" },
  };
  
 -static void universal_camera_init(void)
 +static void __init universal_camera_init(void)
  {
        s3c_set_platdata(&mipi_csis_platdata, sizeof(mipi_csis_platdata),
                         &s5p_device_mipi_csis0);
        /* Free GPIOs controlled directly by the sensor drivers. */
        gpio_free(GPIO_CAM_MEGA_nRST);
        gpio_free(GPIO_CAM_8M_ISP_INT);
 +      gpio_free(GPIO_CAM_VGA_NRST);
 +      gpio_free(GPIO_CAM_VGA_NSTBY);
  
        if (exynos4_fimc_setup_gpio(S5P_CAMPORT_A))
                pr_err("Camera port A setup failed\n");
@@@ -1029,7 -959,6 +1026,7 @@@ static struct platform_device *universa
        &s5p_device_fimc1,
        &s5p_device_fimc2,
        &s5p_device_fimc3,
 +      &s5p_device_g2d,
        &mmc0_fixed_voltage,
        &s3c_device_hsmmc0,
        &s3c_device_hsmmc2,
        &universal_gpio_keys,
        &s5p_device_onenand,
        &s5p_device_fimd0,
 +      &s5p_device_jpeg,
        &s5p_device_mfc,
        &s5p_device_mfc_l,
        &s5p_device_mfc_r,
 +      &cam_vt_dio_fixed_reg_dev,
        &cam_i_core_fixed_reg_dev,
        &cam_s_if_fixed_reg_dev,
        &s5p_device_fimc_md,
@@@ -1065,7 -992,7 +1062,7 @@@ static void __init universal_map_io(voi
        s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
  }
  
 -void s5p_tv_setup(void)
 +static void s5p_tv_setup(void)
  {
        /* direct HPD to HDMI chip */
        gpio_request_one(EXYNOS4_GPX3(7), GPIOF_IN, "hpd-plug");
@@@ -293,8 -293,8 +293,8 @@@ static inline void omap_hsmmc_mux(struc
        }
  }
  
 -static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 -                               struct omap_mmc_platform_data *mmc)
 +static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
 +                                      struct omap_mmc_platform_data *mmc)
  {
        char *hc_name;
  
        mmc->slots[0].pm_caps = c->pm_caps;
        mmc->slots[0].internal_clock = !c->ext_clock;
        mmc->dma_mask = 0xffffffff;
+       mmc->max_freq = c->max_freq;
        if (cpu_is_omap44xx())
                mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
        else
  }
  
  static int omap_hsmmc_done;
 +
 +void omap_hsmmc_late_init(struct omap2_hsmmc_info *c)
 +{
 +      struct platform_device *pdev;
 +      struct omap_mmc_platform_data *mmc_pdata;
 +      int res;
 +
 +      if (omap_hsmmc_done != 1)
 +              return;
 +
 +      omap_hsmmc_done++;
 +
 +      for (; c->mmc; c++) {
 +              if (!c->deferred)
 +                      continue;
 +
 +              pdev = c->pdev;
 +              if (!pdev)
 +                      continue;
 +
 +              mmc_pdata = pdev->dev.platform_data;
 +              if (!mmc_pdata)
 +                      continue;
 +
 +              mmc_pdata->slots[0].switch_pin = c->gpio_cd;
 +              mmc_pdata->slots[0].gpio_wp = c->gpio_wp;
 +
 +              res = omap_device_register(pdev);
 +              if (res)
 +                      pr_err("Could not late init MMC %s\n",
 +                             c->name);
 +      }
 +}
 +
  #define MAX_OMAP_MMC_HWMOD_NAME_LEN           16
  
 -void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
 +static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
 +                                      int ctrl_nr)
  {
        struct omap_hwmod *oh;
 +      struct omap_hwmod *ohs[1];
 +      struct omap_device *od;
        struct platform_device *pdev;
        char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
        struct omap_mmc_platform_data *mmc_data;
        struct omap_mmc_dev_attr *mmc_dev_attr;
        char *name;
 -      int l;
 +      int res;
  
        mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
        if (!mmc_data) {
                pr_err("Cannot allocate memory for mmc device!\n");
 -              goto done;
 +              return;
        }
  
 -      if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) {
 -              pr_err("%s fails!\n", __func__);
 -              goto done;
 -      }
 +      res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
 +      if (res < 0)
 +              goto free_mmc;
 +
        omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
  
        name = "omap_hsmmc";
 -
 -      l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
 +      res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
                     "mmc%d", ctrl_nr);
 -      WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
 +      WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
             "String buffer overflow in MMC%d device setup\n", ctrl_nr);
 +
        oh = omap_hwmod_lookup(oh_name);
        if (!oh) {
                pr_err("Could not look up %s\n", oh_name);
 -              kfree(mmc_data->slots[0].name);
 -              goto done;
 +              goto free_name;
        }
 -
 +      ohs[0] = oh;
        if (oh->dev_attr != NULL) {
                mmc_dev_attr = oh->dev_attr;
                mmc_data->controller_flags = mmc_dev_attr->flags;
        }
  
 -      pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
 -              sizeof(struct omap_mmc_platform_data), NULL, 0, false);
 -      if (IS_ERR(pdev)) {
 -              WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
 -              kfree(mmc_data->slots[0].name);
 -              goto done;
 +      pdev = platform_device_alloc(name, ctrl_nr - 1);
 +      if (!pdev) {
 +              pr_err("Could not allocate pdev for %s\n", name);
 +              goto free_name;
        }
 -      /*
 -       * return device handle to board setup code
 -       * required to populate for regulator framework structure
 -       */
 -      hsmmcinfo->dev = &pdev->dev;
 +      dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
 +
 +      od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
 +      if (!od) {
 +              pr_err("Could not allocate od for %s\n", name);
 +              goto put_pdev;
 +      }
 +
 +      res = platform_device_add_data(pdev, mmc_data,
 +                            sizeof(struct omap_mmc_platform_data));
 +      if (res) {
 +              pr_err("Could not add pdata for %s\n", name);
 +              goto put_pdev;
 +      }
 +
 +      hsmmcinfo->pdev = pdev;
 +
 +      if (hsmmcinfo->deferred)
 +              goto free_mmc;
 +
 +      res = omap_device_register(pdev);
 +      if (res) {
 +              pr_err("Could not register od for %s\n", name);
 +              goto free_od;
 +      }
 +
 +      goto free_mmc;
 +
 +free_od:
 +      omap_device_delete(od);
 +
 +put_pdev:
 +      platform_device_put(pdev);
 +
 +free_name:
 +      kfree(mmc_data->slots[0].name);
  
 -done:
 +free_mmc:
        kfree(mmc_data);
  }
  
 -void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
 +void __init omap_hsmmc_init(struct omap2_hsmmc_info *controllers)
  {
        u32 reg;
  
        }
  
        for (; controllers->mmc; controllers++)
 -              omap_init_hsmmc(controllers, controllers->mmc);
 +              omap_hsmmc_init_one(controllers, controllers->mmc);
  
  }
  
@@@ -21,12 -21,13 +21,14 @@@ struct omap2_hsmmc_info 
        bool    no_off;         /* power_saving and power is not to go off */
        bool    no_off_init;    /* no power off when not in MMC sleep state */
        bool    vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
 +      bool    deferred;       /* mmc needs a deferred probe */
        int     gpio_cd;        /* or -EINVAL */
        int     gpio_wp;        /* or -EINVAL */
        char    *name;          /* or NULL for default */
 -      struct device *dev;     /* returned: pointer to mmc adapter */
 +      struct platform_device *pdev;   /* mmc controller instance */
        int     ocr_mask;       /* temporary HACK */
+       int     max_freq;       /* maximum clock, if constrained by external
+                                * circuitry, or 0 for default */
        /* Remux (pad configuration) when powering on/off */
        void (*remux)(struct device *dev, int slot, int power_on);
        /* init some special card */
  
  #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
  
 -void omap2_hsmmc_init(struct omap2_hsmmc_info *);
 +void omap_hsmmc_init(struct omap2_hsmmc_info *);
 +void omap_hsmmc_late_init(struct omap2_hsmmc_info *);
  
  #else
  
 -static inline void omap2_hsmmc_init(struct omap2_hsmmc_info *info)
 +static inline void omap_hsmmc_init(struct omap2_hsmmc_info *info)
 +{
 +}
 +
 +static inline void omap_hsmmc_late_init(struct omap2_hsmmc_info *info)
  {
  }
  
diff --combined drivers/mmc/card/block.c
@@@ -41,6 -41,7 +41,6 @@@
  #include <linux/mmc/mmc.h>
  #include <linux/mmc/sd.h>
  
 -#include <asm/system.h>
  #include <asm/uaccess.h>
  
  #include "queue.h"
@@@ -1079,6 -1080,7 +1079,7 @@@ static void mmc_blk_rw_rq_prep(struct m
        struct mmc_blk_request *brq = &mqrq->brq;
        struct request *req = mqrq->req;
        struct mmc_blk_data *md = mq->data;
+       bool do_data_tag;
  
        /*
         * Reliable writes are used to implement Forced Unit Access and
                mmc_apply_rel_rw(brq, card, req);
  
        /*
+        * Data tag is used only during writing meta data to speed
+        * up write and any subsequent read of this meta data
+        */
+       do_data_tag = (card->ext_csd.data_tag_unit_size) &&
+               (req->cmd_flags & REQ_META) &&
+               (rq_data_dir(req) == WRITE) &&
+               ((brq->data.blocks * brq->data.blksz) >=
+                card->ext_csd.data_tag_unit_size);
+       /*
         * Pre-defined multi-block transfers are preferable to
         * open ended-ones (and necessary for reliable writes).
         * However, it is not sufficient to just send CMD23,
         * We'll avoid using CMD23-bounded multiblock writes for
         * these, while retaining features like reliable writes.
         */
-       if ((md->flags & MMC_BLK_CMD23) &&
-           mmc_op_multi(brq->cmd.opcode) &&
-           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
+       if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) &&
+           (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) ||
+            do_data_tag)) {
                brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
                brq->sbc.arg = brq->data.blocks |
-                       (do_rel_wr ? (1 << 31) : 0);
+                       (do_rel_wr ? (1 << 31) : 0) |
+                       (do_data_tag ? (1 << 29) : 0);
                brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
                brq->mrq.sbc = &brq->sbc;
        }
diff --combined drivers/mmc/host/Kconfig
@@@ -395,7 -395,7 +395,7 @@@ config MMC_SP
  
  config MMC_S3C
        tristate "Samsung S3C SD/MMC Card Interface support"
 -      depends on ARCH_S3C2410
 +      depends on ARCH_S3C24XX
        help
          This selects a driver for the MCI interface found in
            Samsung's S3C2410, S3C2412, S3C2440, S3C2442 CPUs.
@@@ -533,6 -533,31 +533,31 @@@ config MMC_DW_IDMA
          Designware Mobile Storage IP block. This disables the external DMA
          interface.
  
+ config MMC_DW_PLTFM
+       tristate "Synopsys Designware MCI Support as platform device"
+       depends on MMC_DW
+       default y
+       help
+         This selects the common helper functions support for Host Controller
+         Interface based platform driver. Please select this option if the IP
+         is present as a platform device. This is the common interface for the
+         Synopsys Designware IP.
+         If you have a controller with this interface, say Y or M here.
+         If unsure, say Y.
+ config MMC_DW_PCI
+       tristate "Synopsys Designware MCI support on PCI bus"
+       depends on MMC_DW && PCI
+       help
+         This selects the PCI bus for the Synopsys Designware Mobile Storage IP.
+         Select this option if the IP is present on PCI platform.
+         If you have a controller with this interface, say Y or M here.
+         If unsure, say N.
  config MMC_SH_MMCIF
        tristate "SuperH Internal MMCIF support"
        depends on MMC_BLOCK && (SUPERH || ARCH_SHMOBILE)
  #include <linux/clk.h>
  #include <linux/io.h>
  #include <linux/of.h>
+ #include <linux/of_device.h>
  #include <linux/of_gpio.h>
  #include <linux/gpio.h>
  #include <linux/mmc/card.h>
  #include <linux/mmc/host.h>
 -#include <linux/module.h>
  
  #include <asm/gpio.h>
  
  
  #include "sdhci-pltfm.h"
  
+ #define NVQUIRK_FORCE_SDHCI_SPEC_200  BIT(0)
+ #define NVQUIRK_ENABLE_BLOCK_GAP_DET  BIT(1)
+ struct sdhci_tegra_soc_data {
+       struct sdhci_pltfm_data *pdata;
+       u32 nvquirks;
+ };
+ struct sdhci_tegra {
+       const struct tegra_sdhci_platform_data *plat;
+       const struct sdhci_tegra_soc_data *soc_data;
+ };
  static u32 tegra_sdhci_readl(struct sdhci_host *host, int reg)
  {
        u32 val;
  
  static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
  {
-       if (unlikely(reg == SDHCI_HOST_VERSION)) {
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_tegra *tegra_host = pltfm_host->priv;
+       const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
+       if (unlikely((soc_data->nvquirks & NVQUIRK_FORCE_SDHCI_SPEC_200) &&
+                       (reg == SDHCI_HOST_VERSION))) {
                /* Erratum: Version register is invalid in HW. */
                return SDHCI_SPEC_200;
        }
  
  static void tegra_sdhci_writel(struct sdhci_host *host, u32 val, int reg)
  {
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_tegra *tegra_host = pltfm_host->priv;
+       const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
        /* Seems like we're getting spurious timeout and crc errors, so
         * disable signalling of them. In case of real errors software
         * timers should take care of eventually detecting them.
@@@ -65,7 -89,8 +88,8 @@@
  
        writel(val, host->ioaddr + reg);
  
-       if (unlikely(reg == SDHCI_INT_ENABLE)) {
+       if (unlikely((soc_data->nvquirks & NVQUIRK_ENABLE_BLOCK_GAP_DET) &&
+                       (reg == SDHCI_INT_ENABLE))) {
                /* Erratum: Must enable block gap interrupt detection */
                u8 gap_ctrl = readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL);
                if (val & SDHCI_INT_CARD_INT)
        }
  }
  
- static unsigned int tegra_sdhci_get_ro(struct sdhci_host *sdhci)
+ static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
  {
-       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhci);
-       struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_tegra *tegra_host = pltfm_host->priv;
+       const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
  
        if (!gpio_is_valid(plat->wp_gpio))
                return -1;
@@@ -98,7 -124,8 +123,8 @@@ static irqreturn_t carddetect_irq(int i
  static int tegra_sdhci_8bit(struct sdhci_host *host, int bus_width)
  {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-       struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
+       struct sdhci_tegra *tegra_host = pltfm_host->priv;
+       const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
        u32 ctrl;
  
        ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
@@@ -124,16 -151,44 +150,44 @@@ static struct sdhci_ops tegra_sdhci_op
        .platform_8bit_width = tegra_sdhci_8bit,
  };
  
- static struct sdhci_pltfm_data sdhci_tegra_pdata = {
+ #ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ static struct sdhci_pltfm_data sdhci_tegra20_pdata = {
+       .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+                 SDHCI_QUIRK_SINGLE_POWER_WRITE |
+                 SDHCI_QUIRK_NO_HISPD_BIT |
+                 SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+       .ops  = &tegra_sdhci_ops,
+ };
+ static struct sdhci_tegra_soc_data soc_data_tegra20 = {
+       .pdata = &sdhci_tegra20_pdata,
+       .nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 |
+                   NVQUIRK_ENABLE_BLOCK_GAP_DET,
+ };
+ #endif
+ #ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ static struct sdhci_pltfm_data sdhci_tegra30_pdata = {
        .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
+                 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
                  SDHCI_QUIRK_SINGLE_POWER_WRITE |
                  SDHCI_QUIRK_NO_HISPD_BIT |
                  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
        .ops  = &tegra_sdhci_ops,
  };
  
+ static struct sdhci_tegra_soc_data soc_data_tegra30 = {
+       .pdata = &sdhci_tegra30_pdata,
+ };
+ #endif
  static const struct of_device_id sdhci_tegra_dt_match[] __devinitdata = {
-       { .compatible = "nvidia,tegra20-sdhci", },
+ #ifdef CONFIG_ARCH_TEGRA_3x_SOC
+       { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
+ #endif
+ #ifdef CONFIG_ARCH_TEGRA_2x_SOC
+       { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
+ #endif
        {}
  };
  MODULE_DEVICE_TABLE(of, sdhci_dt_ids);
@@@ -164,13 -219,22 +218,22 @@@ static struct tegra_sdhci_platform_dat
  
  static int __devinit sdhci_tegra_probe(struct platform_device *pdev)
  {
+       const struct of_device_id *match;
+       const struct sdhci_tegra_soc_data *soc_data;
+       struct sdhci_host *host;
        struct sdhci_pltfm_host *pltfm_host;
        struct tegra_sdhci_platform_data *plat;
-       struct sdhci_host *host;
+       struct sdhci_tegra *tegra_host;
        struct clk *clk;
        int rc;
  
-       host = sdhci_pltfm_init(pdev, &sdhci_tegra_pdata);
+       match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
+       if (match)
+               soc_data = match->data;
+       else
+               soc_data = &soc_data_tegra20;
+       host = sdhci_pltfm_init(pdev, soc_data->pdata);
        if (IS_ERR(host))
                return PTR_ERR(host);
  
                goto err_no_plat;
        }
  
-       pltfm_host->priv = plat;
+       tegra_host = devm_kzalloc(&pdev->dev, sizeof(*tegra_host), GFP_KERNEL);
+       if (!tegra_host) {
+               dev_err(mmc_dev(host->mmc), "failed to allocate tegra_host\n");
+               rc = -ENOMEM;
+               goto err_no_plat;
+       }
+       tegra_host->plat = plat;
+       tegra_host->soc_data = soc_data;
+       pltfm_host->priv = tegra_host;
  
        if (gpio_is_valid(plat->power_gpio)) {
                rc = gpio_request(plat->power_gpio, "sdhci_power");
@@@ -283,7 -357,8 +356,8 @@@ static int __devexit sdhci_tegra_remove
  {
        struct sdhci_host *host = platform_get_drvdata(pdev);
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-       struct tegra_sdhci_platform_data *plat = pltfm_host->priv;
+       struct sdhci_tegra *tegra_host = pltfm_host->priv;
+       const struct tegra_sdhci_platform_data *plat = tegra_host->plat;
        int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);
  
        sdhci_remove_host(host, dead);
@@@ -326,5 -401,5 +400,5 @@@ static struct platform_driver sdhci_teg
  module_platform_driver(sdhci_tegra_driver);
  
  MODULE_DESCRIPTION("SDHCI driver for Tegra");
- MODULE_AUTHOR(" Google, Inc.");
+ MODULE_AUTHOR("Google, Inc.");
  MODULE_LICENSE("GPL v2");
diff --combined include/linux/mmc/card.h
@@@ -10,7 -10,6 +10,7 @@@
  #ifndef LINUX_MMC_CARD_H
  #define LINUX_MMC_CARD_H
  
 +#include <linux/device.h>
  #include <linux/mmc/core.h>
  #include <linux/mod_devicetable.h>
  
@@@ -72,6 -71,8 +72,8 @@@ struct mmc_ext_csd 
        bool                    hpi_en;                 /* HPI enablebit */
        bool                    hpi;                    /* HPI support bit */
        unsigned int            hpi_cmd;                /* cmd used as HPI */
+       unsigned int            data_sector_size;       /* 512 bytes or 4KB */
+       unsigned int            data_tag_unit_size;     /* DATA TAG UNIT size */
        unsigned int            boot_ro_lock;           /* ro lock support */
        bool                    boot_ro_lockable;
        u8                      raw_partition_support;  /* 160 */
diff --combined include/linux/mmc/core.h
@@@ -9,7 -9,7 +9,7 @@@
  #define LINUX_MMC_CORE_H
  
  #include <linux/interrupt.h>
 -#include <linux/device.h>
 +#include <linux/completion.h>
  
  struct request;
  struct mmc_data;
@@@ -175,7 -175,6 +175,6 @@@ extern unsigned int mmc_align_data_size
  
  extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
  extern void mmc_release_host(struct mmc_host *host);
- extern void mmc_do_release_host(struct mmc_host *host);
  extern int mmc_try_claim_host(struct mmc_host *host);
  
  extern int mmc_flush_cache(struct mmc_card *);
diff --combined include/linux/mmc/host.h
@@@ -12,7 -12,6 +12,7 @@@
  
  #include <linux/leds.h>
  #include <linux/sched.h>
 +#include <linux/device.h>
  #include <linux/fault-inject.h>
  
  #include <linux/mmc/core.h>
@@@ -81,34 -80,11 +81,11 @@@ struct mmc_ios 
  
  struct mmc_host_ops {
        /*
-        * Hosts that support power saving can use the 'enable' and 'disable'
-        * methods to exit and enter power saving states. 'enable' is called
-        * when the host is claimed and 'disable' is called (or scheduled with
-        * a delay) when the host is released. The 'disable' is scheduled if
-        * the disable delay set by 'mmc_set_disable_delay()' is non-zero,
-        * otherwise 'disable' is called immediately. 'disable' may be
-        * scheduled repeatedly, to permit ever greater power saving at the
-        * expense of ever greater latency to re-enable. Rescheduling is
-        * determined by the return value of the 'disable' method. A positive
-        * value gives the delay in milliseconds.
-        *
-        * In the case where a host function (like set_ios) may be called
-        * with or without the host claimed, enabling and disabling can be
-        * done directly and will nest correctly. Call 'mmc_host_enable()' and
-        * 'mmc_host_lazy_disable()' for this purpose, but note that these
-        * functions must be paired.
-        *
-        * Alternatively, 'mmc_host_enable()' may be paired with
-        * 'mmc_host_disable()' which calls 'disable' immediately.  In this
-        * case the 'disable' method will be called with 'lazy' set to 0.
-        * This is mainly useful for error paths.
-        *
-        * Because lazy disable may be called from a work queue, the 'disable'
-        * method must claim the host when 'lazy' != 0, which will work
-        * correctly because recursion is detected and handled.
+        * 'enable' is called when the host is claimed and 'disable' is called
+        * when the host is released. 'enable' and 'disable' are deprecated.
         */
        int (*enable)(struct mmc_host *host);
-       int (*disable)(struct mmc_host *host, int lazy);
+       int (*disable)(struct mmc_host *host);
        /*
         * It is optional for the host to implement pre_req and post_req in
         * order to support double buffering of requests (prepare one
@@@ -219,7 -195,7 +196,7 @@@ struct mmc_host 
  #define MMC_CAP_SPI           (1 << 4)        /* Talks only SPI protocols */
  #define MMC_CAP_NEEDS_POLL    (1 << 5)        /* Needs polling for card-detection */
  #define MMC_CAP_8_BIT_DATA    (1 << 6)        /* Can the host do 8 bit transfers */
- #define MMC_CAP_DISABLE               (1 << 7)        /* Can the host be disabled */
  #define MMC_CAP_NONREMOVABLE  (1 << 8)        /* Nonremovable e.g. eMMC */
  #define MMC_CAP_WAIT_WHILE_BUSY       (1 << 9)        /* Waits while card is busy */
  #define MMC_CAP_ERASE         (1 << 10)       /* Allow erase/trim commands */
  #define MMC_CAP2_HS200                (MMC_CAP2_HS200_1_8V_SDR | \
                                 MMC_CAP2_HS200_1_2V_SDR)
  #define MMC_CAP2_BROKEN_VOLTAGE       (1 << 7)        /* Use the broken voltage */
+ #define MMC_CAP2_DETECT_ON_ERR        (1 << 8)        /* On I/O err check card removal */
+ #define MMC_CAP2_HC_ERASE_SZ  (1 << 9)        /* High-capacity erase size */
  
        mmc_pm_flag_t           pm_caps;        /* supported pm features */
        unsigned int        power_notify_type;
        unsigned int            removed:1;      /* host is being removed */
  #endif
  
-       /* Only used with MMC_CAP_DISABLE */
-       int                     enabled;        /* host is enabled */
        int                     rescan_disable; /* disable card detection */
-       int                     nesting_cnt;    /* "enable" nesting count */
-       int                     en_dis_recurs;  /* detect recursion */
-       unsigned int            disable_delay;  /* disable delay in msecs */
-       struct delayed_work     disable;        /* disabling work */
  
        struct mmc_card         *card;          /* device attached to this host */
  
@@@ -407,17 -379,8 +380,8 @@@ int mmc_card_awake(struct mmc_host *hos
  int mmc_card_sleep(struct mmc_host *host);
  int mmc_card_can_sleep(struct mmc_host *host);
  
- int mmc_host_enable(struct mmc_host *host);
- int mmc_host_disable(struct mmc_host *host);
- int mmc_host_lazy_disable(struct mmc_host *host);
  int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *);
  
- static inline void mmc_set_disable_delay(struct mmc_host *host,
-                                        unsigned int disable_delay)
- {
-       host->disable_delay = disable_delay;
- }
  /* Module parameter */
  extern bool mmc_assume_removable;