From fda56078bbf3b05a9bb1c2ffe3d3616dd15714d5 Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Wed, 24 Jun 2015 19:51:58 +0300 Subject: mmc: add support for bkops Add support for manual and auto bkops for legacy (not command-queue) mode. Change-Id: I1333e1d4330393e446ba48a9474c83295744c050 Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed merge conflicts and compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 29 +++++++++++++++++++++++++++-- include/linux/mmc/core.h | 21 ++++++++++++++++++++- include/linux/mmc/host.h | 2 ++ include/linux/mmc/mmc.h | 3 +++ 4 files changed, 52 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 8289add95151..80ce6cc36b88 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -86,7 +87,7 @@ struct mmc_ext_csd { bool hpi; /* HPI support bit */ unsigned int hpi_cmd; /* cmd used as HPI */ bool bkops; /* background support bit */ - bool man_bkops_en; /* manual bkops enable bit */ + u8 man_bkops_en; /* manual bkops enable */ 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 */ @@ -274,6 +275,15 @@ struct mmc_part { #define MMC_BLK_DATA_AREA_RPMB (1<<3) }; +/** + * struct mmc_bkops_info - BKOPS data + * @need_manual: indication whether have to send START_BKOPS + * to the device + */ +struct mmc_bkops_info { + bool needs_manual; +}; + /* * MMC device */ @@ -297,9 +307,10 @@ struct mmc_card { #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */ #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ -#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ +#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing manual BKOPS */ #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ #define MMC_STATE_CMDQ (1<<12) /* card is in cmd queue mode */ +#define MMC_STATE_AUTO_BKOPS (1<<13) /* card is doing auto BKOPS */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -363,6 +374,7 @@ struct mmc_card { bool issue_long_pon; u8 *cached_ext_csd; bool cmdq_init; + struct mmc_bkops_info bkops; }; /* @@ -512,6 +524,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) #define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) +#define mmc_card_doing_auto_bkops(c) ((c)->state & MMC_STATE_AUTO_BKOPS) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -524,6 +537,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) #define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) #define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) +#define mmc_card_set_auto_bkops(c) ((c)->state |= MMC_STATE_AUTO_BKOPS) +#define mmc_card_clr_auto_bkops(c) ((c)->state &= ~MMC_STATE_AUTO_BKOPS) /* * Quirk add/remove for MMC products. @@ -594,6 +609,16 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; } +static inline bool mmc_card_support_auto_bkops(const struct mmc_card *c) +{ + return c->ext_csd.rev >= MMC_V5_1; +} + +static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) +{ + return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_MANUAL_EN; +} + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 22c610609a25..446b56765dbb 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -112,6 +112,23 @@ struct mmc_request { struct request *req; }; +struct mmc_bus_ops { + void (*remove)(struct mmc_host *); + void (*detect)(struct mmc_host *); + int (*pre_suspend)(struct mmc_host *); + int (*suspend)(struct mmc_host *); + int (*resume)(struct mmc_host *); + int (*runtime_suspend)(struct mmc_host *); + int (*runtime_resume)(struct mmc_host *); + int (*runtime_idle)(struct mmc_host *); + int (*power_save)(struct mmc_host *); + int (*power_restore)(struct mmc_host *); + int (*alive)(struct mmc_host *); + int (*shutdown)(struct mmc_host *); + int (*reset)(struct mmc_host *); + int (*change_bus_speed)(struct mmc_host *, unsigned long *); +}; + struct mmc_card; struct mmc_async_req; struct mmc_cmdq_req; @@ -139,13 +156,15 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); -extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); +extern void mmc_check_bkops(struct mmc_card *card); +extern void mmc_start_manual_bkops(struct mmc_card *card); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); extern int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, u8 value, unsigned int timeout_ms, bool use_busy_signal, bool ignore_timeout); extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); +extern int mmc_set_auto_bkops(struct mmc_card *card, bool enable); #define MMC_ERASE_ARG 0x00000000 #define MMC_SECURE_ERASE_ARG 0x80000000 diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 42e7b412e6f1..cb46cdf8dcf3 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -22,6 +22,8 @@ #include #include +#define MMC_AUTOSUSPEND_DELAY_MS 3000 + struct mmc_ios { unsigned int clock; /* clock rate */ unsigned int old_rate; /* saved clock rate */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index aa1db902745f..1cde2e5eb283 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -370,6 +370,9 @@ struct _mmc_csd { #define EXT_CSD_PACKED_EVENT_EN BIT(3) +#define EXT_CSD_BKOPS_MANUAL_EN BIT(0) +#define EXT_CSD_BKOPS_AUTO_EN BIT(1) + /* * EXCEPTION_EVENT_STATUS field */ -- cgit v1.2.3