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