All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Osipenko <digetx@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Lyude Paul <lyude@redhat.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
	Thomas Graichen <thomas.graichen@gmail.com>
Cc: dri-devel@lists.freedesktop.org, linux-tegra@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v1 1/2] drm/dp: Add drm_dp_aux_register_ddc/chardev() helpers
Date: Mon,  8 Nov 2021 02:08:20 +0300	[thread overview]
Message-ID: <20211107230821.13511-1-digetx@gmail.com> (raw)

Add drm_dp_aux_register_ddc/chardev() helpers that allow DP drivers
to register I2C DDC adapter and character device separately.

Cc: <stable@vger.kernel.org> # 5.13+
Reported-by: Thomas Graichen <thomas.graichen@gmail.com> # T124 Nyan Big
Tested-by: Thomas Graichen <thomas.graichen@gmail.com> # T124 Nyan Big
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 112 +++++++++++++++++++++++++++-----
 include/drm/drm_dp_helper.h     |   4 ++
 2 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 4d0d1e8e51fa..56e3e57e6dc7 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1775,7 +1775,7 @@ EXPORT_SYMBOL(drm_dp_remote_aux_init);
  * drm_dp_aux_init() - minimally initialise an aux channel
  * @aux: DisplayPort AUX channel
  *
- * If you need to use the drm_dp_aux's i2c adapter prior to registering it with
+ * If you need to use the drm_dp_aux handle prior to registering it with
  * the outside world, call drm_dp_aux_init() first. For drivers which are
  * grandparents to their AUX adapters (e.g. the AUX adapter is parented by a
  * &drm_connector), you must still call drm_dp_aux_register() once the connector
@@ -1790,6 +1790,9 @@ EXPORT_SYMBOL(drm_dp_remote_aux_init);
  */
 void drm_dp_aux_init(struct drm_dp_aux *aux)
 {
+	if (aux->ddc.algo)
+		return;
+
 	mutex_init(&aux->hw_mutex);
 	mutex_init(&aux->cec.lock);
 	INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work);
@@ -1827,31 +1830,23 @@ EXPORT_SYMBOL(drm_dp_aux_init);
  * mentioned above need to call drm_dp_aux_init() in order to use the AUX
  * channel before registration.
  *
+ * Don't mix drm_dp_aux_register() with drm_dp_aux_register_chardev/ddc().
+ *
  * Returns 0 on success or a negative error code on failure.
  */
 int drm_dp_aux_register(struct drm_dp_aux *aux)
 {
 	int ret;
 
-	WARN_ON_ONCE(!aux->drm_dev);
-
-	if (!aux->ddc.algo)
-		drm_dp_aux_init(aux);
-
-	aux->ddc.class = I2C_CLASS_DDC;
-	aux->ddc.owner = THIS_MODULE;
-	aux->ddc.dev.parent = aux->dev;
+	drm_dp_aux_init(aux);
 
-	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
-		sizeof(aux->ddc.name));
-
-	ret = drm_dp_aux_register_devnode(aux);
+	ret = drm_dp_aux_register_ddc(aux);
 	if (ret)
 		return ret;
 
-	ret = i2c_add_adapter(&aux->ddc);
+	ret = drm_dp_aux_register_chardev(aux);
 	if (ret) {
-		drm_dp_aux_unregister_devnode(aux);
+		drm_dp_aux_unregister_ddc(aux);
 		return ret;
 	}
 
@@ -1865,11 +1860,94 @@ 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);
+	drm_dp_aux_unregister_chardev(aux);
+	drm_dp_aux_unregister_ddc(aux);
 }
 EXPORT_SYMBOL(drm_dp_aux_unregister);
 
+/**
+ * drm_dp_aux_register_ddc() -  initialise and register I2C DDC part of AUX channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Automatically calls drm_dp_aux_init() if this hasn't been done yet.
+ * If you need to use the drm_dp_aux's I2C adapter prior to registering it with
+ * the outside world, call drm_dp_aux_register_ddc() first. For drivers which
+ * are grandparents to their AUX adapters (e.g. the AUX adapter is parented by a
+ * &drm_connector), you must still call drm_dp_aux_register_chardev() once the
+ * connector has been registered to allow userspace access to the auxiliary DP
+ * channel.
+ *
+ * For devices which use a separate platform device for their AUX adapters, this
+ * may be called as early as required by the driver.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_aux_register_ddc(struct drm_dp_aux *aux)
+{
+	drm_dp_aux_init(aux);
+
+	if (WARN_ON(aux->ddc.class == I2C_CLASS_DDC))
+		return -EBUSY;
+
+	aux->ddc.class = I2C_CLASS_DDC;
+	aux->ddc.owner = THIS_MODULE;
+	aux->ddc.dev.parent = aux->dev;
+
+	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
+		sizeof(aux->ddc.name));
+
+	return i2c_add_adapter(&aux->ddc);
+}
+EXPORT_SYMBOL(drm_dp_aux_register_ddc);
+
+/**
+ * drm_dp_aux_unregister_ddc() - unregister I2C DDC part of AUX channel
+ * @aux: DisplayPort AUX channel
+ */
+void drm_dp_aux_unregister_ddc(struct drm_dp_aux *aux)
+{
+	i2c_del_adapter(&aux->ddc);
+
+	aux->ddc.class = 0;
+}
+EXPORT_SYMBOL(drm_dp_aux_unregister_ddc);
+
+/**
+ * drm_dp_aux_register_chardev() - initialise and register userspace part of AUX channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Automatically calls drm_dp_aux_init() if this hasn't been done yet. This
+ * should only be called once the parent of @aux, &drm_dp_aux.dev, is
+ * initialized. For devices which are grandparents of their AUX channels,
+ * &drm_dp_aux.dev will typically be the &drm_connector &device which
+ * corresponds to @aux. For these devices, it's advised to call
+ * drm_dp_aux_register_chardev() in &drm_connector_funcs.late_register, and
+ * likewise to call drm_dp_aux_unregister_chardev() in
+ * &drm_connector_funcs.early_unregister. Functions which don't follow this
+ * will likely Oops when %CONFIG_DRM_DP_AUX_CHARDEV is enabled.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_aux_register_chardev(struct drm_dp_aux *aux)
+{
+	WARN_ON_ONCE(!aux->drm_dev);
+
+	drm_dp_aux_init(aux);
+
+	return drm_dp_aux_register_devnode(aux);
+}
+EXPORT_SYMBOL(drm_dp_aux_register_chardev);
+
+/**
+ * drm_dp_aux_unregister() - unregister userspace part of AUX channel
+ * @aux: DisplayPort AUX channel
+ */
+void drm_dp_aux_unregister_chardev(struct drm_dp_aux *aux)
+{
+	drm_dp_aux_unregister_devnode(aux);
+}
+EXPORT_SYMBOL(drm_dp_aux_unregister_chardev);
+
 #define PSR_SETUP_TIME(x) [DP_PSR_SETUP_TIME_ ## x >> DP_PSR_SETUP_TIME_SHIFT] = (x)
 
 /**
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b52df4db3e8f..80130458188d 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -2130,6 +2130,10 @@ void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
 void drm_dp_aux_init(struct drm_dp_aux *aux);
 int drm_dp_aux_register(struct drm_dp_aux *aux);
 void drm_dp_aux_unregister(struct drm_dp_aux *aux);
+int drm_dp_aux_register_ddc(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_ddc(struct drm_dp_aux *aux);
+int drm_dp_aux_register_chardev(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_chardev(struct drm_dp_aux *aux);
 
 int drm_dp_start_crc(struct drm_dp_aux *aux, struct drm_crtc *crtc);
 int drm_dp_stop_crc(struct drm_dp_aux *aux);
-- 
2.33.1


WARNING: multiple messages have this Message-ID (diff)
From: Dmitry Osipenko <digetx@gmail.com>
To: Thierry Reding <thierry.reding@gmail.com>,
	Jonathan Hunter <jonathanh@nvidia.com>,
	Lyude Paul <lyude@redhat.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>,
	Thomas Graichen <thomas.graichen@gmail.com>
Cc: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org
Subject: [PATCH v1 1/2] drm/dp: Add drm_dp_aux_register_ddc/chardev() helpers
Date: Mon,  8 Nov 2021 02:08:20 +0300	[thread overview]
Message-ID: <20211107230821.13511-1-digetx@gmail.com> (raw)

Add drm_dp_aux_register_ddc/chardev() helpers that allow DP drivers
to register I2C DDC adapter and character device separately.

Cc: <stable@vger.kernel.org> # 5.13+
Reported-by: Thomas Graichen <thomas.graichen@gmail.com> # T124 Nyan Big
Tested-by: Thomas Graichen <thomas.graichen@gmail.com> # T124 Nyan Big
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 112 +++++++++++++++++++++++++++-----
 include/drm/drm_dp_helper.h     |   4 ++
 2 files changed, 99 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 4d0d1e8e51fa..56e3e57e6dc7 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1775,7 +1775,7 @@ EXPORT_SYMBOL(drm_dp_remote_aux_init);
  * drm_dp_aux_init() - minimally initialise an aux channel
  * @aux: DisplayPort AUX channel
  *
- * If you need to use the drm_dp_aux's i2c adapter prior to registering it with
+ * If you need to use the drm_dp_aux handle prior to registering it with
  * the outside world, call drm_dp_aux_init() first. For drivers which are
  * grandparents to their AUX adapters (e.g. the AUX adapter is parented by a
  * &drm_connector), you must still call drm_dp_aux_register() once the connector
@@ -1790,6 +1790,9 @@ EXPORT_SYMBOL(drm_dp_remote_aux_init);
  */
 void drm_dp_aux_init(struct drm_dp_aux *aux)
 {
+	if (aux->ddc.algo)
+		return;
+
 	mutex_init(&aux->hw_mutex);
 	mutex_init(&aux->cec.lock);
 	INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work);
@@ -1827,31 +1830,23 @@ EXPORT_SYMBOL(drm_dp_aux_init);
  * mentioned above need to call drm_dp_aux_init() in order to use the AUX
  * channel before registration.
  *
+ * Don't mix drm_dp_aux_register() with drm_dp_aux_register_chardev/ddc().
+ *
  * Returns 0 on success or a negative error code on failure.
  */
 int drm_dp_aux_register(struct drm_dp_aux *aux)
 {
 	int ret;
 
-	WARN_ON_ONCE(!aux->drm_dev);
-
-	if (!aux->ddc.algo)
-		drm_dp_aux_init(aux);
-
-	aux->ddc.class = I2C_CLASS_DDC;
-	aux->ddc.owner = THIS_MODULE;
-	aux->ddc.dev.parent = aux->dev;
+	drm_dp_aux_init(aux);
 
-	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
-		sizeof(aux->ddc.name));
-
-	ret = drm_dp_aux_register_devnode(aux);
+	ret = drm_dp_aux_register_ddc(aux);
 	if (ret)
 		return ret;
 
-	ret = i2c_add_adapter(&aux->ddc);
+	ret = drm_dp_aux_register_chardev(aux);
 	if (ret) {
-		drm_dp_aux_unregister_devnode(aux);
+		drm_dp_aux_unregister_ddc(aux);
 		return ret;
 	}
 
@@ -1865,11 +1860,94 @@ 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);
+	drm_dp_aux_unregister_chardev(aux);
+	drm_dp_aux_unregister_ddc(aux);
 }
 EXPORT_SYMBOL(drm_dp_aux_unregister);
 
+/**
+ * drm_dp_aux_register_ddc() -  initialise and register I2C DDC part of AUX channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Automatically calls drm_dp_aux_init() if this hasn't been done yet.
+ * If you need to use the drm_dp_aux's I2C adapter prior to registering it with
+ * the outside world, call drm_dp_aux_register_ddc() first. For drivers which
+ * are grandparents to their AUX adapters (e.g. the AUX adapter is parented by a
+ * &drm_connector), you must still call drm_dp_aux_register_chardev() once the
+ * connector has been registered to allow userspace access to the auxiliary DP
+ * channel.
+ *
+ * For devices which use a separate platform device for their AUX adapters, this
+ * may be called as early as required by the driver.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_aux_register_ddc(struct drm_dp_aux *aux)
+{
+	drm_dp_aux_init(aux);
+
+	if (WARN_ON(aux->ddc.class == I2C_CLASS_DDC))
+		return -EBUSY;
+
+	aux->ddc.class = I2C_CLASS_DDC;
+	aux->ddc.owner = THIS_MODULE;
+	aux->ddc.dev.parent = aux->dev;
+
+	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
+		sizeof(aux->ddc.name));
+
+	return i2c_add_adapter(&aux->ddc);
+}
+EXPORT_SYMBOL(drm_dp_aux_register_ddc);
+
+/**
+ * drm_dp_aux_unregister_ddc() - unregister I2C DDC part of AUX channel
+ * @aux: DisplayPort AUX channel
+ */
+void drm_dp_aux_unregister_ddc(struct drm_dp_aux *aux)
+{
+	i2c_del_adapter(&aux->ddc);
+
+	aux->ddc.class = 0;
+}
+EXPORT_SYMBOL(drm_dp_aux_unregister_ddc);
+
+/**
+ * drm_dp_aux_register_chardev() - initialise and register userspace part of AUX channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Automatically calls drm_dp_aux_init() if this hasn't been done yet. This
+ * should only be called once the parent of @aux, &drm_dp_aux.dev, is
+ * initialized. For devices which are grandparents of their AUX channels,
+ * &drm_dp_aux.dev will typically be the &drm_connector &device which
+ * corresponds to @aux. For these devices, it's advised to call
+ * drm_dp_aux_register_chardev() in &drm_connector_funcs.late_register, and
+ * likewise to call drm_dp_aux_unregister_chardev() in
+ * &drm_connector_funcs.early_unregister. Functions which don't follow this
+ * will likely Oops when %CONFIG_DRM_DP_AUX_CHARDEV is enabled.
+ *
+ * Returns 0 on success or a negative error code on failure.
+ */
+int drm_dp_aux_register_chardev(struct drm_dp_aux *aux)
+{
+	WARN_ON_ONCE(!aux->drm_dev);
+
+	drm_dp_aux_init(aux);
+
+	return drm_dp_aux_register_devnode(aux);
+}
+EXPORT_SYMBOL(drm_dp_aux_register_chardev);
+
+/**
+ * drm_dp_aux_unregister() - unregister userspace part of AUX channel
+ * @aux: DisplayPort AUX channel
+ */
+void drm_dp_aux_unregister_chardev(struct drm_dp_aux *aux)
+{
+	drm_dp_aux_unregister_devnode(aux);
+}
+EXPORT_SYMBOL(drm_dp_aux_unregister_chardev);
+
 #define PSR_SETUP_TIME(x) [DP_PSR_SETUP_TIME_ ## x >> DP_PSR_SETUP_TIME_SHIFT] = (x)
 
 /**
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b52df4db3e8f..80130458188d 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -2130,6 +2130,10 @@ void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
 void drm_dp_aux_init(struct drm_dp_aux *aux);
 int drm_dp_aux_register(struct drm_dp_aux *aux);
 void drm_dp_aux_unregister(struct drm_dp_aux *aux);
+int drm_dp_aux_register_ddc(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_ddc(struct drm_dp_aux *aux);
+int drm_dp_aux_register_chardev(struct drm_dp_aux *aux);
+void drm_dp_aux_unregister_chardev(struct drm_dp_aux *aux);
 
 int drm_dp_start_crc(struct drm_dp_aux *aux, struct drm_crtc *crtc);
 int drm_dp_stop_crc(struct drm_dp_aux *aux);
-- 
2.33.1


             reply	other threads:[~2021-11-07 23:08 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-07 23:08 Dmitry Osipenko [this message]
2021-11-07 23:08 ` [PATCH v1 1/2] drm/dp: Add drm_dp_aux_register_ddc/chardev() helpers Dmitry Osipenko
2021-11-07 23:08 ` [PATCH v1 2/2] drm/tegra: Use " Dmitry Osipenko
2021-11-07 23:08   ` Dmitry Osipenko
2021-11-08 15:17   ` Daniel Vetter
2021-11-08 15:17     ` Daniel Vetter
2021-11-08 18:16     ` Dmitry Osipenko
2021-11-09  9:19       ` Daniel Vetter
2021-11-09  9:19         ` Daniel Vetter
2021-11-09 13:52         ` Dmitry Osipenko
2021-11-09 14:08           ` Dmitry Osipenko
2021-11-09 14:17             ` Dmitry Osipenko
2021-11-09 14:39               ` Dmitry Osipenko
2021-11-12 10:52                 ` Thierry Reding
2021-11-12 10:52                   ` Thierry Reding
2021-11-12 14:32                   ` Dmitry Osipenko
2021-11-12 14:32                     ` Dmitry Osipenko
2021-11-12 20:26                     ` Lyude Paul
2021-11-12 20:26                       ` Lyude Paul
2021-11-12 20:45                       ` Dmitry Osipenko
2021-11-12 20:45                         ` Dmitry Osipenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211107230821.13511-1-digetx@gmail.com \
    --to=digetx@gmail.com \
    --cc=airlied@linux.ie \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jonathanh@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=lyude@redhat.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=thierry.reding@gmail.com \
    --cc=thomas.graichen@gmail.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.