From bb4840d2fdf357992815bf3a22b5732c460bc485 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Mon, 10 May 2021 12:25:23 +0200 Subject: fs: add linux_rootarg 'root=mmcblkXpN' support Since commit fa2d0aa96941 ("mmc: core: Allow setting slot index via device tree alias") the linux kernel supports stable mmc device names. Barebox has stable names since years so now we can connect both which allows us to pass 'root=mmcblkXpN' as argument for the cmdline. Note: it is crucial that the kernel device tree and the barebox device tree uses the same mmc aliases. This patch adds the support to store the above cmdline as linux_rootarg if enabled. The partuuid is now used as fallback since it is not as unique as the mmcblkXpN scheme. It is added as build option since the system integrator needs to check if the used kernel contains the above commit. Signed-off-by: Marco Felsch Link: https://lore.barebox.org/20210510102523.7147-3-m.felsch@pengutronix.de Signed-off-by: Sascha Hauer --- fs/fs.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/fs.c b/fs/fs.c index 6de5a3b59e..b67bf42ba4 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -2833,6 +2833,33 @@ out: } EXPORT_SYMBOL(chdir); +static char *get_linux_mmcblkdev(struct fs_device_d *fsdev) +{ + struct cdev *cdevm, *cdev; + int id, partnum; + + cdevm = fsdev->cdev->master; + id = of_alias_get_id(cdevm->device_node, "mmc"); + if (id < 0) + return NULL; + + partnum = 1; /* linux partitions are 1 based */ + list_for_each_entry(cdev, &cdevm->partitions, partition_entry) { + + /* + * Partname is not guaranteed but this partition cdev is listed + * in the partitions list so we need to count it instead of + * skipping it. + */ + if (cdev->partname && + !strcmp(cdev->partname, fsdev->cdev->partname)) + return basprintf("root=/dev/mmcblk%dp%d", id, partnum); + partnum++; + } + + return NULL; +} + /* * Mount a device to a directory. * We do this by registering a new device on which the filesystem @@ -2921,11 +2948,19 @@ int mount(const char *device, const char *fsname, const char *pathname, fsdev->vfsmount.mnt_root = fsdev->sb.s_root; - if (!fsdev->linux_rootarg && fsdev->cdev && fsdev->cdev->partuuid[0] != 0) { - char *str = basprintf("root=PARTUUID=%s", - fsdev->cdev->partuuid); + if (!fsdev->linux_rootarg && fsdev->cdev) { + char *str = NULL; + + if (IS_ENABLED(CONFIG_MMCBLKDEV_ROOTARG) && + fsdev->cdev->master && + cdev_is_mci_main_part_dev(fsdev->cdev->master)) + str = get_linux_mmcblkdev(fsdev); + + if (!str && fsdev->cdev->partuuid[0] != 0) + str = basprintf("root=PARTUUID=%s", fsdev->cdev->partuuid); - fsdev_set_linux_rootarg(fsdev, str); + if (str) + fsdev_set_linux_rootarg(fsdev, str); } path_put(&path); -- cgit v1.2.3