| /* | 
|  * 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> | 
|   | 
| 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 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, | 
|   | 
|     /* Attach an emulator if we can */ | 
|     .child_post_bind = dm_scan_fdt_dev, | 
|     .per_child_platdata_auto_alloc_size = | 
|             sizeof(struct pci_child_platdata), | 
| }; |