pmem: convert to generic memremap
[firefly-linux-kernel-4.4.55.git] / include / linux / pmem.h
1 /*
2  * Copyright(c) 2015 Intel Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  */
13 #ifndef __PMEM_H__
14 #define __PMEM_H__
15
16 #include <linux/io.h>
17
18 #ifdef CONFIG_ARCH_HAS_PMEM_API
19 #include <asm/cacheflush.h>
20 #else
21 static inline void arch_wmb_pmem(void)
22 {
23         BUG();
24 }
25
26 static inline bool __arch_has_wmb_pmem(void)
27 {
28         return false;
29 }
30
31 static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
32                 size_t n)
33 {
34         BUG();
35 }
36 #endif
37
38 /*
39  * Architectures that define ARCH_HAS_PMEM_API must provide
40  * implementations for arch_memcpy_to_pmem(), arch_wmb_pmem(), and
41  * __arch_has_wmb_pmem().
42  */
43
44 static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
45 {
46         memcpy(dst, (void __force const *) src, size);
47 }
48
49 static inline void memunmap_pmem(void __pmem *addr)
50 {
51         memunmap((void __force *) addr);
52 }
53
54 /**
55  * arch_has_wmb_pmem - true if wmb_pmem() ensures durability
56  *
57  * For a given cpu implementation within an architecture it is possible
58  * that wmb_pmem() resolves to a nop.  In the case this returns
59  * false, pmem api users are unable to ensure durability and may want to
60  * fall back to a different data consistency model, or otherwise notify
61  * the user.
62  */
63 static inline bool arch_has_wmb_pmem(void)
64 {
65         if (IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API))
66                 return __arch_has_wmb_pmem();
67         return false;
68 }
69
70 static inline bool arch_has_pmem_api(void)
71 {
72         return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API) && arch_has_wmb_pmem();
73 }
74
75 /*
76  * These defaults seek to offer decent performance and minimize the
77  * window between i/o completion and writes being durable on media.
78  * However, it is undefined / architecture specific whether
79  * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
80  * making data durable relative to i/o completion.
81  */
82 static inline void default_memcpy_to_pmem(void __pmem *dst, const void *src,
83                 size_t size)
84 {
85         memcpy((void __force *) dst, src, size);
86 }
87
88 /**
89  * memremap_pmem - map physical persistent memory for pmem api
90  * @offset: physical address of persistent memory
91  * @size: size of the mapping
92  *
93  * Establish a mapping of the architecture specific memory type expected
94  * by memcpy_to_pmem() and wmb_pmem().  For example, it may be
95  * the case that an uncacheable or writethrough mapping is sufficient,
96  * or a writeback mapping provided memcpy_to_pmem() and
97  * wmb_pmem() arrange for the data to be written through the
98  * cache to persistent media.
99  */
100 static inline void __pmem *memremap_pmem(resource_size_t offset,
101                 unsigned long size)
102 {
103 #ifdef ARCH_MEMREMAP_PMEM
104         return (void __pmem *) memremap(offset, size, ARCH_MEMREMAP_PMEM);
105 #else
106         return (void __pmem *) memremap(offset, size, MEMREMAP_WT);
107 #endif
108 }
109
110 /**
111  * memcpy_to_pmem - copy data to persistent memory
112  * @dst: destination buffer for the copy
113  * @src: source buffer for the copy
114  * @n: length of the copy in bytes
115  *
116  * Perform a memory copy that results in the destination of the copy
117  * being effectively evicted from, or never written to, the processor
118  * cache hierarchy after the copy completes.  After memcpy_to_pmem()
119  * data may still reside in cpu or platform buffers, so this operation
120  * must be followed by a wmb_pmem().
121  */
122 static inline void memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
123 {
124         if (arch_has_pmem_api())
125                 arch_memcpy_to_pmem(dst, src, n);
126         else
127                 default_memcpy_to_pmem(dst, src, n);
128 }
129
130 /**
131  * wmb_pmem - synchronize writes to persistent memory
132  *
133  * After a series of memcpy_to_pmem() operations this drains data from
134  * cpu write buffers and any platform (memory controller) buffers to
135  * ensure that written data is durable on persistent memory media.
136  */
137 static inline void wmb_pmem(void)
138 {
139         if (arch_has_pmem_api())
140                 arch_wmb_pmem();
141 }
142 #endif /* __PMEM_H__ */