diff options
Diffstat (limited to 'lib/devres.c')
-rw-r--r-- | lib/devres.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/lib/devres.c b/lib/devres.c index 80b9c76d436a..88ad75952a76 100644 --- a/lib/devres.c +++ b/lib/devres.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/err.h> | ||
1 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
2 | #include <linux/io.h> | 3 | #include <linux/io.h> |
3 | #include <linux/gfp.h> | 4 | #include <linux/gfp.h> |
@@ -86,22 +87,24 @@ void devm_iounmap(struct device *dev, void __iomem *addr) | |||
86 | EXPORT_SYMBOL(devm_iounmap); | 87 | EXPORT_SYMBOL(devm_iounmap); |
87 | 88 | ||
88 | /** | 89 | /** |
89 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | 90 | * devm_ioremap_resource() - check, request region, and ioremap resource |
90 | * @dev: Generic device to handle the resource for | 91 | * @dev: generic device to handle the resource for |
91 | * @res: resource to be handled | 92 | * @res: resource to be handled |
92 | * | 93 | * |
93 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | 94 | * Checks that a resource is a valid memory region, requests the memory region |
94 | * everything is undone on driver detach. Checks arguments, so you can feed | 95 | * and ioremaps it either as cacheable or as non-cacheable memory depending on |
95 | * it the result from e.g. platform_get_resource() directly. Returns the | 96 | * the resource's flags. All operations are managed and will be undone on |
96 | * remapped pointer or NULL on error. Usage example: | 97 | * driver detach. |
98 | * | ||
99 | * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code | ||
100 | * on failure. Usage example: | ||
97 | * | 101 | * |
98 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 102 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
99 | * base = devm_request_and_ioremap(&pdev->dev, res); | 103 | * base = devm_ioremap_resource(&pdev->dev, res); |
100 | * if (!base) | 104 | * if (IS_ERR(base)) |
101 | * return -EADDRNOTAVAIL; | 105 | * return PTR_ERR(base); |
102 | */ | 106 | */ |
103 | void __iomem *devm_request_and_ioremap(struct device *dev, | 107 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) |
104 | struct resource *res) | ||
105 | { | 108 | { |
106 | resource_size_t size; | 109 | resource_size_t size; |
107 | const char *name; | 110 | const char *name; |
@@ -111,7 +114,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
111 | 114 | ||
112 | if (!res || resource_type(res) != IORESOURCE_MEM) { | 115 | if (!res || resource_type(res) != IORESOURCE_MEM) { |
113 | dev_err(dev, "invalid resource\n"); | 116 | dev_err(dev, "invalid resource\n"); |
114 | return NULL; | 117 | return ERR_PTR(-EINVAL); |
115 | } | 118 | } |
116 | 119 | ||
117 | size = resource_size(res); | 120 | size = resource_size(res); |
@@ -119,7 +122,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
119 | 122 | ||
120 | if (!devm_request_mem_region(dev, res->start, size, name)) { | 123 | if (!devm_request_mem_region(dev, res->start, size, name)) { |
121 | dev_err(dev, "can't request region for resource %pR\n", res); | 124 | dev_err(dev, "can't request region for resource %pR\n", res); |
122 | return NULL; | 125 | return ERR_PTR(-EBUSY); |
123 | } | 126 | } |
124 | 127 | ||
125 | if (res->flags & IORESOURCE_CACHEABLE) | 128 | if (res->flags & IORESOURCE_CACHEABLE) |
@@ -130,10 +133,39 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
130 | if (!dest_ptr) { | 133 | if (!dest_ptr) { |
131 | dev_err(dev, "ioremap failed for resource %pR\n", res); | 134 | dev_err(dev, "ioremap failed for resource %pR\n", res); |
132 | devm_release_mem_region(dev, res->start, size); | 135 | devm_release_mem_region(dev, res->start, size); |
136 | dest_ptr = ERR_PTR(-ENOMEM); | ||
133 | } | 137 | } |
134 | 138 | ||
135 | return dest_ptr; | 139 | return dest_ptr; |
136 | } | 140 | } |
141 | EXPORT_SYMBOL(devm_ioremap_resource); | ||
142 | |||
143 | /** | ||
144 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | ||
145 | * @dev: Generic device to handle the resource for | ||
146 | * @res: resource to be handled | ||
147 | * | ||
148 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | ||
149 | * everything is undone on driver detach. Checks arguments, so you can feed | ||
150 | * it the result from e.g. platform_get_resource() directly. Returns the | ||
151 | * remapped pointer or NULL on error. Usage example: | ||
152 | * | ||
153 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
154 | * base = devm_request_and_ioremap(&pdev->dev, res); | ||
155 | * if (!base) | ||
156 | * return -EADDRNOTAVAIL; | ||
157 | */ | ||
158 | void __iomem *devm_request_and_ioremap(struct device *device, | ||
159 | struct resource *res) | ||
160 | { | ||
161 | void __iomem *dest_ptr; | ||
162 | |||
163 | dest_ptr = devm_ioremap_resource(device, res); | ||
164 | if (IS_ERR(dest_ptr)) | ||
165 | return NULL; | ||
166 | |||
167 | return dest_ptr; | ||
168 | } | ||
137 | EXPORT_SYMBOL(devm_request_and_ioremap); | 169 | EXPORT_SYMBOL(devm_request_and_ioremap); |
138 | 170 | ||
139 | #ifdef CONFIG_HAS_IOPORT | 171 | #ifdef CONFIG_HAS_IOPORT |