diff options
author | Simon Glass <sjg@chromium.org> | 2015-03-05 12:25:27 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2015-04-16 19:27:43 -0600 |
commit | 537849aaa1b8f90d99f4c31a2945ab0b817aa599 (patch) | |
tree | a7fa642fcdab8c17c73de18d73e9aaa04473b9fa /drivers/pci/pci_sandbox.c | |
parent | 9569c40668290408eac447f9be99dab603c8e34c (diff) | |
download | u-boot-537849aaa1b8f90d99f4c31a2945ab0b817aa599.tar.gz u-boot-537849aaa1b8f90d99f4c31a2945ab0b817aa599.tar.bz2 u-boot-537849aaa1b8f90d99f4c31a2945ab0b817aa599.zip |
dm: sandbox: Add a simple PCI driver
Add a driver which can access emulations of devices and make them available
in sandbox.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/pci/pci_sandbox.c')
-rw-r--r-- | drivers/pci/pci_sandbox.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c new file mode 100644 index 0000000000..6de5130c2a --- /dev/null +++ b/drivers/pci/pci_sandbox.c @@ -0,0 +1,79 @@ +/* + * 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 <inttypes.h> +#include <pci.h> +#include <dm/root.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn, + uint offset, ulong value, + enum pci_size_t size) +{ + struct dm_pci_emul_ops *ops; + struct udevice *emul; + int ret; + + ret = sandbox_pci_get_emul(bus, devfn, &emul); + if (ret) + return ret == -ENODEV ? 0 : ret; + ops = pci_get_emul_ops(emul); + if (!ops || !ops->write_config) + return -ENOSYS; + + return ops->write_config(emul, offset, value, size); +} + +static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct dm_pci_emul_ops *ops; + struct udevice *emul; + int ret; + + /* Prepare the default response */ + *valuep = pci_get_ff(size); + ret = sandbox_pci_get_emul(bus, devfn, &emul); + if (ret) + return ret == -ENODEV ? 0 : ret; + ops = pci_get_emul_ops(emul); + if (!ops || !ops->read_config) + return -ENOSYS; + + return ops->read_config(emul, offset, valuep, size); +} + +static int sandbox_pci_child_post_bind(struct udevice *dev) +{ + /* Attach an emulator if we can */ + return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false); +} + +static const struct dm_pci_ops sandbox_pci_ops = { + .read_config = sandbox_pci_read_config, + .write_config = sandbox_pci_write_config, +}; + +static const struct udevice_id sandbox_pci_ids[] = { + { .compatible = "sandbox,pci" }, + { } +}; + +U_BOOT_DRIVER(pci_sandbox) = { + .name = "pci_sandbox", + .id = UCLASS_PCI, + .of_match = sandbox_pci_ids, + .ops = &sandbox_pci_ops, + .child_post_bind = sandbox_pci_child_post_bind, + .per_child_platdata_auto_alloc_size = + sizeof(struct pci_child_platdata), +}; |