|
@@ -32,7 +32,9 @@
|
|
|
#include <linux/kthread.h>
|
|
|
#include <linux/suspend.h>
|
|
|
#include "pt_regs.h"
|
|
|
+#if defined(CONFIG_PANEL_NOTIFIER)
|
|
|
#include <linux/soc/qcom/panel_event_notifier.h>
|
|
|
+#endif
|
|
|
|
|
|
#define PINCTRL_STATE_ACTIVE "pmx_ts_active"
|
|
|
#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
|
|
@@ -52,7 +54,7 @@
|
|
|
|
|
|
#define PT_STATUS_STR_LEN (50)
|
|
|
|
|
|
-#if defined(CONFIG_DRM)
|
|
|
+#if defined(CONFIG_DRM) || defined(CONFIG_PANEL_NOTIFIER)
|
|
|
static struct drm_panel *active_panel;
|
|
|
#endif
|
|
|
|
|
@@ -12791,21 +12793,19 @@ static void pt_suspend_work(struct work_struct *work)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+#if defined(CONFIG_PANEL_NOTIFIER)
|
|
|
/*******************************************************************************
|
|
|
- * FUNCTION: drm_notifier_callback
|
|
|
+ * FUNCTION: panel_event_notifier_callback
|
|
|
*
|
|
|
- * SUMMARY: Call back function for DRM notifier to allow to call
|
|
|
+ * SUMMARY: Call back function for Panel Event notifier to allow to call
|
|
|
* resume/suspend attention list.
|
|
|
*
|
|
|
- * RETURN:
|
|
|
- * 0 = success
|
|
|
- *
|
|
|
* PARAMETERS:
|
|
|
- * *self - pointer to notifier_block structure
|
|
|
- * event - event type of fb notifier
|
|
|
- * *data - pointer to fb_event structure
|
|
|
+ * tag - type of input panel.
|
|
|
+ * *notification - pointer to notification details.
|
|
|
+ * *client_data - pointer to core data
|
|
|
******************************************************************************/
|
|
|
-static void drm_notifier_callback(enum panel_event_notifier_tag tag,
|
|
|
+static void panel_event_notifier_callback(enum panel_event_notifier_tag tag,
|
|
|
struct panel_event_notification *notification, void *client_data)
|
|
|
{
|
|
|
struct pt_core_data *cd = client_data;
|
|
@@ -12817,14 +12817,6 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
|
|
|
}
|
|
|
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: DRM notifier called!\n", __func__);
|
|
|
-
|
|
|
- if (!(notification->notif_type == DRM_PANEL_EVENT_BLANK ||
|
|
|
- notification->notif_type == DRM_PANEL_EVENT_BLANK)) {
|
|
|
- pt_debug(cd->dev, DL_INFO, "%s: Event(%d) do not need process\n",
|
|
|
- __func__, notification->notif_type);
|
|
|
- goto exit;
|
|
|
- }
|
|
|
-
|
|
|
if (cd->quick_boot || cd->drv_debug_suspend)
|
|
|
goto exit;
|
|
|
|
|
@@ -12835,10 +12827,167 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
|
|
|
|
|
|
if (notification->notif_type == DRM_PANEL_EVENT_UNBLANK) {
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: UNBLANK!\n", __func__);
|
|
|
- if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ if (notification->notif_data.early_trigger) {
|
|
|
+ pr_err("%s: resume: event = %d, not care\n", __func__, notification->notif_type);
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: resume: event = %d, not care\n",
|
|
|
__func__, notification->notif_type);
|
|
|
- } else if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ } else {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
|
|
|
+ __func__);
|
|
|
+ cancel_work_sync(&cd->resume_offload_work);
|
|
|
+ cancel_work_sync(&cd->suspend_offload_work);
|
|
|
+ cancel_work_sync(&cd->resume_work);
|
|
|
+ cancel_work_sync(&cd->suspend_work);
|
|
|
+
|
|
|
+ queue_work(cd->pt_workqueue, &cd->resume_work);
|
|
|
+#if defined(CONFIG_PM_SLEEP)
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
|
|
|
+ __func__);
|
|
|
+ if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
|
|
|
+ pt_core_resume_(cd->dev);
|
|
|
+#endif
|
|
|
+ cd->fb_state = FB_ON;
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Resume notified!\n", __func__);
|
|
|
+ }
|
|
|
+ } else if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: BLANK!\n", __func__);
|
|
|
+ if (notification->notif_data.early_trigger) {
|
|
|
+#if defined(CONFIG_PM_SLEEP)
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n",
|
|
|
+ __func__);
|
|
|
+ if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
|
|
|
+ pt_core_suspend_(cd->dev);
|
|
|
+#endif
|
|
|
+ cancel_work_sync(&cd->resume_offload_work);
|
|
|
+ cancel_work_sync(&cd->suspend_offload_work);
|
|
|
+ cancel_work_sync(&cd->resume_work);
|
|
|
+ cancel_work_sync(&cd->suspend_work);
|
|
|
+
|
|
|
+ queue_work(cd->pt_workqueue, &cd->suspend_work);
|
|
|
+ cd->fb_state = FB_OFF;
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
|
|
|
+ } else {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %d, not care\n",
|
|
|
+ __func__, notification->notif_type);
|
|
|
+ }
|
|
|
+ } else if (notification->notif_type == DRM_PANEL_EVENT_BLANK_LP) {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: LOWPOWER!\n", __func__);
|
|
|
+ if (notification->notif_data.early_trigger) {
|
|
|
+#if defined(CONFIG_PM_SLEEP)
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n", __func__);
|
|
|
+ if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
|
|
|
+ pt_core_suspend_(cd->dev);
|
|
|
+#endif
|
|
|
+ cancel_work_sync(&cd->resume_offload_work);
|
|
|
+ cancel_work_sync(&cd->suspend_offload_work);
|
|
|
+ cancel_work_sync(&cd->resume_work);
|
|
|
+ cancel_work_sync(&cd->suspend_work);
|
|
|
+
|
|
|
+ queue_work(cd->pt_workqueue, &cd->suspend_work);
|
|
|
+ cd->fb_state = FB_OFF;
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
|
|
|
+ } else {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %d, not care\n",
|
|
|
+ __func__, notification->notif_type);
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: DRM BLANK(%d) do not need process\n",
|
|
|
+ __func__, notification->notif_type);
|
|
|
+ }
|
|
|
+exit:
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ * FUNCTION: pt_setup_panel_event_notifier
|
|
|
+ *
|
|
|
+ * SUMMARY: Set up call back function into drm notifier.
|
|
|
+ *
|
|
|
+ * PARAMETERS:
|
|
|
+ * *cd - pointer to core data
|
|
|
+ ******************************************************************************/
|
|
|
+static void pt_setup_panel_event_notifier(struct pt_core_data *cd)
|
|
|
+{
|
|
|
+ void *cookie = NULL;
|
|
|
+
|
|
|
+ if (!active_panel)
|
|
|
+ pt_debug(cd->dev, DL_ERROR,
|
|
|
+ "%s: Active panel not registered!\n", __func__);
|
|
|
+
|
|
|
+ cd->pt_workqueue = create_singlethread_workqueue("ts_wq");
|
|
|
+ if (!cd->pt_workqueue) {
|
|
|
+ pt_debug(cd->dev, DL_ERROR,
|
|
|
+ "%s: worker thread creation failed !\n", __func__);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cd->pt_workqueue) {
|
|
|
+ INIT_WORK(&cd->resume_work, pt_resume_work);
|
|
|
+ INIT_WORK(&cd->suspend_work, pt_suspend_work);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ cookie = panel_event_notifier_register(PANEL_EVENT_NOTIFICATION_PRIMARY,
|
|
|
+ PANEL_EVENT_NOTIFIER_CLIENT_PRIMARY_TOUCH,
|
|
|
+ active_panel,&panel_event_notifier_callback, cd);
|
|
|
+
|
|
|
+ if (active_panel && !cookie)
|
|
|
+ {
|
|
|
+ pt_debug(cd->dev, DL_ERROR,
|
|
|
+ "%s: Register notifier failed!\n", __func__);
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ * FUNCTION: drm_notifier_callback
|
|
|
+ *
|
|
|
+ * SUMMARY: Call back function for DRM notifier to allow to call
|
|
|
+ * resume/suspend attention list.
|
|
|
+ *
|
|
|
+ * RETURN:
|
|
|
+ * 0 = success
|
|
|
+ *
|
|
|
+ * PARAMETERS:
|
|
|
+ * *self - pointer to notifier_block structure
|
|
|
+ * event - event type of fb notifier
|
|
|
+ * *data - pointer to fb_event structure
|
|
|
+ ******************************************************************************/
|
|
|
+static int drm_notifier_callback(struct notifier_block *self,
|
|
|
+ unsigned long event, void *data)
|
|
|
+{
|
|
|
+ struct pt_core_data *cd =
|
|
|
+ container_of(self, struct pt_core_data, fb_notifier);
|
|
|
+ struct drm_panel_notifier *evdata = data;
|
|
|
+ int *blank;
|
|
|
+
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: DRM notifier called!\n", __func__);
|
|
|
+
|
|
|
+ if (!evdata)
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ if (!(event == DRM_PANEL_EARLY_EVENT_BLANK ||
|
|
|
+ event == DRM_PANEL_EVENT_BLANK)) {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Event(%lu) do not need process\n",
|
|
|
+ __func__, event);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cd->quick_boot || cd->drv_debug_suspend)
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ blank = evdata->data;
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: DRM event:%lu,blank:%d fb_state %d sleep state %d ",
|
|
|
+ __func__, event, *blank, cd->fb_state, cd->sleep_state);
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: DRM Power - %s - FB state %d ",
|
|
|
+ __func__, (*blank == DRM_PANEL_BLANK_UNBLANK)?"UP":"DOWN", cd->fb_state);
|
|
|
+
|
|
|
+ if (*blank == DRM_PANEL_BLANK_UNBLANK) {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: UNBLANK!\n", __func__);
|
|
|
+ if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: resume: event = %lu, not care\n",
|
|
|
+ __func__, event);
|
|
|
+ } else if (event == DRM_PANEL_EVENT_BLANK) {
|
|
|
if (cd->fb_state != FB_ON) {
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
|
|
|
__func__);
|
|
@@ -12858,9 +13007,9 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: Resume notified!\n", __func__);
|
|
|
}
|
|
|
}
|
|
|
- } else if (notification->notif_type == DRM_PANEL_EVENT_BLANK_LP) {
|
|
|
+ } else if (*blank == DRM_PANEL_BLANK_LP || *blank == DRM_PANEL_BLANK_POWERDOWN) {
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: LOWPOWER!\n", __func__);
|
|
|
- if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
|
|
|
if (cd->fb_state != FB_OFF) {
|
|
|
#if defined(CONFIG_PM_SLEEP)
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n",
|
|
@@ -12877,16 +13026,17 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
|
|
|
cd->fb_state = FB_OFF;
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
|
|
|
}
|
|
|
- } else if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
|
|
|
- pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %d, not care\n",
|
|
|
- __func__, notification->notif_type);
|
|
|
+
|
|
|
+ } else if (event == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %lu, not care\n",
|
|
|
+ __func__, event);
|
|
|
}
|
|
|
} else {
|
|
|
pt_debug(cd->dev, DL_INFO, "%s: DRM BLANK(%d) do not need process\n",
|
|
|
- __func__, notification->notif_type);
|
|
|
+ __func__, *blank);
|
|
|
}
|
|
|
exit:
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
@@ -12899,7 +13049,9 @@ exit:
|
|
|
******************************************************************************/
|
|
|
static void pt_setup_drm_notifier(struct pt_core_data *cd)
|
|
|
{
|
|
|
- void *cookie = NULL;
|
|
|
+ cd->fb_state = FB_NONE;
|
|
|
+ cd->fb_notifier.notifier_call = drm_notifier_callback;
|
|
|
+ pt_debug(cd->dev, DL_INFO, "%s: Setting up drm notifier\n", __func__);
|
|
|
|
|
|
if (!active_panel)
|
|
|
pt_debug(cd->dev, DL_ERROR,
|
|
@@ -12916,10 +13068,13 @@ static void pt_setup_drm_notifier(struct pt_core_data *cd)
|
|
|
INIT_WORK(&cd->suspend_work, pt_suspend_work);
|
|
|
}
|
|
|
|
|
|
- cookie = panel_event_notifier_register(PANEL_EVENT_NOTIFICATION_PRIMARY,
|
|
|
- PANEL_EVENT_NOTIFIER_CLIENT_PRIMARY_TOUCH,
|
|
|
- active_panel,&drm_notifier_callback, cd);
|
|
|
+ if (active_panel &&
|
|
|
+ drm_panel_notifier_register(active_panel,
|
|
|
+ &cd->fb_notifier) < 0)
|
|
|
+ pt_debug(cd->dev, DL_ERROR,
|
|
|
+ "%s: Register notifier failed!\n", __func__);
|
|
|
}
|
|
|
+#endif
|
|
|
#elif defined(CONFIG_FB)
|
|
|
/*******************************************************************************
|
|
|
* FUNCTION: fb_notifier_callback
|
|
@@ -17600,7 +17755,7 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev,
|
|
|
/* Set platform easywake value */
|
|
|
cd->easy_wakeup_gesture = cd->cpdata->easy_wakeup_gesture;
|
|
|
|
|
|
-#ifdef CONFIG_DRM
|
|
|
+#if defined(CONFIG_DRM) || defined(CONFIG_PANEL_NOTIFIER)
|
|
|
/* Setup active dsi panel */
|
|
|
active_panel = cd->cpdata->active_panel;
|
|
|
#endif
|
|
@@ -17846,6 +18001,11 @@ skip_enum:
|
|
|
|
|
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|
|
pt_setup_early_suspend(cd);
|
|
|
+#elif defined(CONFIG_PANEL_NOTIFIER)
|
|
|
+ pt_debug(dev, DL_ERROR, "%s: Probe: Setup Panel Event notifier\n", __func__);
|
|
|
+ pt_setup_panel_event_notifier(cd);
|
|
|
+ INIT_WORK(&cd->resume_offload_work, pt_resume_offload_work);
|
|
|
+ INIT_WORK(&cd->suspend_offload_work, pt_suspend_offload_work);
|
|
|
#elif defined(CONFIG_DRM)
|
|
|
pt_debug(dev, DL_ERROR, "%s: Probe: Setup drm notifier\n", __func__);
|
|
|
pt_setup_drm_notifier(cd);
|
|
@@ -17967,9 +18127,12 @@ int pt_release(struct pt_core_data *cd)
|
|
|
|
|
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|
|
unregister_early_suspend(&cd->es);
|
|
|
-#elif defined(CONFIG_DRM)
|
|
|
+#elif defined(CONFIG_PANEL_NOTIFIER)
|
|
|
if (active_panel)
|
|
|
panel_event_notifier_unregister(&cd->fb_notifier);
|
|
|
+#elif defined(CONFIG_DRM)
|
|
|
+ if (active_panel)
|
|
|
+ drm_panel_notifier_unregister(active_panel, &cd->fb_notifier);
|
|
|
#elif defined(CONFIG_FB)
|
|
|
fb_unregister_client(&cd->fb_notifier);
|
|
|
#endif
|