Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: Move PCI-specific devres code to drivers/pci/

The pcim_*() functions in lib/devres.c are guarded by an #ifdef CONFIG_PCI
and, thus, don't belong to this file. They are only ever used for PCI and
are not generic infrastructure.

Move all pcim_*() functions in lib/devres.c to drivers/pci/devres.c.
Adjust the Makefile.

Add drivers/pci/devres.c to Documentation.

Link: https://lore.kernel.org/r/20240131090023.12331-4-pstanner@redhat.com
Suggested-by: Danilo Krummrich <dakr@redhat.com>
Signed-off-by: Philipp Stanner <pstanner@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

authored by

Philipp Stanner and committed by
Bjorn Helgaas
acc2364f ae874027

+212 -208
+3
Documentation/driver-api/pci/pci.rst
··· 7 7 .. kernel-doc:: drivers/pci/iomap.c 8 8 :export: 9 9 10 + .. kernel-doc:: drivers/pci/devres.c 11 + :export: 12 + 10 13 .. kernel-doc:: drivers/pci/pci-driver.c 11 14 :export: 12 15
+1 -1
drivers/pci/Makefile
··· 5 5 obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o \ 6 6 remove.o pci.o pci-driver.o search.o \ 7 7 pci-sysfs.o rom.o setup-res.o irq.o vpd.o \ 8 - setup-bus.o vc.o mmap.o setup-irq.o 8 + setup-bus.o vc.o mmap.o setup-irq.o devres.o 9 9 10 10 obj-$(CONFIG_PCI) += msi/ 11 11 obj-$(CONFIG_PCI) += pcie/
+207
drivers/pci/devres.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/pci.h> 3 + #include "pci.h" 4 + 5 + /* 6 + * PCI iomap devres 7 + */ 8 + #define PCIM_IOMAP_MAX PCI_STD_NUM_BARS 9 + 10 + struct pcim_iomap_devres { 11 + void __iomem *table[PCIM_IOMAP_MAX]; 12 + }; 13 + 14 + static void pcim_iomap_release(struct device *gendev, void *res) 15 + { 16 + struct pci_dev *dev = to_pci_dev(gendev); 17 + struct pcim_iomap_devres *this = res; 18 + int i; 19 + 20 + for (i = 0; i < PCIM_IOMAP_MAX; i++) 21 + if (this->table[i]) 22 + pci_iounmap(dev, this->table[i]); 23 + } 24 + 25 + /** 26 + * pcim_iomap_table - access iomap allocation table 27 + * @pdev: PCI device to access iomap table for 28 + * 29 + * Access iomap allocation table for @dev. If iomap table doesn't 30 + * exist and @pdev is managed, it will be allocated. All iomaps 31 + * recorded in the iomap table are automatically unmapped on driver 32 + * detach. 33 + * 34 + * This function might sleep when the table is first allocated but can 35 + * be safely called without context and guaranteed to succeed once 36 + * allocated. 37 + */ 38 + void __iomem * const *pcim_iomap_table(struct pci_dev *pdev) 39 + { 40 + struct pcim_iomap_devres *dr, *new_dr; 41 + 42 + dr = devres_find(&pdev->dev, pcim_iomap_release, NULL, NULL); 43 + if (dr) 44 + return dr->table; 45 + 46 + new_dr = devres_alloc_node(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL, 47 + dev_to_node(&pdev->dev)); 48 + if (!new_dr) 49 + return NULL; 50 + dr = devres_get(&pdev->dev, new_dr, NULL, NULL); 51 + return dr->table; 52 + } 53 + EXPORT_SYMBOL(pcim_iomap_table); 54 + 55 + /** 56 + * pcim_iomap - Managed pcim_iomap() 57 + * @pdev: PCI device to iomap for 58 + * @bar: BAR to iomap 59 + * @maxlen: Maximum length of iomap 60 + * 61 + * Managed pci_iomap(). Map is automatically unmapped on driver 62 + * detach. 63 + */ 64 + void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen) 65 + { 66 + void __iomem **tbl; 67 + 68 + BUG_ON(bar >= PCIM_IOMAP_MAX); 69 + 70 + tbl = (void __iomem **)pcim_iomap_table(pdev); 71 + if (!tbl || tbl[bar]) /* duplicate mappings not allowed */ 72 + return NULL; 73 + 74 + tbl[bar] = pci_iomap(pdev, bar, maxlen); 75 + return tbl[bar]; 76 + } 77 + EXPORT_SYMBOL(pcim_iomap); 78 + 79 + /** 80 + * pcim_iounmap - Managed pci_iounmap() 81 + * @pdev: PCI device to iounmap for 82 + * @addr: Address to unmap 83 + * 84 + * Managed pci_iounmap(). @addr must have been mapped using pcim_iomap(). 85 + */ 86 + void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr) 87 + { 88 + void __iomem **tbl; 89 + int i; 90 + 91 + pci_iounmap(pdev, addr); 92 + 93 + tbl = (void __iomem **)pcim_iomap_table(pdev); 94 + BUG_ON(!tbl); 95 + 96 + for (i = 0; i < PCIM_IOMAP_MAX; i++) 97 + if (tbl[i] == addr) { 98 + tbl[i] = NULL; 99 + return; 100 + } 101 + WARN_ON(1); 102 + } 103 + EXPORT_SYMBOL(pcim_iounmap); 104 + 105 + /** 106 + * pcim_iomap_regions - Request and iomap PCI BARs 107 + * @pdev: PCI device to map IO resources for 108 + * @mask: Mask of BARs to request and iomap 109 + * @name: Name used when requesting regions 110 + * 111 + * Request and iomap regions specified by @mask. 112 + */ 113 + int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name) 114 + { 115 + void __iomem * const *iomap; 116 + int i, rc; 117 + 118 + iomap = pcim_iomap_table(pdev); 119 + if (!iomap) 120 + return -ENOMEM; 121 + 122 + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 123 + unsigned long len; 124 + 125 + if (!(mask & (1 << i))) 126 + continue; 127 + 128 + rc = -EINVAL; 129 + len = pci_resource_len(pdev, i); 130 + if (!len) 131 + goto err_inval; 132 + 133 + rc = pci_request_region(pdev, i, name); 134 + if (rc) 135 + goto err_inval; 136 + 137 + rc = -ENOMEM; 138 + if (!pcim_iomap(pdev, i, 0)) 139 + goto err_region; 140 + } 141 + 142 + return 0; 143 + 144 + err_region: 145 + pci_release_region(pdev, i); 146 + err_inval: 147 + while (--i >= 0) { 148 + if (!(mask & (1 << i))) 149 + continue; 150 + pcim_iounmap(pdev, iomap[i]); 151 + pci_release_region(pdev, i); 152 + } 153 + 154 + return rc; 155 + } 156 + EXPORT_SYMBOL(pcim_iomap_regions); 157 + 158 + /** 159 + * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones 160 + * @pdev: PCI device to map IO resources for 161 + * @mask: Mask of BARs to iomap 162 + * @name: Name used when requesting regions 163 + * 164 + * Request all PCI BARs and iomap regions specified by @mask. 165 + */ 166 + int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask, 167 + const char *name) 168 + { 169 + int request_mask = ((1 << 6) - 1) & ~mask; 170 + int rc; 171 + 172 + rc = pci_request_selected_regions(pdev, request_mask, name); 173 + if (rc) 174 + return rc; 175 + 176 + rc = pcim_iomap_regions(pdev, mask, name); 177 + if (rc) 178 + pci_release_selected_regions(pdev, request_mask); 179 + return rc; 180 + } 181 + EXPORT_SYMBOL(pcim_iomap_regions_request_all); 182 + 183 + /** 184 + * pcim_iounmap_regions - Unmap and release PCI BARs 185 + * @pdev: PCI device to map IO resources for 186 + * @mask: Mask of BARs to unmap and release 187 + * 188 + * Unmap and release regions specified by @mask. 189 + */ 190 + void pcim_iounmap_regions(struct pci_dev *pdev, int mask) 191 + { 192 + void __iomem * const *iomap; 193 + int i; 194 + 195 + iomap = pcim_iomap_table(pdev); 196 + if (!iomap) 197 + return; 198 + 199 + for (i = 0; i < PCIM_IOMAP_MAX; i++) { 200 + if (!(mask & (1 << i))) 201 + continue; 202 + 203 + pcim_iounmap(pdev, iomap[i]); 204 + pci_release_region(pdev, i); 205 + } 206 + } 207 + EXPORT_SYMBOL(pcim_iounmap_regions);
+1 -207
lib/devres.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/device.h> 2 3 #include <linux/err.h> 3 - #include <linux/pci.h> 4 4 #include <linux/io.h> 5 5 #include <linux/gfp.h> 6 6 #include <linux/export.h> ··· 310 310 } 311 311 EXPORT_SYMBOL(devm_ioport_unmap); 312 312 #endif /* CONFIG_HAS_IOPORT_MAP */ 313 - 314 - #ifdef CONFIG_PCI 315 - /* 316 - * PCI iomap devres 317 - */ 318 - #define PCIM_IOMAP_MAX PCI_STD_NUM_BARS 319 - 320 - struct pcim_iomap_devres { 321 - void __iomem *table[PCIM_IOMAP_MAX]; 322 - }; 323 - 324 - static void pcim_iomap_release(struct device *gendev, void *res) 325 - { 326 - struct pci_dev *dev = to_pci_dev(gendev); 327 - struct pcim_iomap_devres *this = res; 328 - int i; 329 - 330 - for (i = 0; i < PCIM_IOMAP_MAX; i++) 331 - if (this->table[i]) 332 - pci_iounmap(dev, this->table[i]); 333 - } 334 - 335 - /** 336 - * pcim_iomap_table - access iomap allocation table 337 - * @pdev: PCI device to access iomap table for 338 - * 339 - * Access iomap allocation table for @dev. If iomap table doesn't 340 - * exist and @pdev is managed, it will be allocated. All iomaps 341 - * recorded in the iomap table are automatically unmapped on driver 342 - * detach. 343 - * 344 - * This function might sleep when the table is first allocated but can 345 - * be safely called without context and guaranteed to succeed once 346 - * allocated. 347 - */ 348 - void __iomem * const *pcim_iomap_table(struct pci_dev *pdev) 349 - { 350 - struct pcim_iomap_devres *dr, *new_dr; 351 - 352 - dr = devres_find(&pdev->dev, pcim_iomap_release, NULL, NULL); 353 - if (dr) 354 - return dr->table; 355 - 356 - new_dr = devres_alloc_node(pcim_iomap_release, sizeof(*new_dr), GFP_KERNEL, 357 - dev_to_node(&pdev->dev)); 358 - if (!new_dr) 359 - return NULL; 360 - dr = devres_get(&pdev->dev, new_dr, NULL, NULL); 361 - return dr->table; 362 - } 363 - EXPORT_SYMBOL(pcim_iomap_table); 364 - 365 - /** 366 - * pcim_iomap - Managed pcim_iomap() 367 - * @pdev: PCI device to iomap for 368 - * @bar: BAR to iomap 369 - * @maxlen: Maximum length of iomap 370 - * 371 - * Managed pci_iomap(). Map is automatically unmapped on driver 372 - * detach. 373 - */ 374 - void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen) 375 - { 376 - void __iomem **tbl; 377 - 378 - BUG_ON(bar >= PCIM_IOMAP_MAX); 379 - 380 - tbl = (void __iomem **)pcim_iomap_table(pdev); 381 - if (!tbl || tbl[bar]) /* duplicate mappings not allowed */ 382 - return NULL; 383 - 384 - tbl[bar] = pci_iomap(pdev, bar, maxlen); 385 - return tbl[bar]; 386 - } 387 - EXPORT_SYMBOL(pcim_iomap); 388 - 389 - /** 390 - * pcim_iounmap - Managed pci_iounmap() 391 - * @pdev: PCI device to iounmap for 392 - * @addr: Address to unmap 393 - * 394 - * Managed pci_iounmap(). @addr must have been mapped using pcim_iomap(). 395 - */ 396 - void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr) 397 - { 398 - void __iomem **tbl; 399 - int i; 400 - 401 - pci_iounmap(pdev, addr); 402 - 403 - tbl = (void __iomem **)pcim_iomap_table(pdev); 404 - BUG_ON(!tbl); 405 - 406 - for (i = 0; i < PCIM_IOMAP_MAX; i++) 407 - if (tbl[i] == addr) { 408 - tbl[i] = NULL; 409 - return; 410 - } 411 - WARN_ON(1); 412 - } 413 - EXPORT_SYMBOL(pcim_iounmap); 414 - 415 - /** 416 - * pcim_iomap_regions - Request and iomap PCI BARs 417 - * @pdev: PCI device to map IO resources for 418 - * @mask: Mask of BARs to request and iomap 419 - * @name: Name used when requesting regions 420 - * 421 - * Request and iomap regions specified by @mask. 422 - */ 423 - int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name) 424 - { 425 - void __iomem * const *iomap; 426 - int i, rc; 427 - 428 - iomap = pcim_iomap_table(pdev); 429 - if (!iomap) 430 - return -ENOMEM; 431 - 432 - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 433 - unsigned long len; 434 - 435 - if (!(mask & (1 << i))) 436 - continue; 437 - 438 - rc = -EINVAL; 439 - len = pci_resource_len(pdev, i); 440 - if (!len) 441 - goto err_inval; 442 - 443 - rc = pci_request_region(pdev, i, name); 444 - if (rc) 445 - goto err_inval; 446 - 447 - rc = -ENOMEM; 448 - if (!pcim_iomap(pdev, i, 0)) 449 - goto err_region; 450 - } 451 - 452 - return 0; 453 - 454 - err_region: 455 - pci_release_region(pdev, i); 456 - err_inval: 457 - while (--i >= 0) { 458 - if (!(mask & (1 << i))) 459 - continue; 460 - pcim_iounmap(pdev, iomap[i]); 461 - pci_release_region(pdev, i); 462 - } 463 - 464 - return rc; 465 - } 466 - EXPORT_SYMBOL(pcim_iomap_regions); 467 - 468 - /** 469 - * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones 470 - * @pdev: PCI device to map IO resources for 471 - * @mask: Mask of BARs to iomap 472 - * @name: Name used when requesting regions 473 - * 474 - * Request all PCI BARs and iomap regions specified by @mask. 475 - */ 476 - int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask, 477 - const char *name) 478 - { 479 - int request_mask = ((1 << 6) - 1) & ~mask; 480 - int rc; 481 - 482 - rc = pci_request_selected_regions(pdev, request_mask, name); 483 - if (rc) 484 - return rc; 485 - 486 - rc = pcim_iomap_regions(pdev, mask, name); 487 - if (rc) 488 - pci_release_selected_regions(pdev, request_mask); 489 - return rc; 490 - } 491 - EXPORT_SYMBOL(pcim_iomap_regions_request_all); 492 - 493 - /** 494 - * pcim_iounmap_regions - Unmap and release PCI BARs 495 - * @pdev: PCI device to map IO resources for 496 - * @mask: Mask of BARs to unmap and release 497 - * 498 - * Unmap and release regions specified by @mask. 499 - */ 500 - void pcim_iounmap_regions(struct pci_dev *pdev, int mask) 501 - { 502 - void __iomem * const *iomap; 503 - int i; 504 - 505 - iomap = pcim_iomap_table(pdev); 506 - if (!iomap) 507 - return; 508 - 509 - for (i = 0; i < PCIM_IOMAP_MAX; i++) { 510 - if (!(mask & (1 << i))) 511 - continue; 512 - 513 - pcim_iounmap(pdev, iomap[i]); 514 - pci_release_region(pdev, i); 515 - } 516 - } 517 - EXPORT_SYMBOL(pcim_iounmap_regions); 518 - #endif /* CONFIG_PCI */ 519 313 520 314 static void devm_arch_phys_ac_add_release(struct device *dev, void *res) 521 315 {