Commit | Line | Data |
---|---|---|
67dcdd4d DW |
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> | |
98d2d3a2 DW |
10 | #include <cxlmem.h> |
11 | #include <cxlpci.h> | |
67dcdd4d DW |
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 | ||
270205be | 22 | DEFINE_STATIC_SRCU(cxl_mock_srcu); |
67dcdd4d DW |
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 | ||
814dff9a DW |
63 | int __wrap_acpi_table_parse_cedt(enum acpi_cedt_type id, |
64 | acpi_tbl_entry_handler_arg handler_arg, | |
65 | void *arg) | |
67dcdd4d | 66 | { |
814dff9a | 67 | int index, rc; |
67dcdd4d | 68 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); |
67dcdd4d DW |
69 | |
70 | if (ops) | |
814dff9a | 71 | rc = ops->acpi_table_parse_cedt(id, handler_arg, arg); |
67dcdd4d | 72 | else |
814dff9a | 73 | rc = acpi_table_parse_cedt(id, handler_arg, arg); |
67dcdd4d DW |
74 | |
75 | put_cxl_mock_ops(index); | |
76 | ||
814dff9a | 77 | return rc; |
67dcdd4d | 78 | } |
814dff9a | 79 | EXPORT_SYMBOL_NS_GPL(__wrap_acpi_table_parse_cedt, ACPI); |
67dcdd4d DW |
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 | ||
67dcdd4d DW |
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 | ||
4474ce56 DJ |
134 | struct cxl_hdm *__wrap_devm_cxl_setup_hdm(struct cxl_port *port, |
135 | struct cxl_endpoint_dvsec_info *info) | |
136 | ||
d17d0540 DW |
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)) | |
4474ce56 | 143 | cxlhdm = ops->devm_cxl_setup_hdm(port, info); |
d17d0540 | 144 | else |
4474ce56 | 145 | cxlhdm = devm_cxl_setup_hdm(port, info); |
d17d0540 DW |
146 | put_cxl_mock_ops(index); |
147 | ||
148 | return cxlhdm; | |
149 | } | |
150 | EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_setup_hdm, CXL); | |
151 | ||
eb0764b8 DW |
152 | int __wrap_devm_cxl_enable_hdm(struct cxl_port *port, struct cxl_hdm *cxlhdm) |
153 | { | |
154 | int index, rc; | |
155 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
156 | ||
157 | if (ops && ops->is_mock_port(port->uport)) | |
158 | rc = 0; | |
159 | else | |
160 | rc = devm_cxl_enable_hdm(port, cxlhdm); | |
161 | put_cxl_mock_ops(index); | |
162 | ||
163 | return rc; | |
164 | } | |
165 | EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enable_hdm, CXL); | |
166 | ||
664bf115 | 167 | int __wrap_devm_cxl_add_passthrough_decoder(struct cxl_port *port) |
d17d0540 DW |
168 | { |
169 | int rc, index; | |
170 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
171 | ||
172 | if (ops && ops->is_mock_port(port->uport)) | |
664bf115 | 173 | rc = ops->devm_cxl_add_passthrough_decoder(port); |
d17d0540 | 174 | else |
664bf115 | 175 | rc = devm_cxl_add_passthrough_decoder(port); |
d17d0540 DW |
176 | put_cxl_mock_ops(index); |
177 | ||
178 | return rc; | |
179 | } | |
180 | EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_passthrough_decoder, CXL); | |
181 | ||
b777e9be DJ |
182 | int __wrap_devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, |
183 | struct cxl_endpoint_dvsec_info *info) | |
d17d0540 DW |
184 | { |
185 | int rc, index; | |
186 | struct cxl_port *port = cxlhdm->port; | |
187 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
188 | ||
189 | if (ops && ops->is_mock_port(port->uport)) | |
b777e9be | 190 | rc = ops->devm_cxl_enumerate_decoders(cxlhdm, info); |
d17d0540 | 191 | else |
b777e9be | 192 | rc = devm_cxl_enumerate_decoders(cxlhdm, info); |
d17d0540 DW |
193 | put_cxl_mock_ops(index); |
194 | ||
195 | return rc; | |
196 | } | |
197 | EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_enumerate_decoders, CXL); | |
198 | ||
664bf115 | 199 | int __wrap_devm_cxl_port_enumerate_dports(struct cxl_port *port) |
98d2d3a2 DW |
200 | { |
201 | int rc, index; | |
202 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
203 | ||
204 | if (ops && ops->is_mock_port(port->uport)) | |
664bf115 | 205 | rc = ops->devm_cxl_port_enumerate_dports(port); |
98d2d3a2 | 206 | else |
664bf115 | 207 | rc = devm_cxl_port_enumerate_dports(port); |
98d2d3a2 DW |
208 | put_cxl_mock_ops(index); |
209 | ||
210 | return rc; | |
211 | } | |
212 | EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_port_enumerate_dports, CXL); | |
213 | ||
2e4ba0ec DW |
214 | int __wrap_cxl_await_media_ready(struct cxl_dev_state *cxlds) |
215 | { | |
216 | int rc, index; | |
217 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
218 | ||
219 | if (ops && ops->is_mock_dev(cxlds->dev)) | |
220 | rc = 0; | |
221 | else | |
222 | rc = cxl_await_media_ready(cxlds); | |
223 | put_cxl_mock_ops(index); | |
224 | ||
225 | return rc; | |
226 | } | |
227 | EXPORT_SYMBOL_NS_GPL(__wrap_cxl_await_media_ready, CXL); | |
228 | ||
863fdccd | 229 | int __wrap_cxl_hdm_decode_init(struct cxl_dev_state *cxlds, |
59c3368b DJ |
230 | struct cxl_hdm *cxlhdm, |
231 | struct cxl_endpoint_dvsec_info *info) | |
14d78874 DW |
232 | { |
233 | int rc = 0, index; | |
234 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
235 | ||
863fdccd DW |
236 | if (ops && ops->is_mock_dev(cxlds->dev)) |
237 | rc = 0; | |
238 | else | |
59c3368b | 239 | rc = cxl_hdm_decode_init(cxlds, cxlhdm, info); |
14d78874 DW |
240 | put_cxl_mock_ops(index); |
241 | ||
242 | return rc; | |
243 | } | |
a12562bb | 244 | EXPORT_SYMBOL_NS_GPL(__wrap_cxl_hdm_decode_init, CXL); |
14d78874 | 245 | |
59c3368b DJ |
246 | int __wrap_cxl_dvsec_rr_decode(struct device *dev, int dvsec, |
247 | struct cxl_endpoint_dvsec_info *info) | |
248 | { | |
249 | int rc = 0, index; | |
250 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
251 | ||
252 | if (ops && ops->is_mock_dev(dev)) | |
253 | rc = 0; | |
254 | else | |
255 | rc = cxl_dvsec_rr_decode(dev, dvsec, info); | |
256 | put_cxl_mock_ops(index); | |
257 | ||
258 | return rc; | |
259 | } | |
260 | EXPORT_SYMBOL_NS_GPL(__wrap_cxl_dvsec_rr_decode, CXL); | |
261 | ||
eb4663b0 RR |
262 | struct cxl_dport *__wrap_devm_cxl_add_rch_dport(struct cxl_port *port, |
263 | struct device *dport_dev, | |
264 | int port_id, | |
265 | resource_size_t rcrb) | |
266 | { | |
267 | int index; | |
268 | struct cxl_dport *dport; | |
269 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
270 | ||
271 | if (ops && ops->is_mock_port(dport_dev)) { | |
272 | dport = devm_cxl_add_dport(port, dport_dev, port_id, | |
273 | CXL_RESOURCE_NONE); | |
06193378 DW |
274 | if (!IS_ERR(dport)) { |
275 | dport->rcrb.base = rcrb; | |
eb4663b0 | 276 | dport->rch = true; |
06193378 | 277 | } |
eb4663b0 RR |
278 | } else |
279 | dport = devm_cxl_add_rch_dport(port, dport_dev, port_id, rcrb); | |
280 | put_cxl_mock_ops(index); | |
281 | ||
282 | return dport; | |
283 | } | |
284 | EXPORT_SYMBOL_NS_GPL(__wrap_devm_cxl_add_rch_dport, CXL); | |
285 | ||
286 | resource_size_t __wrap_cxl_rcd_component_reg_phys(struct device *dev, | |
287 | struct cxl_dport *dport) | |
d5b1a271 RR |
288 | { |
289 | int index; | |
290 | resource_size_t component_reg_phys; | |
291 | struct cxl_mock_ops *ops = get_cxl_mock_ops(&index); | |
292 | ||
293 | if (ops && ops->is_mock_port(dev)) | |
eb4663b0 | 294 | component_reg_phys = CXL_RESOURCE_NONE; |
d5b1a271 | 295 | else |
eb4663b0 | 296 | component_reg_phys = cxl_rcd_component_reg_phys(dev, dport); |
d5b1a271 RR |
297 | put_cxl_mock_ops(index); |
298 | ||
299 | return component_reg_phys; | |
300 | } | |
eb4663b0 | 301 | EXPORT_SYMBOL_NS_GPL(__wrap_cxl_rcd_component_reg_phys, CXL); |
d5b1a271 | 302 | |
67dcdd4d | 303 | MODULE_LICENSE("GPL v2"); |
814dff9a | 304 | MODULE_IMPORT_NS(ACPI); |
98d2d3a2 | 305 | MODULE_IMPORT_NS(CXL); |