ARM: dts: Move the PMIC interrupt pinctrl line to rk3288-evb common
[cascardo/linux.git] / mm / zbud.c
index 01df13a..a05790b 100644 (file)
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -51,6 +51,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/zbud.h>
+#include <linux/zpool.h>
 
 /*****************
  * Structures
@@ -112,6 +113,90 @@ struct zbud_header {
        bool under_reclaim;
 };
 
+/*****************
+ * zpool
+ ****************/
+
+#ifdef CONFIG_ZPOOL
+
+static int zbud_zpool_evict(struct zbud_pool *pool, unsigned long handle)
+{
+       return zpool_evict(pool, handle);
+}
+
+static struct zbud_ops zbud_zpool_ops = {
+       .evict =        zbud_zpool_evict
+};
+
+static void *zbud_zpool_create(gfp_t gfp, struct zpool_ops *zpool_ops)
+{
+       return zbud_create_pool(gfp, &zbud_zpool_ops);
+}
+
+static void zbud_zpool_destroy(void *pool)
+{
+       zbud_destroy_pool(pool);
+}
+
+static int zbud_zpool_malloc(void *pool, size_t size, gfp_t gfp,
+                       unsigned long *handle)
+{
+       return zbud_alloc(pool, size, gfp, handle);
+}
+static void zbud_zpool_free(void *pool, unsigned long handle)
+{
+       zbud_free(pool, handle);
+}
+
+static int zbud_zpool_shrink(void *pool, unsigned int pages,
+                       unsigned int *reclaimed)
+{
+       unsigned int total = 0;
+       int ret = -EINVAL;
+
+       while (total < pages) {
+               ret = zbud_reclaim_page(pool, 8);
+               if (ret < 0)
+                       break;
+               total++;
+       }
+
+       if (reclaimed)
+               *reclaimed = total;
+
+       return ret;
+}
+
+static void *zbud_zpool_map(void *pool, unsigned long handle,
+                       enum zpool_mapmode mm)
+{
+       return zbud_map(pool, handle);
+}
+static void zbud_zpool_unmap(void *pool, unsigned long handle)
+{
+       zbud_unmap(pool, handle);
+}
+
+static u64 zbud_zpool_total_size(void *pool)
+{
+       return zbud_get_pool_size(pool) * PAGE_SIZE;
+}
+
+static struct zpool_driver zbud_zpool_driver = {
+       .type =         "zbud",
+       .owner =        THIS_MODULE,
+       .create =       zbud_zpool_create,
+       .destroy =      zbud_zpool_destroy,
+       .malloc =       zbud_zpool_malloc,
+       .free =         zbud_zpool_free,
+       .shrink =       zbud_zpool_shrink,
+       .map =          zbud_zpool_map,
+       .unmap =        zbud_zpool_unmap,
+       .total_size =   zbud_zpool_total_size,
+};
+
+#endif /* CONFIG_ZPOOL */
+
 /*****************
  * Helpers
 *****************/
@@ -122,7 +207,7 @@ enum buddy {
 };
 
 /* Converts an allocation size in bytes to size in zbud chunks */
-static int size_to_chunks(int size)
+static int size_to_chunks(size_t size)
 {
        return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT;
 }
@@ -247,7 +332,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
  * gfp arguments are invalid or -ENOMEM if the pool was unable to allocate
  * a new page.
  */
-int zbud_alloc(struct zbud_pool *pool, unsigned int size, gfp_t gfp,
+int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp,
                        unsigned long *handle)
 {
        int chunks, i, freechunks;
@@ -511,11 +596,20 @@ static int __init init_zbud(void)
        /* Make sure the zbud header will fit in one chunk */
        BUILD_BUG_ON(sizeof(struct zbud_header) > ZHDR_SIZE_ALIGNED);
        pr_info("loaded\n");
+
+#ifdef CONFIG_ZPOOL
+       zpool_register_driver(&zbud_zpool_driver);
+#endif
+
        return 0;
 }
 
 static void __exit exit_zbud(void)
 {
+#ifdef CONFIG_ZPOOL
+       zpool_unregister_driver(&zbud_zpool_driver);
+#endif
+
        pr_info("unloaded\n");
 }