From: Adrian Hunter <adrian.hunter@intel.com>
To: Seungwon Jeon <tgih.jun@samsung.com>
Cc: linux-mmc@vger.kernel.org, cjb@laptop.org,
linux-samsung-soc@vger.kernel.org, kgene.kim@samsung.com,
dh.han@samsung.com
Subject: Re: [PATCH] mmc: core: Add cache control for eMMC4.5 device
Date: Thu, 06 Oct 2011 10:06:03 +0300 [thread overview]
Message-ID: <4E8D535B.40200@intel.com> (raw)
In-Reply-To: <000401cc83e1$ca2c8fa0$5e85aee0$%jun@samsung.com>
On 06/10/11 07:38, Seungwon Jeon wrote:
> Adrian Hunter wrote:
>> On 08/09/11 10:29, Seungwon Jeon wrote:
>>> This patch adds cache feature of eMMC4.5 Spec.
>>> If device supports cache capability, host can utilize some specific
>>> operations.
>>>
>>> Signed-off-by: Seungwon Jeon<tgih.jun@samsung.com>
>>> ---
>>> This patch is base on [PATCH v3] mmc: core: Add default timeout value
>> for CMD6
>>>
>>> drivers/mmc/card/block.c | 14 ++++++----
>>> drivers/mmc/core/core.c | 62
>> ++++++++++++++++++++++++++++++++++++++++++++++
>>> drivers/mmc/core/mmc.c | 23 +++++++++++++++++
>>> include/linux/mmc/card.h | 2 +
>>> include/linux/mmc/core.h | 2 +
>>> include/linux/mmc/host.h | 3 ++
>>> include/linux/mmc/mmc.h | 3 ++
>>> 7 files changed, 103 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
>>> index e702c61..84fa4bb 100644
>>> --- a/drivers/mmc/card/block.c
>>> +++ b/drivers/mmc/card/block.c
>>> @@ -779,16 +779,18 @@ out:
>>> static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request
>> *req)
>>> {
>>> struct mmc_blk_data *md = mq->data;
>>> + struct mmc_card *card = md->queue.card;
>>> + int ret = 0;
>>> +
>>> + ret = mmc_flush_cache(card);
>>> + if (ret)
>>> + ret = -EIO;
>>>
>>> - /*
>>> - * No-op, only service this because we need REQ_FUA for reliable
>>> - * writes.
>>> - */
>>> spin_lock_irq(&md->lock);
>>> - __blk_end_request_all(req, 0);
>>> + __blk_end_request_all(req, ret);
>>> spin_unlock_irq(&md->lock);
>>>
>>> - return 1;
>>> + return ret ? 0 : 1;
>>> }
>>>
>>> /*
>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>> index 557856b..14c2431 100644
>>> --- a/drivers/mmc/core/core.c
>>> +++ b/drivers/mmc/core/core.c
>>> @@ -1987,6 +1987,64 @@ int mmc_card_can_sleep(struct mmc_host *host)
>>> }
>>> EXPORT_SYMBOL(mmc_card_can_sleep);
>>>
>>> +/*
>>> + * Flush the cache to the non-volatile storage.
>>> + */
>>> +int mmc_flush_cache(struct mmc_card *card)
>>> +{
>>> + struct mmc_host *host = card->host;
>>> + int err = 0;
>>> +
>>> + if (!(host->caps& MMC_CAP_CACHE_CTRL))
>>> + return err;
>>> +
>>> + if (mmc_card_mmc(card)&&
>>> + (card->ext_csd.cache_size> 0)&&
>>> + (card->ext_csd.cache_ctrl& 1)) {
>>> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> + EXT_CSD_FLUSH_CACHE, 1, 0);
>>> + if (err)
>>> + pr_err("%s: cache flush error %d\n",
>>> + mmc_hostname(card->host), err);
>>> + }
>>> +
>>> + return err;
>>> +}
>>> +EXPORT_SYMBOL(mmc_flush_cache);
>>> +
>>> +/*
>>> + * Turn the cache ON/OFF.
>>> + * Turning the cache OFF shall trigger flushing of the data
>>> + * to the non-volatile storage.
>>> + */
>>> +int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
>>> +{
>>> + struct mmc_card *card = host->card;
>>> + int err = 0;
>>> +
>>> + if (!(host->caps& MMC_CAP_CACHE_CTRL))
>>> + return err;
>>> +
>>
>> This patch does not cover code paths for removable cards.
>> For clarity and in case a platform does not set non-removable
>> flags for eMMC, a check is needed here e.g.
>>
>> if (mmc_card_is_removable(host))
>> return 0;
>>
> Is it worry about normal MMC card type and?
> Then, "card->ext_csd.cache_size" is a good condition for deciding cache control.
> Or even though eMMC should be non-removable type, platform does not set non-removable for eMMC type mistakenly?
Yes. Looking at mmc_pm_notify() and mmc_attach_bus_ops() it seems that an eMMC
will get powered off before suspend if the MMC_CAP_NONREMOVABLE is not set.
That was what I meant about not covering code paths for removable cards.
This code does not cover cards that are not specified as non-removable, so:
if (mmc_card_is_removable(host))
return 0;
> I can't catch the meaning exactly.
> Please let me know.
>
> Thanks.
> Beset regards,
> Seungwon Jeon.
>
>>> + if (card&& mmc_card_mmc(card)&&
>>> + (card->ext_csd.cache_size> 0)) {
>>> + enable = !!enable;
>>> +
>>> + if (card->ext_csd.cache_ctrl ^ enable)
>>> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> + EXT_CSD_CACHE_CTRL, enable, 0);
>>> + if (err)
>>> + pr_err("%s: cache %s error %d\n",
>>> + mmc_hostname(card->host),
>>> + enable ? "on" : "off",
>>> + err);
>>> + else
>>> + card->ext_csd.cache_ctrl = enable;
>>> + }
>>> +
>>> + return err;
>>> +}
>>> +EXPORT_SYMBOL(mmc_cache_ctrl);
>>> +
>>> #ifdef CONFIG_PM
>>>
>>> /**
>>> @@ -2001,6 +2059,9 @@ int mmc_suspend_host(struct mmc_host *host)
>>> cancel_delayed_work(&host->disable);
>>> cancel_delayed_work(&host->detect);
>>> mmc_flush_scheduled_work();
>>> + err = mmc_cache_ctrl(host, 0);
>>> + if (err)
>>> + goto out;
>>>
>>> mmc_bus_get(host);
>>> if (host->bus_ops&& !host->bus_dead) {
>>> @@ -2025,6 +2086,7 @@ int mmc_suspend_host(struct mmc_host *host)
>>> if (!err&& !mmc_card_keep_power(host))
>>> mmc_power_off(host);
>>>
>>> +out:
>>> return err;
>>> }
>>>
>>> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
>>> index ea58a0c..035112b 100644
>>> --- a/drivers/mmc/core/mmc.c
>>> +++ b/drivers/mmc/core/mmc.c
>>> @@ -419,6 +419,12 @@ static int mmc_read_ext_csd(struct mmc_card *card,
>> u8 *ext_csd)
>>> */
>>> card->ext_csd.generic_cmd6_time = 0;
>>>
>>> + card->ext_csd.cache_size =
>>> + ext_csd[EXT_CSD_CACHE_SIZE + 0]<< 0 |
>>> + ext_csd[EXT_CSD_CACHE_SIZE + 1]<< 8 |
>>> + ext_csd[EXT_CSD_CACHE_SIZE + 2]<< 16 |
>>> + ext_csd[EXT_CSD_CACHE_SIZE + 3]<< 24;
>>> +
>>> out:
>>> return err;
>>> }
>>> @@ -851,6 +857,23 @@ static int mmc_init_card(struct mmc_host *host, u32
>> ocr,
>>> }
>>> }
>>>
>>> + /*
>>> + * If cache size is higher than 0, this indicates
>>> + * the the existence of cache and it can be turned on.
>>> + */
>>> + if ((host->caps& MMC_CAP_CACHE_CTRL)&&
>>> + card->ext_csd.cache_size> 0) {
>>> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>>> + EXT_CSD_CACHE_CTRL, 1, 0);
>>> + if (err&& err != -EBADMSG)
>>> + goto free_card;
>>> +
>>> + /*
>>> + * Only if no error, cache is turned on successfully.
>>> + */
>>> + card->ext_csd.cache_ctrl = err ? 0 : 1;
>>> + }
>>> +
>>> if (!oldcard)
>>> host->card = card;
>>>
>>> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
>>> index b713abf..519660b 100644
>>> --- a/include/linux/mmc/card.h
>>> +++ b/include/linux/mmc/card.h
>>> @@ -50,6 +50,7 @@ struct mmc_ext_csd {
>>> u8 rel_sectors;
>>> u8 rel_param;
>>> u8 part_config;
>>> + u8 cache_ctrl;
>>> unsigned int part_time; /* Units: ms */
>>> unsigned int sa_timeout; /* Units: 100ns */
>>> unsigned int generic_cmd6_time; /* Units: 10ms */
>>> @@ -65,6 +66,7 @@ struct mmc_ext_csd {
>>> unsigned long long enhanced_area_offset; /* Units: Byte */
>>> unsigned int enhanced_area_size; /* Units: KB */
>>> unsigned int boot_size; /* in bytes */
>>> + unsigned int cache_size; /* Units: KB */
>>> u8 raw_partition_support; /* 160 */
>>> u8 raw_erased_mem_count; /* 181 */
>>> u8 raw_ext_csd_structure; /* 194 */
>>> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
>>> index b8b1b7a..45b4acf 100644
>>> --- a/include/linux/mmc/core.h
>>> +++ b/include/linux/mmc/core.h
>>> @@ -171,6 +171,8 @@ extern void mmc_release_host(struct mmc_host *host);
>>> extern void mmc_do_release_host(struct mmc_host *host);
>>> extern int mmc_try_claim_host(struct mmc_host *host);
>>>
>>> +extern int mmc_flush_cache(struct mmc_card *);
>>> +
>>> /**
>>> * mmc_claim_host - exclusively claim a host
>>> * @host: mmc host to claim
>>> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
>>> index 4c4bddf..6d0006d 100644
>>> --- a/include/linux/mmc/host.h
>>> +++ b/include/linux/mmc/host.h
>>> @@ -230,6 +230,7 @@ struct mmc_host {
>>> #define MMC_CAP_MAX_CURRENT_600 (1<< 28) /* Host max current
>> limit is 600mA */
>>> #define MMC_CAP_MAX_CURRENT_800 (1<< 29) /* Host max current
>> limit is 800mA */
>>> #define MMC_CAP_CMD23 (1<< 30) /* CMD23 supported. */
>>> +#define MMC_CAP_CACHE_CTRL (1<< 31) /* Allow cache
>> control. */
>>>
>>> mmc_pm_flag_t pm_caps; /* supported pm features */
>>>
>>> @@ -335,6 +336,8 @@ extern int mmc_power_restore_host(struct mmc_host
>> *host);
>>> extern void mmc_detect_change(struct mmc_host *, unsigned long delay);
>>> extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
>>>
>>> +extern int mmc_cache_ctrl(struct mmc_host *, u8);
>>> +
>>> static inline void mmc_signal_sdio_irq(struct mmc_host *host)
>>> {
>>> host->ops->enable_sdio_irq(host, 0);
>>> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
>>> index e869f00..b7fa9f7 100644
>>> --- a/include/linux/mmc/mmc.h
>>> +++ b/include/linux/mmc/mmc.h
>>> @@ -270,6 +270,8 @@ struct _mmc_csd {
>>> * EXT_CSD fields
>>> */
>>>
>>> +#define EXT_CSD_FLUSH_CACHE 32 /* W */
>>> +#define EXT_CSD_CACHE_CTRL 33 /* R/W */
>>> #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
>>> #define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
>>> #define EXT_CSD_WR_REL_PARAM 166 /* RO */
>>> @@ -294,6 +296,7 @@ struct _mmc_csd {
>>> #define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
>>> #define EXT_CSD_TRIM_MULT 232 /* RO */
>>> #define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
>>> +#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
>>>
>>> /*
>>> * EXT_CSD field definitions
>>> --
>>> 1.7.0.4
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
next prev parent reply other threads:[~2011-10-06 7:06 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-08 7:29 [PATCH] mmc: core: Add cache control for eMMC4.5 device Seungwon Jeon
2011-10-05 11:47 ` Adrian Hunter
2011-10-06 4:38 ` Seungwon Jeon
2011-10-06 5:21 ` Andrei E. Warkentin
2011-10-06 8:22 ` Seungwon Jeon
2011-10-06 19:38 ` Andrei E. Warkentin
2011-10-06 7:06 ` Adrian Hunter [this message]
2011-10-06 8:48 ` Seungwon Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E8D535B.40200@intel.com \
--to=adrian.hunter@intel.com \
--cc=cjb@laptop.org \
--cc=dh.han@samsung.com \
--cc=kgene.kim@samsung.com \
--cc=linux-mmc@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=tgih.jun@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.