root/lib/devres.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. devm_ioremap_release
  2. devm_ioremap_match
  3. __devm_ioremap
  4. devm_ioremap
  5. devm_ioremap_uc
  6. devm_ioremap_nocache
  7. devm_ioremap_wc
  8. devm_iounmap
  9. devm_ioremap_resource
  10. devm_of_iomap
  11. devm_ioport_map_release
  12. devm_ioport_map_match
  13. devm_ioport_map
  14. devm_ioport_unmap
  15. pcim_iomap_release
  16. pcim_iomap_table
  17. pcim_iomap
  18. pcim_iounmap
  19. pcim_iomap_regions
  20. pcim_iomap_regions_request_all
  21. pcim_iounmap_regions

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/err.h>
   3 #include <linux/pci.h>
   4 #include <linux/io.h>
   5 #include <linux/gfp.h>
   6 #include <linux/export.h>
   7 #include <linux/of_address.h>
   8 
   9 enum devm_ioremap_type {
  10         DEVM_IOREMAP = 0,
  11         DEVM_IOREMAP_NC,
  12         DEVM_IOREMAP_UC,
  13         DEVM_IOREMAP_WC,
  14 };
  15 
  16 void devm_ioremap_release(struct device *dev, void *res)
  17 {
  18         iounmap(*(void __iomem **)res);
  19 }
  20 
  21 static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
  22 {
  23         return *(void **)res == match_data;
  24 }
  25 
  26 static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
  27                                     resource_size_t size,
  28                                     enum devm_ioremap_type type)
  29 {
  30         void __iomem **ptr, *addr = NULL;
  31 
  32         ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
  33         if (!ptr)
  34                 return NULL;
  35 
  36         switch (type) {
  37         case DEVM_IOREMAP:
  38                 addr = ioremap(offset, size);
  39                 break;
  40         case DEVM_IOREMAP_NC:
  41                 addr = ioremap_nocache(offset, size);
  42                 break;
  43         case DEVM_IOREMAP_UC:
  44                 addr = ioremap_uc(offset, size);
  45                 break;
  46         case DEVM_IOREMAP_WC:
  47                 addr = ioremap_wc(offset, size);
  48                 break;
  49         }
  50 
  51         if (addr) {
  52                 *ptr = addr;
  53                 devres_add(dev, ptr);
  54         } else
  55                 devres_free(ptr);
  56 
  57         return addr;
  58 }
  59 
  60 /**
  61  * devm_ioremap - Managed ioremap()
  62  * @dev: Generic device to remap IO address for
  63  * @offset: Resource address to map
  64  * @size: Size of map
  65  *
  66  * Managed ioremap().  Map is automatically unmapped on driver detach.
  67  */
  68 void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
  69                            resource_size_t size)
  70 {
  71         return __devm_ioremap(dev, offset, size, DEVM_IOREMAP);
  72 }
  73 EXPORT_SYMBOL(devm_ioremap);
  74 
  75 /**
  76  * devm_ioremap_uc - Managed ioremap_uc()
  77  * @dev: Generic device to remap IO address for
  78  * @offset: Resource address to map
  79  * @size: Size of map
  80  *
  81  * Managed ioremap_uc().  Map is automatically unmapped on driver detach.
  82  */
  83 void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset,
  84                               resource_size_t size)
  85 {
  86         return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_UC);
  87 }
  88 EXPORT_SYMBOL_GPL(devm_ioremap_uc);
  89 
  90 /**
  91  * devm_ioremap_nocache - Managed ioremap_nocache()
  92  * @dev: Generic device to remap IO address for
  93  * @offset: Resource address to map
  94  * @size: Size of map
  95  *
  96  * Managed ioremap_nocache().  Map is automatically unmapped on driver
  97  * detach.
  98  */
  99 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 100                                    resource_size_t size)
 101 {
 102         return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NC);
 103 }
 104 EXPORT_SYMBOL(devm_ioremap_nocache);
 105 
 106 /**
 107  * devm_ioremap_wc - Managed ioremap_wc()
 108  * @dev: Generic device to remap IO address for
 109  * @offset: Resource address to map
 110  * @size: Size of map
 111  *
 112  * Managed ioremap_wc().  Map is automatically unmapped on driver detach.
 113  */
 114 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
 115                               resource_size_t size)
 116 {
 117         return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_WC);
 118 }
 119 EXPORT_SYMBOL(devm_ioremap_wc);
 120 
 121 /**
 122  * devm_iounmap - Managed iounmap()
 123  * @dev: Generic device to unmap for
 124  * @addr: Address to unmap
 125  *
 126  * Managed iounmap().  @addr must have been mapped using devm_ioremap*().
 127  */
 128 void devm_iounmap(struct device *dev, void __iomem *addr)
 129 {
 130         WARN_ON(devres_destroy(dev, devm_ioremap_release, devm_ioremap_match,
 131                                (__force void *)addr));
 132         iounmap(addr);
 133 }
 134 EXPORT_SYMBOL(devm_iounmap);
 135 
 136 /**
 137  * devm_ioremap_resource() - check, request region, and ioremap resource
 138  * @dev: generic device to handle the resource for
 139  * @res: resource to be handled
 140  *
 141  * Checks that a resource is a valid memory region, requests the memory
 142  * region and ioremaps it. All operations are managed and will be undone
 143  * on driver detach.
 144  *
 145  * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
 146  * on failure. Usage example:
 147  *
 148  *      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 149  *      base = devm_ioremap_resource(&pdev->dev, res);
 150  *      if (IS_ERR(base))
 151  *              return PTR_ERR(base);
 152  */
 153 void __iomem *devm_ioremap_resource(struct device *dev,
 154                                     const struct resource *res)
 155 {
 156         resource_size_t size;
 157         void __iomem *dest_ptr;
 158 
 159         BUG_ON(!dev);
 160 
 161         if (!res || resource_type(res) != IORESOURCE_MEM) {
 162                 dev_err(dev, "invalid resource\n");
 163                 return IOMEM_ERR_PTR(-EINVAL);
 164         }
 165 
 166         size = resource_size(res);
 167 
 168         if (!devm_request_mem_region(dev, res->start, size, dev_name(dev))) {
 169                 dev_err(dev, "can't request region for resource %pR\n", res);
 170                 return IOMEM_ERR_PTR(-EBUSY);
 171         }
 172 
 173         dest_ptr = devm_ioremap(dev, res->start, size);
 174         if (!dest_ptr) {
 175                 dev_err(dev, "ioremap failed for resource %pR\n", res);
 176                 devm_release_mem_region(dev, res->start, size);
 177                 dest_ptr = IOMEM_ERR_PTR(-ENOMEM);
 178         }
 179 
 180         return dest_ptr;
 181 }
 182 EXPORT_SYMBOL(devm_ioremap_resource);
 183 
 184 /*
 185  * devm_of_iomap - Requests a resource and maps the memory mapped IO
 186  *                 for a given device_node managed by a given device
 187  *
 188  * Checks that a resource is a valid memory region, requests the memory
 189  * region and ioremaps it. All operations are managed and will be undone
 190  * on driver detach of the device.
 191  *
 192  * This is to be used when a device requests/maps resources described
 193  * by other device tree nodes (children or otherwise).
 194  *
 195  * @dev:        The device "managing" the resource
 196  * @node:       The device-tree node where the resource resides
 197  * @index:      index of the MMIO range in the "reg" property
 198  * @size:       Returns the size of the resource (pass NULL if not needed)
 199  * Returns a pointer to the requested and mapped memory or an ERR_PTR() encoded
 200  * error code on failure. Usage example:
 201  *
 202  *      base = devm_of_iomap(&pdev->dev, node, 0, NULL);
 203  *      if (IS_ERR(base))
 204  *              return PTR_ERR(base);
 205  */
 206 void __iomem *devm_of_iomap(struct device *dev, struct device_node *node, int index,
 207                             resource_size_t *size)
 208 {
 209         struct resource res;
 210 
 211         if (of_address_to_resource(node, index, &res))
 212                 return IOMEM_ERR_PTR(-EINVAL);
 213         if (size)
 214                 *size = resource_size(&res);
 215         return devm_ioremap_resource(dev, &res);
 216 }
 217 EXPORT_SYMBOL(devm_of_iomap);
 218 
 219 #ifdef CONFIG_HAS_IOPORT_MAP
 220 /*
 221  * Generic iomap devres
 222  */
 223 static void devm_ioport_map_release(struct device *dev, void *res)
 224 {
 225         ioport_unmap(*(void __iomem **)res);
 226 }
 227 
 228 static int devm_ioport_map_match(struct device *dev, void *res,
 229                                  void *match_data)
 230 {
 231         return *(void **)res == match_data;
 232 }
 233 
 234 /**
 235  * devm_ioport_map - Managed ioport_map()
 236  * @dev: Generic device to map ioport for
 237  * @port: Port to map
 238  * @nr: Number of ports to map
 239  *
 240  * Managed ioport_map().  Map is automatically unmapped on driver
 241  * detach.
 242  */
 243 void __iomem *devm_ioport_map(struct device *dev, unsigned long port,
 244                                unsigned int nr)
 245 {
 246         void __iomem **ptr, *addr;
 247 
 248         ptr = devres_alloc(devm_ioport_map_release, sizeof(*ptr), GFP_KERNEL);
 249         if (!ptr)
 250                 return NULL;
 251 
 252         addr = ioport_map(port, nr);
 253         if (addr) {
 254                 *ptr = addr;
 255                 devres_add(dev, ptr);
 256         } else
 257                 devres_free(ptr);
 258 
 259         return addr;
 260 }
 261 EXPORT_SYMBOL(devm_ioport_map);
 262 
 263 /**
 264  * devm_ioport_unmap - Managed ioport_unmap()
 265  * @dev: Generic device to unmap for
 266  * @addr: Address to unmap
 267  *
 268  * Managed ioport_unmap().  @addr must have been mapped using
 269  * devm_ioport_map().
 270  */
 271 void devm_ioport_unmap(struct device *dev, void __iomem *addr)
 272 {
 273         ioport_unmap(addr);
 274         WARN_ON(devres_destroy(dev, devm_ioport_map_release,
 275                                devm_ioport_map_match, (__force void *)addr));
 276 }
 277 EXPORT_SYMBOL(devm_ioport_unmap);
 278 #endif /* CONFIG_HAS_IOPORT_MAP */
 279 
 280 #ifdef CONFIG_PCI
 281 /*
 282  * PCI iomap devres
 283  */
 284 #define PCIM_IOMAP_MAX  PCI_ROM_RESOURCE
 285 
 286 struct pcim_iomap_devres {
 287         void __iomem *table[PCIM_IOMAP_MAX];
 288 };
 289 
 290 static void pcim_iomap_release(struct device *gendev, void *res)
 291 {
 292         struct pci_dev *dev = to_pci_dev(gendev);
 293         struct pcim_iomap_devres *this = res;
 294         int i;
 295 
 296         for (i = 0; i < PCIM_IOMAP_MAX; i++)
 297                 if (this->table[i])
 298                         pci_iounmap(dev, this->table[i]);
 299 }
 300 
 301 /**
 302  * pcim_iomap_table - access iomap allocation table
 303  * @pdev: PCI device to access iomap table for
 304  *
 305  * Access iomap allocation table for @dev.  If iomap table doesn't
 306  * exist and @pdev is managed, it will be allocated.  All iomaps
 307  * recorded in the iomap table are automatically unmapped on driver
 308  * detach.
 309  *
 310  * This function might sleep when the table is first allocated but can
 311  * be safely called without context and guaranteed to succed once
 312  * allocated.
 313  */
 314 void __iomem * const *pcim_iomap_table(struct pci_dev *pdev)
 315 {
 316         struct pcim_iomap_devres *dr, *new_dr;
 317 
 318         dr = devres_find(&pdev->dev, pcim_iomap_release, NULL, NULL);
 319         if (dr)
 320                 return dr->table;
 321 
 322         new_dr = devres_alloc(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL);
 323         if (!new_dr)
 324                 return NULL;
 325         dr = devres_get(&pdev->dev, new_dr, NULL, NULL);
 326         return dr->table;
 327 }
 328 EXPORT_SYMBOL(pcim_iomap_table);
 329 
 330 /**
 331  * pcim_iomap - Managed pcim_iomap()
 332  * @pdev: PCI device to iomap for
 333  * @bar: BAR to iomap
 334  * @maxlen: Maximum length of iomap
 335  *
 336  * Managed pci_iomap().  Map is automatically unmapped on driver
 337  * detach.
 338  */
 339 void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen)
 340 {
 341         void __iomem **tbl;
 342 
 343         BUG_ON(bar >= PCIM_IOMAP_MAX);
 344 
 345         tbl = (void __iomem **)pcim_iomap_table(pdev);
 346         if (!tbl || tbl[bar])   /* duplicate mappings not allowed */
 347                 return NULL;
 348 
 349         tbl[bar] = pci_iomap(pdev, bar, maxlen);
 350         return tbl[bar];
 351 }
 352 EXPORT_SYMBOL(pcim_iomap);
 353 
 354 /**
 355  * pcim_iounmap - Managed pci_iounmap()
 356  * @pdev: PCI device to iounmap for
 357  * @addr: Address to unmap
 358  *
 359  * Managed pci_iounmap().  @addr must have been mapped using pcim_iomap().
 360  */
 361 void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr)
 362 {
 363         void __iomem **tbl;
 364         int i;
 365 
 366         pci_iounmap(pdev, addr);
 367 
 368         tbl = (void __iomem **)pcim_iomap_table(pdev);
 369         BUG_ON(!tbl);
 370 
 371         for (i = 0; i < PCIM_IOMAP_MAX; i++)
 372                 if (tbl[i] == addr) {
 373                         tbl[i] = NULL;
 374                         return;
 375                 }
 376         WARN_ON(1);
 377 }
 378 EXPORT_SYMBOL(pcim_iounmap);
 379 
 380 /**
 381  * pcim_iomap_regions - Request and iomap PCI BARs
 382  * @pdev: PCI device to map IO resources for
 383  * @mask: Mask of BARs to request and iomap
 384  * @name: Name used when requesting regions
 385  *
 386  * Request and iomap regions specified by @mask.
 387  */
 388 int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
 389 {
 390         void __iomem * const *iomap;
 391         int i, rc;
 392 
 393         iomap = pcim_iomap_table(pdev);
 394         if (!iomap)
 395                 return -ENOMEM;
 396 
 397         for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
 398                 unsigned long len;
 399 
 400                 if (!(mask & (1 << i)))
 401                         continue;
 402 
 403                 rc = -EINVAL;
 404                 len = pci_resource_len(pdev, i);
 405                 if (!len)
 406                         goto err_inval;
 407 
 408                 rc = pci_request_region(pdev, i, name);
 409                 if (rc)
 410                         goto err_inval;
 411 
 412                 rc = -ENOMEM;
 413                 if (!pcim_iomap(pdev, i, 0))
 414                         goto err_region;
 415         }
 416 
 417         return 0;
 418 
 419  err_region:
 420         pci_release_region(pdev, i);
 421  err_inval:
 422         while (--i >= 0) {
 423                 if (!(mask & (1 << i)))
 424                         continue;
 425                 pcim_iounmap(pdev, iomap[i]);
 426                 pci_release_region(pdev, i);
 427         }
 428 
 429         return rc;
 430 }
 431 EXPORT_SYMBOL(pcim_iomap_regions);
 432 
 433 /**
 434  * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones
 435  * @pdev: PCI device to map IO resources for
 436  * @mask: Mask of BARs to iomap
 437  * @name: Name used when requesting regions
 438  *
 439  * Request all PCI BARs and iomap regions specified by @mask.
 440  */
 441 int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
 442                                    const char *name)
 443 {
 444         int request_mask = ((1 << 6) - 1) & ~mask;
 445         int rc;
 446 
 447         rc = pci_request_selected_regions(pdev, request_mask, name);
 448         if (rc)
 449                 return rc;
 450 
 451         rc = pcim_iomap_regions(pdev, mask, name);
 452         if (rc)
 453                 pci_release_selected_regions(pdev, request_mask);
 454         return rc;
 455 }
 456 EXPORT_SYMBOL(pcim_iomap_regions_request_all);
 457 
 458 /**
 459  * pcim_iounmap_regions - Unmap and release PCI BARs
 460  * @pdev: PCI device to map IO resources for
 461  * @mask: Mask of BARs to unmap and release
 462  *
 463  * Unmap and release regions specified by @mask.
 464  */
 465 void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
 466 {
 467         void __iomem * const *iomap;
 468         int i;
 469 
 470         iomap = pcim_iomap_table(pdev);
 471         if (!iomap)
 472                 return;
 473 
 474         for (i = 0; i < PCIM_IOMAP_MAX; i++) {
 475                 if (!(mask & (1 << i)))
 476                         continue;
 477 
 478                 pcim_iounmap(pdev, iomap[i]);
 479                 pci_release_region(pdev, i);
 480         }
 481 }
 482 EXPORT_SYMBOL(pcim_iounmap_regions);
 483 #endif /* CONFIG_PCI */

/* [<][>][^][v][top][bottom][index][help] */