mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 14/17] mtd: Add a partitions parameter to mtd devices
Date: Thu, 12 Feb 2015 09:54:31 +0100	[thread overview]
Message-ID: <1423731274-9860-15-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1423731274-9860-1-git-send-email-s.hauer@pengutronix.de>

The partitions parameter allows to partition a mtd device
using a standard cmdline partition description string. This
way the partitions of a mtd device can be changed at once.
The output of the string can be used to be passed to the kernel
as cmdline partition string. The partitions can also still be
changed with addpart/delpart, the partitions parameter will
be updated accordingly.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/core.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 99d50f1..ac1001e 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -18,6 +18,7 @@
 #include <common.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/mtd.h>
+#include <cmdlinepart.h>
 #include <init.h>
 #include <xfuncs.h>
 #include <driver.h>
@@ -377,6 +378,98 @@ static struct file_operations mtd_ops = {
 	.lseek  = dev_lseek_default,
 };
 
+static int mtd_partition_set(struct device_d *dev, struct param_d *p, const char *val)
+{
+	struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev);
+	struct mtd_info *mtdpart, *tmp;
+	int ret;
+
+	list_for_each_entry_safe(mtdpart, tmp, &mtd->partitions, partitions_entry) {
+		ret = mtd_del_partition(mtdpart);
+		if (ret)
+			return ret;
+	}
+
+	return cmdlinepart_do_parse(mtd->cdev.name, val, mtd->size, CMDLINEPART_ADD_DEVNAME);
+}
+
+static char *print_size(uint64_t s)
+{
+	if (!(s & ((1 << 20) - 1)))
+		return asprintf("%lldM", s >> 20);
+	if (!(s & ((1 << 10) - 1)))
+		return asprintf("%lldk", s >> 10);
+	return asprintf("0x%lld", s);
+}
+
+static int print_part(char *buf, int bufsize, struct mtd_info *mtd, uint64_t last_ofs,
+		int is_last)
+{
+	char *size = print_size(mtd->size);
+	char *ofs = print_size(mtd->master_offset);
+	int ret;
+
+	if (!size || !ofs) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (mtd->master_offset == last_ofs)
+		ret = snprintf(buf, bufsize, "%s(%s)%s", size,
+				mtd->cdev.partname,
+				is_last ? "" : ",");
+	else
+		ret = snprintf(buf, bufsize, "%s@%s(%s)%s", size,
+				ofs,
+				mtd->cdev.partname,
+				is_last ? "" : ",");
+out:
+	free(size);
+	free(ofs);
+
+	return ret;
+}
+
+static int print_parts(char *buf, int bufsize, struct mtd_info *mtd)
+{
+	struct mtd_info *mtdpart;
+	uint64_t last_ofs = 0;
+	int ret = 0;
+
+	list_for_each_entry(mtdpart, &mtd->partitions, partitions_entry) {
+		int now;
+		int is_last = list_is_last(&mtdpart->partitions_entry,
+					&mtd->partitions);
+
+		now = print_part(buf, bufsize, mtdpart, last_ofs, is_last);
+		if (now < 0)
+			return now;
+
+		if (buf && bufsize) {
+			buf += now;
+			bufsize -= now;
+		}
+		ret += now;
+		last_ofs = mtdpart->master_offset + mtdpart->size;
+	}
+
+	return ret;
+}
+
+static const char *mtd_partition_get(struct device_d *dev, struct param_d *p)
+{
+	struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev);
+	int len = 0;
+
+	free(p->value);
+
+	len = print_parts(NULL, 0, mtd);
+	p->value = xzalloc(len + 1);
+	print_parts(p->value, len + 1, mtd);
+
+	return p->value;
+}
+
 static int mtd_part_compare(struct list_head *a, struct list_head *b)
 {
 	struct mtd_info *mtda = container_of(a, struct mtd_info, partitions_entry);
@@ -448,8 +541,10 @@ int add_mtd_device(struct mtd_info *mtd, char *devname, int device_id)
 	if (mtd_can_have_bb(mtd))
 		mtd->cdev_bb = mtd_add_bb(mtd, NULL);
 
-	if (mtd->parent && !mtd->master)
+	if (mtd->parent && !mtd->master) {
+		dev_add_param(&mtd->class_dev, "partitions", mtd_partition_set, mtd_partition_get, 0);
 		of_parse_partitions(&mtd->cdev, mtd->parent->device_node);
+	}
 
 	list_for_each_entry(hook, &mtd_register_hooks, hook)
 		if (hook->add_mtd_device)
-- 
2.1.4


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2015-02-12  8:55 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-12  8:54 mtd partition handling updates Sascha Hauer
2015-02-12  8:54 ` [PATCH 01/17] of: Add for_each_child_of_node_safe Sascha Hauer
2015-02-12  8:54 ` [PATCH 02/17] mtd: core: add error checks Sascha Hauer
2015-02-12  8:54 ` [PATCH 03/17] mtd: partitions: Use xstrdup Sascha Hauer
2015-02-12  8:54 ` [PATCH 04/17] mtd: partitions: Add error check Sascha Hauer
2015-02-12  8:54 ` [PATCH 05/17] mtd: Add partitions to list Sascha Hauer
2015-02-12  8:54 ` [PATCH 06/17] mtd: nand: remove automatically created bb devices Sascha Hauer
2015-02-12  8:54 ` [PATCH 07/17] move cmdline partition parsing code to separate file Sascha Hauer
2015-02-12  8:54 ` [PATCH 08/17] cmdlinepart: Change SIZE_REMAINING to loff_t Sascha Hauer
2015-02-12  8:54 ` [PATCH 09/17] cmdlinepart: make argument types safer Sascha Hauer
2015-02-12  8:54 ` [PATCH 10/17] cmdlinepart: add function to parse a cmdline partition string Sascha Hauer
2015-02-12  8:54 ` [PATCH 11/17] cmndlinepart: skip devname if partstr already contains it Sascha Hauer
2015-02-12  8:54 ` [PATCH 12/17] mtd: forbid conflicting mtd partitions Sascha Hauer
2015-02-12  8:54 ` [PATCH 13/17] mtd: Use flags parameter in mtd_add_partition Sascha Hauer
2015-02-12  8:54 ` Sascha Hauer [this message]
2015-02-12  8:54 ` [PATCH 15/17] mtd: fixup device tree partitions Sascha Hauer
2015-02-12  8:54 ` [PATCH 16/17] defaultenv-2: mtdparts-add: remove unused variable Sascha Hauer
2015-02-12  8:54 ` [PATCH 17/17] defaultenv-2: mtdparts-add: Use new partition parameter Sascha Hauer
2015-02-13  5:54 ` mtd partition handling updates Bo Shen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1423731274-9860-15-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox