mmc: core: enable BKOPS by read-modify-write instead of override
This change adds a read-modify-write logic to BKOPS feature enable. It is required in order to avoid overriding other fields defined in BKOPS_EN register. Change-Id: I689f5cd14d9ec1bb881f503a0418026a59e6c197 Signed-off-by: Talel Shenhar <tatias@codeaurora.org>
This commit is contained in:
parent
2c3155a818
commit
18a5a61a84
|
@ -1352,7 +1352,7 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
|
|||
from = blk_rq_pos(req);
|
||||
nr = blk_rq_sectors(req);
|
||||
|
||||
if (card->ext_csd.bkops_en)
|
||||
if (mmc_card_get_bkops_en_manual(card))
|
||||
card->bkops_info.sectors_changed += blk_rq_sectors(req);
|
||||
|
||||
if (mmc_can_discard(card))
|
||||
|
@ -2296,7 +2296,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
|
|||
|
||||
if (rq_data_dir(next) == WRITE) {
|
||||
mq->num_of_potential_packed_wr_reqs++;
|
||||
if (card->ext_csd.bkops_en)
|
||||
if (mmc_card_get_bkops_en_manual(card))
|
||||
card->bkops_info.sectors_changed +=
|
||||
blk_rq_sectors(next);
|
||||
}
|
||||
|
@ -2553,7 +2553,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
|
|||
return 0;
|
||||
|
||||
if (rqc) {
|
||||
if ((card->ext_csd.bkops_en) && (rq_data_dir(rqc) == WRITE))
|
||||
if (mmc_card_get_bkops_en_manual(card) &&
|
||||
(rq_data_dir(rqc) == WRITE))
|
||||
card->bkops_info.sectors_changed += blk_rq_sectors(rqc);
|
||||
reqs = mmc_blk_prep_packed_list(mq, rqc);
|
||||
}
|
||||
|
@ -2768,7 +2769,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
|
|||
if (mmc_bus_needs_resume(card->host))
|
||||
mmc_resume_bus(card->host);
|
||||
#endif
|
||||
if (card->ext_csd.bkops_en)
|
||||
if (mmc_card_get_bkops_en_manual(card))
|
||||
mmc_stop_bkops(card);
|
||||
}
|
||||
|
||||
|
|
|
@ -1788,7 +1788,7 @@ static int prepare_bkops(struct test_data *td)
|
|||
|
||||
bkops_stat = &card->bkops_info.bkops_stats;
|
||||
|
||||
if (!card->ext_csd.bkops_en) {
|
||||
if (!(mmc_card_get_bkops_en_manual(card))) {
|
||||
pr_err("%s: BKOPS is not enabled by card or host)",
|
||||
__func__);
|
||||
return -ENOTSUPP;
|
||||
|
|
|
@ -400,7 +400,9 @@ EXPORT_SYMBOL(mmc_blk_init_bkops_statistics);
|
|||
*/
|
||||
void mmc_start_delayed_bkops(struct mmc_card *card)
|
||||
{
|
||||
if (!card || !card->ext_csd.bkops_en || mmc_card_doing_bkops(card))
|
||||
if (!card ||
|
||||
!(mmc_card_get_bkops_en_manual(card)) ||
|
||||
mmc_card_doing_bkops(card))
|
||||
return;
|
||||
|
||||
if (card->bkops_info.sectors_changed <
|
||||
|
@ -437,7 +439,7 @@ void mmc_start_bkops(struct mmc_card *card, bool from_exception)
|
|||
int err;
|
||||
|
||||
BUG_ON(!card);
|
||||
if (!card->ext_csd.bkops_en)
|
||||
if (!(mmc_card_get_bkops_en_manual(card)))
|
||||
return;
|
||||
|
||||
if ((card->bkops_info.cancel_delayed_work) && !from_exception) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
#include <linux/mmc/mmc.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "mmc_ops.h"
|
||||
|
@ -725,7 +726,7 @@ void mmc_add_card_debugfs(struct mmc_card *card)
|
|||
goto err;
|
||||
|
||||
if (mmc_card_mmc(card) && (card->ext_csd.rev >= 5) &&
|
||||
card->ext_csd.bkops_en)
|
||||
(mmc_card_get_bkops_en_manual(card)))
|
||||
if (!debugfs_create_file("bkops_stats", S_IRUSR, root, card,
|
||||
&mmc_dbg_bkops_stats_fops))
|
||||
goto err;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
|
@ -530,15 +531,19 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|||
card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
|
||||
card->ext_csd.raw_bkops_status =
|
||||
ext_csd[EXT_CSD_BKOPS_STATUS];
|
||||
if (!card->ext_csd.bkops_en &&
|
||||
if (!(mmc_card_get_bkops_en_manual(card)) &&
|
||||
card->host->caps2 & MMC_CAP2_INIT_BKOPS) {
|
||||
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_BKOPS_EN, 1, 0);
|
||||
if (err)
|
||||
mmc_card_set_bkops_en_manual(card);
|
||||
err = mmc_switch(card,
|
||||
EXT_CSD_CMD_SET_NORMAL,
|
||||
EXT_CSD_BKOPS_EN,
|
||||
card->ext_csd.bkops_en , 0);
|
||||
if (err) {
|
||||
pr_warn("%s: Enabling BKOPS failed\n",
|
||||
mmc_hostname(card->host));
|
||||
else
|
||||
card->ext_csd.bkops_en = 1;
|
||||
mmc_card_clr_bkops_en_manual(card);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1686,8 +1691,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
|
|||
goto free_card;
|
||||
}
|
||||
}
|
||||
|
||||
if (card->ext_csd.bkops_en) {
|
||||
if (mmc_card_get_bkops_en_manual(card)) {
|
||||
INIT_DELAYED_WORK(&card->bkops_info.dw,
|
||||
mmc_start_idle_time_bkops);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ struct mmc_ext_csd {
|
|||
bool hpi; /* HPI support bit */
|
||||
unsigned int hpi_cmd; /* cmd used as HPI */
|
||||
bool bkops; /* background support bit */
|
||||
bool bkops_en; /* background enable bit */
|
||||
u8 bkops_en; /* background enable bits */
|
||||
unsigned int data_sector_size; /* 512 bytes or 4KB */
|
||||
unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
|
||||
unsigned int boot_ro_lock; /* ro lock support */
|
||||
|
@ -401,6 +401,23 @@ struct mmc_card {
|
|||
u8 *cached_ext_csd;
|
||||
};
|
||||
|
||||
/*
|
||||
* mmc_csd registers get/set/clr helpers
|
||||
*/
|
||||
#define mmc_card_get_bkops_en_manual(card) ((card->ext_csd.bkops_en) &\
|
||||
EXT_CSD_BKOPS_EN_MANUAL_EN)
|
||||
#define mmc_card_set_bkops_en_manual(card) ((card->ext_csd.bkops_en) |= \
|
||||
EXT_CSD_BKOPS_EN_MANUAL_EN)
|
||||
#define mmc_card_clr_bkops_en_manual(card) ((card->ext_csd.bkops_en) &= \
|
||||
~EXT_CSD_BKOPS_EN_MANUAL_EN)
|
||||
|
||||
#define mmc_card_get_bkops_en_auto(card) ((card->ext_csd.bkops_en) & \
|
||||
EXT_CSD_BKOPS_EN_AUTO_EN)
|
||||
#define mmc_card_set_bkops_en_auto(card) ((card->ext_csd.bkops_en) |= \
|
||||
EXT_CSD_BKOPS_EN_AUTO_EN)
|
||||
#define mmc_card_clr_bkops_en_auto(card) ((card->ext_csd.bkops_en) &= \
|
||||
~EXT_CSD_BKOPS_EN_AUTO_EN)
|
||||
|
||||
/*
|
||||
* This function fill contents in mmc_part.
|
||||
*/
|
||||
|
|
|
@ -282,6 +282,9 @@ struct _mmc_csd {
|
|||
* EXT_CSD field definitions
|
||||
*/
|
||||
|
||||
#define EXT_CSD_BKOPS_EN_MANUAL_EN BIT(0)
|
||||
#define EXT_CSD_BKOPS_EN_AUTO_EN BIT(1)
|
||||
|
||||
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
|
||||
|
||||
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
|
||||
|
|
Loading…
Reference in New Issue