Skip to content

Commit

Permalink
mmc: core: Move eMMC cache flushing to a new bus_ops callback
Browse files Browse the repository at this point in the history
To prepare to add internal cache management for SD cards, let's start by
moving the eMMC specific code into a new ->flush_cache() bus_ops callback.

In this way, it becomes straight forward to add the SD specific parts,
as subsequent changes are about to show.

Signed-off-by: Ulf Hansson <[email protected]>
Reviewed-by: Avri Altman <[email protected]>
Reviewed-by: Linus Walleij <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
  • Loading branch information
storulf committed Jun 14, 2021
1 parent 70b52f0 commit 8ae11ed
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 25 deletions.
2 changes: 1 addition & 1 deletion drivers/mmc/core/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
struct mmc_card *card = md->queue.card;
int ret = 0;

ret = mmc_flush_cache(card);
ret = mmc_flush_cache(card->host);
blk_mq_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
}

Expand Down
9 changes: 9 additions & 0 deletions drivers/mmc/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct mmc_bus_ops {
int (*hw_reset)(struct mmc_host *);
int (*sw_reset)(struct mmc_host *);
bool (*cache_enabled)(struct mmc_host *);
int (*flush_cache)(struct mmc_host *);
};

void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
Expand Down Expand Up @@ -172,4 +173,12 @@ static inline bool mmc_cache_enabled(struct mmc_host *host)
return false;
}

static inline int mmc_flush_cache(struct mmc_host *host)
{
if (host->bus_ops->flush_cache)
return host->bus_ops->flush_cache(host);

return 0;
}

#endif
25 changes: 23 additions & 2 deletions drivers/mmc/core/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#define DEFAULT_CMD6_TIMEOUT_MS 500
#define MIN_CACHE_EN_TIMEOUT_MS 1600
#define CACHE_FLUSH_TIMEOUT_MS 30000 /* 30s */

static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
Expand Down Expand Up @@ -2036,6 +2037,25 @@ static bool _mmc_cache_enabled(struct mmc_host *host)
host->card->ext_csd.cache_ctrl & 1;
}

/*
* Flush the internal cache of the eMMC to non-volatile storage.
*/
static int _mmc_flush_cache(struct mmc_host *host)
{
int err = 0;

if (_mmc_cache_enabled(host)) {
err = mmc_switch(host->card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_FLUSH_CACHE, 1,
CACHE_FLUSH_TIMEOUT_MS);
if (err)
pr_err("%s: cache flush error %d\n",
mmc_hostname(host), err);
}

return err;
}

static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
{
int err = 0;
Expand All @@ -2047,7 +2067,7 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
if (mmc_card_suspended(host->card))
goto out;

err = mmc_flush_cache(host->card);
err = _mmc_flush_cache(host);
if (err)
goto out;

Expand Down Expand Up @@ -2188,7 +2208,7 @@ static int _mmc_hw_reset(struct mmc_host *host)
* In the case of recovery, we can't expect flushing the cache to work
* always, but we have a go and ignore errors.
*/
mmc_flush_cache(host->card);
_mmc_flush_cache(host);

if ((host->caps & MMC_CAP_HW_RESET) && host->ops->hw_reset &&
mmc_can_reset(card)) {
Expand Down Expand Up @@ -2216,6 +2236,7 @@ static const struct mmc_bus_ops mmc_ops = {
.shutdown = mmc_shutdown,
.hw_reset = _mmc_hw_reset,
.cache_enabled = _mmc_cache_enabled,
.flush_cache = _mmc_flush_cache,
};

/*
Expand Down
21 changes: 0 additions & 21 deletions drivers/mmc/core/mmc_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "mmc_ops.h"

#define MMC_BKOPS_TIMEOUT_MS (120 * 1000) /* 120s */
#define MMC_CACHE_FLUSH_TIMEOUT_MS (30 * 1000) /* 30s */
#define MMC_SANITIZE_TIMEOUT_MS (240 * 1000) /* 240s */

static const u8 tuning_blk_pattern_4bit[] = {
Expand Down Expand Up @@ -964,26 +963,6 @@ void mmc_run_bkops(struct mmc_card *card)
}
EXPORT_SYMBOL(mmc_run_bkops);

/*
* Flush the cache to the non-volatile storage.
*/
int mmc_flush_cache(struct mmc_card *card)
{
int err = 0;

if (mmc_cache_enabled(card->host)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_FLUSH_CACHE, 1,
MMC_CACHE_FLUSH_TIMEOUT_MS);
if (err)
pr_err("%s: cache flush error %d\n",
mmc_hostname(card->host), err);
}

return err;
}
EXPORT_SYMBOL(mmc_flush_cache);

static int mmc_cmdq_switch(struct mmc_card *card, bool enable)
{
u8 val = enable ? EXT_CSD_CMDQ_MODE_ENABLED : 0;
Expand Down
1 change: 0 additions & 1 deletion drivers/mmc/core/mmc_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms);
void mmc_run_bkops(struct mmc_card *card);
int mmc_flush_cache(struct mmc_card *card);
int mmc_cmdq_enable(struct mmc_card *card);
int mmc_cmdq_disable(struct mmc_card *card);
int mmc_sanitize(struct mmc_card *card, unsigned int timeout_ms);
Expand Down

0 comments on commit 8ae11ed

Please sign in to comment.