diff options
author | Chanwoo Choi <cw00.choi@samsung.com> | 2014-05-09 03:43:08 -0400 |
---|---|---|
committer | MyungJoo Ham <myungjoo.ham@samsung.com> | 2014-05-24 09:33:38 -0400 |
commit | 8cd84092d35e52372da2c3c3c2afb1a719917af2 (patch) | |
tree | ccb37cbe9e233257050288dbae74c6b3d914b55f | |
parent | 585fc83ece43be63d5775e536f855db33dd752cf (diff) |
PM / devfreq: Add resource-managed function for devfreq device
This patch add resource-managed function for devfreq device as following
functions. The devm_devfreq_add_device() manages automatically the memory
of devfreq device using device resource management.
- devm_devfreq_add_device()
- devm_devfreq_remove_device()
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
-rw-r--r-- | drivers/devfreq/devfreq.c | 63 | ||||
-rw-r--r-- | include/linux/devfreq.h | 21 |
2 files changed, 83 insertions, 1 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index af4af7708574..8b6295d9d1f5 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -544,6 +544,69 @@ int devfreq_remove_device(struct devfreq *devfreq) | |||
544 | } | 544 | } |
545 | EXPORT_SYMBOL(devfreq_remove_device); | 545 | EXPORT_SYMBOL(devfreq_remove_device); |
546 | 546 | ||
547 | static int devm_devfreq_dev_match(struct device *dev, void *res, void *data) | ||
548 | { | ||
549 | struct devfreq **r = res; | ||
550 | |||
551 | if (WARN_ON(!r || !*r)) | ||
552 | return 0; | ||
553 | |||
554 | return *r == data; | ||
555 | } | ||
556 | |||
557 | static void devm_devfreq_dev_release(struct device *dev, void *res) | ||
558 | { | ||
559 | devfreq_remove_device(*(struct devfreq **)res); | ||
560 | } | ||
561 | |||
562 | /** | ||
563 | * devm_devfreq_add_device() - Resource-managed devfreq_add_device() | ||
564 | * @dev: the device to add devfreq feature. | ||
565 | * @profile: device-specific profile to run devfreq. | ||
566 | * @governor_name: name of the policy to choose frequency. | ||
567 | * @data: private data for the governor. The devfreq framework does not | ||
568 | * touch this value. | ||
569 | * | ||
570 | * This function manages automatically the memory of devfreq device using device | ||
571 | * resource management and simplify the free operation for memory of devfreq | ||
572 | * device. | ||
573 | */ | ||
574 | struct devfreq *devm_devfreq_add_device(struct device *dev, | ||
575 | struct devfreq_dev_profile *profile, | ||
576 | const char *governor_name, | ||
577 | void *data) | ||
578 | { | ||
579 | struct devfreq **ptr, *devfreq; | ||
580 | |||
581 | ptr = devres_alloc(devm_devfreq_dev_release, sizeof(*ptr), GFP_KERNEL); | ||
582 | if (!ptr) | ||
583 | return ERR_PTR(-ENOMEM); | ||
584 | |||
585 | devfreq = devfreq_add_device(dev, profile, governor_name, data); | ||
586 | if (IS_ERR(devfreq)) { | ||
587 | devres_free(ptr); | ||
588 | return ERR_PTR(-ENOMEM); | ||
589 | } | ||
590 | |||
591 | *ptr = devfreq; | ||
592 | devres_add(dev, ptr); | ||
593 | |||
594 | return devfreq; | ||
595 | } | ||
596 | EXPORT_SYMBOL(devm_devfreq_add_device); | ||
597 | |||
598 | /** | ||
599 | * devm_devfreq_remove_device() - Resource-managed devfreq_remove_device() | ||
600 | * @dev: the device to add devfreq feature. | ||
601 | * @devfreq: the devfreq instance to be removed | ||
602 | */ | ||
603 | void devm_devfreq_remove_device(struct device *dev, struct devfreq *devfreq) | ||
604 | { | ||
605 | WARN_ON(devres_release(dev, devm_devfreq_dev_release, | ||
606 | devm_devfreq_dev_match, devfreq)); | ||
607 | } | ||
608 | EXPORT_SYMBOL(devm_devfreq_remove_device); | ||
609 | |||
547 | /** | 610 | /** |
548 | * devfreq_suspend_device() - Suspend devfreq of a device. | 611 | * devfreq_suspend_device() - Suspend devfreq of a device. |
549 | * @devfreq: the devfreq instance to be suspended | 612 | * @devfreq: the devfreq instance to be suspended |
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index d48dc00232a4..023d668a2cb5 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h | |||
@@ -181,6 +181,12 @@ extern struct devfreq *devfreq_add_device(struct device *dev, | |||
181 | const char *governor_name, | 181 | const char *governor_name, |
182 | void *data); | 182 | void *data); |
183 | extern int devfreq_remove_device(struct devfreq *devfreq); | 183 | extern int devfreq_remove_device(struct devfreq *devfreq); |
184 | extern struct devfreq *devm_devfreq_add_device(struct device *dev, | ||
185 | struct devfreq_dev_profile *profile, | ||
186 | const char *governor_name, | ||
187 | void *data); | ||
188 | extern void devm_devfreq_remove_device(struct device *dev, | ||
189 | struct devfreq *devfreq); | ||
184 | 190 | ||
185 | /* Supposed to be called by PM_SLEEP/PM_RUNTIME callbacks */ | 191 | /* Supposed to be called by PM_SLEEP/PM_RUNTIME callbacks */ |
186 | extern int devfreq_suspend_device(struct devfreq *devfreq); | 192 | extern int devfreq_suspend_device(struct devfreq *devfreq); |
@@ -220,7 +226,7 @@ static inline struct devfreq *devfreq_add_device(struct device *dev, | |||
220 | const char *governor_name, | 226 | const char *governor_name, |
221 | void *data) | 227 | void *data) |
222 | { | 228 | { |
223 | return NULL; | 229 | return ERR_PTR(-ENOSYS); |
224 | } | 230 | } |
225 | 231 | ||
226 | static inline int devfreq_remove_device(struct devfreq *devfreq) | 232 | static inline int devfreq_remove_device(struct devfreq *devfreq) |
@@ -228,6 +234,19 @@ static inline int devfreq_remove_device(struct devfreq *devfreq) | |||
228 | return 0; | 234 | return 0; |
229 | } | 235 | } |
230 | 236 | ||
237 | static inline struct devfreq *devm_devfreq_add_device(struct device *dev, | ||
238 | struct devfreq_dev_profile *profile, | ||
239 | const char *governor_name, | ||
240 | void *data) | ||
241 | { | ||
242 | return ERR_PTR(-ENOSYS); | ||
243 | } | ||
244 | |||
245 | static inline void devm_devfreq_remove_device(struct device *dev, | ||
246 | struct devfreq *devfreq) | ||
247 | { | ||
248 | } | ||
249 | |||
231 | static inline int devfreq_suspend_device(struct devfreq *devfreq) | 250 | static inline int devfreq_suspend_device(struct devfreq *devfreq) |
232 | { | 251 | { |
233 | return 0; | 252 | return 0; |