diff options
author | Simon Glass <sjg@chromium.org> | 2015-03-05 12:25:28 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-04-16 19:27:43 -0600 |
commit | 36d0d3b4b4974f4183609ac8b4d77a1f46acba55 (patch) | |
tree | 859816b8b1c7b1c755ab2853a7736287bf9eab5d /drivers/pci | |
parent | 537849aaa1b8f90d99f4c31a2945ab0b817aa599 (diff) | |
download | u-boot-imx-36d0d3b4b4974f4183609ac8b4d77a1f46acba55.zip u-boot-imx-36d0d3b4b4974f4183609ac8b4d77a1f46acba55.tar.gz u-boot-imx-36d0d3b4b4974f4183609ac8b4d77a1f46acba55.tar.bz2 |
dm: sandbox: pci: Add a PCI emulation uclass
Since sandbox does not have real devices (unless it borrows those from the
host) it must use emulations. Provide a uclass which permits PCI operations
to be passed through to an emulation device.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Makefile | 1 | ||||
-rw-r--r-- | drivers/pci/pci-emul-uclass.c | 67 |
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 9e2e5f9..c1c2ae3c 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -8,6 +8,7 @@ ifneq ($(CONFIG_DM_PCI),) obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o +obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o else obj-$(CONFIG_PCI) += pci.o endif diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c new file mode 100644 index 0000000..0f8e3c9 --- /dev/null +++ b/drivers/pci/pci-emul-uclass.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <fdtdec.h> +#include <libfdt.h> +#include <pci.h> +#include <dm/lists.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sandbox_pci_priv { + int dev_count; +}; + +int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, + struct udevice **emulp) +{ + struct udevice *dev; + int ret; + + ret = pci_bus_find_devfn(bus, find_devfn, &dev); + if (ret) { + debug("%s: Could not find emulator for dev %x\n", __func__, + find_devfn); + return ret; + } + + ret = device_find_first_child(dev, emulp); + if (ret) + return ret; + + return *emulp ? 0 : -ENODEV; +} + +static int sandbox_pci_emul_post_probe(struct udevice *dev) +{ + struct sandbox_pci_priv *priv = dev->uclass->priv; + + priv->dev_count++; + sandbox_set_enable_pci_map(true); + + return 0; +} + +static int sandbox_pci_emul_pre_remove(struct udevice *dev) +{ + struct sandbox_pci_priv *priv = dev->uclass->priv; + + priv->dev_count--; + sandbox_set_enable_pci_map(priv->dev_count > 0); + + return 0; +} + +UCLASS_DRIVER(pci_emul) = { + .id = UCLASS_PCI_EMUL, + .name = "pci_emul", + .post_probe = sandbox_pci_emul_post_probe, + .pre_remove = sandbox_pci_emul_pre_remove, + .priv_auto_alloc_size = sizeof(struct sandbox_pci_priv), +}; |