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(a)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