|
@@ -10,6 +10,7 @@
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
* General Public License for more details.
|
|
|
*/
|
|
|
+#include <linux/device.h>
|
|
|
#include <linux/types.h>
|
|
|
#include <linux/io.h>
|
|
|
#include <linux/mm.h>
|
|
@@ -96,3 +97,41 @@ void memunmap(void *addr)
|
|
|
iounmap((void __iomem *) addr);
|
|
|
}
|
|
|
EXPORT_SYMBOL(memunmap);
|
|
|
+
|
|
|
+static void devm_memremap_release(struct device *dev, void *res)
|
|
|
+{
|
|
|
+ memunmap(res);
|
|
|
+}
|
|
|
+
|
|
|
+static int devm_memremap_match(struct device *dev, void *res, void *match_data)
|
|
|
+{
|
|
|
+ return *(void **)res == match_data;
|
|
|
+}
|
|
|
+
|
|
|
+void *devm_memremap(struct device *dev, resource_size_t offset,
|
|
|
+ size_t size, unsigned long flags)
|
|
|
+{
|
|
|
+ void **ptr, *addr;
|
|
|
+
|
|
|
+ ptr = devres_alloc(devm_memremap_release, sizeof(*ptr), GFP_KERNEL);
|
|
|
+ if (!ptr)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ addr = memremap(offset, size, flags);
|
|
|
+ if (addr) {
|
|
|
+ *ptr = addr;
|
|
|
+ devres_add(dev, ptr);
|
|
|
+ } else
|
|
|
+ devres_free(ptr);
|
|
|
+
|
|
|
+ return addr;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(devm_memremap);
|
|
|
+
|
|
|
+void devm_memunmap(struct device *dev, void *addr)
|
|
|
+{
|
|
|
+ WARN_ON(devres_destroy(dev, devm_memremap_release, devm_memremap_match,
|
|
|
+ addr));
|
|
|
+ memunmap(addr);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(devm_memunmap);
|