1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright 2021 Google Inc. |
4 | * |
5 | * The DP AUX bus is used for devices that are connected over a DisplayPort |
6 | * AUX bus. The device on the far side of the bus is referred to as an |
7 | * endpoint in this code. |
8 | * |
9 | * There is only one device connected to the DP AUX bus: an eDP panel. |
10 | * Though historically panels (even DP panels) have been modeled as simple |
11 | * platform devices, putting them under the DP AUX bus allows the panel driver |
12 | * to perform transactions on that bus. |
13 | */ |
14 | |
15 | #include <linux/init.h> |
16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> |
18 | #include <linux/of_device.h> |
19 | #include <linux/pm_domain.h> |
20 | #include <linux/pm_runtime.h> |
21 | |
22 | #include <drm/display/drm_dp_aux_bus.h> |
23 | #include <drm/display/drm_dp_helper.h> |
24 | |
25 | struct dp_aux_ep_device_with_data { |
26 | struct dp_aux_ep_device aux_ep; |
27 | int (*done_probing)(struct drm_dp_aux *aux); |
28 | }; |
29 | |
30 | /** |
31 | * dp_aux_ep_match() - The match function for the dp_aux_bus. |
32 | * @dev: The device to match. |
33 | * @drv: The driver to try to match against. |
34 | * |
35 | * At the moment, we just match on device tree. |
36 | * |
37 | * Return: True if this driver matches this device; false otherwise. |
38 | */ |
39 | static int dp_aux_ep_match(struct device *dev, struct device_driver *drv) |
40 | { |
41 | return !!of_match_device(matches: drv->of_match_table, dev); |
42 | } |
43 | |
44 | /** |
45 | * dp_aux_ep_probe() - The probe function for the dp_aux_bus. |
46 | * @dev: The device to probe. |
47 | * |
48 | * Calls through to the endpoint driver probe. |
49 | * |
50 | * Return: 0 if no error or negative error code. |
51 | */ |
52 | static int dp_aux_ep_probe(struct device *dev) |
53 | { |
54 | struct dp_aux_ep_driver *aux_ep_drv = to_dp_aux_ep_drv(drv: dev->driver); |
55 | struct dp_aux_ep_device *aux_ep = to_dp_aux_ep_dev(dev); |
56 | struct dp_aux_ep_device_with_data *aux_ep_with_data = |
57 | container_of(aux_ep, struct dp_aux_ep_device_with_data, aux_ep); |
58 | int ret; |
59 | |
60 | ret = dev_pm_domain_attach(dev, power_on: true); |
61 | if (ret) |
62 | return dev_err_probe(dev, err: ret, fmt: "Failed to attach to PM Domain\n" ); |
63 | |
64 | ret = aux_ep_drv->probe(aux_ep); |
65 | if (ret) |
66 | goto err_attached; |
67 | |
68 | if (aux_ep_with_data->done_probing) { |
69 | ret = aux_ep_with_data->done_probing(aux_ep->aux); |
70 | if (ret) { |
71 | /* |
72 | * The done_probing() callback should not return |
73 | * -EPROBE_DEFER to us. If it does, we treat it as an |
74 | * error. Passing it on as-is would cause the _panel_ |
75 | * to defer. |
76 | */ |
77 | if (ret == -EPROBE_DEFER) { |
78 | dev_err(dev, |
79 | "DP AUX done_probing() can't defer\n" ); |
80 | ret = -EINVAL; |
81 | } |
82 | goto err_probed; |
83 | } |
84 | } |
85 | |
86 | return 0; |
87 | err_probed: |
88 | if (aux_ep_drv->remove) |
89 | aux_ep_drv->remove(aux_ep); |
90 | err_attached: |
91 | dev_pm_domain_detach(dev, power_off: true); |
92 | |
93 | return ret; |
94 | } |
95 | |
96 | /** |
97 | * dp_aux_ep_remove() - The remove function for the dp_aux_bus. |
98 | * @dev: The device to remove. |
99 | * |
100 | * Calls through to the endpoint driver remove. |
101 | */ |
102 | static void dp_aux_ep_remove(struct device *dev) |
103 | { |
104 | struct dp_aux_ep_driver *aux_ep_drv = to_dp_aux_ep_drv(drv: dev->driver); |
105 | struct dp_aux_ep_device *aux_ep = to_dp_aux_ep_dev(dev); |
106 | |
107 | if (aux_ep_drv->remove) |
108 | aux_ep_drv->remove(aux_ep); |
109 | dev_pm_domain_detach(dev, power_off: true); |
110 | } |
111 | |
112 | /** |
113 | * dp_aux_ep_shutdown() - The shutdown function for the dp_aux_bus. |
114 | * @dev: The device to shutdown. |
115 | * |
116 | * Calls through to the endpoint driver shutdown. |
117 | */ |
118 | static void dp_aux_ep_shutdown(struct device *dev) |
119 | { |
120 | struct dp_aux_ep_driver *aux_ep_drv; |
121 | |
122 | if (!dev->driver) |
123 | return; |
124 | |
125 | aux_ep_drv = to_dp_aux_ep_drv(drv: dev->driver); |
126 | if (aux_ep_drv->shutdown) |
127 | aux_ep_drv->shutdown(to_dp_aux_ep_dev(dev)); |
128 | } |
129 | |
130 | static const struct bus_type dp_aux_bus_type = { |
131 | .name = "dp-aux" , |
132 | .match = dp_aux_ep_match, |
133 | .probe = dp_aux_ep_probe, |
134 | .remove = dp_aux_ep_remove, |
135 | .shutdown = dp_aux_ep_shutdown, |
136 | }; |
137 | |
138 | static ssize_t modalias_show(struct device *dev, |
139 | struct device_attribute *attr, char *buf) |
140 | { |
141 | return of_device_modalias(dev, str: buf, PAGE_SIZE); |
142 | } |
143 | static DEVICE_ATTR_RO(modalias); |
144 | |
145 | static struct attribute *dp_aux_ep_dev_attrs[] = { |
146 | &dev_attr_modalias.attr, |
147 | NULL, |
148 | }; |
149 | ATTRIBUTE_GROUPS(dp_aux_ep_dev); |
150 | |
151 | /** |
152 | * dp_aux_ep_dev_release() - Free memory for the dp_aux_ep device |
153 | * @dev: The device to free. |
154 | */ |
155 | static void dp_aux_ep_dev_release(struct device *dev) |
156 | { |
157 | struct dp_aux_ep_device *aux_ep = to_dp_aux_ep_dev(dev); |
158 | struct dp_aux_ep_device_with_data *aux_ep_with_data = |
159 | container_of(aux_ep, struct dp_aux_ep_device_with_data, aux_ep); |
160 | |
161 | kfree(objp: aux_ep_with_data); |
162 | } |
163 | |
164 | static int dp_aux_ep_dev_modalias(const struct device *dev, struct kobj_uevent_env *env) |
165 | { |
166 | return of_device_uevent_modalias(dev, env); |
167 | } |
168 | |
169 | static struct device_type dp_aux_device_type_type = { |
170 | .groups = dp_aux_ep_dev_groups, |
171 | .uevent = dp_aux_ep_dev_modalias, |
172 | .release = dp_aux_ep_dev_release, |
173 | }; |
174 | |
175 | /** |
176 | * of_dp_aux_ep_destroy() - Destroy an DP AUX endpoint device |
177 | * @dev: The device to destroy. |
178 | * @data: Not used |
179 | * |
180 | * This is just used as a callback by of_dp_aux_depopulate_bus() and |
181 | * is called for _all_ of the child devices of the device providing the AUX bus. |
182 | * We'll only act on those that are of type "dp_aux_bus_type". |
183 | * |
184 | * This function is effectively an inverse of what's in |
185 | * of_dp_aux_populate_bus(). NOTE: since we only populate one child |
186 | * then it's expected that only one device will match all the "if" tests in |
187 | * this function and get to the device_unregister(). |
188 | * |
189 | * Return: 0 if no error or negative error code. |
190 | */ |
191 | static int of_dp_aux_ep_destroy(struct device *dev, void *data) |
192 | { |
193 | struct device_node *np = dev->of_node; |
194 | |
195 | if (dev->bus != &dp_aux_bus_type) |
196 | return 0; |
197 | |
198 | if (!of_node_check_flag(n: np, OF_POPULATED)) |
199 | return 0; |
200 | |
201 | of_node_clear_flag(n: np, OF_POPULATED); |
202 | of_node_put(node: np); |
203 | |
204 | device_unregister(dev); |
205 | |
206 | return 0; |
207 | } |
208 | |
209 | /** |
210 | * of_dp_aux_depopulate_bus() - Undo of_dp_aux_populate_bus |
211 | * @aux: The AUX channel whose device we want to depopulate |
212 | * |
213 | * This will destroy the device that was created |
214 | * by of_dp_aux_populate_bus(). |
215 | */ |
216 | void of_dp_aux_depopulate_bus(struct drm_dp_aux *aux) |
217 | { |
218 | device_for_each_child_reverse(dev: aux->dev, NULL, fn: of_dp_aux_ep_destroy); |
219 | } |
220 | EXPORT_SYMBOL_GPL(of_dp_aux_depopulate_bus); |
221 | |
222 | /** |
223 | * of_dp_aux_populate_bus() - Populate the endpoint device on the DP AUX |
224 | * @aux: The AUX channel whose device we want to populate. It is required that |
225 | * drm_dp_aux_init() has already been called for this AUX channel. |
226 | * @done_probing: Callback functions to call after EP device finishes probing. |
227 | * Will not be called if there are no EP devices and this |
228 | * function will return -ENODEV. |
229 | * |
230 | * This will populate the device (expected to be an eDP panel) under the |
231 | * "aux-bus" node of the device providing the AUX channel (AKA aux->dev). |
232 | * |
233 | * When this function finishes, it is _possible_ (but not guaranteed) that |
234 | * our sub-device will have finished probing. It should be noted that if our |
235 | * sub-device returns -EPROBE_DEFER or is probing asynchronously for some |
236 | * reason that we will not return any error codes ourselves but our |
237 | * sub-device will _not_ have actually probed successfully yet. |
238 | * |
239 | * In many cases it's important for the caller of this function to be notified |
240 | * when our sub device finishes probing. Our sub device is expected to be an |
241 | * eDP panel and the caller is expected to be an eDP controller. The eDP |
242 | * controller needs to be able to get a reference to the panel when it finishes |
243 | * probing. For this reason the caller can pass in a function pointer that |
244 | * will be called when our sub-device finishes probing. |
245 | * |
246 | * If this function succeeds you should later make sure you call |
247 | * of_dp_aux_depopulate_bus() to undo it, or just use the devm version |
248 | * of this function. |
249 | * |
250 | * Return: 0 if no error or negative error code; returns -ENODEV if there are |
251 | * no children. The done_probing() function won't be called in that |
252 | * case. |
253 | */ |
254 | int of_dp_aux_populate_bus(struct drm_dp_aux *aux, |
255 | int (*done_probing)(struct drm_dp_aux *aux)) |
256 | { |
257 | struct device_node *bus = NULL, *np = NULL; |
258 | struct dp_aux_ep_device *aux_ep; |
259 | struct dp_aux_ep_device_with_data *aux_ep_with_data; |
260 | int ret; |
261 | |
262 | /* drm_dp_aux_init() should have been called already; warn if not */ |
263 | WARN_ON_ONCE(!aux->ddc.algo); |
264 | |
265 | if (!aux->dev->of_node) |
266 | return -ENODEV; |
267 | bus = of_get_child_by_name(node: aux->dev->of_node, name: "aux-bus" ); |
268 | if (!bus) |
269 | return -ENODEV; |
270 | |
271 | np = of_get_next_available_child(node: bus, NULL); |
272 | of_node_put(node: bus); |
273 | if (!np) |
274 | return -ENODEV; |
275 | |
276 | if (of_node_test_and_set_flag(n: np, OF_POPULATED)) { |
277 | dev_err(aux->dev, "DP AUX EP device already populated\n" ); |
278 | ret = -EINVAL; |
279 | goto err_did_get_np; |
280 | } |
281 | |
282 | aux_ep_with_data = kzalloc(size: sizeof(*aux_ep_with_data), GFP_KERNEL); |
283 | if (!aux_ep_with_data) { |
284 | ret = -ENOMEM; |
285 | goto err_did_set_populated; |
286 | } |
287 | |
288 | aux_ep_with_data->done_probing = done_probing; |
289 | |
290 | aux_ep = &aux_ep_with_data->aux_ep; |
291 | aux_ep->aux = aux; |
292 | aux_ep->dev.parent = aux->dev; |
293 | aux_ep->dev.bus = &dp_aux_bus_type; |
294 | aux_ep->dev.type = &dp_aux_device_type_type; |
295 | aux_ep->dev.of_node = of_node_get(node: np); |
296 | dev_set_name(dev: &aux_ep->dev, name: "aux-%s" , dev_name(dev: aux->dev)); |
297 | |
298 | ret = device_register(dev: &aux_ep->dev); |
299 | if (ret) { |
300 | dev_err(aux->dev, "Failed to create AUX EP for %pOF: %d\n" , np, ret); |
301 | |
302 | /* |
303 | * As per docs of device_register(), call this instead |
304 | * of kfree() directly for error cases. |
305 | */ |
306 | put_device(dev: &aux_ep->dev); |
307 | |
308 | goto err_did_set_populated; |
309 | } |
310 | |
311 | return 0; |
312 | |
313 | err_did_set_populated: |
314 | of_node_clear_flag(n: np, OF_POPULATED); |
315 | |
316 | err_did_get_np: |
317 | of_node_put(node: np); |
318 | |
319 | return ret; |
320 | } |
321 | EXPORT_SYMBOL_GPL(of_dp_aux_populate_bus); |
322 | |
323 | static void of_dp_aux_depopulate_bus_void(void *data) |
324 | { |
325 | of_dp_aux_depopulate_bus(data); |
326 | } |
327 | |
328 | /** |
329 | * devm_of_dp_aux_populate_bus() - devm wrapper for of_dp_aux_populate_bus() |
330 | * @aux: The AUX channel whose device we want to populate |
331 | * @done_probing: Callback functions to call after EP device finishes probing. |
332 | * Will not be called if there are no EP devices and this |
333 | * function will return -ENODEV. |
334 | * |
335 | * Handles freeing w/ devm on the device "aux->dev". |
336 | * |
337 | * Return: 0 if no error or negative error code; returns -ENODEV if there are |
338 | * no children. The done_probing() function won't be called in that |
339 | * case. |
340 | */ |
341 | int devm_of_dp_aux_populate_bus(struct drm_dp_aux *aux, |
342 | int (*done_probing)(struct drm_dp_aux *aux)) |
343 | { |
344 | int ret; |
345 | |
346 | ret = of_dp_aux_populate_bus(aux, done_probing); |
347 | if (ret) |
348 | return ret; |
349 | |
350 | return devm_add_action_or_reset(aux->dev, |
351 | of_dp_aux_depopulate_bus_void, aux); |
352 | } |
353 | EXPORT_SYMBOL_GPL(devm_of_dp_aux_populate_bus); |
354 | |
355 | int __dp_aux_dp_driver_register(struct dp_aux_ep_driver *drv, struct module *owner) |
356 | { |
357 | drv->driver.owner = owner; |
358 | drv->driver.bus = &dp_aux_bus_type; |
359 | |
360 | return driver_register(drv: &drv->driver); |
361 | } |
362 | EXPORT_SYMBOL_GPL(__dp_aux_dp_driver_register); |
363 | |
364 | void dp_aux_dp_driver_unregister(struct dp_aux_ep_driver *drv) |
365 | { |
366 | driver_unregister(drv: &drv->driver); |
367 | } |
368 | EXPORT_SYMBOL_GPL(dp_aux_dp_driver_unregister); |
369 | |
370 | static int __init dp_aux_bus_init(void) |
371 | { |
372 | int ret; |
373 | |
374 | ret = bus_register(bus: &dp_aux_bus_type); |
375 | if (ret) |
376 | return ret; |
377 | |
378 | return 0; |
379 | } |
380 | |
381 | static void __exit dp_aux_bus_exit(void) |
382 | { |
383 | bus_unregister(bus: &dp_aux_bus_type); |
384 | } |
385 | |
386 | subsys_initcall(dp_aux_bus_init); |
387 | module_exit(dp_aux_bus_exit); |
388 | |
389 | MODULE_AUTHOR("Douglas Anderson <dianders@chromium.org>" ); |
390 | MODULE_DESCRIPTION("DRM DisplayPort AUX bus" ); |
391 | MODULE_LICENSE("GPL v2" ); |
392 | |