mmc: core: Add halt support
Halt is a controller feature that can change the controller mode from command-queue to legacy. This feature is very helpful in error cases. Change-Id: I7f1465b609afed68886256bd605d4019716964f4 Signed-off-by: Asutosh Das <asutoshd@codeaurora.org>
This commit is contained in:
parent
c9bb6d045d
commit
58e91e920d
|
@ -57,6 +57,7 @@ static inline bool mmc_cmdq_should_pull_reqs(struct mmc_host *host,
|
|||
struct mmc_cmdq_context_info *ctx)
|
||||
{
|
||||
if (test_bit(CMDQ_STATE_DCMD_ACTIVE, &ctx->curr_state) ||
|
||||
mmc_host_halt(host) ||
|
||||
test_bit(CMDQ_STATE_ERR, &ctx->curr_state)) {
|
||||
pr_debug("%s: %s: skip pulling reqs: state: %lu\n",
|
||||
mmc_hostname(host), __func__, ctx->curr_state);
|
||||
|
|
|
@ -947,6 +947,39 @@ void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, int err)
|
|||
}
|
||||
EXPORT_SYMBOL(mmc_cmdq_post_req);
|
||||
|
||||
/**
|
||||
* mmc_cmdq_halt - halt/un-halt the command queue engine
|
||||
* @host: host instance
|
||||
* @halt: true - halt, un-halt otherwise
|
||||
*
|
||||
* Host halts the command queue engine. It should complete
|
||||
* the ongoing transfer and release the bus.
|
||||
* All legacy commands can be sent upon successful
|
||||
* completion of this function.
|
||||
* Returns 0 on success, negative otherwise
|
||||
*/
|
||||
int mmc_cmdq_halt(struct mmc_host *host, bool halt)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if ((halt && mmc_host_halt(host)) ||
|
||||
(!halt && !mmc_host_halt(host)))
|
||||
return -EINVAL;
|
||||
|
||||
if (host->cmdq_ops->halt) {
|
||||
err = host->cmdq_ops->halt(host, halt);
|
||||
if (!err && halt)
|
||||
mmc_host_set_halt(host);
|
||||
else if (!err && !halt)
|
||||
mmc_host_clr_halt(host);
|
||||
} else {
|
||||
err = -ENOSYS;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mmc_cmdq_halt);
|
||||
|
||||
int mmc_cmdq_start_req(struct mmc_host *host, struct mmc_cmdq_req *cmdq_req)
|
||||
{
|
||||
struct mmc_request *mrq = &cmdq_req->mrq;
|
||||
|
|
|
@ -115,6 +115,7 @@ struct mmc_card;
|
|||
struct mmc_async_req;
|
||||
struct mmc_cmdq_req;
|
||||
|
||||
extern int mmc_cmdq_halt(struct mmc_host *host, bool enable);
|
||||
extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq,
|
||||
int err);
|
||||
extern int mmc_cmdq_start_req(struct mmc_host *host,
|
||||
|
|
|
@ -97,6 +97,7 @@ struct mmc_cmdq_host_ops {
|
|||
int (*request)(struct mmc_host *host, struct mmc_request *mrq);
|
||||
void (*post_req)(struct mmc_host *host, struct mmc_request *mrq,
|
||||
int err);
|
||||
int (*halt)(struct mmc_host *host, bool halt);
|
||||
};
|
||||
|
||||
struct mmc_host_ops {
|
||||
|
@ -236,6 +237,7 @@ struct mmc_cmdq_context_info {
|
|||
unsigned long curr_state;
|
||||
#define CMDQ_STATE_ERR 0
|
||||
#define CMDQ_STATE_DCMD_ACTIVE 1
|
||||
#define CMDQ_STATE_HALT 2
|
||||
/* no free tag available */
|
||||
unsigned long req_starved;
|
||||
};
|
||||
|
@ -656,6 +658,21 @@ static inline int mmc_host_packed_wr(struct mmc_host *host)
|
|||
return host->caps2 & MMC_CAP2_PACKED_WR;
|
||||
}
|
||||
|
||||
static inline void mmc_host_set_halt(struct mmc_host *host)
|
||||
{
|
||||
set_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
|
||||
}
|
||||
|
||||
static inline void mmc_host_clr_halt(struct mmc_host *host)
|
||||
{
|
||||
clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
|
||||
}
|
||||
|
||||
static inline int mmc_host_halt(struct mmc_host *host)
|
||||
{
|
||||
return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMC_CLKGATE
|
||||
void mmc_host_clk_hold(struct mmc_host *host);
|
||||
void mmc_host_clk_release(struct mmc_host *host);
|
||||
|
|
Loading…
Reference in New Issue