summaryrefslogtreecommitdiffstats
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
parent32da9097e71d917803ab244ffdddeb3bead00d41 (diff)
downloadbarebox-6e9a87b39429c7f63627556d7e1ff6e9c5ac2b81.tar.gz
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>
-rw-r--r--drivers/mci/mci-core.c78
-rw-r--r--include/mci.h1
2 files changed, 56 insertions, 23 deletions
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 4e176f7..055a5e2 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 &&
diff --git a/include/mci.h b/include/mci.h
index 0370547..cc4712c 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -433,6 +433,7 @@ struct mci_part {
uint64_t size; /* partition size (in bytes) */
unsigned int part_cfg; /* partition type */
char *name;
+ int idx;
unsigned int area_type;
#define MMC_BLK_DATA_AREA_MAIN (1<<0)
#define MMC_BLK_DATA_AREA_BOOT (1<<1)