diff options
Diffstat (limited to 'lib/devres.c')
| -rw-r--r-- | lib/devres.c | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/lib/devres.c b/lib/devres.c index 7c0e953a7486..9676617b4486 100644 --- a/lib/devres.c +++ b/lib/devres.c | |||
| @@ -85,6 +85,57 @@ void devm_iounmap(struct device *dev, void __iomem *addr) | |||
| 85 | } | 85 | } |
| 86 | EXPORT_SYMBOL(devm_iounmap); | 86 | EXPORT_SYMBOL(devm_iounmap); |
| 87 | 87 | ||
| 88 | /** | ||
| 89 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | ||
| 90 | * @dev: Generic device to handle the resource for | ||
| 91 | * @res: resource to be handled | ||
| 92 | * | ||
| 93 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | ||
| 94 | * everything is undone on driver detach. Checks arguments, so you can feed | ||
| 95 | * it the result from e.g. platform_get_resource() directly. Returns the | ||
| 96 | * remapped pointer or NULL on error. Usage example: | ||
| 97 | * | ||
| 98 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 99 | * base = devm_request_and_ioremap(&pdev->dev, res); | ||
| 100 | * if (!base) | ||
| 101 | * return -EADDRNOTAVAIL; | ||
| 102 | */ | ||
| 103 | void __iomem *devm_request_and_ioremap(struct device *dev, | ||
| 104 | struct resource *res) | ||
| 105 | { | ||
| 106 | resource_size_t size; | ||
| 107 | const char *name; | ||
| 108 | void __iomem *dest_ptr; | ||
| 109 | |||
| 110 | BUG_ON(!dev); | ||
| 111 | |||
| 112 | if (!res || resource_type(res) != IORESOURCE_MEM) { | ||
| 113 | dev_err(dev, "invalid resource\n"); | ||
| 114 | return NULL; | ||
| 115 | } | ||
| 116 | |||
| 117 | size = resource_size(res); | ||
| 118 | name = res->name ?: dev_name(dev); | ||
| 119 | |||
| 120 | if (!devm_request_mem_region(dev, res->start, size, name)) { | ||
| 121 | dev_err(dev, "can't request region for resource %pR\n", res); | ||
| 122 | return NULL; | ||
| 123 | } | ||
| 124 | |||
| 125 | if (res->flags & IORESOURCE_CACHEABLE) | ||
| 126 | dest_ptr = devm_ioremap(dev, res->start, size); | ||
| 127 | else | ||
| 128 | dest_ptr = devm_ioremap_nocache(dev, res->start, size); | ||
| 129 | |||
| 130 | if (!dest_ptr) { | ||
| 131 | dev_err(dev, "ioremap failed for resource %pR\n", res); | ||
| 132 | devm_release_mem_region(dev, res->start, size); | ||
| 133 | } | ||
| 134 | |||
| 135 | return dest_ptr; | ||
| 136 | } | ||
| 137 | EXPORT_SYMBOL(devm_request_and_ioremap); | ||
| 138 | |||
| 88 | #ifdef CONFIG_HAS_IOPORT | 139 | #ifdef CONFIG_HAS_IOPORT |
| 89 | /* | 140 | /* |
| 90 | * Generic iomap devres | 141 | * Generic iomap devres |
| @@ -253,7 +304,7 @@ EXPORT_SYMBOL(pcim_iounmap); | |||
| 253 | * | 304 | * |
| 254 | * Request and iomap regions specified by @mask. | 305 | * Request and iomap regions specified by @mask. |
| 255 | */ | 306 | */ |
| 256 | int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name) | 307 | int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name) |
| 257 | { | 308 | { |
| 258 | void __iomem * const *iomap; | 309 | void __iomem * const *iomap; |
| 259 | int i, rc; | 310 | int i, rc; |
| @@ -306,7 +357,7 @@ EXPORT_SYMBOL(pcim_iomap_regions); | |||
| 306 | * | 357 | * |
| 307 | * Request all PCI BARs and iomap regions specified by @mask. | 358 | * Request all PCI BARs and iomap regions specified by @mask. |
| 308 | */ | 359 | */ |
| 309 | int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask, | 360 | int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask, |
| 310 | const char *name) | 361 | const char *name) |
| 311 | { | 362 | { |
| 312 | int request_mask = ((1 << 6) - 1) & ~mask; | 363 | int request_mask = ((1 << 6) - 1) & ~mask; |
| @@ -330,7 +381,7 @@ EXPORT_SYMBOL(pcim_iomap_regions_request_all); | |||
| 330 | * | 381 | * |
| 331 | * Unmap and release regions specified by @mask. | 382 | * Unmap and release regions specified by @mask. |
| 332 | */ | 383 | */ |
| 333 | void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask) | 384 | void pcim_iounmap_regions(struct pci_dev *pdev, int mask) |
| 334 | { | 385 | { |
| 335 | void __iomem * const *iomap; | 386 | void __iomem * const *iomap; |
| 336 | int i; | 387 | int i; |
| @@ -348,5 +399,5 @@ void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask) | |||
| 348 | } | 399 | } |
| 349 | } | 400 | } |
| 350 | EXPORT_SYMBOL(pcim_iounmap_regions); | 401 | EXPORT_SYMBOL(pcim_iounmap_regions); |
| 351 | #endif | 402 | #endif /* CONFIG_PCI */ |
| 352 | #endif | 403 | #endif /* CONFIG_HAS_IOPORT */ |
