aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Antognolli <rafael.antognolli@intel.com>2016-01-21 18:10:19 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-02-12 08:22:40 -0500
commite94cb37b34eb8a88fe847438dba55c3f18bf024a (patch)
tree1aaa38c44181b51b36c201373d43ed9f3006d635
parent70412cfa6ddebcc01e6b01b3fccb6068e48596ac (diff)
drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers.
This module is heavily based on i2c-dev. Once loaded, it provides one dev node per DP AUX channel, named drm_dp_auxN, where N is an integer. It's possible to know which connector owns this aux channel by looking at the respective sysfs /sys/class/drm_aux_dev/drm_dp_auxN/connector, if the connector device pointer was correctly set in the aux helper struct. Two main operations are provided on the registers read and write. The address of the register to be read or written is given using lseek. The seek position is updated upon read or write. v2: - lseek is used to select the register to read/write - read/write are used instead of ioctl - no blocking_notifier is used, just a direct callback v3: - use drm_dp_aux_dev prefix for public functions - chardev is named drm_dp_auxN - read/write don't allocate a buffer anymore, and transfer up to 16 bytes a time - remove notifier list from the implementation - option on menuconfig is now a boolean - add inline stub functions to avoid breakage when this option is disabled v4: - fix build system changes - actually disable this module when not selected. v5: - Use kref to avoid device closing while still in use - Don't use list, use an idr for storing aux_dev - Remove "connector" attribute - set aux.dev to the connector drm_connector device, instead of drm_device v6: - Use atomic_t for usage count - Use a mutex instead of spinlock for idr lock - Destroy chardev immediately on unregister - other minor suggestions from Ville v7: - style fixes - error handling fixes v8: - more error handling fixes v9: - remove module_init and module_exit, and add drm_dp_aux_dev_init/exit to drm_kms_helper_init/exit. Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1453417821-2811-3-git-send-email-rafael.antognolli@intel.com
-rw-r--r--drivers/gpu/drm/Kconfig8
-rw-r--r--drivers/gpu/drm/Makefile1
-rw-r--r--drivers/gpu/drm/drm_dp_aux_dev.c368
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c16
-rw-r--r--drivers/gpu/drm/drm_kms_helper_common.c15
-rw-r--r--include/drm/drm_dp_aux_dev.h62
6 files changed, 468 insertions, 2 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 8ae7ab68cb97..7b1560792e6a 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -25,6 +25,14 @@ config DRM_MIPI_DSI
25 bool 25 bool
26 depends on DRM 26 depends on DRM
27 27
28config DRM_DP_AUX_CHARDEV
29 bool "DRM DP AUX Interface"
30 depends on DRM
31 help
32 Choose this option to enable a /dev/drm_dp_auxN node that allows to
33 read and write values to arbitrary DPCD registers on the DP aux
34 channel.
35
28config DRM_KMS_HELPER 36config DRM_KMS_HELPER
29 tristate 37 tristate
30 depends on DRM 38 depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index f619ff4b22a2..e07fd93981e1 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -28,6 +28,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
28drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 28drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
29drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 29drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
30drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o 30drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
31drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
31 32
32obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o 33obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
33 34
diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c b/drivers/gpu/drm/drm_dp_aux_dev.c
new file mode 100644
index 000000000000..f73b38b33a8e
--- /dev/null
+++ b/drivers/gpu/drm/drm_dp_aux_dev.c
@@ -0,0 +1,368 @@
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rafael Antognolli <rafael.antognolli@intel.com>
25 *
26 */
27
28#include <linux/device.h>
29#include <linux/fs.h>
30#include <linux/slab.h>
31#include <linux/init.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/uaccess.h>
35#include <drm/drm_dp_helper.h>
36#include <drm/drm_crtc.h>
37#include <drm/drmP.h>
38
39struct drm_dp_aux_dev {
40 unsigned index;
41 struct drm_dp_aux *aux;
42 struct device *dev;
43 struct kref refcount;
44 atomic_t usecount;
45};
46
47#define DRM_AUX_MINORS 256
48#define AUX_MAX_OFFSET (1 << 20)
49static DEFINE_IDR(aux_idr);
50static DEFINE_MUTEX(aux_idr_mutex);
51static struct class *drm_dp_aux_dev_class;
52static int drm_dev_major = -1;
53
54static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
55{
56 struct drm_dp_aux_dev *aux_dev = NULL;
57
58 mutex_lock(&aux_idr_mutex);
59 aux_dev = idr_find(&aux_idr, index);
60 if (!kref_get_unless_zero(&aux_dev->refcount))
61 aux_dev = NULL;
62 mutex_unlock(&aux_idr_mutex);
63
64 return aux_dev;
65}
66
67static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
68{
69 struct drm_dp_aux_dev *aux_dev;
70 int index;
71
72 aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL);
73 if (!aux_dev)
74 return ERR_PTR(-ENOMEM);
75 aux_dev->aux = aux;
76 atomic_set(&aux_dev->usecount, 1);
77 kref_init(&aux_dev->refcount);
78
79 mutex_lock(&aux_idr_mutex);
80 index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS,
81 GFP_KERNEL);
82 mutex_unlock(&aux_idr_mutex);
83 if (index < 0) {
84 kfree(aux_dev);
85 return ERR_PTR(index);
86 }
87 aux_dev->index = index;
88
89 return aux_dev;
90}
91
92static void release_drm_dp_aux_dev(struct kref *ref)
93{
94 struct drm_dp_aux_dev *aux_dev =
95 container_of(ref, struct drm_dp_aux_dev, refcount);
96
97 kfree(aux_dev);
98}
99
100static ssize_t name_show(struct device *dev,
101 struct device_attribute *attr, char *buf)
102{
103 ssize_t res;
104 struct drm_dp_aux_dev *aux_dev =
105 drm_dp_aux_dev_get_by_minor(MINOR(dev->devt));
106
107 if (!aux_dev)
108 return -ENODEV;
109
110 res = sprintf(buf, "%s\n", aux_dev->aux->name);
111 kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
112
113 return res;
114}
115static DEVICE_ATTR_RO(name);
116
117static struct attribute *drm_dp_aux_attrs[] = {
118 &dev_attr_name.attr,
119 NULL,
120};
121ATTRIBUTE_GROUPS(drm_dp_aux);
122
123static int auxdev_open(struct inode *inode, struct file *file)
124{
125 unsigned int minor = iminor(inode);
126 struct drm_dp_aux_dev *aux_dev;
127
128 aux_dev = drm_dp_aux_dev_get_by_minor(minor);
129 if (!aux_dev)
130 return -ENODEV;
131
132 file->private_data = aux_dev;
133 return 0;
134}
135
136static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
137{
138 return fixed_size_llseek(file, offset, whence, AUX_MAX_OFFSET);
139}
140
141static ssize_t auxdev_read(struct file *file, char __user *buf, size_t count,
142 loff_t *offset)
143{
144 size_t bytes_pending, num_bytes_processed = 0;
145 struct drm_dp_aux_dev *aux_dev = file->private_data;
146 ssize_t res = 0;
147
148 if (!atomic_inc_not_zero(&aux_dev->usecount))
149 return -ENODEV;
150
151 bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - (*offset));
152
153 if (!access_ok(VERIFY_WRITE, buf, bytes_pending)) {
154 res = -EFAULT;
155 goto out;
156 }
157
158 while (bytes_pending > 0) {
159 uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
160 ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
161
162 res = drm_dp_dpcd_read(aux_dev->aux, *offset, localbuf, todo);
163 if (res <= 0) {
164 res = num_bytes_processed ? num_bytes_processed : res;
165 goto out;
166 }
167 if (__copy_to_user(buf + num_bytes_processed, localbuf, res)) {
168 res = num_bytes_processed ?
169 num_bytes_processed : -EFAULT;
170 goto out;
171 }
172 bytes_pending -= res;
173 *offset += res;
174 num_bytes_processed += res;
175 res = num_bytes_processed;
176 }
177
178out:
179 atomic_dec(&aux_dev->usecount);
180 wake_up_atomic_t(&aux_dev->usecount);
181 return res;
182}
183
184static ssize_t auxdev_write(struct file *file, const char __user *buf,
185 size_t count, loff_t *offset)
186{
187 size_t bytes_pending, num_bytes_processed = 0;
188 struct drm_dp_aux_dev *aux_dev = file->private_data;
189 ssize_t res = 0;
190
191 if (!atomic_inc_not_zero(&aux_dev->usecount))
192 return -ENODEV;
193
194 bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - *offset);
195
196 if (!access_ok(VERIFY_READ, buf, bytes_pending)) {
197 res = -EFAULT;
198 goto out;
199 }
200
201 while (bytes_pending > 0) {
202 uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
203 ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
204
205 if (__copy_from_user(localbuf,
206 buf + num_bytes_processed, todo)) {
207 res = num_bytes_processed ?
208 num_bytes_processed : -EFAULT;
209 goto out;
210 }
211
212 res = drm_dp_dpcd_write(aux_dev->aux, *offset, localbuf, todo);
213 if (res <= 0) {
214 res = num_bytes_processed ? num_bytes_processed : res;
215 goto out;
216 }
217 bytes_pending -= res;
218 *offset += res;
219 num_bytes_processed += res;
220 res = num_bytes_processed;
221 }
222
223out:
224 atomic_dec(&aux_dev->usecount);
225 wake_up_atomic_t(&aux_dev->usecount);
226 return res;
227}
228
229static int auxdev_release(struct inode *inode, struct file *file)
230{
231 struct drm_dp_aux_dev *aux_dev = file->private_data;
232
233 kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
234 return 0;
235}
236
237static const struct file_operations auxdev_fops = {
238 .owner = THIS_MODULE,
239 .llseek = auxdev_llseek,
240 .read = auxdev_read,
241 .write = auxdev_write,
242 .open = auxdev_open,
243 .release = auxdev_release,
244};
245
246#define to_auxdev(d) container_of(d, struct drm_dp_aux_dev, aux)
247
248static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
249{
250 struct drm_dp_aux_dev *iter, *aux_dev = NULL;
251 int id;
252
253 /* don't increase kref count here because this function should only be
254 * used by drm_dp_aux_unregister_devnode. Thus, it will always have at
255 * least one reference - the one that drm_dp_aux_register_devnode
256 * created
257 */
258 mutex_lock(&aux_idr_mutex);
259 idr_for_each_entry(&aux_idr, iter, id) {
260 if (iter->aux == aux) {
261 aux_dev = iter;
262 break;
263 }
264 }
265 mutex_unlock(&aux_idr_mutex);
266 return aux_dev;
267}
268
269static int auxdev_wait_atomic_t(atomic_t *p)
270{
271 schedule();
272 return 0;
273}
274/**
275 * drm_dp_aux_unregister_devnode() - unregister a devnode for this aux channel
276 * @aux: DisplayPort AUX channel
277 *
278 * Returns 0 on success or a negative error code on failure.
279 */
280void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
281{
282 struct drm_dp_aux_dev *aux_dev;
283 unsigned int minor;
284
285 aux_dev = drm_dp_aux_dev_get_by_aux(aux);
286 if (!aux_dev) /* attach must have failed */
287 return;
288
289 mutex_lock(&aux_idr_mutex);
290 idr_remove(&aux_idr, aux_dev->index);
291 mutex_unlock(&aux_idr_mutex);
292
293 atomic_dec(&aux_dev->usecount);
294 wait_on_atomic_t(&aux_dev->usecount, auxdev_wait_atomic_t,
295 TASK_UNINTERRUPTIBLE);
296
297 minor = aux_dev->index;
298 if (aux_dev->dev)
299 device_destroy(drm_dp_aux_dev_class,
300 MKDEV(drm_dev_major, minor));
301
302 DRM_DEBUG("drm_dp_aux_dev: aux [%s] unregistering\n", aux->name);
303 kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
304}
305EXPORT_SYMBOL(drm_dp_aux_unregister_devnode);
306
307/**
308 * drm_dp_aux_register_devnode() - register a devnode for this aux channel
309 * @aux: DisplayPort AUX channel
310 *
311 * Returns 0 on success or a negative error code on failure.
312 */
313int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
314{
315 struct drm_dp_aux_dev *aux_dev;
316 int res;
317
318 aux_dev = alloc_drm_dp_aux_dev(aux);
319 if (IS_ERR(aux_dev))
320 return PTR_ERR(aux_dev);
321
322 aux_dev->dev = device_create(drm_dp_aux_dev_class, aux->dev,
323 MKDEV(drm_dev_major, aux_dev->index), NULL,
324 "drm_dp_aux%d", aux_dev->index);
325 if (IS_ERR(aux_dev->dev)) {
326 res = PTR_ERR(aux_dev->dev);
327 aux_dev->dev = NULL;
328 goto error;
329 }
330
331 DRM_DEBUG("drm_dp_aux_dev: aux [%s] registered as minor %d\n",
332 aux->name, aux_dev->index);
333 return 0;
334error:
335 drm_dp_aux_unregister_devnode(aux);
336 return res;
337}
338EXPORT_SYMBOL(drm_dp_aux_register_devnode);
339
340int drm_dp_aux_dev_init(void)
341{
342 int res;
343
344 drm_dp_aux_dev_class = class_create(THIS_MODULE, "drm_dp_aux_dev");
345 if (IS_ERR(drm_dp_aux_dev_class)) {
346 res = PTR_ERR(drm_dp_aux_dev_class);
347 goto out;
348 }
349 drm_dp_aux_dev_class->dev_groups = drm_dp_aux_groups;
350
351 res = register_chrdev(0, "aux", &auxdev_fops);
352 if (res < 0)
353 goto out;
354 drm_dev_major = res;
355
356 return 0;
357out:
358 class_destroy(drm_dp_aux_dev_class);
359 return res;
360}
361EXPORT_SYMBOL(drm_dp_aux_dev_init);
362
363void drm_dp_aux_dev_exit(void)
364{
365 unregister_chrdev(drm_dev_major, "aux");
366 class_destroy(drm_dp_aux_dev_class);
367}
368EXPORT_SYMBOL(drm_dp_aux_dev_exit);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 9535c5b60387..7d58f594cffe 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -28,6 +28,7 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <drm/drm_dp_helper.h> 30#include <drm/drm_dp_helper.h>
31#include <drm/drm_dp_aux_dev.h>
31#include <drm/drmP.h> 32#include <drm/drmP.h>
32 33
33/** 34/**
@@ -754,6 +755,8 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
754 */ 755 */
755int drm_dp_aux_register(struct drm_dp_aux *aux) 756int drm_dp_aux_register(struct drm_dp_aux *aux)
756{ 757{
758 int ret;
759
757 mutex_init(&aux->hw_mutex); 760 mutex_init(&aux->hw_mutex);
758 761
759 aux->ddc.algo = &drm_dp_i2c_algo; 762 aux->ddc.algo = &drm_dp_i2c_algo;
@@ -768,7 +771,17 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
768 strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev), 771 strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
769 sizeof(aux->ddc.name)); 772 sizeof(aux->ddc.name));
770 773
771 return i2c_add_adapter(&aux->ddc); 774 ret = drm_dp_aux_register_devnode(aux);
775 if (ret)
776 return ret;
777
778 ret = i2c_add_adapter(&aux->ddc);
779 if (ret) {
780 drm_dp_aux_unregister_devnode(aux);
781 return ret;
782 }
783
784 return 0;
772} 785}
773EXPORT_SYMBOL(drm_dp_aux_register); 786EXPORT_SYMBOL(drm_dp_aux_register);
774 787
@@ -778,6 +791,7 @@ EXPORT_SYMBOL(drm_dp_aux_register);
778 */ 791 */
779void drm_dp_aux_unregister(struct drm_dp_aux *aux) 792void drm_dp_aux_unregister(struct drm_dp_aux *aux)
780{ 793{
794 drm_dp_aux_unregister_devnode(aux);
781 i2c_del_adapter(&aux->ddc); 795 i2c_del_adapter(&aux->ddc);
782} 796}
783EXPORT_SYMBOL(drm_dp_aux_unregister); 797EXPORT_SYMBOL(drm_dp_aux_unregister);
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
index d3610058de3c..3187c4bb01cb 100644
--- a/drivers/gpu/drm/drm_kms_helper_common.c
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -27,6 +27,7 @@
27 27
28#include <drm/drmP.h> 28#include <drm/drmP.h>
29#include <drm/drm_fb_helper.h> 29#include <drm/drm_fb_helper.h>
30#include <drm/drm_dp_aux_dev.h>
30 31
31MODULE_AUTHOR("David Airlie, Jesse Barnes"); 32MODULE_AUTHOR("David Airlie, Jesse Barnes");
32MODULE_DESCRIPTION("DRM KMS helper"); 33MODULE_DESCRIPTION("DRM KMS helper");
@@ -34,13 +35,25 @@ MODULE_LICENSE("GPL and additional rights");
34 35
35static int __init drm_kms_helper_init(void) 36static int __init drm_kms_helper_init(void)
36{ 37{
38 int ret;
39
37 /* Call init functions from specific kms helpers here */ 40 /* Call init functions from specific kms helpers here */
38 return drm_fb_helper_modinit(); 41 ret = drm_fb_helper_modinit();
42 if (ret < 0)
43 goto out;
44
45 ret = drm_dp_aux_dev_init();
46 if (ret < 0)
47 goto out;
48
49out:
50 return ret;
39} 51}
40 52
41static void __exit drm_kms_helper_exit(void) 53static void __exit drm_kms_helper_exit(void)
42{ 54{
43 /* Call exit functions from specific kms helpers here */ 55 /* Call exit functions from specific kms helpers here */
56 drm_dp_aux_dev_exit();
44} 57}
45 58
46module_init(drm_kms_helper_init); 59module_init(drm_kms_helper_init);
diff --git a/include/drm/drm_dp_aux_dev.h b/include/drm/drm_dp_aux_dev.h
new file mode 100644
index 000000000000..1b76d990d8ab
--- /dev/null
+++ b/include/drm/drm_dp_aux_dev.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rafael Antognolli <rafael.antognolli@intel.com>
25 *
26 */
27
28#ifndef DRM_DP_AUX_DEV
29#define DRM_DP_AUX_DEV
30
31#include <drm/drm_dp_helper.h>
32
33#ifdef CONFIG_DRM_DP_AUX_CHARDEV
34
35int drm_dp_aux_dev_init(void);
36void drm_dp_aux_dev_exit(void);
37int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
38void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
39
40#else
41
42static inline int drm_dp_aux_dev_init(void)
43{
44 return 0;
45}
46
47static inline void drm_dp_aux_dev_exit(void)
48{
49}
50
51static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
52{
53 return 0;
54}
55
56static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
57{
58}
59
60#endif
61
62#endif