mtd: nand: pxa3xx: fix raw read when last_chunk_size == 0
[oweals/u-boot.git] / drivers / block / blk-uclass.c
index 537cf5f0bbcb0d6122c247dcf09c326ee701add9..7c39aa5f2f5fd99c34101a1f636e7dba95bd9d28 100644 (file)
@@ -1,15 +1,17 @@
+// 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 <malloc.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 +23,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 +39,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 +135,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
  *
@@ -331,7 +358,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)
@@ -340,7 +367,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);
@@ -356,7 +383,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)
@@ -448,15 +475,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;
@@ -503,7 +521,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;
 
@@ -564,6 +582,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;
@@ -621,8 +640,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),
 };