mock.c (5461B)
1// SPDX-License-Identifier: GPL-2.0-only 2//Copyright(c) 2021 Intel Corporation. All rights reserved. 3 4#include <linux/libnvdimm.h> 5#include <linux/rculist.h> 6#include <linux/device.h> 7#include <linux/export.h> 8#include <linux/acpi.h> 9#include <linux/pci.h> 10#include <cxlmem.h> 11#include <cxlpci.h> 12#include "mock.h" 13 14static LIST_HEAD(mock); 15 16void register_cxl_mock_ops(struct cxl_mock_ops *ops) 17{ 18 list_add_rcu(&ops->list, &mock); 19} 20EXPORT_SYMBOL_GPL(register_cxl_mock_ops); 21 22static DEFINE_SRCU(cxl_mock_srcu); 23 24void unregister_cxl_mock_ops(struct cxl_mock_ops *ops) 25{ 26 list_del_rcu(&ops->list); 27 synchronize_srcu(&cxl_mock_srcu); 28} 29EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops); 30 31struct cxl_mock_ops *get_cxl_mock_ops(int *index) 32{ 33 *index = srcu_read_lock(&cxl_mock_srcu); 34 return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list); 35} 36EXPORT_SYMBOL_GPL(get_cxl_mock_ops); 37 38void put_cxl_mock_ops(int index) 39{ 40 srcu_read_unlock(&cxl_mock_srcu, index); 41} 42EXPORT_SYMBOL_GPL(put_cxl_mock_ops); 43 44bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode) 45{ 46 struct acpi_device *adev = 47 container_of(fwnode, struct acpi_device, fwnode); 48 int index; 49 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 50 bool retval = false; 51 52 if (ops) 53 retval = ops->is_mock_adev(adev); 54 55 if (!retval) 56 retval = is_acpi_device_node(fwnode); 57 58 put_cxl_mock_ops(index); 59 return retval; 60} 61EXPORT_SYMBOL(__wrap_is_acpi_device_node); 62 63int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id, 64 acpi_tbl_entry_handler_arg handler_arg, 65 void *arg) 66{ 67 int index, rc; 68 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 69 70 if (ops) 71 rc = ops->acpi_table_parse_cedt(id, handler_arg, arg); 72 else 73 rc = acpi_table_parse_cedt(id, handler_arg, arg); 74 75 put_cxl_mock_ops(index); 76 77 return rc; 78} 79EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI); 80 81acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle, 82 acpi_string pathname, 83 struct acpi_object_list *arguments, 84 unsigned long long *data) 85{ 86 int index; 87 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 88 acpi_status status; 89 90 if (ops) 91 status = ops->acpi_evaluate_integer(handle, pathname, arguments, 92 data); 93 else 94 status = acpi_evaluate_integer(handle, pathname, arguments, 95 data); 96 put_cxl_mock_ops(index); 97 98 return status; 99} 100EXPORT_SYMBOL(__wrap_acpi_evaluate_integer); 101 102struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle) 103{ 104 int index; 105 struct acpi_pci_root *root; 106 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 107 108 if (ops) 109 root = ops->acpi_pci_find_root(handle); 110 else 111 root = acpi_pci_find_root(handle); 112 113 put_cxl_mock_ops(index); 114 115 return root; 116} 117EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root); 118 119struct nvdimm_bus * 120__wrap_nvdimm_bus_register(struct device *dev, 121 struct nvdimm_bus_descriptor *nd_desc) 122{ 123 int index; 124 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 125 126 if (ops && ops->is_mock_dev(dev->parent->parent)) 127 nd_desc->provider_name = "cxl_test"; 128 put_cxl_mock_ops(index); 129 130 return nvdimm_bus_register(dev, nd_desc); 131} 132EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register); 133 134struct cxl_hdm *__wrap_devm_cxl_setup_hdm(struct cxl_port *port) 135{ 136 int index; 137 struct cxl_hdm *cxlhdm; 138 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 139 140 if (ops && ops->is_mock_port(port->uport)) 141 cxlhdm = ops->devm_cxl_setup_hdm(port); 142 else 143 cxlhdm = devm_cxl_setup_hdm(port); 144 put_cxl_mock_ops(index); 145 146 return cxlhdm; 147} 148EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL); 149 150int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port) 151{ 152 int rc, index; 153 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 154 155 if (ops && ops->is_mock_port(port->uport)) 156 rc = ops->devm_cxl_add_passthrough_decoder(port); 157 else 158 rc = devm_cxl_add_passthrough_decoder(port); 159 put_cxl_mock_ops(index); 160 161 return rc; 162} 163EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL); 164 165int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm) 166{ 167 int rc, index; 168 struct cxl_port *port = cxlhdm->port; 169 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 170 171 if (ops && ops->is_mock_port(port->uport)) 172 rc = ops->devm_cxl_enumerate_decoders(cxlhdm); 173 else 174 rc = devm_cxl_enumerate_decoders(cxlhdm); 175 put_cxl_mock_ops(index); 176 177 return rc; 178} 179EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL); 180 181int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port) 182{ 183 int rc, index; 184 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 185 186 if (ops && ops->is_mock_port(port->uport)) 187 rc = ops->devm_cxl_port_enumerate_dports(port); 188 else 189 rc = devm_cxl_port_enumerate_dports(port); 190 put_cxl_mock_ops(index); 191 192 return rc; 193} 194EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL); 195 196int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds) 197{ 198 int rc, index; 199 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 200 201 if (ops && ops->is_mock_dev(cxlds->dev)) 202 rc = 0; 203 else 204 rc = cxl_await_media_ready(cxlds); 205 put_cxl_mock_ops(index); 206 207 return rc; 208} 209EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL); 210 211bool __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds, 212 struct cxl_hdm *cxlhdm) 213{ 214 int rc = 0, index; 215 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); 216 217 if (!ops || !ops->is_mock_dev(cxlds->dev)) 218 rc = cxl_hdm_decode_init(cxlds, cxlhdm); 219 put_cxl_mock_ops(index); 220 221 return rc; 222} 223EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL); 224 225MODULE_LICENSE("GPL v2"); 226MODULE_IMPORT_NS(ACPI); 227MODULE_IMPORT_NS(CXL);