mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 17:11:33 +00:00
Merge branch 'fixes' into next
This commit is contained in:
commit
f24483a64e
@ -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)))
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user