On Wed, May 13, 2026 at 09:23:21PM +0300, Dmitry Baryshkov wrote:
> The DisplayPort standard defines a special kind of events called IRQ.
> These events are used to notify DP Source about the events on the Sink
> side. It is extremely important for DP MST handling, where the MST
> events are reported through this IRQ.
>
> In case of the USB-C DP AltMode there is no actual HPD pulse, but the
> events are ported through the bits in the AltMode VDOs.
>
> Extend the drm_connector_oob_hotplug_event() interface and report IRQ
> events to the DisplayPort Sink drivers.
>
> Signed-off-by: Dmitry Baryshkov <[email protected]>
> ---
> drivers/gpu/drm/drm_connector.c | 5 ++++-
> drivers/usb/typec/altmodes/displayport.c | 15 +++++++++++----
> include/drm/drm_connector.h | 19 ++++++++++++++++++-
> 3 files changed, 33 insertions(+), 6 deletions(-)
Greg, Heikki, would you please ack merging this through the drm tree?
>
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 47dc53c4a738..edee9daccd51 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -3510,6 +3510,8 @@ struct drm_connector
> *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to
> connector
> * @connector_fwnode: fwnode_handle to report the event on
> * @status: hot plug detect logical state
> + * @extra_status: additional information provided by the sink without
> changing
> + * the HPD state (or in addition to such a change).
> *
> * On some hardware a hotplug event notification may come from outside the
> display
> * driver / device. An example of this is some USB Type-C setups where the
> hardware
> @@ -3520,7 +3522,8 @@ struct drm_connector
> *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> * a drm_connector reference through calling drm_connector_find_by_fwnode().
> */
> void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
> - enum drm_connector_status status)
> + enum drm_connector_status status,
> + enum drm_connector_status_extra
> extra_status)
> {
> struct drm_connector *connector;
>
> diff --git a/drivers/usb/typec/altmodes/displayport.c
> b/drivers/usb/typec/altmodes/displayport.c
> index 35d9c3086990..7182a8e2e710 100644
> --- a/drivers/usb/typec/altmodes/displayport.c
> +++ b/drivers/usb/typec/altmodes/displayport.c
> @@ -189,7 +189,9 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
> } else {
> drm_connector_oob_hotplug_event(dp->connector_fwnode,
> hpd ?
> connector_status_connected :
> -
> connector_status_disconnected);
> +
> connector_status_disconnected,
> + (hpd && irq_hpd) ?
> DRM_CONNECTOR_DP_IRQ_HPD :
> +
> DRM_CONNECTOR_NO_EXTRA_STATUS);
> dp->hpd = hpd;
> sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
> if (hpd && irq_hpd) {
> @@ -212,7 +214,10 @@ static int dp_altmode_configured(struct dp_altmode *dp)
> */
> if (dp->pending_hpd) {
> drm_connector_oob_hotplug_event(dp->connector_fwnode,
> - connector_status_connected);
> + connector_status_connected,
> + dp->pending_irq_hpd ?
> + DRM_CONNECTOR_DP_IRQ_HPD :
> + DRM_CONNECTOR_NO_EXTRA_STATUS);
> sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
> dp->pending_hpd = false;
> if (dp->pending_irq_hpd) {
> @@ -397,7 +402,8 @@ static int dp_altmode_vdm(struct typec_altmode *alt,
> dp->data.conf = 0;
> if (dp->hpd) {
>
> drm_connector_oob_hotplug_event(dp->connector_fwnode,
> -
> connector_status_disconnected);
> +
> connector_status_disconnected,
> +
> DRM_CONNECTOR_NO_EXTRA_STATUS);
> dp->hpd = false;
> sysfs_notify(&dp->alt->dev.kobj, "displayport",
> "hpd");
> }
> @@ -827,7 +833,8 @@ void dp_altmode_remove(struct typec_altmode *alt)
>
> if (dp->connector_fwnode) {
> drm_connector_oob_hotplug_event(dp->connector_fwnode,
> - connector_status_disconnected);
> + connector_status_disconnected,
> + DRM_CONNECTOR_NO_EXTRA_STATUS);
>
> fwnode_handle_put(dp->connector_fwnode);
> }
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index f83f28cae207..e05197e970d3 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -91,6 +91,22 @@ enum drm_connector_status {
> connector_status_unknown = 3,
> };
>
> +/**
> + * enum drm_connector_status_extra - additional events sent by the sink /
> + * display together or in replacement of the HPD status changes.
> + */
> +enum drm_connector_status_extra {
> + /**
> + * @DRM_CONNECTOR_NO_EXTRA_STATUS: No additional status reported.
> + */
> + DRM_CONNECTOR_NO_EXTRA_STATUS,
> + /**
> + * @DRM_CONNECTOR_DP_IRQ_HPD: DisplayPort Sink has sent the
> + * IRQ_HPD (either by the HPD short pulse or via the AltMode event).
> + */
> + DRM_CONNECTOR_DP_IRQ_HPD,
> +};
> +
> /**
> * enum drm_connector_registration_state - userspace registration status for
> * a &drm_connector
> @@ -2521,7 +2537,8 @@ drm_connector_is_unregistered(struct drm_connector
> *connector)
> }
>
> void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
> - enum drm_connector_status status);
> + enum drm_connector_status status,
> + enum drm_connector_status_extra
> extra_status);
> const char *drm_get_connector_type_name(unsigned int connector_type);
> const char *drm_get_connector_status_name(enum drm_connector_status status);
> const char *drm_get_subpixel_order_name(enum subpixel_order order);
>
> --
> 2.47.3
>
--
With best wishes
Dmitry