Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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#include "../exports.h"
14
15static LIST_HEAD(mock);
16
17static struct cxl_dport *
18redirect_devm_cxl_add_dport_by_dev(struct cxl_port *port,
19 struct device *dport_dev);
20static int redirect_devm_cxl_switch_port_decoders_setup(struct cxl_port *port);
21
22void register_cxl_mock_ops(struct cxl_mock_ops *ops)
23{
24 list_add_rcu(&ops->list, &mock);
25 _devm_cxl_add_dport_by_dev = redirect_devm_cxl_add_dport_by_dev;
26 _devm_cxl_switch_port_decoders_setup =
27 redirect_devm_cxl_switch_port_decoders_setup;
28}
29EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
30
31DEFINE_STATIC_SRCU(cxl_mock_srcu);
32
33void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
34{
35 _devm_cxl_switch_port_decoders_setup =
36 __devm_cxl_switch_port_decoders_setup;
37 _devm_cxl_add_dport_by_dev = __devm_cxl_add_dport_by_dev;
38 list_del_rcu(&ops->list);
39 synchronize_srcu(&cxl_mock_srcu);
40}
41EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
42
43struct cxl_mock_ops *get_cxl_mock_ops(int *index)
44{
45 *index = srcu_read_lock(&cxl_mock_srcu);
46 return list_first_or_null_rcu(&mock, struct cxl_mock_ops, list);
47}
48EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
49
50void put_cxl_mock_ops(int index)
51{
52 srcu_read_unlock(&cxl_mock_srcu, index);
53}
54EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
55
56bool __wrap_is_acpi_device_node(const struct fwnode_handle *fwnode)
57{
58 struct acpi_device *adev =
59 container_of(fwnode, struct acpi_device, fwnode);
60 int index;
61 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
62 bool retval = false;
63
64 if (ops)
65 retval = ops->is_mock_adev(adev);
66
67 if (!retval)
68 retval = is_acpi_device_node(fwnode);
69
70 put_cxl_mock_ops(index);
71 return retval;
72}
73EXPORT_SYMBOL(__wrap_is_acpi_device_node);
74
75int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id,
76 acpi_tbl_entry_handler_arg handler_arg,
77 void *arg)
78{
79 int index, rc;
80 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
81
82 if (ops)
83 rc = ops->acpi_table_parse_cedt(id, handler_arg, arg);
84 else
85 rc = acpi_table_parse_cedt(id, handler_arg, arg);
86
87 put_cxl_mock_ops(index);
88
89 return rc;
90}
91EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, "ACPI");
92
93acpi_status __wrap_acpi_evaluate_integer(acpi_handle handle,
94 acpi_string pathname,
95 struct acpi_object_list *arguments,
96 unsigned long long *data)
97{
98 int index;
99 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
100 acpi_status status;
101
102 if (ops)
103 status = ops->acpi_evaluate_integer(handle, pathname, arguments,
104 data);
105 else
106 status = acpi_evaluate_integer(handle, pathname, arguments,
107 data);
108 put_cxl_mock_ops(index);
109
110 return status;
111}
112EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
113
114struct acpi_pci_root *__wrap_acpi_pci_find_root(acpi_handle handle)
115{
116 int index;
117 struct acpi_pci_root *root;
118 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
119
120 if (ops)
121 root = ops->acpi_pci_find_root(handle);
122 else
123 root = acpi_pci_find_root(handle);
124
125 put_cxl_mock_ops(index);
126
127 return root;
128}
129EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
130
131struct nvdimm_bus *
132__wrap_nvdimm_bus_register(struct device *dev,
133 struct nvdimm_bus_descriptor *nd_desc)
134{
135 int index;
136 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
137
138 if (ops && ops->is_mock_dev(dev->parent->parent))
139 nd_desc->provider_name = "cxl_test";
140 put_cxl_mock_ops(index);
141
142 return nvdimm_bus_register(dev, nd_desc);
143}
144EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
145
146int redirect_devm_cxl_switch_port_decoders_setup(struct cxl_port *port)
147{
148 int rc, index;
149 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
150
151 if (ops && ops->is_mock_port(port->uport_dev))
152 rc = ops->devm_cxl_switch_port_decoders_setup(port);
153 else
154 rc = __devm_cxl_switch_port_decoders_setup(port);
155 put_cxl_mock_ops(index);
156
157 return rc;
158}
159
160int __wrap_devm_cxl_endpoint_decoders_setup(struct cxl_port *port)
161{
162 int rc, index;
163 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
164
165 if (ops && ops->is_mock_port(port->uport_dev))
166 rc = ops->devm_cxl_endpoint_decoders_setup(port);
167 else
168 rc = devm_cxl_endpoint_decoders_setup(port);
169 put_cxl_mock_ops(index);
170
171 return rc;
172}
173EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_endpoint_decoders_setup, "CXL");
174
175int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port)
176{
177 int rc, index;
178 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
179
180 if (ops && ops->is_mock_port(port->uport_dev))
181 rc = ops->devm_cxl_port_enumerate_dports(port);
182 else
183 rc = devm_cxl_port_enumerate_dports(port);
184 put_cxl_mock_ops(index);
185
186 return rc;
187}
188EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, "CXL");
189
190int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds)
191{
192 int rc, index;
193 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
194
195 if (ops && ops->is_mock_dev(cxlds->dev))
196 rc = 0;
197 else
198 rc = cxl_await_media_ready(cxlds);
199 put_cxl_mock_ops(index);
200
201 return rc;
202}
203EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, "CXL");
204
205struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port,
206 struct device *dport_dev,
207 int port_id,
208 resource_size_t rcrb)
209{
210 int index;
211 struct cxl_dport *dport;
212 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
213
214 if (ops && ops->is_mock_port(dport_dev)) {
215 dport = devm_cxl_add_dport(port, dport_dev, port_id,
216 CXL_RESOURCE_NONE);
217 if (!IS_ERR(dport)) {
218 dport->rcrb.base = rcrb;
219 dport->rch = true;
220 }
221 } else
222 dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);
223 put_cxl_mock_ops(index);
224
225 return dport;
226}
227EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, "CXL");
228
229resource_size_t __wrap_cxl_rcd_component_reg_phys(struct device *dev,
230 struct cxl_dport *dport)
231{
232 int index;
233 resource_size_t component_reg_phys;
234 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
235
236 if (ops && ops->is_mock_port(dev))
237 component_reg_phys = CXL_RESOURCE_NONE;
238 else
239 component_reg_phys = cxl_rcd_component_reg_phys(dev, dport);
240 put_cxl_mock_ops(index);
241
242 return component_reg_phys;
243}
244EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, "CXL");
245
246void __wrap_cxl_endpoint_parse_cdat(struct cxl_port *port)
247{
248 int index;
249 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
250 struct cxl_memdev *cxlmd = to_cxl_memdev(port->uport_dev);
251
252 if (ops && ops->is_mock_dev(cxlmd->dev.parent))
253 ops->cxl_endpoint_parse_cdat(port);
254 else
255 cxl_endpoint_parse_cdat(port);
256 put_cxl_mock_ops(index);
257}
258EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, "CXL");
259
260void __wrap_cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)
261{
262 int index;
263 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
264
265 if (!ops || !ops->is_mock_port(dport->dport_dev))
266 cxl_dport_init_ras_reporting(dport, host);
267
268 put_cxl_mock_ops(index);
269}
270EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dport_init_ras_reporting, "CXL");
271
272struct cxl_dport *redirect_devm_cxl_add_dport_by_dev(struct cxl_port *port,
273 struct device *dport_dev)
274{
275 int index;
276 struct cxl_mock_ops *ops = get_cxl_mock_ops(&index);
277 struct cxl_dport *dport;
278
279 if (ops && ops->is_mock_port(port->uport_dev))
280 dport = ops->devm_cxl_add_dport_by_dev(port, dport_dev);
281 else
282 dport = __devm_cxl_add_dport_by_dev(port, dport_dev);
283 put_cxl_mock_ops(index);
284
285 return dport;
286}
287
288MODULE_LICENSE("GPL v2");
289MODULE_DESCRIPTION("cxl_test: emulation module");
290MODULE_IMPORT_NS("ACPI");
291MODULE_IMPORT_NS("CXL");