linux/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
<<
>>
Prefs
   1/*
   2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
   3 *
   4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
   5 *              http://www.samsung.com/
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12
  13#include <linux/clk.h>
  14#include <linux/err.h>
  15#include <linux/platform_device.h>
  16#ifdef CONFIG_PM_RUNTIME
  17#include <linux/pm_runtime.h>
  18#endif
  19#include "s5p_mfc_common.h"
  20#include "s5p_mfc_debug.h"
  21#include "s5p_mfc_pm.h"
  22
  23#define MFC_GATE_CLK_NAME       "mfc"
  24
  25#define CLK_DEBUG
  26
  27static struct s5p_mfc_pm *pm;
  28static struct s5p_mfc_dev *p_dev;
  29
  30#ifdef CLK_DEBUG
  31static atomic_t clk_ref;
  32#endif
  33
  34int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
  35{
  36        int ret = 0;
  37
  38        pm = &dev->pm;
  39        p_dev = dev;
  40        pm->clock_gate = clk_get(&dev->plat_dev->dev, MFC_GATE_CLK_NAME);
  41        if (IS_ERR(pm->clock_gate)) {
  42                mfc_err("Failed to get clock-gating control\n");
  43                ret = PTR_ERR(pm->clock_gate);
  44                goto err_g_ip_clk;
  45        }
  46
  47        ret = clk_prepare(pm->clock_gate);
  48        if (ret) {
  49                mfc_err("Failed to prepare clock-gating control\n");
  50                goto err_p_ip_clk;
  51        }
  52
  53        atomic_set(&pm->power, 0);
  54#ifdef CONFIG_PM_RUNTIME
  55        pm->device = &dev->plat_dev->dev;
  56        pm_runtime_enable(pm->device);
  57#endif
  58#ifdef CLK_DEBUG
  59        atomic_set(&clk_ref, 0);
  60#endif
  61        return 0;
  62err_p_ip_clk:
  63        clk_put(pm->clock_gate);
  64err_g_ip_clk:
  65        return ret;
  66}
  67
  68void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
  69{
  70        clk_unprepare(pm->clock_gate);
  71        clk_put(pm->clock_gate);
  72#ifdef CONFIG_PM_RUNTIME
  73        pm_runtime_disable(pm->device);
  74#endif
  75}
  76
  77int s5p_mfc_clock_on(void)
  78{
  79        int ret;
  80#ifdef CLK_DEBUG
  81        atomic_inc(&clk_ref);
  82        mfc_debug(3, "+ %d\n", atomic_read(&clk_ref));
  83#endif
  84        ret = clk_enable(pm->clock_gate);
  85        return ret;
  86}
  87
  88void s5p_mfc_clock_off(void)
  89{
  90#ifdef CLK_DEBUG
  91        atomic_dec(&clk_ref);
  92        mfc_debug(3, "- %d\n", atomic_read(&clk_ref));
  93#endif
  94        clk_disable(pm->clock_gate);
  95}
  96
  97int s5p_mfc_power_on(void)
  98{
  99#ifdef CONFIG_PM_RUNTIME
 100        return pm_runtime_get_sync(pm->device);
 101#else
 102        atomic_set(&pm->power, 1);
 103        return 0;
 104#endif
 105}
 106
 107int s5p_mfc_power_off(void)
 108{
 109#ifdef CONFIG_PM_RUNTIME
 110        return pm_runtime_put_sync(pm->device);
 111#else
 112        atomic_set(&pm->power, 0);
 113        return 0;
 114#endif
 115}
 116
 117
 118