Lines Matching +full:devfreq +full:- +full:event

1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/drivers/devfreq/governor_passive.c
16 #include <linux/devfreq.h>
29 list_for_each_entry(parent_cpu_data, &p_data->cpu_data_list, node) in get_parent_cpu_data()
30 if (parent_cpu_data->first_cpu == cpumask_first(policy->related_cpus)) in get_parent_cpu_data()
40 list_for_each_entry_safe(parent_cpu_data, tmp, &p_data->cpu_data_list, node) { in delete_parent_cpu_data()
41 list_del(&parent_cpu_data->node); in delete_parent_cpu_data()
43 if (parent_cpu_data->opp_table) in delete_parent_cpu_data()
44 dev_pm_opp_put_opp_table(parent_cpu_data->opp_table); in delete_parent_cpu_data()
77 static int get_target_freq_with_cpufreq(struct devfreq *devfreq, in get_target_freq_with_cpufreq() argument
81 (struct devfreq_passive_data *)devfreq->data; in get_target_freq_with_cpufreq()
92 ret = -EINVAL; in get_target_freq_with_cpufreq()
103 cpu_cur = parent_cpu_data->cur_freq * HZ_PER_KHZ; in get_target_freq_with_cpufreq()
104 freq = get_target_freq_by_required_opp(parent_cpu_data->dev, in get_target_freq_with_cpufreq()
105 parent_cpu_data->opp_table, in get_target_freq_with_cpufreq()
106 devfreq->opp_table, &cpu_cur); in get_target_freq_with_cpufreq()
114 devfreq_get_freq_range(devfreq, &dev_min, &dev_max); in get_target_freq_with_cpufreq()
116 cpu_min = parent_cpu_data->min_freq; in get_target_freq_with_cpufreq()
117 cpu_max = parent_cpu_data->max_freq; in get_target_freq_with_cpufreq()
118 cpu_cur = parent_cpu_data->cur_freq; in get_target_freq_with_cpufreq()
120 cpu_percent = ((cpu_cur - cpu_min) * 100) / (cpu_max - cpu_min); in get_target_freq_with_cpufreq()
121 freq = dev_min + mult_frac(dev_max - dev_min, cpu_percent, 100); in get_target_freq_with_cpufreq()
130 static int get_target_freq_with_devfreq(struct devfreq *devfreq, in get_target_freq_with_devfreq() argument
134 = (struct devfreq_passive_data *)devfreq->data; in get_target_freq_with_devfreq()
135 struct devfreq *parent_devfreq = (struct devfreq *)p_data->parent; in get_target_freq_with_devfreq()
140 child_freq = get_target_freq_by_required_opp(parent_devfreq->dev.parent, in get_target_freq_with_devfreq()
141 parent_devfreq->opp_table, in get_target_freq_with_devfreq()
142 devfreq->opp_table, freq); in get_target_freq_with_devfreq()
147 for (i = 0; i < parent_devfreq->max_state; i++) in get_target_freq_with_devfreq()
148 if (parent_devfreq->freq_table[i] == *freq) in get_target_freq_with_devfreq()
151 if (i == parent_devfreq->max_state) in get_target_freq_with_devfreq()
152 return -EINVAL; in get_target_freq_with_devfreq()
154 if (i < devfreq->max_state) { in get_target_freq_with_devfreq()
155 child_freq = devfreq->freq_table[i]; in get_target_freq_with_devfreq()
157 count = devfreq->max_state; in get_target_freq_with_devfreq()
158 child_freq = devfreq->freq_table[count - 1]; in get_target_freq_with_devfreq()
167 static int devfreq_passive_get_target_freq(struct devfreq *devfreq, in devfreq_passive_get_target_freq() argument
171 (struct devfreq_passive_data *)devfreq->data; in devfreq_passive_get_target_freq()
175 return -EINVAL; in devfreq_passive_get_target_freq()
178 * If the devfreq device with passive governor has the specific method in devfreq_passive_get_target_freq()
182 if (p_data->get_target_freq) in devfreq_passive_get_target_freq()
183 return p_data->get_target_freq(devfreq, freq); in devfreq_passive_get_target_freq()
185 switch (p_data->parent_type) { in devfreq_passive_get_target_freq()
187 ret = get_target_freq_with_devfreq(devfreq, freq); in devfreq_passive_get_target_freq()
190 ret = get_target_freq_with_cpufreq(devfreq, freq); in devfreq_passive_get_target_freq()
193 ret = -EINVAL; in devfreq_passive_get_target_freq()
194 dev_err(&devfreq->dev, "Invalid parent type\n"); in devfreq_passive_get_target_freq()
202 unsigned long event, void *ptr) in cpufreq_passive_notifier_call() argument
206 struct devfreq *devfreq = (struct devfreq *)p_data->this; in cpufreq_passive_notifier_call() local
212 if (event != CPUFREQ_POSTCHANGE || !freqs) in cpufreq_passive_notifier_call()
215 parent_cpu_data = get_parent_cpu_data(p_data, freqs->policy); in cpufreq_passive_notifier_call()
216 if (!parent_cpu_data || parent_cpu_data->cur_freq == freqs->new) in cpufreq_passive_notifier_call()
219 cur_freq = parent_cpu_data->cur_freq; in cpufreq_passive_notifier_call()
220 parent_cpu_data->cur_freq = freqs->new; in cpufreq_passive_notifier_call()
222 mutex_lock(&devfreq->lock); in cpufreq_passive_notifier_call()
223 ret = devfreq_update_target(devfreq, freqs->new); in cpufreq_passive_notifier_call()
224 mutex_unlock(&devfreq->lock); in cpufreq_passive_notifier_call()
226 parent_cpu_data->cur_freq = cur_freq; in cpufreq_passive_notifier_call()
227 dev_err(&devfreq->dev, "failed to update the frequency.\n"); in cpufreq_passive_notifier_call()
234 static int cpufreq_passive_unregister_notifier(struct devfreq *devfreq) in cpufreq_passive_unregister_notifier() argument
237 = (struct devfreq_passive_data *)devfreq->data; in cpufreq_passive_unregister_notifier()
240 if (p_data->nb.notifier_call) { in cpufreq_passive_unregister_notifier()
241 ret = cpufreq_unregister_notifier(&p_data->nb, in cpufreq_passive_unregister_notifier()
252 static int cpufreq_passive_register_notifier(struct devfreq *devfreq) in cpufreq_passive_register_notifier() argument
255 = (struct devfreq_passive_data *)devfreq->data; in cpufreq_passive_register_notifier()
256 struct device *dev = devfreq->dev.parent; in cpufreq_passive_register_notifier()
264 p_data->cpu_data_list in cpufreq_passive_register_notifier()
265 = (struct list_head)LIST_HEAD_INIT(p_data->cpu_data_list); in cpufreq_passive_register_notifier()
267 p_data->nb.notifier_call = cpufreq_passive_notifier_call; in cpufreq_passive_register_notifier()
268 ret = cpufreq_register_notifier(&p_data->nb, CPUFREQ_TRANSITION_NOTIFIER); in cpufreq_passive_register_notifier()
271 p_data->nb.notifier_call = NULL; in cpufreq_passive_register_notifier()
278 ret = -EPROBE_DEFER; in cpufreq_passive_register_notifier()
291 ret = -ENOMEM; in cpufreq_passive_register_notifier()
298 ret = -ENODEV; in cpufreq_passive_register_notifier()
309 parent_cpu_data->dev = cpu_dev; in cpufreq_passive_register_notifier()
310 parent_cpu_data->opp_table = opp_table; in cpufreq_passive_register_notifier()
311 parent_cpu_data->first_cpu = cpumask_first(policy->related_cpus); in cpufreq_passive_register_notifier()
312 parent_cpu_data->cur_freq = policy->cur; in cpufreq_passive_register_notifier()
313 parent_cpu_data->min_freq = policy->cpuinfo.min_freq; in cpufreq_passive_register_notifier()
314 parent_cpu_data->max_freq = policy->cpuinfo.max_freq; in cpufreq_passive_register_notifier()
316 list_add_tail(&parent_cpu_data->node, &p_data->cpu_data_list); in cpufreq_passive_register_notifier()
320 mutex_lock(&devfreq->lock); in cpufreq_passive_register_notifier()
321 ret = devfreq_update_target(devfreq, 0L); in cpufreq_passive_register_notifier()
322 mutex_unlock(&devfreq->lock); in cpufreq_passive_register_notifier()
338 unsigned long event, void *ptr) in devfreq_passive_notifier_call() argument
342 struct devfreq *devfreq = (struct devfreq *)data->this; in devfreq_passive_notifier_call() local
343 struct devfreq *parent = (struct devfreq *)data->parent; in devfreq_passive_notifier_call()
345 unsigned long freq = freqs->new; in devfreq_passive_notifier_call()
348 mutex_lock_nested(&devfreq->lock, SINGLE_DEPTH_NESTING); in devfreq_passive_notifier_call()
349 switch (event) { in devfreq_passive_notifier_call()
351 if (parent->previous_freq > freq) in devfreq_passive_notifier_call()
352 ret = devfreq_update_target(devfreq, freq); in devfreq_passive_notifier_call()
356 if (parent->previous_freq < freq) in devfreq_passive_notifier_call()
357 ret = devfreq_update_target(devfreq, freq); in devfreq_passive_notifier_call()
360 mutex_unlock(&devfreq->lock); in devfreq_passive_notifier_call()
363 dev_warn(&devfreq->dev, in devfreq_passive_notifier_call()
364 "failed to update devfreq using passive governor\n"); in devfreq_passive_notifier_call()
369 static int devfreq_passive_unregister_notifier(struct devfreq *devfreq) in devfreq_passive_unregister_notifier() argument
372 = (struct devfreq_passive_data *)devfreq->data; in devfreq_passive_unregister_notifier()
373 struct devfreq *parent = (struct devfreq *)p_data->parent; in devfreq_passive_unregister_notifier()
374 struct notifier_block *nb = &p_data->nb; in devfreq_passive_unregister_notifier()
379 static int devfreq_passive_register_notifier(struct devfreq *devfreq) in devfreq_passive_register_notifier() argument
382 = (struct devfreq_passive_data *)devfreq->data; in devfreq_passive_register_notifier()
383 struct devfreq *parent = (struct devfreq *)p_data->parent; in devfreq_passive_register_notifier()
384 struct notifier_block *nb = &p_data->nb; in devfreq_passive_register_notifier()
387 return -EPROBE_DEFER; in devfreq_passive_register_notifier()
389 nb->notifier_call = devfreq_passive_notifier_call; in devfreq_passive_register_notifier()
393 static int devfreq_passive_event_handler(struct devfreq *devfreq, in devfreq_passive_event_handler() argument
394 unsigned int event, void *data) in devfreq_passive_event_handler() argument
397 = (struct devfreq_passive_data *)devfreq->data; in devfreq_passive_event_handler()
401 return -EINVAL; in devfreq_passive_event_handler()
403 p_data->this = devfreq; in devfreq_passive_event_handler()
405 switch (event) { in devfreq_passive_event_handler()
407 if (p_data->parent_type == DEVFREQ_PARENT_DEV) in devfreq_passive_event_handler()
408 ret = devfreq_passive_register_notifier(devfreq); in devfreq_passive_event_handler()
409 else if (p_data->parent_type == CPUFREQ_PARENT_DEV) in devfreq_passive_event_handler()
410 ret = cpufreq_passive_register_notifier(devfreq); in devfreq_passive_event_handler()
413 if (p_data->parent_type == DEVFREQ_PARENT_DEV) in devfreq_passive_event_handler()
414 WARN_ON(devfreq_passive_unregister_notifier(devfreq)); in devfreq_passive_event_handler()
415 else if (p_data->parent_type == CPUFREQ_PARENT_DEV) in devfreq_passive_event_handler()
416 WARN_ON(cpufreq_passive_unregister_notifier(devfreq)); in devfreq_passive_event_handler()
450 MODULE_DESCRIPTION("DEVFREQ Passive governor");