]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
devres: add devm_kmalloc() and friends (managed memory allocators)
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Sat, 25 Jul 2015 12:52:36 +0000 (21:52 +0900)
committerLothar Waßmann <LW@KARO-electronics.de>
Thu, 10 Sep 2015 06:17:18 +0000 (08:17 +0200)
devm_kmalloc() is identical to kmalloc() except that the memory
allocated with it is managed and will be automatically released
when the device is removed/unbound.

Likewise for the other variants.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Simon Glass <sjg@chromium.org>
drivers/core/devres.c
include/dm/device.h

index 49c270c57c81f90f90b3052e94f582f13bdbbbd7..f235c1bcfddb4b3c2c6128b69dc5fedab9001e08 100644 (file)
@@ -194,3 +194,37 @@ void devres_release_all(struct udevice *dev)
 {
        release_nodes(dev, &dev->devres_head, false);
 }
+
+/*
+ * Managed kmalloc/kfree
+ */
+static void devm_kmalloc_release(struct udevice *dev, void *res)
+{
+       /* noop */
+}
+
+static int devm_kmalloc_match(struct udevice *dev, void *res, void *data)
+{
+       return res == data;
+}
+
+void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp)
+{
+       void *data;
+
+       data = _devres_alloc(devm_kmalloc_release, size, gfp);
+       if (unlikely(!data))
+               return NULL;
+
+       devres_add(dev, data);
+
+       return data;
+}
+
+void devm_kfree(struct udevice *dev, void *p)
+{
+       int rc;
+
+       rc = devres_destroy(dev, devm_kmalloc_release, devm_kmalloc_match, p);
+       WARN_ON(rc);
+}
index 85513e10eef71a545bd9a751a394508e72670a36..c474f2dabba3f35ae4f72ae8766799e5b43255d6 100644 (file)
@@ -14,6 +14,8 @@
 #include <dm/uclass-id.h>
 #include <fdtdec.h>
 #include <linker_lists.h>
+#include <linux/compat.h>
+#include <linux/kernel.h>
 #include <linux/list.h>
 
 struct driver_info;
@@ -605,4 +607,46 @@ int devres_destroy(struct udevice *dev, dr_release_t release,
 int devres_release(struct udevice *dev, dr_release_t release,
                   dr_match_t match, void *match_data);
 
+/* managed devm_k.alloc/kfree for device drivers */
+/**
+ * devm_kmalloc - Resource-managed kmalloc
+ * @dev: Device to allocate memory for
+ * @size: Allocation size
+ * @gfp: Allocation gfp flags
+ *
+ * Managed kmalloc.  Memory allocated with this function is
+ * automatically freed on driver detach.  Like all other devres
+ * resources, guaranteed alignment is unsigned long long.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+void *devm_kmalloc(struct udevice *dev, size_t size, gfp_t gfp);
+static inline void *devm_kzalloc(struct udevice *dev, size_t size, gfp_t gfp)
+{
+       return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
+}
+static inline void *devm_kmalloc_array(struct udevice *dev,
+                                      size_t n, size_t size, gfp_t flags)
+{
+       if (size != 0 && n > SIZE_MAX / size)
+               return NULL;
+       return devm_kmalloc(dev, n * size, flags);
+}
+static inline void *devm_kcalloc(struct udevice *dev,
+                                size_t n, size_t size, gfp_t flags)
+{
+       return devm_kmalloc_array(dev, n, size, flags | __GFP_ZERO);
+}
+
+/**
+ * devm_kfree - Resource-managed kfree
+ * @dev: Device this memory belongs to
+ * @p: Memory to free
+ *
+ * Free memory allocated with devm_kmalloc().
+ */
+void devm_kfree(struct udevice *dev, void *p);
+
+
 #endif