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 struct sandbox_pci_priv { 16 int dev_count; 17 }; 18 19 int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, 20 struct udevice **emulp) 21 { 22 struct udevice *dev; 23 int ret; 24 25 ret = pci_bus_find_devfn(bus, find_devfn, &dev); 26 if (ret) { 27 debug("%s: Could not find emulator for dev %x\n", __func__, 28 find_devfn); 29 return ret; 30 } 31 32 ret = device_find_first_child(dev, emulp); 33 if (ret) 34 return ret; 35 36 return *emulp ? 0 : -ENODEV; 37 } 38 39 static int sandbox_pci_emul_post_probe(struct udevice *dev) 40 { 41 struct sandbox_pci_priv *priv = dev->uclass->priv; 42 43 priv->dev_count++; 44 sandbox_set_enable_pci_map(true); 45 46 return 0; 47 } 48 49 static int sandbox_pci_emul_pre_remove(struct udevice *dev) 50 { 51 struct sandbox_pci_priv *priv = dev->uclass->priv; 52 53 priv->dev_count--; 54 sandbox_set_enable_pci_map(priv->dev_count > 0); 55 56 return 0; 57 } 58 59 UCLASS_DRIVER(pci_emul) = { 60 .id = UCLASS_PCI_EMUL, 61 .name = "pci_emul", 62 .post_probe = sandbox_pci_emul_post_probe, 63 .pre_remove = sandbox_pci_emul_pre_remove, 64 .priv_auto_alloc_size = sizeof(struct sandbox_pci_priv), 65 }; 66