Lines Matching refs:genpd

30 #define GENPD_DEV_CALLBACK(genpd, type, callback, dev)		\  argument
35 __routine = genpd->dev_ops.callback; \
46 void (*lock)(struct generic_pm_domain *genpd);
47 void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
48 int (*lock_interruptible)(struct generic_pm_domain *genpd);
49 void (*unlock)(struct generic_pm_domain *genpd);
52 static void genpd_lock_mtx(struct generic_pm_domain *genpd) in genpd_lock_mtx() argument
54 mutex_lock(&genpd->mlock); in genpd_lock_mtx()
57 static void genpd_lock_nested_mtx(struct generic_pm_domain *genpd, in genpd_lock_nested_mtx() argument
60 mutex_lock_nested(&genpd->mlock, depth); in genpd_lock_nested_mtx()
63 static int genpd_lock_interruptible_mtx(struct generic_pm_domain *genpd) in genpd_lock_interruptible_mtx() argument
65 return mutex_lock_interruptible(&genpd->mlock); in genpd_lock_interruptible_mtx()
68 static void genpd_unlock_mtx(struct generic_pm_domain *genpd) in genpd_unlock_mtx() argument
70 return mutex_unlock(&genpd->mlock); in genpd_unlock_mtx()
80 static void genpd_lock_spin(struct generic_pm_domain *genpd) in genpd_lock_spin() argument
81 __acquires(&genpd->slock) in genpd_lock_spin()
85 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_spin()
86 genpd->lock_flags = flags; in genpd_lock_spin()
89 static void genpd_lock_nested_spin(struct generic_pm_domain *genpd, in genpd_lock_nested_spin() argument
91 __acquires(&genpd->slock) in genpd_lock_nested_spin()
95 spin_lock_irqsave_nested(&genpd->slock, flags, depth); in genpd_lock_nested_spin()
96 genpd->lock_flags = flags; in genpd_lock_nested_spin()
99 static int genpd_lock_interruptible_spin(struct generic_pm_domain *genpd) in genpd_lock_interruptible_spin() argument
100 __acquires(&genpd->slock) in genpd_lock_interruptible_spin()
104 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_interruptible_spin()
105 genpd->lock_flags = flags; in genpd_lock_interruptible_spin()
109 static void genpd_unlock_spin(struct generic_pm_domain *genpd) in genpd_unlock_spin() argument
110 __releases(&genpd->slock) in genpd_unlock_spin()
112 spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags); in genpd_unlock_spin()
127 #define genpd_status_on(genpd) (genpd->status == GENPD_STATE_ON) argument
128 #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) argument
129 #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) argument
130 #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP) argument
131 #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN) argument
132 #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON) argument
135 const struct generic_pm_domain *genpd) in irq_safe_dev_in_sleep_domain() argument
139 ret = pm_runtime_is_irq_safe(dev) && !genpd_is_irq_safe(genpd); in irq_safe_dev_in_sleep_domain()
146 if (genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) in irq_safe_dev_in_sleep_domain()
151 genpd->name); in irq_safe_dev_in_sleep_domain()
188 static int genpd_stop_dev(const struct generic_pm_domain *genpd, in genpd_stop_dev() argument
191 return GENPD_DEV_CALLBACK(genpd, int, stop, dev); in genpd_stop_dev()
194 static int genpd_start_dev(const struct generic_pm_domain *genpd, in genpd_start_dev() argument
197 return GENPD_DEV_CALLBACK(genpd, int, start, dev); in genpd_start_dev()
200 static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) in genpd_sd_counter_dec() argument
204 if (!WARN_ON(atomic_read(&genpd->sd_count) == 0)) in genpd_sd_counter_dec()
205 ret = !!atomic_dec_and_test(&genpd->sd_count); in genpd_sd_counter_dec()
210 static void genpd_sd_counter_inc(struct generic_pm_domain *genpd) in genpd_sd_counter_inc() argument
212 atomic_inc(&genpd->sd_count); in genpd_sd_counter_inc()
219 static void genpd_debug_add(struct generic_pm_domain *genpd);
221 static void genpd_debug_remove(struct generic_pm_domain *genpd) in genpd_debug_remove() argument
226 debugfs_lookup_and_remove(genpd->name, genpd_debugfs_dir); in genpd_debug_remove()
229 static void genpd_update_accounting(struct generic_pm_domain *genpd) in genpd_update_accounting() argument
234 if (now <= genpd->accounting_time) in genpd_update_accounting()
237 delta = now - genpd->accounting_time; in genpd_update_accounting()
244 if (genpd->status == GENPD_STATE_ON) in genpd_update_accounting()
245 genpd->states[genpd->state_idx].idle_time += delta; in genpd_update_accounting()
247 genpd->on_time += delta; in genpd_update_accounting()
249 genpd->accounting_time = now; in genpd_update_accounting()
252 static inline void genpd_debug_add(struct generic_pm_domain *genpd) {} in genpd_debug_add() argument
253 static inline void genpd_debug_remove(struct generic_pm_domain *genpd) {} in genpd_debug_remove() argument
254 static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {} in genpd_update_accounting() argument
257 static int _genpd_reeval_performance_state(struct generic_pm_domain *genpd, in _genpd_reeval_performance_state() argument
265 if (state == genpd->performance_state) in _genpd_reeval_performance_state()
269 if (state > genpd->performance_state) in _genpd_reeval_performance_state()
273 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in _genpd_reeval_performance_state()
294 list_for_each_entry(link, &genpd->parent_links, parent_node) { in _genpd_reeval_performance_state()
302 static int genpd_xlate_performance_state(struct generic_pm_domain *genpd, in genpd_xlate_performance_state() argument
309 return dev_pm_opp_xlate_performance_state(genpd->opp_table, in genpd_xlate_performance_state()
314 static int _genpd_set_performance_state(struct generic_pm_domain *genpd, in _genpd_set_performance_state() argument
321 if (state == genpd->performance_state) in _genpd_set_performance_state()
325 list_for_each_entry(link, &genpd->child_links, child_node) { in _genpd_set_performance_state()
329 ret = genpd_xlate_performance_state(genpd, parent, state); in _genpd_set_performance_state()
351 if (genpd->set_performance_state) { in _genpd_set_performance_state()
352 ret = genpd->set_performance_state(genpd, state); in _genpd_set_performance_state()
357 genpd->performance_state = state; in _genpd_set_performance_state()
362 list_for_each_entry_continue_reverse(link, &genpd->child_links, in _genpd_set_performance_state()
386 struct generic_pm_domain *genpd = dev_to_genpd(dev); in genpd_set_performance_state() local
396 state = _genpd_reeval_performance_state(genpd, state); in genpd_set_performance_state()
398 ret = _genpd_set_performance_state(genpd, state, 0); in genpd_set_performance_state()
439 struct generic_pm_domain *genpd; in dev_pm_genpd_set_performance_state() local
442 genpd = dev_to_genpd_safe(dev); in dev_pm_genpd_set_performance_state()
443 if (!genpd) in dev_pm_genpd_set_performance_state()
450 genpd_lock(genpd); in dev_pm_genpd_set_performance_state()
458 genpd_unlock(genpd); in dev_pm_genpd_set_performance_state()
481 struct generic_pm_domain *genpd; in dev_pm_genpd_set_next_wakeup() local
484 genpd = dev_to_genpd_safe(dev); in dev_pm_genpd_set_next_wakeup()
485 if (!genpd) in dev_pm_genpd_set_next_wakeup()
506 struct generic_pm_domain *genpd; in dev_pm_genpd_get_next_hrtimer() local
508 genpd = dev_to_genpd_safe(dev); in dev_pm_genpd_get_next_hrtimer()
509 if (!genpd) in dev_pm_genpd_get_next_hrtimer()
512 if (genpd->gd) in dev_pm_genpd_get_next_hrtimer()
513 return genpd->gd->next_hrtimer; in dev_pm_genpd_get_next_hrtimer()
532 struct generic_pm_domain *genpd; in dev_pm_genpd_synced_poweroff() local
534 genpd = dev_to_genpd_safe(dev); in dev_pm_genpd_synced_poweroff()
535 if (!genpd) in dev_pm_genpd_synced_poweroff()
538 genpd_lock(genpd); in dev_pm_genpd_synced_poweroff()
539 genpd->synced_poweroff = true; in dev_pm_genpd_synced_poweroff()
540 genpd_unlock(genpd); in dev_pm_genpd_synced_poweroff()
544 static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) in _genpd_power_on() argument
546 unsigned int state_idx = genpd->state_idx; in _genpd_power_on()
552 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_on()
559 if (!genpd->power_on) in _genpd_power_on()
562 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode; in _genpd_power_on()
564 ret = genpd->power_on(genpd); in _genpd_power_on()
572 ret = genpd->power_on(genpd); in _genpd_power_on()
577 if (elapsed_ns <= genpd->states[state_idx].power_on_latency_ns) in _genpd_power_on()
580 genpd->states[state_idx].power_on_latency_ns = elapsed_ns; in _genpd_power_on()
581 genpd->gd->max_off_time_changed = true; in _genpd_power_on()
583 genpd->name, "on", elapsed_ns); in _genpd_power_on()
586 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_on()
587 genpd->synced_poweroff = false; in _genpd_power_on()
590 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_on()
595 static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed) in _genpd_power_off() argument
597 unsigned int state_idx = genpd->state_idx; in _genpd_power_off()
603 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_off()
610 if (!genpd->power_off) in _genpd_power_off()
613 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode; in _genpd_power_off()
615 ret = genpd->power_off(genpd); in _genpd_power_off()
623 ret = genpd->power_off(genpd); in _genpd_power_off()
628 if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) in _genpd_power_off()
631 genpd->states[state_idx].power_off_latency_ns = elapsed_ns; in _genpd_power_off()
632 genpd->gd->max_off_time_changed = true; in _genpd_power_off()
634 genpd->name, "off", elapsed_ns); in _genpd_power_off()
637 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_off()
641 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_off()
652 static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) in genpd_queue_power_off_work() argument
654 queue_work(pm_wq, &genpd->power_off_work); in genpd_queue_power_off_work()
669 static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, in genpd_power_off() argument
682 if (!genpd_status_on(genpd) || genpd->prepared_count > 0) in genpd_power_off()
690 if (genpd_is_always_on(genpd) || in genpd_power_off()
691 genpd_is_rpm_always_on(genpd) || in genpd_power_off()
692 atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
701 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_power_off()
707 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in genpd_power_off()
713 irq_safe_dev_in_sleep_domain(pdd->dev, genpd)) in genpd_power_off()
720 if (genpd->gov && genpd->gov->power_down_ok) { in genpd_power_off()
721 if (!genpd->gov->power_down_ok(&genpd->domain)) in genpd_power_off()
726 if (!genpd->gov) in genpd_power_off()
727 genpd->state_idx = 0; in genpd_power_off()
730 if (atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
733 ret = _genpd_power_off(genpd, true); in genpd_power_off()
735 genpd->states[genpd->state_idx].rejected++; in genpd_power_off()
739 genpd->status = GENPD_STATE_OFF; in genpd_power_off()
740 genpd_update_accounting(genpd); in genpd_power_off()
741 genpd->states[genpd->state_idx].usage++; in genpd_power_off()
743 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_off()
761 static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) in genpd_power_on() argument
766 if (genpd_status_on(genpd)) in genpd_power_on()
774 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_on()
789 ret = _genpd_power_on(genpd, true); in genpd_power_on()
793 genpd->status = GENPD_STATE_ON; in genpd_power_on()
794 genpd_update_accounting(genpd); in genpd_power_on()
800 &genpd->child_links, in genpd_power_on()
813 struct generic_pm_domain *genpd = dev_to_genpd(dev); in genpd_dev_pm_start() local
815 return genpd_start_dev(genpd, dev); in genpd_dev_pm_start()
828 struct generic_pm_domain *genpd = ERR_PTR(-ENODATA); in genpd_dev_pm_qos_notifier() local
840 genpd = dev_to_genpd(dev); in genpd_dev_pm_qos_notifier()
846 if (!IS_ERR(genpd)) { in genpd_dev_pm_qos_notifier()
847 genpd_lock(genpd); in genpd_dev_pm_qos_notifier()
848 genpd->gd->max_off_time_changed = true; in genpd_dev_pm_qos_notifier()
849 genpd_unlock(genpd); in genpd_dev_pm_qos_notifier()
866 struct generic_pm_domain *genpd; in genpd_power_off_work_fn() local
868 genpd = container_of(work, struct generic_pm_domain, power_off_work); in genpd_power_off_work_fn()
870 genpd_lock(genpd); in genpd_power_off_work_fn()
871 genpd_power_off(genpd, false, 0); in genpd_power_off_work_fn()
872 genpd_unlock(genpd); in genpd_power_off_work_fn()
931 struct generic_pm_domain *genpd; in genpd_runtime_suspend() local
942 genpd = dev_to_genpd(dev); in genpd_runtime_suspend()
943 if (IS_ERR(genpd)) in genpd_runtime_suspend()
952 suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL; in genpd_runtime_suspend()
964 ret = genpd_stop_dev(genpd, dev); in genpd_runtime_suspend()
977 genpd->gd->max_off_time_changed = true; in genpd_runtime_suspend()
986 if (irq_safe_dev_in_sleep_domain(dev, genpd)) in genpd_runtime_suspend()
989 genpd_lock(genpd); in genpd_runtime_suspend()
990 genpd_power_off(genpd, true, 0); in genpd_runtime_suspend()
992 genpd_unlock(genpd); in genpd_runtime_suspend()
1007 struct generic_pm_domain *genpd; in genpd_runtime_resume() local
1017 genpd = dev_to_genpd(dev); in genpd_runtime_resume()
1018 if (IS_ERR(genpd)) in genpd_runtime_resume()
1025 if (irq_safe_dev_in_sleep_domain(dev, genpd)) in genpd_runtime_resume()
1028 genpd_lock(genpd); in genpd_runtime_resume()
1030 ret = genpd_power_on(genpd, 0); in genpd_runtime_resume()
1031 genpd_unlock(genpd); in genpd_runtime_resume()
1041 ret = genpd_start_dev(genpd, dev); in genpd_runtime_resume()
1056 genpd->gd->max_off_time_changed = true; in genpd_runtime_resume()
1064 genpd_stop_dev(genpd, dev); in genpd_runtime_resume()
1066 if (!pm_runtime_is_irq_safe(dev) || genpd_is_irq_safe(genpd)) { in genpd_runtime_resume()
1067 genpd_lock(genpd); in genpd_runtime_resume()
1068 genpd_power_off(genpd, true, 0); in genpd_runtime_resume()
1070 genpd_unlock(genpd); in genpd_runtime_resume()
1089 struct generic_pm_domain *genpd; in genpd_power_off_unused() local
1098 list_for_each_entry(genpd, &gpd_list, gpd_list_node) in genpd_power_off_unused()
1099 genpd_queue_power_off_work(genpd); in genpd_power_off_unused()
1122 static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, in genpd_sync_power_off() argument
1127 if (!genpd_status_on(genpd) || genpd_is_always_on(genpd)) in genpd_sync_power_off()
1130 if (genpd->suspended_count != genpd->device_count in genpd_sync_power_off()
1131 || atomic_read(&genpd->sd_count) > 0) in genpd_sync_power_off()
1135 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_sync_power_off()
1142 genpd->state_idx = genpd->state_count - 1; in genpd_sync_power_off()
1143 if (_genpd_power_off(genpd, false)) in genpd_sync_power_off()
1146 genpd->status = GENPD_STATE_OFF; in genpd_sync_power_off()
1148 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_off()
1171 static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, in genpd_sync_power_on() argument
1176 if (genpd_status_on(genpd)) in genpd_sync_power_on()
1179 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_on()
1191 _genpd_power_on(genpd, false); in genpd_sync_power_on()
1192 genpd->status = GENPD_STATE_ON; in genpd_sync_power_on()
1206 struct generic_pm_domain *genpd; in genpd_prepare() local
1211 genpd = dev_to_genpd(dev); in genpd_prepare()
1212 if (IS_ERR(genpd)) in genpd_prepare()
1215 genpd_lock(genpd); in genpd_prepare()
1217 if (genpd->prepared_count++ == 0) in genpd_prepare()
1218 genpd->suspended_count = 0; in genpd_prepare()
1220 genpd_unlock(genpd); in genpd_prepare()
1224 genpd_lock(genpd); in genpd_prepare()
1226 genpd->prepared_count--; in genpd_prepare()
1228 genpd_unlock(genpd); in genpd_prepare()
1249 struct generic_pm_domain *genpd; in genpd_finish_suspend() local
1252 genpd = dev_to_genpd(dev); in genpd_finish_suspend()
1253 if (IS_ERR(genpd)) in genpd_finish_suspend()
1260 if (device_wakeup_path(dev) && genpd_is_active_wakeup(genpd)) in genpd_finish_suspend()
1263 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_suspend()
1265 ret = genpd_stop_dev(genpd, dev); in genpd_finish_suspend()
1272 genpd_lock(genpd); in genpd_finish_suspend()
1273 genpd->suspended_count++; in genpd_finish_suspend()
1274 genpd_sync_power_off(genpd, true, 0); in genpd_finish_suspend()
1275 genpd_unlock(genpd); in genpd_finish_suspend()
1306 struct generic_pm_domain *genpd; in genpd_finish_resume() local
1311 genpd = dev_to_genpd(dev); in genpd_finish_resume()
1312 if (IS_ERR(genpd)) in genpd_finish_resume()
1315 if (device_wakeup_path(dev) && genpd_is_active_wakeup(genpd)) in genpd_finish_resume()
1318 genpd_lock(genpd); in genpd_finish_resume()
1319 genpd_sync_power_on(genpd, true, 0); in genpd_finish_resume()
1320 genpd->suspended_count--; in genpd_finish_resume()
1321 genpd_unlock(genpd); in genpd_finish_resume()
1323 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_resume()
1325 ret = genpd_start_dev(genpd, dev); in genpd_finish_resume()
1420 struct generic_pm_domain *genpd; in genpd_complete() local
1424 genpd = dev_to_genpd(dev); in genpd_complete()
1425 if (IS_ERR(genpd)) in genpd_complete()
1430 genpd_lock(genpd); in genpd_complete()
1432 genpd->prepared_count--; in genpd_complete()
1433 if (!genpd->prepared_count) in genpd_complete()
1434 genpd_queue_power_off_work(genpd); in genpd_complete()
1436 genpd_unlock(genpd); in genpd_complete()
1441 struct generic_pm_domain *genpd; in genpd_switch_state() local
1444 genpd = dev_to_genpd_safe(dev); in genpd_switch_state()
1445 if (!genpd) in genpd_switch_state()
1448 use_lock = genpd_is_irq_safe(genpd); in genpd_switch_state()
1451 genpd_lock(genpd); in genpd_switch_state()
1454 genpd->suspended_count++; in genpd_switch_state()
1455 genpd_sync_power_off(genpd, use_lock, 0); in genpd_switch_state()
1457 genpd_sync_power_on(genpd, use_lock, 0); in genpd_switch_state()
1458 genpd->suspended_count--; in genpd_switch_state()
1462 genpd_unlock(genpd); in genpd_switch_state()
1577 static void genpd_update_cpumask(struct generic_pm_domain *genpd, in genpd_update_cpumask() argument
1582 if (!genpd_is_cpu_domain(genpd)) in genpd_update_cpumask()
1585 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_update_cpumask()
1594 cpumask_set_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1596 cpumask_clear_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1599 static void genpd_set_cpumask(struct generic_pm_domain *genpd, int cpu) in genpd_set_cpumask() argument
1602 genpd_update_cpumask(genpd, cpu, true, 0); in genpd_set_cpumask()
1605 static void genpd_clear_cpumask(struct generic_pm_domain *genpd, int cpu) in genpd_clear_cpumask() argument
1608 genpd_update_cpumask(genpd, cpu, false, 0); in genpd_clear_cpumask()
1611 static int genpd_get_cpu(struct generic_pm_domain *genpd, struct device *dev) in genpd_get_cpu() argument
1615 if (!genpd_is_cpu_domain(genpd)) in genpd_get_cpu()
1626 static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, in genpd_add_device() argument
1629 struct genpd_governor_data *gd = genpd->gd; in genpd_add_device()
1639 gpd_data->cpu = genpd_get_cpu(genpd, base_dev); in genpd_add_device()
1641 ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; in genpd_add_device()
1645 genpd_lock(genpd); in genpd_add_device()
1647 genpd_set_cpumask(genpd, gpd_data->cpu); in genpd_add_device()
1648 dev_pm_domain_set(dev, &genpd->domain); in genpd_add_device()
1650 genpd->device_count++; in genpd_add_device()
1654 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); in genpd_add_device()
1656 genpd_unlock(genpd); in genpd_add_device()
1672 int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) in pm_genpd_add_device() argument
1676 if (!genpd || !dev) in pm_genpd_add_device()
1680 ret = genpd_add_device(genpd, dev, dev); in pm_genpd_add_device()
1687 static int genpd_remove_device(struct generic_pm_domain *genpd, in genpd_remove_device() argument
1701 genpd_lock(genpd); in genpd_remove_device()
1703 if (genpd->prepared_count > 0) { in genpd_remove_device()
1708 genpd->device_count--; in genpd_remove_device()
1709 if (genpd->gd) in genpd_remove_device()
1710 genpd->gd->max_off_time_changed = true; in genpd_remove_device()
1712 genpd_clear_cpumask(genpd, gpd_data->cpu); in genpd_remove_device()
1717 genpd_unlock(genpd); in genpd_remove_device()
1719 if (genpd->detach_dev) in genpd_remove_device()
1720 genpd->detach_dev(genpd, dev); in genpd_remove_device()
1727 genpd_unlock(genpd); in genpd_remove_device()
1739 struct generic_pm_domain *genpd = dev_to_genpd_safe(dev); in pm_genpd_remove_device() local
1741 if (!genpd) in pm_genpd_remove_device()
1744 return genpd_remove_device(genpd, dev); in pm_genpd_remove_device()
1765 struct generic_pm_domain *genpd; in dev_pm_genpd_add_notifier() local
1769 genpd = dev_to_genpd_safe(dev); in dev_pm_genpd_add_notifier()
1770 if (!genpd) in dev_pm_genpd_add_notifier()
1781 genpd_lock(genpd); in dev_pm_genpd_add_notifier()
1782 ret = raw_notifier_chain_register(&genpd->power_notifiers, nb); in dev_pm_genpd_add_notifier()
1783 genpd_unlock(genpd); in dev_pm_genpd_add_notifier()
1787 genpd->name); in dev_pm_genpd_add_notifier()
1811 struct generic_pm_domain *genpd; in dev_pm_genpd_remove_notifier() local
1815 genpd = dev_to_genpd_safe(dev); in dev_pm_genpd_remove_notifier()
1816 if (!genpd) in dev_pm_genpd_remove_notifier()
1827 genpd_lock(genpd); in dev_pm_genpd_remove_notifier()
1828 ret = raw_notifier_chain_unregister(&genpd->power_notifiers, in dev_pm_genpd_remove_notifier()
1830 genpd_unlock(genpd); in dev_pm_genpd_remove_notifier()
1834 genpd->name); in dev_pm_genpd_remove_notifier()
1843 static int genpd_add_subdomain(struct generic_pm_domain *genpd, in genpd_add_subdomain() argument
1849 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain) in genpd_add_subdomain()
1850 || genpd == subdomain) in genpd_add_subdomain()
1858 if (!genpd_is_irq_safe(genpd) && genpd_is_irq_safe(subdomain)) { in genpd_add_subdomain()
1860 genpd->name, subdomain->name); in genpd_add_subdomain()
1869 genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); in genpd_add_subdomain()
1871 if (!genpd_status_on(genpd) && genpd_status_on(subdomain)) { in genpd_add_subdomain()
1876 list_for_each_entry(itr, &genpd->parent_links, parent_node) { in genpd_add_subdomain()
1877 if (itr->child == subdomain && itr->parent == genpd) { in genpd_add_subdomain()
1883 link->parent = genpd; in genpd_add_subdomain()
1884 list_add_tail(&link->parent_node, &genpd->parent_links); in genpd_add_subdomain()
1888 genpd_sd_counter_inc(genpd); in genpd_add_subdomain()
1891 genpd_unlock(genpd); in genpd_add_subdomain()
1903 int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, in pm_genpd_add_subdomain() argument
1909 ret = genpd_add_subdomain(genpd, subdomain); in pm_genpd_add_subdomain()
1921 int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, in pm_genpd_remove_subdomain() argument
1927 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) in pm_genpd_remove_subdomain()
1931 genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); in pm_genpd_remove_subdomain()
1935 genpd->name, subdomain->name); in pm_genpd_remove_subdomain()
1940 list_for_each_entry_safe(link, l, &genpd->parent_links, parent_node) { in pm_genpd_remove_subdomain()
1948 genpd_sd_counter_dec(genpd); in pm_genpd_remove_subdomain()
1955 genpd_unlock(genpd); in pm_genpd_remove_subdomain()
1968 static int genpd_set_default_power_state(struct generic_pm_domain *genpd) in genpd_set_default_power_state() argument
1976 genpd->states = state; in genpd_set_default_power_state()
1977 genpd->state_count = 1; in genpd_set_default_power_state()
1978 genpd->free_states = genpd_free_default_power_state; in genpd_set_default_power_state()
1983 static int genpd_alloc_data(struct generic_pm_domain *genpd) in genpd_alloc_data() argument
1988 if (genpd_is_cpu_domain(genpd) && in genpd_alloc_data()
1989 !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL)) in genpd_alloc_data()
1992 if (genpd->gov) { in genpd_alloc_data()
2006 if (genpd->state_count == 0) { in genpd_alloc_data()
2007 ret = genpd_set_default_power_state(genpd); in genpd_alloc_data()
2012 genpd->gd = gd; in genpd_alloc_data()
2016 if (genpd_is_cpu_domain(genpd)) in genpd_alloc_data()
2017 free_cpumask_var(genpd->cpus); in genpd_alloc_data()
2022 static void genpd_free_data(struct generic_pm_domain *genpd) in genpd_free_data() argument
2024 put_device(&genpd->dev); in genpd_free_data()
2025 if (genpd_is_cpu_domain(genpd)) in genpd_free_data()
2026 free_cpumask_var(genpd->cpus); in genpd_free_data()
2027 if (genpd->free_states) in genpd_free_data()
2028 genpd->free_states(genpd->states, genpd->state_count); in genpd_free_data()
2029 kfree(genpd->gd); in genpd_free_data()
2032 static void genpd_lock_init(struct generic_pm_domain *genpd) in genpd_lock_init() argument
2034 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) { in genpd_lock_init()
2035 spin_lock_init(&genpd->slock); in genpd_lock_init()
2036 genpd->lock_ops = &genpd_spin_ops; in genpd_lock_init()
2038 mutex_init(&genpd->mlock); in genpd_lock_init()
2039 genpd->lock_ops = &genpd_mtx_ops; in genpd_lock_init()
2051 int pm_genpd_init(struct generic_pm_domain *genpd, in pm_genpd_init() argument
2056 if (IS_ERR_OR_NULL(genpd)) in pm_genpd_init()
2059 INIT_LIST_HEAD(&genpd->parent_links); in pm_genpd_init()
2060 INIT_LIST_HEAD(&genpd->child_links); in pm_genpd_init()
2061 INIT_LIST_HEAD(&genpd->dev_list); in pm_genpd_init()
2062 RAW_INIT_NOTIFIER_HEAD(&genpd->power_notifiers); in pm_genpd_init()
2063 genpd_lock_init(genpd); in pm_genpd_init()
2064 genpd->gov = gov; in pm_genpd_init()
2065 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); in pm_genpd_init()
2066 atomic_set(&genpd->sd_count, 0); in pm_genpd_init()
2067 genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON; in pm_genpd_init()
2068 genpd->device_count = 0; in pm_genpd_init()
2069 genpd->provider = NULL; in pm_genpd_init()
2070 genpd->has_provider = false; in pm_genpd_init()
2071 genpd->accounting_time = ktime_get_mono_fast_ns(); in pm_genpd_init()
2072 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; in pm_genpd_init()
2073 genpd->domain.ops.runtime_resume = genpd_runtime_resume; in pm_genpd_init()
2074 genpd->domain.ops.prepare = genpd_prepare; in pm_genpd_init()
2075 genpd->domain.ops.suspend_noirq = genpd_suspend_noirq; in pm_genpd_init()
2076 genpd->domain.ops.resume_noirq = genpd_resume_noirq; in pm_genpd_init()
2077 genpd->domain.ops.freeze_noirq = genpd_freeze_noirq; in pm_genpd_init()
2078 genpd->domain.ops.thaw_noirq = genpd_thaw_noirq; in pm_genpd_init()
2079 genpd->domain.ops.poweroff_noirq = genpd_poweroff_noirq; in pm_genpd_init()
2080 genpd->domain.ops.restore_noirq = genpd_restore_noirq; in pm_genpd_init()
2081 genpd->domain.ops.complete = genpd_complete; in pm_genpd_init()
2082 genpd->domain.start = genpd_dev_pm_start; in pm_genpd_init()
2084 if (genpd->flags & GENPD_FLAG_PM_CLK) { in pm_genpd_init()
2085 genpd->dev_ops.stop = pm_clk_suspend; in pm_genpd_init()
2086 genpd->dev_ops.start = pm_clk_resume; in pm_genpd_init()
2091 genpd->flags |= GENPD_FLAG_RPM_ALWAYS_ON; in pm_genpd_init()
2094 if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) && in pm_genpd_init()
2095 !genpd_status_on(genpd)) { in pm_genpd_init()
2096 pr_err("always-on PM domain %s is not on\n", genpd->name); in pm_genpd_init()
2101 if (!gov && genpd->state_count > 1) in pm_genpd_init()
2102 pr_warn("%s: no governor for states\n", genpd->name); in pm_genpd_init()
2104 ret = genpd_alloc_data(genpd); in pm_genpd_init()
2108 device_initialize(&genpd->dev); in pm_genpd_init()
2109 dev_set_name(&genpd->dev, "%s", genpd->name); in pm_genpd_init()
2112 list_add(&genpd->gpd_list_node, &gpd_list); in pm_genpd_init()
2114 genpd_debug_add(genpd); in pm_genpd_init()
2120 static int genpd_remove(struct generic_pm_domain *genpd) in genpd_remove() argument
2124 if (IS_ERR_OR_NULL(genpd)) in genpd_remove()
2127 genpd_lock(genpd); in genpd_remove()
2129 if (genpd->has_provider) { in genpd_remove()
2130 genpd_unlock(genpd); in genpd_remove()
2131 pr_err("Provider present, unable to remove %s\n", genpd->name); in genpd_remove()
2135 if (!list_empty(&genpd->parent_links) || genpd->device_count) { in genpd_remove()
2136 genpd_unlock(genpd); in genpd_remove()
2137 pr_err("%s: unable to remove %s\n", __func__, genpd->name); in genpd_remove()
2141 list_for_each_entry_safe(link, l, &genpd->child_links, child_node) { in genpd_remove()
2147 list_del(&genpd->gpd_list_node); in genpd_remove()
2148 genpd_unlock(genpd); in genpd_remove()
2149 genpd_debug_remove(genpd); in genpd_remove()
2150 cancel_work_sync(&genpd->power_off_work); in genpd_remove()
2151 genpd_free_data(genpd); in genpd_remove()
2153 pr_debug("%s: removed %s\n", __func__, genpd->name); in genpd_remove()
2171 int pm_genpd_remove(struct generic_pm_domain *genpd) in pm_genpd_remove() argument
2176 ret = genpd_remove(genpd); in pm_genpd_remove()
2296 static bool genpd_present(const struct generic_pm_domain *genpd) in genpd_present() argument
2303 if (gpd == genpd) { in genpd_present()
2319 struct generic_pm_domain *genpd) in of_genpd_add_provider_simple() argument
2323 if (!np || !genpd) in of_genpd_add_provider_simple()
2326 if (!genpd_present(genpd)) in of_genpd_add_provider_simple()
2329 genpd->dev.of_node = np; in of_genpd_add_provider_simple()
2332 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
2333 ret = dev_pm_opp_of_add_table(&genpd->dev); in of_genpd_add_provider_simple()
2335 return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n"); in of_genpd_add_provider_simple()
2341 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_simple()
2342 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_simple()
2345 ret = genpd_add_provider(np, genpd_xlate_simple, genpd); in of_genpd_add_provider_simple()
2347 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
2348 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_simple()
2349 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_simple()
2355 genpd->provider = &np->fwnode; in of_genpd_add_provider_simple()
2356 genpd->has_provider = true; in of_genpd_add_provider_simple()
2370 struct generic_pm_domain *genpd; in of_genpd_add_provider_onecell() local
2381 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2383 if (!genpd) in of_genpd_add_provider_onecell()
2385 if (!genpd_present(genpd)) in of_genpd_add_provider_onecell()
2388 genpd->dev.of_node = np; in of_genpd_add_provider_onecell()
2391 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2392 ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); in of_genpd_add_provider_onecell()
2394 dev_err_probe(&genpd->dev, ret, in of_genpd_add_provider_onecell()
2403 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_onecell()
2404 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_onecell()
2407 genpd->provider = &np->fwnode; in of_genpd_add_provider_onecell()
2408 genpd->has_provider = true; in of_genpd_add_provider_onecell()
2419 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2421 if (!genpd) in of_genpd_add_provider_onecell()
2424 genpd->provider = NULL; in of_genpd_add_provider_onecell()
2425 genpd->has_provider = false; in of_genpd_add_provider_onecell()
2427 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2428 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_onecell()
2429 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_onecell()
2493 struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); in genpd_get_from_provider() local
2504 genpd = provider->xlate(genpdspec, provider->data); in genpd_get_from_provider()
2505 if (!IS_ERR(genpd)) in genpd_get_from_provider()
2511 return genpd; in genpd_get_from_provider()
2524 struct generic_pm_domain *genpd; in of_genpd_add_device() local
2532 genpd = genpd_get_from_provider(genpdspec); in of_genpd_add_device()
2533 if (IS_ERR(genpd)) { in of_genpd_add_device()
2534 ret = PTR_ERR(genpd); in of_genpd_add_device()
2538 ret = genpd_add_device(genpd, dev, dev); in of_genpd_add_device()
2638 struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT); in of_genpd_remove_last() local
2648 genpd = ret ? ERR_PTR(ret) : gpd; in of_genpd_remove_last()
2654 return genpd; in of_genpd_remove_last()
3052 struct generic_pm_domain *genpd = NULL; in pm_genpd_opp_to_performance_state() local
3055 genpd = container_of(genpd_dev, struct generic_pm_domain, dev); in pm_genpd_opp_to_performance_state()
3057 if (unlikely(!genpd->opp_to_performance_state)) in pm_genpd_opp_to_performance_state()
3060 genpd_lock(genpd); in pm_genpd_opp_to_performance_state()
3061 state = genpd->opp_to_performance_state(genpd, opp); in pm_genpd_opp_to_performance_state()
3062 genpd_unlock(genpd); in pm_genpd_opp_to_performance_state()
3115 struct generic_pm_domain *genpd) in genpd_summary_one() argument
3127 ret = genpd_lock_interruptible(genpd); in genpd_summary_one()
3131 if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) in genpd_summary_one()
3133 if (!genpd_status_on(genpd)) in genpd_summary_one()
3135 status_lookup[genpd->status], genpd->state_idx); in genpd_summary_one()
3138 status_lookup[genpd->status]); in genpd_summary_one()
3139 seq_printf(s, "%-30s %-49s %u", genpd->name, state, genpd->performance_state); in genpd_summary_one()
3146 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_summary_one()
3147 if (list_is_first(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
3150 if (!list_is_last(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
3154 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in genpd_summary_one()
3156 genpd_is_irq_safe(genpd) ? in genpd_summary_one()
3169 genpd_unlock(genpd); in genpd_summary_one()
3176 struct generic_pm_domain *genpd; in summary_show() local
3187 list_for_each_entry(genpd, &gpd_list, gpd_list_node) { in summary_show()
3188 ret = genpd_summary_one(s, genpd); in summary_show()
3204 struct generic_pm_domain *genpd = s->private; in status_show() local
3207 ret = genpd_lock_interruptible(genpd); in status_show()
3211 if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup))) in status_show()
3214 if (genpd->status == GENPD_STATE_OFF) in status_show()
3215 seq_printf(s, "%s-%u\n", status_lookup[genpd->status], in status_show()
3216 genpd->state_idx); in status_show()
3218 seq_printf(s, "%s\n", status_lookup[genpd->status]); in status_show()
3220 genpd_unlock(genpd); in status_show()
3226 struct generic_pm_domain *genpd = s->private; in sub_domains_show() local
3230 ret = genpd_lock_interruptible(genpd); in sub_domains_show()
3234 list_for_each_entry(link, &genpd->parent_links, parent_node) in sub_domains_show()
3237 genpd_unlock(genpd); in sub_domains_show()
3243 struct generic_pm_domain *genpd = s->private; in idle_states_show() local
3248 ret = genpd_lock_interruptible(genpd); in idle_states_show()
3254 for (i = 0; i < genpd->state_count; i++) { in idle_states_show()
3255 idle_time += genpd->states[i].idle_time; in idle_states_show()
3257 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) { in idle_states_show()
3259 if (now > genpd->accounting_time) { in idle_states_show()
3260 delta = now - genpd->accounting_time; in idle_states_show()
3267 genpd->states[i].usage, genpd->states[i].rejected); in idle_states_show()
3270 genpd_unlock(genpd); in idle_states_show()
3276 struct generic_pm_domain *genpd = s->private; in active_time_show() local
3280 ret = genpd_lock_interruptible(genpd); in active_time_show()
3284 if (genpd->status == GENPD_STATE_ON) { in active_time_show()
3286 if (now > genpd->accounting_time) in active_time_show()
3287 delta = now - genpd->accounting_time; in active_time_show()
3290 on_time = genpd->on_time + delta; in active_time_show()
3294 genpd_unlock(genpd); in active_time_show()
3300 struct generic_pm_domain *genpd = s->private; in total_idle_time_show() local
3305 ret = genpd_lock_interruptible(genpd); in total_idle_time_show()
3309 for (i = 0; i < genpd->state_count; i++) { in total_idle_time_show()
3310 total += genpd->states[i].idle_time; in total_idle_time_show()
3312 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) { in total_idle_time_show()
3314 if (now > genpd->accounting_time) { in total_idle_time_show()
3315 delta = now - genpd->accounting_time; in total_idle_time_show()
3324 genpd_unlock(genpd); in total_idle_time_show()
3331 struct generic_pm_domain *genpd = s->private; in devices_show() local
3336 ret = genpd_lock_interruptible(genpd); in devices_show()
3340 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in devices_show()
3342 genpd_is_irq_safe(genpd) ? in devices_show()
3351 genpd_unlock(genpd); in devices_show()
3357 struct generic_pm_domain *genpd = s->private; in perf_state_show() local
3359 if (genpd_lock_interruptible(genpd)) in perf_state_show()
3362 seq_printf(s, "%u\n", genpd->performance_state); in perf_state_show()
3364 genpd_unlock(genpd); in perf_state_show()
3377 static void genpd_debug_add(struct generic_pm_domain *genpd) in genpd_debug_add() argument
3384 d = debugfs_create_dir(genpd->name, genpd_debugfs_dir); in genpd_debug_add()
3387 d, genpd, &status_fops); in genpd_debug_add()
3389 d, genpd, &sub_domains_fops); in genpd_debug_add()
3391 d, genpd, &idle_states_fops); in genpd_debug_add()
3393 d, genpd, &active_time_fops); in genpd_debug_add()
3395 d, genpd, &total_idle_time_fops); in genpd_debug_add()
3397 d, genpd, &devices_fops); in genpd_debug_add()
3398 if (genpd->set_performance_state) in genpd_debug_add()
3400 d, genpd, &perf_state_fops); in genpd_debug_add()
3405 struct generic_pm_domain *genpd; in genpd_debug_init() local
3412 list_for_each_entry(genpd, &gpd_list, gpd_list_node) in genpd_debug_init()
3413 genpd_debug_add(genpd); in genpd_debug_init()