Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-12-05 Thread Jae hoon Chung
Hi Konstantin.

Thanks for your comment..
I will consider your opinion and send path-v4...then also let me know
more comments :)

Best Regards,
Jaehoon Chung

2011/12/2 Konstantin Dorfman :
> Hello Jaehoon,
> After applying your patch and debugging it for some time,
> I want to share my results and suggests some changes to the patch.
> See comments below:
>
>> +void mmc_start_bkops(struct mmc_card *card)
>> +{
>> +     int err;
>> +     unsigned long flags;
>> +
>> +     BUG_ON(!card);
>> +     if ((!card->ext_csd.bkops_en) ||
>> +                     !(card->host->caps2 & MMC_CAP2_BKOPS))
>> +             return;
>> +
>> +     /*
>> +      * If card is already doing bkops or need for
>> +      * bkops flag is not set, then do nothing just
>> +      * return
>> +      */
>> +     if (mmc_card_doing_bkops(card)
>> +                     || !mmc_card_need_bkops(card))
>> +             return;
>> +
>> +     mmc_claim_host(card->host);
>> +     err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +                     EXT_CSD_BKOPS_START, 1, 0);
>> +     if (err) {
>> +             pr_warning("error %d starting bkops\n", err);
>> +             mmc_card_clr_need_bkops(card);
>> +             goto out;
>> +     }
>> +     spin_lock_irqsave(&card->host->lock, flags);
>> +     mmc_card_clr_need_bkops(card);
>> +     mmc_card_set_doing_bkops(card);
>
> mmc_switch() will use CMD6 with MMC_RSP_R1B flag (see mmc_switch()
> implementation), this flag
> causes mmc controler to wait until busy line (DAT0) released:
>
> from eMMC v4.5 protocol
> 6.12 Responses
> ...
> R1b is identical to R1 with an optional busy signal transmitted on the
> data line DAT0.
> The Device may become busy after receiving these commands based on its
> state prior to the command reception.
> ...
> 7.4.56 BKOPS_START [164]
> Writing any value to this field shall manually start background
> operations. Device shall stay busy till no more
> background operations are needed.
> cut
>
> This means, that mmc_switch() returns only after BKOPS finished by card
> and there is no point
> in setting mmc_card_set_doing_bkops(card). Also, HPI command send to the
> card in order to interrupt BKOPS in mmc_queue_thread()
> will never actually interrupt BKOPS. To resolve this I suggest following:
>
> 1)  Define two variants of mmc_switch(...,wait_flag) for BKOPS, where
>      wait_flag is true sends CMD6 with MMC_RSP_R1b flag as it happens now.
>      wait_flag is false sends CMD6 with MMC_RSP_R1 flag (the only
> difference is MMC_RSP_BUSY bit),
>    so the flow continues immediately after CMD response arrives and will
> not wait for busy line release.
>
> 2) The only situation when we want to use synchronous mmc_switch(...,
> true) is URGENT bit arrives from card, in mmc_blk_issue_rw_rq().
>   There is no point in waiting for idle time check in mmc_queue_thread(),
> host should start synchronous BKOPS immediately.
>
> 3) When in idle (no requests to issue) we can read BKOPS_STATUS[246] from
> card and depending on state decide:
>     0: nothing to do go idle
>     1: start BKOPS with no wait for busy line ( mmc_switch(..., false))
> and mmc_set_doing_bkops()
>     3&2: start synchronous BKOPS
>
> Let me describe this by pseudo-code below:
>
> queue.c:  mmc_queue_thread():
> ...
> req = blk_fetch_request(q)
> if(req == NULL) {
>  state = read_bkops_state(); // read BKOPS_STATUS[246] from card
>  switch(state) {
>    case 0:
>      go_idle()
>      break;
>    case 1:
>      start_asynch_bkops()  // send CMD6 with no wait for busy
>      mmc_set_doing_bkops() // update flag
>      break;
>    case 2:
>    case 3:
>      start_synch_bkops() // start CMD6 with wait for busy
>      break;
>    default:
>      go_idle()
>  }
> } else {
>   if( mmc_doing_bkops() ) {
>     mmc_send_hpi()
>     mmc_clear_doing_bkops()
>   }
>   issue(req)
> }
>
> mmc\card\block.c: mmc_blk_issue_rw_rq()
> ...
>  if ( (mmc_is_exception_event(card,EXT_CSD_URGENT_BKOPS)) {
>        start_synch_bkops() // start CMD6 with wait for busy
>  }
> ...
> ---end of pseudo code-
>
> Does this make sense?
> Thanks, Kostya
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-12-01 Thread Konstantin Dorfman
Hello Jaehoon,
After applying your patch and debugging it for some time,
I want to share my results and suggests some changes to the patch.
See comments below:

> +void mmc_start_bkops(struct mmc_card *card)
> +{
> + int err;
> + unsigned long flags;
> +
> + BUG_ON(!card);
> + if ((!card->ext_csd.bkops_en) ||
> + !(card->host->caps2 & MMC_CAP2_BKOPS))
> + return;
> +
> + /*
> +  * If card is already doing bkops or need for
> +  * bkops flag is not set, then do nothing just
> +  * return
> +  */
> + if (mmc_card_doing_bkops(card)
> + || !mmc_card_need_bkops(card))
> + return;
> +
> + mmc_claim_host(card->host);
> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> + EXT_CSD_BKOPS_START, 1, 0);
> + if (err) {
> + pr_warning("error %d starting bkops\n", err);
> + mmc_card_clr_need_bkops(card);
> + goto out;
> + }
> + spin_lock_irqsave(&card->host->lock, flags);
> + mmc_card_clr_need_bkops(card);
> + mmc_card_set_doing_bkops(card);

mmc_switch() will use CMD6 with MMC_RSP_R1B flag (see mmc_switch()
implementation), this flag
causes mmc controler to wait until busy line (DAT0) released:

from eMMC v4.5 protocol
6.12 Responses
...
R1b is identical to R1 with an optional busy signal transmitted on the
data line DAT0.
The Device may become busy after receiving these commands based on its
state prior to the command reception.
...
7.4.56 BKOPS_START [164]
Writing any value to this field shall manually start background
operations. Device shall stay busy till no more
background operations are needed.
cut

This means, that mmc_switch() returns only after BKOPS finished by card
and there is no point
in setting mmc_card_set_doing_bkops(card). Also, HPI command send to the
card in order to interrupt BKOPS in mmc_queue_thread()
will never actually interrupt BKOPS. To resolve this I suggest following:

1)  Define two variants of mmc_switch(...,wait_flag) for BKOPS, where
  wait_flag is true sends CMD6 with MMC_RSP_R1b flag as it happens now.
  wait_flag is false sends CMD6 with MMC_RSP_R1 flag (the only
difference is MMC_RSP_BUSY bit),
so the flow continues immediately after CMD response arrives and will
not wait for busy line release.

2) The only situation when we want to use synchronous mmc_switch(...,
true) is URGENT bit arrives from card, in mmc_blk_issue_rw_rq().
   There is no point in waiting for idle time check in mmc_queue_thread(),
host should start synchronous BKOPS immediately.

3) When in idle (no requests to issue) we can read BKOPS_STATUS[246] from
card and depending on state decide:
 0: nothing to do go idle
 1: start BKOPS with no wait for busy line ( mmc_switch(..., false))
and mmc_set_doing_bkops()
 3&2: start synchronous BKOPS

Let me describe this by pseudo-code below:

queue.c:  mmc_queue_thread():
...
req = blk_fetch_request(q)
if(req == NULL) {
  state = read_bkops_state(); // read BKOPS_STATUS[246] from card
  switch(state) {
case 0:
  go_idle()
  break;
case 1:
  start_asynch_bkops()  // send CMD6 with no wait for busy
  mmc_set_doing_bkops() // update flag
  break;
case 2:
case 3:
  start_synch_bkops() // start CMD6 with wait for busy
  break;
default:
  go_idle()
  }
} else {
   if( mmc_doing_bkops() ) {
 mmc_send_hpi()
 mmc_clear_doing_bkops()
   }
   issue(req)
}

mmc\card\block.c: mmc_blk_issue_rw_rq()
...
  if ( (mmc_is_exception_event(card,EXT_CSD_URGENT_BKOPS)) {
start_synch_bkops() // start CMD6 with wait for busy
  }
...
---end of pseudo code-

Does this make sense?
Thanks, Kostya



--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-29 Thread Jaehoon Chung
Hi Adrian.

On 11/29/2011 09:20 PM, Adrian Hunter wrote:

> On 17/11/11 02:50, Jaehoon Chung wrote:
>> Enable eMMC background operations (BKOPS) feature.
>>
>> If URGENT_BKOPS is set after a response, note that BKOPS
>> are required. After all I/O requests are finished, run
>> BKOPS if required. Should read/write operations be requested
>> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
>> and then service the request.
>>
>> If you want to enable this feature, set MMC_CAP2_BKOPS.
>>
>> Future considerations
>>  * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
>>  * Interrupt ongoing BKOPS before powering off the card.
>>
>> Signed-off-by: Jaehoon Chung 
>> Signed-off-by: Kyungmin Park 
>> CC: Hanumath Prasad 
>> ---
>> Changelog V3:
>>  - move the bkops setting's location in mmc_blk_issue_rw_rq
>>  - modify condition checking
>>  - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
>>  - remove the unused code
>>  - change pr_debug instead of pr_warn in mmc_send_hpi_cmd
>>  - Add the Future consideration suggested by Per
>>  
>> Changelog V2:
>>  - Use EXCEPTION_STATUS instead of URGENT_BKOPS
>>  - Add function to check Exception_status(for eMMC4.5)
>>  - remove unnecessary code.
>>
> 
> The main problem with bkops is:
> 
>   If the status is at level 3 ("critical"), some operations
>   may extend beyond their original timeouts due to maintenance
>   operations which cannot be delayed anymore.
> 
> This means:
> 
>   1. at level 3 either bkops are run or the timeout of the next
>   (data?) operation is extended
> 
>   2. at level 3 either the bkops must not be interrupted or the
>   level must be rechecked after interruption and bkops run again
>   if the level is still 3


Thanks for your comment..I will consider to solve this problem.

Best Regards,
Jaehoon Chung

> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-29 Thread Adrian Hunter
On 17/11/11 02:50, Jaehoon Chung wrote:
> Enable eMMC background operations (BKOPS) feature.
> 
> If URGENT_BKOPS is set after a response, note that BKOPS
> are required. After all I/O requests are finished, run
> BKOPS if required. Should read/write operations be requested
> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
> and then service the request.
> 
> If you want to enable this feature, set MMC_CAP2_BKOPS.
> 
> Future considerations
>  * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
>  * Interrupt ongoing BKOPS before powering off the card.
> 
> Signed-off-by: Jaehoon Chung 
> Signed-off-by: Kyungmin Park 
> CC: Hanumath Prasad 
> ---
> Changelog V3:
>   - move the bkops setting's location in mmc_blk_issue_rw_rq
>   - modify condition checking
>   - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
>   - remove the unused code
>   - change pr_debug instead of pr_warn in mmc_send_hpi_cmd
>   - Add the Future consideration suggested by Per
>   
> Changelog V2:
>   - Use EXCEPTION_STATUS instead of URGENT_BKOPS
>   - Add function to check Exception_status(for eMMC4.5)
>   - remove unnecessary code.
> 

The main problem with bkops is:

If the status is at level 3 ("critical"), some operations
may extend beyond their original timeouts due to maintenance
operations which cannot be delayed anymore.

This means:

1. at level 3 either bkops are run or the timeout of the next
(data?) operation is extended

2. at level 3 either the bkops must not be interrupted or the
level must be rechecked after interruption and bkops run again
if the level is still 3
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-28 Thread Konstantin Dorfman
Hi Jaehoon,

>
> i didn't know how poll for ack from card..did you know?
> So i implemented that send the hpi command whatever status.
>
> If let me know checking for ack from card, i will consider that.

Some of MMC controllers (in my case msm_sdcc) can process automatically
"busy line" and fire interrupt with "prog done" bit asserted, so we can
use handler of this irq to turn off "doing bkops" flag. Otherwise it is
possible to read mmc controller status and check busy line, in case it is
already released we can skip HPI command.

Thanks,
Kostya

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-22 Thread Jaehoon Chung
Hi Konstantin

On 11/22/2011 09:44 PM, Konstantin Dorfman wrote:

> Hello Jaehoon,
> 
> ...
>> +/**
>> + *  mmc_start_bkops - start BKOPS for supported cards
>> + *  @card: MMC card to start BKOPS
>> + *
>> + *  Start background operations whenever requested.
>> + *  when the urgent BKOPS bit is set in a R1 command response
>> + *  then background operations should be started immediately.
>> +*/
>> +void mmc_start_bkops(struct mmc_card *card)
>> +{
>> +int err;
>> +unsigned long flags;
>> +
>> +BUG_ON(!card);
>> +if ((!card->ext_csd.bkops_en) ||
>> +!(card->host->caps2 & MMC_CAP2_BKOPS))
>> +return;
>> +
>> +/*
>> + * If card is already doing bkops or need for
>> + * bkops flag is not set, then do nothing just
>> + * return
>> + */
>> +if (mmc_card_doing_bkops(card)
>> +|| !mmc_card_need_bkops(card))
>> +return;
>> +
>> +mmc_claim_host(card->host);
>> +err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +EXT_CSD_BKOPS_START, 1, 0);
>> +if (err) {
>> +pr_warning("error %d starting bkops\n", err);
>> +mmc_card_clr_need_bkops(card);
>> +goto out;
>> +}
>> +spin_lock_irqsave(&card->host->lock, flags);
>> +mmc_card_clr_need_bkops(card);
>> +mmc_card_set_doing_bkops(card);
> Sending CMD6 (by mmc_switch()) will start BKOPS on card,
> according to eMMC spec:
> -
> 7.4.56 BKOPS_START [164]
> Writing any value to this field shall manually start background operations.
> Device shall stay busy till no more background operations are needed.
> -
> Where/when mmc_card_clear_doing_bkops() should called? The only place I
> see this happens is
> in mmc_interrupt_bkops(). This means, that once BKOPS started, next
> read/write request
> will _always_(and not when card really busy) send HPI and only then will
> clear "doing" flag.


Right, that is called only in mmc_interrupt_bkops. I wonder how did you check
to finish the bkops without hpi command?

> May be it is possible to poll for ack from card about when BKOPS finished?
> Another possibility that
> mmc_switch() synchronous and after flow returns from it, we can clear
> "doing" flag immediately.
> Does it make sense?

i didn't know how poll for ack from card..did you know?
So i implemented that send the hpi command whatever status.

If let me know checking for ack from card, i will consider that.

Thanks

Best Regards,
Jaehoon Chung
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-22 Thread Konstantin Dorfman
> Hello Jaehoon,
>
> ...
>> +/**
>> + *  mmc_start_bkops - start BKOPS for supported cards
>> + *  @card: MMC card to start BKOPS
>> + *
>> + *  Start background operations whenever requested.
>> + *  when the urgent BKOPS bit is set in a R1 command response
>> + *  then background operations should be started immediately.
>> +*/
>> +void mmc_start_bkops(struct mmc_card *card)
>> +{
>> +int err;
>> +unsigned long flags;
>> +
>> +BUG_ON(!card);
>> +if ((!card->ext_csd.bkops_en) ||
>> +!(card->host->caps2 & MMC_CAP2_BKOPS))
>> +return;
>> +
>> +/*
>> + * If card is already doing bkops or need for
>> + * bkops flag is not set, then do nothing just
>> + * return
>> + */
>> +if (mmc_card_doing_bkops(card)
>> +|| !mmc_card_need_bkops(card))
>> +return;
>> +
>> +mmc_claim_host(card->host);
>> +err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>> +EXT_CSD_BKOPS_START, 1, 0);
>> +if (err) {
>> +pr_warning("error %d starting bkops\n", err);
>> +mmc_card_clr_need_bkops(card);
>> +goto out;
>> +}
>> +spin_lock_irqsave(&card->host->lock, flags);
>> +mmc_card_clr_need_bkops(card);
>> +mmc_card_set_doing_bkops(card);
> Sending CMD6 (by mmc_switch()) will start BKOPS on card,
> according to eMMC spec:
> -
> 7.4.56 BKOPS_START [164]
> Writing any value to this field shall manually start background
> operations.
> Device shall stay busy till no more background operations are needed.
> -
> Where/when mmc_card_clear_doing_bkops() should called? The only place I
> see this happens is
> in mmc_interrupt_bkops(). This means, that once BKOPS started, next
> read/write request
> will _always_(and not when card really busy) send HPI and only then will
> clear "doing" flag.
>
> May be it is possible to poll for ack from card about when BKOPS finished?
> Another possibility that
> mmc_switch() synchronous and after flow returns from it, we can clear
> "doing" flag immediately.
> Does it make sense?
> ...

Now I understand that mmc_switch() command was modified for BKOPS_START to
be non-blocking, so the flow never waits for BKOPS to be finished. Because
of this HPI is always sent before next request.
Since start bkops flow is not frequent, it is ok.
Thanks,
Kostya

>> +spin_unlock_irqrestore(&card->host->lock, flags);
>> +out:
>> +mmc_release_host(card->host);
>> +}
>> +EXPORT_SYMBOL(mmc_start_bkops);
>> +
>
> Thanks,
> Kostya
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-22 Thread Konstantin Dorfman
Hello Jaehoon,

...
> +/**
> + *   mmc_start_bkops - start BKOPS for supported cards
> + *   @card: MMC card to start BKOPS
> + *
> + *   Start background operations whenever requested.
> + *   when the urgent BKOPS bit is set in a R1 command response
> + *   then background operations should be started immediately.
> +*/
> +void mmc_start_bkops(struct mmc_card *card)
> +{
> + int err;
> + unsigned long flags;
> +
> + BUG_ON(!card);
> + if ((!card->ext_csd.bkops_en) ||
> + !(card->host->caps2 & MMC_CAP2_BKOPS))
> + return;
> +
> + /*
> +  * If card is already doing bkops or need for
> +  * bkops flag is not set, then do nothing just
> +  * return
> +  */
> + if (mmc_card_doing_bkops(card)
> + || !mmc_card_need_bkops(card))
> + return;
> +
> + mmc_claim_host(card->host);
> + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> + EXT_CSD_BKOPS_START, 1, 0);
> + if (err) {
> + pr_warning("error %d starting bkops\n", err);
> + mmc_card_clr_need_bkops(card);
> + goto out;
> + }
> + spin_lock_irqsave(&card->host->lock, flags);
> + mmc_card_clr_need_bkops(card);
> + mmc_card_set_doing_bkops(card);
Sending CMD6 (by mmc_switch()) will start BKOPS on card,
according to eMMC spec:
-
7.4.56 BKOPS_START [164]
Writing any value to this field shall manually start background operations.
Device shall stay busy till no more background operations are needed.
-
Where/when mmc_card_clear_doing_bkops() should called? The only place I
see this happens is
in mmc_interrupt_bkops(). This means, that once BKOPS started, next
read/write request
will _always_(and not when card really busy) send HPI and only then will
clear "doing" flag.

May be it is possible to poll for ack from card about when BKOPS finished?
Another possibility that
mmc_switch() synchronous and after flow returns from it, we can clear
"doing" flag immediately.
Does it make sense?
...
> + spin_unlock_irqrestore(&card->host->lock, flags);
> +out:
> + mmc_release_host(card->host);
> +}
> +EXPORT_SYMBOL(mmc_start_bkops);
> +

Thanks,
Kostya

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-20 Thread Per Forlin
Hi Konstantin,

On Sun, Nov 20, 2011 at 5:12 PM, Konstantin Dorfman
 wrote:
> Hello Per,
>
>> On Thu, Nov 17, 2011 at 4:01 PM, Konstantin Dorfman
>>  wrote:
>>> Hello Jaenhoon,
>>>
>>> I have a few suggestions regarding the situation when Host starts BKOPS:
>>>
>>> 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event)
>>> when going to mmc_sleep, which means that the bus is in idle state (this
>>> also covers the case in mmc_queue_thread, because in this case no I/O
>>> request exists). It seems like checking the status periodically in
>>> addition
>>> to mmc_suspend is not needed. Since if the device was in idle and we
>>> performed a single BKOPS then there is no point in performing another
>>> BKOPS
>>> unless there was actually another I/O request.
>>>
>>> 2) Also this implies an answer to the question about need to interrupt
>>> BKOPS
>>> before powering off card - the answer is no.
>> By the answer no you mean there is no risk of data corruption if
>> cutting power in the middle of a BKOPS. When the card is powered up
>> next time it will verify that bkops is in a defined state, and do
>> recovery if necessary. An interesting comment I got from Sebastian is
>> if this recovery mechanism affects card boot time.
>> The question is: May the card boot up slower (due to recovery) next
>> time if BKOPS was ongoing at power off?
>> I assume this recovery time should be insignificant, but I don't know for
>> sure.
>>
> Let me explain proposed flow:
> The only trigger to start BKOPS command should be mmc_power_off() function,
> just before sending POWER_OFF_NOTIFICATION[34] and only when BKOPS is needed
> (by needed I understand situation, when URGENT_BKOPS event arrived or
> BKOPS_STATUS 0x2 or 0x3).
> The flow will wait till BKOPS successfully completed and than continue to
> powering off the card. Power off will never occur in the middle of BKOPS.
> Also do not need to start BKOPS when mmc_queue_thread() is in IDLE state
> (no requests exists), because in such case power off should be done to card.
>
I wonder how this works with suspend.
If suspend is called on the system, MMC should suspend quickly and not
wait for the BKOPS to finish.
For pm_runtime_suspend it's fine to return -EBUSY and defer
pm_runtime_suspend until BKOPS is completed.
mmc_power_on/off is too low level I think. What about adding this at
the suspend/resume level instead?

>>> 3) Based on statistical data we have (day long test) it looks like we do
>>> not
>>> need to do any preventive BKOPS caused by BKOPS_STATUS less than
>>> critical
>>> (0x3).
>> I proposed this "preventive action" but at that time I didn't have any
>> data to back it up with. I've run some day long tests and what I could
>> see is when BKOPS_LEVEL goes from 0 to 1, it goes back to 0 without
>> having to start BKOPS. Can you confirm this with your tests as well?
>> One explanation I got for this is that level of 1 only means the eMMC
>> internal cache is fragmented and not the actual memory.
> We have such data from card vendors, but I plan to do similar tests to
> confirm.
> I will update about the results.
Looking forward to see your results.

Thanks,
Per
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-20 Thread Konstantin Dorfman
Hello Per,

> On Thu, Nov 17, 2011 at 4:01 PM, Konstantin Dorfman
>  wrote:
>> Hello Jaenhoon,
>>
>> I have a few suggestions regarding the situation when Host starts BKOPS:
>>
>> 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event)
>> when going to mmc_sleep, which means that the bus is in idle state (this
>> also covers the case in mmc_queue_thread, because in this case no I/O
>> request exists). It seems like checking the status periodically in
>> addition
>> to mmc_suspend is not needed. Since if the device was in idle and we
>> performed a single BKOPS then there is no point in performing another
>> BKOPS
>> unless there was actually another I/O request.
>>
>> 2) Also this implies an answer to the question about need to interrupt
>> BKOPS
>> before powering off card - the answer is no.
> By the answer no you mean there is no risk of data corruption if
> cutting power in the middle of a BKOPS. When the card is powered up
> next time it will verify that bkops is in a defined state, and do
> recovery if necessary. An interesting comment I got from Sebastian is
> if this recovery mechanism affects card boot time.
> The question is: May the card boot up slower (due to recovery) next
> time if BKOPS was ongoing at power off?
> I assume this recovery time should be insignificant, but I don't know for
> sure.
>
Let me explain proposed flow:
The only trigger to start BKOPS command should be mmc_power_off() function,
just before sending POWER_OFF_NOTIFICATION[34] and only when BKOPS is needed
(by needed I understand situation, when URGENT_BKOPS event arrived or
BKOPS_STATUS 0x2 or 0x3).
The flow will wait till BKOPS successfully completed and than continue to
powering off the card. Power off will never occur in the middle of BKOPS.
Also do not need to start BKOPS when mmc_queue_thread() is in IDLE state
(no requests exists), because in such case power off should be done to card.

>> 3) Based on statistical data we have (day long test) it looks like we do
>> not
>> need to do any preventive BKOPS caused by BKOPS_STATUS less than
>> critical
>> (0x3).
> I proposed this "preventive action" but at that time I didn't have any
> data to back it up with. I've run some day long tests and what I could
> see is when BKOPS_LEVEL goes from 0 to 1, it goes back to 0 without
> having to start BKOPS. Can you confirm this with your tests as well?
> One explanation I got for this is that level of 1 only means the eMMC
> internal cache is fragmented and not the actual memory.
We have such data from card vendors, but I plan to do similar tests to
confirm.
I will update about the results.

Thanks,
Kostya

>
> Thanks,
> Per
>
>> -Original Message-
>> From: linux-mmc-ow...@vger.kernel.org
>> [mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Jaehoon Chung
>> Sent: Thursday, November 17, 2011 2:50 AM
>> To: linux-mmc
>> Cc: Chris Ball; Kyungmin Park; Hanumath Prasad; Per Forlin; Sebastian
>> Rasmussen; Dong, Chuanxiao; svenk...@ti.com
>> Subject: [PATCH v3] mmc: support BKOPS feature for eMMC
>>
>> Enable eMMC background operations (BKOPS) feature.
>>
>> If URGENT_BKOPS is set after a response, note that BKOPS
>> are required. After all I/O requests are finished, run
>> BKOPS if required. Should read/write operations be requested
>> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
>> and then service the request.
>>
>> If you want to enable this feature, set MMC_CAP2_BKOPS.
>>
>> Future considerations
>>  * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
>>  * Interrupt ongoing BKOPS before powering off the card.
>>
>> Signed-off-by: Jaehoon Chung 
>> Signed-off-by: Kyungmin Park 
>> CC: Hanumath Prasad 
>> ---
>> Changelog V3:
>>        - move the bkops setting's location in mmc_blk_issue_rw_rq
>>        - modify condition checking
>>        - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
>>        - remove the unused code
>>        - change pr_debug instead of pr_warn in mmc_send_hpi_cmd
>>        - Add the Future consideration suggested by Per
>>
>> Changelog V2:
>>        - Use EXCEPTION_STATUS instead of URGENT_BKOPS
>>        - Add function to check Exception_status(for eMMC4.5)
>>        - remove unnecessary code.
>>
>>  drivers/mmc/card/block.c   |   10 +
>>  drivers/mmc/card/queue.c   |    4 ++
>>  drivers/mmc/core/core.c    |   87
>> 
>>  drivers/mmc/core/mmc.c     |    8 
>>  drivers/mmc/cor

Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-17 Thread Per Forlin
On Thu, Nov 17, 2011 at 4:01 PM, Konstantin Dorfman
 wrote:
> Hello Jaenhoon,
>
> I have a few suggestions regarding the situation when Host starts BKOPS:
>
> 1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event)
> when going to mmc_sleep, which means that the bus is in idle state (this
> also covers the case in mmc_queue_thread, because in this case no I/O
> request exists). It seems like checking the status periodically in addition
> to mmc_suspend is not needed. Since if the device was in idle and we
> performed a single BKOPS then there is no point in performing another BKOPS
> unless there was actually another I/O request.
>
> 2) Also this implies an answer to the question about need to interrupt BKOPS
> before powering off card - the answer is no.
By the answer no you mean there is no risk of data corruption if
cutting power in the middle of a BKOPS. When the card is powered up
next time it will verify that bkops is in a defined state, and do
recovery if necessary. An interesting comment I got from Sebastian is
if this recovery mechanism affects card boot time.
The question is: May the card boot up slower (due to recovery) next
time if BKOPS was ongoing at power off?
I assume this recovery time should be insignificant, but I don't know for sure.

> 3) Based on statistical data we have (day long test) it looks like we do not
> need to do any preventive BKOPS caused by BKOPS_STATUS less than critical
> (0x3).
I proposed this "preventive action" but at that time I didn't have any
data to back it up with. I've run some day long tests and what I could
see is when BKOPS_LEVEL goes from 0 to 1, it goes back to 0 without
having to start BKOPS. Can you confirm this with your tests as well?
One explanation I got for this is that level of 1 only means the eMMC
internal cache is fragmented and not the actual memory.

Thanks,
Per

> -Original Message-
> From: linux-mmc-ow...@vger.kernel.org
> [mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Jaehoon Chung
> Sent: Thursday, November 17, 2011 2:50 AM
> To: linux-mmc
> Cc: Chris Ball; Kyungmin Park; Hanumath Prasad; Per Forlin; Sebastian
> Rasmussen; Dong, Chuanxiao; svenk...@ti.com
> Subject: [PATCH v3] mmc: support BKOPS feature for eMMC
>
> Enable eMMC background operations (BKOPS) feature.
>
> If URGENT_BKOPS is set after a response, note that BKOPS
> are required. After all I/O requests are finished, run
> BKOPS if required. Should read/write operations be requested
> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
> and then service the request.
>
> If you want to enable this feature, set MMC_CAP2_BKOPS.
>
> Future considerations
>  * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
>  * Interrupt ongoing BKOPS before powering off the card.
>
> Signed-off-by: Jaehoon Chung 
> Signed-off-by: Kyungmin Park 
> CC: Hanumath Prasad 
> ---
> Changelog V3:
>        - move the bkops setting's location in mmc_blk_issue_rw_rq
>        - modify condition checking
>        - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
>        - remove the unused code
>        - change pr_debug instead of pr_warn in mmc_send_hpi_cmd
>        - Add the Future consideration suggested by Per
>
> Changelog V2:
>        - Use EXCEPTION_STATUS instead of URGENT_BKOPS
>        - Add function to check Exception_status(for eMMC4.5)
>        - remove unnecessary code.
>
>  drivers/mmc/card/block.c   |   10 +
>  drivers/mmc/card/queue.c   |    4 ++
>  drivers/mmc/core/core.c    |   87
> 
>  drivers/mmc/core/mmc.c     |    8 
>  drivers/mmc/core/mmc_ops.c |    6 +++-
>  include/linux/mmc/card.h   |   12 ++
>  include/linux/mmc/core.h   |    3 ++
>  include/linux/mmc/host.h   |    1 +
>  include/linux/mmc/mmc.h    |   14 +++
>  9 files changed, 144 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index c80bb6d..9d19ebb 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq,
> struct request *rqc)
>                type = rq_data_dir(req) == READ ? MMC_BLK_READ :
> MMC_BLK_WRITE;
>                mmc_queue_bounce_post(mq_rq);
>
> +               /*
> +                * Check BKOPS urgency from each R1 response
> +                */
> +               if (mmc_card_mmc(card) &&
> +                       (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) {
> +                       if (mmc_is_exception_event(card,
> +                                       EXT_CSD_URGENT_BKOPS))
> +                               mmc_card_set_nee

RE: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-17 Thread Konstantin Dorfman
Hello Jaenhoon,

I have a few suggestions regarding the situation when Host starts BKOPS:

1) Host should start BKOPS (based on BKOPS_STATUS or URGENT_BKOPS event)
when going to mmc_sleep, which means that the bus is in idle state (this
also covers the case in mmc_queue_thread, because in this case no I/O
request exists). It seems like checking the status periodically in addition
to mmc_suspend is not needed. Since if the device was in idle and we
performed a single BKOPS then there is no point in performing another BKOPS
unless there was actually another I/O request.

2) Also this implies an answer to the question about need to interrupt BKOPS
before powering off card - the answer is no.

3) Based on statistical data we have (day long test) it looks like we do not
need to do any preventive BKOPS caused by BKOPS_STATUS less than critical
(0x3).

Thanks,
Konstantin Dorfman
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

-Original Message-
From: linux-mmc-ow...@vger.kernel.org
[mailto:linux-mmc-ow...@vger.kernel.org] On Behalf Of Jaehoon Chung
Sent: Thursday, November 17, 2011 2:50 AM
To: linux-mmc
Cc: Chris Ball; Kyungmin Park; Hanumath Prasad; Per Forlin; Sebastian
Rasmussen; Dong, Chuanxiao; svenk...@ti.com
Subject: [PATCH v3] mmc: support BKOPS feature for eMMC

Enable eMMC background operations (BKOPS) feature.

If URGENT_BKOPS is set after a response, note that BKOPS
are required. After all I/O requests are finished, run
BKOPS if required. Should read/write operations be requested
during BKOPS, first issue HPI to interrupt the ongoing BKOPS
and then service the request.

If you want to enable this feature, set MMC_CAP2_BKOPS.

Future considerations
 * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
 * Interrupt ongoing BKOPS before powering off the card.

Signed-off-by: Jaehoon Chung 
Signed-off-by: Kyungmin Park 
CC: Hanumath Prasad 
---
Changelog V3:
- move the bkops setting's location in mmc_blk_issue_rw_rq
- modify condition checking
- bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
- remove the unused code
- change pr_debug instead of pr_warn in mmc_send_hpi_cmd
- Add the Future consideration suggested by Per

Changelog V2:
- Use EXCEPTION_STATUS instead of URGENT_BKOPS
- Add function to check Exception_status(for eMMC4.5)
- remove unnecessary code.

 drivers/mmc/card/block.c   |   10 +
 drivers/mmc/card/queue.c   |4 ++
 drivers/mmc/core/core.c|   87

 drivers/mmc/core/mmc.c |8 
 drivers/mmc/core/mmc_ops.c |6 +++-
 include/linux/mmc/card.h   |   12 ++
 include/linux/mmc/core.h   |3 ++
 include/linux/mmc/host.h   |1 +
 include/linux/mmc/mmc.h|   14 +++
 9 files changed, 144 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c80bb6d..9d19ebb 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq,
struct request *rqc)
type = rq_data_dir(req) == READ ? MMC_BLK_READ :
MMC_BLK_WRITE;
mmc_queue_bounce_post(mq_rq);
 
+   /*
+* Check BKOPS urgency from each R1 response
+*/
+   if (mmc_card_mmc(card) &&
+   (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) {
+   if (mmc_is_exception_event(card,
+   EXT_CSD_URGENT_BKOPS))
+   mmc_card_set_need_bkops(card);
+   }
+
switch (status) {
case MMC_BLK_SUCCESS:
case MMC_BLK_PARTIAL:
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59c..20bb4a5 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -61,6 +61,9 @@ static int mmc_queue_thread(void *d)
spin_unlock_irq(q->queue_lock);
 
if (req || mq->mqrq_prev->req) {
+   if (mmc_card_doing_bkops(mq->card))
+   mmc_interrupt_bkops(mq->card);
+
set_current_state(TASK_RUNNING);
mq->issue_fn(mq, req);
} else {
@@ -68,6 +71,7 @@ static int mmc_queue_thread(void *d)
set_current_state(TASK_RUNNING);
break;
}
+   mmc_start_bkops(mq->card);
up(&mq->thread_sem);
schedule();
down(&mq->thread_sem);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7ee2e07..2d2f1d5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -238,6 +238,50 @@ mmc_start_request(struct mmc_host *ho

Re: [PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-17 Thread S, Venkatraman
On Thu, Nov 17, 2011 at 6:20 AM, Jaehoon Chung  wrote:
> Enable eMMC background operations (BKOPS) feature.
>
> If URGENT_BKOPS is set after a response, note that BKOPS
> are required. After all I/O requests are finished, run
> BKOPS if required. Should read/write operations be requested
> during BKOPS, first issue HPI to interrupt the ongoing BKOPS
> and then service the request.
>
> If you want to enable this feature, set MMC_CAP2_BKOPS.
>
> Future considerations
>  * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
>  * Interrupt ongoing BKOPS before powering off the card.
>
> Signed-off-by: Jaehoon Chung 
> Signed-off-by: Kyungmin Park 
> CC: Hanumath Prasad 
> ---
> Changelog V3:
>        - move the bkops setting's location in mmc_blk_issue_rw_rq
>        - modify condition checking
>        - bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
>        - remove the unused code
>        - change pr_debug instead of pr_warn in mmc_send_hpi_cmd
>        - Add the Future consideration suggested by Per
>
> Changelog V2:
>        - Use EXCEPTION_STATUS instead of URGENT_BKOPS
>        - Add function to check Exception_status(for eMMC4.5)
>        - remove unnecessary code.
>
>  drivers/mmc/card/block.c   |   10 +
>  drivers/mmc/card/queue.c   |    4 ++
>  drivers/mmc/core/core.c    |   87 
> 
>  drivers/mmc/core/mmc.c     |    8 
>  drivers/mmc/core/mmc_ops.c |    6 +++-
>  include/linux/mmc/card.h   |   12 ++
>  include/linux/mmc/core.h   |    3 ++
>  include/linux/mmc/host.h   |    1 +
>  include/linux/mmc/mmc.h    |   14 +++
>  9 files changed, 144 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index c80bb6d..9d19ebb 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
> struct request *rqc)
>                type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
>                mmc_queue_bounce_post(mq_rq);
>
> +               /*
> +                * Check BKOPS urgency from each R1 response
> +                */
> +               if (mmc_card_mmc(card) &&
> +                       (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) {
> +                       if (mmc_is_exception_event(card,
> +                                       EXT_CSD_URGENT_BKOPS))
> +                               mmc_card_set_need_bkops(card);
> +               }
> +
>                switch (status) {
>                case MMC_BLK_SUCCESS:
>                case MMC_BLK_PARTIAL:
> diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
> index dcad59c..20bb4a5 100644
> --- a/drivers/mmc/card/queue.c
> +++ b/drivers/mmc/card/queue.c
> @@ -61,6 +61,9 @@ static int mmc_queue_thread(void *d)
>                spin_unlock_irq(q->queue_lock);
>
>                if (req || mq->mqrq_prev->req) {
> +                       if (mmc_card_doing_bkops(mq->card))
> +                               mmc_interrupt_bkops(mq->card);

Should you interrupt bkops for any request or just for read /write requests ?

> +
>                        set_current_state(TASK_RUNNING);
>                        mq->issue_fn(mq, req);
>                } else {
> @@ -68,6 +71,7 @@ static int mmc_queue_thread(void *d)
>                                set_current_state(TASK_RUNNING);
>                                break;
>                        }
> +                       mmc_start_bkops(mq->card);
>                        up(&mq->thread_sem);
>                        schedule();
>                        down(&mq->thread_sem);
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 7ee2e07..2d2f1d5 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -238,6 +238,50 @@ mmc_start_request(struct mmc_host *host, struct 
> mmc_request *mrq)
>        host->ops->request(host, mrq);
>  }
>
> +/**
> + *     mmc_start_bkops - start BKOPS for supported cards
> + *     @card: MMC card to start BKOPS
> + *
> + *     Start background operations whenever requested.
> + *     when the urgent BKOPS bit is set in a R1 command response
> + *     then background operations should be started immediately.
> +*/
> +void mmc_start_bkops(struct mmc_card *card)
> +{
> +       int err;
> +       unsigned long flags;
> +
> +       BUG_ON(!card);
> +       if ((!card->ext_csd.bkops_en) ||
> +                       !(card->host->caps2 & MMC_CAP2_BKOPS))
> +               return;
> +
> +       /*
> +        * If card is already doing bkops or need for
> +        * bkops flag is not set, then do nothing just
> +        * return
> +        */
> +       if (mmc_card_doing_bkops(card)
> +                       || !mmc_card_need_bkops(card))
> +               return;
> +
> +       mmc_claim_host(card->host);
> +       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
> +                       EXT_CSD_BKOPS_START, 1, 0);
> +   

[PATCH v3] mmc: support BKOPS feature for eMMC

2011-11-16 Thread Jaehoon Chung
Enable eMMC background operations (BKOPS) feature.

If URGENT_BKOPS is set after a response, note that BKOPS
are required. After all I/O requests are finished, run
BKOPS if required. Should read/write operations be requested
during BKOPS, first issue HPI to interrupt the ongoing BKOPS
and then service the request.

If you want to enable this feature, set MMC_CAP2_BKOPS.

Future considerations
 * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner.
 * Interrupt ongoing BKOPS before powering off the card.

Signed-off-by: Jaehoon Chung 
Signed-off-by: Kyungmin Park 
CC: Hanumath Prasad 
---
Changelog V3:
- move the bkops setting's location in mmc_blk_issue_rw_rq
- modify condition checking
- bkops_en is assigned ext_csd[EXT_CSD_BKOPS_EN] instead of "1"
- remove the unused code
- change pr_debug instead of pr_warn in mmc_send_hpi_cmd
- Add the Future consideration suggested by Per

Changelog V2:
- Use EXCEPTION_STATUS instead of URGENT_BKOPS
- Add function to check Exception_status(for eMMC4.5)
- remove unnecessary code.

 drivers/mmc/card/block.c   |   10 +
 drivers/mmc/card/queue.c   |4 ++
 drivers/mmc/core/core.c|   87 
 drivers/mmc/core/mmc.c |8 
 drivers/mmc/core/mmc_ops.c |6 +++-
 include/linux/mmc/card.h   |   12 ++
 include/linux/mmc/core.h   |3 ++
 include/linux/mmc/host.h   |1 +
 include/linux/mmc/mmc.h|   14 +++
 9 files changed, 144 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index c80bb6d..9d19ebb 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1188,6 +1188,16 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, 
struct request *rqc)
type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
mmc_queue_bounce_post(mq_rq);
 
+   /*
+* Check BKOPS urgency from each R1 response
+*/
+   if (mmc_card_mmc(card) &&
+   (brq->cmd.resp[0] & R1_EXCEPTION_EVENT)) {
+   if (mmc_is_exception_event(card,
+   EXT_CSD_URGENT_BKOPS))
+   mmc_card_set_need_bkops(card);
+   }
+
switch (status) {
case MMC_BLK_SUCCESS:
case MMC_BLK_PARTIAL:
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59c..20bb4a5 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -61,6 +61,9 @@ static int mmc_queue_thread(void *d)
spin_unlock_irq(q->queue_lock);
 
if (req || mq->mqrq_prev->req) {
+   if (mmc_card_doing_bkops(mq->card))
+   mmc_interrupt_bkops(mq->card);
+
set_current_state(TASK_RUNNING);
mq->issue_fn(mq, req);
} else {
@@ -68,6 +71,7 @@ static int mmc_queue_thread(void *d)
set_current_state(TASK_RUNNING);
break;
}
+   mmc_start_bkops(mq->card);
up(&mq->thread_sem);
schedule();
down(&mq->thread_sem);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7ee2e07..2d2f1d5 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -238,6 +238,50 @@ mmc_start_request(struct mmc_host *host, struct 
mmc_request *mrq)
host->ops->request(host, mrq);
 }
 
+/**
+ * mmc_start_bkops - start BKOPS for supported cards
+ * @card: MMC card to start BKOPS
+ *
+ * Start background operations whenever requested.
+ * when the urgent BKOPS bit is set in a R1 command response
+ * then background operations should be started immediately.
+*/
+void mmc_start_bkops(struct mmc_card *card)
+{
+   int err;
+   unsigned long flags;
+
+   BUG_ON(!card);
+   if ((!card->ext_csd.bkops_en) ||
+   !(card->host->caps2 & MMC_CAP2_BKOPS))
+   return;
+
+   /*
+* If card is already doing bkops or need for
+* bkops flag is not set, then do nothing just
+* return
+*/
+   if (mmc_card_doing_bkops(card)
+   || !mmc_card_need_bkops(card))
+   return;
+
+   mmc_claim_host(card->host);
+   err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+   EXT_CSD_BKOPS_START, 1, 0);
+   if (err) {
+   pr_warning("error %d starting bkops\n", err);
+   mmc_card_clr_need_bkops(card);
+   goto out;
+   }
+   spin_lock_irqsave(&card->host->lock, flags);
+   mmc_card_clr_need_bkops(card);
+   mmc_card_set_doing_bkops(card);
+   spin_unlock_irqrestore(&card->host->lock, f