317 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//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 22DEFINE_STATIC_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 else73 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 else94 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 else111 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 struct cxl_endpoint_dvsec_info *info)136 137{138 int index;139 struct cxl_hdm *cxlhdm;140 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);141 142 if (ops && ops->is_mock_port(port->uport_dev))143 cxlhdm = ops->devm_cxl_setup_hdm(port, info);144 else145 cxlhdm = devm_cxl_setup_hdm(port, info);146 put_cxl_mock_ops(index);147 148 return cxlhdm;149}150EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL);151 152int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port)153{154 int rc, index;155 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);156 157 if (ops && ops->is_mock_port(port->uport_dev))158 rc = ops->devm_cxl_add_passthrough_decoder(port);159 else160 rc = devm_cxl_add_passthrough_decoder(port);161 put_cxl_mock_ops(index);162 163 return rc;164}165EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL);166 167int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,168 struct cxl_endpoint_dvsec_info *info)169{170 int rc, index;171 struct cxl_port *port = cxlhdm->port;172 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);173 174 if (ops && ops->is_mock_port(port->uport_dev))175 rc = ops->devm_cxl_enumerate_decoders(cxlhdm, info);176 else177 rc = devm_cxl_enumerate_decoders(cxlhdm, info);178 put_cxl_mock_ops(index);179 180 return rc;181}182EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL);183 184int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port)185{186 int rc, index;187 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);188 189 if (ops && ops->is_mock_port(port->uport_dev))190 rc = ops->devm_cxl_port_enumerate_dports(port);191 else192 rc = devm_cxl_port_enumerate_dports(port);193 put_cxl_mock_ops(index);194 195 return rc;196}197EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL);198 199int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)200{201 int rc, index;202 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);203 204 if (ops && ops->is_mock_dev(cxlds->dev))205 rc = 0;206 else207 rc = cxl_await_media_ready(cxlds);208 put_cxl_mock_ops(index);209 210 return rc;211}212EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL);213 214int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds,215 struct cxl_hdm *cxlhdm,216 struct cxl_endpoint_dvsec_info *info)217{218 int rc = 0, index;219 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);220 221 if (ops && ops->is_mock_dev(cxlds->dev))222 rc = 0;223 else224 rc = cxl_hdm_decode_init(cxlds, cxlhdm, info);225 put_cxl_mock_ops(index);226 227 return rc;228}229EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL);230 231int __wrap_cxl_dvsec_rr_decode(struct device *dev, struct cxl_port *port,232 struct cxl_endpoint_dvsec_info *info)233{234 int rc = 0, index;235 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);236 237 if (ops && ops->is_mock_dev(dev))238 rc = 0;239 else240 rc = cxl_dvsec_rr_decode(dev, port, info);241 put_cxl_mock_ops(index);242 243 return rc;244}245EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, CXL);246 247struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port,248 struct device *dport_dev,249 int port_id,250 resource_size_t rcrb)251{252 int index;253 struct cxl_dport *dport;254 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);255 256 if (ops && ops->is_mock_port(dport_dev)) {257 dport = devm_cxl_add_dport(port, dport_dev, port_id,258 CXL_RESOURCE_NONE);259 if (!IS_ERR(dport)) {260 dport->rcrb.base = rcrb;261 dport->rch = true;262 }263 } else264 dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);265 put_cxl_mock_ops(index);266 267 return dport;268}269EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, CXL);270 271resource_size_t __wrap_cxl_rcd_component_reg_phys(struct device *dev,272 struct cxl_dport *dport)273{274 int index;275 resource_size_t component_reg_phys;276 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);277 278 if (ops && ops->is_mock_port(dev))279 component_reg_phys = CXL_RESOURCE_NONE;280 else281 component_reg_phys = cxl_rcd_component_reg_phys(dev, dport);282 put_cxl_mock_ops(index);283 284 return component_reg_phys;285}286EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, CXL);287 288void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)289{290 int index;291 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);292 struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);293 294 if (ops && ops->is_mock_dev(cxlmd->dev.parent))295 ops->cxl_endpoint_parse_cdat(port);296 else297 cxl_endpoint_parse_cdat(port);298 put_cxl_mock_ops(index);299}300EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, CXL);301 302void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)303{304 int index;305 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);306 307 if (!ops || !ops->is_mock_port(dport->dport_dev))308 cxl_dport_init_ras_reporting(dport, host);309 310 put_cxl_mock_ops(index);311}312EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, CXL);313 314MODULE_LICENSE("GPL v2");315MODULE_IMPORT_NS(ACPI);316MODULE_IMPORT_NS(CXL);317