Skip to content

Commit 8915fc6

Browse files
authored
drm/bridge: display-connector: detect DP state if cable is plugged on boot (#397)
drm/bridge: display-connector: detect DP state if cable is plugged on boot
2 parents 70a1b6e + 481191b commit 8915fc6

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

drivers/gpu/drm/bridge/display-connector.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
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

3033
static 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+
90121
static 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,
178209
static 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

Comments
 (0)