diff options
-rw-r--r-- | drivers/gpu/drm/panel/panel-lg-sw43408.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c index d9befd42b995..02495f6548fb 100644 --- a/drivers/gpu/drm/panel/panel-lg-sw43408.c +++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c @@ -84,6 +84,8 @@ struct panel_info { struct pinctrl_state *active; struct pinctrl_state *suspend; + struct notifier_block nb; + bool prepared; bool enabled; bool first_enable; @@ -94,7 +96,6 @@ static inline struct panel_info *to_panel_info(struct drm_panel *panel) return container_of(panel, struct panel_info, base); } - /* * Need to reset gpios and regulators once in the beginning, */ @@ -416,6 +417,65 @@ pr_err("In sw43408 panel_enable\n"); return 0; } +static int panel_lab_regulator_event(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct panel_info *pinfo = + container_of(nb, struct panel_info, nb); + int ret; +pr_err("In sw43408 panel_lab_regulator_event\n"); + + if (event & REGULATOR_EVENT_OVER_CURRENT) { + /* Try to reinitialise the panel, since lab regulator would + * have been disabled by the short circuit. + * if it throws an error, then the panel won't recover; + * shutdown the panel. + */ + ret = lg_panel_prepare(&pinfo->base); + + if (ret) { + dev_err(pinfo->base.dev, + "Failed to re-enable lab regulator: %d\n", + ret); + lg_panel_unprepare(&pinfo->base); + return ret; + } + } + + return 0; +} + +static int panel_register_lab_notify(struct panel_info *pinfo) +{ + int i, ret = 0; + struct regulator *lab_reg = NULL; +pr_err("In sw43408 panel_register_lab_notify\n"); + + pinfo->nb.notifier_call = panel_lab_regulator_event; + + for (i = 0; i < ARRAY_SIZE(pinfo->supplies); i++) { + if (strcmp(pinfo->supplies[i].supply, "lab") == 0) { + lab_reg = pinfo->supplies[i].consumer; + break; + } + } + + if (lab_reg != NULL) { + ret = devm_regulator_register_notifier(lab_reg, &pinfo->nb); + + if (ret) + dev_err(pinfo->base.dev, + "Failed to register lab notifier: %d\n", ret); + } else { + dev_err(pinfo->base.dev, + "Invalid name while trying to register lab notifier: %d\n", ret); + + ret = -EINVAL; + } + + return ret; +} + static int lg_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -635,6 +695,10 @@ pr_err("In sw43408 panel add\n"); if (ret < 0) return ret; + ret = panel_register_lab_notify(pinfo); + if (ret < 0) + return ret; + pinfo->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(pinfo->reset_gpio)) { DRM_DEV_ERROR(dev, "cannot get reset gpio %ld\n", |