usb: typec: altmodes/displayport: add irq_hpd to sysfs
Add irq_hpd sysfs node to displayport driver. This allows the userspace to subscribe to irq events similar to how it can subscribe to changes in hpd. irq_hpd is read only and returns the number of irq events generated since driver probe. pending_irq_hpd is added so that a sysfs_emit can be generated if the HPD high event belonging to the same status message is delayed until a successful configuration. Signed-off-by: RD Babiera <rdbabiera@google.com> Reviewed-by: Badhri Jagan Sridharan <badhri@google.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/20250623204947.732915-2-rdbabiera@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9962d0433a
commit
8b4f6fafed
@@ -62,3 +62,13 @@ Description:
|
||||
by VESA DisplayPort Alt Mode on USB Type-C Standard.
|
||||
- 0 when HPD’s logical state is low (HPD_Low) as defined by
|
||||
VESA DisplayPort Alt Mode on USB Type-C Standard.
|
||||
|
||||
What: /sys/bus/typec/devices/.../displayport/irq_hpd
|
||||
Date: June 2025
|
||||
Contact: RD Babiera <rdbabiera@google.com>
|
||||
Description:
|
||||
IRQ_HPD events are sent over the USB PD protocol in Status Update and
|
||||
Attention messages. IRQ_HPD can only be asserted when HPD is high,
|
||||
and is asserted when an IRQ_HPD has been issued since the last Status
|
||||
Update. This is a read only node that returns the number of IRQ events
|
||||
raised in the driver's lifetime.
|
||||
|
||||
@@ -65,6 +65,13 @@ struct dp_altmode {
|
||||
enum dp_state state;
|
||||
bool hpd;
|
||||
bool pending_hpd;
|
||||
u32 irq_hpd_count;
|
||||
/*
|
||||
* hpd is mandatory for irq_hpd assertion, so irq_hpd also needs its own pending flag if
|
||||
* both hpd and irq_hpd are asserted in the first Status Update before the pin assignment
|
||||
* is configured.
|
||||
*/
|
||||
bool pending_irq_hpd;
|
||||
|
||||
struct mutex lock; /* device lock */
|
||||
struct work_struct work;
|
||||
@@ -151,6 +158,7 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
|
||||
{
|
||||
bool configured = !!DP_CONF_GET_PIN_ASSIGN(dp->data.conf);
|
||||
bool hpd = !!(dp->data.status & DP_STATUS_HPD_STATE);
|
||||
bool irq_hpd = !!(dp->data.status & DP_STATUS_IRQ_HPD);
|
||||
u8 con = DP_STATUS_CONNECTION(dp->data.status);
|
||||
int ret = 0;
|
||||
|
||||
@@ -170,6 +178,8 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
|
||||
dp->hpd = hpd;
|
||||
dp->pending_hpd = true;
|
||||
}
|
||||
if (dp->hpd && dp->pending_hpd && irq_hpd)
|
||||
dp->pending_irq_hpd = true;
|
||||
}
|
||||
} else {
|
||||
drm_connector_oob_hotplug_event(dp->connector_fwnode,
|
||||
@@ -177,6 +187,10 @@ static int dp_altmode_status_update(struct dp_altmode *dp)
|
||||
connector_status_disconnected);
|
||||
dp->hpd = hpd;
|
||||
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
|
||||
if (hpd && irq_hpd) {
|
||||
dp->irq_hpd_count++;
|
||||
sysfs_notify(&dp->alt->dev.kobj, "displayport", "irq_hpd");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -196,6 +210,11 @@ static int dp_altmode_configured(struct dp_altmode *dp)
|
||||
connector_status_connected);
|
||||
sysfs_notify(&dp->alt->dev.kobj, "displayport", "hpd");
|
||||
dp->pending_hpd = false;
|
||||
if (dp->pending_irq_hpd) {
|
||||
dp->irq_hpd_count++;
|
||||
sysfs_notify(&dp->alt->dev.kobj, "displayport", "irq_hpd");
|
||||
dp->pending_irq_hpd = false;
|
||||
}
|
||||
}
|
||||
|
||||
return dp_altmode_notify(dp);
|
||||
@@ -707,10 +726,19 @@ static ssize_t hpd_show(struct device *dev, struct device_attribute *attr, char
|
||||
}
|
||||
static DEVICE_ATTR_RO(hpd);
|
||||
|
||||
static ssize_t irq_hpd_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct dp_altmode *dp = dev_get_drvdata(dev);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", dp->irq_hpd_count);
|
||||
}
|
||||
static DEVICE_ATTR_RO(irq_hpd);
|
||||
|
||||
static struct attribute *displayport_attrs[] = {
|
||||
&dev_attr_configuration.attr,
|
||||
&dev_attr_pin_assignment.attr,
|
||||
&dev_attr_hpd.attr,
|
||||
&dev_attr_irq_hpd.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user