2 * linux/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c
4 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com/
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.
13 #include <linux/clk.h>
14 #include <linux/err.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include "s5p_mfc_common.h"
18 #include "s5p_mfc_debug.h"
19 #include "s5p_mfc_pm.h"
21 static struct s5p_mfc_pm
*pm
;
22 static struct s5p_mfc_dev
*p_dev
;
23 static atomic_t clk_ref
;
25 int s5p_mfc_init_pm(struct s5p_mfc_dev
*dev
)
32 pm
->num_clocks
= dev
->variant
->num_clocks
;
33 pm
->clk_names
= dev
->variant
->clk_names
;
34 pm
->device
= &dev
->plat_dev
->dev
;
35 pm
->clock_gate
= NULL
;
38 for (i
= 0; i
< pm
->num_clocks
; i
++) {
39 pm
->clocks
[i
] = devm_clk_get(pm
->device
, pm
->clk_names
[i
]);
40 if (IS_ERR(pm
->clocks
[i
])) {
41 mfc_err("Failed to get clock: %s\n",
43 return PTR_ERR(pm
->clocks
[i
]);
47 if (dev
->variant
->use_clock_gating
)
48 pm
->clock_gate
= pm
->clocks
[0];
50 pm_runtime_enable(pm
->device
);
51 atomic_set(&clk_ref
, 0);
55 void s5p_mfc_final_pm(struct s5p_mfc_dev
*dev
)
57 pm_runtime_disable(pm
->device
);
60 int s5p_mfc_clock_on(void)
63 mfc_debug(3, "+ %d\n", atomic_read(&clk_ref
));
65 return clk_enable(pm
->clock_gate
);
68 void s5p_mfc_clock_off(void)
71 mfc_debug(3, "- %d\n", atomic_read(&clk_ref
));
73 clk_disable(pm
->clock_gate
);
76 int s5p_mfc_power_on(void)
80 ret
= pm_runtime_get_sync(pm
->device
);
85 for (i
= 0; i
< pm
->num_clocks
; i
++) {
86 ret
= clk_prepare_enable(pm
->clocks
[i
]);
88 mfc_err("clock prepare failed for clock: %s\n",
95 /* prepare for software clock gating */
96 clk_disable(pm
->clock_gate
);
101 clk_disable_unprepare(pm
->clocks
[i
]);
102 pm_runtime_put(pm
->device
);
106 int s5p_mfc_power_off(void)
110 /* finish software clock gating */
111 clk_enable(pm
->clock_gate
);
113 for (i
= 0; i
< pm
->num_clocks
; i
++)
114 clk_disable_unprepare(pm
->clocks
[i
]);
116 return pm_runtime_put_sync(pm
->device
);