aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/region_devs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvdimm/region_devs.c')
-rw-r--r--drivers/nvdimm/region_devs.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index e8d5ba7b29af..4c0ac4abb629 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -38,7 +38,7 @@ static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm,
38 38
39 dev_dbg(dev, "%s: map %d flush address%s\n", nvdimm_name(nvdimm), 39 dev_dbg(dev, "%s: map %d flush address%s\n", nvdimm_name(nvdimm),
40 nvdimm->num_flush, nvdimm->num_flush == 1 ? "" : "es"); 40 nvdimm->num_flush, nvdimm->num_flush == 1 ? "" : "es");
41 for (i = 0; i < nvdimm->num_flush; i++) { 41 for (i = 0; i < (1 << ndrd->hints_shift); i++) {
42 struct resource *res = &nvdimm->flush_wpq[i]; 42 struct resource *res = &nvdimm->flush_wpq[i];
43 unsigned long pfn = PHYS_PFN(res->start); 43 unsigned long pfn = PHYS_PFN(res->start);
44 void __iomem *flush_page; 44 void __iomem *flush_page;
@@ -54,14 +54,15 @@ static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm,
54 54
55 if (j < i) 55 if (j < i)
56 flush_page = (void __iomem *) ((unsigned long) 56 flush_page = (void __iomem *) ((unsigned long)
57 ndrd->flush_wpq[dimm][j] & PAGE_MASK); 57 ndrd_get_flush_wpq(ndrd, dimm, j)
58 & PAGE_MASK);
58 else 59 else
59 flush_page = devm_nvdimm_ioremap(dev, 60 flush_page = devm_nvdimm_ioremap(dev,
60 PHYS_PFN(pfn), PAGE_SIZE); 61 PFN_PHYS(pfn), PAGE_SIZE);
61 if (!flush_page) 62 if (!flush_page)
62 return -ENXIO; 63 return -ENXIO;
63 ndrd->flush_wpq[dimm][i] = flush_page 64 ndrd_set_flush_wpq(ndrd, dimm, i, flush_page
64 + (res->start & ~PAGE_MASK); 65 + (res->start & ~PAGE_MASK));
65 } 66 }
66 67
67 return 0; 68 return 0;
@@ -93,7 +94,10 @@ int nd_region_activate(struct nd_region *nd_region)
93 return -ENOMEM; 94 return -ENOMEM;
94 dev_set_drvdata(dev, ndrd); 95 dev_set_drvdata(dev, ndrd);
95 96
96 ndrd->flush_mask = (1 << ilog2(num_flush)) - 1; 97 if (!num_flush)
98 return 0;
99
100 ndrd->hints_shift = ilog2(num_flush);
97 for (i = 0; i < nd_region->ndr_mappings; i++) { 101 for (i = 0; i < nd_region->ndr_mappings; i++) {
98 struct nd_mapping *nd_mapping = &nd_region->mapping[i]; 102 struct nd_mapping *nd_mapping = &nd_region->mapping[i];
99 struct nvdimm *nvdimm = nd_mapping->nvdimm; 103 struct nvdimm *nvdimm = nd_mapping->nvdimm;
@@ -900,8 +904,8 @@ void nvdimm_flush(struct nd_region *nd_region)
900 */ 904 */
901 wmb(); 905 wmb();
902 for (i = 0; i < nd_region->ndr_mappings; i++) 906 for (i = 0; i < nd_region->ndr_mappings; i++)
903 if (ndrd->flush_wpq[i][0]) 907 if (ndrd_get_flush_wpq(ndrd, i, 0))
904 writeq(1, ndrd->flush_wpq[i][idx & ndrd->flush_mask]); 908 writeq(1, ndrd_get_flush_wpq(ndrd, i, idx));
905 wmb(); 909 wmb();
906} 910}
907EXPORT_SYMBOL_GPL(nvdimm_flush); 911EXPORT_SYMBOL_GPL(nvdimm_flush);
@@ -925,7 +929,7 @@ int nvdimm_has_flush(struct nd_region *nd_region)
925 929
926 for (i = 0; i < nd_region->ndr_mappings; i++) 930 for (i = 0; i < nd_region->ndr_mappings; i++)
927 /* flush hints present, flushing required */ 931 /* flush hints present, flushing required */
928 if (ndrd->flush_wpq[i][0]) 932 if (ndrd_get_flush_wpq(ndrd, i, 0))
929 return 1; 933 return 1;
930 934
931 /* 935 /*