static void sh_mobile_fb_reconfig(struct fb_info *info) { struct sh_mobile_lcdc_chan *ch = info->par; struct fb_videomode mode1, mode2; struct fb_event event; int evnt = FB_EVENT_MODE_CHANGE_ALL; if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) /* More framebuffer users are active */ return; fb_var_to_videomode(&mode1, &ch->display_var); fb_var_to_videomode(&mode2, &info->var); if (fb_mode_is_equal(&mode1, &mode2)) return; /* Display has been re-plugged, framebuffer is free now, reconfigure */ if (fb_set_var(info, &ch->display_var) < 0) /* Couldn't reconfigure, hopefully, can continue as before */ return; info->fix.line_length = mode1.xres * (ch->cfg.bpp / 8); /* * fb_set_var() calls the notifier change internally, only if * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a * user event, we have to call the chain ourselves. */ event.info = info; event.data = &mode1; fb_notifier_call_chain(evnt, &event); }
static void start_vsync_boost(struct tb_private_info *info) { int ret = 0; #ifdef CONFIG_FB_DYNAMIC_FREQ do { struct fb_event event; event.data = info; ret = fb_notifier_call_chain(FB_EVENT_MODE_PAN, &event); } while(0); #endif }
static int s5p_dp_notify(struct notifier_block *nb, unsigned long action, void *data) { struct s5p_dp_device *dp; int ret = 0; ktime_t start; #if defined(CONFIG_V1A) || defined(CONFIG_V2A) || defined(CONFIG_CHAGALL) struct fb_event event; #endif dp = container_of(nb, struct s5p_dp_device, notifier); switch (action) { case FB_EVENT_PSR_ENTER: #if defined(CONFIG_V1A) || defined(CONFIG_V2A) || defined(CONFIG_CHAGALL) fb_notifier_call_chain(FB_EVENT_PSR_WACOM_CHECK, &event); #endif dev_dbg(dp->dev, "FB_EVENT_PSR_ENTER occurs!\n"); start = ktime_get(); ret = s5p_dp_psr_enter(dp); dev_info(dp->dev,"FB_EVENT_PSR_ENTER time = %lld us\n", ktime_us_delta(ktime_get(), start)); break; case FB_EVENT_PSR_PRE_ENTRY: dev_dbg(dp->dev, "FB_EVENT_PRE_ENTRY occurs!\n"); ret = s5p_dp_psr_pre_entry(dp); break; case FB_EVENT_PSR_EXIT: dev_dbg(dp->dev, "FB_EVENT_PSR_EXIT occurs!\n"); dp->psr_exit_state = PSR_PRE_EXIT; start = ktime_get(); ret = s5p_dp_psr_exit(dp); dev_info(dp->dev,"FB_EVENT_PSR_EXIT time = %lld us\n", ktime_us_delta(ktime_get(), start)); break; } return ret; }
static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) { int ret; int i; struct vga_switcheroo_client *active = NULL; for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { if (vgasr_priv.clients[i].active == true) { active = &vgasr_priv.clients[i]; break; } } if (!active) return 0; active->active = false; if (new_client->fb_info) { struct fb_event event; event.info = new_client->fb_info; fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); } ret = vgasr_priv.handler->switchto(new_client->id); if (ret) return ret; if (new_client->reprobe) new_client->reprobe(new_client->pdev); if (active->pwr_state == VGA_SWITCHEROO_ON) vga_switchoff(active); new_client->active = true; return 0; }
static int s5p_dp_psr_enter(struct s5p_dp_device *dp) { struct platform_device *pdev; struct s5p_dp_platdata *pdata; int timeout_loop = 0; struct fb_event event; int ret = 0; u8 data; pdev = to_platform_device(dp->dev); pdata = pdev->dev.platform_data; mutex_lock(&dp->lock); dev_dbg(dp->dev, "%s +\n", __func__); if (dp->psr_enter_state == PSR_ENTER_DONE) { dev_info(dp->dev, "%s: Already edP PSR_ENTER state\n", __func__); goto err_exit; } if (dp->psr_exit_state == PSR_PRE_EXIT) { dev_info(dp->dev, "%s: edP does not need to PSR_ENTER\n", __func__); goto err_exit; } dp->psr_enter_state = PSR_PRE_ENTER; s5p_dp_enable_psr(dp); for (;;) { timeout_loop++; if (s5p_dp_get_psr_status(dp) == PSR_STATUS_ACTIVE) break; if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { dev_err(dp->dev, "DP: Timeout of PSR active\n"); ret = -ETIMEDOUT; dp->psr_enter_state = PSR_NONE; dp->psr_error_count++; goto err_exit; } mdelay(1); } mdelay(2); dev_dbg(dp->dev, "PSR ENTER DP timeout_loop: %d\n", timeout_loop); s5p_dp_read_byte_from_dpcd(dp, DPCD_ADDR_SINK_PSR_STATUS, &data); if (data == 0) dev_info(dp->dev, "%s: SINK_PSR_STATUS = 0x%02X\n", __func__, data); s5p_dp_set_analog_power_down(dp, ANALOG_TOTAL, 1); clk_disable(dp->clock); fb_notifier_call_chain(FB_EVENT_PSR_DONE, &event); dp->psr_enter_state = PSR_ENTER_DONE; err_exit: dev_dbg(dp->dev, "%s -\n", __func__); mutex_unlock(&dp->lock); return ret; }
static void vigs_crtc_dpms(struct drm_crtc *crtc, int mode) { struct vigs_crtc *vigs_crtc = crtc_to_vigs_crtc(crtc); struct vigs_device *vigs_dev = crtc->dev->dev_private; int blank, i; struct fb_event event; DRM_DEBUG_KMS("enter: fb_blank = %d, mode = %d\n", vigs_crtc->in_fb_blank, mode); if (vigs_crtc->in_fb_blank) { return; } switch (mode) { case DRM_MODE_DPMS_ON: blank = FB_BLANK_UNBLANK; break; case DRM_MODE_DPMS_STANDBY: blank = FB_BLANK_NORMAL; break; case DRM_MODE_DPMS_SUSPEND: blank = FB_BLANK_VSYNC_SUSPEND; break; case DRM_MODE_DPMS_OFF: blank = FB_BLANK_POWERDOWN; break; default: DRM_ERROR("unspecified mode %d\n", mode); return; } event.info = vigs_dev->fbdev->base.fbdev; event.data = ␣ /* * We can't just 'console_lock' here, since * this may result in deadlock: * fb func: * console_lock(); * mutex_lock(&dev->mode_config.mutex); * DRM func: * mutex_lock(&dev->mode_config.mutex); * console_lock(); * * So we just try to acquire it for 5 times with a delay * and then just skip. * * This code is here only because pm is currently done via * backlight which is bad, we need to make proper pm via * kernel support. */ for (i = 0; i < 5; ++i) { if (console_trylock()) { fb_notifier_call_chain(FB_EVENT_BLANK, &event); console_unlock(); return; } msleep(100); DRM_ERROR("unable to lock console, trying again\n"); } DRM_ERROR("unable to lock console, skipping fb call chain\n"); }