summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWengang Wu <wgw@motorola.com>2014-07-17 16:45:00 -0500
committerJee Su Chang <w20740@motorola.com>2014-07-17 22:07:22 +0000
commit0e4a00c83a912944beed3d2d36915278a0d418f7 (patch)
treed19773db4d9ee2cc16aee52405f754af4e54d3dc
parentb0b06d3dbb9d3a100b58b21f7de31ca3cb5240d7 (diff)
downloadolio-linux-3.10-0e4a00c83a912944beed3d2d36915278a0d418f7.tar.xz
olio-linux-3.10-0e4a00c83a912944beed3d2d36915278a0d418f7.zip
IKXCLOCK-3032 Display: turn off display automatically after early init
Change-Id: I9aa283e6014611039fd04f44118cd9bb1f29963f
-rw-r--r--drivers/video/omap2/displays/panel-minnow.c108
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c6
2 files changed, 91 insertions, 23 deletions
diff --git a/drivers/video/omap2/displays/panel-minnow.c b/drivers/video/omap2/displays/panel-minnow.c
index be370356711..e6b87422196 100644
--- a/drivers/video/omap2/displays/panel-minnow.c
+++ b/drivers/video/omap2/displays/panel-minnow.c
@@ -339,14 +339,20 @@ struct minnow_panel_data {
bool vsync_events_enabled;
ktime_t vsync_events_timestamp;
#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
+ bool early_inited;
struct notifier_block displayenable_nb;
struct work_struct early_init_work;
+ struct delayed_work early_init_timeout_work;
#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */
#if defined(CONFIG_HAS_AMBIENTMODE)
struct completion resume_completion;
#endif
};
+#define DECLARE_MPD_FROM_CONTAINER(ptr, member) \
+ struct minnow_panel_data *mpd = \
+ container_of(ptr, struct minnow_panel_data, member)
+
/* panel parameter passed from boot-loader */
static char *def_panel_param;
module_param_named(panel_param, def_panel_param, charp, 0);
@@ -365,7 +371,8 @@ static int minnow_panel_update_locked(struct minnow_panel_data *mpd);
static void minnow_panel_esd_work(struct work_struct *work);
static void minnow_panel_ulps_work(struct work_struct *work);
-static int minnow_panel_enable(struct omap_dss_device *dssdev);
+static int minnow_panel_enable_mlocked(struct minnow_panel_data *mpd);
+static void minnow_panel_disable_mlocked(struct minnow_panel_data *mpd);
static void minnow_panel_sync_resume_mlocked(struct minnow_panel_data *mpd)
{
@@ -387,8 +394,7 @@ static void minnow_panel_sync_resume_mlocked(struct minnow_panel_data *mpd)
static int omapdss_displayenable_notify(struct notifier_block *self,
unsigned long action, void *dev)
{
- struct minnow_panel_data *mpd =
- container_of(self, struct minnow_panel_data, displayenable_nb);
+ DECLARE_MPD_FROM_CONTAINER(self, displayenable_nb);
dev_info(&mpd->dssdev->dev, "%s, action is %lu", __func__, action);
if (action == DISPLAY_WAKE_EVENT) {
/* Queue work to init the display */
@@ -399,13 +405,38 @@ static int omapdss_displayenable_notify(struct notifier_block *self,
static void minnow_panel_early_init_func(struct work_struct *work)
{
- struct minnow_panel_data *mpd;
+ DECLARE_MPD_FROM_CONTAINER(work, early_init_work);
int r;
- mpd = container_of(work, struct minnow_panel_data, early_init_work);
- r = minnow_panel_enable(mpd->dssdev);
- if (r)
- dev_err(&mpd->dssdev->dev, "minnow_panel_enable failed: %d\n",
- r);
+ mutex_lock(&mpd->lock);
+ if (!mpd->enabled) {
+ r = minnow_panel_enable_mlocked(mpd);
+ if (r) {
+ dev_err(&mpd->dssdev->dev,
+ "%s: minnow_panel_enable failed: %d\n",
+ __func__, r);
+ } else {
+ /* it will turn off display if it's not enabled
+ * by android within 500ms or kernel suspend
+ */
+ mpd->early_inited = true;
+ queue_delayed_work(mpd->workqueue,
+ &mpd->early_init_timeout_work,
+ msecs_to_jiffies(500));
+ }
+ }
+ mutex_unlock(&mpd->lock);
+}
+
+static void minnow_panel_early_init_timeout_func(struct work_struct *work)
+{
+ DECLARE_MPD_FROM_CONTAINER(work, early_init_timeout_work.work);
+ mutex_lock(&mpd->lock);
+ if (mpd->early_inited) {
+ minnow_panel_disable_mlocked(mpd);
+ dev_dbg(&mpd->dssdev->dev, "%s: cancelled previous early"
+ " initialize works\n", __func__);
+ }
+ mutex_unlock(&mpd->lock);
}
#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */
@@ -2355,6 +2386,8 @@ static int minnow_panel_probe(struct omap_dss_device *dssdev)
#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
INIT_WORK(&mpd->early_init_work, minnow_panel_early_init_func);
+ INIT_DELAYED_WORK(&mpd->early_init_timeout_work,
+ minnow_panel_early_init_timeout_func);
mpd->displayenable_nb.notifier_call = omapdss_displayenable_notify;
wakeup_source_register_notify(&mpd->displayenable_nb);
#endif /* CONFIG_WAKEUP_SOURCE_NOTIFY */
@@ -2667,13 +2700,12 @@ err:
return r;
}
-static int minnow_panel_enable(struct omap_dss_device *dssdev)
+static int minnow_panel_enable_mlocked(struct minnow_panel_data *mpd)
{
- struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_device *dssdev = mpd->dssdev;
bool update;
int r = 0;
- mutex_lock(&mpd->lock);
dev_info(&dssdev->dev, "%s: current state = %d\n",
__func__, dssdev->state);
@@ -2703,20 +2735,20 @@ static int minnow_panel_enable(struct omap_dss_device *dssdev)
}
wake_unlock(&mpd->wake_lock);
}
- mutex_unlock(&mpd->lock);
return r;
}
-static void minnow_panel_disable(struct omap_dss_device *dssdev)
+static void minnow_panel_disable_mlocked(struct minnow_panel_data *mpd)
{
- struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
+ struct omap_dss_device *dssdev = mpd->dssdev;
dev_info(&dssdev->dev, "%s: current state = %d\n",
__func__, dssdev->state);
- mutex_lock(&mpd->lock);
wake_lock(&mpd->wake_lock);
+ mpd->early_inited = false;
+ cancel_delayed_work(&mpd->early_init_timeout_work);
minnow_panel_cancel_ulps_work(mpd);
minnow_panel_cancel_esd_work(mpd);
minnow_panel_sync_resume_mlocked(mpd);
@@ -2730,7 +2762,6 @@ static void minnow_panel_disable(struct omap_dss_device *dssdev)
dsi_bus_unlock(dssdev);
wake_unlock(&mpd->wake_lock);
- mutex_unlock(&mpd->lock);
}
#if defined(CONFIG_HAS_AMBIENTMODE)
@@ -2741,6 +2772,14 @@ static int minnow_panel_suspend(struct omap_dss_device *dssdev)
__func__, dssdev->state, wake_lock_active(&mpd->wake_lock));
mutex_lock(&mpd->lock);
+#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
+ /* it needs turn off display if it's early initialized */
+ if (mpd->early_inited) {
+ minnow_panel_disable_mlocked(mpd);
+ dev_dbg(&mpd->dssdev->dev, "%s: cancelled previous early"
+ " initialize works\n", __func__);
+ }
+#endif
if (mpd->enabled) {
dsi_bus_lock(dssdev);
minnow_panel_enter_ulps_locked(mpd);
@@ -2834,8 +2873,7 @@ err:
static void minnow_panel_te_timeout_work_callback(struct work_struct *work)
{
- struct minnow_panel_data *mpd = container_of(work, struct minnow_panel_data,
- te_timeout_work.work);
+ DECLARE_MPD_FROM_CONTAINER(work, te_timeout_work.work);
struct omap_dss_device *dssdev = mpd->dssdev;
dev_err(&dssdev->dev, "TE not received for 250ms!\n");
@@ -2844,6 +2882,32 @@ static void minnow_panel_te_timeout_work_callback(struct work_struct *work)
dsi_bus_unlock(dssdev);
}
+static int minnow_panel_enable(struct omap_dss_device *dssdev)
+{
+ struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
+ int r;
+
+ mutex_lock(&mpd->lock);
+#ifdef CONFIG_WAKEUP_SOURCE_NOTIFY
+ if (mpd->early_inited) {
+ mpd->early_inited = false;
+ cancel_delayed_work(&mpd->early_init_timeout_work);
+ }
+#endif
+ r = minnow_panel_enable_mlocked(mpd);
+ mutex_unlock(&mpd->lock);
+ return r;
+}
+
+static void minnow_panel_disable(struct omap_dss_device *dssdev)
+{
+ struct minnow_panel_data *mpd = dev_get_drvdata(&dssdev->dev);
+
+ mutex_lock(&mpd->lock);
+ minnow_panel_disable_mlocked(mpd);
+ mutex_unlock(&mpd->lock);
+}
+
static int minnow_panel_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h)
{
@@ -3078,8 +3142,7 @@ err1:
static void minnow_panel_ulps_work(struct work_struct *work)
{
- struct minnow_panel_data *mpd = container_of(work, struct minnow_panel_data,
- ulps_work.work);
+ DECLARE_MPD_FROM_CONTAINER(work, ulps_work.work);
struct omap_dss_device *dssdev = mpd->dssdev;
mutex_lock(&mpd->lock);
@@ -3098,8 +3161,7 @@ static void minnow_panel_ulps_work(struct work_struct *work)
static void minnow_panel_esd_work(struct work_struct *work)
{
- struct minnow_panel_data *mpd = container_of(work, struct minnow_panel_data,
- esd_work.work);
+ DECLARE_MPD_FROM_CONTAINER(work, esd_work.work);
struct omap_dss_device *dssdev = mpd->dssdev;
int r;
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 350ceaa81ff..7464de4c93f 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1251,8 +1251,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
switch (blank) {
case FB_BLANK_UNBLANK:
+#if !defined(CONFIG_WAKEUP_SOURCE_NOTIFY) && !defined(CONFIG_HAS_AMBIENTMODE)
if (display->state == OMAP_DSS_DISPLAY_ACTIVE)
goto exit;
+#endif
r = display->driver->enable(display);
@@ -1269,8 +1271,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
+#if !defined(CONFIG_WAKEUP_SOURCE_NOTIFY) && !defined(CONFIG_HAS_AMBIENTMODE)
if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
goto exit;
+#endif
if (d->auto_update_work_enabled)
omapfb_stop_auto_update(fbdev, display);
@@ -1283,7 +1287,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
r = -EINVAL;
}
+#if !defined(CONFIG_WAKEUP_SOURCE_NOTIFY) && !defined(CONFIG_HAS_AMBIENTMODE)
exit:
+#endif
omapfb_unlock(fbdev);
return r;