drm/exynos: Consolidate suspend/resume in drm_drv

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 <seanpaul@chromium.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
Sean Paul
2014-01-30 16:19:27 -05:00
committed by Inki Dae
parent a43b933bcb
commit af65c80487
5 changed files with 170 additions and 288 deletions

View File

@@ -1789,6 +1789,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");
@@ -1822,8 +1824,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:
@@ -1832,20 +1835,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);
@@ -2085,11 +2084,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:
@@ -2105,88 +2104,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,
},
};