summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2016-05-01 11:36:28 -0600
committerSimon Glass <sjg@chromium.org>2016-05-17 09:54:43 -0600
commit52138fd4072b64448855eac4c2c9815b46f5b43c (patch)
treefd5dead396df725150d71861e69d656d22e73dd9
parent199a1201ab901413a80c64a9eee72f82977ba8d3 (diff)
downloadtalos-obmc-uboot-52138fd4072b64448855eac4c2c9815b46f5b43c.tar.gz
talos-obmc-uboot-52138fd4072b64448855eac4c2c9815b46f5b43c.zip
dm: blk: Allow blk_create_device() to allocate the device number
Allow a devnum parameter of -1 to indicate that the device number should be alocated automatically. The next highest available device number for that interface type is used. Signed-off-by: Simon Glass <sjg@chromium.org>
-rw-r--r--drivers/block/blk-uclass.c29
-rw-r--r--include/blk.h15
2 files changed, 43 insertions, 1 deletions
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 3687b9a100..c947d95023 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -411,6 +411,26 @@ int blk_prepare_device(struct udevice *dev)
return 0;
}
+int blk_find_max_devnum(enum if_type if_type)
+{
+ struct udevice *dev;
+ int max_devnum = -ENODEV;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_BLK, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(dev, uc) {
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+ if (desc->if_type == if_type && desc->devnum > max_devnum)
+ max_devnum = desc->devnum;
+ }
+
+ return max_devnum;
+}
+
int blk_create_device(struct udevice *parent, const char *drv_name,
const char *name, int if_type, int devnum, int blksz,
lbaint_t size, struct udevice **devp)
@@ -428,6 +448,15 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
desc->lba = size / blksz;
desc->part_type = PART_TYPE_UNKNOWN;
desc->bdev = dev;
+ if (devnum == -1) {
+ ret = blk_find_max_devnum(if_type);
+ if (ret == -ENODEV)
+ devnum = 0;
+ else if (ret < 0)
+ return ret;
+ else
+ devnum = ret + 1;
+ }
desc->devnum = devnum;
*devp = dev;
diff --git a/include/blk.h b/include/blk.h
index 2caac9c96b..547c3b48dc 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -270,7 +270,8 @@ int blk_next_device(struct udevice **devp);
* @drv_name: Driver name to use for the block device
* @name: Name for the device
* @if_type: Interface type (enum if_type_t)
- * @devnum: Device number, specific to the interface type
+ * @devnum: Device number, specific to the interface type, or -1 to
+ * allocate the next available number
* @blksz: Block size of the device in bytes (typically 512)
* @size: Total size of the device in bytes
* @devp: the new device (which has not been probed)
@@ -299,6 +300,18 @@ int blk_prepare_device(struct udevice *dev);
*/
int blk_unbind_all(int if_type);
+/**
+ * blk_find_max_devnum() - find the maximum device number for an interface type
+ *
+ * Finds the last allocated device number for an interface type @if_type. The
+ * next number is safe to use for a newly allocated device.
+ *
+ * @if_type: Interface type to scan
+ * @return maximum device number found, or -ENODEV if none, or other -ve on
+ * error
+ */
+int blk_find_max_devnum(enum if_type if_type);
+
#else
#include <errno.h>
/*
OpenPOWER on IntegriCloud