drm/exynos: Fix suspend/resume support
Commit7d902c05b4
("drm: Nuke drm_atomic_helper_connector_dpms") removed drm_atomic_helper_connector_dpms() helper saying that it was a dead code. It was however indirectly used by Exynos DRM driver for implementing suspend/resume support. To fix this regression (after that patch Exynos DRM suspend/resume functions became no-ops and hardware fails to suspend), this patch rewrites them with drm_atomic_helper_suspend/resume() helpers. Fixes:7d902c05b4
("drm: Nuke drm_atomic_helper_connector_dpms") Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Acked-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
parent
5baf6bb0fd
commit
6e8edf8a7d
|
@ -168,25 +168,19 @@ static struct drm_driver exynos_drm_driver = {
|
|||
static int exynos_drm_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||
|
||||
if (pm_runtime_suspended(dev) || !drm_dev)
|
||||
return 0;
|
||||
|
||||
drm_modeset_lock_all(drm_dev);
|
||||
drm_connector_list_iter_begin(drm_dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
int old_dpms = connector->dpms;
|
||||
|
||||
if (connector->funcs->dpms)
|
||||
connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
|
||||
/* Set the old mode back to the connector for resume */
|
||||
connector->dpms = old_dpms;
|
||||
drm_kms_helper_poll_disable(drm_dev);
|
||||
exynos_drm_fbdev_suspend(drm_dev);
|
||||
private->suspend_state = drm_atomic_helper_suspend(drm_dev);
|
||||
if (IS_ERR(private->suspend_state)) {
|
||||
exynos_drm_fbdev_resume(drm_dev);
|
||||
drm_kms_helper_poll_enable(drm_dev);
|
||||
return PTR_ERR(private->suspend_state);
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
drm_modeset_unlock_all(drm_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -194,24 +188,14 @@ static int exynos_drm_suspend(struct device *dev)
|
|||
static int exynos_drm_resume(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||
|
||||
if (pm_runtime_suspended(dev) || !drm_dev)
|
||||
return 0;
|
||||
|
||||
drm_modeset_lock_all(drm_dev);
|
||||
drm_connector_list_iter_begin(drm_dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
if (connector->funcs->dpms) {
|
||||
int dpms = connector->dpms;
|
||||
|
||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||
connector->funcs->dpms(connector, dpms);
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_end(&conn_iter);
|
||||
drm_modeset_unlock_all(drm_dev);
|
||||
drm_atomic_helper_resume(drm_dev, private->suspend_state);
|
||||
exynos_drm_fbdev_resume(drm_dev);
|
||||
drm_kms_helper_poll_enable(drm_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -202,6 +202,7 @@ struct drm_exynos_file_private {
|
|||
*/
|
||||
struct exynos_drm_private {
|
||||
struct drm_fb_helper *fb_helper;
|
||||
struct drm_atomic_state *suspend_state;
|
||||
|
||||
struct device *dma_dev;
|
||||
void *mapping;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/exynos_drm.h>
|
||||
|
||||
#include <linux/console.h>
|
||||
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_fb.h"
|
||||
#include "exynos_drm_fbdev.h"
|
||||
|
@ -285,3 +287,21 @@ void exynos_drm_output_poll_changed(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_hotplug_event(fb_helper);
|
||||
}
|
||||
|
||||
void exynos_drm_fbdev_suspend(struct drm_device *dev)
|
||||
{
|
||||
struct exynos_drm_private *private = dev->dev_private;
|
||||
|
||||
console_lock();
|
||||
drm_fb_helper_set_suspend(private->fb_helper, 1);
|
||||
console_unlock();
|
||||
}
|
||||
|
||||
void exynos_drm_fbdev_resume(struct drm_device *dev)
|
||||
{
|
||||
struct exynos_drm_private *private = dev->dev_private;
|
||||
|
||||
console_lock();
|
||||
drm_fb_helper_set_suspend(private->fb_helper, 0);
|
||||
console_unlock();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ int exynos_drm_fbdev_init(struct drm_device *dev);
|
|||
void exynos_drm_fbdev_fini(struct drm_device *dev);
|
||||
void exynos_drm_fbdev_restore_mode(struct drm_device *dev);
|
||||
void exynos_drm_output_poll_changed(struct drm_device *dev);
|
||||
void exynos_drm_fbdev_suspend(struct drm_device *drm);
|
||||
void exynos_drm_fbdev_resume(struct drm_device *drm);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -39,6 +41,14 @@ static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
|
|||
|
||||
#define exynos_drm_output_poll_changed (NULL)
|
||||
|
||||
static inline void exynos_drm_fbdev_suspend(struct drm_device *drm)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void exynos_drm_fbdev_resume(struct drm_device *drm)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue