[PATCH 2/3] Add boot_enable sysfs attribute to select MMC boot operation partition
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 --- 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 intpart_curr; struct device_attribute force_ro; +struct device_attribute boot_enable; struct device_attribute power_ro_lock; intarea_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, , 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(>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), >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), >boot_enable); +boot_enable_fail: device_remove_file(disk_to_dev(md->disk), >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-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] Add boot_enable sysfs attribute to select MMC boot operation partition
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 narmstr...@neotion.com --- 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 intpart_curr; struct device_attribute force_ro; +struct device_attribute boot_enable; struct device_attribute power_ro_lock; intarea_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-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/