1212#include <linux/of.h>
1313#include <linux/platform_device.h>
1414#include <linux/regulator/consumer.h>
15+ #include <linux/workqueue.h>
1516
1617#include <drm/drm_atomic_helper.h>
1718#include <drm/drm_bridge.h>
@@ -25,6 +26,8 @@ struct display_connector {
2526
2627 struct regulator * supply ;
2728 struct gpio_desc * ddc_en ;
29+
30+ struct work_struct hpd_work ;
2831};
2932
3033static inline struct display_connector *
@@ -87,6 +90,34 @@ display_connector_bridge_detect(struct drm_bridge *bridge, struct drm_connector
8790 return display_connector_detect (bridge );
8891}
8992
93+ static void display_connector_hpd_enable (struct drm_bridge * bridge )
94+ {
95+ struct display_connector * conn = to_display_connector (bridge );
96+
97+ enable_irq (conn -> hpd_irq );
98+
99+ if (conn -> bridge .type == DRM_MODE_CONNECTOR_DisplayPort )
100+ schedule_work (& conn -> hpd_work );
101+ }
102+
103+ static void display_connector_hpd_disable (struct drm_bridge * bridge )
104+ {
105+ struct display_connector * conn = to_display_connector (bridge );
106+
107+ if (conn -> bridge .type == DRM_MODE_CONNECTOR_DisplayPort )
108+ cancel_work_sync (& conn -> hpd_work );
109+
110+ disable_irq (conn -> hpd_irq );
111+ }
112+
113+ static void display_connector_hpd_work (struct work_struct * work )
114+ {
115+ struct display_connector * conn = container_of (work , struct display_connector , hpd_work );
116+ struct drm_bridge * bridge = & conn -> bridge ;
117+
118+ drm_bridge_hpd_notify (bridge , display_connector_detect (bridge ));
119+ }
120+
90121static const struct drm_edid * display_connector_edid_read (struct drm_bridge * bridge ,
91122 struct drm_connector * connector )
92123{
@@ -178,6 +209,8 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge,
178209static const struct drm_bridge_funcs display_connector_bridge_funcs = {
179210 .attach = display_connector_attach ,
180211 .detect = display_connector_bridge_detect ,
212+ .hpd_enable = display_connector_hpd_enable ,
213+ .hpd_disable = display_connector_hpd_disable ,
181214 .edid_read = display_connector_edid_read ,
182215 .atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts ,
183216 .atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts ,
@@ -307,6 +340,7 @@ static int display_connector_probe(struct platform_device *pdev)
307340 NULL , display_connector_hpd_irq ,
308341 IRQF_TRIGGER_RISING |
309342 IRQF_TRIGGER_FALLING |
343+ IRQF_NO_AUTOEN |
310344 IRQF_ONESHOT ,
311345 "HPD" , conn );
312346 if (ret ) {
@@ -378,6 +412,8 @@ static int display_connector_probe(struct platform_device *pdev)
378412 conn -> bridge .ops |= DRM_BRIDGE_OP_DETECT ;
379413 if (conn -> hpd_irq >= 0 )
380414 conn -> bridge .ops |= DRM_BRIDGE_OP_HPD ;
415+ if (conn -> hpd_irq >= 0 && type == DRM_MODE_CONNECTOR_DisplayPort )
416+ INIT_WORK (& conn -> hpd_work , display_connector_hpd_work );
381417
382418 dev_dbg (& pdev -> dev ,
383419 "Found %s display connector '%s' %s DDC bus and %s HPD GPIO (ops 0x%x)\n" ,
0 commit comments