diff options
-rw-r--r-- | target/linux/generic/patches-3.8/030-backport-lib-devres-Introduce-devm_ioremap_resource.patch | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.8/030-backport-lib-devres-Introduce-devm_ioremap_resource.patch b/target/linux/generic/patches-3.8/030-backport-lib-devres-Introduce-devm_ioremap_resource.patch new file mode 100644 index 000000000..b90222348 --- /dev/null +++ b/target/linux/generic/patches-3.8/030-backport-lib-devres-Introduce-devm_ioremap_resource.patch @@ -0,0 +1,251 @@ +From 75096579c3ac39ddc2f8b0d9a8924eba31f4d920 Mon Sep 17 00:00:00 2001 +From: Thierry Reding <thierry.reding@avionic-design.de> +Date: Mon, 21 Jan 2013 11:08:54 +0100 +Subject: [PATCH] lib: devres: Introduce devm_ioremap_resource() + +The devm_request_and_ioremap() function is very useful and helps avoid a +whole lot of boilerplate. However, one issue that keeps popping up is +its lack of a specific error code to determine which of the steps that +it performs failed. Furthermore, while the function gives an example and +suggests what error code to return on failure, a wide variety of error +codes are used throughout the tree. + +In an attempt to fix these problems, this patch adds a new function that +drivers can transition to. The devm_ioremap_resource() returns a pointer +to the remapped I/O memory on success or an ERR_PTR() encoded error code +on failure. Callers can check for failure using IS_ERR() and determine +its cause by extracting the error code using PTR_ERR(). + +devm_request_and_ioremap() is implemented as a wrapper around the new +API and return NULL on failure as before. This ensures that backwards +compatibility is maintained until all users have been converted to the +new API, at which point the old devm_request_and_ioremap() function +should be removed. + +A semantic patch is included which can be used to convert from the old +devm_request_and_ioremap() API to the new devm_ioremap_resource() API. +Some non-trivial cases may require manual intervention, though. + +Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> +Cc: Arnd Bergmann <arnd@arndb.de> +Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + Documentation/driver-model/devres.txt | 3 +- + include/linux/device.h | 1 + + lib/devres.c | 57 ++++++++++--- + scripts/coccinelle/api/devm_ioremap_resource.cocci | 90 ++++++++++++++++++++ + 4 files changed, 137 insertions(+), 14 deletions(-) + create mode 100644 scripts/coccinelle/api/devm_ioremap_resource.cocci + +--- a/Documentation/driver-model/devres.txt ++++ b/Documentation/driver-model/devres.txt +@@ -266,7 +266,8 @@ IOMAP + devm_ioremap() + devm_ioremap_nocache() + devm_iounmap() +- devm_request_and_ioremap() : checks resource, requests region, ioremaps ++ devm_ioremap_resource() : checks resource, requests memory region, ioremaps ++ devm_request_and_ioremap() : obsoleted by devm_ioremap_resource() + pcim_iomap() + pcim_iounmap() + pcim_iomap_table() : array of mapped addresses indexed by BAR +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -573,6 +573,7 @@ extern int devres_release_group(struct d + extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp); + extern void devm_kfree(struct device *dev, void *p); + ++void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); + void __iomem *devm_request_and_ioremap(struct device *dev, + struct resource *res); + +--- a/lib/devres.c ++++ b/lib/devres.c +@@ -86,22 +86,24 @@ void devm_iounmap(struct device *dev, vo + EXPORT_SYMBOL(devm_iounmap); + + /** +- * devm_request_and_ioremap() - Check, request region, and ioremap resource +- * @dev: Generic device to handle the resource for ++ * devm_ioremap_resource() - 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: ++ * Checks that a resource is a valid memory region, requests the memory region ++ * and ioremaps it either as cacheable or as non-cacheable memory depending on ++ * the resource's flags. All operations are managed and will be undone on ++ * driver detach. ++ * ++ * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code ++ * on failure. Usage example: + * + * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- * base = devm_request_and_ioremap(&pdev->dev, res); +- * if (!base) +- * return -EADDRNOTAVAIL; ++ * base = devm_ioremap_resource(&pdev->dev, res); ++ * if (IS_ERR(base)) ++ * return PTR_ERR(base); + */ +-void __iomem *devm_request_and_ioremap(struct device *dev, +- struct resource *res) ++void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) + { + resource_size_t size; + const char *name; +@@ -111,7 +113,7 @@ void __iomem *devm_request_and_ioremap(s + + if (!res || resource_type(res) != IORESOURCE_MEM) { + dev_err(dev, "invalid resource\n"); +- return NULL; ++ return ERR_PTR(-EINVAL); + } + + size = resource_size(res); +@@ -119,7 +121,7 @@ void __iomem *devm_request_and_ioremap(s + + if (!devm_request_mem_region(dev, res->start, size, name)) { + dev_err(dev, "can't request region for resource %pR\n", res); +- return NULL; ++ return ERR_PTR(-EBUSY); + } + + if (res->flags & IORESOURCE_CACHEABLE) +@@ -130,10 +132,39 @@ void __iomem *devm_request_and_ioremap(s + if (!dest_ptr) { + dev_err(dev, "ioremap failed for resource %pR\n", res); + devm_release_mem_region(dev, res->start, size); ++ dest_ptr = ERR_PTR(-ENOMEM); + } + + return dest_ptr; + } ++EXPORT_SYMBOL(devm_ioremap_resource); ++ ++/** ++ * 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 *device, ++ struct resource *res) ++{ ++ void __iomem *dest_ptr; ++ ++ dest_ptr = devm_ioremap_resource(device, res); ++ if (IS_ERR(dest_ptr)) ++ return NULL; ++ ++ return dest_ptr; ++} + EXPORT_SYMBOL(devm_request_and_ioremap); + + #ifdef CONFIG_HAS_IOPORT +--- /dev/null ++++ b/scripts/coccinelle/api/devm_ioremap_resource.cocci +@@ -0,0 +1,90 @@ ++virtual patch ++virtual report ++ ++@depends on patch@ ++expression base, dev, res; ++@@ ++ ++-base = devm_request_and_ioremap(dev, res); +++base = devm_ioremap_resource(dev, res); ++ ... ++ if ( ++-base == NULL +++IS_ERR(base) ++ || ...) { ++<... ++- return ...; +++ return PTR_ERR(base); ++...> ++ } ++ ++@depends on patch@ ++expression e, E, ret; ++identifier l; ++@@ ++ ++ e = devm_ioremap_resource(...); ++ ... ++ if (IS_ERR(e) || ...) { ++ ... when any ++- ret = E; +++ ret = PTR_ERR(e); ++ ... ++( ++ return ret; ++| ++ goto l; ++) ++ } ++ ++@depends on patch@ ++expression e; ++@@ ++ ++ e = devm_ioremap_resource(...); ++ ... ++ if (IS_ERR(e) || ...) { ++ ... ++- \(dev_dbg\|dev_err\|pr_debug\|pr_err\|DRM_ERROR\)(...); ++ ... ++ } ++ ++@depends on patch@ ++expression e; ++identifier l; ++@@ ++ ++ e = devm_ioremap_resource(...); ++ ... ++ if (IS_ERR(e) || ...) ++-{ ++( ++ return ...; ++| ++ goto l; ++) ++-} ++ ++@r depends on report@ ++expression e; ++identifier l; ++position p1; ++@@ ++ ++*e = devm_request_and_ioremap@p1(...); ++ ... ++ if (e == NULL || ...) { ++ ... ++( ++ return ...; ++| ++ goto l; ++) ++ } ++ ++@script:python depends on r@ ++p1 << r.p1; ++@@ ++ ++msg = "ERROR: deprecated devm_request_and_ioremap() API used on line %s" % (p1[0].line) ++coccilib.report.print_report(p1[0], msg) |