Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56eac98b authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'exynos-drm-fixes-for-v4.14-rc1' of...

Merge tag 'exynos-drm-fixes-for-v4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes

- fix suspend/resume issues.
- fix memory corruption detected by kasan.
- fix build error on x86.

* tag 'exynos-drm-fixes-for-v4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
  drm/exynos/hdmi: Fix unsafe list iteration
  drm: exynos: include linux/irq.h
  drm/exynos: Fix suspend/resume support
  drm/exynos: Fix locking in the suspend/resume paths
parents c106c7a5 04fc52fb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
#include <linux/mfd/syscon.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
+12 −24
Original line number Diff line number Diff line
@@ -168,23 +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_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);

	return 0;
}
@@ -192,22 +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_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_atomic_helper_resume(drm_dev, private->suspend_state);
	exynos_drm_fbdev_resume(drm_dev);
	drm_kms_helper_poll_enable(drm_dev);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -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;
+20 −0
Original line number Diff line number Diff line
@@ -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();
}
+10 −0
Original line number Diff line number Diff line
@@ -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