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 134*664bf115SDan 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)) 141*664bf115SDan Williams cxlhdm = ops->devm_cxl_setup_hdm(port); 142d17d0540SDan Williams else 143*664bf115SDan 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 150*664bf115SDan 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)) 156*664bf115SDan Williams rc = ops->devm_cxl_add_passthrough_decoder(port); 157d17d0540SDan Williams else 158*664bf115SDan 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 165*664bf115SDan 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)) 172*664bf115SDan Williams rc = ops->devm_cxl_enumerate_decoders(cxlhdm); 173d17d0540SDan Williams else 174*664bf115SDan 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 181*664bf115SDan 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)) 187*664bf115SDan Williams rc = ops->devm_cxl_port_enumerate_dports(port); 18898d2d3a2SDan Williams else 189*664bf115SDan 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 19667dcdd4dSDan Williams MODULE_LICENSE("GPL v2"); 197814dff9aSDan Williams MODULE_IMPORT_NS(ACPI); 19898d2d3a2SDan Williams MODULE_IMPORT_NS(CXL); 199