X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdevres.c;h=edc27a5d1b735aba4855d33e9756ab375d9569ce;hb=c34ebbae01e3d1f6a5cced6a40dc0ed792590d22;hp=2a668dd7cac7cb81e6cc44e1ebe61e12225e3934;hpb=9468482bd4c3b89abe04a770848d5eaa1ea830b0;p=linux-2.6-omap-h63xx.git diff --git a/lib/devres.c b/lib/devres.c index 2a668dd7cac..edc27a5d1b7 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -274,21 +274,21 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name) rc = pci_request_region(pdev, i, name); if (rc) - goto err_region; + goto err_inval; rc = -ENOMEM; if (!pcim_iomap(pdev, i, 0)) - goto err_iomap; + goto err_region; } return 0; - err_iomap: - pcim_iounmap(pdev, iomap[i]); err_region: pci_release_region(pdev, i); err_inval: while (--i >= 0) { + if (!(mask & (1 << i))) + continue; pcim_iounmap(pdev, iomap[i]); pci_release_region(pdev, i); } @@ -296,5 +296,56 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name) return rc; } EXPORT_SYMBOL(pcim_iomap_regions); + +/** + * pcim_iomap_regions_request_all - Request all BARs and iomap specified ones + * @pdev: PCI device to map IO resources for + * @mask: Mask of BARs to iomap + * @name: Name used when requesting regions + * + * Request all PCI BARs and iomap regions specified by @mask. + */ +int pcim_iomap_regions_request_all(struct pci_dev *pdev, u16 mask, + const char *name) +{ + int request_mask = ((1 << 6) - 1) & ~mask; + int rc; + + rc = pci_request_selected_regions(pdev, request_mask, name); + if (rc) + return rc; + + rc = pcim_iomap_regions(pdev, mask, name); + if (rc) + pci_release_selected_regions(pdev, request_mask); + return rc; +} +EXPORT_SYMBOL(pcim_iomap_regions_request_all); + +/** + * pcim_iounmap_regions - Unmap and release PCI BARs + * @pdev: PCI device to map IO resources for + * @mask: Mask of BARs to unmap and release + * + * Unamp and release regions specified by @mask. + */ +void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask) +{ + void __iomem * const *iomap; + int i; + + iomap = pcim_iomap_table(pdev); + if (!iomap) + return; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + if (!(mask & (1 << i))) + continue; + + pcim_iounmap(pdev, iomap[i]); + pci_release_region(pdev, i); + } +} +EXPORT_SYMBOL(pcim_iounmap_regions); #endif #endif