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.wall...@linaro.org>
---
 drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

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);
-- 
2.30.2

Reply via email to