aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaehoon Chung <jh80.chung@samsung.com>2012-09-17 04:42:02 -0400
committerChris Ball <cjb@laptop.org>2012-10-03 10:05:12 -0400
commit950d56acce5d401f477b91d0177605b543d63d07 (patch)
tree205505f3976d02c6ef2fa9d6c911407f0e0f6c80
parentbec9d4e5939987053169a9bb48fc58b6a2d3e237 (diff)
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. Immediately run BKOPS if required. Read/write operations should be requested during BKOPS(LEVEL-1), then issue HPI to interrupt the ongoing BKOPS and service the foreground operation. (This patch only controls the LEVEL2/3.) When repeating the writing 1GB data, at a certain time, performance is decreased. At that time, card triggers the Level-3 or Level-2. After running bkops, performance is recovered. Future considerations: * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. * Interrupt ongoing BKOPS before powering off the card. * How do we get BKOPS_STATUS value (periodically send ext_csd command)? * If using periodic bkops, also consider runtime_pm control. Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Konstantin Dorfman <kdorfman@codeaurora.org> Reviewed-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/core/core.c160
-rw-r--r--drivers/mmc/core/mmc.c11
-rw-r--r--drivers/mmc/core/mmc_ops.c26
-rw-r--r--include/linux/mmc/card.h8
-rw-r--r--include/linux/mmc/core.h4
-rw-r--r--include/linux/mmc/mmc.h19
6 files changed, 220 insertions, 8 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index af2c4d2fd69e..044cd016320e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -26,6 +26,7 @@
26#include <linux/suspend.h> 26#include <linux/suspend.h>
27#include <linux/fault-inject.h> 27#include <linux/fault-inject.h>
28#include <linux/random.h> 28#include <linux/random.h>
29#include <linux/slab.h>
29 30
30#include <linux/mmc/card.h> 31#include <linux/mmc/card.h>
31#include <linux/mmc/host.h> 32#include <linux/mmc/host.h>
@@ -41,6 +42,12 @@
41#include "sd_ops.h" 42#include "sd_ops.h"
42#include "sdio_ops.h" 43#include "sdio_ops.h"
43 44
45/*
46 * Background operations can take a long time, depending on the housekeeping
47 * operations the card has to perform.
48 */
49#define MMC_BKOPS_MAX_TIMEOUT (4 * 60 * 1000) /* max time to wait in ms */
50
44static struct workqueue_struct *workqueue; 51static struct workqueue_struct *workqueue;
45static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; 52static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
46 53
@@ -245,6 +252,70 @@ mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
245 host->ops->request(host, mrq); 252 host->ops->request(host, mrq);
246} 253}
247 254
255/**
256 * mmc_start_bkops - start BKOPS for supported cards
257 * @card: MMC card to start BKOPS
258 * @form_exception: A flag to indicate if this function was
259 * called due to an exception raised by the card
260 *
261 * Start background operations whenever requested.
262 * When the urgent BKOPS bit is set in a R1 command response
263 * then background operations should be started immediately.
264*/
265void mmc_start_bkops(struct mmc_card *card, bool from_exception)
266{
267 int err;
268 int timeout;
269 bool use_busy_signal;
270
271 BUG_ON(!card);
272
273 if (!card->ext_csd.bkops_en || mmc_card_doing_bkops(card))
274 return;
275
276 err = mmc_read_bkops_status(card);
277 if (err) {
278 pr_err("%s: Failed to read bkops status: %d\n",
279 mmc_hostname(card->host), err);
280 return;
281 }
282
283 if (!card->ext_csd.raw_bkops_status)
284 return;
285
286 if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
287 from_exception)
288 return;
289
290 mmc_claim_host(card->host);
291 if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
292 timeout = MMC_BKOPS_MAX_TIMEOUT;
293 use_busy_signal = true;
294 } else {
295 timeout = 0;
296 use_busy_signal = false;
297 }
298
299 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
300 EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
301 if (err) {
302 pr_warn("%s: Error %d starting bkops\n",
303 mmc_hostname(card->host), err);
304 goto out;
305 }
306
307 /*
308 * For urgent bkops status (LEVEL_2 and more)
309 * bkops executed synchronously, otherwise
310 * the operation is in progress
311 */
312 if (!use_busy_signal)
313 mmc_card_set_doing_bkops(card);
314out:
315 mmc_release_host(card->host);
316}
317EXPORT_SYMBOL(mmc_start_bkops);
318
248static void mmc_wait_done(struct mmc_request *mrq) 319static void mmc_wait_done(struct mmc_request *mrq)
249{ 320{
250 complete(&mrq->completion); 321 complete(&mrq->completion);
@@ -354,6 +425,14 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host,
354 if (host->areq) { 425 if (host->areq) {
355 mmc_wait_for_req_done(host, host->areq->mrq); 426 mmc_wait_for_req_done(host, host->areq->mrq);
356 err = host->areq->err_check(host->card, host->areq); 427 err = host->areq->err_check(host->card, host->areq);
428 /*
429 * Check BKOPS urgency for each R1 response
430 */
431 if (host->card && mmc_card_mmc(host->card) &&
432 ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) ||
433 (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) &&
434 (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT))
435 mmc_start_bkops(host->card, true);
357 } 436 }
358 437
359 if (!err && areq) 438 if (!err && areq)
@@ -398,7 +477,7 @@ EXPORT_SYMBOL(mmc_wait_for_req);
398 * @card: the MMC card associated with the HPI transfer 477 * @card: the MMC card associated with the HPI transfer
399 * 478 *
400 * Issued High Priority Interrupt, and check for card status 479 * Issued High Priority Interrupt, and check for card status
401 * util out-of prg-state. 480 * until out-of prg-state.
402 */ 481 */
403int mmc_interrupt_hpi(struct mmc_card *card) 482int mmc_interrupt_hpi(struct mmc_card *card)
404{ 483{
@@ -490,6 +569,64 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries
490EXPORT_SYMBOL(mmc_wait_for_cmd); 569EXPORT_SYMBOL(mmc_wait_for_cmd);
491 570
492/** 571/**
572 * mmc_stop_bkops - stop ongoing BKOPS
573 * @card: MMC card to check BKOPS
574 *
575 * Send HPI command to stop ongoing background operations to
576 * allow rapid servicing of foreground operations, e.g. read/
577 * writes. Wait until the card comes out of the programming state
578 * to avoid errors in servicing read/write requests.
579 */
580int mmc_stop_bkops(struct mmc_card *card)
581{
582 int err = 0;
583
584 BUG_ON(!card);
585 err = mmc_interrupt_hpi(card);
586
587 /*
588 * If err is EINVAL, we can't issue an HPI.
589 * It should complete the BKOPS.
590 */
591 if (!err || (err == -EINVAL)) {
592 mmc_card_clr_doing_bkops(card);
593 err = 0;
594 }
595
596 return err;
597}
598EXPORT_SYMBOL(mmc_stop_bkops);
599
600int mmc_read_bkops_status(struct mmc_card *card)
601{
602 int err;
603 u8 *ext_csd;
604
605 /*
606 * In future work, we should consider storing the entire ext_csd.
607 */
608 ext_csd = kmalloc(512, GFP_KERNEL);
609 if (!ext_csd) {
610 pr_err("%s: could not allocate buffer to receive the ext_csd.\n",
611 mmc_hostname(card->host));
612 return -ENOMEM;
613 }
614
615 mmc_claim_host(card->host);
616 err = mmc_send_ext_csd(card, ext_csd);
617 mmc_release_host(card->host);
618 if (err)
619 goto out;
620
621 card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS];
622 card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS];
623out:
624 kfree(ext_csd);
625 return err;
626}
627EXPORT_SYMBOL(mmc_read_bkops_status);
628
629/**
493 * mmc_set_data_timeout - set the timeout for a data command 630 * mmc_set_data_timeout - set the timeout for a data command
494 * @data: data phase for command 631 * @data: data phase for command
495 * @card: the MMC card associated with the data transfer 632 * @card: the MMC card associated with the data transfer
@@ -2333,9 +2470,14 @@ int mmc_suspend_host(struct mmc_host *host)
2333 2470
2334 mmc_bus_get(host); 2471 mmc_bus_get(host);
2335 if (host->bus_ops && !host->bus_dead) { 2472 if (host->bus_ops && !host->bus_dead) {
2336 2473 if (host->bus_ops->suspend) {
2337 if (host->bus_ops->suspend) 2474 if (mmc_card_doing_bkops(host->card)) {
2475 err = mmc_stop_bkops(host->card);
2476 if (err)
2477 goto out;
2478 }
2338 err = host->bus_ops->suspend(host); 2479 err = host->bus_ops->suspend(host);
2480 }
2339 2481
2340 if (err == -ENOSYS || !host->bus_ops->resume) { 2482 if (err == -ENOSYS || !host->bus_ops->resume) {
2341 /* 2483 /*
@@ -2417,11 +2559,21 @@ int mmc_pm_notify(struct notifier_block *notify_block,
2417 struct mmc_host *host = container_of( 2559 struct mmc_host *host = container_of(
2418 notify_block, struct mmc_host, pm_notify); 2560 notify_block, struct mmc_host, pm_notify);
2419 unsigned long flags; 2561 unsigned long flags;
2420 2562 int err = 0;
2421 2563
2422 switch (mode) { 2564 switch (mode) {
2423 case PM_HIBERNATION_PREPARE: 2565 case PM_HIBERNATION_PREPARE:
2424 case PM_SUSPEND_PREPARE: 2566 case PM_SUSPEND_PREPARE:
2567 if (host->card && mmc_card_mmc(host->card) &&
2568 mmc_card_doing_bkops(host->card)) {
2569 err = mmc_stop_bkops(host->card);
2570 if (err) {
2571 pr_err("%s: didn't stop bkops\n",
2572 mmc_hostname(host));
2573 return err;
2574 }
2575 mmc_card_clr_doing_bkops(host->card);
2576 }
2425 2577
2426 spin_lock_irqsave(&host->lock, flags); 2578 spin_lock_irqsave(&host->lock, flags);
2427 host->rescan_disable = 1; 2579 host->rescan_disable = 1;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 396b25891bb9..7509de14aa78 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -463,6 +463,17 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
463 } 463 }
464 464
465 if (card->ext_csd.rev >= 5) { 465 if (card->ext_csd.rev >= 5) {
466 /* check whether the eMMC card supports BKOPS */
467 if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
468 card->ext_csd.bkops = 1;
469 card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
470 card->ext_csd.raw_bkops_status =
471 ext_csd[EXT_CSD_BKOPS_STATUS];
472 if (!card->ext_csd.bkops_en)
473 pr_info("%s: BKOPS_EN bit is not set\n",
474 mmc_hostname(card->host));
475 }
476
466 /* check whether the eMMC card supports HPI */ 477 /* check whether the eMMC card supports HPI */
467 if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) { 478 if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
468 card->ext_csd.hpi = 1; 479 card->ext_csd.hpi = 1;
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 225371a28861..a0e172042e65 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -393,18 +393,19 @@ int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
393} 393}
394 394
395/** 395/**
396 * mmc_switch - modify EXT_CSD register 396 * __mmc_switch - modify EXT_CSD register
397 * @card: the MMC card associated with the data transfer 397 * @card: the MMC card associated with the data transfer
398 * @set: cmd set values 398 * @set: cmd set values
399 * @index: EXT_CSD register index 399 * @index: EXT_CSD register index
400 * @value: value to program into EXT_CSD register 400 * @value: value to program into EXT_CSD register
401 * @timeout_ms: timeout (ms) for operation performed by register write, 401 * @timeout_ms: timeout (ms) for operation performed by register write,
402 * timeout of zero implies maximum possible timeout 402 * timeout of zero implies maximum possible timeout
403 * @use_busy_signal: use the busy signal as response type
403 * 404 *
404 * Modifies the EXT_CSD register for selected card. 405 * Modifies the EXT_CSD register for selected card.
405 */ 406 */
406int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, 407int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
407 unsigned int timeout_ms) 408 unsigned int timeout_ms, bool use_busy_signal)
408{ 409{
409 int err; 410 int err;
410 struct mmc_command cmd = {0}; 411 struct mmc_command cmd = {0};
@@ -418,13 +419,23 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
418 (index << 16) | 419 (index << 16) |
419 (value << 8) | 420 (value << 8) |
420 set; 421 set;
421 cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; 422 cmd.flags = MMC_CMD_AC;
423 if (use_busy_signal)
424 cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
425 else
426 cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
427
428
422 cmd.cmd_timeout_ms = timeout_ms; 429 cmd.cmd_timeout_ms = timeout_ms;
423 430
424 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 431 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
425 if (err) 432 if (err)
426 return err; 433 return err;
427 434
435 /* No need to check card status in case of unblocking command */
436 if (!use_busy_signal)
437 return 0;
438
428 /* Must check status to be sure of no errors */ 439 /* Must check status to be sure of no errors */
429 do { 440 do {
430 err = mmc_send_status(card, &status); 441 err = mmc_send_status(card, &status);
@@ -449,6 +460,13 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
449 460
450 return 0; 461 return 0;
451} 462}
463EXPORT_SYMBOL_GPL(__mmc_switch);
464
465int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
466 unsigned int timeout_ms)
467{
468 return __mmc_switch(card, set, index, value, timeout_ms, true);
469}
452EXPORT_SYMBOL_GPL(mmc_switch); 470EXPORT_SYMBOL_GPL(mmc_switch);
453 471
454int mmc_send_status(struct mmc_card *card, u32 *status) 472int mmc_send_status(struct mmc_card *card, u32 *status)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 4b27f9f503e4..78cc3be85391 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -76,10 +76,13 @@ struct mmc_ext_csd {
76 bool hpi_en; /* HPI enablebit */ 76 bool hpi_en; /* HPI enablebit */
77 bool hpi; /* HPI support bit */ 77 bool hpi; /* HPI support bit */
78 unsigned int hpi_cmd; /* cmd used as HPI */ 78 unsigned int hpi_cmd; /* cmd used as HPI */
79 bool bkops; /* background support bit */
80 bool bkops_en; /* background enable bit */
79 unsigned int data_sector_size; /* 512 bytes or 4KB */ 81 unsigned int data_sector_size; /* 512 bytes or 4KB */
80 unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ 82 unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
81 unsigned int boot_ro_lock; /* ro lock support */ 83 unsigned int boot_ro_lock; /* ro lock support */
82 bool boot_ro_lockable; 84 bool boot_ro_lockable;
85 u8 raw_exception_status; /* 53 */
83 u8 raw_partition_support; /* 160 */ 86 u8 raw_partition_support; /* 160 */
84 u8 raw_erased_mem_count; /* 181 */ 87 u8 raw_erased_mem_count; /* 181 */
85 u8 raw_ext_csd_structure; /* 194 */ 88 u8 raw_ext_csd_structure; /* 194 */
@@ -93,6 +96,7 @@ struct mmc_ext_csd {
93 u8 raw_sec_erase_mult; /* 230 */ 96 u8 raw_sec_erase_mult; /* 230 */
94 u8 raw_sec_feature_support;/* 231 */ 97 u8 raw_sec_feature_support;/* 231 */
95 u8 raw_trim_mult; /* 232 */ 98 u8 raw_trim_mult; /* 232 */
99 u8 raw_bkops_status; /* 246 */
96 u8 raw_sectors[4]; /* 212 - 4 bytes */ 100 u8 raw_sectors[4]; /* 212 - 4 bytes */
97 101
98 unsigned int feature_support; 102 unsigned int feature_support;
@@ -226,6 +230,7 @@ struct mmc_card {
226#define MMC_CARD_REMOVED (1<<7) /* card has been removed */ 230#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
227#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */ 231#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
228#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */ 232#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */
233#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
229 unsigned int quirks; /* card quirks */ 234 unsigned int quirks; /* card quirks */
230#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ 235#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
231#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ 236#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
@@ -393,6 +398,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
393#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) 398#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
394#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) 399#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
395#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP) 400#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP)
401#define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS)
396 402
397#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) 403#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
398#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) 404#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -405,7 +411,9 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
405#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) 411#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
406#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) 412#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
407#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP) 413#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
414#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
408 415
416#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
409#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP) 417#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
410/* 418/*
411 * Quirk add/remove for MMC products. 419 * Quirk add/remove for MMC products.
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 1b431c728b9a..9b9cdafc7737 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -134,6 +134,8 @@ struct mmc_host;
134struct mmc_card; 134struct mmc_card;
135struct mmc_async_req; 135struct mmc_async_req;
136 136
137extern int mmc_stop_bkops(struct mmc_card *);
138extern int mmc_read_bkops_status(struct mmc_card *);
137extern struct mmc_async_req *mmc_start_req(struct mmc_host *, 139extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
138 struct mmc_async_req *, int *); 140 struct mmc_async_req *, int *);
139extern int mmc_interrupt_hpi(struct mmc_card *); 141extern int mmc_interrupt_hpi(struct mmc_card *);
@@ -142,6 +144,8 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
142extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); 144extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
143extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, 145extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
144 struct mmc_command *, int); 146 struct mmc_command *, int);
147extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
148extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
145extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); 149extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
146 150
147#define MMC_ERASE_ARG 0x00000000 151#define MMC_ERASE_ARG 0x00000000
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index d425cab144d9..01e4b394029b 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -139,6 +139,7 @@ static inline bool mmc_op_multi(u32 opcode)
139#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ 139#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
140#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ 140#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
141#define R1_SWITCH_ERROR (1 << 7) /* sx, c */ 141#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
142#define R1_EXCEPTION_EVENT (1 << 6) /* sx, a */
142#define R1_APP_CMD (1 << 5) /* sr, c */ 143#define R1_APP_CMD (1 << 5) /* sr, c */
143 144
144#define R1_STATE_IDLE 0 145#define R1_STATE_IDLE 0
@@ -274,12 +275,15 @@ struct _mmc_csd {
274#define EXT_CSD_FLUSH_CACHE 32 /* W */ 275#define EXT_CSD_FLUSH_CACHE 32 /* W */
275#define EXT_CSD_CACHE_CTRL 33 /* R/W */ 276#define EXT_CSD_CACHE_CTRL 33 /* R/W */
276#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ 277#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
278#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO */
277#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */ 279#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
278#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ 280#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
279#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ 281#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
280#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ 282#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
281#define EXT_CSD_HPI_MGMT 161 /* R/W */ 283#define EXT_CSD_HPI_MGMT 161 /* R/W */
282#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ 284#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
285#define EXT_CSD_BKOPS_EN 163 /* R/W */
286#define EXT_CSD_BKOPS_START 164 /* W */
283#define EXT_CSD_SANITIZE_START 165 /* W */ 287#define EXT_CSD_SANITIZE_START 165 /* W */
284#define EXT_CSD_WR_REL_PARAM 166 /* RO */ 288#define EXT_CSD_WR_REL_PARAM 166 /* RO */
285#define EXT_CSD_BOOT_WP 173 /* R/W */ 289#define EXT_CSD_BOOT_WP 173 /* R/W */
@@ -313,11 +317,13 @@ struct _mmc_csd {
313#define EXT_CSD_PWR_CL_200_360 237 /* RO */ 317#define EXT_CSD_PWR_CL_200_360 237 /* RO */
314#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */ 318#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
315#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */ 319#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
320#define EXT_CSD_BKOPS_STATUS 246 /* RO */
316#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ 321#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
317#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ 322#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
318#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ 323#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
319#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ 324#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
320#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ 325#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
326#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
321#define EXT_CSD_HPI_FEATURES 503 /* RO */ 327#define EXT_CSD_HPI_FEATURES 503 /* RO */
322 328
323/* 329/*
@@ -378,6 +384,19 @@ struct _mmc_csd {
378#define EXT_CSD_PWR_CL_8BIT_SHIFT 4 384#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
379#define EXT_CSD_PWR_CL_4BIT_SHIFT 0 385#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
380/* 386/*
387 * EXCEPTION_EVENT_STATUS field
388 */
389#define EXT_CSD_URGENT_BKOPS BIT(0)
390#define EXT_CSD_DYNCAP_NEEDED BIT(1)
391#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2)
392#define EXT_CSD_PACKED_FAILURE BIT(3)
393
394/*
395 * BKOPS status level
396 */
397#define EXT_CSD_BKOPS_LEVEL_2 0x2
398
399/*
381 * MMC_SWITCH access modes 400 * MMC_SWITCH access modes
382 */ 401 */
383 402