Commit 5a587383 authored by Tomeu Vizoso's avatar Tomeu Vizoso Committed by Daniel Vetter

drm/rockchip: Use atomic PM helpers

This driver was still using the old legacy helpers and that caused a few
NULL dereferences when trying to call empty callbacks.
Signed-off-by: default avatarTomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Caesar Wang <wxt@rock-chips.com>
Cc: Douglas Anderson <dianders@chromium.org>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Yakir Yang <ykk@rock-chips.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1465224813-7359-1-git-send-email-tomeu.vizoso@collabora.com
parent 7442148e
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_graph.h> #include <linux/of_graph.h>
#include <linux/component.h> #include <linux/component.h>
#include <linux/console.h>
#include "rockchip_drm_drv.h" #include "rockchip_drm_drv.h"
#include "rockchip_drm_fb.h" #include "rockchip_drm_fb.h"
...@@ -312,25 +313,38 @@ static struct drm_driver rockchip_drm_driver = { ...@@ -312,25 +313,38 @@ static struct drm_driver rockchip_drm_driver = {
}; };
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int rockchip_drm_sys_suspend(struct device *dev) void rockchip_drm_fb_suspend(struct drm_device *drm)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct rockchip_drm_private *priv = drm->dev_private;
struct drm_connector *connector;
if (!drm) console_lock();
return 0; drm_fb_helper_set_suspend(&priv->fbdev_helper, 1);
console_unlock();
}
drm_modeset_lock_all(drm); void rockchip_drm_fb_resume(struct drm_device *drm)
list_for_each_entry(connector, &drm->mode_config.connector_list, head) { {
int old_dpms = connector->dpms; struct rockchip_drm_private *priv = drm->dev_private;
if (connector->funcs->dpms) console_lock();
connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); drm_fb_helper_set_suspend(&priv->fbdev_helper, 0);
console_unlock();
}
/* Set the old mode back to the connector for resume */ static int rockchip_drm_sys_suspend(struct device *dev)
connector->dpms = old_dpms; {
struct drm_device *drm = dev_get_drvdata(dev);
struct rockchip_drm_private *priv = drm->dev_private;
drm_kms_helper_poll_disable(drm);
rockchip_drm_fb_suspend(drm);
priv->state = drm_atomic_helper_suspend(drm);
if (IS_ERR(priv->state)) {
rockchip_drm_fb_resume(drm);
drm_kms_helper_poll_enable(drm);
return PTR_ERR(priv->state);
} }
drm_modeset_unlock_all(drm);
return 0; return 0;
} }
...@@ -338,47 +352,11 @@ static int rockchip_drm_sys_suspend(struct device *dev) ...@@ -338,47 +352,11 @@ static int rockchip_drm_sys_suspend(struct device *dev)
static int rockchip_drm_sys_resume(struct device *dev) static int rockchip_drm_sys_resume(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct drm_device *drm = dev_get_drvdata(dev);
struct drm_connector *connector; struct rockchip_drm_private *priv = drm->dev_private;
enum drm_connector_status status;
bool changed = false;
if (!drm)
return 0;
drm_modeset_lock_all(drm);
list_for_each_entry(connector, &drm->mode_config.connector_list, head) {
int desired_mode = connector->dpms;
/*
* at suspend time, we save dpms to connector->dpms,
* restore the old_dpms, and at current time, the connector
* dpms status must be DRM_MODE_DPMS_OFF.
*/
connector->dpms = DRM_MODE_DPMS_OFF;
/*
* If the connector has been disconnected during suspend,
* disconnect it from the encoder and leave it off. We'll notify
* userspace at the end.
*/
if (desired_mode == DRM_MODE_DPMS_ON) {
status = connector->funcs->detect(connector, true);
if (status == connector_status_disconnected) {
connector->encoder = NULL;
connector->status = status;
changed = true;
continue;
}
}
if (connector->funcs->dpms)
connector->funcs->dpms(connector, desired_mode);
}
drm_modeset_unlock_all(drm);
drm_helper_resume_force_mode(drm);
if (changed) drm_atomic_helper_resume(drm, priv->state);
drm_kms_helper_hotplug_event(drm); rockchip_drm_fb_resume(drm);
drm_kms_helper_poll_enable(drm);
return 0; return 0;
} }
......
...@@ -60,6 +60,7 @@ struct rockchip_drm_private { ...@@ -60,6 +60,7 @@ struct rockchip_drm_private {
struct drm_fb_helper fbdev_helper; struct drm_fb_helper fbdev_helper;
struct drm_gem_object *fbdev_bo; struct drm_gem_object *fbdev_bo;
const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC]; const struct rockchip_crtc_funcs *crtc_funcs[ROCKCHIP_MAX_CRTC];
struct drm_atomic_state *state;
}; };
int rockchip_register_crtc_funcs(struct drm_crtc *crtc, int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment