summaryrefslogtreecommitdiffstats
path: root/lib/devres.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-01-12 11:53:55 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-01-12 11:53:55 -0500
commitd3b7737f2b70ed2fb7cef985e70d04fb5dee7b7c (patch)
tree190e42f90d152ebad1c077809422c366cdf0577b /lib/devres.c
parentdc6821e0cfe74802aefd2067b40fcdc03fc4599e (diff)
parent070680218379e15c1901f4bf21b98e3cbf12b527 (diff)
Merge commit '070680218379e15c1901f4bf21b98e3cbf12b527' into stable/for-linus-fixes-3.3
* commit '070680218379e15c1901f4bf21b98e3cbf12b527': (50 commits) xen-balloon: convert sysdev_class to a regular subsystem clocksource: convert sysdev_class to a regular subsystem ibm_rtl: convert sysdev_class to a regular subsystem edac: convert sysdev_class to a regular subsystem rtmutex-tester: convert sysdev_class to a regular subsystem driver-core: implement 'sysdev' functionality for regular devices and buses kref: fix up the kfree build problems kref: Remove the memory barriers kref: Implement kref_put in terms of kref_sub kref: Inline all functions Drivers: hv: Get rid of an unnecessary check in hv.c Drivers: hv: Make the vmbus driver unloadable Drivers: hv: Fix a memory leak Documentation: Update stable address MAINTAINERS: stable: Update address w1: add fast search for single slave bus driver-core: skip uevent generation when nobody is listening drivers: hv: Don't OOPS when you cannot init vmbus firmware: google: fix gsmi.c build warning drivers_base: make argument to platform_device_register_full const ...
Diffstat (limited to 'lib/devres.c')
-rw-r--r--lib/devres.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/lib/devres.c b/lib/devres.c
index 7c0e953a748..4fbc09e6e9e 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -85,6 +85,57 @@ void devm_iounmap(struct device *dev, void __iomem *addr)
}
EXPORT_SYMBOL(devm_iounmap);
+/**
+ * devm_request_and_ioremap() - Check, request region, and ioremap resource
+ * @dev: Generic device to handle the resource for
+ * @res: resource to be handled
+ *
+ * Takes all necessary steps to ioremap a mem resource. Uses managed device, so
+ * everything is undone on driver detach. Checks arguments, so you can feed
+ * it the result from e.g. platform_get_resource() directly. Returns the
+ * remapped pointer or NULL on error. Usage example:
+ *
+ * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ * base = devm_request_and_ioremap(&pdev->dev, res);
+ * if (!base)
+ * return -EADDRNOTAVAIL;
+ */
+void __iomem *devm_request_and_ioremap(struct device *dev,
+ struct resource *res)
+{
+ resource_size_t size;
+ const char *name;
+ void __iomem *dest_ptr;
+
+ BUG_ON(!dev);
+
+ if (!res || resource_type(res) != IORESOURCE_MEM) {
+ dev_err(dev, "invalid resource\n");
+ return NULL;
+ }
+
+ size = resource_size(res);
+ name = res->name ?: dev_name(dev);
+
+ if (!devm_request_mem_region(dev, res->start, size, name)) {
+ dev_err(dev, "can't request region for resource %pR\n", res);
+ return NULL;
+ }
+
+ if (res->flags & IORESOURCE_CACHEABLE)
+ dest_ptr = devm_ioremap(dev, res->start, size);
+ else
+ dest_ptr = devm_ioremap_nocache(dev, res->start, size);
+
+ if (!dest_ptr) {
+ dev_err(dev, "ioremap failed for resource %pR\n", res);
+ devm_release_mem_region(dev, res->start, size);
+ }
+
+ return dest_ptr;
+}
+EXPORT_SYMBOL(devm_request_and_ioremap);
+
#ifdef CONFIG_HAS_IOPORT
/*
* Generic iomap devres
@@ -348,5 +399,5 @@ void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask)
}
}
EXPORT_SYMBOL(pcim_iounmap_regions);
-#endif
-#endif
+#endif /* CONFIG_PCI */
+#endif /* CONFIG_HAS_IOPORT */