106 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * linux/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c4 *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 17int s5p_mfc_init_pm(struct s5p_mfc_dev *dev)18{19 struct s5p_mfc_pm *pm = &dev->pm;20 int i;21 22 pm->num_clocks = dev->variant->num_clocks;23 pm->clk_names = dev->variant->clk_names;24 pm->device = &dev->plat_dev->dev;25 pm->clock_gate = NULL;26 27 /* clock control */28 for (i = 0; i < pm->num_clocks; i++) {29 pm->clocks[i] = devm_clk_get(pm->device, pm->clk_names[i]);30 if (IS_ERR(pm->clocks[i])) {31 /* additional clocks are optional */32 if (i && PTR_ERR(pm->clocks[i]) == -ENOENT) {33 pm->clocks[i] = NULL;34 continue;35 }36 mfc_err("Failed to get clock: %s\n",37 pm->clk_names[i]);38 return PTR_ERR(pm->clocks[i]);39 }40 }41 42 if (dev->variant->use_clock_gating)43 pm->clock_gate = pm->clocks[0];44 45 pm_runtime_enable(pm->device);46 return 0;47}48 49void s5p_mfc_final_pm(struct s5p_mfc_dev *dev)50{51 pm_runtime_disable(dev->pm.device);52}53 54int s5p_mfc_clock_on(struct s5p_mfc_dev *dev)55{56 return clk_enable(dev->pm.clock_gate);57}58 59void s5p_mfc_clock_off(struct s5p_mfc_dev *dev)60{61 clk_disable(dev->pm.clock_gate);62}63 64int s5p_mfc_power_on(struct s5p_mfc_dev *dev)65{66 int i, ret = 0;67 68 ret = pm_runtime_resume_and_get(dev->pm.device);69 if (ret < 0)70 return ret;71 72 /* clock control */73 for (i = 0; i < dev->pm.num_clocks; i++) {74 ret = clk_prepare_enable(dev->pm.clocks[i]);75 if (ret < 0) {76 mfc_err("clock prepare failed for clock: %s\n",77 dev->pm.clk_names[i]);78 goto err;79 }80 }81 82 /* prepare for software clock gating */83 clk_disable(dev->pm.clock_gate);84 85 return 0;86err:87 while (--i >= 0)88 clk_disable_unprepare(dev->pm.clocks[i]);89 pm_runtime_put(dev->pm.device);90 return ret;91}92 93int s5p_mfc_power_off(struct s5p_mfc_dev *dev)94{95 int i;96 97 /* finish software clock gating */98 clk_enable(dev->pm.clock_gate);99 100 for (i = 0; i < dev->pm.num_clocks; i++)101 clk_disable_unprepare(dev->pm.clocks[i]);102 103 return pm_runtime_put_sync(dev->pm.device);104}105 106