All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 0/3] Add drm_dp_aux chardev support.
@ 2015-12-03 22:53 Rafael Antognolli
  2015-12-03 22:54 ` [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions Rafael Antognolli
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Rafael Antognolli @ 2015-12-03 22:53 UTC (permalink / raw)
  To: intel-gfx, dri-devel

This series implement support to a drm_dp_aux chardev that allows reading and
writing an arbitrary amount of bytes to arbitrary dpcd register addresses using
regular read, write and lseek operations.

Rafael Antognolli (3):
  drm/kms_helper: Add a common place to call init and exit functions.
  drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers.
  drm/dp: Set aux.dev to the drm_connector device, instead of
    drm_device.

 drivers/gpu/drm/Kconfig                 |   8 +
 drivers/gpu/drm/Makefile                |   5 +-
 drivers/gpu/drm/drm_dp_aux_dev.c        | 368 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_dp_helper.c         |  16 +-
 drivers/gpu/drm/drm_fb_helper.c         |   9 +-
 drivers/gpu/drm/drm_kms_helper_common.c |  56 +++++
 drivers/gpu/drm/i915/intel_dp.c         |  22 +-
 include/drm/drm_dp_aux_dev.h            |  62 ++++++
 include/drm/drm_fb_helper.h             |   6 +
 9 files changed, 527 insertions(+), 25 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_dp_aux_dev.c
 create mode 100644 drivers/gpu/drm/drm_kms_helper_common.c
 create mode 100644 include/drm/drm_dp_aux_dev.h

-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions.
  2015-12-03 22:53 [PATCH v9 0/3] Add drm_dp_aux chardev support Rafael Antognolli
@ 2015-12-03 22:54 ` Rafael Antognolli
  2015-12-04  8:33   ` [Intel-gfx] " Daniel Vetter
  2015-12-06 16:24   ` Lukas Wunner
  2015-12-03 22:54 ` [PATCH v9 2/3] drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers Rafael Antognolli
  2015-12-03 22:54 ` [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device Rafael Antognolli
  2 siblings, 2 replies; 8+ messages in thread
From: Rafael Antognolli @ 2015-12-03 22:54 UTC (permalink / raw)
  To: intel-gfx, dri-devel

The module_init and module_exit functions will start here, and call the
subsequent init's and exit's.

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
---
 drivers/gpu/drm/Makefile                |  4 ++-
 drivers/gpu/drm/drm_fb_helper.c         |  9 +++----
 drivers/gpu/drm/drm_kms_helper_common.c | 43 +++++++++++++++++++++++++++++++++
 include/drm/drm_fb_helper.h             |  6 +++++
 4 files changed, 56 insertions(+), 6 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_kms_helper_common.c

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 1e9ff4c..76399da 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -24,7 +24,9 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
 drm-y += $(drm-m)
 
 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
-		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
+		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
+		drm_kms_helper_common.o
+
 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 69cbab5..576f769 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -2175,9 +2175,9 @@ EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
  * but the module doesn't depend on any fb console symbols.  At least
  * attempt to load fbcon to avoid leaving the system without a usable console.
  */
-#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
-static int __init drm_fb_helper_modinit(void)
+int drm_fb_helper_modinit(void)
 {
+#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
 	const char *name = "fbcon";
 	struct module *fbcon;
 
@@ -2187,8 +2187,7 @@ static int __init drm_fb_helper_modinit(void)
 
 	if (!fbcon)
 		request_module_nowait(name);
+#endif
 	return 0;
 }
-
-module_init(drm_fb_helper_modinit);
-#endif
+EXPORT_SYMBOL(drm_fb_helper_modinit);
diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
new file mode 100644
index 0000000..920b2fb
--- /dev/null
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rafael Antognolli <rafael.antognolli@intel.com>
+ *
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+
+static int __init drm_kms_helper_init(void)
+{
+	/* Call init functions from specific kms helpers here */
+	return drm_fb_helper_modinit();
+}
+
+static void __exit drm_kms_helper_exit(void)
+{
+	/* Call exit functions from specific kms helpers here */
+}
+
+module_init(drm_kms_helper_init);
+module_exit(drm_kms_helper_exit);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 87b090c..4fed7a2 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -148,6 +148,7 @@ struct drm_fb_helper {
 };
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
+int drm_fb_helper_modinit(void);
 void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
 			   const struct drm_fb_helper_funcs *funcs);
 int drm_fb_helper_init(struct drm_device *dev,
@@ -212,6 +213,11 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
 int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
 				       struct drm_connector *connector);
 #else
+static inline int drm_fb_helper_modinit(void)
+{
+	return 0;
+}
+
 static inline void drm_fb_helper_prepare(struct drm_device *dev,
 					struct drm_fb_helper *helper,
 					const struct drm_fb_helper_funcs *funcs)
-- 
2.4.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v9 2/3] drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers.
  2015-12-03 22:53 [PATCH v9 0/3] Add drm_dp_aux chardev support Rafael Antognolli
  2015-12-03 22:54 ` [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions Rafael Antognolli
@ 2015-12-03 22:54 ` Rafael Antognolli
  2015-12-03 22:54 ` [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device Rafael Antognolli
  2 siblings, 0 replies; 8+ messages in thread
From: Rafael Antognolli @ 2015-12-03 22:54 UTC (permalink / raw)
  To: intel-gfx, dri-devel

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>
---
 drivers/gpu/drm/Kconfig                 |   8 +
 drivers/gpu/drm/Makefile                |   1 +
 drivers/gpu/drm/drm_dp_aux_dev.c        | 368 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_dp_helper.c         |  16 +-
 drivers/gpu/drm/drm_kms_helper_common.c |  15 +-
 include/drm/drm_dp_aux_dev.h            |  62 ++++++
 6 files changed, 468 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_dp_aux_dev.c
 create mode 100644 include/drm/drm_dp_aux_dev.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c4bf9a1..daefcce 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -25,6 +25,14 @@ config DRM_MIPI_DSI
 	bool
 	depends on DRM
 
+config DRM_DP_AUX_CHARDEV
+	bool "DRM DP AUX Interface"
+	depends on DRM
+	help
+	  Choose this option to enable a /dev/drm_dp_auxN node that allows to
+	  read and write values to arbitrary DPCD registers on the DP aux
+	  channel.
+
 config DRM_KMS_HELPER
 	tristate
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 76399da..57e153d 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -30,6 +30,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
+drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
 
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
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 0000000..f73b38b
--- /dev/null
+++ b/drivers/gpu/drm/drm_dp_aux_dev.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rafael Antognolli <rafael.antognolli@intel.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <drm/drm_dp_helper.h>
+#include <drm/drm_crtc.h>
+#include <drm/drmP.h>
+
+struct drm_dp_aux_dev {
+	unsigned index;
+	struct drm_dp_aux *aux;
+	struct device *dev;
+	struct kref refcount;
+	atomic_t usecount;
+};
+
+#define DRM_AUX_MINORS	256
+#define AUX_MAX_OFFSET	(1 << 20)
+static DEFINE_IDR(aux_idr);
+static DEFINE_MUTEX(aux_idr_mutex);
+static struct class *drm_dp_aux_dev_class;
+static int drm_dev_major = -1;
+
+static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_minor(unsigned index)
+{
+	struct drm_dp_aux_dev *aux_dev = NULL;
+
+	mutex_lock(&aux_idr_mutex);
+	aux_dev = idr_find(&aux_idr, index);
+	if (!kref_get_unless_zero(&aux_dev->refcount))
+		aux_dev = NULL;
+	mutex_unlock(&aux_idr_mutex);
+
+	return aux_dev;
+}
+
+static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *aux_dev;
+	int index;
+
+	aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL);
+	if (!aux_dev)
+		return ERR_PTR(-ENOMEM);
+	aux_dev->aux = aux;
+	atomic_set(&aux_dev->usecount, 1);
+	kref_init(&aux_dev->refcount);
+
+	mutex_lock(&aux_idr_mutex);
+	index = idr_alloc_cyclic(&aux_idr, aux_dev, 0, DRM_AUX_MINORS,
+				 GFP_KERNEL);
+	mutex_unlock(&aux_idr_mutex);
+	if (index < 0) {
+		kfree(aux_dev);
+		return ERR_PTR(index);
+	}
+	aux_dev->index = index;
+
+	return aux_dev;
+}
+
+static void release_drm_dp_aux_dev(struct kref *ref)
+{
+	struct drm_dp_aux_dev *aux_dev =
+		container_of(ref, struct drm_dp_aux_dev, refcount);
+
+	kfree(aux_dev);
+}
+
+static ssize_t name_show(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	ssize_t res;
+	struct drm_dp_aux_dev *aux_dev =
+		drm_dp_aux_dev_get_by_minor(MINOR(dev->devt));
+
+	if (!aux_dev)
+		return -ENODEV;
+
+	res = sprintf(buf, "%s\n", aux_dev->aux->name);
+	kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
+
+	return res;
+}
+static DEVICE_ATTR_RO(name);
+
+static struct attribute *drm_dp_aux_attrs[] = {
+	&dev_attr_name.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(drm_dp_aux);
+
+static int auxdev_open(struct inode *inode, struct file *file)
+{
+	unsigned int minor = iminor(inode);
+	struct drm_dp_aux_dev *aux_dev;
+
+	aux_dev = drm_dp_aux_dev_get_by_minor(minor);
+	if (!aux_dev)
+		return -ENODEV;
+
+	file->private_data = aux_dev;
+	return 0;
+}
+
+static loff_t auxdev_llseek(struct file *file, loff_t offset, int whence)
+{
+	return fixed_size_llseek(file, offset, whence, AUX_MAX_OFFSET);
+}
+
+static ssize_t auxdev_read(struct file *file, char __user *buf, size_t count,
+			   loff_t *offset)
+{
+	size_t bytes_pending, num_bytes_processed = 0;
+	struct drm_dp_aux_dev *aux_dev = file->private_data;
+	ssize_t res = 0;
+
+	if (!atomic_inc_not_zero(&aux_dev->usecount))
+		return -ENODEV;
+
+	bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - (*offset));
+
+	if (!access_ok(VERIFY_WRITE, buf, bytes_pending)) {
+		res = -EFAULT;
+		goto out;
+	}
+
+	while (bytes_pending > 0) {
+		uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
+		ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
+
+		res = drm_dp_dpcd_read(aux_dev->aux, *offset, localbuf, todo);
+		if (res <= 0) {
+			res = num_bytes_processed ? num_bytes_processed : res;
+			goto out;
+		}
+		if (__copy_to_user(buf + num_bytes_processed, localbuf, res)) {
+			res = num_bytes_processed ?
+				num_bytes_processed : -EFAULT;
+			goto out;
+		}
+		bytes_pending -= res;
+		*offset += res;
+		num_bytes_processed += res;
+		res = num_bytes_processed;
+	}
+
+out:
+	atomic_dec(&aux_dev->usecount);
+	wake_up_atomic_t(&aux_dev->usecount);
+	return res;
+}
+
+static ssize_t auxdev_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *offset)
+{
+	size_t bytes_pending, num_bytes_processed = 0;
+	struct drm_dp_aux_dev *aux_dev = file->private_data;
+	ssize_t res = 0;
+
+	if (!atomic_inc_not_zero(&aux_dev->usecount))
+		return -ENODEV;
+
+	bytes_pending = min((loff_t)count, AUX_MAX_OFFSET - *offset);
+
+	if (!access_ok(VERIFY_READ, buf, bytes_pending)) {
+		res = -EFAULT;
+		goto out;
+	}
+
+	while (bytes_pending > 0) {
+		uint8_t localbuf[DP_AUX_MAX_PAYLOAD_BYTES];
+		ssize_t todo = min_t(size_t, bytes_pending, sizeof(localbuf));
+
+		if (__copy_from_user(localbuf,
+				     buf + num_bytes_processed, todo)) {
+			res = num_bytes_processed ?
+				num_bytes_processed : -EFAULT;
+			goto out;
+		}
+
+		res = drm_dp_dpcd_write(aux_dev->aux, *offset, localbuf, todo);
+		if (res <= 0) {
+			res = num_bytes_processed ? num_bytes_processed : res;
+			goto out;
+		}
+		bytes_pending -= res;
+		*offset += res;
+		num_bytes_processed += res;
+		res = num_bytes_processed;
+	}
+
+out:
+	atomic_dec(&aux_dev->usecount);
+	wake_up_atomic_t(&aux_dev->usecount);
+	return res;
+}
+
+static int auxdev_release(struct inode *inode, struct file *file)
+{
+	struct drm_dp_aux_dev *aux_dev = file->private_data;
+
+	kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
+	return 0;
+}
+
+static const struct file_operations auxdev_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= auxdev_llseek,
+	.read		= auxdev_read,
+	.write		= auxdev_write,
+	.open		= auxdev_open,
+	.release	= auxdev_release,
+};
+
+#define to_auxdev(d) container_of(d, struct drm_dp_aux_dev, aux)
+
+static struct drm_dp_aux_dev *drm_dp_aux_dev_get_by_aux(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *iter, *aux_dev = NULL;
+	int id;
+
+	/* don't increase kref count here because this function should only be
+	 * used by drm_dp_aux_unregister_devnode. Thus, it will always have at
+	 * least one reference - the one that drm_dp_aux_register_devnode
+	 * created
+	 */
+	mutex_lock(&aux_idr_mutex);
+	idr_for_each_entry(&aux_idr, iter, id) {
+		if (iter->aux == aux) {
+			aux_dev = iter;
+			break;
+		}
+	}
+	mutex_unlock(&aux_idr_mutex);
+	return aux_dev;
+}
+
+static int auxdev_wait_atomic_t(atomic_t *p)
+{
+	schedule();
+	return 0;
+}
+/**
+ * drm_dp_aux_unregister_devnode() - unregister a devnode for this aux channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *aux_dev;
+	unsigned int minor;
+
+	aux_dev = drm_dp_aux_dev_get_by_aux(aux);
+	if (!aux_dev) /* attach must have failed */
+		return;
+
+	mutex_lock(&aux_idr_mutex);
+	idr_remove(&aux_idr, aux_dev->index);
+	mutex_unlock(&aux_idr_mutex);
+
+	atomic_dec(&aux_dev->usecount);
+	wait_on_atomic_t(&aux_dev->usecount, auxdev_wait_atomic_t,
+			 TASK_UNINTERRUPTIBLE);
+
+	minor = aux_dev->index;
+	if (aux_dev->dev)
+		device_destroy(drm_dp_aux_dev_class,
+			       MKDEV(drm_dev_major, minor));
+
+	DRM_DEBUG("drm_dp_aux_dev: aux [%s] unregistering\n", aux->name);
+	kref_put(&aux_dev->refcount, release_drm_dp_aux_dev);
+}
+EXPORT_SYMBOL(drm_dp_aux_unregister_devnode);
+
+/**
+ * drm_dp_aux_register_devnode() - register a devnode for this aux channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
+{
+	struct drm_dp_aux_dev *aux_dev;
+	int res;
+
+	aux_dev = alloc_drm_dp_aux_dev(aux);
+	if (IS_ERR(aux_dev))
+		return PTR_ERR(aux_dev);
+
+	aux_dev->dev = device_create(drm_dp_aux_dev_class, aux->dev,
+				     MKDEV(drm_dev_major, aux_dev->index), NULL,
+				     "drm_dp_aux%d", aux_dev->index);
+	if (IS_ERR(aux_dev->dev)) {
+		res = PTR_ERR(aux_dev->dev);
+		aux_dev->dev = NULL;
+		goto error;
+	}
+
+	DRM_DEBUG("drm_dp_aux_dev: aux [%s] registered as minor %d\n",
+		  aux->name, aux_dev->index);
+	return 0;
+error:
+	drm_dp_aux_unregister_devnode(aux);
+	return res;
+}
+EXPORT_SYMBOL(drm_dp_aux_register_devnode);
+
+int drm_dp_aux_dev_init(void)
+{
+	int res;
+
+	drm_dp_aux_dev_class = class_create(THIS_MODULE, "drm_dp_aux_dev");
+	if (IS_ERR(drm_dp_aux_dev_class)) {
+		res = PTR_ERR(drm_dp_aux_dev_class);
+		goto out;
+	}
+	drm_dp_aux_dev_class->dev_groups = drm_dp_aux_groups;
+
+	res = register_chrdev(0, "aux", &auxdev_fops);
+	if (res < 0)
+		goto out;
+	drm_dev_major = res;
+
+	return 0;
+out:
+	class_destroy(drm_dp_aux_dev_class);
+	return res;
+}
+EXPORT_SYMBOL(drm_dp_aux_dev_init);
+
+void drm_dp_aux_dev_exit(void)
+{
+	unregister_chrdev(drm_dev_major, "aux");
+	class_destroy(drm_dp_aux_dev_class);
+}
+EXPORT_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 9535c5b..7d58f59 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -28,6 +28,7 @@
 #include <linux/sched.h>
 #include <linux/i2c.h>
 #include <drm/drm_dp_helper.h>
+#include <drm/drm_dp_aux_dev.h>
 #include <drm/drmP.h>
 
 /**
@@ -754,6 +755,8 @@ static const struct i2c_algorithm drm_dp_i2c_algo = {
  */
 int drm_dp_aux_register(struct drm_dp_aux *aux)
 {
+	int ret;
+
 	mutex_init(&aux->hw_mutex);
 
 	aux->ddc.algo = &drm_dp_i2c_algo;
@@ -768,7 +771,17 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
 	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
 		sizeof(aux->ddc.name));
 
-	return i2c_add_adapter(&aux->ddc);
+	ret = drm_dp_aux_register_devnode(aux);
+	if (ret)
+		return ret;
+
+	ret = i2c_add_adapter(&aux->ddc);
+	if (ret) {
+		drm_dp_aux_unregister_devnode(aux);
+		return ret;
+	}
+
+	return 0;
 }
 EXPORT_SYMBOL(drm_dp_aux_register);
 
@@ -778,6 +791,7 @@ EXPORT_SYMBOL(drm_dp_aux_register);
  */
 void drm_dp_aux_unregister(struct drm_dp_aux *aux)
 {
+	drm_dp_aux_unregister_devnode(aux);
 	i2c_del_adapter(&aux->ddc);
 }
 EXPORT_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 920b2fb..2565b9e 100644
--- a/drivers/gpu/drm/drm_kms_helper_common.c
+++ b/drivers/gpu/drm/drm_kms_helper_common.c
@@ -27,16 +27,29 @@
 
 #include <drm/drmP.h>
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_dp_aux_dev.h>
 
 static int __init drm_kms_helper_init(void)
 {
+	int ret;
+
 	/* Call init functions from specific kms helpers here */
-	return drm_fb_helper_modinit();
+	ret = drm_fb_helper_modinit();
+	if (ret < 0)
+		goto out;
+
+	ret = drm_dp_aux_dev_init();
+	if (ret < 0)
+		goto out;
+
+out:
+	return ret;
 }
 
 static void __exit drm_kms_helper_exit(void)
 {
 	/* Call exit functions from specific kms helpers here */
+	drm_dp_aux_dev_exit();
 }
 
 module_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 0000000..1b76d99
--- /dev/null
+++ b/include/drm/drm_dp_aux_dev.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rafael Antognolli <rafael.antognolli@intel.com>
+ *
+ */
+
+#ifndef DRM_DP_AUX_DEV
+#define DRM_DP_AUX_DEV
+
+#include <drm/drm_dp_helper.h>
+
+#ifdef CONFIG_DRM_DP_AUX_CHARDEV
+
+int drm_dp_aux_dev_init(void);
+void drm_dp_aux_dev_exit(void);
+int drm_dp_aux_register_devnode(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux);
+
+#else
+
+static inline int drm_dp_aux_dev_init(void)
+{
+	return 0;
+}
+
+static inline void drm_dp_aux_dev_exit(void)
+{
+}
+
+static inline int drm_dp_aux_register_devnode(struct drm_dp_aux *aux)
+{
+	return 0;
+}
+
+static inline void drm_dp_aux_unregister_devnode(struct drm_dp_aux *aux)
+{
+}
+
+#endif
+
+#endif
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device.
  2015-12-03 22:53 [PATCH v9 0/3] Add drm_dp_aux chardev support Rafael Antognolli
  2015-12-03 22:54 ` [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions Rafael Antognolli
  2015-12-03 22:54 ` [PATCH v9 2/3] drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers Rafael Antognolli
@ 2015-12-03 22:54 ` Rafael Antognolli
  2015-12-06 16:08   ` Lukas Wunner
  2 siblings, 1 reply; 8+ messages in thread
From: Rafael Antognolli @ 2015-12-03 22:54 UTC (permalink / raw)
  To: intel-gfx, dri-devel

So far, the i915 driver and some other drivers set it to the drm_device,
which doesn't allow one to know which DP a given aux channel is related
to. Changing this to be the drm_connector provides proper nesting, still
allowing one to get the drm_device from it. Some drivers already set it
to the drm_connector.

This also removes the need to add a sysfs link for the i2c device under
the connector, as it will already be there.

v2:
 - As a side effect, drm_dp_aux_unregister() must be called before
 intel_connector_unregister(), as both the aux.dev and the i2c adapter
 dev are children of the drm_connector device now. Calling
 drm_dp_aux_unregister() before prevents them from being destroyed
 twice.

Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f2bfca0..515893c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1162,14 +1162,12 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp)
 static void
 intel_dp_aux_fini(struct intel_dp *intel_dp)
 {
-	drm_dp_aux_unregister(&intel_dp->aux);
 	kfree(intel_dp->aux.name);
 }
 
 static int
 intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 {
-	struct drm_device *dev = intel_dp_to_dev(intel_dp);
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	enum port port = intel_dig_port->port;
 	int ret;
@@ -1180,7 +1178,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 	if (!intel_dp->aux.name)
 		return -ENOMEM;
 
-	intel_dp->aux.dev = dev->dev;
+	intel_dp->aux.dev = connector->base.kdev;
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
 
 	DRM_DEBUG_KMS("registering %s bus for %s\n",
@@ -1195,27 +1193,15 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
 		return ret;
 	}
 
-	ret = sysfs_create_link(&connector->base.kdev->kobj,
-				&intel_dp->aux.ddc.dev.kobj,
-				intel_dp->aux.ddc.dev.kobj.name);
-	if (ret < 0) {
-		DRM_ERROR("sysfs_create_link() for %s failed (%d)\n",
-			  intel_dp->aux.name, ret);
-		intel_dp_aux_fini(intel_dp);
-		return ret;
-	}
-
 	return 0;
 }
 
 static void
 intel_dp_connector_unregister(struct intel_connector *intel_connector)
 {
-	struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
-
-	if (!intel_connector->mst_port)
-		sysfs_remove_link(&intel_connector->base.kdev->kobj,
-				  intel_dp->aux.ddc.dev.kobj.name);
+	struct intel_dp *intel_dp =
+		enc_to_intel_dp(&intel_connector->encoder->base);
+	drm_dp_aux_unregister(&intel_dp->aux);
 	intel_connector_unregister(intel_connector);
 }
 
-- 
2.4.3

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Intel-gfx] [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions.
  2015-12-03 22:54 ` [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions Rafael Antognolli
@ 2015-12-04  8:33   ` Daniel Vetter
  2015-12-06 16:24   ` Lukas Wunner
  1 sibling, 0 replies; 8+ messages in thread
From: Daniel Vetter @ 2015-12-04  8:33 UTC (permalink / raw)
  To: Rafael Antognolli; +Cc: intel-gfx, dri-devel

On Thu, Dec 03, 2015 at 02:54:00PM -0800, Rafael Antognolli wrote:
> The module_init and module_exit functions will start here, and call the
> subsequent init's and exit's.
> 
> Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
> ---
>  drivers/gpu/drm/Makefile                |  4 ++-
>  drivers/gpu/drm/drm_fb_helper.c         |  9 +++----
>  drivers/gpu/drm/drm_kms_helper_common.c | 43 +++++++++++++++++++++++++++++++++
>  include/drm/drm_fb_helper.h             |  6 +++++
>  4 files changed, 56 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_kms_helper_common.c
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 1e9ff4c..76399da 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -24,7 +24,9 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
>  drm-y += $(drm-m)
>  
>  drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
> -		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
> +		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
> +		drm_kms_helper_common.o
> +
>  drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
>  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
>  drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 69cbab5..576f769 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -2175,9 +2175,9 @@ EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
>   * but the module doesn't depend on any fb console symbols.  At least
>   * attempt to load fbcon to avoid leaving the system without a usable console.
>   */
> -#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
> -static int __init drm_fb_helper_modinit(void)
> +int drm_fb_helper_modinit(void)
>  {
> +#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
>  	const char *name = "fbcon";
>  	struct module *fbcon;
>  
> @@ -2187,8 +2187,7 @@ static int __init drm_fb_helper_modinit(void)
>  
>  	if (!fbcon)
>  		request_module_nowait(name);
> +#endif
>  	return 0;
>  }
> -
> -module_init(drm_fb_helper_modinit);
> -#endif
> +EXPORT_SYMBOL(drm_fb_helper_modinit);
> diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
> new file mode 100644
> index 0000000..920b2fb
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_kms_helper_common.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright © 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + *    Rafael Antognolli <rafael.antognolli@intel.com>
> + *
> + */
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_fb_helper.h>
> +
> +static int __init drm_kms_helper_init(void)
> +{
> +	/* Call init functions from specific kms helpers here */
> +	return drm_fb_helper_modinit();
> +}
> +
> +static void __exit drm_kms_helper_exit(void)
> +{
> +	/* Call exit functions from specific kms helpers here */
> +}
> +
> +module_init(drm_kms_helper_init);
> +module_exit(drm_kms_helper_exit);

If you do a new file please move all the other module metadata in here too
(MODULE_* macros mostly).

Thanks, Daniel

> diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
> index 87b090c..4fed7a2 100644
> --- a/include/drm/drm_fb_helper.h
> +++ b/include/drm/drm_fb_helper.h
> @@ -148,6 +148,7 @@ struct drm_fb_helper {
>  };
>  
>  #ifdef CONFIG_DRM_FBDEV_EMULATION
> +int drm_fb_helper_modinit(void);
>  void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
>  			   const struct drm_fb_helper_funcs *funcs);
>  int drm_fb_helper_init(struct drm_device *dev,
> @@ -212,6 +213,11 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
>  int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
>  				       struct drm_connector *connector);
>  #else
> +static inline int drm_fb_helper_modinit(void)
> +{
> +	return 0;
> +}
> +
>  static inline void drm_fb_helper_prepare(struct drm_device *dev,
>  					struct drm_fb_helper *helper,
>  					const struct drm_fb_helper_funcs *funcs)
> -- 
> 2.4.3
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device.
  2015-12-03 22:54 ` [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device Rafael Antognolli
@ 2015-12-06 16:08   ` Lukas Wunner
  2016-01-21 23:13     ` Rafael Antognolli
  0 siblings, 1 reply; 8+ messages in thread
From: Lukas Wunner @ 2015-12-06 16:08 UTC (permalink / raw)
  To: Rafael Antognolli; +Cc: intel-gfx, dri-devel

Hi Rafael,

On Thu, Dec 03, 2015 at 02:54:02PM -0800, Rafael Antognolli wrote:
> So far, the i915 driver and some other drivers set it to the drm_device,
> which doesn't allow one to know which DP a given aux channel is related
> to. Changing this to be the drm_connector provides proper nesting, still
> allowing one to get the drm_device from it. Some drivers already set it
> to the drm_connector.
> 
> This also removes the need to add a sysfs link for the i2c device under
> the connector, as it will already be there.
> 
> v2:

Two minor nits, I think this should be "v9" instead of "v2" because
this was newly added since v8, and the subject should be prefixed
"drm/i915" (or "drm/i915/dp" or whatever) instead of "drm/dp" because
this only touches i915 and not drm core.


>  - As a side effect, drm_dp_aux_unregister() must be called before
>  intel_connector_unregister(), as both the aux.dev and the i2c adapter
>  dev are children of the drm_connector device now. Calling
>  drm_dp_aux_unregister() before prevents them from being destroyed
>  twice.

I haven't verified what Ville wrote (that there are WARNs because of
this ordering issue), but if this is true then we need to make sure
all other drivers get the order right, otherwise they'd spew WARNs
as well once this gets merged.

I've checked that for every driver and the only one affected is radeon.
A fix is now in my GitHub repo, feel free to include the commit in your
series if you want to. I haven't been able to actually test it though
as I don't have a radeon card:
https://github.com/l1k/linux/commit/485e197a7cac88e24348150526988149428feeaa


> 
> Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 22 ++++------------------
>  1 file changed, 4 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index f2bfca0..515893c 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -1162,14 +1162,12 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp)
>  static void
>  intel_dp_aux_fini(struct intel_dp *intel_dp)
>  {
> -	drm_dp_aux_unregister(&intel_dp->aux);
>  	kfree(intel_dp->aux.name);
>  }

Hm, instead of moving the single call of drm_dp_aux_unregister()
to intel_dp_connector_unregister() I think it would be more clear
to call intel_dp_aux_fini() from intel_dp_connector_unregister()
and remove its invocation from intel_dp_encoder_destroy().

Ville introduced intel_dp_aux_fini() very recently with a121f4e5fae5,
he should probably have a say on how to solve this.

Kind regards,

Lukas

>  
>  static int
>  intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
>  {
> -	struct drm_device *dev = intel_dp_to_dev(intel_dp);
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	enum port port = intel_dig_port->port;
>  	int ret;
> @@ -1180,7 +1178,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
>  	if (!intel_dp->aux.name)
>  		return -ENOMEM;
>  
> -	intel_dp->aux.dev = dev->dev;
> +	intel_dp->aux.dev = connector->base.kdev;
>  	intel_dp->aux.transfer = intel_dp_aux_transfer;
>  
>  	DRM_DEBUG_KMS("registering %s bus for %s\n",
> @@ -1195,27 +1193,15 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
>  		return ret;
>  	}
>  
> -	ret = sysfs_create_link(&connector->base.kdev->kobj,
> -				&intel_dp->aux.ddc.dev.kobj,
> -				intel_dp->aux.ddc.dev.kobj.name);
> -	if (ret < 0) {
> -		DRM_ERROR("sysfs_create_link() for %s failed (%d)\n",
> -			  intel_dp->aux.name, ret);
> -		intel_dp_aux_fini(intel_dp);
> -		return ret;
> -	}
> -
>  	return 0;
>  }
>  
>  static void
>  intel_dp_connector_unregister(struct intel_connector *intel_connector)
>  {
> -	struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
> -
> -	if (!intel_connector->mst_port)
> -		sysfs_remove_link(&intel_connector->base.kdev->kobj,
> -				  intel_dp->aux.ddc.dev.kobj.name);
> +	struct intel_dp *intel_dp =
> +		enc_to_intel_dp(&intel_connector->encoder->base);
> +	drm_dp_aux_unregister(&intel_dp->aux);
>  	intel_connector_unregister(intel_connector);
>  }
>  
> -- 
> 2.4.3
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions.
  2015-12-03 22:54 ` [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions Rafael Antognolli
  2015-12-04  8:33   ` [Intel-gfx] " Daniel Vetter
@ 2015-12-06 16:24   ` Lukas Wunner
  1 sibling, 0 replies; 8+ messages in thread
From: Lukas Wunner @ 2015-12-06 16:24 UTC (permalink / raw)
  To: Rafael Antognolli; +Cc: intel-gfx, dri-devel

Hi Rafael,

On Thu, Dec 03, 2015 at 02:54:00PM -0800, Rafael Antognolli wrote:
> The module_init and module_exit functions will start here, and call the
> subsequent init's and exit's.
> 
> Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
> ---
>  drivers/gpu/drm/Makefile                |  4 ++-
>  drivers/gpu/drm/drm_fb_helper.c         |  9 +++----
>  drivers/gpu/drm/drm_kms_helper_common.c | 43 +++++++++++++++++++++++++++++++++
>  include/drm/drm_fb_helper.h             |  6 +++++
>  4 files changed, 56 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/gpu/drm/drm_kms_helper_common.c
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 1e9ff4c..76399da 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -24,7 +24,9 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
>  drm-y += $(drm-m)
>  
>  drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
> -		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
> +		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
> +		drm_kms_helper_common.o
> +
>  drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
>  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
>  drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 69cbab5..576f769 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -2175,9 +2175,9 @@ EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
>   * but the module doesn't depend on any fb console symbols.  At least
>   * attempt to load fbcon to avoid leaving the system without a usable console.
>   */
> -#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
> -static int __init drm_fb_helper_modinit(void)
> +int drm_fb_helper_modinit(void)

Do keep the __init, the function can then be jettisoned once the module
has initialized and the memory occupied by it becomes available.

Kind regards,

Lukas

>  {
> +#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT)
>  	const char *name = "fbcon";
>  	struct module *fbcon;
>  
> @@ -2187,8 +2187,7 @@ static int __init drm_fb_helper_modinit(void)
>  
>  	if (!fbcon)
>  		request_module_nowait(name);
> +#endif
>  	return 0;
>  }
> -
> -module_init(drm_fb_helper_modinit);
> -#endif
> +EXPORT_SYMBOL(drm_fb_helper_modinit);
> diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c
> new file mode 100644
> index 0000000..920b2fb
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_kms_helper_common.c
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright © 2015 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + *
> + * Authors:
> + *    Rafael Antognolli <rafael.antognolli@intel.com>
> + *
> + */
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_fb_helper.h>
> +
> +static int __init drm_kms_helper_init(void)
> +{
> +	/* Call init functions from specific kms helpers here */
> +	return drm_fb_helper_modinit();
> +}
> +
> +static void __exit drm_kms_helper_exit(void)
> +{
> +	/* Call exit functions from specific kms helpers here */
> +}
> +
> +module_init(drm_kms_helper_init);
> +module_exit(drm_kms_helper_exit);
> diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
> index 87b090c..4fed7a2 100644
> --- a/include/drm/drm_fb_helper.h
> +++ b/include/drm/drm_fb_helper.h
> @@ -148,6 +148,7 @@ struct drm_fb_helper {
>  };
>  
>  #ifdef CONFIG_DRM_FBDEV_EMULATION
> +int drm_fb_helper_modinit(void);
>  void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper,
>  			   const struct drm_fb_helper_funcs *funcs);
>  int drm_fb_helper_init(struct drm_device *dev,
> @@ -212,6 +213,11 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_
>  int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper,
>  				       struct drm_connector *connector);
>  #else
> +static inline int drm_fb_helper_modinit(void)
> +{
> +	return 0;
> +}
> +
>  static inline void drm_fb_helper_prepare(struct drm_device *dev,
>  					struct drm_fb_helper *helper,
>  					const struct drm_fb_helper_funcs *funcs)
> -- 
> 2.4.3
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device.
  2015-12-06 16:08   ` Lukas Wunner
@ 2016-01-21 23:13     ` Rafael Antognolli
  0 siblings, 0 replies; 8+ messages in thread
From: Rafael Antognolli @ 2016-01-21 23:13 UTC (permalink / raw)
  To: Lukas Wunner; +Cc: intel-gfx, dri-devel

Hi Lukas,

Sorry for the late answer, I went on vacation and then was busy with
something else. Anyway, I tried to address all comments (yours and
Daniel's) on a new version. See some comments below.

On Sun, Dec 06, 2015 at 05:08:49PM +0100, Lukas Wunner wrote:
> Hi Rafael,
> 
> On Thu, Dec 03, 2015 at 02:54:02PM -0800, Rafael Antognolli wrote:
> > So far, the i915 driver and some other drivers set it to the drm_device,
> > which doesn't allow one to know which DP a given aux channel is related
> > to. Changing this to be the drm_connector provides proper nesting, still
> > allowing one to get the drm_device from it. Some drivers already set it
> > to the drm_connector.
> > 
> > This also removes the need to add a sysfs link for the i2c device under
> > the connector, as it will already be there.
> > 
> > v2:
> 
> Two minor nits, I think this should be "v9" instead of "v2" because
> this was newly added since v8, and the subject should be prefixed
> "drm/i915" (or "drm/i915/dp" or whatever) instead of "drm/dp" because
> this only touches i915 and not drm core.
> 
> 
> >  - As a side effect, drm_dp_aux_unregister() must be called before
> >  intel_connector_unregister(), as both the aux.dev and the i2c adapter
> >  dev are children of the drm_connector device now. Calling
> >  drm_dp_aux_unregister() before prevents them from being destroyed
> >  twice.
> 
> I haven't verified what Ville wrote (that there are WARNs because of
> this ordering issue), but if this is true then we need to make sure
> all other drivers get the order right, otherwise they'd spew WARNs
> as well once this gets merged.
> 
> I've checked that for every driver and the only one affected is radeon.
> A fix is now in my GitHub repo, feel free to include the commit in your
> series if you want to. I haven't been able to actually test it though
> as I don't have a radeon card:
> https://github.com/l1k/linux/commit/485e197a7cac88e24348150526988149428feeaa
> 

Nice, I added it to the series, though I also don't have a radeon to
test it.

> > 
> > Signed-off-by: Rafael Antognolli <rafael.antognolli@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c | 22 ++++------------------
> >  1 file changed, 4 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> > index f2bfca0..515893c 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -1162,14 +1162,12 @@ static void intel_aux_reg_init(struct intel_dp *intel_dp)
> >  static void
> >  intel_dp_aux_fini(struct intel_dp *intel_dp)
> >  {
> > -	drm_dp_aux_unregister(&intel_dp->aux);
> >  	kfree(intel_dp->aux.name);
> >  }
> 
> Hm, instead of moving the single call of drm_dp_aux_unregister()
> to intel_dp_connector_unregister() I think it would be more clear
> to call intel_dp_aux_fini() from intel_dp_connector_unregister()
> and remove its invocation from intel_dp_encoder_destroy().
> 
> Ville introduced intel_dp_aux_fini() very recently with a121f4e5fae5,
> he should probably have a say on how to solve this.

I makes sense to me, so I did what you suggest.

Thanks for the review,
Rafael

> >  
> >  static int
> >  intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
> >  {
> > -	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> >  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> >  	enum port port = intel_dig_port->port;
> >  	int ret;
> > @@ -1180,7 +1178,7 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
> >  	if (!intel_dp->aux.name)
> >  		return -ENOMEM;
> >  
> > -	intel_dp->aux.dev = dev->dev;
> > +	intel_dp->aux.dev = connector->base.kdev;
> >  	intel_dp->aux.transfer = intel_dp_aux_transfer;
> >  
> >  	DRM_DEBUG_KMS("registering %s bus for %s\n",
> > @@ -1195,27 +1193,15 @@ intel_dp_aux_init(struct intel_dp *intel_dp, struct intel_connector *connector)
> >  		return ret;
> >  	}
> >  
> > -	ret = sysfs_create_link(&connector->base.kdev->kobj,
> > -				&intel_dp->aux.ddc.dev.kobj,
> > -				intel_dp->aux.ddc.dev.kobj.name);
> > -	if (ret < 0) {
> > -		DRM_ERROR("sysfs_create_link() for %s failed (%d)\n",
> > -			  intel_dp->aux.name, ret);
> > -		intel_dp_aux_fini(intel_dp);
> > -		return ret;
> > -	}
> > -
> >  	return 0;
> >  }
> >  
> >  static void
> >  intel_dp_connector_unregister(struct intel_connector *intel_connector)
> >  {
> > -	struct intel_dp *intel_dp = intel_attached_dp(&intel_connector->base);
> > -
> > -	if (!intel_connector->mst_port)
> > -		sysfs_remove_link(&intel_connector->base.kdev->kobj,
> > -				  intel_dp->aux.ddc.dev.kobj.name);
> > +	struct intel_dp *intel_dp =
> > +		enc_to_intel_dp(&intel_connector->encoder->base);
> > +	drm_dp_aux_unregister(&intel_dp->aux);
> >  	intel_connector_unregister(intel_connector);
> >  }
> >  
> > -- 
> > 2.4.3
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2016-01-21 23:13 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-03 22:53 [PATCH v9 0/3] Add drm_dp_aux chardev support Rafael Antognolli
2015-12-03 22:54 ` [PATCH v9 1/3] drm/kms_helper: Add a common place to call init and exit functions Rafael Antognolli
2015-12-04  8:33   ` [Intel-gfx] " Daniel Vetter
2015-12-06 16:24   ` Lukas Wunner
2015-12-03 22:54 ` [PATCH v9 2/3] drm/dp: Add a drm_aux-dev module for reading/writing dpcd registers Rafael Antognolli
2015-12-03 22:54 ` [PATCH v9 3/3] drm/dp: Set aux.dev to the drm_connector device, instead of drm_device Rafael Antognolli
2015-12-06 16:08   ` Lukas Wunner
2016-01-21 23:13     ` Rafael Antognolli

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.