1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2537849aaSSimon Glass /* 3537849aaSSimon Glass * Copyright (c) 2014 Google, Inc 4537849aaSSimon Glass * Written by Simon Glass <sjg@chromium.org> 5537849aaSSimon Glass */ 6537849aaSSimon Glass 7537849aaSSimon Glass #include <common.h> 8537849aaSSimon Glass #include <dm.h> 9537849aaSSimon Glass #include <fdtdec.h> 10537849aaSSimon Glass #include <inttypes.h> 11537849aaSSimon Glass #include <pci.h> 12537849aaSSimon Glass 13537849aaSSimon Glass static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn, 14537849aaSSimon Glass uint offset, ulong value, 15537849aaSSimon Glass enum pci_size_t size) 16537849aaSSimon Glass { 17537849aaSSimon Glass struct dm_pci_emul_ops *ops; 18537849aaSSimon Glass struct udevice *emul; 19537849aaSSimon Glass int ret; 20537849aaSSimon Glass 21537849aaSSimon Glass ret = sandbox_pci_get_emul(bus, devfn, &emul); 22537849aaSSimon Glass if (ret) 23537849aaSSimon Glass return ret == -ENODEV ? 0 : ret; 24537849aaSSimon Glass ops = pci_get_emul_ops(emul); 25537849aaSSimon Glass if (!ops || !ops->write_config) 26537849aaSSimon Glass return -ENOSYS; 27537849aaSSimon Glass 28537849aaSSimon Glass return ops->write_config(emul, offset, value, size); 29537849aaSSimon Glass } 30537849aaSSimon Glass 31537849aaSSimon Glass static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn, 32537849aaSSimon Glass uint offset, ulong *valuep, 33537849aaSSimon Glass enum pci_size_t size) 34537849aaSSimon Glass { 35537849aaSSimon Glass struct dm_pci_emul_ops *ops; 36537849aaSSimon Glass struct udevice *emul; 37537849aaSSimon Glass int ret; 38537849aaSSimon Glass 39537849aaSSimon Glass /* Prepare the default response */ 40537849aaSSimon Glass *valuep = pci_get_ff(size); 41537849aaSSimon Glass ret = sandbox_pci_get_emul(bus, devfn, &emul); 42537849aaSSimon Glass if (ret) 43537849aaSSimon Glass return ret == -ENODEV ? 0 : ret; 44537849aaSSimon Glass ops = pci_get_emul_ops(emul); 45537849aaSSimon Glass if (!ops || !ops->read_config) 46537849aaSSimon Glass return -ENOSYS; 47537849aaSSimon Glass 48537849aaSSimon Glass return ops->read_config(emul, offset, valuep, size); 49537849aaSSimon Glass } 50537849aaSSimon Glass 51537849aaSSimon Glass static const struct dm_pci_ops sandbox_pci_ops = { 52537849aaSSimon Glass .read_config = sandbox_pci_read_config, 53537849aaSSimon Glass .write_config = sandbox_pci_write_config, 54537849aaSSimon Glass }; 55537849aaSSimon Glass 56537849aaSSimon Glass static const struct udevice_id sandbox_pci_ids[] = { 57537849aaSSimon Glass { .compatible = "sandbox,pci" }, 58537849aaSSimon Glass { } 59537849aaSSimon Glass }; 60537849aaSSimon Glass 61537849aaSSimon Glass U_BOOT_DRIVER(pci_sandbox) = { 62537849aaSSimon Glass .name = "pci_sandbox", 63537849aaSSimon Glass .id = UCLASS_PCI, 64537849aaSSimon Glass .of_match = sandbox_pci_ids, 65537849aaSSimon Glass .ops = &sandbox_pci_ops, 6691195485SSimon Glass 6791195485SSimon Glass /* Attach an emulator if we can */ 6891195485SSimon Glass .child_post_bind = dm_scan_fdt_dev, 69537849aaSSimon Glass .per_child_platdata_auto_alloc_size = 70537849aaSSimon Glass sizeof(struct pci_child_platdata), 71537849aaSSimon Glass }; 72