From 8f510aeb223b26c4ffbece9fa92e4befea470f57 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 10 Nov 2015 20:31:07 +0900 Subject: PM / devfreq: Add devfreq_get_devfreq_by_phandle() This patch adds the new devfreq_get_devfreq_by_phandle() OF helper function which can find the instance of devfreq device by using phandle ("devfreq"). Signed-off-by: Chanwoo Choi Signed-off-by: MyungJoo Ham [m.reichl and linux.amoon: Tested it on exynos4412-odroidu3 board] Tested-by: Markus Reichl Tested-by: Anand Moon Acked-by: Krzysztof Kozlowski --- include/linux/devfreq.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux/devfreq.h') diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 6fa02a20eb63..aa0b8424ebc3 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -208,6 +208,9 @@ extern int devm_devfreq_register_opp_notifier(struct device *dev, extern void devm_devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq); +extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, + int index); + /** * devfreq_update_stats() - update the last_status pointer in struct devfreq * @df: the devfreq instance whose status needs updating @@ -307,6 +310,12 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, { } +static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, + int index) +{ + return ERR_PTR(-ENODEV); +} + static inline int devfreq_update_stats(struct devfreq *df) { return -EINVAL; -- cgit v1.2.3 From 0fe3a66410a3ba96679be903f1e287d7a0a264a9 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 26 Jan 2016 13:21:26 +0900 Subject: PM / devfreq: Add new DEVFREQ_TRANSITION_NOTIFIER notifier This patch adds the new DEVFREQ_TRANSITION_NOTIFIER notifier to send the notification when the frequency of device is changed. This notifier has two state as following: - DEVFREQ_PRECHANGE : Notify it before chaning the frequency of device - DEVFREQ_POSTCHANGE : Notify it after changed the frequency of device And this patch adds the resourced-managed function to release the resource automatically when error happen. Signed-off-by: Chanwoo Choi [m.reichl and linux.amoon: Tested it on exynos4412-odroidu3 board] Tested-by: Markus Reichl Tested-by: Anand Moon Signed-off-by: MyungJoo Ham Acked-by: Krzysztof Kozlowski --- include/linux/devfreq.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'include/linux/devfreq.h') diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index aa0b8424ebc3..98c699304e12 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -19,6 +19,13 @@ #define DEVFREQ_NAME_LEN 16 +/* DEVFREQ notifier interface */ +#define DEVFREQ_TRANSITION_NOTIFIER (0) + +/* Transition notifiers of DEVFREQ_TRANSITION_NOTIFIER */ +#define DEVFREQ_PRECHANGE (0) +#define DEVFREQ_POSTCHANGE (1) + struct devfreq; /** @@ -143,6 +150,7 @@ struct devfreq_governor { * @trans_table: Statistics of devfreq transitions * @time_in_state: Statistics of devfreq states * @last_stat_updated: The last time stat updated + * @transition_notifier_list: list head of DEVFREQ_TRANSITION_NOTIFIER notifier * * This structure stores the devfreq information for a give device. * @@ -177,6 +185,13 @@ struct devfreq { unsigned int *trans_table; unsigned long *time_in_state; unsigned long last_stat_updated; + + struct srcu_notifier_head transition_notifier_list; +}; + +struct devfreq_freqs { + unsigned long old; + unsigned long new; }; #if defined(CONFIG_PM_DEVFREQ) @@ -207,7 +222,20 @@ extern int devm_devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq); extern void devm_devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq); - +extern int devfreq_register_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list); +extern int devfreq_unregister_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list); +extern int devm_devfreq_register_notifier(struct device *dev, + struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list); +extern void devm_devfreq_unregister_notifier(struct device *dev, + struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list); extern struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index); @@ -310,6 +338,35 @@ static inline void devm_devfreq_unregister_opp_notifier(struct device *dev, { } +static inline int devfreq_register_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + return 0; +} + +static inline int devfreq_unregister_notifier(struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + return 0; +} + +static inline int devm_devfreq_register_notifier(struct device *dev, + struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ + return 0; +} + +static inline void devm_devfreq_unregister_notifier(struct device *dev, + struct devfreq *devfreq, + struct notifier_block *nb, + unsigned int list) +{ +} + static inline struct devfreq *devfreq_get_devfreq_by_phandle(struct device *dev, int index) { -- cgit v1.2.3 From 996133119f57334c38b020dbfaaac5b5eb127e29 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Tue, 22 Mar 2016 13:44:03 +0900 Subject: PM / devfreq: Add new passive governor This patch adds the new passive governor for DEVFREQ framework. The following governors are already present and used for DVFS (Dynamic Voltage and Frequency Scaling) drivers. The following governors are independently used for one device driver which don't give the influence to other device drviers and also don't receive the effect from other device drivers. - ondemand / performance / powersave / userspace The passive governor depends on operation of parent driver with specific governos extremely and is not able to decide the new frequency by oneself. According to the decided new frequency of parent driver with governor, the passive governor uses it to decide the appropriate frequency for own device driver. The passive governor must need the following information from device tree: - the source clock and OPP tables - the instance of parent device For exameple, there are one more devfreq device drivers which need to change their source clock according to their utilization on runtime. But, they share the same power line (e.g., regulator). So, specific device driver is operated as parent with ondemand governor and then the rest device driver with passive governor is influenced by parent device. Suggested-by: Myungjoo Ham Signed-off-by: Chanwoo Choi [tjakobi: Reported RCU locking issue and cw00.choi fix it] Reported-by: Tobias Jakobi [linux.amoon: Reported possible recursive locking and cw00.choi fix it] Reported-by: Anand Moon Signed-off-by: MyungJoo Ham Acked-by: Krzysztof Kozlowski --- include/linux/devfreq.h | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'include/linux/devfreq.h') diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 98c699304e12..2de4e2eea180 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -272,6 +272,39 @@ struct devfreq_simple_ondemand_data { }; #endif +#if IS_ENABLED(CONFIG_DEVFREQ_GOV_PASSIVE) +/** + * struct devfreq_passive_data - void *data fed to struct devfreq + * and devfreq_add_device + * @parent: the devfreq instance of parent device. + * @get_target_freq: Optional callback, Returns desired operating frequency + * for the device using passive governor. That is called + * when passive governor should decide the next frequency + * by using the new frequency of parent devfreq device + * using governors except for passive governor. + * If the devfreq device has the specific method to decide + * the next frequency, should use this callback. + * @this: the devfreq instance of own device. + * @nb: the notifier block for DEVFREQ_TRANSITION_NOTIFIER list + * + * The devfreq_passive_data have to set the devfreq instance of parent + * device with governors except for the passive governor. But, don't need to + * initialize the 'this' and 'nb' field because the devfreq core will handle + * them. + */ +struct devfreq_passive_data { + /* Should set the devfreq instance of parent device */ + struct devfreq *parent; + + /* Optional callback to decide the next frequency of passvice device */ + int (*get_target_freq)(struct devfreq *this, unsigned long *freq); + + /* For passive governor's internal use. Don't need to set them */ + struct devfreq *this; + struct notifier_block nb; +}; +#endif + #else /* !CONFIG_PM_DEVFREQ */ static inline struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, -- cgit v1.2.3