1*f5dce77fSThomas Zimmermann // SPDX-License-Identifier: GPL-2.0 2*f5dce77fSThomas Zimmermann 3*f5dce77fSThomas Zimmermann #include <linux/pci.h> 4*f5dce77fSThomas Zimmermann #include <linux/screen_info.h> 5*f5dce77fSThomas Zimmermann 6*f5dce77fSThomas Zimmermann static struct pci_dev *__screen_info_pci_dev(struct resource *res) 7*f5dce77fSThomas Zimmermann { 8*f5dce77fSThomas Zimmermann struct pci_dev *pdev = NULL; 9*f5dce77fSThomas Zimmermann const struct resource *r = NULL; 10*f5dce77fSThomas Zimmermann 11*f5dce77fSThomas Zimmermann if (!(res->flags & IORESOURCE_MEM)) 12*f5dce77fSThomas Zimmermann return NULL; 13*f5dce77fSThomas Zimmermann 14*f5dce77fSThomas Zimmermann while (!r && (pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) { 15*f5dce77fSThomas Zimmermann r = pci_find_resource(pdev, res); 16*f5dce77fSThomas Zimmermann } 17*f5dce77fSThomas Zimmermann 18*f5dce77fSThomas Zimmermann return pdev; 19*f5dce77fSThomas Zimmermann } 20*f5dce77fSThomas Zimmermann 21*f5dce77fSThomas Zimmermann /** 22*f5dce77fSThomas Zimmermann * screen_info_pci_dev() - Return PCI parent device that contains screen_info's framebuffer 23*f5dce77fSThomas Zimmermann * @si: the screen_info 24*f5dce77fSThomas Zimmermann * 25*f5dce77fSThomas Zimmermann * Returns: 26*f5dce77fSThomas Zimmermann * The screen_info's parent device or NULL on success, or a pointer-encoded 27*f5dce77fSThomas Zimmermann * errno value otherwise. The value NULL is not an error. It signals that no 28*f5dce77fSThomas Zimmermann * PCI device has been found. 29*f5dce77fSThomas Zimmermann */ 30*f5dce77fSThomas Zimmermann struct pci_dev *screen_info_pci_dev(const struct screen_info *si) 31*f5dce77fSThomas Zimmermann { 32*f5dce77fSThomas Zimmermann struct resource res[SCREEN_INFO_MAX_RESOURCES]; 33*f5dce77fSThomas Zimmermann ssize_t i, numres; 34*f5dce77fSThomas Zimmermann 35*f5dce77fSThomas Zimmermann numres = screen_info_resources(si, res, ARRAY_SIZE(res)); 36*f5dce77fSThomas Zimmermann if (numres < 0) 37*f5dce77fSThomas Zimmermann return ERR_PTR(numres); 38*f5dce77fSThomas Zimmermann 39*f5dce77fSThomas Zimmermann for (i = 0; i < numres; ++i) { 40*f5dce77fSThomas Zimmermann struct pci_dev *pdev = __screen_info_pci_dev(&res[i]); 41*f5dce77fSThomas Zimmermann 42*f5dce77fSThomas Zimmermann if (pdev) 43*f5dce77fSThomas Zimmermann return pdev; 44*f5dce77fSThomas Zimmermann } 45*f5dce77fSThomas Zimmermann 46*f5dce77fSThomas Zimmermann return NULL; 47*f5dce77fSThomas Zimmermann } 48*f5dce77fSThomas Zimmermann EXPORT_SYMBOL(screen_info_pci_dev); 49