Merge "mmc: block: Adding device attribute for minimum sectors to start BKOPS"
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt
index 08f7312..7dde34f 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -25,6 +25,15 @@
running parallel lmdd write and lmdd read operations and calculating
the max number of packed writes requests.
+ min_sectors_to_check_bkops_status This attribute is used to
+ determine whether the status bit that indicates the need for BKOPS
+ should be checked. The value is stored in this attribute represents
+ the minimum number of sectors that needs to be changed in the device
+ (written or discarded) in order to require the status-bit of BKOPS
+ to be checked. The value can modified via sysfs by writing the
+ required value to:
+ /sys/block/<block_dev_name>/min_sectors_to_check_bkops_status
+
SD and MMC Device Attributes
============================
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index b9cd8ec..7387d9a 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -121,6 +121,7 @@
struct device_attribute force_ro;
struct device_attribute power_ro_lock;
struct device_attribute num_wr_reqs_to_start_packing;
+ struct device_attribute min_sectors_to_check_bkops_status;
int area_type;
};
@@ -306,6 +307,48 @@
return count;
}
+static ssize_t
+min_sectors_to_check_bkops_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+ unsigned int min_sectors_to_check_bkops_status;
+ struct mmc_card *card = md->queue.card;
+ int ret;
+
+ if (!card)
+ return -EINVAL;
+
+ min_sectors_to_check_bkops_status =
+ card->bkops_info.min_sectors_to_queue_delayed_work;
+
+ ret = snprintf(buf, PAGE_SIZE, "%d\n",
+ min_sectors_to_check_bkops_status);
+
+ mmc_blk_put(md);
+ return ret;
+}
+
+static ssize_t
+min_sectors_to_check_bkops_status_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value;
+ struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+ struct mmc_card *card = md->queue.card;
+
+ if (!card)
+ return -EINVAL;
+
+ sscanf(buf, "%d", &value);
+ if (value >= 0)
+ card->bkops_info.min_sectors_to_queue_delayed_work = value;
+
+ mmc_blk_put(md);
+ return count;
+}
+
static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
{
struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
@@ -2316,6 +2359,19 @@
if (ret)
goto power_ro_lock_fail;
+ md->min_sectors_to_check_bkops_status.show =
+ min_sectors_to_check_bkops_status_show;
+ md->min_sectors_to_check_bkops_status.store =
+ min_sectors_to_check_bkops_status_store;
+ sysfs_attr_init(&md->min_sectors_to_check_bkops_status.attr);
+ md->min_sectors_to_check_bkops_status.attr.name =
+ "min_sectors_to_check_bkops_status";
+ md->min_sectors_to_check_bkops_status.attr.mode = S_IRUGO | S_IWUSR;
+ ret = device_create_file(disk_to_dev(md->disk),
+ &md->min_sectors_to_check_bkops_status);
+ if (ret)
+ goto power_ro_lock_fail;
+
return ret;
power_ro_lock_fail:
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 9b9e8cc..7e03e5a 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -291,7 +291,7 @@
return;
if (card->bkops_info.sectors_changed <
- BKOPS_MIN_SECTORS_TO_QUEUE_DELAYED_WORK)
+ card->bkops_info.min_sectors_to_queue_delayed_work)
return;
pr_debug("%s: %s: queueing delayed_bkops_work\n",
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 457db7f..ca8b01c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1336,6 +1336,8 @@
card->bkops_info.delay_ms,
card->bkops_info.host_suspend_tout_ms/2);
+ card->bkops_info.min_sectors_to_queue_delayed_work =
+ BKOPS_MIN_SECTORS_TO_QUEUE_DELAYED_WORK;
}
}
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 257bcc0..477733c 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -248,6 +248,7 @@
struct delayed_work dw;
unsigned int host_suspend_tout_ms;
unsigned int delay_ms;
+ unsigned int min_sectors_to_queue_delayed_work;
/*
* A default time for checking the need for non urgent BKOPS once mmcqd
* is idle.