diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 890fce9b3683e8b0be59a923fcb9fb1cbab727d4..1eeeb6dfe6444f4bcce49f6e46350698b7cf4162 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -978,6 +978,19 @@ disable_xfrm - BOOLEAN Disable IPSEC encryption on this interface, whatever the policy +drop_unicast_in_l2_multicast - BOOLEAN + Drop any unicast IP packets that are received in link-layer + multicast (or broadcast) frames. + This behavior (for multicast) is actually a SHOULD in RFC + 1122, but is disabled by default for compatibility reasons. + Default: off (0) + +drop_gratuitous_arp - BOOLEAN + Drop all gratuitous ARP frames, for example if there's a known + good ARP proxy on the network and such frames need not be used + (or in the case of 802.11, must not be used to prevent attacks.) + Default: off (0) + tag - INTEGER Allows you to write a number, which can be used as required. @@ -1264,6 +1277,19 @@ force_tllao - BOOLEAN race condition where the sender deletes the cached link-layer address prior to receiving a response to a previous solicitation." +drop_unicast_in_l2_multicast - BOOLEAN + Drop any unicast IPv6 packets that are received in link-layer + multicast (or broadcast) frames. + + By default this is turned off. + +drop_unsolicited_na - BOOLEAN + Drop all unsolicited neighbor advertisements, for example if there's + a known good NA proxy on the network and such frames need not be used + (or in the case of 802.11, must not be used to prevent attacks.) + + By default this is turned off. + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_func.c b/drivers/input/touchscreen/wacom/wacom_i2c_func.c index 347b4bcc88b6aa4f2eb589e811dabaf019487f36..a7244bc6d1a384da8b3270a01c1d7f9b99c6751f 100644 --- a/drivers/input/touchscreen/wacom/wacom_i2c_func.c +++ b/drivers/input/touchscreen/wacom/wacom_i2c_func.c @@ -837,6 +837,7 @@ static void handle_gestures(int x, int y, ktime_t end, struct wacom_i2c *wac_i2c int dx = x - wac_i2c->gesture_start_x; int dy = y - wac_i2c->gesture_start_y; int dt = ktime_to_ms(ktime_sub(end, wac_i2c->gesture_start_time)); + int dtb = ktime_to_ms(ktime_sub(wac_i2c->gesture_start_time, wac_i2c->gesture_old_end_time)); if (abs(dy) > abs(dx)) { if (abs(dy) > MIN_GEST_DIST) { @@ -850,18 +851,20 @@ static void handle_gestures(int x, int y, ktime_t end, struct wacom_i2c *wac_i2c return; } } - //********************************************************************new gesture*********************************** - if ((dt >= SHORT_PRESS_TIME) && (dt < LONG_PRESS_TIME)) { - printk(KERN_DEBUG "[E-PEN] short pressed!\n"); + if ((dt >= SHORT_PRESS_TIME) && (dt < SHORT_PRESS_DOUBLED) && (dtb <= BREAK_TIME) && (dtb > 0)) { + printk(KERN_DEBUG "[E-PEN] double short pressed, send back event!\n"); input_report_key(wac_i2c->input_dev, KEY_BACK, 1); input_report_key(wac_i2c->input_dev, KEY_BACK, 0); input_sync(wac_i2c->input_dev); - wac_i2c->gesture_key = KEY_PEN_SP; return; } - + else if ((dt >= SHORT_PRESS_DOUBLED) && (dt < LONG_PRESS_TIME)) + { + printk(KERN_DEBUG "[E-PEN] short pressed!\n"); + wac_i2c->gesture_key = KEY_PEN_SP; + } else if (dt >= LONG_PRESS_TIME) { wac_i2c->gesture_key = KEY_PEN_LP; return; @@ -880,6 +883,8 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) u8 gain = 0; u8 height = 0; int aveStrength = 2; + ktime_t time; + #ifdef WACOM_USE_SOFTKEY static s16 softkey, pressed, keycode; #endif @@ -1053,7 +1058,9 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c) wac_i2c->gesture_start_time = ktime_get(); } else if (!stylus && wac_i2c->side_pressed) { printk(KERN_DEBUG "[E-PEN] side off\n"); - handle_gestures(x, y, ktime_get(), wac_i2c); + time = ktime_get(); + handle_gestures(x, y, time, wac_i2c); + wac_i2c->gesture_old_end_time = time; if (wac_i2c->gesture_key > -1 && (wac_i2c->enabled_gestures & (1 << (wac_i2c->gesture_key - 0x2f1)))) { diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index bbedab55e59e5347e15baff03c5568e915d30dff..f60bfca5da58cae3d4b704a40327d17ba13dd0ee 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -17,8 +17,9 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif /* Registers */ @@ -47,8 +48,9 @@ struct lp855x { struct mutex xfer_lock; struct lp855x_platform_data *pdata; int enabled; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; +#ifdef CONFIG_FB + struct notifier_block fb_notif; + bool fb_suspended; #endif }; @@ -321,27 +323,55 @@ static int lp855x_config(struct lp855x *lp) } #endif -#ifdef CONFIG_HAS_EARLYSUSPEND -static void lp855x_early_suspend(struct early_suspend *h) +#ifdef CONFIG_FB +static void lp855x_fb_suspend(struct lp855x *lp) { - struct lp855x *lp = - container_of(h, struct lp855x, early_suspend); + if (lp->fb_suspended) + return; lp855x_set_power(lp, 0); + lp->fb_suspended = true; } -static void lp855x_late_resume(struct early_suspend *h) +static void lp855x_fb_resume(struct lp855x *lp) { - struct lp855x *lp = - container_of(h, struct lp855x, early_suspend); + if (!lp->fb_suspended) + return; lp855x_set_power(lp, 1); backlight_update_status(lp->bl); #if defined(CONFIG_MACH_KONA) lp855x_config(lp); #endif + lp->fb_suspended = false; +} +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct lp855x *info = container_of(self, struct lp855x, fb_notif); + if (evdata && evdata->data && info) { + if (event == FB_EVENT_BLANK) { + blank = evdata->data; + switch (*blank) { + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + lp855x_fb_resume(info); + break; + default: + case FB_BLANK_POWERDOWN: + lp855x_fb_suspend(info); + break; + } + } + } + return 0; } + #endif static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) @@ -381,13 +411,11 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) } lp->enabled = 1; -#ifdef CONFIG_HAS_EARLYSUSPEND - if (lp->pdata->use_gpio_en) { - lp->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2; - lp->early_suspend.suspend = lp855x_early_suspend; - lp->early_suspend.resume = lp855x_late_resume; - register_early_suspend(&lp->early_suspend); - } + +#ifdef CONFIG_FB + lp->fb_suspended = false; + lp->fb_notif.notifier_call = fb_notifier_callback; + fb_register_client(&lp->fb_notif); #endif ret = lp855x_backlight_register(lp); diff --git a/drivers/video/samsung/gd2evf.c b/drivers/video/samsung/gd2evf.c index a171c1936a4f13587f1be1b247c02ecf33f1248e..ca4a770027cadc59e07ee0811d6c84a52aa14430 100644 --- a/drivers/video/samsung/gd2evf.c +++ b/drivers/video/samsung/gd2evf.c @@ -413,7 +413,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #if defined(CONFIG_PM) #ifdef CONFIG_HAS_EARLYSUSPEND -void gd2evf_early_suspend(struct early_suspend *h) +void gd2evf_fb_suspend(struct early_suspend *h) { struct lcd_info *lcd = container_of(h, struct lcd_info , early_suspend); @@ -424,7 +424,7 @@ void gd2evf_early_suspend(struct early_suspend *h) return ; } -void gd2evf_late_resume(struct early_suspend *h) +void gd2evf_fb_resume(struct early_suspend *h) { struct lcd_info *lcd = container_of(h, struct lcd_info , early_suspend); @@ -504,10 +504,10 @@ static int gd2evf_probe(struct spi_device *spi) dev_set_drvdata(&spi->dev, lcd); #ifdef CONFIG_HAS_EARLYSUSPEND - lcd->early_suspend.suspend = gd2evf_early_suspend; - lcd->early_suspend.resume = NULL; /* gd2evf_late_resume; */ + lcd->early_suspend.suspend = gd2evf_fb_suspend; + lcd->early_suspend.resume = NULL; /* gd2evf_fb_resume; */ lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - register_early_suspend(&lcd->early_suspend); + register_fb_suspend(&lcd->early_suspend); #endif return 0; diff --git a/drivers/video/samsung/hx8369b.c b/drivers/video/samsung/hx8369b.c index 1265110868e79da5689023665c8e511982149fe6..ae66d26f1b4ac3f73ab8d1053be92b01c84f9f69 100644 --- a/drivers/video/samsung/hx8369b.c +++ b/drivers/video/samsung/hx8369b.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" @@ -48,7 +48,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned int irq; unsigned int connected; @@ -222,8 +223,8 @@ static const unsigned char SEQ_SLEEP_IN[] = { 0x00, 0x00 }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int _hx8369b_write(struct lcd_info *lcd, const unsigned char *seq, int len) { @@ -463,7 +464,7 @@ static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL); #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void hx8369b_early_suspend(void) +void hx8369b_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -478,7 +479,7 @@ void hx8369b_early_suspend(void) return ; } -void hx8369b_late_resume(void) +void hx8369b_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -490,6 +491,8 @@ void hx8369b_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -536,8 +539,8 @@ static int hx8369b_probe(struct device *dev) dev_info(&lcd->ld->dev, "hx8369b lcd panel driver has been probed.\n"); - lcd_early_suspend = hx8369b_early_suspend; - lcd_late_resume = hx8369b_late_resume; + lcd_fb_suspend = hx8369b_fb_suspend; + lcd_fb_resume = hx8369b_fb_resume; return 0; diff --git a/drivers/video/samsung/lcdfreq.c b/drivers/video/samsung/lcdfreq.c index 0379115692efcf2820ad95d57a3d6f925a8436f7..8de08a365b1e58105631fa023d42d9e107c13a81 100644 --- a/drivers/video/samsung/lcdfreq.c +++ b/drivers/video/samsung/lcdfreq.c @@ -14,6 +14,10 @@ #include #include #include +#ifdef CONFIG_FB +#include +#include +#endif #include #include @@ -80,7 +84,10 @@ struct lcdfreq_info { int blank; - struct early_suspend early_suspend; +#ifdef CONFIG_FB + struct notifier_block fb_notif; + bool fb_suspended; +#endif }; static inline struct lcdfreq_info *dev_get_lcdfreq(struct device *dev) @@ -393,10 +400,11 @@ static struct attribute_group lcdfreq_attr_group = { .attrs = lcdfreq_attributes, }; -static void lcdfreq_early_suspend(struct early_suspend *h) +#ifdef CONFIG_FB +static void lcdfreq_fb_suspend(struct lcdfreq_info *lcdfreq) { - struct lcdfreq_info *lcdfreq = - container_of(h, struct lcdfreq_info, early_suspend); + if (lcdfreq->fb_suspended) + return; dev_info(lcdfreq->dev, "%s\n", __func__); @@ -406,13 +414,14 @@ static void lcdfreq_early_suspend(struct early_suspend *h) atomic_set(&lcdfreq->usage, 0); mutex_unlock(&lcdfreq->lock); + lcdfreq->fb_suspended = true; return; } -static void lcdfreq_late_resume(struct early_suspend *h) +static void lcdfreq_fb_resume(struct lcdfreq_info *lcdfreq) { - struct lcdfreq_info *lcdfreq = - container_of(h, struct lcdfreq_info, early_suspend); + if (!lcdfreq->fb_suspended) + return; dev_info(lcdfreq->dev, "%s\n", __func__); @@ -420,9 +429,38 @@ static void lcdfreq_late_resume(struct early_suspend *h) lcdfreq->enable = true; mutex_unlock(&lcdfreq->lock); + lcdfreq->fb_suspended = false; return; } +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct lcdfreq_info *info = container_of(self, struct lcdfreq_info, fb_notif); + + if (evdata && evdata->data && info) { + if (event == FB_EVENT_BLANK) { + blank = evdata->data; + switch (*blank) { + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + lcdfreq_fb_resume(info); + break; + default: + case FB_BLANK_POWERDOWN: + lcdfreq_fb_suspend(info); + break; + } + } + } + + return 0; +} +#endif #if 0 static int lcdfreq_pm_notifier_event(struct notifier_block *this, unsigned long event, void *ptr) @@ -578,10 +616,11 @@ static int lcdfreq_probe(struct platform_device *pdev) info->reboot_noti.notifier_call = lcdfreq_reboot_notify; register_reboot_notifier(&info->reboot_noti); - info->early_suspend.suspend = lcdfreq_early_suspend; - info->early_suspend.resume = lcdfreq_late_resume; - info->early_suspend.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING + 1; - register_early_suspend(&info->early_suspend); +#ifdef CONFIG_FB + info->fb_suspended = false; + info->fb_notif.notifier_call = fb_notifier_callback; + fb_register_client(&info->fb_notif); +#endif info->ielcd_reg = ioremap(IELCD_REG_BASE, IELCD_MAP_SIZE); info->enable = true; diff --git a/drivers/video/samsung/mdnie.c b/drivers/video/samsung/mdnie.c index 2f424bdd0d37d5a253d694b5fa159d4d4e088045..d4bf0147336b62f7c3549000cddb5cab0ad869db 100644 --- a/drivers/video/samsung/mdnie.c +++ b/drivers/video/samsung/mdnie.c @@ -1009,15 +1009,20 @@ static struct device_attribute mdnie_attributes[] = { }; #ifdef CONFIG_PM -#if defined(CONFIG_HAS_EARLYSUSPEND) -#if defined(CONFIG_FB_MDNIE_PWM) -static void mdnie_early_suspend(struct early_suspend *h) +#if defined(CONFIG_FB) +static void mdnie_fb_suspend(struct mdnie_info *mdnie) { - struct mdnie_info *mdnie = container_of(h, struct mdnie_info, early_suspend); - struct lcd_platform_data *pd = mdnie->lcd_pd; + if (mdnie->fb_suspended) + return; + + mdnie->fb_suspended = true; dev_info(mdnie->dev, "+%s\n", __func__); + printk("%s: scenario:%d accessibility:%d", __func__, mdnie->scenario, mdnie->accessibility); +#if defined(CONFIG_FB_MDNIE_PWM) + struct lcd_platform_data *pd = mdnie->lcd_pd; + mdnie->bd_enable = FALSE; if (mdnie->enable) @@ -1026,22 +1031,23 @@ static void mdnie_early_suspend(struct early_suspend *h) if (pd && pd->power_on) pd->power_on(NULL, 0); +#endif dev_info(mdnie->dev, "-%s\n", __func__); return; } -#endif -static void mdnie_late_resume(struct early_suspend *h) +static void mdnie_fb_resume(struct mdnie_info *mdnie) { - struct mdnie_info *mdnie = container_of(h, struct mdnie_info, early_suspend); -#if defined(CONFIG_FB_MDNIE_PWM) - struct lcd_platform_data *pd = mdnie->lcd_pd; -#endif + if (!mdnie->fb_suspended) + return; + + mdnie->fb_suspended = false; dev_info(mdnie->dev, "+%s\n", __func__); #if defined(CONFIG_FB_MDNIE_PWM) + struct lcd_platform_data *pd = mdnie->lcd_pd; if (mdnie->enable) mdnie_pwm_control(mdnie, 0); @@ -1055,7 +1061,6 @@ static void mdnie_late_resume(struct early_suspend *h) mdnie->bd_enable = TRUE; #endif - mdnie_update(mdnie); dev_info(mdnie->dev, "-%s\n", __func__); @@ -1063,6 +1068,32 @@ static void mdnie_late_resume(struct early_suspend *h) return; } #endif + +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct mdnie_info *mdnie = container_of(self, struct mdnie_info, fb_notif); + if (evdata && evdata->data && mdnie) { + if (event == FB_EVENT_BLANK) { + blank = evdata->data; + switch (*blank) { + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + mdnie_fb_resume(mdnie); + break; + default: + case FB_BLANK_POWERDOWN: + mdnie_fb_suspend(mdnie); + break; + } + } + } + return 0; +} #endif static int mdnie_probe(struct platform_device *pdev) @@ -1140,13 +1171,10 @@ static int mdnie_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mdnie); dev_set_drvdata(mdnie->dev, mdnie); -#ifdef CONFIG_HAS_EARLYSUSPEND -#if defined(CONFIG_FB_MDNIE_PWM) - mdnie->early_suspend.suspend = mdnie_early_suspend; -#endif - mdnie->early_suspend.resume = mdnie_late_resume; - mdnie->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - register_early_suspend(&mdnie->early_suspend); +#ifdef CONFIG_FB + mdnie->fb_suspended = false; + mdnie->fb_notif.notifier_call = fb_notifier_callback; + fb_register_client(&mdnie->fb_notif); #endif @@ -1228,7 +1256,7 @@ static struct platform_driver mdnie_driver = { }, .probe = mdnie_probe, .remove = mdnie_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND +#ifndef CONFIG_FB .suspend = mdnie_suspend, .resume = mdnie_resume, #endif diff --git a/drivers/video/samsung/mdnie.h b/drivers/video/samsung/mdnie.h index 24f72c13a7ec57366ca12ca7c47148d7439d4b1f..16636fc3723f9fc1ef437b8c218d15f67ba6eccb 100644 --- a/drivers/video/samsung/mdnie.h +++ b/drivers/video/samsung/mdnie.h @@ -1,8 +1,9 @@ #ifndef __MDNIE_H__ #define __MDNIE_H__ -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif #define END_SEQ 0xffff @@ -111,8 +112,9 @@ struct mdnie_info { unsigned int accessibility; unsigned int color_correction; char path[50]; -#ifdef CONFIG_HAS_EARLYSUSPEND - struct early_suspend early_suspend; +#ifdef CONFIG_FB + struct notifier_block fb_notif; + bool fb_suspended; #endif #ifdef CONFIG_FB_MDNIE_RGB_ADJUST u8 r_adj; diff --git a/drivers/video/samsung/nt35560.c b/drivers/video/samsung/nt35560.c index 97e2f7caba4a4572ccee29393a2479a0f3a7b304..b24873bdf8d672f4e3d3c3d57dcf181c5c50341d 100644 --- a/drivers/video/samsung/nt35560.c +++ b/drivers/video/samsung/nt35560.c @@ -460,7 +460,7 @@ static DEVICE_ATTR(lcd_type, 0664, lcdtype_show, NULL); #if defined(CONFIG_PM) #ifdef CONFIG_HAS_EARLYSUSPEND -void nt35560_early_suspend(struct early_suspend *h) +void nt35560_fb_suspend(struct early_suspend *h) { struct lcd_info *lcd = container_of(h, struct lcd_info , early_suspend); @@ -471,7 +471,7 @@ void nt35560_early_suspend(struct early_suspend *h) return ; } -void nt35560_late_resume(struct early_suspend *h) +void nt35560_fb_resume(struct early_suspend *h) { struct lcd_info *lcd = container_of(h, struct lcd_info , early_suspend); @@ -567,10 +567,10 @@ static int nt35560_probe(struct spi_device *spi) dev_set_drvdata(&spi->dev, lcd); #ifdef CONFIG_HAS_EARLYSUSPEND - lcd->early_suspend.suspend = nt35560_early_suspend; - lcd->early_suspend.resume = nt35560_late_resume; + lcd->early_suspend.suspend = nt35560_fb_suspend; + lcd->early_suspend.resume = nt35560_fb_resume; lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - register_early_suspend(&lcd->early_suspend); + register_fb_suspend(&lcd->early_suspend); #endif dev_info(&lcd->ld->dev, "nt35560 panel driver has been probed.\n"); diff --git a/drivers/video/samsung/s3cfb.h b/drivers/video/samsung/s3cfb.h index 820de723ab895aed80317d1b3fc5220c4a787253..7a08ad26084945e051e31c27788bbaebdf497fc4 100644 --- a/drivers/video/samsung/s3cfb.h +++ b/drivers/video/samsung/s3cfb.h @@ -17,8 +17,11 @@ #include #include #ifdef CONFIG_HAS_WAKELOCK +#ifdef CONFIG_FB +#include +#include +#endif #include -#include #endif #include #endif @@ -238,7 +241,10 @@ struct s3cfb_global { int timeline_max; unsigned int support_fence; #ifdef CONFIG_HAS_WAKELOCK - struct early_suspend early_suspend; +#ifdef CONFIG_FB + struct notifier_block fb_notif; + bool fb_suspended; +#endif struct wake_lock idle_lock; #endif #ifdef FEATURE_BUSFREQ_LOCK @@ -491,8 +497,8 @@ extern void s3cfb_set_lcd_info(struct s3cfb_global *ctrl); #ifdef CONFIG_FB_S5P_MIPI_DSIM extern int s3cfb_vsync_status_check(void); -extern void s5p_dsim_early_suspend(void); -extern void s5p_dsim_late_resume(void); +extern void s5p_dsim_fb_suspend(void); +extern void s5p_dsim_fb_resume(void); extern void set_dsim_hs_clk_toggle_count(u8 count); extern void set_dsim_lcd_enabled(u8 enable); #endif diff --git a/drivers/video/samsung/s3cfb_ea8061.c b/drivers/video/samsung/s3cfb_ea8061.c index d9290740044828d33f3df9f63818c2c9b9a42469..f52a81871a40bcbd6f2b82856217ad5947406537 100644 --- a/drivers/video/samsung/s3cfb_ea8061.c +++ b/drivers/video/samsung/s3cfb_ea8061.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "ea8061_param.h" @@ -73,7 +73,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; unsigned char **gamma_table; unsigned char **elvss_table; @@ -112,8 +113,8 @@ static unsigned int aid_candela_table[GAMMA_MAX] = { }; #endif -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #if defined(GPIO_ERR_FG) static void err_fg_detection_work(struct work_struct *work) @@ -1029,7 +1030,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND static struct lcd_info *g_lcd; -void ea8061_early_suspend(void) +void ea8061_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -1052,7 +1053,7 @@ void ea8061_early_suspend(void) return ; } -void ea8061_late_resume(void) +void ea8061_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -1069,6 +1070,8 @@ void ea8061_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -1146,6 +1149,7 @@ static int ea8061_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -1221,8 +1225,8 @@ static int ea8061_probe(struct device *dev) } #endif - lcd_early_suspend = ea8061_early_suspend; - lcd_late_resume = ea8061_late_resume; + lcd_fb_suspend = ea8061_fb_suspend; + lcd_fb_resume = ea8061_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_lms501xx.c b/drivers/video/samsung/s3cfb_lms501xx.c index 8bbc8b787ddf425a9357df157ba85b6cbdb9bced..24a5343211e14e6258cd0be509fed342b0dc23d3 100644 --- a/drivers/video/samsung/s3cfb_lms501xx.c +++ b/drivers/video/samsung/s3cfb_lms501xx.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "lms501xx.h" @@ -64,7 +64,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; @@ -90,8 +91,8 @@ static const unsigned int candela_table[GAMMA_MAX-1] = { 230, 240, MAX_BRIGHTNESS, MAX_GAMMA }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); struct LCD_BRIGHTNESS { int off; int deflt; @@ -874,7 +875,7 @@ static DEVICE_ATTR(auto_brightness, 0644, #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void lms501xx_early_suspend(void) +void lms501xx_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -904,7 +905,7 @@ void lms501xx_early_suspend(void) return ; } -void lms501xx_late_resume(void) +void lms501xx_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -925,18 +926,20 @@ void lms501xx_late_resume(void) #endif + lcd->fb_suspended = false; + return ; } #ifdef DDI_STATUS_REG_PREVENTESD static void lms501xx_reinitialize_lcd(void) { - lms501xx_early_suspend(); - s5p_dsim_early_suspend(); + lms501xx_fb_suspend(); + s5p_dsim_fb_suspend(); msleep(20); - s5p_dsim_late_resume(); + s5p_dsim_fb_resume(); msleep(20); - lms501xx_late_resume(); + lms501xx_fb_resume(); printk(KERN_INFO "%s, re-initialize LCD - Done\n", __func__); } #endif @@ -1006,6 +1009,7 @@ static int lms501xx_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -1058,8 +1062,8 @@ static int lms501xx_probe(struct device *dev) schedule_delayed_work(&lcd->check_ddi, msecs_to_jiffies(20000)); } #endif - lcd_early_suspend = lms501xx_early_suspend; - lcd_late_resume = lms501xx_late_resume; + lcd_fb_suspend = lms501xx_fb_suspend; + lcd_fb_resume = lms501xx_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_main.c b/drivers/video/samsung/s3cfb_main.c index 35dc1d5add493cc398831177eeef9b1d56496008..d285878271a2000b2f99148938247ea92454dbad 100644 --- a/drivers/video/samsung/s3cfb_main.c +++ b/drivers/video/samsung/s3cfb_main.c @@ -47,7 +47,10 @@ #endif #ifdef CONFIG_HAS_WAKELOCK #include -#include +#ifdef CONFIG_FB +#include +#include +#endif #include #endif @@ -546,13 +549,15 @@ void s3cfb_lcd0_pmu_off(void) } #ifdef CONFIG_PM -#ifdef CONFIG_HAS_EARLYSUSPEND -void (*lcd_early_suspend)(void); -void (*lcd_late_resume)(void); +#ifdef CONFIG_FB +void (*lcd_fb_suspend)(void); +void (*lcd_fb_resume)(void); -void s3cfb_early_suspend(struct early_suspend *h) +void s3cfb_fb_suspend(struct s3cfb_global *info) { - struct s3cfb_global *info = container_of(h, struct s3cfb_global, early_suspend); + if (info->fb_suspended) + return; + struct s3c_platform_fb *pdata = to_fb_plat(info->dev); struct platform_device *pdev = to_platform_device(info->dev); struct s3cfb_global *fbdev[2]; @@ -562,13 +567,13 @@ void s3cfb_early_suspend(struct early_suspend *h) #ifdef CONFIG_FB_S5P_GD2EVF info->suspend = 1; - if (lcd_early_suspend && current_mipi_lcd) - lcd_early_suspend(); + if (lcd_fb_suspend && current_mipi_lcd) + lcd_fb_suspend(); else gd2evf_power_ext(0); #elif defined(CONFIG_FB_S5P_MIPI_DSIM) - if (lcd_early_suspend) - lcd_early_suspend(); + if (lcd_fb_suspend) + lcd_fb_suspend(); #endif for (i = 0; i < FIMD_MAX; i++) { @@ -618,9 +623,9 @@ void s3cfb_early_suspend(struct early_suspend *h) } #ifdef CONFIG_FB_S5P_GD2EVF if (current_mipi_lcd) - s5p_dsim_early_suspend(); + s5p_dsim_fb_suspend(); #elif defined(CONFIG_FB_S5P_MIPI_DSIM) - s5p_dsim_early_suspend(); + s5p_dsim_fb_suspend(); #endif #ifdef CONFIG_EXYNOS_DEV_PD /* disable the power domain */ @@ -638,12 +643,15 @@ void s3cfb_early_suspend(struct early_suspend *h) dev_info(info->dev, "-%s\n", __func__); + info->fb_suspended = true; return; } -void s3cfb_late_resume(struct early_suspend *h) +void s3cfb_fb_resume(struct s3cfb_global *info) { - struct s3cfb_global *info = container_of(h, struct s3cfb_global, early_suspend); + if (!info->fb_suspended) + return; + struct s3c_platform_fb *pdata = to_fb_plat(info->dev); struct fb_info *fb; struct s3cfb_window *win; @@ -662,9 +670,9 @@ void s3cfb_late_resume(struct early_suspend *h) #ifdef CONFIG_FB_S5P_GD2EVF if (current_mipi_lcd) - s5p_dsim_late_resume(); + s5p_dsim_fb_resume(); #elif defined(CONFIG_FB_S5P_MIPI_DSIM) - s5p_dsim_late_resume(); + s5p_dsim_fb_resume(); #endif for (i = 0; i < FIMD_MAX; i++) { @@ -748,14 +756,14 @@ void s3cfb_late_resume(struct early_suspend *h) } #ifdef CONFIG_FB_S5P_GD2EVF - if (lcd_late_resume && current_mipi_lcd) - lcd_late_resume(); + if (lcd_fb_resume && current_mipi_lcd) + lcd_fb_resume(); else gd2evf_power_ext(1); info->suspend = 0; #elif defined(CONFIG_FB_S5P_MIPI_DSIM) - if (lcd_late_resume) - lcd_late_resume(); + if (lcd_fb_resume) + lcd_fb_resume(); #endif #ifdef CONFIG_FB_S5P_TRACE_UNDERRUN @@ -764,11 +772,41 @@ void s3cfb_late_resume(struct early_suspend *h) #endif dev_info(info->dev, "-%s\n", __func__); + info->fb_suspended = false; return; } -#else /* else !CONFIG_HAS_EARLYSUSPEND */ +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct s3cfb_global *info = container_of(self, struct s3cfb_global, fb_notif); + + if (evdata && evdata->data && info) { + if (event == FB_EVENT_BLANK) { + blank = evdata->data; + switch (*blank) { + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + s3cfb_fb_resume(info); + break; + default: + case FB_BLANK_POWERDOWN: + s3cfb_fb_suspend(info); + break; + } + } + } + + return 0; +} +#endif + +#ifndef CONFIG_HAS_EARLYSUSPEND int s3cfb_suspend(struct platform_device *pdev, pm_message_t state) { struct s3c_platform_fb *pdata = to_fb_plat(&pdev->dev); @@ -905,7 +943,7 @@ static int s3cfb_disable(struct s3cfb_global *fbdev) dev_info(fbdev->dev, "+%s\n", __func__); - if (lcd_early_suspend && current_mipi_lcd) + if (lcd_fb_suspend && current_mipi_lcd) s6d6aa1_power_ext(0); else gd2evf_power_ext(0); @@ -961,7 +999,7 @@ static int s3cfb_enable(struct s3cfb_global *fbdev) #endif if (current_mipi_lcd) - s5p_dsim_late_resume(); + s5p_dsim_fb_resume(); mutex_lock(&fbdev->output_lock); @@ -1017,11 +1055,11 @@ static int s3cfb_enable(struct s3cfb_global *fbdev) mutex_unlock(&fbdev->output_lock); - if (lcd_late_resume && current_mipi_lcd) + if (lcd_fb_resume && current_mipi_lcd) s6d6aa1_power_ext(1); else { gd2evf_power_ext(1); - s5p_dsim_early_suspend(); + s5p_dsim_fb_suspend(); } #ifdef CONFIG_FB_S5P_TRACE_UNDERRUN @@ -1265,12 +1303,10 @@ static int s3cfb_probe(struct platform_device *pdev) #endif #ifdef CONFIG_HAS_WAKELOCK -#ifdef CONFIG_HAS_EARLYSUSPEND - fbdev[i]->early_suspend.suspend = s3cfb_early_suspend; - fbdev[i]->early_suspend.resume = s3cfb_late_resume; - fbdev[i]->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; - - register_early_suspend(&fbdev[i]->early_suspend); +#ifdef CONFIG_FB + fbdev[i]->fb_suspended = false; + fbdev[i]->fb_notif.notifier_call = fb_notifier_callback; + fb_register_client(&fbdev[i]->fb_notif); #endif #endif #if defined(CONFIG_FB_S5P_VSYNC_THREAD) @@ -1375,8 +1411,8 @@ static int s3cfb_remove(struct platform_device *pdev) fbdev[i] = fbfimd->fbdev[i]; #ifdef CONFIG_HAS_WAKELOCK -#ifdef CONFIG_HAS_EARLYSUSPEND - unregister_early_suspend(&fbdev[i]->early_suspend); +#ifdef CONFIG_FB + fb_unregister_client(&fbdev[i]->fb_notif); #endif #endif free_irq(fbdev[i]->irq, fbdev[i]); diff --git a/drivers/video/samsung/s3cfb_nt71391.c b/drivers/video/samsung/s3cfb_nt71391.c index 4e329c0b0a47dd6386defbe48337ac426e6a9a90..3ecebd8a693b120b5b48bcfa4e95c9f07b2de663 100644 --- a/drivers/video/samsung/s3cfb_nt71391.c +++ b/drivers/video/samsung/s3cfb_nt71391.c @@ -21,8 +21,9 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif #include "s3cfb.h" @@ -41,6 +42,10 @@ struct lcd_info { #if defined(CONFIG_MACH_KONA) unsigned int connected; struct mutex lock; +#endif +#ifdef CONFIG_FB + struct notifier_block fb_notif; + bool fb_suspended; #endif struct lcd_device *ld; struct lcd_platform_data *lcd_pd; @@ -285,12 +290,12 @@ static struct lcd_ops nt71391_lcd_ops = { }; #ifdef CONFIG_HAS_EARLYSUSPEND -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); struct lcd_info *g_lcd; -void nt71391_early_suspend(void) +void nt71391_fb_suspend(void) { struct lcd_info *lcd = g_lcd; int err = 0; @@ -306,7 +311,7 @@ void nt71391_early_suspend(void) return ; } -void nt71391_late_resume(void) +void nt71391_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -318,6 +323,8 @@ void nt71391_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -355,8 +362,8 @@ static int __init nt71391_probe(struct device *dev) dev_info(dev, "lcd panel driver has been probed.\n"); #ifdef CONFIG_HAS_EARLYSUSPEND - lcd_early_suspend = nt71391_early_suspend; - lcd_late_resume = nt71391_late_resume; + lcd_fb_suspend = nt71391_fb_suspend; + lcd_fb_resume = nt71391_fb_resume; #endif ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type); if (ret < 0) diff --git a/drivers/video/samsung/s3cfb_s6d7aa0.c b/drivers/video/samsung/s3cfb_s6d7aa0.c index fae246189dc2a2dda6b7e94d4fe902b7c69deb4a..ce09abf69b0eaa96704fab17753c07153614fe47 100644 --- a/drivers/video/samsung/s3cfb_s6d7aa0.c +++ b/drivers/video/samsung/s3cfb_s6d7aa0.c @@ -19,10 +19,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "s6d7aa0_param.h" @@ -52,8 +52,8 @@ struct lcd_info { }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int s6d7aa0_power(struct lcd_info *lcd, int power); static int _s6d7aa0_write(struct lcd_info *lcd, const unsigned char *seq, int len) @@ -406,7 +406,7 @@ static DEVICE_ATTR(window_type, 0444, window_type_show, NULL); #ifdef CONFIG_HAS_EARLYSUSPEND static struct lcd_info *g_lcd; -void s6d7aa0_early_suspend(void) +void s6d7aa0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -420,7 +420,7 @@ void s6d7aa0_early_suspend(void) return ; } -void s6d7aa0_late_resume(void) +void s6d7aa0_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -431,6 +431,8 @@ void s6d7aa0_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -513,8 +515,8 @@ static int s6d7aa0_probe(struct device *dev) pr_err("failed to reqeust irq. %d\n", lcd->err_fg_irq); } - lcd_early_suspend = s6d7aa0_early_suspend; - lcd_late_resume = s6d7aa0_late_resume; + lcd_fb_suspend = s6d7aa0_fb_suspend; + lcd_fb_resume = s6d7aa0_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_s6e39a0.c b/drivers/video/samsung/s3cfb_s6e39a0.c index a07e45582e0d830a26ed7bf99965e7e83e99fa06..7265fe07b62590d198a0c4d48afa16b65e7b3d53 100644 --- a/drivers/video/samsung/s3cfb_s6e39a0.c +++ b/drivers/video/samsung/s3cfb_s6e39a0.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" @@ -89,7 +89,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned int lcd_id; @@ -110,8 +111,8 @@ struct lcd_info { struct dsim_global *dsim; }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int s6e39a0_write(struct lcd_info *lcd, const unsigned char *seq, int len) { @@ -869,7 +870,7 @@ static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store); #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6e39a0_early_suspend(void) +void s6e39a0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -880,7 +881,7 @@ void s6e39a0_early_suspend(void) return ; } -void s6e39a0_late_resume(void) +void s6e39a0_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -888,6 +889,8 @@ void s6e39a0_late_resume(void) s6e39a0_power(lcd, FB_BLANK_UNBLANK); dev_info(&lcd->ld->dev, "-%s\n", __func__); + lcd->fb_suspended = false; + return ; } #endif @@ -1003,10 +1006,10 @@ static int s6e39a0_probe(struct device *dev) #if 0 #ifdef CONFIG_HAS_EARLYSUSPEND - lcd->early_suspend.suspend = s6e39a0_early_suspend; - lcd->early_suspend.resume = s6e39a0_late_resume; + lcd->early_suspend.suspend = s6e39a0_fb_suspend; + lcd->early_suspend.resume = s6e39a0_fb_resume; lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2; - register_early_suspend(&lcd->early_suspend); + register_fb_suspend(&lcd->early_suspend); #endif #endif @@ -1037,8 +1040,8 @@ static int s6e39a0_probe(struct device *dev) s6e39a0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1); #endif - lcd_early_suspend = s6e39a0_early_suspend; - lcd_late_resume = s6e39a0_late_resume; + lcd_fb_suspend = s6e39a0_fb_suspend; + lcd_fb_resume = s6e39a0_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_s6e63m0.c b/drivers/video/samsung/s3cfb_s6e63m0.c index 95b1501bd1980be81fecd370fbc1e3734870e417..e6acbacc1c4552922d3e7ff969ee0af35839e503 100644 --- a/drivers/video/samsung/s3cfb_s6e63m0.c +++ b/drivers/video/samsung/s3cfb_s6e63m0.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "s6e63m0_gamma_l.h" @@ -98,7 +98,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; @@ -127,8 +128,8 @@ static const unsigned int candela_table[GAMMA_MAX] = { 230, 240, 250, MAX_GAMMA }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int s6e63m0_power(struct lcd_info *lcd, int power); static int s6e63m0_read(struct lcd_info *lcd, const u8 addr, @@ -138,13 +139,13 @@ static int s6e63m0_read(struct lcd_info *lcd, const u8 addr, static void esd_reset_lcd(struct lcd_info *lcd) { dev_info(&lcd->ld->dev, "++%s\n", __func__); - if (lcd_early_suspend) - lcd_early_suspend(); + if (lcd_fb_suspend) + lcd_fb_suspend(); lcd->dsim->ops->suspend(); lcd->dsim->ops->resume(); - if (lcd_late_resume) - lcd_late_resume(); + if (lcd_fb_resume) + lcd_fb_resume(); dev_info(&lcd->ld->dev, "--%s\n", __func__); } @@ -825,7 +826,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6e63m0_early_suspend(void) +void s6e63m0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; set_dsim_lcd_enabled(0); @@ -845,7 +846,7 @@ void s6e63m0_early_suspend(void) return ; } -void s6e63m0_late_resume(void) +void s6e63m0_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -862,6 +863,8 @@ void s6e63m0_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -989,6 +992,7 @@ static int s6e63m0_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -1066,8 +1070,8 @@ static int s6e63m0_probe(struct device *dev) } #endif - lcd_early_suspend = s6e63m0_early_suspend; - lcd_late_resume = s6e63m0_late_resume; + lcd_fb_suspend = s6e63m0_fb_suspend; + lcd_fb_resume = s6e63m0_fb_resume; dev_info(&lcd->ld->dev, "s6e63m0 lcd panel driver has been probed.\n"); diff --git a/drivers/video/samsung/s3cfb_s6e8aa0.c b/drivers/video/samsung/s3cfb_s6e8aa0.c index 52deb818e6852b557f0da0e1fe64b991a7f2b250..5b930c511fa97f043715c238a42dbcae4ec599e2 100644 --- a/drivers/video/samsung/s3cfb_s6e8aa0.c +++ b/drivers/video/samsung/s3cfb_s6e8aa0.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "s6e8aa0_gamma_l.h" @@ -108,7 +108,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; @@ -189,8 +190,8 @@ static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = { }; #endif -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #if defined(GPIO_OLED_DET) static void oled_detection_work(struct work_struct *work) @@ -1280,14 +1281,17 @@ static ssize_t auto_brightness_store(struct device *dev, static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store); -#ifdef CONFIG_HAS_EARLYSUSPEND +#ifdef CONFIG_FB struct lcd_info *g_lcd; -void s6e8ax0_early_suspend(void) +void s6e8ax0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; int err = 0; + if (lcd->fb_suspended) + return; + set_dsim_lcd_enabled(0); dev_info(&lcd->ld->dev, "+%s\n", __func__); @@ -1304,13 +1308,18 @@ void s6e8ax0_early_suspend(void) s6e8ax0_power(lcd, FB_BLANK_POWERDOWN); dev_info(&lcd->ld->dev, "-%s\n", __func__); + lcd->fb_suspended = true; + return ; } -void s6e8ax0_late_resume(void) +void s6e8ax0_fb_resume(void) { struct lcd_info *lcd = g_lcd; + if (!lcd->fb_suspended) + return; + dev_info(&lcd->ld->dev, "+%s\n", __func__); s6e8ax0_power(lcd, FB_BLANK_UNBLANK); #if defined(GPIO_OLED_DET) @@ -1322,6 +1331,8 @@ void s6e8ax0_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -1452,6 +1463,7 @@ static int s6e8ax0_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -1541,8 +1553,8 @@ static int s6e8ax0_probe(struct device *dev) } #endif - lcd_early_suspend = s6e8ax0_early_suspend; - lcd_late_resume = s6e8ax0_late_resume; + lcd_fb_suspend = s6e8ax0_fb_suspend; + lcd_fb_resume = s6e8ax0_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_s6e8aa0a.c b/drivers/video/samsung/s3cfb_s6e8aa0a.c index f07a74343c73eee7e0875bf59fd67d66fde42a82..5318923bbfeac00622633aab6b121d5da7760a7b 100644 --- a/drivers/video/samsung/s3cfb_s6e8aa0a.c +++ b/drivers/video/samsung/s3cfb_s6e8aa0a.c @@ -216,8 +216,8 @@ static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = { static void s3cfb_reinitialize_lcd(void); static int s6e8ax0_read_ddi_status_reg(struct lcd_info *lcd, u8 *buf); #endif -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #ifdef DDI_STATUS_REG_PREVENTESD static void check_ddi_work(struct work_struct *work) { @@ -1405,7 +1405,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6e8ax0_early_suspend(void) +void s6e8ax0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -1435,7 +1435,7 @@ void s6e8ax0_early_suspend(void) return ; } -void s6e8ax0_late_resume(void) +void s6e8ax0_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -1459,13 +1459,13 @@ void s6e8ax0_late_resume(void) #ifdef DDI_STATUS_REG_PREVENTESD static void s3cfb_reinitialize_lcd(void) { - s6e8ax0_early_suspend(); - s5p_dsim_early_suspend(); + s6e8ax0_fb_suspend(); + s5p_dsim_fb_suspend(); msleep(20); - s5p_dsim_late_resume(); + s5p_dsim_fb_resume(); msleep(20); - s6e8ax0_late_resume(); + s6e8ax0_fb_resume(); printk(KERN_INFO "%s, re-initialize LCD - Done\n", __func__); } #endif @@ -1693,8 +1693,8 @@ static int s6e8ax0_probe(struct device *dev) schedule_delayed_work(&lcd->check_ddi, msecs_to_jiffies(20000)); } #endif - lcd_early_suspend = s6e8ax0_early_suspend; - lcd_late_resume = s6e8ax0_late_resume; + lcd_fb_suspend = s6e8ax0_fb_suspend; + lcd_fb_resume = s6e8ax0_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_s6e8ab0.c b/drivers/video/samsung/s3cfb_s6e8ab0.c index 76a98d9035a9b073882ba1bc6d6e003276001630..2bb5cff83259e451dd252a522e35162dc14ecfe7 100644 --- a/drivers/video/samsung/s3cfb_s6e8ab0.c +++ b/drivers/video/samsung/s3cfb_s6e8ab0.c @@ -87,7 +87,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; @@ -105,8 +106,8 @@ struct lcd_info { struct dsim_global *dsim; }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len) { @@ -653,7 +654,7 @@ static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL); #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6e8ax0_early_suspend(void) +void s6e8ax0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -666,7 +667,7 @@ void s6e8ax0_early_suspend(void) return ; } -void s6e8ax0_late_resume(void) +void s6e8ax0_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -676,6 +677,8 @@ void s6e8ax0_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -830,8 +833,8 @@ static int s6e8ax0_probe(struct device *dev) update_brightness(lcd, 1); #endif - lcd_early_suspend = s6e8ax0_early_suspend; - lcd_late_resume = s6e8ax0_late_resume; + lcd_fb_suspend = s6e8ax0_fb_suspend; + lcd_fb_resume = s6e8ax0_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_s6evr01.c b/drivers/video/samsung/s3cfb_s6evr01.c index 7a59cf30913b34fee179550549f7b97f15008920..631b5d58fe86639850b7fd8ad7e70e47517a8ad5 100644 --- a/drivers/video/samsung/s3cfb_s6evr01.c +++ b/drivers/video/samsung/s3cfb_s6evr01.c @@ -29,10 +29,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "s6evr01_param.h" @@ -118,8 +118,8 @@ static unsigned int aid_candela_table[GAMMA_MAX] = { }; #endif -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #if defined(GPIO_ERR_FG) static void err_fg_detection_work(struct work_struct *work) @@ -1042,7 +1042,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND static struct lcd_info *g_lcd; -void s6evr01_early_suspend(void) +void s6evr01_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -1073,7 +1073,7 @@ void s6evr01_early_suspend(void) return ; } -void s6evr01_late_resume(void) +void s6evr01_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -1097,6 +1097,8 @@ void s6evr01_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -1172,6 +1174,7 @@ static int s6evr01_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -1263,8 +1266,8 @@ static int s6evr01_probe(struct device *dev) } #endif - lcd_early_suspend = s6evr01_early_suspend; - lcd_late_resume = s6evr01_late_resume; + lcd_fb_suspend = s6evr01_fb_suspend; + lcd_fb_resume = s6evr01_fb_resume; return 0; diff --git a/drivers/video/samsung/s3cfb_s6evr02.c b/drivers/video/samsung/s3cfb_s6evr02.c index f0e911845a7ee6c6460b265f492879dc6e69bf1e..423c0479437e3b6c3045906a0c1a30f5336e50e3 100644 --- a/drivers/video/samsung/s3cfb_s6evr02.c +++ b/drivers/video/samsung/s3cfb_s6evr02.c @@ -29,10 +29,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" #include "s6evr02_param.h" @@ -76,7 +76,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; unsigned char **gamma_table; unsigned char **elvss_table; @@ -118,8 +119,8 @@ static unsigned int aid_candela_table[GAMMA_MAX] = { }; #endif -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #if defined(GPIO_ERR_FG) static void err_fg_detection_work(struct work_struct *work) @@ -1068,7 +1069,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND static struct lcd_info *g_lcd; -void s6evr02_early_suspend(void) +void s6evr02_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -1099,7 +1100,7 @@ void s6evr02_early_suspend(void) return ; } -void s6evr02_late_resume(void) +void s6evr02_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -1123,6 +1124,8 @@ void s6evr02_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -1198,6 +1201,7 @@ static int s6evr02_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -1289,8 +1293,8 @@ static int s6evr02_probe(struct device *dev) } #endif - lcd_early_suspend = s6evr02_early_suspend; - lcd_late_resume = s6evr02_late_resume; + lcd_fb_suspend = s6evr02_fb_suspend; + lcd_fb_resume = s6evr02_fb_resume; return 0; diff --git a/drivers/video/samsung/s5p-dsim.c b/drivers/video/samsung/s5p-dsim.c index 61cefab7206bf3859ec1d5859234ddc687544ced..30f8c8165d29237636ffcad7d026398e73cb31b9 100644 --- a/drivers/video/samsung/s5p-dsim.c +++ b/drivers/video/samsung/s5p-dsim.c @@ -45,9 +45,9 @@ #include "s5p_dsim_lowlevel.h" #include "s3cfb.h" -#ifdef CONFIG_HAS_WAKELOCK -#include -#include +#ifdef CONFIG_FB +#include +#include #include #endif @@ -793,7 +793,7 @@ static void s5p_dsim_set_clock(struct dsim_global *dsim, } } -static int s5p_dsim_late_resume_init_dsim(struct dsim_global *dsim) +static int s5p_dsim_fb_resume_init_dsim(struct dsim_global *dsim) { unsigned int dsim_base = dsim->reg_base; @@ -1180,8 +1180,8 @@ static int s5p_dsim_fifo_clear(struct dsim_global *dsim) } #endif -#ifdef CONFIG_HAS_EARLYSUSPEND -void s5p_dsim_early_suspend(void) +#ifdef CONFIG_FB +void s5p_dsim_fb_suspend(void) { u32 int_stat = 0; pm_message_t state; @@ -1234,7 +1234,7 @@ void s5p_dsim_early_suspend(void) return; } -void s5p_dsim_late_resume(void) +void s5p_dsim_fb_resume(void) { struct dsim_global *dsim = g_dsim; @@ -1251,7 +1251,7 @@ void s5p_dsim_late_resume(void) dsim->mipi_ddi_pd->lcd_power_on(dsim->dev, 1); usleep_range(25000, 25000); - s5p_dsim_late_resume_init_dsim(dsim); + s5p_dsim_fb_resume_init_dsim(dsim); s5p_dsim_init_link(dsim); usleep_range(10000, 10000); @@ -1424,8 +1424,8 @@ static struct dsim_ops s5p_dsim_ops = { .cmd_write = s5p_dsim_wr_data, .cmd_read = s5p_dsim_rd_data, .cmd_dcs_read = s5p_dsim_dcs_rd_data, - .suspend = s5p_dsim_early_suspend, - .resume = s5p_dsim_late_resume, + .suspend = s5p_dsim_fb_suspend, + .resume = s5p_dsim_fb_resume, }; static int s5p_dsim_probe(struct platform_device *pdev) @@ -1593,11 +1593,11 @@ static int s5p_dsim_probe(struct platform_device *pdev) #if 0 #ifdef CONFIG_HAS_WAKELOCK -#ifdef CONFIG_HAS_EARLYSUSPEND - dsim->early_suspend.suspend = s5p_dsim_early_suspend; - dsim->early_suspend.resume = s5p_dsim_late_resume; +#ifdef CONFIG_FB + dsim->early_suspend.suspend = s5p_dsim_fb_suspend; + dsim->early_suspend.resume = s5p_dsim_fb_resume; dsim->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1; - register_early_suspend(&dsim->early_suspend); + register_fb_suspend(&dsim->early_suspend); #endif #endif #endif @@ -1626,7 +1626,7 @@ static int s5p_dsim_remove(struct platform_device *pdev) static struct platform_driver s5p_dsim_driver = { .probe = s5p_dsim_probe, .remove = s5p_dsim_remove, -#ifndef CONFIG_HAS_EARLYSUSPEND +#ifndef CONFIG_FB .suspend = s5p_dsim_suspend, .resume = s5p_dsim_resume, #endif diff --git a/drivers/video/samsung/s6d6aa1.c b/drivers/video/samsung/s6d6aa1.c index b2b8334b73aee26a5e169d76edcc94d553c38959..b981788c06da29f060a322c527c6b55da11268c9 100644 --- a/drivers/video/samsung/s6d6aa1.c +++ b/drivers/video/samsung/s6d6aa1.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" @@ -53,7 +53,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned int irq; unsigned int connected; @@ -215,20 +216,20 @@ static unsigned char TRANS_BRIGHTNESS[] = { 249, 250, 251, 252, 253, 254, 255, 255, }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #if defined(GPIO_VGH_DET) static void esd_reset_lcd(struct lcd_info *lcd) { dev_info(&lcd->ld->dev, "++%s\n", __func__); - if (lcd_early_suspend) - lcd_early_suspend(); + if (lcd_fb_suspend) + lcd_fb_suspend(); lcd->dsim->ops->suspend(); lcd->dsim->ops->resume(); - if (lcd_late_resume) - lcd_late_resume(); + if (lcd_fb_resume) + lcd_fb_resume(); dev_info(&lcd->ld->dev, "--%s\n", __func__); } @@ -600,7 +601,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6d6aa1_early_suspend(void) +void s6d6aa1_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -623,7 +624,7 @@ void s6d6aa1_early_suspend(void) return ; } -void s6d6aa1_late_resume(void) +void s6d6aa1_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -639,6 +640,8 @@ void s6d6aa1_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -711,8 +714,8 @@ static int s6d6aa1_probe(struct device *dev) } #endif - lcd_early_suspend = s6d6aa1_early_suspend; - lcd_late_resume = s6d6aa1_late_resume; + lcd_fb_suspend = s6d6aa1_fb_suspend; + lcd_fb_resume = s6d6aa1_fb_resume; return 0; diff --git a/drivers/video/samsung/s6d6aa1_gd2.c b/drivers/video/samsung/s6d6aa1_gd2.c index 3db707262bea0e7d1aca4dd4aff810f6bb36c8bb..c45e019cc0bdc8298825c88a0544f2c4302984e9 100644 --- a/drivers/video/samsung/s6d6aa1_gd2.c +++ b/drivers/video/samsung/s6d6aa1_gd2.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" @@ -56,7 +56,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned int irq; unsigned int connected; @@ -197,23 +198,23 @@ static unsigned char TRANS_BRIGHTNESS[] = { struct lcd_info *g_lcd; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); -void s6d6aa1_early_suspend(void); -void s6d6aa1_late_resume(void); +void s6d6aa1_fb_suspend(void); +void s6d6aa1_fb_resume(void); #if defined(GPIO_VGH_DET) static void esd_reset_lcd(struct lcd_info *lcd) { dev_info(&lcd->ld->dev, "++%s\n", __func__); - if (lcd_early_suspend) - lcd_early_suspend(); + if (lcd_fb_suspend) + lcd_fb_suspend(); lcd->dsim->ops->suspend(); lcd->dsim->ops->resume(); - if (lcd_late_resume) - lcd_late_resume(); + if (lcd_fb_resume) + lcd_fb_resume(); dev_info(&lcd->ld->dev, "--%s\n", __func__); } @@ -475,9 +476,9 @@ int s6d6aa1_power_ext(int onoff) lcd->evf_switching = 1; if (onoff) - s6d6aa1_late_resume(); + s6d6aa1_fb_resume(); else - s6d6aa1_early_suspend(); + s6d6aa1_fb_suspend(); lcd->evf_switching = 0; @@ -635,7 +636,7 @@ static ssize_t outdoor_store(struct device *dev, static DEVICE_ATTR(outdoor, 0644, outdoor_show, outdoor_store); #ifdef CONFIG_HAS_EARLYSUSPEND -void s6d6aa1_early_suspend(void) +void s6d6aa1_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -658,7 +659,7 @@ void s6d6aa1_early_suspend(void) return ; } -void s6d6aa1_late_resume(void) +void s6d6aa1_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -674,6 +675,8 @@ void s6d6aa1_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -752,8 +755,8 @@ static int s6d6aa1_probe(struct device *dev) } #endif - lcd_early_suspend = s6d6aa1_early_suspend; - lcd_late_resume = s6d6aa1_late_resume; + lcd_fb_suspend = s6d6aa1_fb_suspend; + lcd_fb_resume = s6d6aa1_fb_resume; return 0; diff --git a/drivers/video/samsung/s6d6aa1_sf2.c b/drivers/video/samsung/s6d6aa1_sf2.c index 7fb5170473f782bda207c39f73ceee95a969db17..0a0007cb05566f2f4de8c66638dc2345d2ddf2f8 100644 --- a/drivers/video/samsung/s6d6aa1_sf2.c +++ b/drivers/video/samsung/s6d6aa1_sf2.c @@ -63,7 +63,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; #ifndef CONFIG_SAMSUNG_PRODUCT_SHIP unsigned char id[LDI_ID_LEN]; @@ -228,20 +229,20 @@ static unsigned char TRANS_BRIGHTNESS[] = { 249, 250, 251, 252, 253, 254, 255, 255, }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); #if defined(GPIO_OLED_DET) static void esd_reset_lcd(struct lcd_info *lcd) { dev_info(&lcd->ld->dev, "++%s\n", __func__); - if (lcd_early_suspend) - lcd_early_suspend(); + if (lcd_fb_suspend) + lcd_fb_suspend(); lcd->dsim->ops->suspend(); lcd->dsim->ops->resume(); - if (lcd_late_resume) - lcd_late_resume(); + if (lcd_fb_resume) + lcd_fb_resume(); dev_info(&lcd->ld->dev, "--%s\n", __func__); } @@ -648,7 +649,7 @@ static void s6d6aa1_read_id(struct lcd_info *lcd, u8 *buf) #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6d6aa1_early_suspend(void) +void s6d6aa1_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -671,7 +672,7 @@ void s6d6aa1_early_suspend(void) return ; } -void s6d6aa1_late_resume(void) +void s6d6aa1_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -694,6 +695,8 @@ Turning OFF/ON the LCD voltages as requested by H/W Team request for factory tes set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -770,8 +773,8 @@ static int s6d6aa1_probe(struct device *dev) } #endif - lcd_early_suspend = s6d6aa1_early_suspend; - lcd_late_resume = s6d6aa1_late_resume; + lcd_fb_suspend = s6d6aa1_fb_suspend; + lcd_fb_resume = s6d6aa1_fb_resume; return 0; diff --git a/drivers/video/samsung/s6dr171.c b/drivers/video/samsung/s6dr171.c index 868c006ab6015a26f1447dfe24eadea29f67bcda..d17d9fa58bbda5baf1cbac33d46322a35c2d6199 100644 --- a/drivers/video/samsung/s6dr171.c +++ b/drivers/video/samsung/s6dr171.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" @@ -66,7 +66,8 @@ struct lcd_info { struct lcd_device *ld; struct backlight_device *bd; struct lcd_platform_data *lcd_pd; - struct early_suspend early_suspend; + struct notifier_block fb_notif; + bool fb_suspended; unsigned char id[LDI_ID_LEN]; @@ -79,8 +80,8 @@ struct lcd_info { struct dsim_global *dsim; }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int s6dr171_write(struct lcd_info *lcd, const unsigned char *seq, int len) { @@ -392,7 +393,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6dr171_early_suspend(void) +void s6dr171_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -405,7 +406,7 @@ void s6dr171_early_suspend(void) return ; } -void s6dr171_late_resume(void) +void s6dr171_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -415,6 +416,8 @@ void s6dr171_late_resume(void) set_dsim_lcd_enabled(1); + lcd->fb_suspended = false; + return ; } #endif @@ -483,6 +486,7 @@ static int s6dr171_probe(struct device *dev) lcd->ldi_enable = 1; lcd->connected = 1; lcd->auto_brightness = 0; + lcd->fb_suspended = false; ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce); if (ret < 0) @@ -513,8 +517,8 @@ static int s6dr171_probe(struct device *dev) /*return -EPERM;*/ } - lcd_early_suspend = s6dr171_early_suspend; - lcd_late_resume = s6dr171_late_resume; + lcd_fb_suspend = s6dr171_fb_suspend; + lcd_fb_resume = s6dr171_fb_resume; return 0; diff --git a/drivers/video/samsung/s6e88a0_mipi_lcd.c b/drivers/video/samsung/s6e88a0_mipi_lcd.c index 76d7e6519ee53d2ec3f03a51a7cbcc7ee59aac54..573a1f715fb85cc371da9506450a851281704120 100644 --- a/drivers/video/samsung/s6e88a0_mipi_lcd.c +++ b/drivers/video/samsung/s6e88a0_mipi_lcd.c @@ -26,10 +26,10 @@ #include #include #include -#ifdef CONFIG_HAS_EARLYSUSPEND -#include +#ifdef CONFIG_FB +#include +#include #endif - #include "s5p-dsim.h" #include "s3cfb.h" @@ -102,8 +102,8 @@ static const unsigned int candela_table[GAMMA_MAX] = { 220, 234, 249, 265, 282, 300, 400 }; -extern void (*lcd_early_suspend)(void); -extern void (*lcd_late_resume)(void); +extern void (*lcd_fb_suspend)(void); +extern void (*lcd_fb_resume)(void); static int _s6e88a0_write(struct lcd_info *lcd, const unsigned char *seq, int len) { @@ -1237,7 +1237,7 @@ static DEVICE_ATTR(parameter, 0444, parameter_show, NULL); #ifdef CONFIG_HAS_EARLYSUSPEND static struct lcd_info *g_lcd; -void s6e88a0_early_suspend(void) +void s6e88a0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -1249,7 +1249,7 @@ void s6e88a0_early_suspend(void) return; } -void s6e88a0_late_resume(void) +void s6e88a0_fb_resume(void) { struct lcd_info *lcd = g_lcd; @@ -1376,8 +1376,8 @@ static int s6e88a0_probe(struct device *dev) update_brightness(lcd, 1); - lcd_early_suspend = s6e88a0_early_suspend; - lcd_late_resume = s6e88a0_late_resume; + lcd_fb_suspend = s6e88a0_fb_suspend; + lcd_fb_resume = s6e88a0_fb_resume; dev_info(&lcd->ld->dev, "%s lcd panel driver has been probed.\n", __FILE__); diff --git a/drivers/video/samsung/s6e8aa1.c b/drivers/video/samsung/s6e8aa1.c index d5cd9b8cc745b760898de20cf66484d742c7a5be..8445c7fb7ae97235eba03b3125f0c9529aa75122 100644 --- a/drivers/video/samsung/s6e8aa1.c +++ b/drivers/video/samsung/s6e8aa1.c @@ -391,7 +391,7 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_ #ifdef CONFIG_HAS_EARLYSUSPEND struct lcd_info *g_lcd; -void s6e8ax0_early_suspend(void) +void s6e8ax0_fb_suspend(void) { struct lcd_info *lcd = g_lcd; @@ -404,7 +404,7 @@ void s6e8ax0_early_suspend(void) return ; } -void s6e8ax0_late_resume(void) +void s6e8ax0_fb_resume(void) { struct lcd_info *lcd = g_lcd; diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 5f8146695b7ff199b3135c89a079b4649d5cf269..d83d62f26ff07201b1aac79a5faf6cae152afb11 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -38,6 +38,8 @@ enum IPV4_DEVCONF_ACCEPT_LOCAL, IPV4_DEVCONF_SRC_VMARK, IPV4_DEVCONF_PROXY_ARP_PVLAN, + IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, + IPV4_DEVCONF_DROP_GRATUITOUS_ARP, __IPV4_DEVCONF_MAX }; diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 84b1447481b58a81d5cc7a098e68ca25e815f56f..ab95c440c13b7dc58cf3981404be83c3e0be1a92 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -170,8 +170,10 @@ struct ipv6_devconf { __s32 mc_forwarding; #endif __s32 disable_ipv6; + __s32 drop_unicast_in_l2_multicast; __s32 accept_dad; __s32 force_tllao; + __s32 drop_unsolicited_na; void *sysctl; }; @@ -213,6 +215,8 @@ enum { DEVCONF_DISABLE_IPV6, DEVCONF_ACCEPT_DAD, DEVCONF_FORCE_TLLAO, + DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, + DEVCONF_DROP_UNSOLICITED_NA, DEVCONF_MAX }; diff --git a/include/linux/wacom_i2c.h b/include/linux/wacom_i2c.h index d68616aa9cf32caa0be6faba4e06e65fb8986338..9054ed0b72bc819211279396a148178d443b048e 100644 --- a/include/linux/wacom_i2c.h +++ b/include/linux/wacom_i2c.h @@ -392,6 +392,8 @@ struct wacom_g5_platform_data { }; #define SHORT_PRESS_TIME 0 +#define SHORT_PRESS_DOUBLED 200 +#define BREAK_TIME 200 #define LONG_PRESS_TIME 1000 #define MIN_GEST_DIST 3000 @@ -470,6 +472,7 @@ struct wacom_i2c { int gesture_start_x; int gesture_start_y; ktime_t gesture_start_time; + ktime_t gesture_old_end_time; }; #endif /* _LINUX_WACOM_I2C_H */ diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index d8f852dbf6600f4dab50893153bebdbc1d927f2a..4bae334b23904f7eeaff16fbd88fa37f40176430 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -847,6 +847,14 @@ static int arp_process(struct sk_buff *skb) if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip)) goto out; + /* + * For some 802.11 wireless deployments (and possibly other networks), + * there will be an ARP proxy and gratuitous ARP frames are attacks + * and thus should not be accepted. + */ + if (IN_DEV_CONF_GET(in_dev, DROP_GRATUITOUS_ARP) && sip == tip) + goto out; + /* * Special case: We must set Frame Relay source Q.922 address */ diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 085d63fbfd2acc1d8eaaedbdce2f83119e1720cf..7f870c47d236c66a90ce4348be95d9d5d2f4335a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1624,6 +1624,8 @@ static struct devinet_sysctl_table { DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"), DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"), DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"), + DEVINET_SYSCTL_RW_ENTRY(DROP_GRATUITOUS_ARP, + "drop_gratuitous_arp"), DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"), @@ -1631,6 +1633,8 @@ static struct devinet_sysctl_table { "force_igmp_version"), DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, "promote_secondaries"), + DEVINET_SYSCTL_FLUSHING_ENTRY(DROP_UNICAST_IN_L2_MULTICAST, + "drop_unicast_in_l2_multicast"), }, }; diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index c8f48efc5fd3d778831458b1b72ccf07ca794594..0d3fdfc007a2e1f8650e0094fd620912885b0546 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -358,9 +358,34 @@ static int ip_rcv_finish(struct sk_buff *skb) if (rt->rt_type == RTN_MULTICAST) { IP_UPD_PO_STATS_BH(dev_net(rt->dst.dev), IPSTATS_MIB_INMCAST, skb->len); - } else if (rt->rt_type == RTN_BROADCAST) + } else if (rt->rt_type == RTN_BROADCAST) { IP_UPD_PO_STATS_BH(dev_net(rt->dst.dev), IPSTATS_MIB_INBCAST, skb->len); + } else { + struct in_device *in_dev = __in_dev_get_rcu(skb->dev); + + /* RFC 1122 3.3.6: + * + * When a host sends a datagram to a link-layer broadcast + * address, the IP destination address MUST be a legal IP + * broadcast or IP multicast address. + * + * A host SHOULD silently discard a datagram that is received + * via a link-layer broadcast (see Section 2.4) but does not + * specify an IP multicast or broadcast destination address. + * + * This doesn't explicitly say L2 *broadcast*, but broadcast is + * in a way a form of multicast and the most common use case for + * this is 802.11 protecting against cross-station spoofing (the + * so-called "hole-196" attack) so do it for both. + */ + if (in_dev && + IN_DEV_ORCONF(in_dev, DROP_UNICAST_IN_L2_MULTICAST) && + (skb->pkt_type == PACKET_BROADCAST || + skb->pkt_type == PACKET_MULTICAST)) + goto drop; + } + return dst_input(skb); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 5574fc23b6b41c8ef4c5c98252173506c4ccaa6f..1fb46ee45f2fc2fd6981f870d001157a7aaabc48 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3883,6 +3883,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_DISABLE_IPV6] = cnf->disable_ipv6; array[DEVCONF_ACCEPT_DAD] = cnf->accept_dad; array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; + array[DEVCONF_DROP_UNICAST_IN_L2_MULTICAST] = cnf->drop_unicast_in_l2_multicast; + array[DEVCONF_DROP_UNSOLICITED_NA] = cnf->drop_unsolicited_na; } static inline size_t inet6_ifla6_size(void) @@ -4551,6 +4553,20 @@ static struct addrconf_sysctl_table .mode = 0644, .proc_handler = proc_dointvec }, + { + .procname = "drop_unicast_in_l2_multicast", + .data = &ipv6_devconf.drop_unicast_in_l2_multicast, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "drop_unsolicited_na", + .data = &ipv6_devconf.drop_unsolicited_na, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { /* sentinel */ } diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index e2a08ae54ca9bcd880ba86c02233e2649423ef37..bd734502192c68de7fff2615456c6224ff099555 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -111,6 +111,16 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt ipv6_addr_loopback(&hdr->daddr)) goto err; + /* If enabled, drop unicast packets that were encapsulated in link-layer + * multicast or broadcast to protected against the so-called "hole-196" + * attack in 802.11 wireless. + */ + if (!ipv6_addr_is_multicast(&hdr->daddr) && + (skb->pkt_type == PACKET_BROADCAST || + skb->pkt_type == PACKET_MULTICAST) && + idev->cnf.drop_unicast_in_l2_multicast) + goto err; + skb->transport_header = skb->network_header + sizeof(*hdr); IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index d8878ed36120fb025b3422fa211a59c4c5d35b16..66c8e6d1e62b6f22b6422d4edb2a589f99ead366 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -932,6 +932,7 @@ static void ndisc_recv_na(struct sk_buff *skb) offsetof(struct nd_msg, opt)); struct ndisc_options ndopts; struct net_device *dev = skb->dev; + struct inet6_dev *idev = __in6_dev_get(dev); struct inet6_ifaddr *ifp; struct neighbour *neigh; @@ -954,6 +955,14 @@ static void ndisc_recv_na(struct sk_buff *skb) return; } + /* For some 802.11 wireless deployments (and possibly other networks), + * there will be a NA proxy and unsolicitd packets are attacks + * and thus should not be accepted. + */ + if (!msg->icmph.icmp6_solicited && idev && + idev->cnf.drop_unsolicited_na) + return; + if (!ndisc_parse_options(msg->opt, ndoptlen, &ndopts)) { ND_PRINTK2(KERN_WARNING "ICMPv6 NS: invalid ND option\n");