From patchwork Thu Jan 30 21:19:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 3559391 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CA515C02DC for ; Thu, 30 Jan 2014 21:22:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2573420181 for ; Thu, 30 Jan 2014 21:22:35 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 9165020173 for ; Thu, 30 Jan 2014 21:22:33 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 725F346AE9 for ; Thu, 30 Jan 2014 13:22:33 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qc0-f177.google.com (mail-qc0-f177.google.com [209.85.216.177]) by gabe.freedesktop.org (Postfix) with ESMTP id A705646424 for ; Thu, 30 Jan 2014 13:20:36 -0800 (PST) Received: by mail-qc0-f177.google.com with SMTP id i8so5794562qcq.36 for ; Thu, 30 Jan 2014 13:20:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wPCpYNy03QzCVCjld8IsodUSE0f1paKHQwPJusIX8iw=; b=lRwOnXwQgyI7KdUJV+qH+5ksnOzOZYbfdE/90mTOBSkpXqADUD6RND0bFkL5L8TVBG Dupu3H1GrxsVMV3kThPVcxX37BfX4wTsnBKqOr4bHPynQqZRXZHaVjdF42ej+gYzeCtw kGHEPh6nQ8YI7cO5ZXTgZf3AaVQnLGEUxVJY4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wPCpYNy03QzCVCjld8IsodUSE0f1paKHQwPJusIX8iw=; b=lKMRisp6SHKJPy07lWsN7Tb712R15ZiEIuNt5+nCS1PEmeXTe1gBPOJF8lIx55z7XD UWV0pvASZkNz0ndka833JCdz7DipV+jDeT1Q0jr8FeizHlMzTfunlpPqsmhwi8gLrLnE ZQf5vmxIifrg7vLcYX0kjd9THZDgPbu5Q07iL00PZo7c/9IoWzeGsEwuqppFN0hx6IhJ TGDeer8zjQ7jyKt9N58Zok49dEBwfyaV707qGj0Lfg3JfkO/9VKEAYXIlIIarsYAcSSk H6frfUvD+hPf6my1PU/XXK0BU7aQXpLjrJSiQRO6aZeRSyugPz7iQj4cPw4SmtvN0WYR WdjQ== X-Gm-Message-State: ALoCoQkJ25aV/xjwF9KIm85Y2gd84qGfhGufhhkHOL7Dg/QauIVrw3qCdRPqADzh4r74qVLEz3Jo X-Received: by 10.224.44.9 with SMTP id y9mr25811762qae.45.1391116836131; Thu, 30 Jan 2014 13:20:36 -0800 (PST) Received: from seanpaul-glaptop.roam.corp.google.com (cpe-173-095-180-236.nc.res.rr.com. [173.95.180.236]) by mx.google.com with ESMTPSA id r13sm20673608qan.7.2014.01.30.13.20.34 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 30 Jan 2014 13:20:34 -0800 (PST) From: Sean Paul To: dri-devel@lists.freedesktop.org, inki.dae@samsung.com Subject: [PATCH v4 28/34] drm/exynos: Consolidate suspend/resume in drm_drv Date: Thu, 30 Jan 2014 16:19:27 -0500 Message-Id: <1391116773-28471-29-git-send-email-seanpaul@chromium.org> X-Mailer: git-send-email 1.8.5.1 In-Reply-To: <1391116773-28471-1-git-send-email-seanpaul@chromium.org> References: <1391116773-28471-1-git-send-email-seanpaul@chromium.org> Cc: marcheu@chromium.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch removes all of the suspend/resume logic from the individual drivers and consolidates it in drm_drv. This consolidation reduces the number of functions which enable/disable the hardware to just one -- the dpms callback. This ensures that we always power up/down in a consistent manner. Signed-off-by: Sean Paul --- Changes in v2: - Added to the patchset Changes in v3: - Made appropriate changes to vidi as well (removed pm_ops) Changes in v4: - Added pm_runtime_get/put back into the dpms handlers for hdmi drivers/gpu/drm/exynos/exynos_drm_drv.c | 97 +++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_fimd.c | 86 +++------------------- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 119 +++++++++++++------------------ drivers/gpu/drm/exynos/exynos_hdmi.c | 88 +++-------------------- drivers/gpu/drm/exynos/exynos_mixer.c | 68 ++---------------- 5 files changed, 170 insertions(+), 288 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 87ac369..c8869de 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -11,6 +11,7 @@ * option) any later version. */ +#include #include #include @@ -53,6 +54,7 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) return -ENOMEM; INIT_LIST_HEAD(&private->pageflip_event_list); + dev_set_drvdata(dev->dev, dev); dev->dev_private = (void *)private; /* @@ -163,6 +165,41 @@ static const struct file_operations exynos_drm_gem_fops = { .mmap = exynos_drm_gem_mmap_buffer, }; +static int exynos_drm_suspend(struct drm_device *dev, pm_message_t state) +{ + struct drm_connector *connector; + + drm_modeset_lock_all(dev); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + 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_modeset_unlock_all(dev); + + return 0; +} + +static int exynos_drm_resume(struct drm_device *dev) +{ + struct drm_connector *connector; + + drm_modeset_lock_all(dev); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->funcs->dpms) + connector->funcs->dpms(connector, connector->dpms); + } + + drm_helper_resume_force_mode(dev); + drm_modeset_unlock_all(dev); + + return 0; +} + static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) { struct drm_exynos_file_private *file_priv; @@ -296,6 +333,8 @@ static struct drm_driver exynos_drm_driver = { DRIVER_GEM | DRIVER_PRIME, .load = exynos_drm_load, .unload = exynos_drm_unload, + .suspend = exynos_drm_suspend, + .resume = exynos_drm_resume, .open = exynos_drm_open, .preclose = exynos_drm_preclose, .lastclose = exynos_drm_lastclose, @@ -330,6 +369,9 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) if (ret) return ret; + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + return drm_platform_init(&exynos_drm_driver, pdev); } @@ -340,12 +382,67 @@ static int exynos_drm_platform_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int exynos_drm_sys_suspend(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + pm_message_t message; + + if (pm_runtime_suspended(dev)) + return 0; + + message.event = PM_EVENT_SUSPEND; + return exynos_drm_suspend(drm_dev, message); +} + +static int exynos_drm_sys_resume(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + + if (pm_runtime_suspended(dev)) + return 0; + + return exynos_drm_resume(drm_dev); +} +#endif + +#ifdef CONFIG_PM_RUNTIME +static int exynos_drm_runtime_suspend(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + pm_message_t message; + + if (pm_runtime_suspended(dev)) + return 0; + + message.event = PM_EVENT_SUSPEND; + return exynos_drm_suspend(drm_dev, message); +} + +static int exynos_drm_runtime_resume(struct device *dev) +{ + struct drm_device *drm_dev = dev_get_drvdata(dev); + + if (!pm_runtime_suspended(dev)) + return 0; + + return exynos_drm_resume(drm_dev); +} +#endif + +static const struct dev_pm_ops exynos_drm_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(exynos_drm_sys_suspend, exynos_drm_sys_resume) + SET_RUNTIME_PM_OPS(exynos_drm_runtime_suspend, + exynos_drm_runtime_resume, NULL) +}; + static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, .driver = { .owner = THIS_MODULE, .name = "exynos-drm", + .pm = &exynos_drm_pm_ops, }, }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 1efdcac..f78fbf4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -732,6 +732,8 @@ static int fimd_poweron(struct exynos_drm_manager *mgr) ctx->suspended = false; + pm_runtime_get_sync(ctx->dev); + ret = clk_prepare_enable(ctx->bus_clk); if (ret < 0) { DRM_ERROR("Failed to prepare_enable the bus clk [%d]\n", ret); @@ -785,32 +787,24 @@ static int fimd_poweroff(struct exynos_drm_manager *mgr) clk_disable_unprepare(ctx->lcd_clk); clk_disable_unprepare(ctx->bus_clk); + pm_runtime_put_sync(ctx->dev); + ctx->suspended = true; return 0; } static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) { - struct fimd_context *ctx = mgr->ctx; - - DRM_DEBUG_KMS("%d\n", mode); + DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode); switch (mode) { case DRM_MODE_DPMS_ON: - /* - * enable fimd hardware only if suspended status. - * - * P.S. fimd_dpms function would be called at booting time so - * clk_enable could be called double time. - */ - if (ctx->suspended) - pm_runtime_get_sync(ctx->dev); + fimd_poweron(mgr); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (!ctx->suspended) - pm_runtime_put_sync(ctx->dev); + fimd_poweroff(mgr); break; default: DRM_DEBUG_KMS("unspecified mode %d\n", mode); @@ -929,7 +923,6 @@ static int fimd_probe(struct platform_device *pdev) exynos_drm_manager_register(&fimd_manager); pm_runtime_enable(dev); - pm_runtime_get_sync(dev); for (win = 0; win < WINDOWS_NR; win++) fimd_clear_win(ctx, win); @@ -939,84 +932,23 @@ static int fimd_probe(struct platform_device *pdev) static int fimd_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; struct exynos_drm_manager *mgr = platform_get_drvdata(pdev); - struct fimd_context *ctx = mgr->ctx; exynos_drm_manager_unregister(&fimd_manager); - if (ctx->suspended) - goto out; - - pm_runtime_set_suspended(dev); - pm_runtime_put_sync(dev); + fimd_dpms(mgr, DRM_MODE_DPMS_OFF); -out: - pm_runtime_disable(dev); - - return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int fimd_suspend(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_fimd_manager(dev); - - /* - * do not use pm_runtime_suspend(). if pm_runtime_suspend() is - * called here, an error would be returned by that interface - * because the usage_count of pm runtime is more than 1. - */ - if (!pm_runtime_suspended(dev)) - return fimd_poweroff(mgr); + pm_runtime_disable(&pdev->dev); return 0; } -static int fimd_resume(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_fimd_manager(dev); - - /* - * if entered to sleep when lcd panel was on, the usage_count - * of pm runtime would still be 1 so in this case, fimd driver - * should be on directly not drawing on pm runtime interface. - */ - if (pm_runtime_suspended(dev)) - return 0; - - return fimd_poweron(mgr); -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int fimd_runtime_suspend(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_fimd_manager(dev); - - return fimd_poweroff(mgr); -} - -static int fimd_runtime_resume(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_fimd_manager(dev); - - return fimd_poweron(mgr); -} -#endif - -static const struct dev_pm_ops fimd_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume) - SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) -}; - struct platform_driver fimd_driver = { .probe = fimd_probe, .remove = fimd_remove, .driver = { .name = "exynos4-fb", .owner = THIS_MODULE, - .pm = &fimd_pm_ops, .of_match_table = fimd_driver_dt_match, }, }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index f6f4438..5d0b5cd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -140,31 +140,6 @@ static struct exynos_drm_display vidi_display = { .ops = &vidi_display_ops, }; -static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) -{ - struct vidi_context *ctx = mgr->ctx; - - DRM_DEBUG_KMS("%d\n", mode); - - mutex_lock(&ctx->lock); - - switch (mode) { - case DRM_MODE_DPMS_ON: - /* TODO. */ - break; - case DRM_MODE_DPMS_STANDBY: - case DRM_MODE_DPMS_SUSPEND: - case DRM_MODE_DPMS_OFF: - /* TODO. */ - break; - default: - DRM_DEBUG_KMS("unspecified mode %d\n", mode); - break; - } - - mutex_unlock(&ctx->lock); -} - static void vidi_apply(struct exynos_drm_manager *mgr) { struct vidi_context *ctx = mgr->ctx; @@ -319,6 +294,55 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) /* TODO. */ } +static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) +{ + struct vidi_context *ctx = mgr->ctx; + + DRM_DEBUG_KMS("%s\n", __FILE__); + + if (enable != false && enable != true) + return -EINVAL; + + if (enable) { + ctx->suspended = false; + + /* if vblank was enabled status, enable it again. */ + if (test_and_clear_bit(0, &ctx->irq_flags)) + vidi_enable_vblank(mgr); + + vidi_apply(mgr); + } else { + ctx->suspended = true; + } + + return 0; +} + +static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) +{ + struct vidi_context *ctx = mgr->ctx; + + DRM_DEBUG_KMS("%d\n", mode); + + mutex_lock(&ctx->lock); + + switch (mode) { + case DRM_MODE_DPMS_ON: + vidi_power_on(mgr, true); + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + vidi_power_on(mgr, false); + break; + default: + DRM_DEBUG_KMS("unspecified mode %d\n", mode); + break; + } + + mutex_unlock(&ctx->lock); +} + static int vidi_mgr_initialize(struct exynos_drm_manager *mgr, struct drm_device *drm_dev, int pipe) { @@ -390,30 +414,6 @@ static void vidi_fake_vblank_handler(struct work_struct *work) exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe); } -static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) -{ - struct vidi_context *ctx = mgr->ctx; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (enable != false && enable != true) - return -EINVAL; - - if (enable) { - ctx->suspended = false; - - /* if vblank was enabled status, enable it again. */ - if (test_and_clear_bit(0, &ctx->irq_flags)) - vidi_enable_vblank(mgr); - - vidi_apply(mgr); - } else { - ctx->suspended = true; - } - - return 0; -} - static int vidi_show_connection(struct device *dev, struct device_attribute *attr, char *buf) { @@ -578,32 +578,11 @@ static int vidi_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int vidi_suspend(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - - return vidi_power_on(mgr, false); -} - -static int vidi_resume(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_vidi_mgr(dev); - - return vidi_power_on(mgr, true); -} -#endif - -static const struct dev_pm_ops vidi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(vidi_suspend, vidi_resume) -}; - struct platform_driver vidi_driver = { .probe = vidi_probe, .remove = vidi_remove, .driver = { .name = "exynos-drm-vidi", .owner = THIS_MODULE, - .pm = &vidi_pm_ops, }, }; diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 3faea8f..3313743 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -1737,6 +1737,8 @@ static void hdmi_poweron(struct exynos_drm_display *display) mutex_unlock(&hdata->hdmi_mutex); + pm_runtime_get_sync(hdata->dev); + if (regulator_bulk_enable(res->regul_count, res->regul_bulk)) DRM_DEBUG_KMS("failed to enable regulator bulk\n"); @@ -1770,8 +1772,9 @@ static void hdmi_poweroff(struct exynos_drm_display *display) clk_disable_unprepare(res->hdmiphy); regulator_bulk_disable(res->regul_count, res->regul_bulk); - mutex_lock(&hdata->hdmi_mutex); + pm_runtime_put_sync(hdata->dev); + mutex_lock(&hdata->hdmi_mutex); hdata->powered = false; out: @@ -1780,20 +1783,16 @@ out: static void hdmi_dpms(struct exynos_drm_display *display, int mode) { - struct hdmi_context *hdata = display->ctx; - DRM_DEBUG_KMS("mode %d\n", mode); switch (mode) { case DRM_MODE_DPMS_ON: - if (pm_runtime_suspended(hdata->dev)) - pm_runtime_get_sync(hdata->dev); + hdmi_poweron(display); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (!pm_runtime_suspended(hdata->dev)) - pm_runtime_put_sync(hdata->dev); + hdmi_poweroff(display); break; default: DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); @@ -2033,11 +2032,11 @@ static int hdmi_probe(struct platform_device *pdev) goto err_hdmiphy; } + pm_runtime_enable(dev); + hdmi_display.ctx = hdata; exynos_drm_display_register(&hdmi_display); - pm_runtime_enable(dev); - return 0; err_hdmiphy: @@ -2053,88 +2052,19 @@ static int hdmi_remove(struct platform_device *pdev) struct exynos_drm_display *display = get_hdmi_display(dev); struct hdmi_context *hdata = display->ctx; - pm_runtime_disable(dev); - put_device(&hdata->hdmiphy_port->dev); put_device(&hdata->ddc_port->dev); + pm_runtime_disable(&pdev->dev); return 0; } -#ifdef CONFIG_PM_SLEEP -static int hdmi_suspend(struct device *dev) -{ - struct exynos_drm_display *display = get_hdmi_display(dev); - struct hdmi_context *hdata = display->ctx; - - disable_irq(hdata->irq); - - hdata->hpd = false; - if (hdata->drm_dev) - drm_helper_hpd_irq_event(hdata->drm_dev); - - if (pm_runtime_suspended(dev)) { - DRM_DEBUG_KMS("Already suspended\n"); - return 0; - } - - hdmi_poweroff(display); - - return 0; -} - -static int hdmi_resume(struct device *dev) -{ - struct exynos_drm_display *display = get_hdmi_display(dev); - struct hdmi_context *hdata = display->ctx; - - hdata->hpd = gpio_get_value(hdata->hpd_gpio); - - enable_irq(hdata->irq); - - if (!pm_runtime_suspended(dev)) { - DRM_DEBUG_KMS("Already resumed\n"); - return 0; - } - - hdmi_poweron(display); - - return 0; -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int hdmi_runtime_suspend(struct device *dev) -{ - struct exynos_drm_display *display = get_hdmi_display(dev); - - hdmi_poweroff(display); - - return 0; -} - -static int hdmi_runtime_resume(struct device *dev) -{ - struct exynos_drm_display *display = get_hdmi_display(dev); - - hdmi_poweron(display); - - return 0; -} -#endif - -static const struct dev_pm_ops hdmi_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(hdmi_suspend, hdmi_resume) - SET_RUNTIME_PM_OPS(hdmi_runtime_suspend, hdmi_runtime_resume, NULL) -}; - struct platform_driver hdmi_driver = { .probe = hdmi_probe, .remove = hdmi_remove, .driver = { .name = "exynos-hdmi", .owner = THIS_MODULE, - .pm = &hdmi_pm_ops, .of_match_table = hdmi_match_types, }, }; diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index d522857..ce28881 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -1061,6 +1061,8 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) ctx->powered = true; mutex_unlock(&ctx->mixer_mutex); + pm_runtime_get_sync(ctx->dev); + clk_prepare_enable(res->mixer); if (ctx->vp_enabled) { clk_prepare_enable(res->vp); @@ -1093,6 +1095,8 @@ static void mixer_poweroff(struct exynos_drm_manager *mgr) clk_disable_unprepare(res->sclk_mixer); } + pm_runtime_put_sync(ctx->dev); + mutex_lock(&ctx->mixer_mutex); ctx->powered = false; @@ -1102,18 +1106,14 @@ out: static void mixer_dpms(struct exynos_drm_manager *mgr, int mode) { - struct mixer_context *mixer_ctx = mgr->ctx; - switch (mode) { case DRM_MODE_DPMS_ON: - if (pm_runtime_suspended(mixer_ctx->dev)) - pm_runtime_get_sync(mixer_ctx->dev); + mixer_poweron(mgr); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - if (!pm_runtime_suspended(mixer_ctx->dev)) - pm_runtime_put_sync(mixer_ctx->dev); + mixer_poweroff(mgr); break; default: DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode); @@ -1250,66 +1250,10 @@ static int mixer_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int mixer_suspend(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_mixer_manager(dev); - - if (pm_runtime_suspended(dev)) { - DRM_DEBUG_KMS("Already suspended\n"); - return 0; - } - - mixer_poweroff(mgr); - - return 0; -} - -static int mixer_resume(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_mixer_manager(dev); - - if (!pm_runtime_suspended(dev)) { - DRM_DEBUG_KMS("Already resumed\n"); - return 0; - } - - mixer_poweron(mgr); - - return 0; -} -#endif - -#ifdef CONFIG_PM_RUNTIME -static int mixer_runtime_suspend(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_mixer_manager(dev); - - mixer_poweroff(mgr); - - return 0; -} - -static int mixer_runtime_resume(struct device *dev) -{ - struct exynos_drm_manager *mgr = get_mixer_manager(dev); - - mixer_poweron(mgr); - - return 0; -} -#endif - -static const struct dev_pm_ops mixer_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume) - SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL) -}; - struct platform_driver mixer_driver = { .driver = { .name = "exynos-mixer", .owner = THIS_MODULE, - .pm = &mixer_pm_ops, .of_match_table = mixer_match_types, }, .probe = mixer_probe,