167dcdd4dSDan Williams // SPDX-License-Identifier: GPL-2.0-only 267dcdd4dSDan Williams //Copyright(c) 2021 Intel Corporation. All rights reserved. 367dcdd4dSDan Williams 467dcdd4dSDan Williams #include <linux/libnvdimm.h> 567dcdd4dSDan Williams #include <linux/rculist.h> 667dcdd4dSDan Williams #include <linux/device.h> 767dcdd4dSDan Williams #include <linux/export.h> 867dcdd4dSDan Williams #include <linux/acpi.h> 967dcdd4dSDan Williams #include <linux/pci.h> 1098d2d3a2SDan Williams #include <cxlmem.h> 1198d2d3a2SDan Williams #include <cxlpci.h> 1267dcdd4dSDan Williams #include "mock.h" 1367dcdd4dSDan Williams 1467dcdd4dSDan Williams static LIST_HEAD(mock); 1567dcdd4dSDan Williams 1667dcdd4dSDan Williams void register_cxl_mock_ops(struct cxl_mock_ops *ops) 1767dcdd4dSDan Williams { 1867dcdd4dSDan Williams list_add_rcu(&ops->list, &mock); 1967dcdd4dSDan Williams } 2067dcdd4dSDan Williams EXPORT_SYMBOL_GPL(register_cxl_mock_ops); 2167dcdd4dSDan Williams 2267dcdd4dSDan Williams static DEFINE_SRCU(cxl_mock_srcu); 2367dcdd4dSDan Williams 2467dcdd4dSDan Williams void unregister_cxl_mock_ops(struct cxl_mock_ops *ops) 2567dcdd4dSDan Williams { 2667dcdd4dSDan Williams list_del_rcu(&ops->list); 2767dcdd4dSDan Williams synchronize_srcu(&cxl_mock_srcu); 2867dcdd4dSDan Williams } 2967dcdd4dSDan Williams EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops); 3067dcdd4dSDan Williams 3167dcdd4dSDan Williams struct cxl_mock_ops *get_cxl_mock_ops(int *index) 3267dcdd4dSDan Williams { 3367dcdd4dSDan Williams *index = srcu_read_lock(&cxl_mock_srcu); 3467dcdd4dSDan Williams return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list); 3567dcdd4dSDan Williams } 3667dcdd4dSDan Williams EXPORT_SYMBOL_GPL(get_cxl_mock_ops); 3767dcdd4dSDan Williams 3867dcdd4dSDan Williams void put_cxl_mock_ops(int index) 3967dcdd4dSDan Williams { 4067dcdd4dSDan Williams srcu_read_unlock(&cxl_mock_srcu, index); 4167dcdd4dSDan Williams } 4267dcdd4dSDan Williams EXPORT_SYMBOL_GPL(put_cxl_mock_ops); 4367dcdd4dSDan Williams 4467dcdd4dSDan Williams bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode) 4567dcdd4dSDan Williams { 4667dcdd4dSDan Williams struct acpi_device *adev = 4767dcdd4dSDan Williams container_of(fwnode, struct acpi_device, fwnode); 4867dcdd4dSDan Williams int index; 4967dcdd4dSDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 5067dcdd4dSDan Williams bool retval = false; 5167dcdd4dSDan Williams 5267dcdd4dSDan Williams if (ops) 5367dcdd4dSDan Williams retval = ops->is_mock_adev(adev); 5467dcdd4dSDan Williams 5567dcdd4dSDan Williams if (!retval) 5667dcdd4dSDan Williams retval = is_acpi_device_node(fwnode); 5767dcdd4dSDan Williams 5867dcdd4dSDan Williams put_cxl_mock_ops(index); 5967dcdd4dSDan Williams return retval; 6067dcdd4dSDan Williams } 6167dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_is_acpi_device_node); 6267dcdd4dSDan Williams 63814dff9aSDan Williams int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id, 64814dff9aSDan Williams acpi_tbl_entry_handler_arg handler_arg, 65814dff9aSDan Williams void *arg) 6667dcdd4dSDan Williams { 67814dff9aSDan Williams int index, rc; 6867dcdd4dSDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 6967dcdd4dSDan Williams 7067dcdd4dSDan Williams if (ops) 71814dff9aSDan Williams rc = ops->acpi_table_parse_cedt(id, handler_arg, arg); 7267dcdd4dSDan Williams else 73814dff9aSDan Williams rc = acpi_table_parse_cedt(id, handler_arg, arg); 74814dff9aSDan Williams 7567dcdd4dSDan Williams put_cxl_mock_ops(index); 76814dff9aSDan Williams 77814dff9aSDan Williams return rc; 7867dcdd4dSDan Williams } 79814dff9aSDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI); 8067dcdd4dSDan Williams 8167dcdd4dSDan Williams acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle, 8267dcdd4dSDan Williams acpi_string pathname, 8367dcdd4dSDan Williams struct acpi_object_list *arguments, 8467dcdd4dSDan Williams unsigned long long *data) 8567dcdd4dSDan Williams { 8667dcdd4dSDan Williams int index; 8767dcdd4dSDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 8867dcdd4dSDan Williams acpi_status status; 8967dcdd4dSDan Williams 9067dcdd4dSDan Williams if (ops) 9167dcdd4dSDan Williams status = ops->acpi_evaluate_integer(handle, pathname, arguments, 9267dcdd4dSDan Williams data); 9367dcdd4dSDan Williams else 9467dcdd4dSDan Williams status = acpi_evaluate_integer(handle, pathname, arguments, 9567dcdd4dSDan Williams data); 9667dcdd4dSDan Williams put_cxl_mock_ops(index); 9767dcdd4dSDan Williams 9867dcdd4dSDan Williams return status; 9967dcdd4dSDan Williams } 10067dcdd4dSDan Williams EXPORT_SYMBOL(__wrap_acpi_evaluate_integer); 10167dcdd4dSDan Williams 10267dcdd4dSDan Williams struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle) 10367dcdd4dSDan Williams { 10467dcdd4dSDan Williams int index; 10567dcdd4dSDan Williams struct acpi_pci_root *root; 10667dcdd4dSDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 10767dcdd4dSDan Williams 10867dcdd4dSDan Williams if (ops) 10967dcdd4dSDan Williams root = ops->acpi_pci_find_root(handle); 11067dcdd4dSDan Williams else 11167dcdd4dSDan Williams root = acpi_pci_find_root(handle); 11267dcdd4dSDan Williams 11367dcdd4dSDan Williams put_cxl_mock_ops(index); 11467dcdd4dSDan Williams 11567dcdd4dSDan Williams return root; 11667dcdd4dSDan Williams } 11767dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root); 11867dcdd4dSDan Williams 11967dcdd4dSDan Williams struct nvdimm_bus * 12067dcdd4dSDan Williams __wrap_nvdimm_bus_register(struct device *dev, 12167dcdd4dSDan Williams struct nvdimm_bus_descriptor *nd_desc) 12267dcdd4dSDan Williams { 12367dcdd4dSDan Williams int index; 12467dcdd4dSDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 12567dcdd4dSDan Williams 12667dcdd4dSDan Williams if (ops && ops->is_mock_dev(dev->parent->parent)) 12767dcdd4dSDan Williams nd_desc->provider_name = "cxl_test"; 12867dcdd4dSDan Williams put_cxl_mock_ops(index); 12967dcdd4dSDan Williams 13067dcdd4dSDan Williams return nvdimm_bus_register(dev, nd_desc); 13167dcdd4dSDan Williams } 13267dcdd4dSDan Williams EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register); 13367dcdd4dSDan Williams 134664bf115SDan Williams struct cxl_hdm *__wrap_devm_cxl_setup_hdm(struct cxl_port *port) 135d17d0540SDan Williams { 136d17d0540SDan Williams int index; 137d17d0540SDan Williams struct cxl_hdm *cxlhdm; 138d17d0540SDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 139d17d0540SDan Williams 140d17d0540SDan Williams if (ops && ops->is_mock_port(port->uport)) 141664bf115SDan Williams cxlhdm = ops->devm_cxl_setup_hdm(port); 142d17d0540SDan Williams else 143664bf115SDan Williams cxlhdm = devm_cxl_setup_hdm(port); 144d17d0540SDan Williams put_cxl_mock_ops(index); 145d17d0540SDan Williams 146d17d0540SDan Williams return cxlhdm; 147d17d0540SDan Williams } 148d17d0540SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL); 149d17d0540SDan Williams 150664bf115SDan Williams int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port) 151d17d0540SDan Williams { 152d17d0540SDan Williams int rc, index; 153d17d0540SDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 154d17d0540SDan Williams 155d17d0540SDan Williams if (ops && ops->is_mock_port(port->uport)) 156664bf115SDan Williams rc = ops->devm_cxl_add_passthrough_decoder(port); 157d17d0540SDan Williams else 158664bf115SDan Williams rc = devm_cxl_add_passthrough_decoder(port); 159d17d0540SDan Williams put_cxl_mock_ops(index); 160d17d0540SDan Williams 161d17d0540SDan Williams return rc; 162d17d0540SDan Williams } 163d17d0540SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL); 164d17d0540SDan Williams 165664bf115SDan Williams int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm) 166d17d0540SDan Williams { 167d17d0540SDan Williams int rc, index; 168d17d0540SDan Williams struct cxl_port *port = cxlhdm->port; 169d17d0540SDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 170d17d0540SDan Williams 171d17d0540SDan Williams if (ops && ops->is_mock_port(port->uport)) 172664bf115SDan Williams rc = ops->devm_cxl_enumerate_decoders(cxlhdm); 173d17d0540SDan Williams else 174664bf115SDan Williams rc = devm_cxl_enumerate_decoders(cxlhdm); 175d17d0540SDan Williams put_cxl_mock_ops(index); 176d17d0540SDan Williams 177d17d0540SDan Williams return rc; 178d17d0540SDan Williams } 179d17d0540SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL); 180d17d0540SDan Williams 181664bf115SDan Williams int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port) 18298d2d3a2SDan Williams { 18398d2d3a2SDan Williams int rc, index; 18498d2d3a2SDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 18598d2d3a2SDan Williams 18698d2d3a2SDan Williams if (ops && ops->is_mock_port(port->uport)) 187664bf115SDan Williams rc = ops->devm_cxl_port_enumerate_dports(port); 18898d2d3a2SDan Williams else 189664bf115SDan Williams rc = devm_cxl_port_enumerate_dports(port); 19098d2d3a2SDan Williams put_cxl_mock_ops(index); 19198d2d3a2SDan Williams 19298d2d3a2SDan Williams return rc; 19398d2d3a2SDan Williams } 19498d2d3a2SDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL); 19598d2d3a2SDan Williams 1962e4ba0ecSDan Williams int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds) 1972e4ba0ecSDan Williams { 1982e4ba0ecSDan Williams int rc, index; 1992e4ba0ecSDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 2002e4ba0ecSDan Williams 2012e4ba0ecSDan Williams if (ops && ops->is_mock_dev(cxlds->dev)) 2022e4ba0ecSDan Williams rc = 0; 2032e4ba0ecSDan Williams else 2042e4ba0ecSDan Williams rc = cxl_await_media_ready(cxlds); 2052e4ba0ecSDan Williams put_cxl_mock_ops(index); 2062e4ba0ecSDan Williams 2072e4ba0ecSDan Williams return rc; 2082e4ba0ecSDan Williams } 2092e4ba0ecSDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL); 2102e4ba0ecSDan Williams 211863fdccdSDan Williams int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds, 212fcfbc93cSDan Williams struct cxl_hdm *cxlhdm) 21314d78874SDan Williams { 21414d78874SDan Williams int rc = 0, index; 21514d78874SDan Williams struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 21614d78874SDan Williams 217863fdccdSDan Williams if (ops && ops->is_mock_dev(cxlds->dev)) 218863fdccdSDan Williams rc = 0; 219863fdccdSDan Williams else 220fcfbc93cSDan Williams rc = cxl_hdm_decode_init(cxlds, cxlhdm); 22114d78874SDan Williams put_cxl_mock_ops(index); 22214d78874SDan Williams 22314d78874SDan Williams return rc; 22414d78874SDan Williams } 225a12562bbSDan Williams EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL); 22614d78874SDan Williams 227*d5b1a271SRobert Richter resource_size_t __wrap_cxl_rcrb_to_component(struct device *dev, 228*d5b1a271SRobert Richter resource_size_t rcrb, 229*d5b1a271SRobert Richter enum cxl_rcrb which) 230*d5b1a271SRobert Richter { 231*d5b1a271SRobert Richter int index; 232*d5b1a271SRobert Richter resource_size_t component_reg_phys; 233*d5b1a271SRobert Richter struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 234*d5b1a271SRobert Richter 235*d5b1a271SRobert Richter if (ops && ops->is_mock_port(dev)) 236*d5b1a271SRobert Richter component_reg_phys = 237*d5b1a271SRobert Richter ops->cxl_rcrb_to_component(dev, rcrb, which); 238*d5b1a271SRobert Richter else 239*d5b1a271SRobert Richter component_reg_phys = cxl_rcrb_to_component(dev, rcrb, which); 240*d5b1a271SRobert Richter put_cxl_mock_ops(index); 241*d5b1a271SRobert Richter 242*d5b1a271SRobert Richter return component_reg_phys; 243*d5b1a271SRobert Richter } 244*d5b1a271SRobert Richter EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcrb_to_component, CXL); 245*d5b1a271SRobert Richter 24667dcdd4dSDan Williams MODULE_LICENSE("GPL v2"); 247814dff9aSDan Williams MODULE_IMPORT_NS(ACPI); 24898d2d3a2SDan Williams MODULE_IMPORT_NS(CXL); 249