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
next 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: linkBe 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.