Lines Matching refs:genpd
28 #define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \ argument
33 __routine = genpd->dev_ops.callback; \
44 void (*lock)(struct generic_pm_domain *genpd);
45 void (*lock_nested)(struct generic_pm_domain *genpd, int depth);
46 int (*lock_interruptible)(struct generic_pm_domain *genpd);
47 void (*unlock)(struct generic_pm_domain *genpd);
50 static void genpd_lock_mtx(struct generic_pm_domain *genpd) in genpd_lock_mtx() argument
52 mutex_lock(&genpd->mlock); in genpd_lock_mtx()
55 static void genpd_lock_nested_mtx(struct generic_pm_domain *genpd, in genpd_lock_nested_mtx() argument
58 mutex_lock_nested(&genpd->mlock, depth); in genpd_lock_nested_mtx()
61 static int genpd_lock_interruptible_mtx(struct generic_pm_domain *genpd) in genpd_lock_interruptible_mtx() argument
63 return mutex_lock_interruptible(&genpd->mlock); in genpd_lock_interruptible_mtx()
66 static void genpd_unlock_mtx(struct generic_pm_domain *genpd) in genpd_unlock_mtx() argument
68 return mutex_unlock(&genpd->mlock); in genpd_unlock_mtx()
78 static void genpd_lock_spin(struct generic_pm_domain *genpd) in genpd_lock_spin() argument
79 __acquires(&genpd->slock) in genpd_lock_spin()
83 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_spin()
84 genpd->lock_flags = flags; in genpd_lock_spin()
87 static void genpd_lock_nested_spin(struct generic_pm_domain *genpd, in genpd_lock_nested_spin() argument
89 __acquires(&genpd->slock) in genpd_lock_nested_spin()
93 spin_lock_irqsave_nested(&genpd->slock, flags, depth); in genpd_lock_nested_spin()
94 genpd->lock_flags = flags; in genpd_lock_nested_spin()
97 static int genpd_lock_interruptible_spin(struct generic_pm_domain *genpd) in genpd_lock_interruptible_spin() argument
98 __acquires(&genpd->slock) in genpd_lock_interruptible_spin()
102 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_interruptible_spin()
103 genpd->lock_flags = flags; in genpd_lock_interruptible_spin()
107 static void genpd_unlock_spin(struct generic_pm_domain *genpd) in genpd_unlock_spin() argument
108 __releases(&genpd->slock) in genpd_unlock_spin()
110 spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags); in genpd_unlock_spin()
125 #define genpd_status_on(genpd) (genpd->status == GPD_STATE_ACTIVE) argument
126 #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) argument
127 #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) argument
128 #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP) argument
131 const struct generic_pm_domain *genpd) in irq_safe_dev_in_no_sleep_domain() argument
135 ret = pm_runtime_is_irq_safe(dev) && !genpd_is_irq_safe(genpd); in irq_safe_dev_in_no_sleep_domain()
142 if (ret && !genpd_is_always_on(genpd)) in irq_safe_dev_in_no_sleep_domain()
144 genpd->name); in irq_safe_dev_in_no_sleep_domain()
157 struct generic_pm_domain *genpd = NULL, *gpd; in genpd_lookup_dev() local
165 genpd = gpd; in genpd_lookup_dev()
171 return genpd; in genpd_lookup_dev()
186 static int genpd_stop_dev(const struct generic_pm_domain *genpd, in genpd_stop_dev() argument
189 return GENPD_DEV_CALLBACK(genpd, int, stop, dev); in genpd_stop_dev()
192 static int genpd_start_dev(const struct generic_pm_domain *genpd, in genpd_start_dev() argument
195 return GENPD_DEV_CALLBACK(genpd, int, start, dev); in genpd_start_dev()
198 static bool genpd_sd_counter_dec(struct generic_pm_domain *genpd) in genpd_sd_counter_dec() argument
202 if (!WARN_ON(atomic_read(&genpd->sd_count) == 0)) in genpd_sd_counter_dec()
203 ret = !!atomic_dec_and_test(&genpd->sd_count); in genpd_sd_counter_dec()
208 static void genpd_sd_counter_inc(struct generic_pm_domain *genpd) in genpd_sd_counter_inc() argument
210 atomic_inc(&genpd->sd_count); in genpd_sd_counter_inc()
215 static void genpd_update_accounting(struct generic_pm_domain *genpd) in genpd_update_accounting() argument
220 delta = ktime_sub(now, genpd->accounting_time); in genpd_update_accounting()
227 if (genpd->status == GPD_STATE_ACTIVE) { in genpd_update_accounting()
228 int state_idx = genpd->state_idx; in genpd_update_accounting()
230 genpd->states[state_idx].idle_time = in genpd_update_accounting()
231 ktime_add(genpd->states[state_idx].idle_time, delta); in genpd_update_accounting()
233 genpd->on_time = ktime_add(genpd->on_time, delta); in genpd_update_accounting()
236 genpd->accounting_time = now; in genpd_update_accounting()
239 static inline void genpd_update_accounting(struct generic_pm_domain *genpd) {} in genpd_update_accounting() argument
259 struct generic_pm_domain *genpd; in dev_pm_genpd_set_performance_state() local
265 genpd = dev_to_genpd(dev); in dev_pm_genpd_set_performance_state()
266 if (IS_ERR(genpd)) in dev_pm_genpd_set_performance_state()
269 if (unlikely(!genpd->set_performance_state)) in dev_pm_genpd_set_performance_state()
278 genpd_lock(genpd); in dev_pm_genpd_set_performance_state()
285 if (state == genpd->performance_state) in dev_pm_genpd_set_performance_state()
289 if (state > genpd->performance_state) in dev_pm_genpd_set_performance_state()
293 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in dev_pm_genpd_set_performance_state()
300 if (state == genpd->performance_state) in dev_pm_genpd_set_performance_state()
314 if (genpd_status_on(genpd)) { in dev_pm_genpd_set_performance_state()
315 ret = genpd->set_performance_state(genpd, state); in dev_pm_genpd_set_performance_state()
322 genpd->performance_state = state; in dev_pm_genpd_set_performance_state()
325 genpd_unlock(genpd); in dev_pm_genpd_set_performance_state()
331 static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed) in _genpd_power_on() argument
333 unsigned int state_idx = genpd->state_idx; in _genpd_power_on()
338 if (!genpd->power_on) in _genpd_power_on()
342 return genpd->power_on(genpd); in _genpd_power_on()
345 ret = genpd->power_on(genpd); in _genpd_power_on()
351 if (unlikely(genpd->set_performance_state)) { in _genpd_power_on()
352 ret = genpd->set_performance_state(genpd, genpd->performance_state); in _genpd_power_on()
355 genpd->name, genpd->performance_state, ret); in _genpd_power_on()
359 if (elapsed_ns <= genpd->states[state_idx].power_on_latency_ns) in _genpd_power_on()
362 genpd->states[state_idx].power_on_latency_ns = elapsed_ns; in _genpd_power_on()
363 genpd->max_off_time_changed = true; in _genpd_power_on()
365 genpd->name, "on", elapsed_ns); in _genpd_power_on()
370 static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed) in _genpd_power_off() argument
372 unsigned int state_idx = genpd->state_idx; in _genpd_power_off()
377 if (!genpd->power_off) in _genpd_power_off()
381 return genpd->power_off(genpd); in _genpd_power_off()
384 ret = genpd->power_off(genpd); in _genpd_power_off()
389 if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) in _genpd_power_off()
392 genpd->states[state_idx].power_off_latency_ns = elapsed_ns; in _genpd_power_off()
393 genpd->max_off_time_changed = true; in _genpd_power_off()
395 genpd->name, "off", elapsed_ns); in _genpd_power_off()
407 static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) in genpd_queue_power_off_work() argument
409 queue_work(pm_wq, &genpd->power_off_work); in genpd_queue_power_off_work()
423 static int genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, in genpd_power_off() argument
435 if (!genpd_status_on(genpd) || genpd->prepared_count > 0) in genpd_power_off()
443 if (genpd_is_always_on(genpd) || atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
446 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in genpd_power_off()
458 irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd)) in genpd_power_off()
465 if (genpd->gov && genpd->gov->power_down_ok) { in genpd_power_off()
466 if (!genpd->gov->power_down_ok(&genpd->domain)) in genpd_power_off()
470 if (genpd->power_off) { in genpd_power_off()
473 if (atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
484 ret = _genpd_power_off(genpd, true); in genpd_power_off()
489 genpd->status = GPD_STATE_POWER_OFF; in genpd_power_off()
490 genpd_update_accounting(genpd); in genpd_power_off()
492 list_for_each_entry(link, &genpd->slave_links, slave_node) { in genpd_power_off()
510 static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) in genpd_power_on() argument
515 if (genpd_status_on(genpd)) in genpd_power_on()
523 list_for_each_entry(link, &genpd->slave_links, slave_node) { in genpd_power_on()
538 ret = _genpd_power_on(genpd, true); in genpd_power_on()
542 genpd->status = GPD_STATE_ACTIVE; in genpd_power_on()
543 genpd_update_accounting(genpd); in genpd_power_on()
549 &genpd->slave_links, in genpd_power_on()
570 struct generic_pm_domain *genpd; in genpd_dev_pm_qos_notifier() local
579 genpd = dev_to_genpd(dev); in genpd_dev_pm_qos_notifier()
581 genpd = ERR_PTR(-ENODATA); in genpd_dev_pm_qos_notifier()
586 if (!IS_ERR(genpd)) { in genpd_dev_pm_qos_notifier()
587 genpd_lock(genpd); in genpd_dev_pm_qos_notifier()
588 genpd->max_off_time_changed = true; in genpd_dev_pm_qos_notifier()
589 genpd_unlock(genpd); in genpd_dev_pm_qos_notifier()
606 struct generic_pm_domain *genpd; in genpd_power_off_work_fn() local
608 genpd = container_of(work, struct generic_pm_domain, power_off_work); in genpd_power_off_work_fn()
610 genpd_lock(genpd); in genpd_power_off_work_fn()
611 genpd_power_off(genpd, false, 0); in genpd_power_off_work_fn()
612 genpd_unlock(genpd); in genpd_power_off_work_fn()
671 struct generic_pm_domain *genpd; in genpd_runtime_suspend() local
681 genpd = dev_to_genpd(dev); in genpd_runtime_suspend()
682 if (IS_ERR(genpd)) in genpd_runtime_suspend()
691 suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL; in genpd_runtime_suspend()
704 ret = genpd_stop_dev(genpd, dev); in genpd_runtime_suspend()
717 genpd->max_off_time_changed = true; in genpd_runtime_suspend()
726 if (irq_safe_dev_in_no_sleep_domain(dev, genpd)) in genpd_runtime_suspend()
729 genpd_lock(genpd); in genpd_runtime_suspend()
730 genpd_power_off(genpd, true, 0); in genpd_runtime_suspend()
731 genpd_unlock(genpd); in genpd_runtime_suspend()
746 struct generic_pm_domain *genpd; in genpd_runtime_resume() local
756 genpd = dev_to_genpd(dev); in genpd_runtime_resume()
757 if (IS_ERR(genpd)) in genpd_runtime_resume()
764 if (irq_safe_dev_in_no_sleep_domain(dev, genpd)) { in genpd_runtime_resume()
769 genpd_lock(genpd); in genpd_runtime_resume()
770 ret = genpd_power_on(genpd, 0); in genpd_runtime_resume()
771 genpd_unlock(genpd); in genpd_runtime_resume()
782 ret = genpd_start_dev(genpd, dev); in genpd_runtime_resume()
797 genpd->max_off_time_changed = true; in genpd_runtime_resume()
805 genpd_stop_dev(genpd, dev); in genpd_runtime_resume()
808 (pm_runtime_is_irq_safe(dev) && genpd_is_irq_safe(genpd))) { in genpd_runtime_resume()
809 genpd_lock(genpd); in genpd_runtime_resume()
810 genpd_power_off(genpd, true, 0); in genpd_runtime_resume()
811 genpd_unlock(genpd); in genpd_runtime_resume()
830 struct generic_pm_domain *genpd; in genpd_power_off_unused() local
839 list_for_each_entry(genpd, &gpd_list, gpd_list_node) in genpd_power_off_unused()
840 genpd_queue_power_off_work(genpd); in genpd_power_off_unused()
850 static bool genpd_present(const struct generic_pm_domain *genpd) in genpd_present() argument
854 if (IS_ERR_OR_NULL(genpd)) in genpd_present()
858 if (gpd == genpd) in genpd_present()
881 static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, in genpd_sync_power_off() argument
886 if (!genpd_status_on(genpd) || genpd_is_always_on(genpd)) in genpd_sync_power_off()
889 if (genpd->suspended_count != genpd->device_count in genpd_sync_power_off()
890 || atomic_read(&genpd->sd_count) > 0) in genpd_sync_power_off()
894 genpd->state_idx = genpd->state_count - 1; in genpd_sync_power_off()
895 if (_genpd_power_off(genpd, false)) in genpd_sync_power_off()
898 genpd->status = GPD_STATE_POWER_OFF; in genpd_sync_power_off()
900 list_for_each_entry(link, &genpd->slave_links, slave_node) { in genpd_sync_power_off()
923 static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, in genpd_sync_power_on() argument
928 if (genpd_status_on(genpd)) in genpd_sync_power_on()
931 list_for_each_entry(link, &genpd->slave_links, slave_node) { in genpd_sync_power_on()
943 _genpd_power_on(genpd, false); in genpd_sync_power_on()
945 genpd->status = GPD_STATE_ACTIVE; in genpd_sync_power_on()
965 const struct generic_pm_domain *genpd) in resume_needed() argument
972 active_wakeup = genpd_is_active_wakeup(genpd); in resume_needed()
987 struct generic_pm_domain *genpd; in genpd_prepare() local
992 genpd = dev_to_genpd(dev); in genpd_prepare()
993 if (IS_ERR(genpd)) in genpd_prepare()
1001 if (resume_needed(dev, genpd)) in genpd_prepare()
1004 genpd_lock(genpd); in genpd_prepare()
1006 if (genpd->prepared_count++ == 0) in genpd_prepare()
1007 genpd->suspended_count = 0; in genpd_prepare()
1009 genpd_unlock(genpd); in genpd_prepare()
1013 genpd_lock(genpd); in genpd_prepare()
1015 genpd->prepared_count--; in genpd_prepare()
1017 genpd_unlock(genpd); in genpd_prepare()
1035 struct generic_pm_domain *genpd; in genpd_finish_suspend() local
1038 genpd = dev_to_genpd(dev); in genpd_finish_suspend()
1039 if (IS_ERR(genpd)) in genpd_finish_suspend()
1049 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) in genpd_finish_suspend()
1052 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_suspend()
1054 ret = genpd_stop_dev(genpd, dev); in genpd_finish_suspend()
1064 genpd_lock(genpd); in genpd_finish_suspend()
1065 genpd->suspended_count++; in genpd_finish_suspend()
1066 genpd_sync_power_off(genpd, true, 0); in genpd_finish_suspend()
1067 genpd_unlock(genpd); in genpd_finish_suspend()
1094 struct generic_pm_domain *genpd; in genpd_resume_noirq() local
1099 genpd = dev_to_genpd(dev); in genpd_resume_noirq()
1100 if (IS_ERR(genpd)) in genpd_resume_noirq()
1103 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) in genpd_resume_noirq()
1106 genpd_lock(genpd); in genpd_resume_noirq()
1107 genpd_sync_power_on(genpd, true, 0); in genpd_resume_noirq()
1108 genpd->suspended_count--; in genpd_resume_noirq()
1109 genpd_unlock(genpd); in genpd_resume_noirq()
1111 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_resume_noirq()
1113 ret = genpd_start_dev(genpd, dev); in genpd_resume_noirq()
1132 const struct generic_pm_domain *genpd; in genpd_freeze_noirq() local
1137 genpd = dev_to_genpd(dev); in genpd_freeze_noirq()
1138 if (IS_ERR(genpd)) in genpd_freeze_noirq()
1145 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_freeze_noirq()
1147 ret = genpd_stop_dev(genpd, dev); in genpd_freeze_noirq()
1161 const struct generic_pm_domain *genpd; in genpd_thaw_noirq() local
1166 genpd = dev_to_genpd(dev); in genpd_thaw_noirq()
1167 if (IS_ERR(genpd)) in genpd_thaw_noirq()
1170 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_thaw_noirq()
1172 ret = genpd_start_dev(genpd, dev); in genpd_thaw_noirq()
1204 struct generic_pm_domain *genpd; in genpd_restore_noirq() local
1209 genpd = dev_to_genpd(dev); in genpd_restore_noirq()
1210 if (IS_ERR(genpd)) in genpd_restore_noirq()
1217 genpd_lock(genpd); in genpd_restore_noirq()
1218 if (genpd->suspended_count++ == 0) in genpd_restore_noirq()
1224 genpd->status = GPD_STATE_POWER_OFF; in genpd_restore_noirq()
1226 genpd_sync_power_on(genpd, true, 0); in genpd_restore_noirq()
1227 genpd_unlock(genpd); in genpd_restore_noirq()
1229 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_restore_noirq()
1231 ret = genpd_start_dev(genpd, dev); in genpd_restore_noirq()
1250 struct generic_pm_domain *genpd; in genpd_complete() local
1254 genpd = dev_to_genpd(dev); in genpd_complete()
1255 if (IS_ERR(genpd)) in genpd_complete()
1260 genpd_lock(genpd); in genpd_complete()
1262 genpd->prepared_count--; in genpd_complete()
1263 if (!genpd->prepared_count) in genpd_complete()
1264 genpd_queue_power_off_work(genpd); in genpd_complete()
1266 genpd_unlock(genpd); in genpd_complete()
1278 struct generic_pm_domain *genpd; in genpd_syscore_switch() local
1280 genpd = dev_to_genpd(dev); in genpd_syscore_switch()
1281 if (!genpd_present(genpd)) in genpd_syscore_switch()
1285 genpd->suspended_count++; in genpd_syscore_switch()
1286 genpd_sync_power_off(genpd, false, 0); in genpd_syscore_switch()
1288 genpd_sync_power_on(genpd, false, 0); in genpd_syscore_switch()
1289 genpd->suspended_count--; in genpd_syscore_switch()
1376 static int genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, in genpd_add_device() argument
1384 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(dev)) in genpd_add_device()
1391 genpd_lock(genpd); in genpd_add_device()
1393 ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; in genpd_add_device()
1397 dev_pm_domain_set(dev, &genpd->domain); in genpd_add_device()
1399 genpd->device_count++; in genpd_add_device()
1400 genpd->max_off_time_changed = true; in genpd_add_device()
1402 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); in genpd_add_device()
1405 genpd_unlock(genpd); in genpd_add_device()
1420 int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) in pm_genpd_add_device() argument
1425 ret = genpd_add_device(genpd, dev, NULL); in pm_genpd_add_device()
1432 static int genpd_remove_device(struct generic_pm_domain *genpd, in genpd_remove_device() argument
1445 genpd_lock(genpd); in genpd_remove_device()
1447 if (genpd->prepared_count > 0) { in genpd_remove_device()
1452 genpd->device_count--; in genpd_remove_device()
1453 genpd->max_off_time_changed = true; in genpd_remove_device()
1455 if (genpd->detach_dev) in genpd_remove_device()
1456 genpd->detach_dev(genpd, dev); in genpd_remove_device()
1462 genpd_unlock(genpd); in genpd_remove_device()
1469 genpd_unlock(genpd); in genpd_remove_device()
1481 struct generic_pm_domain *genpd = genpd_lookup_dev(dev); in pm_genpd_remove_device() local
1483 if (!genpd) in pm_genpd_remove_device()
1486 return genpd_remove_device(genpd, dev); in pm_genpd_remove_device()
1490 static int genpd_add_subdomain(struct generic_pm_domain *genpd, in genpd_add_subdomain() argument
1496 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain) in genpd_add_subdomain()
1497 || genpd == subdomain) in genpd_add_subdomain()
1505 if (!genpd_is_irq_safe(genpd) && genpd_is_irq_safe(subdomain)) { in genpd_add_subdomain()
1507 genpd->name, subdomain->name); in genpd_add_subdomain()
1516 genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); in genpd_add_subdomain()
1518 if (!genpd_status_on(genpd) && genpd_status_on(subdomain)) { in genpd_add_subdomain()
1523 list_for_each_entry(itr, &genpd->master_links, master_node) { in genpd_add_subdomain()
1524 if (itr->slave == subdomain && itr->master == genpd) { in genpd_add_subdomain()
1530 link->master = genpd; in genpd_add_subdomain()
1531 list_add_tail(&link->master_node, &genpd->master_links); in genpd_add_subdomain()
1535 genpd_sd_counter_inc(genpd); in genpd_add_subdomain()
1538 genpd_unlock(genpd); in genpd_add_subdomain()
1550 int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, in pm_genpd_add_subdomain() argument
1556 ret = genpd_add_subdomain(genpd, subdomain); in pm_genpd_add_subdomain()
1568 int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, in pm_genpd_remove_subdomain() argument
1574 if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) in pm_genpd_remove_subdomain()
1578 genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); in pm_genpd_remove_subdomain()
1581 pr_warn("%s: unable to remove subdomain %s\n", genpd->name, in pm_genpd_remove_subdomain()
1587 list_for_each_entry_safe(link, l, &genpd->master_links, master_node) { in pm_genpd_remove_subdomain()
1595 genpd_sd_counter_dec(genpd); in pm_genpd_remove_subdomain()
1602 genpd_unlock(genpd); in pm_genpd_remove_subdomain()
1609 static int genpd_set_default_power_state(struct generic_pm_domain *genpd) in genpd_set_default_power_state() argument
1617 genpd->states = state; in genpd_set_default_power_state()
1618 genpd->state_count = 1; in genpd_set_default_power_state()
1619 genpd->free = state; in genpd_set_default_power_state()
1624 static void genpd_lock_init(struct generic_pm_domain *genpd) in genpd_lock_init() argument
1626 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) { in genpd_lock_init()
1627 spin_lock_init(&genpd->slock); in genpd_lock_init()
1628 genpd->lock_ops = &genpd_spin_ops; in genpd_lock_init()
1630 mutex_init(&genpd->mlock); in genpd_lock_init()
1631 genpd->lock_ops = &genpd_mtx_ops; in genpd_lock_init()
1643 int pm_genpd_init(struct generic_pm_domain *genpd, in pm_genpd_init() argument
1648 if (IS_ERR_OR_NULL(genpd)) in pm_genpd_init()
1651 INIT_LIST_HEAD(&genpd->master_links); in pm_genpd_init()
1652 INIT_LIST_HEAD(&genpd->slave_links); in pm_genpd_init()
1653 INIT_LIST_HEAD(&genpd->dev_list); in pm_genpd_init()
1654 genpd_lock_init(genpd); in pm_genpd_init()
1655 genpd->gov = gov; in pm_genpd_init()
1656 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); in pm_genpd_init()
1657 atomic_set(&genpd->sd_count, 0); in pm_genpd_init()
1658 genpd->status = is_off ? GPD_STATE_POWER_OFF : GPD_STATE_ACTIVE; in pm_genpd_init()
1659 genpd->device_count = 0; in pm_genpd_init()
1660 genpd->max_off_time_ns = -1; in pm_genpd_init()
1661 genpd->max_off_time_changed = true; in pm_genpd_init()
1662 genpd->provider = NULL; in pm_genpd_init()
1663 genpd->has_provider = false; in pm_genpd_init()
1664 genpd->accounting_time = ktime_get(); in pm_genpd_init()
1665 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; in pm_genpd_init()
1666 genpd->domain.ops.runtime_resume = genpd_runtime_resume; in pm_genpd_init()
1667 genpd->domain.ops.prepare = genpd_prepare; in pm_genpd_init()
1668 genpd->domain.ops.suspend_noirq = genpd_suspend_noirq; in pm_genpd_init()
1669 genpd->domain.ops.resume_noirq = genpd_resume_noirq; in pm_genpd_init()
1670 genpd->domain.ops.freeze_noirq = genpd_freeze_noirq; in pm_genpd_init()
1671 genpd->domain.ops.thaw_noirq = genpd_thaw_noirq; in pm_genpd_init()
1672 genpd->domain.ops.poweroff_noirq = genpd_poweroff_noirq; in pm_genpd_init()
1673 genpd->domain.ops.restore_noirq = genpd_restore_noirq; in pm_genpd_init()
1674 genpd->domain.ops.complete = genpd_complete; in pm_genpd_init()
1676 if (genpd->flags & GENPD_FLAG_PM_CLK) { in pm_genpd_init()
1677 genpd->dev_ops.stop = pm_clk_suspend; in pm_genpd_init()
1678 genpd->dev_ops.start = pm_clk_resume; in pm_genpd_init()
1682 if (genpd_is_always_on(genpd) && !genpd_status_on(genpd)) in pm_genpd_init()
1686 if (genpd->state_count == 0) { in pm_genpd_init()
1687 ret = genpd_set_default_power_state(genpd); in pm_genpd_init()
1692 device_initialize(&genpd->dev); in pm_genpd_init()
1693 dev_set_name(&genpd->dev, "%s", genpd->name); in pm_genpd_init()
1696 list_add(&genpd->gpd_list_node, &gpd_list); in pm_genpd_init()
1703 static int genpd_remove(struct generic_pm_domain *genpd) in genpd_remove() argument
1707 if (IS_ERR_OR_NULL(genpd)) in genpd_remove()
1710 genpd_lock(genpd); in genpd_remove()
1712 if (genpd->has_provider) { in genpd_remove()
1713 genpd_unlock(genpd); in genpd_remove()
1714 pr_err("Provider present, unable to remove %s\n", genpd->name); in genpd_remove()
1718 if (!list_empty(&genpd->master_links) || genpd->device_count) { in genpd_remove()
1719 genpd_unlock(genpd); in genpd_remove()
1720 pr_err("%s: unable to remove %s\n", __func__, genpd->name); in genpd_remove()
1724 list_for_each_entry_safe(link, l, &genpd->slave_links, slave_node) { in genpd_remove()
1730 list_del(&genpd->gpd_list_node); in genpd_remove()
1731 genpd_unlock(genpd); in genpd_remove()
1732 cancel_work_sync(&genpd->power_off_work); in genpd_remove()
1733 kfree(genpd->free); in genpd_remove()
1734 pr_debug("%s: removed %s\n", __func__, genpd->name); in genpd_remove()
1752 int pm_genpd_remove(struct generic_pm_domain *genpd) in pm_genpd_remove() argument
1757 ret = genpd_remove(genpd); in pm_genpd_remove()
1882 struct generic_pm_domain *genpd) in of_genpd_add_provider_simple() argument
1886 if (!np || !genpd) in of_genpd_add_provider_simple()
1891 if (!genpd_present(genpd)) in of_genpd_add_provider_simple()
1894 genpd->dev.of_node = np; in of_genpd_add_provider_simple()
1897 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
1898 ret = dev_pm_opp_of_add_table(&genpd->dev); in of_genpd_add_provider_simple()
1900 dev_err(&genpd->dev, "Failed to add OPP table: %d\n", in of_genpd_add_provider_simple()
1906 ret = genpd_add_provider(np, genpd_xlate_simple, genpd); in of_genpd_add_provider_simple()
1908 if (genpd->set_performance_state) in of_genpd_add_provider_simple()
1909 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_simple()
1914 genpd->provider = &np->fwnode; in of_genpd_add_provider_simple()
1915 genpd->has_provider = true; in of_genpd_add_provider_simple()
1932 struct generic_pm_domain *genpd; in of_genpd_add_provider_onecell() local
1945 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
1947 if (!genpd) in of_genpd_add_provider_onecell()
1949 if (!genpd_present(genpd)) in of_genpd_add_provider_onecell()
1952 genpd->dev.of_node = np; in of_genpd_add_provider_onecell()
1955 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
1956 ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); in of_genpd_add_provider_onecell()
1958 dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n", in of_genpd_add_provider_onecell()
1964 genpd->provider = &np->fwnode; in of_genpd_add_provider_onecell()
1965 genpd->has_provider = true; in of_genpd_add_provider_onecell()
1978 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
1980 if (!genpd) in of_genpd_add_provider_onecell()
1983 genpd->provider = NULL; in of_genpd_add_provider_onecell()
1984 genpd->has_provider = false; in of_genpd_add_provider_onecell()
1986 if (genpd->set_performance_state) in of_genpd_add_provider_onecell()
1987 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_onecell()
2050 struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); in genpd_get_from_provider() local
2061 genpd = provider->xlate(genpdspec, provider->data); in genpd_get_from_provider()
2062 if (!IS_ERR(genpd)) in genpd_get_from_provider()
2068 return genpd; in genpd_get_from_provider()
2081 struct generic_pm_domain *genpd; in of_genpd_add_device() local
2086 genpd = genpd_get_from_provider(genpdspec); in of_genpd_add_device()
2087 if (IS_ERR(genpd)) { in of_genpd_add_device()
2088 ret = PTR_ERR(genpd); in of_genpd_add_device()
2092 ret = genpd_add_device(genpd, dev, NULL); in of_genpd_add_device()
2154 struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT); in of_genpd_remove_last() local
2164 genpd = ret ? ERR_PTR(ret) : gpd; in of_genpd_remove_last()
2170 return genpd; in of_genpd_remove_last()
2529 struct generic_pm_domain *genpd; in of_genpd_opp_to_performance_state() local
2533 genpd = dev_to_genpd(dev); in of_genpd_opp_to_performance_state()
2534 if (IS_ERR(genpd)) in of_genpd_opp_to_performance_state()
2537 if (unlikely(!genpd->set_performance_state)) in of_genpd_opp_to_performance_state()
2540 genpd_lock(genpd); in of_genpd_opp_to_performance_state()
2542 opp = of_dev_pm_opp_find_required_opp(&genpd->dev, np); in of_genpd_opp_to_performance_state()
2549 state = genpd->opp_to_performance_state(genpd, opp); in of_genpd_opp_to_performance_state()
2553 genpd_unlock(genpd); in of_genpd_opp_to_performance_state()
2606 struct generic_pm_domain *genpd) in genpd_summary_one() argument
2618 ret = genpd_lock_interruptible(genpd); in genpd_summary_one()
2622 if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) in genpd_summary_one()
2624 if (!genpd_status_on(genpd)) in genpd_summary_one()
2626 status_lookup[genpd->status], genpd->state_idx); in genpd_summary_one()
2629 status_lookup[genpd->status]); in genpd_summary_one()
2630 seq_printf(s, "%-30s %-15s ", genpd->name, state); in genpd_summary_one()
2637 list_for_each_entry(link, &genpd->master_links, master_node) { in genpd_summary_one()
2639 if (!list_is_last(&link->master_node, &genpd->master_links)) in genpd_summary_one()
2643 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in genpd_summary_one()
2645 genpd_is_irq_safe(genpd) ? in genpd_summary_one()
2657 genpd_unlock(genpd); in genpd_summary_one()
2664 struct generic_pm_domain *genpd; in genpd_summary_show() local
2675 list_for_each_entry(genpd, &gpd_list, gpd_list_node) { in genpd_summary_show()
2676 ret = genpd_summary_one(s, genpd); in genpd_summary_show()
2692 struct generic_pm_domain *genpd = s->private; in genpd_status_show() local
2695 ret = genpd_lock_interruptible(genpd); in genpd_status_show()
2699 if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup))) in genpd_status_show()
2702 if (genpd->status == GPD_STATE_POWER_OFF) in genpd_status_show()
2703 seq_printf(s, "%s-%u\n", status_lookup[genpd->status], in genpd_status_show()
2704 genpd->state_idx); in genpd_status_show()
2706 seq_printf(s, "%s\n", status_lookup[genpd->status]); in genpd_status_show()
2708 genpd_unlock(genpd); in genpd_status_show()
2714 struct generic_pm_domain *genpd = s->private; in genpd_sub_domains_show() local
2718 ret = genpd_lock_interruptible(genpd); in genpd_sub_domains_show()
2722 list_for_each_entry(link, &genpd->master_links, master_node) in genpd_sub_domains_show()
2725 genpd_unlock(genpd); in genpd_sub_domains_show()
2731 struct generic_pm_domain *genpd = s->private; in genpd_idle_states_show() local
2735 ret = genpd_lock_interruptible(genpd); in genpd_idle_states_show()
2741 for (i = 0; i < genpd->state_count; i++) { in genpd_idle_states_show()
2745 if ((genpd->status == GPD_STATE_POWER_OFF) && in genpd_idle_states_show()
2746 (genpd->state_idx == i)) in genpd_idle_states_show()
2747 delta = ktime_sub(ktime_get(), genpd->accounting_time); in genpd_idle_states_show()
2750 ktime_add(genpd->states[i].idle_time, delta)); in genpd_idle_states_show()
2754 genpd_unlock(genpd); in genpd_idle_states_show()
2760 struct generic_pm_domain *genpd = s->private; in genpd_active_time_show() local
2764 ret = genpd_lock_interruptible(genpd); in genpd_active_time_show()
2768 if (genpd->status == GPD_STATE_ACTIVE) in genpd_active_time_show()
2769 delta = ktime_sub(ktime_get(), genpd->accounting_time); in genpd_active_time_show()
2772 ktime_add(genpd->on_time, delta))); in genpd_active_time_show()
2774 genpd_unlock(genpd); in genpd_active_time_show()
2780 struct generic_pm_domain *genpd = s->private; in genpd_total_idle_time_show() local
2785 ret = genpd_lock_interruptible(genpd); in genpd_total_idle_time_show()
2789 for (i = 0; i < genpd->state_count; i++) { in genpd_total_idle_time_show()
2791 if ((genpd->status == GPD_STATE_POWER_OFF) && in genpd_total_idle_time_show()
2792 (genpd->state_idx == i)) in genpd_total_idle_time_show()
2793 delta = ktime_sub(ktime_get(), genpd->accounting_time); in genpd_total_idle_time_show()
2795 total = ktime_add(total, genpd->states[i].idle_time); in genpd_total_idle_time_show()
2801 genpd_unlock(genpd); in genpd_total_idle_time_show()
2808 struct generic_pm_domain *genpd = s->private; in genpd_devices_show() local
2813 ret = genpd_lock_interruptible(genpd); in genpd_devices_show()
2817 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in genpd_devices_show()
2819 genpd_is_irq_safe(genpd) ? in genpd_devices_show()
2828 genpd_unlock(genpd); in genpd_devices_show()
2834 struct generic_pm_domain *genpd = s->private; in genpd_perf_state_show() local
2836 if (genpd_lock_interruptible(genpd)) in genpd_perf_state_show()
2839 seq_printf(s, "%u\n", genpd->performance_state); in genpd_perf_state_show()
2841 genpd_unlock(genpd); in genpd_perf_state_show()
2880 struct generic_pm_domain *genpd; in genpd_debug_init() local
2892 list_for_each_entry(genpd, &gpd_list, gpd_list_node) { in genpd_debug_init()
2893 d = debugfs_create_dir(genpd->name, genpd_debugfs_dir); in genpd_debug_init()
2898 d, genpd, &genpd_status_fops); in genpd_debug_init()
2900 d, genpd, &genpd_sub_domains_fops); in genpd_debug_init()
2902 d, genpd, &genpd_idle_states_fops); in genpd_debug_init()
2904 d, genpd, &genpd_active_time_fops); in genpd_debug_init()
2906 d, genpd, &genpd_total_idle_time_fops); in genpd_debug_init()
2908 d, genpd, &genpd_devices_fops); in genpd_debug_init()
2909 if (genpd->set_performance_state) in genpd_debug_init()
2911 d, genpd, &genpd_perf_state_fops); in genpd_debug_init()