Commit dee02770 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mmc-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc

Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Introduce host claiming by context to support blkmq
   - Preparations for enabling CQE (eMMC CMDQ) requests
   - Re-factorizations to prepare for blkmq support
   - Re-factorizations to prepare for CQE support
   - Fix signal voltage switch for SD cards without power cycle
   - Convert RPMB to a character device
   - Export eMMC revision via sysfs
   - Support eMMC DT binding for fixed driver type
   - Document mmc_regulator_get_supply() API

 MMC host:
   - omap_hsmmc: Updated regulator management for PBIAS
   - sdhci-omap: Add new OMAP SDHCI driver
   - meson-mx-sdio: New driver for the Amlogic Meson8 and Meson8b SoCs
   - sdhci-pci: Add support for Intel CDF
   - sdhci-acpi: Fix voltage switch for some Intel host controllers
   - sdhci-msm: Enable delay circuit calibration clocks
   - sdhci-msm: Manage power IRQ properly
   - mediatek: Add support of mt2701/mt2712
   - mediatek: Updates management of clocks and tunings
   - mediatek: Upgrade eMMC HS400 support
   - rtsx_pci: Update tuning for gen3 PCI-Express
   - renesas_sdhi: Support R-Car Gen[123] fallback compatibility strings
   - Catch all errors when getting regulators
   - Various additional improvements and cleanups"

* tag 'mmc-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (91 commits)
  sdhci-fujitsu: add support for setting the CMD_DAT_DELAY attribute
  dt-bindings: sdhci-fujitsu: document cmd-dat-delay property
  mmc: tmio: Replace msleep() of 20ms or less with usleep_range()
  mmc: dw_mmc: Convert timers to use timer_setup()
  mmc: dw_mmc: Cleanup the DTO timer like the CTO one
  mmc: vub300: Use common code in __download_offload_pseudocode()
  mmc: tmio: Use common error handling code in tmio_mmc_host_probe()
  mmc: Convert timers to use timer_setup()
  mmc: sdhci-acpi: Fix voltage switch for some Intel host controllers
  mmc: sdhci-acpi: Let devices define their own private data
  mmc: mediatek: perfer to use rise edge latching for cmd line
  mmc: mediatek: improve eMMC hs400 mode read performance
  mmc: mediatek: add latch-ck support
  mmc: mediatek: add support of source_cg clock
  mmc: mediatek: add stop_clk fix and enhance_rx support
  mmc: mediatek: add busy_check support
  mmc: mediatek: add async fifo and data tune support
  mmc: mediatek: add pad_tune0 support
  mmc: mediatek: make hs400_tune_response only for mt8173
  arm64: dts: mt8173: remove "mediatek, mt8135-mmc" from mmc nodes
  ...
parents e4a8ca3b 06641e8d
What: /sys/bus/mmc/devices/.../rev
Date: October 2017
Contact: Jin Qian <jinqian@android.com>
Description: Extended CSD revision number
* Amlogic Meson6, Meson8 and Meson8b SDIO/MMC controller
The highspeed MMC host controller on Amlogic SoCs provides an interface
for MMC, SD, SDIO and SDHC types of memory cards.
Supported maximum speeds are the ones of the eMMC standard 4.41 as well
as the speed of SD standard 2.0.
The hardware provides an internal "mux" which allows up to three slots
to be controlled. Only one slot can be accessed at a time.
Required properties:
- compatible : must be one of
- "amlogic,meson8-sdio"
- "amlogic,meson8b-sdio"
along with the generic "amlogic,meson-mx-sdio"
- reg : mmc controller base registers
- interrupts : mmc controller interrupt
- #address-cells : must be 1
- size-cells : must be 0
- clocks : phandle to clock providers
- clock-names : must contain "core" and "clkin"
Required child nodes:
A node for each slot provided by the MMC controller is required.
NOTE: due to a driver limitation currently only one slot (= child node)
is supported!
Required properties on each child node (= slot):
- compatible : must be "mmc-slot" (see mmc.txt within this directory)
- reg : the slot (or "port") ID
Optional properties on each child node (= slot):
- bus-width : must be 1 or 4 (8-bit bus is not supported)
- for cd and all other additional generic mmc parameters
please refer to mmc.txt within this directory
Examples:
mmc@c1108c20 {
compatible = "amlogic,meson8-sdio", "amlogic,meson-mx-sdio";
reg = <0xc1108c20 0x20>;
interrupts = <0 28 1>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&clkc CLKID_SDIO>, <&clkc CLKID_CLK81>;
clock-names = "core", "clkin";
slot@1 {
compatible = "mmc-slot";
reg = <1>;
bus-width = <4>;
};
};
......@@ -53,6 +53,9 @@ Optional properties:
- no-sdio: controller is limited to send sdio cmd during initialization
- no-sd: controller is limited to send sd cmd during initialization
- no-mmc: controller is limited to send mmc cmd during initialization
- fixed-emmc-driver-type: for non-removable eMMC, enforce this driver type.
The value <n> is the driver type as specified in the eMMC specification
(table 206 in spec version 5.1).
*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"
......
......@@ -7,10 +7,18 @@ This file documents differences between the core properties in mmc.txt
and the properties used by the msdc driver.
Required properties:
- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc"
- compatible: value should be either of the following.
"mediatek,mt8135-mmc": for mmc host ip compatible with mt8135
"mediatek,mt8173-mmc": for mmc host ip compatible with mt8173
"mediatek,mt2701-mmc": for mmc host ip compatible with mt2701
"mediatek,mt2712-mmc": for mmc host ip compatible with mt2712
- reg: physical base address of the controller and length
- interrupts: Should contain MSDC interrupt number
- clocks: MSDC source clock, HCLK
- clock-names: "source", "hclk"
- clocks: Should contain phandle for the clock feeding the MMC controller
- clock-names: Should contain the following:
"source" - source clock (required)
"hclk" - HCLK which used for host (required)
"source_cg" - independent source clock gate (required for MT2712)
- pinctrl-names: should be "default", "state_uhs"
- pinctrl-0: should contain default/high speed pin ctrl
- pinctrl-1: should contain uhs mode pin ctrl
......@@ -30,6 +38,10 @@ Optional properties:
- mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection
If present,HS400 command responses are sampled on rising edges.
If not present,HS400 command responses are sampled on falling edges.
- mediatek,latch-ck: Some SoCs do not support enhance_rx, need set correct latch-ck to avoid data crc
error caused by stop clock(fifo full)
Valid range = [0:0x7]. if not present, default value is 0.
applied to compatible "mediatek,mt2701-mmc".
Examples:
mmc0: mmc@11230000 {
......
......@@ -15,6 +15,8 @@ Required properties:
Optional properties:
- vqmmc-supply: phandle to the regulator device tree node, mentioned
as the VCCQ/VDD_IO supply in the eMMC/SD specs.
- fujitsu,cmd-dat-delay-select: boolean property indicating that this host
requires the CMD_DAT_DELAY control to be enabled.
Example:
......
......@@ -18,6 +18,8 @@ Required properties:
"core" - SDC MMC clock (MCLK) (required)
"bus" - SDCC bus voter clock (optional)
"xo" - TCXO clock (optional)
"cal" - reference clock for RCLK delay calibration (optional)
"sleep" - sleep clock for RCLK delay calibration (optional)
Example:
......
* TI OMAP SDHCI Controller
Refer to mmc.txt for standard MMC bindings.
Required properties:
- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
Example:
mmc1: mmc@4809c000 {
compatible = "ti,dra7-sdhci";
reg = <0x4809c000 0x400>;
ti,hwmods = "mmc1";
bus-width = <4>;
vmmc-supply = <&vmmc>; /* phandle to regulator node */
};
......@@ -10,7 +10,7 @@ described in mmc.txt, can be used. Additionally the following tmio_mmc-specific
optional bindings can be used.
Required properties:
- compatible: "renesas,sdhi-shmobile" - a generic sh-mobile SDHI unit
- compatible: should contain one or more of the following:
"renesas,sdhi-sh73a0" - SDHI IP on SH73A0 SoC
"renesas,sdhi-r7s72100" - SDHI IP on R7S72100 SoC
"renesas,sdhi-r8a73a4" - SDHI IP on R8A73A4 SoC
......@@ -26,6 +26,16 @@ Required properties:
"renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC
"renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC
"renesas,sdhi-r8a7796" - SDHI IP on R8A7796 SoC
"renesas,sdhi-shmobile" - a generic sh-mobile SDHI controller
"renesas,rcar-gen1-sdhi" - a generic R-Car Gen1 SDHI controller
"renesas,rcar-gen2-sdhi" - a generic R-Car Gen2 or RZ/G1
SDHI controller
"renesas,rcar-gen3-sdhi" - a generic R-Car Gen3 SDHI controller
When compatible with the generic version, nodes must list
the SoC-specific version corresponding to the platform
first followed by the generic version.
- clocks: Most controllers only have 1 clock source per channel. However, on
some variations of this controller, the internal card detection
......@@ -43,3 +53,61 @@ Optional properties:
- pinctrl-names: should be "default", "state_uhs"
- pinctrl-0: should contain default/high speed pin ctrl
- pinctrl-1: should contain uhs mode pin ctrl
Example: R8A7790 (R-Car H2) SDHI controller nodes
sdhi0: sd@ee100000 {
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
reg = <0 0xee100000 0 0x328>;
interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 314>;
dmas = <&dmac0 0xcd>, <&dmac0 0xce>,
<&dmac1 0xcd>, <&dmac1 0xce>;
dma-names = "tx", "rx", "tx", "rx";
max-frequency = <195000000>;
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
resets = <&cpg 314>;
status = "disabled";
};
sdhi1: sd@ee120000 {
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
reg = <0 0xee120000 0 0x328>;
interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 313>;
dmas = <&dmac0 0xc9>, <&dmac0 0xca>,
<&dmac1 0xc9>, <&dmac1 0xca>;
dma-names = "tx", "rx", "tx", "rx";
max-frequency = <195000000>;
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
resets = <&cpg 313>;
status = "disabled";
};
sdhi2: sd@ee140000 {
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
reg = <0 0xee140000 0 0x100>;
interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 312>;
dmas = <&dmac0 0xc1>, <&dmac0 0xc2>,
<&dmac1 0xc1>, <&dmac1 0xc2>;
dma-names = "tx", "rx", "tx", "rx";
max-frequency = <97500000>;
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
resets = <&cpg 312>;
status = "disabled";
};
sdhi3: sd@ee160000 {
compatible = "renesas,sdhi-r8a7790", "renesas,rcar-gen2-sdhi";
reg = <0 0xee160000 0 0x100>;
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cpg CPG_MOD 311>;
dmas = <&dmac0 0xd3>, <&dmac0 0xd4>,
<&dmac1 0xd3>, <&dmac1 0xd4>;
dma-names = "tx", "rx", "tx", "rx";
max-frequency = <97500000>;
power-domains = <&sysc R8A7790_PD_ALWAYS_ON>;
resets = <&cpg 311>;
status = "disabled";
};
......@@ -12067,6 +12067,12 @@ L: linux-mmc@vger.kernel.org
S: Maintained
F: drivers/mmc/host/sdhci-spear.c
SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER
M: Kishon Vijay Abraham I <kishon@ti.com>
L: linux-mmc@vger.kernel.org
S: Maintained
F: drivers/mmc/host/sdhci-omap.c
SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
M: Scott Bauer <scott.bauer@intel.com>
M: Jonathan Derrick <jonathan.derrick@intel.com>
......
......@@ -682,8 +682,7 @@
};
mmc0: mmc@11230000 {
compatible = "mediatek,mt8173-mmc",
"mediatek,mt8135-mmc";
compatible = "mediatek,mt8173-mmc";
reg = <0 0x11230000 0 0x1000>;
interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>;
clocks = <&pericfg CLK_PERI_MSDC30_0>,
......@@ -693,8 +692,7 @@
};
mmc1: mmc@11240000 {
compatible = "mediatek,mt8173-mmc",
"mediatek,mt8135-mmc";
compatible = "mediatek,mt8173-mmc";
reg = <0 0x11240000 0 0x1000>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_LOW>;
clocks = <&pericfg CLK_PERI_MSDC30_1>,
......@@ -704,8 +702,7 @@
};
mmc2: mmc@11250000 {
compatible = "mediatek,mt8173-mmc",
"mediatek,mt8135-mmc";
compatible = "mediatek,mt8173-mmc";
reg = <0 0x11250000 0 0x1000>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_LOW>;
clocks = <&pericfg CLK_PERI_MSDC30_2>,
......@@ -715,8 +712,7 @@
};
mmc3: mmc@11260000 {
compatible = "mediatek,mt8173-mmc",
"mediatek,mt8135-mmc";
compatible = "mediatek,mt8173-mmc";
reg = <0 0x11260000 0 0x1000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_LOW>;
clocks = <&pericfg CLK_PERI_MSDC30_3>,
......
This diff is collapsed.
......@@ -369,10 +369,17 @@ int mmc_add_card(struct mmc_card *card)
*/
void mmc_remove_card(struct mmc_card *card)
{
struct mmc_host *host = card->host;
#ifdef CONFIG_DEBUG_FS
mmc_remove_card_debugfs(card);
#endif
if (host->cqe_enabled) {
host->cqe_ops->cqe_disable(host);
host->cqe_enabled = false;
}
if (mmc_card_present(card)) {
if (mmc_host_is_spi(card->host)) {
pr_info("%s: SPI card removed\n",
......
This diff is collapsed.
......@@ -49,6 +49,7 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
int mmc_set_uhs_voltage(struct mmc_host *host, u32 ocr);
int mmc_host_set_uhs_voltage(struct mmc_host *host);
int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
......@@ -107,6 +108,8 @@ static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { }
void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq);
bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq);
int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq);
struct mmc_async_req;
struct mmc_async_req *mmc_start_areq(struct mmc_host *host,
......@@ -128,10 +131,11 @@ int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen);
int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
bool is_rel_write);
int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
int __mmc_claim_host(struct mmc_host *host, struct mmc_ctx *ctx,
atomic_t *abort);
void mmc_release_host(struct mmc_host *host);
void mmc_get_card(struct mmc_card *card);
void mmc_put_card(struct mmc_card *card);
void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx);
void mmc_put_card(struct mmc_card *card, struct mmc_ctx *ctx);
/**
* mmc_claim_host - exclusively claim a host
......@@ -141,7 +145,11 @@ void mmc_put_card(struct mmc_card *card);
*/
static inline void mmc_claim_host(struct mmc_host *host)
{
__mmc_claim_host(host, NULL);
__mmc_claim_host(host, NULL, NULL);
}
int mmc_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq);
void mmc_cqe_post_req(struct mmc_host *host, struct mmc_request *mrq);
int mmc_cqe_recovery(struct mmc_host *host);
#endif
......@@ -111,12 +111,6 @@ void mmc_retune_hold(struct mmc_host *host)
host->hold_retune += 1;
}
void mmc_retune_hold_now(struct mmc_host *host)
{
host->retune_now = 0;
host->hold_retune += 1;
}
void mmc_retune_release(struct mmc_host *host)
{
if (host->hold_retune)
......@@ -124,6 +118,7 @@ void mmc_retune_release(struct mmc_host *host)
else
WARN_ON(1);
}
EXPORT_SYMBOL(mmc_retune_release);
int mmc_retune(struct mmc_host *host)
{
......@@ -184,7 +179,7 @@ static void mmc_retune_timer(unsigned long data)
int mmc_of_parse(struct mmc_host *host)
{
struct device *dev = host->parent;
u32 bus_width;
u32 bus_width, drv_type;
int ret;
bool cd_cap_invert, cd_gpio_invert = false;
bool ro_cap_invert, ro_gpio_invert = false;
......@@ -326,6 +321,15 @@ int mmc_of_parse(struct mmc_host *host)
if (device_property_read_bool(dev, "no-mmc"))
host->caps2 |= MMC_CAP2_NO_MMC;
/* Must be after "non-removable" check */
if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
if (host->caps & MMC_CAP_NONREMOVABLE)
host->fixed_drv_type = drv_type;
else
dev_err(host->parent,
"can't use fixed driver type, media is removable\n");
}
host->dsr_req = !device_property_read_u32(dev, "dsr", &host->dsr);
if (host->dsr_req && (host->dsr & ~0xffff)) {
dev_err(host->parent,
......@@ -398,6 +402,8 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
host->max_blk_size = 512;
host->max_blk_count = PAGE_SIZE / 512;
host->fixed_drv_type = -EINVAL;
return host;
}
......
......@@ -19,12 +19,17 @@ void mmc_unregister_host_class(void);
void mmc_retune_enable(struct mmc_host *host);
void mmc_retune_disable(struct mmc_host *host);
void mmc_retune_hold(struct mmc_host *host);
void mmc_retune_hold_now(struct mmc_host *host);
void mmc_retune_release(struct mmc_host *host);
int mmc_retune(struct mmc_host *host);
void mmc_retune_pause(struct mmc_host *host);
void mmc_retune_unpause(struct mmc_host *host);
static inline void mmc_retune_hold_now(struct mmc_host *host)
{
host->retune_now = 0;
host->hold_retune += 1;
}
static inline void mmc_retune_recheck(struct mmc_host *host)
{
if (host->hold_retune <= 1)
......
......@@ -780,6 +780,7 @@ MMC_DEV_ATTR(manfid, "0x%06x\n", card->cid.manfid);
MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_DEV_ATTR(prv, "0x%x\n", card->cid.prv);
MMC_DEV_ATTR(rev, "0x%x\n", card->ext_csd.rev);
MMC_DEV_ATTR(pre_eol_info, "%02x\n", card->ext_csd.pre_eol_info);
MMC_DEV_ATTR(life_time, "0x%02x 0x%02x\n",
card->ext_csd.device_life_time_est_typ_a,
......@@ -838,6 +839,7 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_name.attr,
&dev_attr_oemid.attr,
&dev_attr_prv.attr,
&dev_attr_rev.attr,
&dev_attr_pre_eol_info.attr,
&dev_attr_life_time.attr,
&dev_attr_serial.attr,
......@@ -1289,13 +1291,18 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
static void mmc_select_driver_type(struct mmc_card *card)
{
int card_drv_type, drive_strength, drv_type;
int fixed_drv_type = card->host->fixed_drv_type;
card_drv_type = card->ext_csd.raw_driver_strength |
mmc_driver_type_mask(0);
drive_strength = mmc_select_drive_strength(card,
card->ext_csd.hs200_max_dtr,
card_drv_type, &drv_type);
if (fixed_drv_type >= 0)
drive_strength = card_drv_type & mmc_driver_type_mask(fixed_drv_type)
? fixed_drv_type : 0;
else
drive_strength = mmc_select_drive_strength(card,
card->ext_csd.hs200_max_dtr,
card_drv_type, &drv_type);
card->drive_strength = drive_strength;
......@@ -1785,6 +1792,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
}
}
/*
* Enable Command Queue if supported. Note that Packed Commands cannot
* be used with Command Queue.
*/
card->ext_csd.cmdq_en = false;
if (card->ext_csd.cmdq_support && host->caps2 & MMC_CAP2_CQE) {
err = mmc_cmdq_enable(card);
if (err && err != -EBADMSG)
goto free_card;
if (err) {
pr_warn("%s: Enabling CMDQ failed\n",
mmc_hostname(card->host));
card->ext_csd.cmdq_support = false;
card->ext_csd.cmdq_depth = 0;
err = 0;
}
}
/*
* In some cases (e.g. RPMB or mmc_test), the Command Queue must be
* disabled for a time, so a flag is needed to indicate to re-enable the
......@@ -1792,6 +1816,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*/
card->reenable_cmdq = card->ext_csd.cmdq_en;
if (card->ext_csd.cmdq_en && !host->cqe_enabled) {
err = host->cqe_ops->cqe_enable(host, card);
if (err) {
pr_err("%s: Failed to enable CQE, error %d\n",
mmc_hostname(host), err);
} else {
host->cqe_enabled = true;
pr_info("%s: Command Queue Engine enabled\n",
mmc_hostname(host));
}
}
if (!oldcard)
host->card = card;
......@@ -1911,14 +1947,14 @@ static void mmc_detect(struct mmc_host *host)
{
int err;
mmc_get_card(host->card);
mmc_get_card(host->card, NULL);
/*
* Just check if our card has been removed.
*/
err = _mmc_detect_card_removed(host);
mmc_put_card(host->card);
mmc_put_card(host->card, NULL);
if (err) {
mmc_remove(host);
......
......@@ -977,7 +977,6 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
from_exception)
return;
mmc_claim_host(card->host);
if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
timeout = MMC_OPS_TIMEOUT_MS;
use_busy_signal = true;
......@@ -995,7 +994,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
pr_warn("%s: Error %d starting bkops\n",
mmc_hostname(card->host), err);
mmc_retune_release(card->host);
goto out;
return;
}
/*
......@@ -1007,9 +1006,8 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
mmc_card_set_doing_bkops(card);
else
mmc_retune_release(card->host);
out:
mmc_release_host(card->host);
}
EXPORT_SYMBOL(mmc_start_bkops);
/*
* Flush the cache to the non-volatile storage.
......
......@@ -30,7 +30,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
{
struct mmc_queue *mq = q->queuedata;
if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq)))
if (mq && mmc_card_removed(mq->card))
return BLKPREP_KILL;
req->rq_flags |= RQF_DONTPREP;
......@@ -177,6 +177,29 @@ static void mmc_exit_request(struct request_queue *q, struct request *req)
mq_rq->sg = NULL;
}
static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
{
struct mmc_host *host = card->host;
u64 limit = BLK_BOUNCE_HIGH;
if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue);
if (mmc_can_erase(card))
mmc_queue_setup_discard(mq->queue, card);
blk_queue_bounce_limit(mq->queue, limit);
blk_queue_max_hw_sectors(mq->queue,
min(host->max_blk_count, host->max_req_size / 512));
blk_queue_max_segments(mq->queue, host->max_segs);
blk_queue_max_segment_size(mq->queue, host->max_seg_size);
/* Initialize thread_sem even if it is not used */
sema_init(&mq->thread_sem, 1);
}
/**
* mmc_init_queue - initialise a queue structure.
* @mq: mmc queue
......@@ -190,12 +213,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
spinlock_t *lock, const char *subname)
{
struct mmc_host *host = card->host;
u64 limit = BLK_BOUNCE_HIGH;
int ret = -ENOMEM;
if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
mq->card = card;
mq->queue = blk_alloc_queue(GFP_KERNEL);
if (!mq->queue)
......@@ -214,18 +233,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
}
blk_queue_prep_rq(mq->queue, mmc_prep_request);
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, mq->queue);
if (mmc_can_erase(card))
mmc_queue_setup_discard(mq->queue, card);
blk_queue_bounce_limit(mq->queue, limit);
blk_queue_max_hw_sectors(mq->queue,
min(host->max_blk_count, host->max_req_size / 512));
blk_queue_max_segments(mq->queue, host->max_segs);
blk_queue_max_segment_size(mq->queue, host->max_seg_size);
sema_init(&mq->thread_sem, 1);
mmc_setup_queue(mq, card);
mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s",
host->index, subname ? subname : "");
......
......@@ -36,12 +36,14 @@ struct mmc_blk_request {
/**
* enum mmc_drv_op - enumerates the operations in the mmc_queue_req
* @MMC_DRV_OP_IOCTL: ioctl operation
* @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation
* @MMC_DRV_OP_BOOT_WP: write protect boot partitions
* @MMC_DRV_OP_GET_CARD_STATUS: get card status
* @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card
*/
enum mmc_drv_op {
MMC_DRV_OP_IOCTL,
MMC_DRV_OP_IOCTL_RPMB,
MMC_DRV_OP_BOOT_WP,
MMC_DRV_OP_GET_CARD_STATUS,
MMC_DRV_OP_GET_EXT_CSD,
......@@ -82,6 +84,4 @@ extern void mmc_queue_resume(struct mmc_queue *);
extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
struct mmc_queue_req *);
extern int mmc_access_rpmb(struct mmc_queue *);
#endif
......@@ -908,6 +908,18 @@ unsigned mmc_sd_get_max_clock(struct mmc_card *card)
return max_dtr;
}
static bool mmc_sd_card_using_v18(struct mmc_card *card)
{
/*
* According to the SD spec., the Bus Speed Mode (function group 1) bits
* 2 to 4 are zero if the card is initialized at 3.3V signal level. Thus
* they can be used to determine if the card has already switched to
* 1.8V signaling.
*/
return card->sw_caps.sd3_bus_mode &
(SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR104 | SD_MODE_UHS_DDR50);
}
/*
* Handle the detection and initialisation of a card.
*
......@@ -921,9 +933,10 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
int err;
u32 cid[4];
u32 rocr = 0;
bool v18_fixup_failed = false;
WARN_ON(!host->claimed);
retry:
err = mmc_sd_get_cid(host, ocr, cid, &rocr);
if (err)
return err;
......@@ -989,6 +1002,36 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
if (err)
goto free_card;
/*
* If the card has not been power cycled, it may still be using 1.8V
* signaling. Detect that situation and try to initialize a UHS-I (1.8V)
* transfer mode.
*/
if (!v18_fixup_failed && !mmc_host_is_spi(host) && mmc_host_uhs(host) &&
mmc_sd_card_using_v18(card) &&
host->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_180) {
/*
* Re-read switch information in case it has changed since
* oldcard was initialized.
*/
if (oldcard) {
err = mmc_read_switch(card);
if (err)
goto free_card;
}
if (mmc_sd_card_using_v18(card)) {
if (mmc_host_set_uhs_voltage(host) ||
mmc_sd_init_uhs_card(card)) {
v18_fixup_failed = true;
mmc_power_cycle(host, ocr);
if (!oldcard)
mmc_remove_card(card);
goto retry;
}
goto done;
}
}
/* Initialization sequence for UHS-I cards */
if (rocr & SD_ROCR_S18A) {
err = mmc_sd_init_uhs_card(card);
......@@ -1021,7 +1064,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
}
}
done:
host->card = card;
return 0;
......@@ -1056,14 +1099,14 @@ static void mmc_sd_detect(struct mmc_host *host)
{