MMC core:
- Improve API to make it clear that mmc_hw_reset() is for cards - Fixup support for writeback-cache for eMMC and SD - Check for errors after writes on SPI MMC host: - renesas_sdhi: A couple of fixes of TAP settings for eMMC HS400 mode - mmci_stm32: Fixup check of all elements in sg list - sdhci-xenon: Revert unnecessary fix for annoying 1.8V regulator warning -----BEGIN PGP SIGNATURE----- iQJLBAABCgA1FiEEugLDXPmKSktSkQsV/iaEJXNYjCkFAmJP/M0XHHVsZi5oYW5z c29uQGxpbmFyby5vcmcACgkQ/iaEJXNYjCnMnxAAjBBCFMHHG8wykeE8S3L6Bf5Y gQGMBwCD5LAATOEHWsomtIlGDP9fa1NJawTJbMjCdX3oec3svx9WT1h6bSGMfieB DYqhVYb+USHx3HsoVteu1fUq4VCtNv9PSnsQermEnV3iLeke8ahmlIlUc2SUW8BA Y/37gxmvOFv2xCWtp5OWwqHLaBrWlgd5I/5c+f2YnlZ59ROitSUNMp0GUGk8mij4 0uGKbz+ZtwrynoZxhvtxahyHSH/s6csrkKLtHDUMcIpO7s6kneSLkbOwU6z9p0Hm ILKdmrzrsfD23g4J8nshziGBnf+09a9dTuaEw872n/Oe9Gm1TA1GvhD021Prk7fa iR1WzlfEZ+lK7SRo1urdz/OPaFsyAVinBbq3fZZ4LteKZw9Ef/9wph/+3vjECEMe M7W8Zw4ir1iGwReRumY9dNvSB/ShfS5E0Cd6pybNHD+t2l68LYO/RBVDd2D1Efq4 ng7lsmmEkGQRodZaDQkUx9qU+RfxWKs0farfgW4zDMPVCEfrhXQ4P398rzuw04mB VBjnen8D68QswwQPkNzKcG81c00qgKtxy/0soL1kYa2BpQMDrM7wWYYs/U/BGTZs ut1GsozWcpnZ3smVG1i5sQVqJ8dhhM5z7Ebfb6FieV1iTSiWtUlQFlT3mhYRvk+L JtbTRFQCOrjmxvlV9fQ= =MC9g -----END PGP SIGNATURE----- Merge tag 'mmc-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc Pull MMC updates from Ulf Hansson: "MMC core: - Improve API to make it clear that mmc_hw_reset() is for cards - Fixup support for writeback-cache for eMMC and SD - Check for errors after writes on SPI MMC host: - renesas_sdhi: A couple of fixes of TAP settings for eMMC HS400 mode - mmci_stm32: Fixup check of all elements in sg list - sdhci-xenon: Revert unnecessary fix for annoying 1.8V regulator warning" * tag 'mmc-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: mmc: core: improve API to make clear mmc_hw_reset is for cards mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is complete mmc: renesas_sdhi: special 4tap settings only apply to HS400 mmc: core: Fixup support for writeback-cache for eMMC and SD mmc: block: Check for errors after write on SPI mmc: mmci: stm32: correctly check all elements of sg list Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning"
This commit is contained in:
commit
0ccab01401
|
@ -993,7 +993,7 @@ static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host,
|
|||
return -EEXIST;
|
||||
|
||||
md->reset_done |= type;
|
||||
err = mmc_hw_reset(host);
|
||||
err = mmc_hw_reset(host->card);
|
||||
/* Ensure we switch back to the correct partition */
|
||||
if (err) {
|
||||
struct mmc_blk_data *main_md =
|
||||
|
@ -1880,6 +1880,31 @@ static inline bool mmc_blk_rq_error(struct mmc_blk_request *brq)
|
|||
brq->data.error || brq->cmd.resp[0] & CMD_ERRORS;
|
||||
}
|
||||
|
||||
static int mmc_spi_err_check(struct mmc_card *card)
|
||||
{
|
||||
u32 status = 0;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* SPI does not have a TRAN state we have to wait on, instead the
|
||||
* card is ready again when it no longer holds the line LOW.
|
||||
* We still have to ensure two things here before we know the write
|
||||
* was successful:
|
||||
* 1. The card has not disconnected during busy and we actually read our
|
||||
* own pull-up, thinking it was still connected, so ensure it
|
||||
* still responds.
|
||||
* 2. Check for any error bits, in particular R1_SPI_IDLE to catch a
|
||||
* just reconnected card after being disconnected during busy.
|
||||
*/
|
||||
err = __mmc_send_status(card, &status, 0);
|
||||
if (err)
|
||||
return err;
|
||||
/* All R1 and R2 bits of SPI are errors in our case */
|
||||
if (status)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmc_blk_busy_cb(void *cb_data, bool *busy)
|
||||
{
|
||||
struct mmc_blk_busy_data *data = cb_data;
|
||||
|
@ -1903,9 +1928,16 @@ static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)
|
|||
struct mmc_blk_busy_data cb_data;
|
||||
int err;
|
||||
|
||||
if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ)
|
||||
if (rq_data_dir(req) == READ)
|
||||
return 0;
|
||||
|
||||
if (mmc_host_is_spi(card->host)) {
|
||||
err = mmc_spi_err_check(card);
|
||||
if (err)
|
||||
mqrq->brq.data.bytes_xfered = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
cb_data.card = card;
|
||||
cb_data.status = 0;
|
||||
err = __mmc_poll_for_busy(card->host, 0, MMC_BLK_TIMEOUT_MS,
|
||||
|
@ -2350,6 +2382,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
|
|||
struct mmc_blk_data *md;
|
||||
int devidx, ret;
|
||||
char cap_str[10];
|
||||
bool cache_enabled = false;
|
||||
bool fua_enabled = false;
|
||||
|
||||
devidx = ida_simple_get(&mmc_blk_ida, 0, max_devices, GFP_KERNEL);
|
||||
if (devidx < 0) {
|
||||
|
@ -2429,13 +2463,17 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
|
|||
md->flags |= MMC_BLK_CMD23;
|
||||
}
|
||||
|
||||
if (mmc_card_mmc(card) &&
|
||||
md->flags & MMC_BLK_CMD23 &&
|
||||
if (md->flags & MMC_BLK_CMD23 &&
|
||||
((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) ||
|
||||
card->ext_csd.rel_sectors)) {
|
||||
md->flags |= MMC_BLK_REL_WR;
|
||||
blk_queue_write_cache(md->queue.queue, true, true);
|
||||
fua_enabled = true;
|
||||
cache_enabled = true;
|
||||
}
|
||||
if (mmc_cache_enabled(card->host))
|
||||
cache_enabled = true;
|
||||
|
||||
blk_queue_write_cache(md->queue.queue, cache_enabled, fua_enabled);
|
||||
|
||||
string_get_size((u64)size, 512, STRING_UNITS_2,
|
||||
cap_str, sizeof(cap_str));
|
||||
|
|
|
@ -1995,7 +1995,7 @@ static void mmc_hw_reset_for_init(struct mmc_host *host)
|
|||
|
||||
/**
|
||||
* mmc_hw_reset - reset the card in hardware
|
||||
* @host: MMC host to which the card is attached
|
||||
* @card: card to be reset
|
||||
*
|
||||
* Hard reset the card. This function is only for upper layers, like the
|
||||
* block layer or card drivers. You cannot use it in host drivers (struct
|
||||
|
@ -2003,8 +2003,9 @@ static void mmc_hw_reset_for_init(struct mmc_host *host)
|
|||
*
|
||||
* Return: 0 on success, -errno on failure
|
||||
*/
|
||||
int mmc_hw_reset(struct mmc_host *host)
|
||||
int mmc_hw_reset(struct mmc_card *card)
|
||||
{
|
||||
struct mmc_host *host = card->host;
|
||||
int ret;
|
||||
|
||||
ret = host->bus_ops->hw_reset(host);
|
||||
|
|
|
@ -2325,10 +2325,9 @@ static int mmc_test_profile_sglen_r_nonblock_perf(struct mmc_test_card *test)
|
|||
static int mmc_test_reset(struct mmc_test_card *test)
|
||||
{
|
||||
struct mmc_card *card = test->card;
|
||||
struct mmc_host *host = card->host;
|
||||
int err;
|
||||
|
||||
err = mmc_hw_reset(host);
|
||||
err = mmc_hw_reset(card);
|
||||
if (!err) {
|
||||
/*
|
||||
* Reset will re-enable the card's command queue, but tests
|
||||
|
|
|
@ -62,8 +62,8 @@ static int sdmmc_idma_validate_data(struct mmci_host *host,
|
|||
* excepted the last element which has no constraint on idmasize
|
||||
*/
|
||||
for_each_sg(data->sg, sg, data->sg_len - 1, i) {
|
||||
if (!IS_ALIGNED(data->sg->offset, sizeof(u32)) ||
|
||||
!IS_ALIGNED(data->sg->length, SDMMC_IDMA_BURST)) {
|
||||
if (!IS_ALIGNED(sg->offset, sizeof(u32)) ||
|
||||
!IS_ALIGNED(sg->length, SDMMC_IDMA_BURST)) {
|
||||
dev_err(mmc_dev(host->mmc),
|
||||
"unaligned scatterlist: ofst:%x length:%d\n",
|
||||
data->sg->offset, data->sg->length);
|
||||
|
@ -71,7 +71,7 @@ static int sdmmc_idma_validate_data(struct mmci_host *host,
|
|||
}
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(data->sg->offset, sizeof(u32))) {
|
||||
if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
|
||||
dev_err(mmc_dev(host->mmc),
|
||||
"unaligned last scatterlist: ofst:%x length:%d\n",
|
||||
data->sg->offset, data->sg->length);
|
||||
|
|
|
@ -144,9 +144,9 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
|
|||
return clk_get_rate(priv->clk);
|
||||
|
||||
if (priv->clkh) {
|
||||
/* HS400 with 4TAP needs different clock settings */
|
||||
bool use_4tap = priv->quirks && priv->quirks->hs400_4taps;
|
||||
bool need_slow_clkh = (host->mmc->ios.timing == MMC_TIMING_UHS_SDR104) ||
|
||||
(host->mmc->ios.timing == MMC_TIMING_MMC_HS400);
|
||||
bool need_slow_clkh = host->mmc->ios.timing == MMC_TIMING_MMC_HS400;
|
||||
clkh_shift = use_4tap && need_slow_clkh ? 1 : 2;
|
||||
ref_clk = priv->clkh;
|
||||
}
|
||||
|
@ -396,10 +396,10 @@ static void renesas_sdhi_hs400_complete(struct mmc_host *mmc)
|
|||
SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) |
|
||||
sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
|
||||
|
||||
/* Set the sampling clock selection range of HS400 mode */
|
||||
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
|
||||
SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN |
|
||||
0x4 << SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT);
|
||||
sd_scc_read32(host, priv,
|
||||
SH_MOBILE_SDHI_SCC_DTCNTL));
|
||||
|
||||
/* Avoid bad TAP */
|
||||
if (bad_taps & BIT(priv->tap_set)) {
|
||||
|
|
|
@ -241,16 +241,6 @@ static void xenon_voltage_switch(struct sdhci_host *host)
|
|||
{
|
||||
/* Wait for 5ms after set 1.8V signal enable bit */
|
||||
usleep_range(5000, 5500);
|
||||
|
||||
/*
|
||||
* For some reason the controller's Host Control2 register reports
|
||||
* the bit representing 1.8V signaling as 0 when read after it was
|
||||
* written as 1. Subsequent read reports 1.
|
||||
*
|
||||
* Since this may cause some issues, do an empty read of the Host
|
||||
* Control2 register here to circumvent this.
|
||||
*/
|
||||
sdhci_readw(host, SDHCI_HOST_CONTROL2);
|
||||
}
|
||||
|
||||
static unsigned int xenon_get_max_clock(struct sdhci_host *host)
|
||||
|
|
|
@ -1633,7 +1633,7 @@ static void ath10k_sdio_hif_power_down(struct ath10k *ar)
|
|||
return;
|
||||
}
|
||||
|
||||
ret = mmc_hw_reset(ar_sdio->func->card->host);
|
||||
ret = mmc_hw_reset(ar_sdio->func->card);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "unable to reset sdio: %d\n", ret);
|
||||
|
||||
|
|
|
@ -4165,7 +4165,7 @@ static int brcmf_sdio_bus_reset(struct device *dev)
|
|||
|
||||
/* reset the adapter */
|
||||
sdio_claim_host(sdiodev->func1);
|
||||
mmc_hw_reset(sdiodev->func1->card->host);
|
||||
mmc_hw_reset(sdiodev->func1->card);
|
||||
sdio_release_host(sdiodev->func1);
|
||||
|
||||
brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
|
||||
|
|
|
@ -2639,7 +2639,7 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
|
|||
|
||||
/* Run a HW reset of the SDIO interface. */
|
||||
sdio_claim_host(func);
|
||||
ret = mmc_hw_reset(func->card->host);
|
||||
ret = mmc_hw_reset(func->card);
|
||||
sdio_release_host(func);
|
||||
|
||||
switch (ret) {
|
||||
|
|
|
@ -146,7 +146,7 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
|
|||
* To guarantee that the SDIO card is power cycled, as required to make
|
||||
* the FW programming to succeed, let's do a brute force HW reset.
|
||||
*/
|
||||
mmc_hw_reset(card->host);
|
||||
mmc_hw_reset(card);
|
||||
|
||||
sdio_enable_func(func);
|
||||
sdio_release_host(func);
|
||||
|
|
|
@ -175,7 +175,7 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq);
|
|||
int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd,
|
||||
int retries);
|
||||
|
||||
int mmc_hw_reset(struct mmc_host *host);
|
||||
int mmc_hw_reset(struct mmc_card *card);
|
||||
int mmc_sw_reset(struct mmc_host *host);
|
||||
void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card);
|
||||
|
||||
|
|
Loading…
Reference in New Issue