checkpatch.pl: Request a test when a new command is added
[oweals/u-boot.git] / drivers / block / blk-uclass.c
index aee2a50d6269248609ef3a6cef0aae2a07127797..b19375cbc8da3466eef5e22a3d27952b2140500d 100644 (file)
@@ -1,15 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2016 Google, Inc
  * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <blk.h>
 #include <dm.h>
+#include <log.h>
+#include <malloc.h>
+#include <part.h>
 #include <dm/device-internal.h>
 #include <dm/lists.h>
+#include <dm/uclass-internal.h>
+#include <linux/err.h>
 
 static const char *if_typename_str[IF_TYPE_COUNT] = {
        [IF_TYPE_IDE]           = "ide",
@@ -21,8 +25,9 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
        [IF_TYPE_SD]            = "sd",
        [IF_TYPE_SATA]          = "sata",
        [IF_TYPE_HOST]          = "host",
-       [IF_TYPE_SYSTEMACE]     = "ace",
        [IF_TYPE_NVME]          = "nvme",
+       [IF_TYPE_EFI]           = "efi",
+       [IF_TYPE_VIRTIO]        = "virtio",
 };
 
 static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
@@ -36,7 +41,8 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
        [IF_TYPE_SATA]          = UCLASS_AHCI,
        [IF_TYPE_HOST]          = UCLASS_ROOT,
        [IF_TYPE_NVME]          = UCLASS_NVME,
-       [IF_TYPE_SYSTEMACE]     = UCLASS_INVALID,
+       [IF_TYPE_EFI]           = UCLASS_EFI,
+       [IF_TYPE_VIRTIO]        = UCLASS_VIRTIO,
 };
 
 static enum if_type if_typename_to_iftype(const char *if_typename)
@@ -131,6 +137,29 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
        return NULL;
 }
 
+/**
+ * blk_get_by_device() - Get the block device descriptor for the given device
+ * @dev:       Instance of a storage device
+ *
+ * Return: With block device descriptor on success , NULL if there is no such
+ *        block device.
+ */
+struct blk_desc *blk_get_by_device(struct udevice *dev)
+{
+       struct udevice *child_dev;
+
+       device_foreach_child(child_dev, dev) {
+               if (device_get_uclass_id(child_dev) != UCLASS_BLK)
+                       continue;
+
+               return dev_get_uclass_platdata(child_dev);
+       }
+
+       debug("%s: No block device found\n", __func__);
+
+       return NULL;
+}
+
 /**
  * get_desc() - Get the block device descriptor for the given device number
  *
@@ -294,9 +323,6 @@ ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
        if (IS_ERR_VALUE(n))
                return n;
 
-       /* flush cache after read */
-       flush_cache((ulong)buffer, blkcnt * desc->blksz);
-
        return n;
 }
 
@@ -334,7 +360,7 @@ int blk_first_device(int if_type, struct udevice **devp)
        struct blk_desc *desc;
        int ret;
 
-       ret = uclass_first_device(UCLASS_BLK, devp);
+       ret = uclass_find_first_device(UCLASS_BLK, devp);
        if (ret)
                return ret;
        if (!*devp)
@@ -343,7 +369,7 @@ int blk_first_device(int if_type, struct udevice **devp)
                desc = dev_get_uclass_platdata(*devp);
                if (desc->if_type == if_type)
                        return 0;
-               ret = uclass_next_device(devp);
+               ret = uclass_find_next_device(devp);
                if (ret)
                        return ret;
        } while (*devp);
@@ -359,7 +385,7 @@ int blk_next_device(struct udevice **devp)
        desc = dev_get_uclass_platdata(*devp);
        if_type = desc->if_type;
        do {
-               ret = uclass_next_device(devp);
+               ret = uclass_find_next_device(devp);
                if (ret)
                        return ret;
                if (!*devp)
@@ -451,15 +477,6 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
        return ops->erase(dev, start, blkcnt);
 }
 
-int blk_prepare_device(struct udevice *dev)
-{
-       struct blk_desc *desc = dev_get_uclass_platdata(dev);
-
-       part_init(desc);
-
-       return 0;
-}
-
 int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
 {
        struct udevice *dev;
@@ -506,7 +523,7 @@ int blk_find_max_devnum(enum if_type if_type)
        return max_devnum;
 }
 
-static int blk_next_free_devnum(enum if_type if_type)
+int blk_next_free_devnum(enum if_type if_type)
 {
        int ret;
 
@@ -567,6 +584,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
        desc = dev_get_uclass_platdata(dev);
        desc->if_type = if_type;
        desc->blksz = blksz;
+       desc->log2blksz = LOG2(desc->blksz);
        desc->lba = lba;
        desc->part_type = PART_TYPE_UNKNOWN;
        desc->bdev = dev;
@@ -624,8 +642,20 @@ int blk_unbind_all(int if_type)
        return 0;
 }
 
+static int blk_post_probe(struct udevice *dev)
+{
+#if defined(CONFIG_PARTITIONS) && defined(CONFIG_HAVE_BLOCK_DEVICE)
+       struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+       part_init(desc);
+#endif
+
+       return 0;
+}
+
 UCLASS_DRIVER(blk) = {
        .id             = UCLASS_BLK,
        .name           = "blk",
+       .post_probe     = blk_post_probe,
        .per_device_platdata_auto_alloc_size = sizeof(struct blk_desc),
 };