1 /* 2 * Copyright (c) 2014 Google, Inc 3 * Written by Simon Glass <sjg@chromium.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <dm.h> 10 #include <fdtdec.h> 11 #include <linux/libfdt.h> 12 #include <pci.h> 13 #include <dm/lists.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 struct sandbox_pci_priv { 18 int dev_count; 19 }; 20 21 int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, 22 struct udevice **emulp) 23 { 24 struct udevice *dev; 25 int ret; 26 27 ret = pci_bus_find_devfn(bus, find_devfn, &dev); 28 if (ret) { 29 debug("%s: Could not find emulator for dev %x\n", __func__, 30 find_devfn); 31 return ret; 32 } 33 34 ret = device_find_first_child(dev, emulp); 35 if (ret) 36 return ret; 37 38 return *emulp ? 0 : -ENODEV; 39 } 40 41 static int sandbox_pci_emul_post_probe(struct udevice *dev) 42 { 43 struct sandbox_pci_priv *priv = dev->uclass->priv; 44 45 priv->dev_count++; 46 sandbox_set_enable_pci_map(true); 47 48 return 0; 49 } 50 51 static int sandbox_pci_emul_pre_remove(struct udevice *dev) 52 { 53 struct sandbox_pci_priv *priv = dev->uclass->priv; 54 55 priv->dev_count--; 56 sandbox_set_enable_pci_map(priv->dev_count > 0); 57 58 return 0; 59 } 60 61 UCLASS_DRIVER(pci_emul) = { 62 .id = UCLASS_PCI_EMUL, 63 .name = "pci_emul", 64 .post_probe = sandbox_pci_emul_post_probe, 65 .pre_remove = sandbox_pci_emul_pre_remove, 66 .priv_auto_alloc_size = sizeof(struct sandbox_pci_priv), 67 }; 68