mock.c 7.7 KB

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