summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKe Qinghua <qinghua.ke@freescale.com>2014-04-04 16:22:34 +0800
committerNitin Garg <nitin.garg@freescale.com>2014-04-21 22:35:45 -0500
commit24b7d5ca843cd63f1ee1ae7ebdb00f78dd3f62b9 (patch)
treea7c935a5401c93ad3bdec37a9957da95a5287406 /drivers
parent85c1fa95bf70927b33a0613edb690ae4759e0653 (diff)
ENGR00305254-7 imx6sx sarbesd board bring up
Enable early suspend/late resume code Signed-off-by: Ke Qinghua <qinghua.ke@freescale.com> Acked-by: Jason Liu
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/gpio_event.c39
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c92
2 files changed, 120 insertions, 11 deletions
diff --git a/drivers/input/misc/gpio_event.c b/drivers/input/misc/gpio_event.c
index 90f07eba3ce9..d4e5b4dfe19f 100644
--- a/drivers/input/misc/gpio_event.c
+++ b/drivers/input/misc/gpio_event.c
@@ -13,6 +13,7 @@
*
*/
+#include <linux/earlysuspend.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/gpio_event.h>
@@ -23,6 +24,7 @@
struct gpio_event {
struct gpio_event_input_devs *input_devs;
const struct gpio_event_platform_data *info;
+ struct early_suspend early_suspend;
void *state[0];
};
@@ -99,19 +101,23 @@ err_no_func:
return ret;
}
-static void __maybe_unused gpio_event_suspend(struct gpio_event *ip)
+#ifdef CONFIG_HAS_EARLYSUSPEND
+void gpio_event_suspend(struct early_suspend *h)
{
+ struct gpio_event *ip;
+ ip = container_of(h, struct gpio_event, early_suspend);
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_SUSPEND);
- if (ip->info->power)
- ip->info->power(ip->info, 0);
+ ip->info->power(ip->info, 0);
}
-static void __maybe_unused gpio_event_resume(struct gpio_event *ip)
+void gpio_event_resume(struct early_suspend *h)
{
- if (ip->info->power)
- ip->info->power(ip->info, 1);
+ struct gpio_event *ip;
+ ip = container_of(h, struct gpio_event, early_suspend);
+ ip->info->power(ip->info, 1);
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_RESUME);
}
+#endif
static int gpio_event_probe(struct platform_device *pdev)
{
@@ -163,8 +169,15 @@ static int gpio_event_probe(struct platform_device *pdev)
}
ip->input_devs->count = dev_count;
ip->info = event_info;
- if (event_info->power)
+ if (event_info->power) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ ip->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ ip->early_suspend.suspend = gpio_event_suspend;
+ ip->early_suspend.resume = gpio_event_resume;
+ register_early_suspend(&ip->early_suspend);
+#endif
ip->info->power(ip->info, 1);
+ }
err = gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_INIT);
if (err)
@@ -185,8 +198,12 @@ static int gpio_event_probe(struct platform_device *pdev)
err_input_register_device_failed:
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
err_call_all_func_failed:
- if (event_info->power)
+ if (event_info->power) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&ip->early_suspend);
+#endif
ip->info->power(ip->info, 0);
+ }
for (i = 0; i < registered; i++)
input_unregister_device(ip->input_devs->dev[i]);
for (i = dev_count - 1; i >= registered; i--) {
@@ -205,8 +222,12 @@ static int gpio_event_remove(struct platform_device *pdev)
int i;
gpio_event_call_all_func(ip, GPIO_EVENT_FUNC_UNINIT);
- if (ip->info->power)
+ if (ip->info->power) {
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&ip->early_suspend);
+#endif
ip->info->power(ip->info, 0);
+ }
for (i = 0; i < ip->input_devs->count; i++)
input_unregister_device(ip->input_devs->dev[i]);
kfree(ip);
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index 57dad6f90725..bc853225d6c3 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -49,6 +49,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
+#include <linux/earlysuspend.h>
#include "mxc_dispdrv.h"
/*
@@ -99,6 +100,9 @@ struct mxcfb_info {
struct fb_var_screeninfo cur_var;
ktime_t vsync_nf_timestamp;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend fbdrv_earlysuspend;
+#endif
};
struct mxcfb_pfmt {
@@ -136,6 +140,10 @@ enum {
static bool g_dp_in_use[2];
LIST_HEAD(fb_alloc_list);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mxcfb_early_suspend(struct early_suspend *h);
+static void mxcfb_later_resume(struct early_suspend *h);
+#endif
/* Return default standard(RGB) pixel format */
static uint32_t bpp_to_pixfmt(int bpp)
@@ -1685,7 +1693,7 @@ static irqreturn_t mxcfb_alpha_irq_handler(int irq, void *dev_id)
/*
* Suspends the framebuffer and blanks the screen. Power management support
*/
-static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
+static int mxcfb_core_suspend(struct platform_device *pdev, pm_message_t state)
{
struct fb_info *fbi = platform_get_drvdata(pdev);
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
@@ -1717,9 +1725,22 @@ static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
}
/*
+ * Suspends the framebuffer and blanks the screen. Power management support
+ */
+static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ if (strstr(mxc_fbi->dispdrv->drv->name, "hdmi"))
+ return mxcfb_core_suspend(pdev, state);
+
+ return 0;
+}
+/*
* Resumes the framebuffer and unblanks the screen. Power management support
*/
-static int mxcfb_resume(struct platform_device *pdev)
+static int mxcfb_core_resume(struct platform_device *pdev)
{
struct fb_info *fbi = platform_get_drvdata(pdev);
struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
@@ -1737,6 +1758,18 @@ static int mxcfb_resume(struct platform_device *pdev)
fb_set_suspend(mxc_fbi->ovfbi, 0);
console_unlock();
}
+ return 0;
+}
+/*
+ * Resumes the framebuffer and unblanks the screen. Power management support
+ */
+static int mxcfb_resume(struct platform_device *pdev)
+{
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+
+ if (strstr(mxc_fbi->dispdrv->drv->name, "hdmi"))
+ return mxcfb_core_resume(pdev);
return 0;
}
@@ -2515,6 +2548,13 @@ static int mxcfb_probe(struct platform_device *pdev)
"Error %d on creating file\n", ret);
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ mxcfbi->fbdrv_earlysuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
+ mxcfbi->fbdrv_earlysuspend.suspend = mxcfb_early_suspend;
+ mxcfbi->fbdrv_earlysuspend.resume = mxcfb_later_resume;
+ mxcfbi->fbdrv_earlysuspend.data = pdev;
+ register_early_suspend(&mxcfbi->fbdrv_earlysuspend);
+#endif
return 0;
mxcfb_setupoverlay_failed:
@@ -2537,6 +2577,9 @@ static int mxcfb_remove(struct platform_device *pdev)
if (!fbi)
return 0;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&mxc_fbi->fbdrv_earlysuspend);
+#endif
device_remove_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
device_remove_file(fbi->dev, &dev_attr_fsl_disp_property);
@@ -2579,6 +2622,51 @@ static struct platform_driver mxcfb_driver = {
.suspend = mxcfb_suspend,
.resume = mxcfb_resume,
};
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mxcfb_early_suspend(struct early_suspend *h)
+{
+ struct platform_device *pdev = (struct platform_device *)h->data;
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
+ pm_message_t state = { .event = PM_EVENT_SUSPEND };
+ struct fb_event event;
+ int blank = FB_BLANK_POWERDOWN;
+
+ if (mxcfbi->ipu_ch == MEM_FG_SYNC)
+ return;
+
+ if (strstr(mxcfbi->dispdrv->drv->name, "hdmi")) {
+ /* Only black the hdmi fb due to audio dependency */
+ memset(fbi->screen_base, 0, fbi->fix.smem_len);
+ return;
+ }
+
+ mxcfb_core_suspend(pdev, state);
+ event.info = fbi;
+ event.data = &blank;
+ fb_notifier_call_chain(FB_EVENT_BLANK, &event);
+}
+
+static void mxcfb_later_resume(struct early_suspend *h)
+{
+ struct platform_device *pdev = (struct platform_device *)h->data;
+ struct fb_info *fbi = platform_get_drvdata(pdev);
+ struct mxcfb_info *mxcfbi = (struct mxcfb_info *)fbi->par;
+ struct fb_event event;
+
+ if (mxcfbi->ipu_ch == MEM_FG_SYNC)
+ return;
+
+ /* HDMI resume function has been called */
+ if (strstr(mxcfbi->dispdrv->drv->name, "hdmi"))
+ return;
+
+ mxcfb_core_resume(pdev);
+ event.info = fbi;
+ event.data = &mxcfbi->next_blank;
+ fb_notifier_call_chain(FB_EVENT_BLANK, &event);
+}
+#endif
/*!
* Main entry function for the framebuffer. The function registers the power