aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/clock_ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base/power/clock_ops.c')
-rw-r--r--drivers/base/power/clock_ops.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c
index 78369305e069..f061eaa48bb5 100644
--- a/drivers/base/power/clock_ops.c
+++ b/drivers/base/power/clock_ops.c
@@ -12,6 +12,7 @@
12#include <linux/pm.h> 12#include <linux/pm.h>
13#include <linux/pm_clock.h> 13#include <linux/pm_clock.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/clkdev.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/err.h> 17#include <linux/err.h>
17 18
@@ -53,7 +54,8 @@ static inline int __pm_clk_enable(struct device *dev, struct clk *clk)
53 */ 54 */
54static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) 55static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
55{ 56{
56 ce->clk = clk_get(dev, ce->con_id); 57 if (!ce->clk)
58 ce->clk = clk_get(dev, ce->con_id);
57 if (IS_ERR(ce->clk)) { 59 if (IS_ERR(ce->clk)) {
58 ce->status = PCE_STATUS_ERROR; 60 ce->status = PCE_STATUS_ERROR;
59 } else { 61 } else {
@@ -63,15 +65,8 @@ static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
63 } 65 }
64} 66}
65 67
66/** 68static int __pm_clk_add(struct device *dev, const char *con_id,
67 * pm_clk_add - Start using a device clock for power management. 69 struct clk *clk)
68 * @dev: Device whose clock is going to be used for power management.
69 * @con_id: Connection ID of the clock.
70 *
71 * Add the clock represented by @con_id to the list of clocks used for
72 * the power management of @dev.
73 */
74int pm_clk_add(struct device *dev, const char *con_id)
75{ 70{
76 struct pm_subsys_data *psd = dev_to_psd(dev); 71 struct pm_subsys_data *psd = dev_to_psd(dev);
77 struct pm_clock_entry *ce; 72 struct pm_clock_entry *ce;
@@ -93,6 +88,12 @@ int pm_clk_add(struct device *dev, const char *con_id)
93 kfree(ce); 88 kfree(ce);
94 return -ENOMEM; 89 return -ENOMEM;
95 } 90 }
91 } else {
92 if (IS_ERR(ce->clk) || !__clk_get(clk)) {
93 kfree(ce);
94 return -ENOENT;
95 }
96 ce->clk = clk;
96 } 97 }
97 98
98 pm_clk_acquire(dev, ce); 99 pm_clk_acquire(dev, ce);
@@ -104,6 +105,32 @@ int pm_clk_add(struct device *dev, const char *con_id)
104} 105}
105 106
106/** 107/**
108 * pm_clk_add - Start using a device clock for power management.
109 * @dev: Device whose clock is going to be used for power management.
110 * @con_id: Connection ID of the clock.
111 *
112 * Add the clock represented by @con_id to the list of clocks used for
113 * the power management of @dev.
114 */
115int pm_clk_add(struct device *dev, const char *con_id)
116{
117 return __pm_clk_add(dev, con_id, NULL);
118}
119
120/**
121 * pm_clk_add_clk - Start using a device clock for power management.
122 * @dev: Device whose clock is going to be used for power management.
123 * @clk: Clock pointer
124 *
125 * Add the clock to the list of clocks used for the power management of @dev.
126 * It will increment refcount on clock pointer, use clk_put() on it when done.
127 */
128int pm_clk_add_clk(struct device *dev, struct clk *clk)
129{
130 return __pm_clk_add(dev, NULL, clk);
131}
132
133/**
107 * __pm_clk_remove - Destroy PM clock entry. 134 * __pm_clk_remove - Destroy PM clock entry.
108 * @ce: PM clock entry to destroy. 135 * @ce: PM clock entry to destroy.
109 */ 136 */