diff options
-rw-r--r-- | drivers/cpuidle/driver.c | 29 | ||||
-rw-r--r-- | include/linux/cpuidle.h | 6 |
2 files changed, 33 insertions, 2 deletions
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 40cd3f3024df..58bf3b1ac9c4 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | static struct cpuidle_driver *cpuidle_curr_driver; | 17 | static struct cpuidle_driver *cpuidle_curr_driver; |
18 | DEFINE_SPINLOCK(cpuidle_driver_lock); | 18 | DEFINE_SPINLOCK(cpuidle_driver_lock); |
19 | int cpuidle_driver_refcount; | ||
19 | 20 | ||
20 | static void __cpuidle_register_driver(struct cpuidle_driver *drv) | 21 | static void __cpuidle_register_driver(struct cpuidle_driver *drv) |
21 | { | 22 | { |
@@ -89,8 +90,34 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv) | |||
89 | } | 90 | } |
90 | 91 | ||
91 | spin_lock(&cpuidle_driver_lock); | 92 | spin_lock(&cpuidle_driver_lock); |
92 | cpuidle_curr_driver = NULL; | 93 | |
94 | if (!WARN_ON(cpuidle_driver_refcount > 0)) | ||
95 | cpuidle_curr_driver = NULL; | ||
96 | |||
93 | spin_unlock(&cpuidle_driver_lock); | 97 | spin_unlock(&cpuidle_driver_lock); |
94 | } | 98 | } |
95 | 99 | ||
96 | EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); | 100 | EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); |
101 | |||
102 | struct cpuidle_driver *cpuidle_driver_ref(void) | ||
103 | { | ||
104 | struct cpuidle_driver *drv; | ||
105 | |||
106 | spin_lock(&cpuidle_driver_lock); | ||
107 | |||
108 | drv = cpuidle_curr_driver; | ||
109 | cpuidle_driver_refcount++; | ||
110 | |||
111 | spin_unlock(&cpuidle_driver_lock); | ||
112 | return drv; | ||
113 | } | ||
114 | |||
115 | void cpuidle_driver_unref(void) | ||
116 | { | ||
117 | spin_lock(&cpuidle_driver_lock); | ||
118 | |||
119 | if (!WARN_ON(cpuidle_driver_refcount <= 0)) | ||
120 | cpuidle_driver_refcount--; | ||
121 | |||
122 | spin_unlock(&cpuidle_driver_lock); | ||
123 | } | ||
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 8570012a535a..27cfced7b57b 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h | |||
@@ -136,7 +136,9 @@ struct cpuidle_driver { | |||
136 | extern void disable_cpuidle(void); | 136 | extern void disable_cpuidle(void); |
137 | extern int cpuidle_idle_call(void); | 137 | extern int cpuidle_idle_call(void); |
138 | extern int cpuidle_register_driver(struct cpuidle_driver *drv); | 138 | extern int cpuidle_register_driver(struct cpuidle_driver *drv); |
139 | struct cpuidle_driver *cpuidle_get_driver(void); | 139 | extern struct cpuidle_driver *cpuidle_get_driver(void); |
140 | extern struct cpuidle_driver *cpuidle_driver_ref(void); | ||
141 | extern void cpuidle_driver_unref(void); | ||
140 | extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); | 142 | extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); |
141 | extern int cpuidle_register_device(struct cpuidle_device *dev); | 143 | extern int cpuidle_register_device(struct cpuidle_device *dev); |
142 | extern void cpuidle_unregister_device(struct cpuidle_device *dev); | 144 | extern void cpuidle_unregister_device(struct cpuidle_device *dev); |
@@ -157,6 +159,8 @@ static inline int cpuidle_idle_call(void) { return -ENODEV; } | |||
157 | static inline int cpuidle_register_driver(struct cpuidle_driver *drv) | 159 | static inline int cpuidle_register_driver(struct cpuidle_driver *drv) |
158 | {return -ENODEV; } | 160 | {return -ENODEV; } |
159 | static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } | 161 | static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; } |
162 | static inline struct cpuidle_driver *cpuidle_driver_ref(void) {return NULL; } | ||
163 | static inline void cpuidle_driver_unref(void) {} | ||
160 | static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } | 164 | static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } |
161 | static inline int cpuidle_register_device(struct cpuidle_device *dev) | 165 | static inline int cpuidle_register_device(struct cpuidle_device *dev) |
162 | {return -ENODEV; } | 166 | {return -ENODEV; } |