memremap: move dev_pagemap callbacks into a separate structure
[linux-2.6-microblaze.git] / drivers / nvdimm / pmem.c
index d9d8450..c2449af 100644 (file)
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /*
  * Persistent Memory Driver
  *
  * Copyright (c) 2014-2015, Intel Corporation.
  * Copyright (c) 2015, Christoph Hellwig <hch@lst.de>.
  * Copyright (c) 2015, Boaz Harrosh <boaz@plexistor.com>.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
  */
 
 #include <asm/cacheflush.h>
@@ -311,12 +303,20 @@ static const struct attribute_group *pmem_attribute_groups[] = {
        NULL,
 };
 
-static void pmem_release_queue(void *q)
+static void pmem_pagemap_cleanup(struct percpu_ref *ref)
 {
+       struct request_queue *q;
+
+       q = container_of(ref, typeof(*q), q_usage_counter);
        blk_cleanup_queue(q);
 }
 
-static void pmem_freeze_queue(struct percpu_ref *ref)
+static void pmem_release_queue(void *ref)
+{
+       pmem_pagemap_cleanup(ref);
+}
+
+static void pmem_pagemap_kill(struct percpu_ref *ref)
 {
        struct request_queue *q;
 
@@ -339,19 +339,24 @@ static void pmem_release_pgmap_ops(void *__pgmap)
        dev_pagemap_put_ops();
 }
 
-static void fsdax_pagefree(struct page *page, void *data)
+static void pmem_pagemap_page_free(struct page *page, void *data)
 {
        wake_up_var(&page->_refcount);
 }
 
+static const struct dev_pagemap_ops fsdax_pagemap_ops = {
+       .page_free              = pmem_pagemap_page_free,
+       .kill                   = pmem_pagemap_kill,
+       .cleanup                = pmem_pagemap_cleanup,
+};
+
 static int setup_pagemap_fsdax(struct device *dev, struct dev_pagemap *pgmap)
 {
        dev_pagemap_get_ops();
        if (devm_add_action_or_reset(dev, pmem_release_pgmap_ops, pgmap))
                return -ENOMEM;
        pgmap->type = MEMORY_DEVICE_FS_DAX;
-       pgmap->page_free = fsdax_pagefree;
-
+       pgmap->ops = &fsdax_pagemap_ops;
        return 0;
 }
 
@@ -407,12 +412,8 @@ static int pmem_attach_disk(struct device *dev,
        if (!q)
                return -ENOMEM;
 
-       if (devm_add_action_or_reset(dev, pmem_release_queue, q))
-               return -ENOMEM;
-
        pmem->pfn_flags = PFN_DEV;
        pmem->pgmap.ref = &q->q_usage_counter;
-       pmem->pgmap.kill = pmem_freeze_queue;
        if (is_nd_pfn(dev)) {
                if (setup_pagemap_fsdax(dev, &pmem->pgmap))
                        return -ENOMEM;
@@ -433,6 +434,9 @@ static int pmem_attach_disk(struct device *dev,
                pmem->pfn_flags |= PFN_MAP;
                memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
        } else {
+               if (devm_add_action_or_reset(dev, pmem_release_queue,
+                                       &q->q_usage_counter))
+                       return -ENOMEM;
                addr = devm_memremap(dev, pmem->phys_addr,
                                pmem->size, ARCH_MEMREMAP_PMEM);
                memcpy(&bb_res, &nsio->res, sizeof(bb_res));