Merge branch 'fixes' into next

This commit is contained in:
Ulf Hansson 2019-06-18 13:32:07 +02:00
commit f24483a64e
5 changed files with 99 additions and 7 deletions

View File

@ -144,8 +144,9 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
int err = cmd->error;
/* Flag re-tuning needed on CRC errors */
if ((cmd->opcode != MMC_SEND_TUNING_BLOCK &&
cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200) &&
if (cmd->opcode != MMC_SEND_TUNING_BLOCK &&
cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
!host->retune_crc_disable &&
(err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) ||
(mrq->data && mrq->data->error == -EILSEQ) ||
(mrq->stop && mrq->stop->error == -EILSEQ)))

View File

@ -15,6 +15,7 @@
#include "sdio_ops.h"
#include "core.h"
#include "card.h"
#include "host.h"
/**
* sdio_claim_host - exclusively claim a bus for a certain SDIO function
@ -734,3 +735,79 @@ int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags)
return 0;
}
EXPORT_SYMBOL_GPL(sdio_set_host_pm_flags);
/**
* sdio_retune_crc_disable - temporarily disable retuning on CRC errors
* @func: SDIO function attached to host
*
* If the SDIO card is known to be in a state where it might produce
* CRC errors on the bus in response to commands (like if we know it is
* transitioning between power states), an SDIO function driver can
* call this function to temporarily disable the SD/MMC core behavior of
* triggering an automatic retuning.
*
* This function should be called while the host is claimed and the host
* should remain claimed until sdio_retune_crc_enable() is called.
* Specifically, the expected sequence of calls is:
* - sdio_claim_host()
* - sdio_retune_crc_disable()
* - some number of calls like sdio_writeb() and sdio_readb()
* - sdio_retune_crc_enable()
* - sdio_release_host()
*/
void sdio_retune_crc_disable(struct sdio_func *func)
{
func->card->host->retune_crc_disable = true;
}
EXPORT_SYMBOL_GPL(sdio_retune_crc_disable);
/**
* sdio_retune_crc_enable - re-enable retuning on CRC errors
* @func: SDIO function attached to host
*
* This is the compement to sdio_retune_crc_disable().
*/
void sdio_retune_crc_enable(struct sdio_func *func)
{
func->card->host->retune_crc_disable = false;
}
EXPORT_SYMBOL_GPL(sdio_retune_crc_enable);
/**
* sdio_retune_hold_now - start deferring retuning requests till release
* @func: SDIO function attached to host
*
* This function can be called if it's currently a bad time to do
* a retune of the SDIO card. Retune requests made during this time
* will be held and we'll actually do the retune sometime after the
* release.
*
* This function could be useful if an SDIO card is in a power state
* where it can respond to a small subset of commands that doesn't
* include the retuning command. Care should be taken when using
* this function since (presumably) the retuning request we might be
* deferring was made for a good reason.
*
* This function should be called while the host is claimed.
*/
void sdio_retune_hold_now(struct sdio_func *func)
{
mmc_retune_hold_now(func->card->host);
}
EXPORT_SYMBOL_GPL(sdio_retune_hold_now);
/**
* sdio_retune_release - signal that it's OK to retune now
* @func: SDIO function attached to host
*
* This is the complement to sdio_retune_hold_now(). Calling this
* function won't make a retune happen right away but will allow
* them to be scheduled normally.
*
* This function should be called while the host is claimed.
*/
void sdio_retune_release(struct sdio_func *func)
{
mmc_retune_release(func->card->host);
}
EXPORT_SYMBOL_GPL(sdio_retune_release);

View File

@ -678,6 +678,12 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
brcmf_dbg(TRACE, "Enter: on=%d\n", on);
sdio_retune_crc_disable(bus->sdiodev->func1);
/* Cannot re-tune if device is asleep; defer till we're awake */
if (on)
sdio_retune_hold_now(bus->sdiodev->func1);
wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT);
/* 1st KSO write goes to AOS wake up core if device is asleep */
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
@ -738,6 +744,11 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)
if (try_cnt > MAX_KSO_ATTEMPTS)
brcmf_err("max tries: rd_val=0x%x err=%d\n", rd_val, err);
if (on)
sdio_retune_release(bus->sdiodev->func1);
sdio_retune_crc_enable(bus->sdiodev->func1);
return err;
}
@ -3375,11 +3386,7 @@ err:
static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
{
if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
bus->ci->chip == CY_CC_4373_CHIP_ID ||
bus->ci->chip == BRCM_CC_4339_CHIP_ID ||
bus->ci->chip == BRCM_CC_4345_CHIP_ID ||
bus->ci->chip == BRCM_CC_4354_CHIP_ID)
if (bus->ci->chip == CY_CC_43012_CHIP_ID)
return true;
else
return false;

View File

@ -398,6 +398,7 @@ struct mmc_host {
unsigned int retune_now:1; /* do re-tuning at next req */
unsigned int retune_paused:1; /* re-tuning is temporarily disabled */
unsigned int use_blk_mq:1; /* use blk-mq */
unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */
int rescan_disable; /* disable card detection */
int rescan_entered; /* used with nonremovable devices */

View File

@ -167,4 +167,10 @@ extern void sdio_f0_writeb(struct sdio_func *func, unsigned char b,
extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func);
extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
extern void sdio_retune_crc_disable(struct sdio_func *func);
extern void sdio_retune_crc_enable(struct sdio_func *func);
extern void sdio_retune_hold_now(struct sdio_func *func);
extern void sdio_retune_release(struct sdio_func *func);
#endif /* LINUX_MMC_SDIO_FUNC_H */