summaryrefslogtreecommitdiffstats
path: root/drivers/mci/mci-core.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2017-01-13 15:06:57 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-01-19 15:21:33 +0100
commit6e9a87b39429c7f63627556d7e1ff6e9c5ac2b81 (patch)
tree66eef93b9d5fd54c86bbe5d556cecc768829683a /drivers/mci/mci-core.c
parent32da9097e71d917803ab244ffdddeb3bead00d41 (diff)
downloadbarebox-6e9a87b39429c7f63627556d7e1ff6e9c5ac2b81.tar.gz
barebox-6e9a87b39429c7f63627556d7e1ff6e9c5ac2b81.tar.xz
mci: Allow to partition eMMC boot partitions
So far the eMMC boot partitions cannot be partitioned from the device tree. Since they are often 4MiB in size they are big enough to hold a barebox image and the environment. Add partition parsing to the boot partitions to allow this usecase. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mci/mci-core.c')
-rw-r--r--drivers/mci/mci-core.c78
1 files changed, 55 insertions, 23 deletions
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 4e176f7b3c..055a5e2b06 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -436,6 +436,7 @@ static void mci_part_add(struct mci *mci, uint64_t size,
part->blk.num_blocks = mci_calc_blk_cnt(size, part->blk.blockbits);
part->area_type = area_type;
part->part_cfg = part_cfg;
+ part->idx = idx;
if (area_type == MMC_BLK_DATA_AREA_MAIN)
part->blk.cdev.device_node = mci->host->hw_dev->device_node;
@@ -1573,6 +1574,59 @@ static const char *mci_boot_names[] = {
"user",
};
+static int mci_register_partition(struct mci_part *part)
+{
+ struct mci *mci = part->mci;
+ struct mci_host *host = mci->host;
+ const char *partnodename = NULL;
+ struct device_node *np;
+ int rc;
+
+ /*
+ * An MMC/SD card acts like an ordinary disk.
+ * So, re-use the disk driver to gain access to this media
+ */
+ part->blk.dev = &mci->dev;
+ part->blk.ops = &mci_ops;
+
+ rc = blockdevice_register(&part->blk);
+ if (rc != 0) {
+ dev_err(&mci->dev, "Failed to register MCI/SD blockdevice\n");
+ return rc;
+ }
+ dev_info(&mci->dev, "registered %s\n", part->blk.cdev.name);
+
+ np = host->hw_dev->device_node;
+
+ /* create partitions on demand */
+ switch (part->area_type) {
+ case MMC_BLK_DATA_AREA_BOOT:
+ if (part->idx == 0)
+ partnodename = "boot0-partitions";
+ else
+ partnodename = "boot1-partitions";
+
+ np = of_get_child_by_name(host->hw_dev->device_node,
+ partnodename);
+ break;
+ case MMC_BLK_DATA_AREA_MAIN:
+ break;
+ default:
+ return 0;
+ }
+
+ rc = parse_partition_table(&part->blk);
+ if (rc != 0) {
+ dev_warn(&mci->dev, "No partition table found\n");
+ rc = 0; /* it's not a failure */
+ }
+
+ if (np)
+ of_parse_partitions(&part->blk.cdev, np);
+
+ return 0;
+}
+
/**
* Probe an MCI card at the given host interface
* @param mci MCI device instance
@@ -1647,29 +1701,7 @@ static int mci_card_probe(struct mci *mci)
for (i = 0; i < mci->nr_parts; i++) {
struct mci_part *part = &mci->part[i];
- /*
- * An MMC/SD card acts like an ordinary disk.
- * So, re-use the disk driver to gain access to this media
- */
- part->blk.dev = &mci->dev;
- part->blk.ops = &mci_ops;
-
- rc = blockdevice_register(&part->blk);
- if (rc != 0) {
- dev_err(&mci->dev, "Failed to register MCI/SD blockdevice\n");
- goto on_error;
- }
- dev_info(&mci->dev, "registered %s\n", part->blk.cdev.name);
-
- /* create partitions on demand */
- if (part->area_type == MMC_BLK_DATA_AREA_MAIN) {
- rc = parse_partition_table(&part->blk);
- if (rc != 0) {
- dev_warn(&mci->dev, "No partition table found\n");
- rc = 0; /* it's not a failure */
- }
- of_parse_partitions(&part->blk.cdev, host->hw_dev->device_node);
- }
+ rc = mci_register_partition(part);
if (IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS) &&
part->area_type == MMC_BLK_DATA_AREA_BOOT &&