cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

s5p_mfc_pm.c (2373B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * linux/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c
      4 *
      5 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
      6 *		http://www.samsung.com/
      7 */
      8
      9#include <linux/clk.h>
     10#include <linux/err.h>
     11#include <linux/platform_device.h>
     12#include <linux/pm_runtime.h>
     13#include "s5p_mfc_common.h"
     14#include "s5p_mfc_debug.h"
     15#include "s5p_mfc_pm.h"
     16
     17static struct s5p_mfc_pm *pm;
     18static struct s5p_mfc_dev *p_dev;
     19static atomic_t clk_ref;
     20
     21int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)
     22{
     23	int i;
     24
     25	pm = &dev->pm;
     26	p_dev = dev;
     27
     28	pm->num_clocks = dev->variant->num_clocks;
     29	pm->clk_names = dev->variant->clk_names;
     30	pm->device = &dev->plat_dev->dev;
     31	pm->clock_gate = NULL;
     32
     33	/* clock control */
     34	for (i = 0; i < pm->num_clocks; i++) {
     35		pm->clocks[i] = devm_clk_get(pm->device, pm->clk_names[i]);
     36		if (IS_ERR(pm->clocks[i])) {
     37			/* additional clocks are optional */
     38			if (i && PTR_ERR(pm->clocks[i]) == -ENOENT) {
     39				pm->clocks[i] = NULL;
     40				continue;
     41			}
     42			mfc_err("Failed to get clock: %s\n",
     43				pm->clk_names[i]);
     44			return PTR_ERR(pm->clocks[i]);
     45		}
     46	}
     47
     48	if (dev->variant->use_clock_gating)
     49		pm->clock_gate = pm->clocks[0];
     50
     51	pm_runtime_enable(pm->device);
     52	atomic_set(&clk_ref, 0);
     53	return 0;
     54}
     55
     56void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)
     57{
     58	pm_runtime_disable(pm->device);
     59}
     60
     61int s5p_mfc_clock_on(void)
     62{
     63	atomic_inc(&clk_ref);
     64	mfc_debug(3, "+ %d\n", atomic_read(&clk_ref));
     65
     66	return clk_enable(pm->clock_gate);
     67}
     68
     69void s5p_mfc_clock_off(void)
     70{
     71	atomic_dec(&clk_ref);
     72	mfc_debug(3, "- %d\n", atomic_read(&clk_ref));
     73
     74	clk_disable(pm->clock_gate);
     75}
     76
     77int s5p_mfc_power_on(void)
     78{
     79	int i, ret = 0;
     80
     81	ret = pm_runtime_resume_and_get(pm->device);
     82	if (ret < 0)
     83		return ret;
     84
     85	/* clock control */
     86	for (i = 0; i < pm->num_clocks; i++) {
     87		ret = clk_prepare_enable(pm->clocks[i]);
     88		if (ret < 0) {
     89			mfc_err("clock prepare failed for clock: %s\n",
     90				pm->clk_names[i]);
     91			i++;
     92			goto err;
     93		}
     94	}
     95
     96	/* prepare for software clock gating */
     97	clk_disable(pm->clock_gate);
     98
     99	return 0;
    100err:
    101	while (--i > 0)
    102		clk_disable_unprepare(pm->clocks[i]);
    103	pm_runtime_put(pm->device);
    104	return ret;
    105}
    106
    107int s5p_mfc_power_off(void)
    108{
    109	int i;
    110
    111	/* finish software clock gating */
    112	clk_enable(pm->clock_gate);
    113
    114	for (i = 0; i < pm->num_clocks; i++)
    115		clk_disable_unprepare(pm->clocks[i]);
    116
    117	return pm_runtime_put_sync(pm->device);
    118}
    119