[PATCH 2/3] Add boot_enable sysfs attribute to select MMC boot operation partition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add sysfs attribute to select the eMMC boot mode operation according to
the eMMC 4.5 specifications.
Valid values are : 0 for disabled, 1 for first boot partition, 2 for
second boot partition, 7 for user area.

Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxx>
---
 drivers/mmc/card/block.c |   72
+++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 5bab73b..e11c42e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -114,6 +114,7 @@ struct mmc_blk_data {
      */
     unsigned int    part_curr;
     struct device_attribute force_ro;
+    struct device_attribute boot_enable;
     struct device_attribute power_ro_lock;
     int    area_type;
 };
@@ -264,6 +265,23 @@ static ssize_t force_ro_show(struct device *dev,
struct device_attribute *attr,
     return ret;
 }
 
+static ssize_t boot_enable_show(struct device *dev,
+                 struct device_attribute *attr, char *buf)
+{
+    int ret;
+    struct mmc_card *card;
+    struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+
+    md = mmc_blk_get(dev_to_disk(dev));
+    card = md->queue.card;
+
+    ret = snprintf(buf, PAGE_SIZE, "%d",
+                (card->ext_csd.part_config &
+                 EXT_CSD_PART_CONFIG_EN_MASK) >> 3);
+    mmc_blk_put(md);
+    return ret;
+}
+
 static ssize_t force_ro_store(struct device *dev, struct
device_attribute *attr,
                   const char *buf, size_t count)
 {
@@ -283,6 +301,48 @@ out:
     return ret;
 }
 
+static ssize_t boot_enable_store(struct device *dev,
+                  struct device_attribute *attr, const char *buf,
+                  size_t count)
+{
+    int ret;
+    char *end;
+    u8 part_config;
+    struct mmc_card *card;
+    struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+    unsigned long set = simple_strtoul(buf, &end, 0);
+    if (end == buf) {
+        ret = -EINVAL;
+        goto out;
+    }
+
+    md = mmc_blk_get(dev_to_disk(dev));
+    card = md->queue.card;
+
+    part_config = card->ext_csd.part_config;
+
+    part_config &= EXT_CSD_PART_CONFIG_EN_MASK;
+    part_config |= (set << 3) & EXT_CSD_PART_CONFIG_EN_MASK;
+
+    mmc_claim_host(card->host);
+
+    ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                 EXT_CSD_PART_CONFIG, part_config,
+                 card->ext_csd.part_time);
+
+    mmc_release_host(card->host);
+
+    if (ret)
+        return ret;
+
+    card->ext_csd.part_config = part_config;
+
+    ret = count;
+out:
+    mmc_blk_put(md);
+    return ret;
+}
+
 static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
     struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
@@ -2202,6 +2262,15 @@ static int mmc_add_disk(struct mmc_blk_data *md)
     if (ret)
         goto force_ro_fail;
 
+    md->boot_enable.show = boot_enable_show;
+    md->boot_enable.store = boot_enable_store;
+    sysfs_attr_init(&md->boot_enable.attr);
+    md->boot_enable.attr.name = "boot_enable";
+    md->boot_enable.attr.mode = S_IRUGO | S_IWUSR;
+    ret = device_create_file(disk_to_dev(md->disk), &md->boot_enable);
+    if (ret)
+        goto boot_enable_fail;
+
     if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
          card->ext_csd.boot_ro_lockable) {
         umode_t mode;
@@ -2225,6 +2294,8 @@ static int mmc_add_disk(struct mmc_blk_data *md)
     return ret;
 
 power_ro_lock_fail:
+    device_remove_file(disk_to_dev(md->disk), &md->boot_enable);
+boot_enable_fail:
     device_remove_file(disk_to_dev(md->disk), &md->force_ro);
 force_ro_fail:
     del_gendisk(md->disk);
@@ -2434,4 +2505,3 @@ module_exit(mmc_blk_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
-
-- 
1.7.0.4

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




[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux