diff mbox series

RFC: drm/panel: s6e63m0: Register ESD IRQ handler

Message ID 20210509230808.353422-1-linus.walleij@linaro.org (mailing list archive)
State New, archived
Headers show
Series RFC: drm/panel: s6e63m0: Register ESD IRQ handler | expand

Commit Message

Linus Walleij May 9, 2021, 11:08 p.m. UTC
The S6E63M0 can emit an "ESD IRQ" which spells out
electrostatic discharge interrupt request. This exist
on other panels as well.

The interrupt will according to some sources occur
as a result of the display being bent or cracked
and generally failing to display the desired content.

I have no idea about how we should handle this
IRQ, but the codebase for the Samsung GT-S7710 handles
it by restarting the display controller pipeline,
and possibly we should also bring the panel, bridge,
and display controller down/up in response.

One idea I have is to broadcast a notifier so that the
core can react to this in process context in response
to this interrupt and restart the display pipeline.
I.e. raw_notifier_call_chain().

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
index 603c5dfe8768..5e4d2e8aa7a7 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
@@ -17,6 +17,8 @@ 
 #include <linux/module.h>
 #include <linux/regulator/consumer.h>
 #include <linux/media-bus-format.h>
+#include <linux/of_irq.h>
+#include <linux/interrupt.h>
 
 #include <video/mipi_display.h>
 
@@ -713,6 +715,18 @@  static int s6e63m0_backlight_register(struct s6e63m0 *ctx, u32 max_brightness)
 	return ret;
 }
 
+static irqreturn_t s6e63m0_esd_irq(int irq, void *data)
+{
+	struct s6e63m0 *ctx = data;
+
+	dev_info(ctx->dev, "ESD IRQ occurred\n");
+
+	/* Signal to the display controller to restart? */
+	msleep(100);
+
+	return IRQ_HANDLED;
+}
+
 int s6e63m0_probe(struct device *dev,
 		  int (*dcs_read)(struct device *dev, const u8 cmd, u8 *val),
 		  int (*dcs_write)(struct device *dev, const u8 *data, size_t len),
@@ -720,6 +734,7 @@  int s6e63m0_probe(struct device *dev,
 {
 	struct s6e63m0 *ctx;
 	u32 max_brightness;
+	int irq;
 	int ret;
 
 	ctx = devm_kzalloc(dev, sizeof(struct s6e63m0), GFP_KERNEL);
@@ -758,6 +773,13 @@  int s6e63m0_probe(struct device *dev,
 		return PTR_ERR(ctx->reset_gpio);
 	}
 
+	irq = of_irq_get(dev->of_node, 0);
+	if (irq) {
+		ret = devm_request_threaded_irq(dev, irq, NULL,
+						s6e63m0_esd_irq, IRQF_ONESHOT,
+						"s6e63m0-esd", ctx);
+	}
+
 	drm_panel_init(&ctx->panel, dev, &s6e63m0_drm_funcs,
 		       dsi_mode ? DRM_MODE_CONNECTOR_DSI :
 		       DRM_MODE_CONNECTOR_DPI);