Applied.

Thanks.

2017년 01월 13일 17:30에 Marek Szyprowski 이(가) 쓴 글:
> This patch adds runtime support calls to notify device core when MIC
> device is really in use. Runtime PM is implemented by enabling and
> disabling clocks like in other Exynos DRM subdrivers. Adding runtime
> PM support is needed to let power domain with this device to be turned
> off when display is not used.
> 
> Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
> ---
> Changelog:
> v2:
> - moved clock control to runtime PM callbacks as requested by Inki Dae
> 
> v1: http://www.spinics.net/lists/dri-devel/msg129095.html
> - initial version
> ---
>  drivers/gpu/drm/exynos/exynos_drm_mic.c | 82 
> ++++++++++++++++++++++++---------
>  1 file changed, 59 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_mic.c 
> b/drivers/gpu/drm/exynos/exynos_drm_mic.c
> index a0def0be6d65..430f67c63707 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_mic.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_mic.c
> @@ -19,6 +19,7 @@
>  #include <linux/of_graph.h>
>  #include <linux/clk.h>
>  #include <linux/component.h>
> +#include <linux/pm_runtime.h>
>  #include <drm/drmP.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
> @@ -312,7 +313,6 @@ static void mic_disable(struct drm_bridge *bridge) { }
>  static void mic_post_disable(struct drm_bridge *bridge)
>  {
>       struct exynos_mic *mic = bridge->driver_private;
> -     int i;
>  
>       mutex_lock(&mic_mutex);
>       if (!mic->enabled)
> @@ -320,9 +320,7 @@ static void mic_post_disable(struct drm_bridge *bridge)
>  
>       mic_set_path(mic, 0);
>  
> -     for (i = NUM_CLKS - 1; i > -1; i--)
> -             clk_disable_unprepare(mic->clks[i]);
> -
> +     pm_runtime_put(mic->dev);
>       mic->enabled = 0;
>  
>  already_disabled:
> @@ -332,27 +330,22 @@ static void mic_post_disable(struct drm_bridge *bridge)
>  static void mic_pre_enable(struct drm_bridge *bridge)
>  {
>       struct exynos_mic *mic = bridge->driver_private;
> -     int ret, i;
> +     int ret;
>  
>       mutex_lock(&mic_mutex);
>       if (mic->enabled)
> -             goto already_enabled;
> +             goto unlock;
>  
> -     for (i = 0; i < NUM_CLKS; i++) {
> -             ret = clk_prepare_enable(mic->clks[i]);
> -             if (ret < 0) {
> -                     DRM_ERROR("Failed to enable clock (%s)\n",
> -                                                     clk_names[i]);
> -                     goto turn_off_clks;
> -             }
> -     }
> +     ret = pm_runtime_get_sync(mic->dev);
> +     if (ret < 0)
> +             goto unlock;
>  
>       mic_set_path(mic, 1);
>  
>       ret = mic_sw_reset(mic);
>       if (ret) {
>               DRM_ERROR("Failed to reset\n");
> -             goto turn_off_clks;
> +             goto turn_off;
>       }
>  
>       if (!mic->i80_mode)
> @@ -365,10 +358,9 @@ static void mic_pre_enable(struct drm_bridge *bridge)
>  
>       return;
>  
> -turn_off_clks:
> -     while (--i > -1)
> -             clk_disable_unprepare(mic->clks[i]);
> -already_enabled:
> +turn_off:
> +     pm_runtime_put(mic->dev);
> +unlock:
>       mutex_unlock(&mic_mutex);
>  }
>  
> @@ -401,14 +393,12 @@ static void exynos_mic_unbind(struct device *dev, 
> struct device *master,
>                             void *data)
>  {
>       struct exynos_mic *mic = dev_get_drvdata(dev);
> -     int i;
>  
>       mutex_lock(&mic_mutex);
>       if (!mic->enabled)
>               goto already_disabled;
>  
> -     for (i = NUM_CLKS - 1; i > -1; i--)
> -             clk_disable_unprepare(mic->clks[i]);
> +     pm_runtime_put(mic->dev);
>  
>  already_disabled:
>       mutex_unlock(&mic_mutex);
> @@ -421,6 +411,41 @@ static void exynos_mic_unbind(struct device *dev, struct 
> device *master,
>       .unbind = exynos_mic_unbind,
>  };
>  
> +#ifdef CONFIG_PM
> +static int exynos_mic_suspend(struct device *dev)
> +{
> +     struct exynos_mic *mic = dev_get_drvdata(dev);
> +     int i;
> +
> +     for (i = NUM_CLKS - 1; i > -1; i--)
> +             clk_disable_unprepare(mic->clks[i]);
> +
> +     return 0;
> +}
> +
> +static int exynos_mic_resume(struct device *dev)
> +{
> +     struct exynos_mic *mic = dev_get_drvdata(dev);
> +     int ret, i;
> +
> +     for (i = 0; i < NUM_CLKS; i++) {
> +             ret = clk_prepare_enable(mic->clks[i]);
> +             if (ret < 0) {
> +                     DRM_ERROR("Failed to enable clock (%s)\n",
> +                                                     clk_names[i]);
> +                     while (--i > -1)
> +                             clk_disable_unprepare(mic->clks[i]);
> +                     return ret;
> +             }
> +     }
> +     return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops exynos_mic_pm_ops = {
> +     SET_RUNTIME_PM_OPS(exynos_mic_suspend, exynos_mic_resume, NULL)
> +};
> +
>  static int exynos_mic_probe(struct platform_device *pdev)
>  {
>       struct device *dev = &pdev->dev;
> @@ -473,9 +498,18 @@ static int exynos_mic_probe(struct platform_device *pdev)
>  
>       platform_set_drvdata(pdev, mic);
>  
> +     pm_runtime_enable(dev);
> +
> +     ret = component_add(dev, &exynos_mic_component_ops);
> +     if (ret)
> +             goto err_pm;
> +
>       DRM_DEBUG_KMS("MIC has been probed\n");
> -     return component_add(dev, &exynos_mic_component_ops);
>  
> +     return 0;
> +
> +err_pm:
> +     pm_runtime_disable(dev);
>  err:
>       return ret;
>  }
> @@ -483,6 +517,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
>  static int exynos_mic_remove(struct platform_device *pdev)
>  {
>       component_del(&pdev->dev, &exynos_mic_component_ops);
> +     pm_runtime_disable(&pdev->dev);
>       return 0;
>  }
>  
> @@ -497,6 +532,7 @@ struct platform_driver mic_driver = {
>       .remove         = exynos_mic_remove,
>       .driver         = {
>               .name   = "exynos-mic",
> +             .pm     = &exynos_mic_pm_ops,
>               .owner  = THIS_MODULE,
>               .of_match_table = exynos_mic_of_match,
>       },
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to