linux-stable/drivers/mmc/core/sdio.c

1269 lines
28 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* linux/drivers/mmc/sdio.c
*
* Copyright 2006-2007 Pierre Ossman
*/
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include "core.h"
#include "card.h"
#include "host.h"
#include "bus.h"
#include "quirks.h"
#include "sd.h"
#include "sdio_bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"
#include "sdio_ops.h"
#include "sdio_cis.h"
MMC_DEV_ATTR(vendor, "0x%04x\n", card->cis.vendor);
MMC_DEV_ATTR(device, "0x%04x\n", card->cis.device);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
static struct attribute *sdio_std_attrs[] = {
&dev_attr_vendor.attr,
&dev_attr_device.attr,
&dev_attr_ocr.attr,
&dev_attr_rca.attr,
NULL,
};
ATTRIBUTE_GROUPS(sdio_std);
static struct device_type sdio_type = {
.groups = sdio_std_groups,
};
static int sdio_read_fbr(struct sdio_func *func)
{
int ret;
unsigned char data;
if (mmc_card_nonstd_func_interface(func->card)) {
func->class = SDIO_CLASS_NONE;
return 0;
}
ret = mmc_io_rw_direct(func->card, 0, 0,
SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data);
if (ret)
goto out;
data &= 0x0f;
if (data == 0x0f) {
ret = mmc_io_rw_direct(func->card, 0, 0,
SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF_EXT, 0, &data);
if (ret)
goto out;
}
func->class = data;
out:
return ret;
}
static int sdio_init_func(struct mmc_card *card, unsigned int fn)
{
int ret;
struct sdio_func *func;
if (WARN_ON(fn > SDIO_MAX_FUNCS))
return -EINVAL;
func = sdio_alloc_func(card);
if (IS_ERR(func))
return PTR_ERR(func);
func->num = fn;
if (!(card->quirks & MMC_QUIRK_NONSTD_SDIO)) {
ret = sdio_read_fbr(func);
if (ret)
goto fail;
ret = sdio_read_func_cis(func);
if (ret)
goto fail;
} else {
func->vendor = func->card->cis.vendor;
func->device = func->card->cis.device;
func->max_blksize = func->card->cis.blksize;
}
card->sdio_func[fn - 1] = func;
return 0;
fail:
/*
* It is okay to remove the function here even though we hold
* the host lock as we haven't registered the device yet.
*/
sdio_remove_func(func);
return ret;
}
static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
{
int ret;
int cccr_vsn;
int uhs = ocr & R4_18V_PRESENT;
unsigned char data;
unsigned char speed;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CCCR, 0, &data);
if (ret)
goto out;
cccr_vsn = data & 0x0f;
if (cccr_vsn > SDIO_CCCR_REV_3_00) {
pr_err("%s: unrecognised CCCR structure version %d\n",
mmc_hostname(card->host), cccr_vsn);
return -EINVAL;
}
card->cccr.sdio_vsn = (data & 0xf0) >> 4;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_CAPS, 0, &data);
if (ret)
goto out;
if (data & SDIO_CCCR_CAP_SMB)
card->cccr.multi_block = 1;
if (data & SDIO_CCCR_CAP_LSC)
card->cccr.low_speed = 1;
if (data & SDIO_CCCR_CAP_4BLS)
card->cccr.wide_bus = 1;
if (cccr_vsn >= SDIO_CCCR_REV_1_10) {
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_POWER, 0, &data);
if (ret)
goto out;
if (data & SDIO_POWER_SMPC)
card->cccr.high_power = 1;
}
if (cccr_vsn >= SDIO_CCCR_REV_1_20) {
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (ret)
goto out;
card->scr.sda_spec3 = 0;
card->sw_caps.sd3_bus_mode = 0;
card->sw_caps.sd3_drv_type = 0;
if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) {
card->scr.sda_spec3 = 1;
ret = mmc_io_rw_direct(card, 0, 0,
SDIO_CCCR_UHS, 0, &data);
if (ret)
goto out;
if (mmc_host_uhs(card->host)) {
if (data & SDIO_UHS_DDR50)
card->sw_caps.sd3_bus_mode
|= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50
| SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
if (data & SDIO_UHS_SDR50)
card->sw_caps.sd3_bus_mode
|= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25
| SD_MODE_UHS_SDR12;
if (data & SDIO_UHS_SDR104)
card->sw_caps.sd3_bus_mode
|= SD_MODE_UHS_SDR104 | SD_MODE_UHS_SDR50
| SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12;
}
ret = mmc_io_rw_direct(card, 0, 0,
SDIO_CCCR_DRIVE_STRENGTH, 0, &data);
if (ret)
goto out;
if (data & SDIO_DRIVE_SDTA)
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A;
if (data & SDIO_DRIVE_SDTC)
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
if (data & SDIO_DRIVE_SDTD)
card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
}
/* if no uhs mode ensure we check for high speed */
if (!card->sw_caps.sd3_bus_mode) {
if (speed & SDIO_SPEED_SHS) {
card->cccr.high_speed = 1;
card->sw_caps.hs_max_dtr = 50000000;
} else {
card->cccr.high_speed = 0;
card->sw_caps.hs_max_dtr = 25000000;
}
}
}
out:
return ret;
}
static int sdio_enable_wide(struct mmc_card *card)
{
int ret;
u8 ctrl;
if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
return 0;
if (card->cccr.low_speed && !card->cccr.wide_bus)
return 0;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
if (ret)
return ret;
if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED)
pr_warn("%s: SDIO_CCCR_IF is invalid: 0x%02x\n",
mmc_hostname(card->host), ctrl);
/* set as 4-bit bus width */
ctrl &= ~SDIO_BUS_WIDTH_MASK;
ctrl |= SDIO_BUS_WIDTH_4BIT;
ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
if (ret)
return ret;
return 1;
}
/*
* If desired, disconnect the pull-up resistor on CD/DAT[3] (pin 1)
* of the card. This may be required on certain setups of boards,
* controllers and embedded sdio device which do not need the card's
* pull-up. As a result, card detection is disabled and power is saved.
*/
static int sdio_disable_cd(struct mmc_card *card)
{
int ret;
u8 ctrl;
if (!mmc_card_disable_cd(card))
return 0;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
if (ret)
return ret;
ctrl |= SDIO_BUS_CD_DISABLE;
return mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
}
/*
* Devices that remain active during a system suspend are
* put back into 1-bit mode.
*/
static int sdio_disable_wide(struct mmc_card *card)
{
int ret;
u8 ctrl;
if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
return 0;
if (card->cccr.low_speed && !card->cccr.wide_bus)
return 0;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
if (ret)
return ret;
if (!(ctrl & SDIO_BUS_WIDTH_4BIT))
return 0;
ctrl &= ~SDIO_BUS_WIDTH_4BIT;
ctrl |= SDIO_BUS_ASYNC_INT;
ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL);
if (ret)
return ret;
mmc_set_bus_width(card->host, MMC_BUS_WIDTH_1);
return 0;
}
static int sdio_disable_4bit_bus(struct mmc_card *card)
{
int err;
if (card->type == MMC_TYPE_SDIO)
goto out;
if (!(card->host->caps & MMC_CAP_4_BIT_DATA))
return 0;
if (!(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4))
return 0;
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1);
if (err)
return err;
out:
return sdio_disable_wide(card);
}
static int sdio_enable_4bit_bus(struct mmc_card *card)
{
int err;
err = sdio_enable_wide(card);
if (err <= 0)
return err;
if (card->type == MMC_TYPE_SDIO)
goto out;
if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) {
err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
if (err) {
sdio_disable_wide(card);
return err;
}
}
out:
mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
return 0;
}
/*
* Test if the card supports high-speed mode and, if so, switch to it.
*/
static int mmc_sdio_switch_hs(struct mmc_card *card, int enable)
{
int ret;
u8 speed;
if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED))
return 0;
if (!card->cccr.high_speed)
return 0;
ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (ret)
return ret;
if (enable)
speed |= SDIO_SPEED_EHS;
else
speed &= ~SDIO_SPEED_EHS;
ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
if (ret)
return ret;
return 1;
}
/*
* Enable SDIO/combo card's high-speed mode. Return 0/1 if [not]supported.
*/
static int sdio_enable_hs(struct mmc_card *card)
{
int ret;
ret = mmc_sdio_switch_hs(card, true);
if (ret <= 0 || card->type == MMC_TYPE_SDIO)
return ret;
ret = mmc_sd_switch_hs(card);
if (ret <= 0)
mmc_sdio_switch_hs(card, false);
return ret;
}
static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)
{
unsigned max_dtr;
if (mmc_card_hs(card)) {
/*
* The SDIO specification doesn't mention how
* the CIS transfer speed register relates to
* high-speed, but it seems that 50 MHz is
* mandatory.
*/
max_dtr = 50000000;
} else {
max_dtr = card->cis.max_dtr;
}
if (card->type == MMC_TYPE_SD_COMBO)
max_dtr = min(max_dtr, mmc_sd_get_max_clock(card));
return max_dtr;
}
static unsigned char host_drive_to_sdio_drive(int host_strength)
{
switch (host_strength) {
case MMC_SET_DRIVER_TYPE_A:
return SDIO_DTSx_SET_TYPE_A;
case MMC_SET_DRIVER_TYPE_B:
return SDIO_DTSx_SET_TYPE_B;
case MMC_SET_DRIVER_TYPE_C:
return SDIO_DTSx_SET_TYPE_C;
case MMC_SET_DRIVER_TYPE_D:
return SDIO_DTSx_SET_TYPE_D;
default:
return SDIO_DTSx_SET_TYPE_B;
}
}
static void sdio_select_driver_type(struct mmc_card *card)
{
int card_drv_type, drive_strength, drv_type;
unsigned char card_strength;
int err;
card->drive_strength = 0;
card_drv_type = card->sw_caps.sd3_drv_type | SD_DRIVER_TYPE_B;
drive_strength = mmc_select_drive_strength(card,
card->sw_caps.uhs_max_dtr,
card_drv_type, &drv_type);
if (drive_strength) {
/* if error just use default for drive strength B */
err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
&card_strength);
if (err)
return;
card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
card_strength |= host_drive_to_sdio_drive(drive_strength);
/* if error default to drive strength B */
err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
card_strength, NULL);
if (err)
return;
card->drive_strength = drive_strength;
}
if (drv_type)
mmc_set_driver_type(card->host, drv_type);
}
static int sdio_set_bus_speed_mode(struct mmc_card *card)
{
unsigned int bus_speed, timing;
int err;
unsigned char speed;
unsigned int max_rate;
/*
* If the host doesn't support any of the UHS-I modes, fallback on
* default speed.
*/
if (!mmc_host_uhs(card->host))
return 0;
bus_speed = SDIO_SPEED_SDR12;
timing = MMC_TIMING_UHS_SDR12;
if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
bus_speed = SDIO_SPEED_SDR104;
timing = MMC_TIMING_UHS_SDR104;
card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
card->sd_bus_speed = UHS_SDR104_BUS_SPEED;
} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
bus_speed = SDIO_SPEED_DDR50;
timing = MMC_TIMING_UHS_DDR50;
card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
card->sd_bus_speed = UHS_DDR50_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR50)) {
bus_speed = SDIO_SPEED_SDR50;
timing = MMC_TIMING_UHS_SDR50;
card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
card->sd_bus_speed = UHS_SDR50_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
bus_speed = SDIO_SPEED_SDR25;
timing = MMC_TIMING_UHS_SDR25;
card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
card->sd_bus_speed = UHS_SDR25_BUS_SPEED;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR12)) {
bus_speed = SDIO_SPEED_SDR12;
timing = MMC_TIMING_UHS_SDR12;
card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
card->sd_bus_speed = UHS_SDR12_BUS_SPEED;
}
err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (err)
return err;
speed &= ~SDIO_SPEED_BSS_MASK;
speed |= bus_speed;
err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
if (err)
return err;
max_rate = min_not_zero(card->quirk_max_rate,
card->sw_caps.uhs_max_dtr);
mmc_set_timing(card->host, timing);
mmc_set_clock(card->host, max_rate);
return 0;
}
/*
* UHS-I specific initialization procedure
*/
static int mmc_sdio_init_uhs_card(struct mmc_card *card)
{
int err;
if (!card->scr.sda_spec3)
return 0;
/* Switch to wider bus */
err = sdio_enable_4bit_bus(card);
if (err)
goto out;
/* Set the driver strength for the card */
sdio_select_driver_type(card);
/* Set bus speed mode of the card */
err = sdio_set_bus_speed_mode(card);
if (err)
goto out;
/*
* SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
* SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
*/
if (!mmc_host_is_spi(card->host) &&
((card->host->ios.timing == MMC_TIMING_UHS_SDR50) ||
(card->host->ios.timing == MMC_TIMING_UHS_SDR104)))
err = mmc_execute_tuning(card);
out:
return err;
}
static int mmc_sdio_pre_init(struct mmc_host *host, u32 ocr,
struct mmc_card *card)
{
if (card)
mmc_remove_card(card);
/*
* Reset the card by performing the same steps that are taken by
* mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
*
* sdio_reset() is technically not needed. Having just powered up the
* hardware, it should already be in reset state. However, some
* platforms (such as SD8686 on OLPC) do not instantly cut power,
* meaning that a reset is required when restoring power soon after
* powering off. It is harmless in other cases.
*
* The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
* is not necessary for non-removable cards. However, it is required
* for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
* harmless in other situations.
*
*/
sdio_reset(host);
mmc_go_idle(host);
mmc_send_if_cond(host, ocr);
return mmc_send_io_op_cond(host, 0, NULL);
}
/*
* Handle the detection and initialisation of a card.
*
* In the case of a resume, "oldcard" will contain the card
* we're trying to reinitialise.
*/
static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
struct mmc_card *oldcard)
{
struct mmc_card *card;
int err;
int retries = 10;
u32 rocr = 0;
u32 ocr_card = ocr;
WARN_ON(!host->claimed);
/* to query card if 1.8V signalling is supported */
if (mmc_host_uhs(host))
ocr |= R4_18V_PRESENT;
try_again:
if (!retries) {
pr_warn("%s: Skipping voltage switch\n", mmc_hostname(host));
ocr &= ~R4_18V_PRESENT;
}
/*
* Inform the card of the voltage
*/
err = mmc_send_io_op_cond(host, ocr, &rocr);
if (err)
return err;
/*
* For SPI, enable CRC as appropriate.
*/
if (mmc_host_is_spi(host)) {
err = mmc_spi_set_crc(host, use_spi_crc);
if (err)
return err;
}
/*
* Allocate card structure.
*/
card = mmc_alloc_card(host, &sdio_type);
if (IS_ERR(card))
return PTR_ERR(card);
if ((rocr & R4_MEMORY_PRESENT) &&
mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
card->type = MMC_TYPE_SD_COMBO;
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
err = -ENOENT;
goto mismatch;
}
} else {
card->type = MMC_TYPE_SDIO;
if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
err = -ENOENT;
goto mismatch;
}
}
/*
* Call the optional HC's init_card function to handle quirks.
*/
if (host->ops->init_card)
host->ops->init_card(host, card);
/*
* If the host and card support UHS-I mode request the card
* to switch to 1.8V signaling level. No 1.8v signalling if
* UHS mode is not enabled to maintain compatibility and some
* systems that claim 1.8v signalling in fact do not support
* it. Per SDIO spec v3, section 3.1.2, if the voltage is already
* 1.8v, the card sets S18A to 0 in the R4 response. So it will
* fails to check rocr & R4_18V_PRESENT, but we still need to
* try to init uhs card. sdio_read_cccr will take over this task
* to make sure which speed mode should work.
*/
if (rocr & ocr & R4_18V_PRESENT) {
err = mmc_set_uhs_voltage(host, ocr_card);
if (err == -EAGAIN) {
mmc_sdio_pre_init(host, ocr_card, card);
retries--;
goto try_again;
} else if (err) {
ocr &= ~R4_18V_PRESENT;
}
}
/*
* For native busses: set card RCA and quit open drain mode.
*/
if (!mmc_host_is_spi(host)) {
err = mmc_send_relative_addr(host, &card->rca);
if (err)
goto remove;
/*
* Update oldcard with the new RCA received from the SDIO
* device -- we're doing this so that it's updated in the
* "card" struct when oldcard overwrites that later.
*/
if (oldcard)
oldcard->rca = card->rca;
}
/*
* Read CSD, before selecting the card
*/
if (!oldcard && card->type == MMC_TYPE_SD_COMBO) {
err = mmc_sd_get_csd(host, card);
if (err)
goto remove;
mmc_decode_cid(card);
}
/*
* Select card, as all following commands rely on that.
*/
if (!mmc_host_is_spi(host)) {
err = mmc_select_card(card);
if (err)
goto remove;
}
if (card->quirks & MMC_QUIRK_NONSTD_SDIO) {
/*
* This is non-standard SDIO device, meaning it doesn't
* have any CIA (Common I/O area) registers present.
* It's host's responsibility to fill cccr and cis
* structures in init_card().
*/
mmc_set_clock(host, card->cis.max_dtr);
if (card->cccr.high_speed) {
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
}
if (oldcard)
mmc_remove_card(card);
else
host->card = card;
return 0;
}
/*
* Read the common registers. Note that we should try to
* validate whether UHS would work or not.
*/
err = sdio_read_cccr(card, ocr);
if (err) {
mmc_sdio_pre_init(host, ocr_card, card);
if (ocr & R4_18V_PRESENT) {
/* Retry init sequence, but without R4_18V_PRESENT. */
retries = 0;
goto try_again;
}
return err;
}
/*
* Read the common CIS tuples.
*/
err = sdio_read_common_cis(card);
if (err)
goto remove;
if (oldcard) {
if (card->cis.vendor == oldcard->cis.vendor &&
card->cis.device == oldcard->cis.device) {
mmc_remove_card(card);
card = oldcard;
} else {
err = -ENOENT;
goto mismatch;
}
}
card->ocr = ocr_card;
mmc_fixup_device(card, sdio_fixup_methods);
if (card->type == MMC_TYPE_SD_COMBO) {
err = mmc_sd_setup_card(host, card, oldcard != NULL);
/* handle as SDIO-only card if memory init failed */
if (err) {
mmc_go_idle(host);
if (mmc_host_is_spi(host))
/* should not fail, as it worked previously */
mmc_spi_set_crc(host, use_spi_crc);
card->type = MMC_TYPE_SDIO;
} else
card->dev.type = &sd_type;
}
/*
* If needed, disconnect card detection pull-up resistor.
*/
err = sdio_disable_cd(card);
if (err)
goto remove;
/* Initialization sequence for UHS-I cards */
/* Only if card supports 1.8v and UHS signaling */
if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) {
err = mmc_sdio_init_uhs_card(card);
if (err)
goto remove;
} else {
/*
* Switch to high-speed (if supported).
*/
err = sdio_enable_hs(card);
if (err > 0)
mmc_set_timing(card->host, MMC_TIMING_SD_HS);
else if (err)
goto remove;
/*
* Change to the card's maximum speed.
*/
mmc_set_clock(host, mmc_sdio_get_max_clock(card));
/*
* Switch to wider bus (if supported).
*/
err = sdio_enable_4bit_bus(card);
if (err)
goto remove;
}
if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
pr_err("%s: Host failed to negotiate down from 3.3V\n",
mmc_hostname(host));
err = -EINVAL;
goto remove;
}
host->card = card;
return 0;
mismatch:
pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host));
remove:
if (oldcard != card)
mmc_remove_card(card);
return err;
}
static int mmc_sdio_reinit_card(struct mmc_host *host)
{
int ret;
ret = mmc_sdio_pre_init(host, host->card->ocr, NULL);
if (ret)
return ret;
return mmc_sdio_init_card(host, host->card->ocr, host->card);
}
/*
* Host is being removed. Free up the current card.
*/
static void mmc_sdio_remove(struct mmc_host *host)
{
int i;
for (i = 0;i < host->card->sdio_funcs;i++) {
if (host->card->sdio_func[i]) {
sdio_remove_func(host->card->sdio_func[i]);
host->card->sdio_func[i] = NULL;
}
}
mmc_remove_card(host->card);
host->card = NULL;
}
/*
* Card detection - card is alive.
*/
static int mmc_sdio_alive(struct mmc_host *host)
{
return mmc_select_card(host->card);
}
/*
* Card detection callback from host.
*/
static void mmc_sdio_detect(struct mmc_host *host)
{
int err;
/* Make sure card is powered before detecting it */
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
err = pm_runtime_get_sync(&host->card->dev);
if (err < 0) {
pm_runtime_put_noidle(&host->card->dev);
goto out;
}
}
mmc_claim_host(host);
/*
* Just check if our card has been removed.
*/
err = _mmc_detect_card_removed(host);
mmc_release_host(host);
/*
* Tell PM core it's OK to power off the card now.
*
* The _sync variant is used in order to ensure that the card
* is left powered off in case an error occurred, and the card
* is going to be removed.
*
* Since there is no specific reason to believe a new user
* is about to show up at this point, the _sync variant is
* desirable anyway.
*/
if (host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_put_sync(&host->card->dev);
out:
if (err) {
mmc_sdio_remove(host);
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
mmc_release_host(host);
}
}
/*
* SDIO pre_suspend. We need to suspend all functions separately.
* Therefore all registered functions must have drivers with suspend
* and resume methods. Failing that we simply remove the whole card.
*/
static int mmc_sdio_pre_suspend(struct mmc_host *host)
{
int i, err = 0;
for (i = 0; i < host->card->sdio_funcs; i++) {
struct sdio_func *func = host->card->sdio_func[i];
if (func && sdio_func_present(func) && func->dev.driver) {
const struct dev_pm_ops *pmops = func->dev.driver->pm;
if (!pmops || !pmops->suspend || !pmops->resume) {
/* force removal of entire card in that case */
err = -ENOSYS;
break;
}
}
}
return err;
}
/*
* SDIO suspend. Suspend all functions separately.
*/
static int mmc_sdio_suspend(struct mmc_host *host)
{
WARN_ON(host->sdio_irqs && !mmc_card_keep_power(host));
/* Prevent processing of SDIO IRQs in suspended state. */
mmc_card_set_suspended(host->card);
cancel_delayed_work_sync(&host->sdio_irq_work);
mmc_claim_host(host);
if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host))
sdio_disable_4bit_bus(host->card);
if (!mmc_card_keep_power(host)) {
mmc_power_off(host);
} else if (host->retune_period) {
mmc_retune_timer_stop(host);
mmc_retune_needed(host);
}
mmc_release_host(host);
return 0;
}
static int mmc_sdio_resume(struct mmc_host *host)
{
int err = 0;
/* Basic card reinitialization. */
mmc_claim_host(host);
/*
* Restore power and reinitialize the card when needed. Note that a
* removable card is checked from a detect work later on in the resume
* process.
*/
if (!mmc_card_keep_power(host)) {
mmc_power_up(host, host->card->ocr);
/*
* Tell runtime PM core we just powered up the card,
* since it still believes the card is powered off.
* Note that currently runtime PM is only enabled
* for SDIO cards that are MMC_CAP_POWER_OFF_CARD
*/
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
pm_runtime_disable(&host->card->dev);
pm_runtime_set_active(&host->card->dev);
pm_runtime_enable(&host->card->dev);
}
err = mmc_sdio_reinit_card(host);
} else if (mmc_card_wake_sdio_irq(host)) {
/* We may have switched to 1-bit mode during suspend */
err = sdio_enable_4bit_bus(host->card);
}
if (err)
goto out;
/* Allow SDIO IRQs to be processed again. */
mmc_card_clr_suspended(host->card);
if (host->sdio_irqs) {
if (!(host->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD))
wake_up_process(host->sdio_irq_thread);
else if (host->caps & MMC_CAP_SDIO_IRQ)
mmc: core: Fixup processing of SDIO IRQs during system suspend/resume System suspend/resume of SDIO cards, with SDIO IRQs enabled and when using MMC_CAP2_SDIO_IRQ_NOTHREAD is unfortunate still suffering from a fragile behaviour. Some problems have been taken care of so far, but more issues remains. For example, calling the ->ack_sdio_irq() callback to let host drivers re-enable the SDIO IRQs is a bad idea, unless the IRQ have been consumed, which may not be the case during system suspend/resume. This may lead to that a host driver re-signals the same SDIO IRQ over and over again, causing a storm of IRQs and gives a ping-pong effect towards the sdio_irq_work(). Moreover, calling the ->enable_sdio_irq() callback at system resume to re-enable already enabled SDIO IRQs for the host, causes the runtime PM count for some host drivers to become in-balanced. This then leads to the host to remain runtime resumed, no matter if it's needed or not. To fix these problems, let's check if process_sdio_pending_irqs() actually consumed the SDIO IRQ, before we continue to ack the IRQ by invoking the ->ack_sdio_irq() callback. Additionally, there should be no need to re-enable SDIO IRQs as the host driver already knows if they were enabled at system suspend, thus also whether it needs to re-enable them at system resume. For this reason, drop the call to ->enable_sdio_irq() during system resume. In regards to these changes there is yet another issue, which is when there is an SDIO IRQ being signaled by the host driver, but after the SDIO card has been system suspended. Currently these IRQs are just thrown away, while we should at least make sure to try to consume them when the SDIO card has been system resumed. Fix this by queueing a sdio_irq_work() after we system resumed the SDIO card. Tested-by: Matthias Kaehlcke <mka@chromium.org> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
2019-09-08 10:12:33 +00:00
queue_delayed_work(system_wq, &host->sdio_irq_work, 0);
}
out:
mmc_release_host(host);
host->pm_flags &= ~MMC_PM_KEEP_POWER;
return err;
}
static int mmc_sdio_runtime_suspend(struct mmc_host *host)
{
/* No references to the card, cut the power to it. */
mmc_claim_host(host);
mmc_power_off(host);
mmc_release_host(host);
return 0;
}
static int mmc_sdio_runtime_resume(struct mmc_host *host)
{
int ret;
/* Restore power and re-initialize. */
mmc_claim_host(host);
mmc_power_up(host, host->card->ocr);
ret = mmc_sdio_reinit_card(host);
mmc_release_host(host);
return ret;
}
mmc: core: Re-work HW reset for SDIO cards It have turned out that it's not a good idea to unconditionally do a power cycle and then to re-initialize the SDIO card, as currently done through mmc_hw_reset() -> mmc_sdio_hw_reset(). This because there may be multiple SDIO func drivers probed, who also shares the same SDIO card. To address these scenarios, one may be tempted to use a notification mechanism, as to allow the core to inform each of the probed func drivers, about an ongoing HW reset. However, supporting such an operation from the func driver point of view, may not be entirely trivial. Therefore, let's use a more simplistic approach to solve the problem, by instead forcing the card to be removed and re-detected, via scheduling a rescan-work. In this way, we can rely on existing infrastructure, as the func driver's ->remove() and ->probe() callbacks, becomes invoked to deal with the cleanup and the re-initialization. This solution may be considered as rather heavy, especially if a func driver doesn't share its card with other func drivers. To address this, let's keep the current immediate HW reset option as well, but run it only when there is one func driver probed for the card. Finally, to allow the caller of mmc_hw_reset(), to understand if the reset is being asynchronously managed from a scheduled work, it returns 1 (propagated from mmc_sdio_hw_reset()). If the HW reset is executed successfully and synchronously it returns 0, which maintains the existing behaviour. Reviewed-by: Douglas Anderson <dianders@chromium.org> Tested-by: Douglas Anderson <dianders@chromium.org> Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
2019-10-17 13:25:36 +00:00
/*
* SDIO HW reset
*
* Returns 0 if the HW reset was executed synchronously, returns 1 if the HW
* reset was asynchronously scheduled, else a negative error code.
*/
static int mmc_sdio_hw_reset(struct mmc_host *host)
{
mmc: core: Re-work HW reset for SDIO cards It have turned out that it's not a good idea to unconditionally do a power cycle and then to re-initialize the SDIO card, as currently done through mmc_hw_reset() -> mmc_sdio_hw_reset(). This because there may be multiple SDIO func drivers probed, who also shares the same SDIO card. To address these scenarios, one may be tempted to use a notification mechanism, as to allow the core to inform each of the probed func drivers, about an ongoing HW reset. However, supporting such an operation from the func driver point of view, may not be entirely trivial. Therefore, let's use a more simplistic approach to solve the problem, by instead forcing the card to be removed and re-detected, via scheduling a rescan-work. In this way, we can rely on existing infrastructure, as the func driver's ->remove() and ->probe() callbacks, becomes invoked to deal with the cleanup and the re-initialization. This solution may be considered as rather heavy, especially if a func driver doesn't share its card with other func drivers. To address this, let's keep the current immediate HW reset option as well, but run it only when there is one func driver probed for the card. Finally, to allow the caller of mmc_hw_reset(), to understand if the reset is being asynchronously managed from a scheduled work, it returns 1 (propagated from mmc_sdio_hw_reset()). If the HW reset is executed successfully and synchronously it returns 0, which maintains the existing behaviour. Reviewed-by: Douglas Anderson <dianders@chromium.org> Tested-by: Douglas Anderson <dianders@chromium.org> Cc: stable@vger.kernel.org # v5.4+ Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
2019-10-17 13:25:36 +00:00
struct mmc_card *card = host->card;
/*
* In case the card is shared among multiple func drivers, reset the
* card through a rescan work. In this way it will be removed and
* re-detected, thus all func drivers becomes informed about it.
*/
if (atomic_read(&card->sdio_funcs_probed) > 1) {
if (mmc_card_removed(card))
return 1;
host->rescan_entered = 0;
mmc_card_set_removed(card);
_mmc_detect_change(host, 0, false);
return 1;
}
/*
* A single func driver has been probed, then let's skip the heavy
* hotplug dance above and execute the reset immediately.
*/
mmc_power_cycle(host, card->ocr);
return mmc_sdio_reinit_card(host);
}
static int mmc_sdio_sw_reset(struct mmc_host *host)
{
mmc_set_clock(host, host->f_init);
sdio_reset(host);
mmc_go_idle(host);
mmc_set_initial_state(host);
mmc_set_initial_signal_voltage(host);
return mmc_sdio_reinit_card(host);
}
static const struct mmc_bus_ops mmc_sdio_ops = {
.remove = mmc_sdio_remove,
.detect = mmc_sdio_detect,
.pre_suspend = mmc_sdio_pre_suspend,
.suspend = mmc_sdio_suspend,
.resume = mmc_sdio_resume,
.runtime_suspend = mmc_sdio_runtime_suspend,
.runtime_resume = mmc_sdio_runtime_resume,
.alive = mmc_sdio_alive,
.hw_reset = mmc_sdio_hw_reset,
.sw_reset = mmc_sdio_sw_reset,
};
/*
* Starting point for SDIO card init.
*/
int mmc_attach_sdio(struct mmc_host *host)
{
int err, i, funcs;
u32 ocr, rocr;
struct mmc_card *card;
WARN_ON(!host->claimed);
err = mmc_send_io_op_cond(host, 0, &ocr);
if (err)
return err;
mmc_attach_bus(host, &mmc_sdio_ops);
if (host->ocr_avail_sdio)
host->ocr_avail = host->ocr_avail_sdio;
rocr = mmc_select_voltage(host, ocr);
/*
* Can we support the voltage(s) of the card(s)?
*/
if (!rocr) {
err = -EINVAL;
goto err;
}
/*
* Detect and init the card.
*/
err = mmc_sdio_init_card(host, rocr, NULL);
if (err)
goto err;
card = host->card;
MMC core learns about SPI Teach the MMC/SD/SDIO core about using SPI mode. - Use mmc_host_is_spi() so enumeration works through SPI signaling and protocols, not just the native versions. - Provide the SPI response type flags with each request issued, including requests from the new lock/unlock code. - Understand that cmd->resp[0] and mmc_get_status() results for SPI return different values than for "native" MMC/SD protocol; this affects resetting, checking card lock status, and some others. - Understand that some commands act a bit differently ... notably: * OP_COND command doesn't return the OCR * APP_CMD status doesn't have an R1_APP_CMD analogue Those changes required some new and updated primitives: - Provide utilities to access two SPI-only requests, and one request that wasn't previously needed: * mmc_spi_read_ocr() ... SPI only * mmc_spi_set_crc() ... SPI only (override by module parm) * mmc_send_cid() ... for use without broadcast mode - Updated internal routines: * Previous mmc_send_csd() modified into mmc_send_cxd_native(); it uses native "R2" responses, which include 16 bytes of data. * Previous mmc_send_ext_csd() becomes new mmc_send_cxd_data() helper for command-and-data access * Bugfix to that mmc_send_cxd_data() code: dma-to-stack is unsafe/nonportable, so kmalloc a bounce buffer instead. - Modified mmc_send_ext_csd() now uses mmc_send_cxd_data() helper - Modified mmc_send_csd(), and new mmc_spi_send_cid(), routines use those helper routines based on whether they're native or SPI The newest categories of cards supported by the MMC stack aren't expected to work yet with SPI: MMC or SD cards with over 4GB data, and SDIO. All those cards support SPI mode, so eventually they should work too. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
2007-08-08 16:11:32 +00:00
/*
* Enable runtime PM only if supported by host+card+board
*/
if (host->caps & MMC_CAP_POWER_OFF_CARD) {
/*
* Do not allow runtime suspend until after SDIO function
* devices are added.
*/
pm_runtime_get_noresume(&card->dev);
/*
* Let runtime PM core know our card is active
*/
err = pm_runtime_set_active(&card->dev);
if (err)
goto remove;
/*
* Enable runtime PM for this card
*/
pm_runtime_enable(&card->dev);
}
/*
* The number of functions on the card is encoded inside
* the ocr.
*/
funcs = (ocr & 0x70000000) >> 28;
card->sdio_funcs = 0;
/*
* Initialize (but don't add) all present functions.
*/
for (i = 0; i < funcs; i++, card->sdio_funcs++) {
err = sdio_init_func(host->card, i + 1);
if (err)
goto remove;
/*
* Enable Runtime PM for this func (if supported)
*/
if (host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_enable(&card->sdio_func[i]->dev);
}
/*
* First add the card to the driver model...
*/
mmc_release_host(host);
err = mmc_add_card(host->card);
if (err)
goto remove_added;
/*
* ...then the SDIO functions.
*/
for (i = 0;i < funcs;i++) {
err = sdio_add_func(host->card->sdio_func[i]);
if (err)
goto remove_added;
}
if (host->caps & MMC_CAP_POWER_OFF_CARD)
pm_runtime_put(&card->dev);
mmc_claim_host(host);
return 0;
remove:
mmc_release_host(host);
remove_added:
/*
* The devices are being deleted so it is not necessary to disable
* runtime PM. Similarly we also don't pm_runtime_put() the SDIO card
* because it needs to be active to remove any function devices that
* were probed, and after that it gets deleted.
*/
mmc_sdio_remove(host);
mmc_claim_host(host);
err:
mmc_detach_bus(host);
pr_err("%s: error %d whilst initialising SDIO card\n",
mmc_hostname(host), err);
return err;
}