aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChanwoo Choi <cw00.choi@samsung.com>2014-05-09 03:43:08 -0400
committerMyungJoo Ham <myungjoo.ham@samsung.com>2014-05-24 09:33:38 -0400
commit8cd84092d35e52372da2c3c3c2afb1a719917af2 (patch)
treeccb37cbe9e233257050288dbae74c6b3d914b55f
parent585fc83ece43be63d5775e536f855db33dd752cf (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.c63
-rw-r--r--include/linux/devfreq.h21
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}
545EXPORT_SYMBOL(devfreq_remove_device); 545EXPORT_SYMBOL(devfreq_remove_device);
546 546
547static 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
557static 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 */
574struct 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}
596EXPORT_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 */
603void 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}
608EXPORT_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);
183extern int devfreq_remove_device(struct devfreq *devfreq); 183extern int devfreq_remove_device(struct devfreq *devfreq);
184extern struct devfreq *devm_devfreq_add_device(struct device *dev,
185 struct devfreq_dev_profile *profile,
186 const char *governor_name,
187 void *data);
188extern 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 */
186extern int devfreq_suspend_device(struct devfreq *devfreq); 192extern 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
226static inline int devfreq_remove_device(struct devfreq *devfreq) 232static 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
237static 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
245static inline void devm_devfreq_remove_device(struct device *dev,
246 struct devfreq *devfreq)
247{
248}
249
231static inline int devfreq_suspend_device(struct devfreq *devfreq) 250static inline int devfreq_suspend_device(struct devfreq *devfreq)
232{ 251{
233 return 0; 252 return 0;