Merge tag 'soc-drivers-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-block.git] / tools / testing / cxl / test / mock.c
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
14 static LIST_HEAD(mock);
15
16 void register_cxl_mock_ops(struct cxl_mock_ops *ops)
17 {
18         list_add_rcu(&ops->list, &mock);
19 }
20 EXPORT_SYMBOL_GPL(register_cxl_mock_ops);
21
22 DEFINE_STATIC_SRCU(cxl_mock_srcu);
23
24 void unregister_cxl_mock_ops(struct cxl_mock_ops *ops)
25 {
26         list_del_rcu(&ops->list);
27         synchronize_srcu(&cxl_mock_srcu);
28 }
29 EXPORT_SYMBOL_GPL(unregister_cxl_mock_ops);
30
31 struct 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 }
36 EXPORT_SYMBOL_GPL(get_cxl_mock_ops);
37
38 void put_cxl_mock_ops(int index)
39 {
40         srcu_read_unlock(&cxl_mock_srcu, index);
41 }
42 EXPORT_SYMBOL_GPL(put_cxl_mock_ops);
43
44 bool __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 }
61 EXPORT_SYMBOL(__wrap_is_acpi_device_node);
62
63 int __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 }
79 EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI);
80
81 acpi_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 }
100 EXPORT_SYMBOL(__wrap_acpi_evaluate_integer);
101
102 struct 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 }
117 EXPORT_SYMBOL_GPL(__wrap_acpi_pci_find_root);
118
119 struct 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 }
132 EXPORT_SYMBOL_GPL(__wrap_nvdimm_bus_register);
133
134 struct 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         else
145                 cxlhdm = devm_cxl_setup_hdm(port, info);
146         put_cxl_mock_ops(index);
147
148         return cxlhdm;
149 }
150 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL);
151
152 int __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         else
160                 rc = devm_cxl_add_passthrough_decoder(port);
161         put_cxl_mock_ops(index);
162
163         return rc;
164 }
165 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL);
166
167 int __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         else
177                 rc = devm_cxl_enumerate_decoders(cxlhdm, info);
178         put_cxl_mock_ops(index);
179
180         return rc;
181 }
182 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL);
183
184 int __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         else
192                 rc = devm_cxl_port_enumerate_dports(port);
193         put_cxl_mock_ops(index);
194
195         return rc;
196 }
197 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL);
198
199 int __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         else
207                 rc = cxl_await_media_ready(cxlds);
208         put_cxl_mock_ops(index);
209
210         return rc;
211 }
212 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL);
213
214 int __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         else
224                 rc = cxl_hdm_decode_init(cxlds, cxlhdm, info);
225         put_cxl_mock_ops(index);
226
227         return rc;
228 }
229 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL);
230
231 int __wrap_cxl_dvsec_rr_decode(struct device *dev, int dvsec,
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         else
240                 rc = cxl_dvsec_rr_decode(dev, dvsec, info);
241         put_cxl_mock_ops(index);
242
243         return rc;
244 }
245 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, CXL);
246
247 struct 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         } else
264                 dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb);
265         put_cxl_mock_ops(index);
266
267         return dport;
268 }
269 EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, CXL);
270
271 resource_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         else
281                 component_reg_phys = cxl_rcd_component_reg_phys(dev, dport);
282         put_cxl_mock_ops(index);
283
284         return component_reg_phys;
285 }
286 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, CXL);
287
288 void __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         else
297                 cxl_endpoint_parse_cdat(port);
298         put_cxl_mock_ops(index);
299 }
300 EXPORT_SYMBOL_NS_GPL(__wrap_cxl_endpoint_parse_cdat, CXL);
301
302 MODULE_LICENSE("GPL v2");
303 MODULE_IMPORT_NS(ACPI);
304 MODULE_IMPORT_NS(CXL);