Lines Matching +full:power +full:- +full:domain

1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/base/power/domain.c - Common code related to device power domains.
25 #include "power.h"
34 __routine = genpd->dev_ops.callback; \
53 mutex_lock(&genpd->mlock); in genpd_lock_mtx()
59 mutex_lock_nested(&genpd->mlock, depth); in genpd_lock_nested_mtx()
64 return mutex_lock_interruptible(&genpd->mlock); in genpd_lock_interruptible_mtx()
69 return mutex_unlock(&genpd->mlock); in genpd_unlock_mtx()
80 __acquires(&genpd->slock) in genpd_lock_spin()
84 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_spin()
85 genpd->lock_flags = flags; in genpd_lock_spin()
90 __acquires(&genpd->slock) in genpd_lock_nested_spin()
94 spin_lock_irqsave_nested(&genpd->slock, flags, depth); in genpd_lock_nested_spin()
95 genpd->lock_flags = flags; in genpd_lock_nested_spin()
99 __acquires(&genpd->slock) in genpd_lock_interruptible_spin()
103 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_interruptible_spin()
104 genpd->lock_flags = flags; in genpd_lock_interruptible_spin()
109 __releases(&genpd->slock) in genpd_unlock_spin()
111 spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags); in genpd_unlock_spin()
121 #define genpd_lock(p) p->lock_ops->lock(p)
122 #define genpd_lock_nested(p, d) p->lock_ops->lock_nested(p, d)
123 #define genpd_lock_interruptible(p) p->lock_ops->lock_interruptible(p)
124 #define genpd_unlock(p) p->lock_ops->unlock(p)
126 #define genpd_status_on(genpd) (genpd->status == GENPD_STATE_ON)
127 #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE)
128 #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
129 #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
130 #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
131 #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
141 * Warn once if an IRQ safe device is attached to a no sleep domain, as in irq_safe_dev_in_no_sleep_domain()
143 * domain this isn't case, thus don't warn. in irq_safe_dev_in_no_sleep_domain()
146 dev_warn_once(dev, "PM domain %s will not be powered off\n", in irq_safe_dev_in_no_sleep_domain()
147 genpd->name); in irq_safe_dev_in_no_sleep_domain()
155 * Get the generic PM domain for a particular struct device.
156 * This validates the struct device pointer, the PM domain pointer,
157 * and checks that the PM domain pointer is a real generic PM domain.
162 if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain)) in dev_to_genpd_safe()
165 /* A genpd's always have its ->runtime_suspend() callback assigned. */ in dev_to_genpd_safe()
166 if (dev->pm_domain->ops.runtime_suspend == genpd_runtime_suspend) in dev_to_genpd_safe()
167 return pd_to_genpd(dev->pm_domain); in dev_to_genpd_safe()
174 * attached to the device is a genpd domain.
178 if (IS_ERR_OR_NULL(dev->pm_domain)) in dev_to_genpd()
179 return ERR_PTR(-EINVAL); in dev_to_genpd()
181 return pd_to_genpd(dev->pm_domain); in dev_to_genpd()
200 if (!WARN_ON(atomic_read(&genpd->sd_count) == 0)) in genpd_sd_counter_dec()
201 ret = !!atomic_dec_and_test(&genpd->sd_count); in genpd_sd_counter_dec()
208 atomic_inc(&genpd->sd_count); in genpd_sd_counter_inc()
218 delta = ktime_sub(now, genpd->accounting_time); in genpd_update_accounting()
221 * If genpd->status is active, it means we are just in genpd_update_accounting()
225 if (genpd->status == GENPD_STATE_ON) { in genpd_update_accounting()
226 int state_idx = genpd->state_idx; in genpd_update_accounting()
228 genpd->states[state_idx].idle_time = in genpd_update_accounting()
229 ktime_add(genpd->states[state_idx].idle_time, delta); in genpd_update_accounting()
231 genpd->on_time = ktime_add(genpd->on_time, delta); in genpd_update_accounting()
234 genpd->accounting_time = now; in genpd_update_accounting()
248 if (state == genpd->performance_state) in _genpd_reeval_performance_state()
252 if (state > genpd->performance_state) in _genpd_reeval_performance_state()
255 /* Traverse all devices within the domain */ in _genpd_reeval_performance_state()
256 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in _genpd_reeval_performance_state()
259 if (pd_data->performance_state > state) in _genpd_reeval_performance_state()
260 state = pd_data->performance_state; in _genpd_reeval_performance_state()
264 * Traverse all sub-domains within the domain. This can be in _genpd_reeval_performance_state()
265 * done without any additional locking as the link->performance_state in _genpd_reeval_performance_state()
266 * field is protected by the parent genpd->lock, which is already taken. in _genpd_reeval_performance_state()
268 * Also note that link->performance_state (subdomain's performance state in _genpd_reeval_performance_state()
269 * requirement to parent domain) is different from in _genpd_reeval_performance_state()
270 * link->child->performance_state (current performance state requirement in _genpd_reeval_performance_state()
271 * of the devices/sub-domains of the subdomain) and so can have a in _genpd_reeval_performance_state()
274 * Note that we also take vote from powered-off sub-domains into account in _genpd_reeval_performance_state()
277 list_for_each_entry(link, &genpd->parent_links, parent_node) { in _genpd_reeval_performance_state()
278 if (link->performance_state > state) in _genpd_reeval_performance_state()
279 state = link->performance_state; in _genpd_reeval_performance_state()
292 if (state == genpd->performance_state) in _genpd_set_performance_state()
296 list_for_each_entry(link, &genpd->child_links, child_node) { in _genpd_set_performance_state()
297 parent = link->parent; in _genpd_set_performance_state()
299 if (!parent->set_performance_state) in _genpd_set_performance_state()
303 ret = dev_pm_opp_xlate_performance_state(genpd->opp_table, in _genpd_set_performance_state()
304 parent->opp_table, in _genpd_set_performance_state()
313 link->prev_performance_state = link->performance_state; in _genpd_set_performance_state()
314 link->performance_state = parent_state; in _genpd_set_performance_state()
319 link->performance_state = link->prev_performance_state; in _genpd_set_performance_state()
327 ret = genpd->set_performance_state(genpd, state); in _genpd_set_performance_state()
331 genpd->performance_state = state; in _genpd_set_performance_state()
336 list_for_each_entry_continue_reverse(link, &genpd->child_links, in _genpd_set_performance_state()
338 parent = link->parent; in _genpd_set_performance_state()
340 if (!parent->set_performance_state) in _genpd_set_performance_state()
345 parent_state = link->prev_performance_state; in _genpd_set_performance_state()
346 link->performance_state = parent_state; in _genpd_set_performance_state()
352 parent->name, parent_state); in _genpd_set_performance_state()
362 * dev_pm_genpd_set_performance_state- Set performance state of device's power
363 * domain.
365 * @dev: Device for which the performance-state needs to be set.
385 return -ENODEV; in dev_pm_genpd_set_performance_state()
387 if (unlikely(!genpd->set_performance_state)) in dev_pm_genpd_set_performance_state()
388 return -EINVAL; in dev_pm_genpd_set_performance_state()
390 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_set_performance_state()
391 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_set_performance_state()
392 return -EINVAL; in dev_pm_genpd_set_performance_state()
396 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_set_performance_state()
397 prev = gpd_data->performance_state; in dev_pm_genpd_set_performance_state()
398 gpd_data->performance_state = state; in dev_pm_genpd_set_performance_state()
403 gpd_data->performance_state = prev; in dev_pm_genpd_set_performance_state()
413 unsigned int state_idx = genpd->state_idx; in _genpd_power_on()
418 /* Notify consumers that we are about to power on. */ in _genpd_power_on()
419 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_on()
426 if (!genpd->power_on) in _genpd_power_on()
430 ret = genpd->power_on(genpd); in _genpd_power_on()
438 ret = genpd->power_on(genpd); in _genpd_power_on()
443 if (elapsed_ns <= genpd->states[state_idx].power_on_latency_ns) in _genpd_power_on()
446 genpd->states[state_idx].power_on_latency_ns = elapsed_ns; in _genpd_power_on()
447 genpd->max_off_time_changed = true; in _genpd_power_on()
448 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", in _genpd_power_on()
449 genpd->name, "on", elapsed_ns); in _genpd_power_on()
452 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_on()
455 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_on()
462 unsigned int state_idx = genpd->state_idx; in _genpd_power_off()
467 /* Notify consumers that we are about to power off. */ in _genpd_power_off()
468 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_off()
475 if (!genpd->power_off) in _genpd_power_off()
479 ret = genpd->power_off(genpd); in _genpd_power_off()
487 ret = genpd->power_off(genpd); in _genpd_power_off()
492 if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) in _genpd_power_off()
495 genpd->states[state_idx].power_off_latency_ns = elapsed_ns; in _genpd_power_off()
496 genpd->max_off_time_changed = true; in _genpd_power_off()
497 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", in _genpd_power_off()
498 genpd->name, "off", elapsed_ns); in _genpd_power_off()
501 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_off()
505 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_off()
510 * genpd_queue_power_off_work - Queue up the execution of genpd_power_off().
511 * @genpd: PM domain to power off.
518 queue_work(pm_wq, &genpd->power_off_work); in genpd_queue_power_off_work()
522 * genpd_power_off - Remove power from a given PM domain.
523 * @genpd: PM domain to power down.
524 * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the
527 * be RPM_SUSPENDED, while it tries to power off the PM domain.
530 * have been powered down, remove power from @genpd.
541 * Do not try to power off the domain in the following situations: in genpd_power_off()
542 * (1) The domain is already in the "power off" state. in genpd_power_off()
545 if (!genpd_status_on(genpd) || genpd->prepared_count > 0) in genpd_power_off()
549 * Abort power off for the PM domain in the following situations: in genpd_power_off()
550 * (1) The domain is configured as always on. in genpd_power_off()
551 * (2) When the domain has a subdomain being powered on. in genpd_power_off()
555 atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
556 return -EBUSY; in genpd_power_off()
558 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in genpd_power_off()
561 stat = dev_pm_qos_flags(pdd->dev, PM_QOS_FLAG_NO_POWER_OFF); in genpd_power_off()
563 return -EBUSY; in genpd_power_off()
566 * Do not allow PM domain to be powered off, when an IRQ safe in genpd_power_off()
567 * device is part of a non-IRQ safe domain. in genpd_power_off()
569 if (!pm_runtime_suspended(pdd->dev) || in genpd_power_off()
570 irq_safe_dev_in_no_sleep_domain(pdd->dev, genpd)) in genpd_power_off()
575 return -EBUSY; in genpd_power_off()
577 if (genpd->gov && genpd->gov->power_down_ok) { in genpd_power_off()
578 if (!genpd->gov->power_down_ok(&genpd->domain)) in genpd_power_off()
579 return -EAGAIN; in genpd_power_off()
583 if (!genpd->gov) in genpd_power_off()
584 genpd->state_idx = 0; in genpd_power_off()
586 /* Don't power off, if a child domain is waiting to power on. */ in genpd_power_off()
587 if (atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
588 return -EBUSY; in genpd_power_off()
592 genpd->states[genpd->state_idx].rejected++; in genpd_power_off()
596 genpd->status = GENPD_STATE_OFF; in genpd_power_off()
598 genpd->states[genpd->state_idx].usage++; in genpd_power_off()
600 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_off()
601 genpd_sd_counter_dec(link->parent); in genpd_power_off()
602 genpd_lock_nested(link->parent, depth + 1); in genpd_power_off()
603 genpd_power_off(link->parent, false, depth + 1); in genpd_power_off()
604 genpd_unlock(link->parent); in genpd_power_off()
611 * genpd_power_on - Restore power to a given PM domain and its parents.
612 * @genpd: PM domain to power up.
615 * Restore power to @genpd and all of its parents so that it is possible to
631 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_on()
632 struct generic_pm_domain *parent = link->parent; in genpd_power_on()
650 genpd->status = GENPD_STATE_ON; in genpd_power_on()
657 &genpd->child_links, in genpd_power_on()
659 genpd_sd_counter_dec(link->parent); in genpd_power_on()
660 genpd_lock_nested(link->parent, depth + 1); in genpd_power_on()
661 genpd_power_off(link->parent, false, depth + 1); in genpd_power_on()
662 genpd_unlock(link->parent); in genpd_power_on()
682 dev = gpd_data->base.dev; in genpd_dev_pm_qos_notifier()
688 spin_lock_irq(&dev->power.lock); in genpd_dev_pm_qos_notifier()
690 pdd = dev->power.subsys_data ? in genpd_dev_pm_qos_notifier()
691 dev->power.subsys_data->domain_data : NULL; in genpd_dev_pm_qos_notifier()
693 to_gpd_data(pdd)->td.constraint_changed = true; in genpd_dev_pm_qos_notifier()
696 genpd = ERR_PTR(-ENODATA); in genpd_dev_pm_qos_notifier()
699 spin_unlock_irq(&dev->power.lock); in genpd_dev_pm_qos_notifier()
703 genpd->max_off_time_changed = true; in genpd_dev_pm_qos_notifier()
707 dev = dev->parent; in genpd_dev_pm_qos_notifier()
708 if (!dev || dev->power.ignore_children) in genpd_dev_pm_qos_notifier()
716 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
731 * __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
738 if (dev->type && dev->type->pm) in __genpd_runtime_suspend()
739 cb = dev->type->pm->runtime_suspend; in __genpd_runtime_suspend()
740 else if (dev->class && dev->class->pm) in __genpd_runtime_suspend()
741 cb = dev->class->pm->runtime_suspend; in __genpd_runtime_suspend()
742 else if (dev->bus && dev->bus->pm) in __genpd_runtime_suspend()
743 cb = dev->bus->pm->runtime_suspend; in __genpd_runtime_suspend()
747 if (!cb && dev->driver && dev->driver->pm) in __genpd_runtime_suspend()
748 cb = dev->driver->pm->runtime_suspend; in __genpd_runtime_suspend()
754 * __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
761 if (dev->type && dev->type->pm) in __genpd_runtime_resume()
762 cb = dev->type->pm->runtime_resume; in __genpd_runtime_resume()
763 else if (dev->class && dev->class->pm) in __genpd_runtime_resume()
764 cb = dev->class->pm->runtime_resume; in __genpd_runtime_resume()
765 else if (dev->bus && dev->bus->pm) in __genpd_runtime_resume()
766 cb = dev->bus->pm->runtime_resume; in __genpd_runtime_resume()
770 if (!cb && dev->driver && dev->driver->pm) in __genpd_runtime_resume()
771 cb = dev->driver->pm->runtime_resume; in __genpd_runtime_resume()
777 * genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
781 * pm_domain field points to the domain member of an object of type
782 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
788 struct gpd_timing_data *td = &dev_gpd_data(dev)->td; in genpd_runtime_suspend()
798 return -EINVAL; in genpd_runtime_suspend()
801 * A runtime PM centric subsystem/driver may re-use the runtime PM in genpd_runtime_suspend()
806 suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL; in genpd_runtime_suspend()
808 return -EBUSY; in genpd_runtime_suspend()
828 if (elapsed_ns > td->suspend_latency_ns) { in genpd_runtime_suspend()
829 td->suspend_latency_ns = elapsed_ns; in genpd_runtime_suspend()
832 genpd->max_off_time_changed = true; in genpd_runtime_suspend()
833 td->constraint_changed = true; in genpd_runtime_suspend()
838 * If power.irq_safe is set, this routine may be run with in genpd_runtime_suspend()
839 * IRQs disabled, so suspend only if the PM domain also is irq_safe. in genpd_runtime_suspend()
852 * genpd_runtime_resume - Resume a device belonging to I/O PM domain.
856 * pm_domain field points to the domain member of an object of type
857 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
862 struct gpd_timing_data *td = &dev_gpd_data(dev)->td; in genpd_runtime_resume()
873 return -EINVAL; in genpd_runtime_resume()
876 * As we don't power off a non IRQ safe domain, which holds in genpd_runtime_resume()
877 * an IRQ safe device, we don't need to restore power to it. in genpd_runtime_resume()
908 if (elapsed_ns > td->resume_latency_ns) { in genpd_runtime_resume()
909 td->resume_latency_ns = elapsed_ns; in genpd_runtime_resume()
912 genpd->max_off_time_changed = true; in genpd_runtime_resume()
913 td->constraint_changed = true; in genpd_runtime_resume()
941 * genpd_power_off_unused - Power off all PM domains with no devices in use.
948 pr_warn("genpd: Not disabling unused power domains\n"); in genpd_power_off_unused()
966 * genpd_sync_power_off - Synchronously power off a PM domain and its parents.
967 * @genpd: PM domain to power off, if possible.
971 * Check if the given PM domain can be powered off (during system suspend or
974 * This function is only called in "noirq" and "syscore" stages of system power
986 if (genpd->suspended_count != genpd->device_count in genpd_sync_power_off()
987 || atomic_read(&genpd->sd_count) > 0) in genpd_sync_power_off()
991 genpd->state_idx = genpd->state_count - 1; in genpd_sync_power_off()
995 genpd->status = GENPD_STATE_OFF; in genpd_sync_power_off()
997 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_off()
998 genpd_sd_counter_dec(link->parent); in genpd_sync_power_off()
1001 genpd_lock_nested(link->parent, depth + 1); in genpd_sync_power_off()
1003 genpd_sync_power_off(link->parent, use_lock, depth + 1); in genpd_sync_power_off()
1006 genpd_unlock(link->parent); in genpd_sync_power_off()
1011 * genpd_sync_power_on - Synchronously power on a PM domain and its parents.
1012 * @genpd: PM domain to power on.
1016 * This function is only called in "noirq" and "syscore" stages of system power
1028 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_on()
1029 genpd_sd_counter_inc(link->parent); in genpd_sync_power_on()
1032 genpd_lock_nested(link->parent, depth + 1); in genpd_sync_power_on()
1034 genpd_sync_power_on(link->parent, use_lock, depth + 1); in genpd_sync_power_on()
1037 genpd_unlock(link->parent); in genpd_sync_power_on()
1041 genpd->status = GENPD_STATE_ON; in genpd_sync_power_on()
1045 * resume_needed - Check whether to resume a device before system suspend.
1047 * @genpd: PM domain the device belongs to.
1073 * genpd_prepare - Start power transition of a device in a PM domain.
1076 * Start a power transition of a device (during a system-wide power transition)
1077 * under the assumption that its pm_domain field points to the domain member of
1078 * an object of type struct generic_pm_domain representing a PM domain
1090 return -EINVAL; in genpd_prepare()
1102 if (genpd->prepared_count++ == 0) in genpd_prepare()
1103 genpd->suspended_count = 0; in genpd_prepare()
1111 genpd->prepared_count--; in genpd_prepare()
1121 * genpd_finish_suspend - Completion of suspend or hibernation of device in an
1122 * I/O pm domain.
1126 * Stop the device and remove power from the domain if all devices in it have
1136 return -EINVAL; in genpd_finish_suspend()
1145 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) in genpd_finish_suspend()
1148 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_suspend()
1161 genpd->suspended_count++; in genpd_finish_suspend()
1169 * genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
1172 * Stop the device and remove power from the domain if all devices in it have
1183 * genpd_resume_noirq - Start of resume of device in an I/O PM domain.
1186 * Restore power to the device's PM domain, if necessary, and start the device.
1197 return -EINVAL; in genpd_resume_noirq()
1199 if (dev->power.wakeup_path && genpd_is_active_wakeup(genpd)) in genpd_resume_noirq()
1204 genpd->suspended_count--; in genpd_resume_noirq()
1207 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_resume_noirq()
1218 * genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
1222 * pm_domain field points to the domain member of an object of type
1223 * struct generic_pm_domain representing a power domain consisting of I/O
1235 return -EINVAL; in genpd_freeze_noirq()
1241 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_freeze_noirq()
1249 * genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
1252 * Start the device, unless power has been removed from the domain already
1264 return -EINVAL; in genpd_thaw_noirq()
1266 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_thaw_noirq()
1277 * genpd_poweroff_noirq - Completion of hibernation of device in an
1278 * I/O PM domain.
1281 * Stop the device and remove power from the domain if all devices in it have
1292 * genpd_restore_noirq - Start of restore of device in an I/O PM domain.
1295 * Make sure the domain will be in the same power state as before the
1307 return -EINVAL; in genpd_restore_noirq()
1311 * first time for the given domain in the present cycle. in genpd_restore_noirq()
1314 if (genpd->suspended_count++ == 0) { in genpd_restore_noirq()
1316 * The boot kernel might put the domain into arbitrary state, in genpd_restore_noirq()
1318 * so that it tries to power it on in case it was really off. in genpd_restore_noirq()
1320 genpd->status = GENPD_STATE_OFF; in genpd_restore_noirq()
1326 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_restore_noirq()
1337 * genpd_complete - Complete power transition of a device in a power domain.
1340 * Complete a power transition of a device (during a system-wide power
1342 * domain member of an object of type struct generic_pm_domain representing
1343 * a power domain consisting of I/O devices.
1359 genpd->prepared_count--; in genpd_complete()
1360 if (!genpd->prepared_count) in genpd_complete()
1367 * genpd_syscore_switch - Switch power during system core suspend or resume.
1368 * @dev: Device that normally is marked as "always on" to switch power for.
1382 genpd->suspended_count++; in genpd_syscore_switch()
1386 genpd->suspended_count--; in genpd_syscore_switch()
1426 ret = -ENOMEM; in genpd_alloc_dev_data()
1430 gpd_data->base.dev = dev; in genpd_alloc_dev_data()
1431 gpd_data->td.constraint_changed = true; in genpd_alloc_dev_data()
1432 gpd_data->td.effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS; in genpd_alloc_dev_data()
1433 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; in genpd_alloc_dev_data()
1435 spin_lock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1437 if (dev->power.subsys_data->domain_data) { in genpd_alloc_dev_data()
1438 ret = -EINVAL; in genpd_alloc_dev_data()
1442 dev->power.subsys_data->domain_data = &gpd_data->base; in genpd_alloc_dev_data()
1444 spin_unlock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1449 spin_unlock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1459 spin_lock_irq(&dev->power.lock); in genpd_free_dev_data()
1461 dev->power.subsys_data->domain_data = NULL; in genpd_free_dev_data()
1463 spin_unlock_irq(&dev->power.lock); in genpd_free_dev_data()
1477 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_update_cpumask()
1478 struct generic_pm_domain *parent = link->parent; in genpd_update_cpumask()
1486 cpumask_set_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1488 cpumask_clear_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1508 return -1; in genpd_get_cpu()
1515 return -1; in genpd_get_cpu()
1527 return -EINVAL; in genpd_add_device()
1533 gpd_data->cpu = genpd_get_cpu(genpd, base_dev); in genpd_add_device()
1535 ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; in genpd_add_device()
1541 genpd_set_cpumask(genpd, gpd_data->cpu); in genpd_add_device()
1542 dev_pm_domain_set(dev, &genpd->domain); in genpd_add_device()
1544 genpd->device_count++; in genpd_add_device()
1545 genpd->max_off_time_changed = true; in genpd_add_device()
1547 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); in genpd_add_device()
1554 dev_pm_qos_add_notifier(dev, &gpd_data->nb, in genpd_add_device()
1561 * pm_genpd_add_device - Add a device to an I/O PM domain.
1562 * @genpd: PM domain to add the device to.
1586 pdd = dev->power.subsys_data->domain_data; in genpd_remove_device()
1588 dev_pm_qos_remove_notifier(dev, &gpd_data->nb, in genpd_remove_device()
1593 if (genpd->prepared_count > 0) { in genpd_remove_device()
1594 ret = -EAGAIN; in genpd_remove_device()
1598 genpd->device_count--; in genpd_remove_device()
1599 genpd->max_off_time_changed = true; in genpd_remove_device()
1601 genpd_clear_cpumask(genpd, gpd_data->cpu); in genpd_remove_device()
1604 list_del_init(&pdd->list_node); in genpd_remove_device()
1608 if (genpd->detach_dev) in genpd_remove_device()
1609 genpd->detach_dev(genpd, dev); in genpd_remove_device()
1617 dev_pm_qos_add_notifier(dev, &gpd_data->nb, DEV_PM_QOS_RESUME_LATENCY); in genpd_remove_device()
1623 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1631 return -EINVAL; in pm_genpd_remove_device()
1638 * dev_pm_genpd_add_notifier - Add a genpd power on/off notifier for @dev
1643 * Users may call this function to add a genpd power on/off notifier for an
1645 * sent when genpd is powering on/off the PM domain.
1660 return -ENODEV; in dev_pm_genpd_add_notifier()
1662 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_add_notifier()
1663 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_add_notifier()
1664 return -EINVAL; in dev_pm_genpd_add_notifier()
1666 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_add_notifier()
1667 if (gpd_data->power_nb) in dev_pm_genpd_add_notifier()
1668 return -EEXIST; in dev_pm_genpd_add_notifier()
1671 ret = raw_notifier_chain_register(&genpd->power_notifiers, nb); in dev_pm_genpd_add_notifier()
1675 dev_warn(dev, "failed to add notifier for PM domain %s\n", in dev_pm_genpd_add_notifier()
1676 genpd->name); in dev_pm_genpd_add_notifier()
1680 gpd_data->power_nb = nb; in dev_pm_genpd_add_notifier()
1686 * dev_pm_genpd_remove_notifier - Remove a genpd power on/off notifier for @dev
1690 * Users may call this function to remove a genpd power on/off notifier for an
1706 return -ENODEV; in dev_pm_genpd_remove_notifier()
1708 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_remove_notifier()
1709 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_remove_notifier()
1710 return -EINVAL; in dev_pm_genpd_remove_notifier()
1712 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_remove_notifier()
1713 if (!gpd_data->power_nb) in dev_pm_genpd_remove_notifier()
1714 return -ENODEV; in dev_pm_genpd_remove_notifier()
1717 ret = raw_notifier_chain_unregister(&genpd->power_notifiers, in dev_pm_genpd_remove_notifier()
1718 gpd_data->power_nb); in dev_pm_genpd_remove_notifier()
1722 dev_warn(dev, "failed to remove notifier for PM domain %s\n", in dev_pm_genpd_remove_notifier()
1723 genpd->name); in dev_pm_genpd_remove_notifier()
1727 gpd_data->power_nb = NULL; in dev_pm_genpd_remove_notifier()
1740 return -EINVAL; in genpd_add_subdomain()
1743 * If the domain can be powered on/off in an IRQ safe in genpd_add_subdomain()
1749 genpd->name, subdomain->name); in genpd_add_subdomain()
1750 return -EINVAL; in genpd_add_subdomain()
1755 return -ENOMEM; in genpd_add_subdomain()
1761 ret = -EINVAL; in genpd_add_subdomain()
1765 list_for_each_entry(itr, &genpd->parent_links, parent_node) { in genpd_add_subdomain()
1766 if (itr->child == subdomain && itr->parent == genpd) { in genpd_add_subdomain()
1767 ret = -EINVAL; in genpd_add_subdomain()
1772 link->parent = genpd; in genpd_add_subdomain()
1773 list_add_tail(&link->parent_node, &genpd->parent_links); in genpd_add_subdomain()
1774 link->child = subdomain; in genpd_add_subdomain()
1775 list_add_tail(&link->child_node, &subdomain->child_links); in genpd_add_subdomain()
1788 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1789 * @genpd: Leader PM domain to add the subdomain to.
1806 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1807 * @genpd: Leader PM domain to remove the subdomain from.
1814 int ret = -EINVAL; in pm_genpd_remove_subdomain()
1817 return -EINVAL; in pm_genpd_remove_subdomain()
1822 if (!list_empty(&subdomain->parent_links) || subdomain->device_count) { in pm_genpd_remove_subdomain()
1824 genpd->name, subdomain->name); in pm_genpd_remove_subdomain()
1825 ret = -EBUSY; in pm_genpd_remove_subdomain()
1829 list_for_each_entry_safe(link, l, &genpd->parent_links, parent_node) { in pm_genpd_remove_subdomain()
1830 if (link->child != subdomain) in pm_genpd_remove_subdomain()
1833 list_del(&link->parent_node); in pm_genpd_remove_subdomain()
1834 list_del(&link->child_node); in pm_genpd_remove_subdomain()
1863 return -ENOMEM; in genpd_set_default_power_state()
1865 genpd->states = state; in genpd_set_default_power_state()
1866 genpd->state_count = 1; in genpd_set_default_power_state()
1867 genpd->free_states = genpd_free_default_power_state; in genpd_set_default_power_state()
1874 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) { in genpd_lock_init()
1875 spin_lock_init(&genpd->slock); in genpd_lock_init()
1876 genpd->lock_ops = &genpd_spin_ops; in genpd_lock_init()
1878 mutex_init(&genpd->mlock); in genpd_lock_init()
1879 genpd->lock_ops = &genpd_mtx_ops; in genpd_lock_init()
1884 * pm_genpd_init - Initialize a generic I/O PM domain object.
1885 * @genpd: PM domain object to initialize.
1886 * @gov: PM domain governor to associate with the domain (may be NULL).
1887 * @is_off: Initial value of the domain's power_is_off field.
1897 return -EINVAL; in pm_genpd_init()
1899 INIT_LIST_HEAD(&genpd->parent_links); in pm_genpd_init()
1900 INIT_LIST_HEAD(&genpd->child_links); in pm_genpd_init()
1901 INIT_LIST_HEAD(&genpd->dev_list); in pm_genpd_init()
1902 RAW_INIT_NOTIFIER_HEAD(&genpd->power_notifiers); in pm_genpd_init()
1904 genpd->gov = gov; in pm_genpd_init()
1905 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); in pm_genpd_init()
1906 atomic_set(&genpd->sd_count, 0); in pm_genpd_init()
1907 genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON; in pm_genpd_init()
1908 genpd->device_count = 0; in pm_genpd_init()
1909 genpd->max_off_time_ns = -1; in pm_genpd_init()
1910 genpd->max_off_time_changed = true; in pm_genpd_init()
1911 genpd->provider = NULL; in pm_genpd_init()
1912 genpd->has_provider = false; in pm_genpd_init()
1913 genpd->accounting_time = ktime_get(); in pm_genpd_init()
1914 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; in pm_genpd_init()
1915 genpd->domain.ops.runtime_resume = genpd_runtime_resume; in pm_genpd_init()
1916 genpd->domain.ops.prepare = genpd_prepare; in pm_genpd_init()
1917 genpd->domain.ops.suspend_noirq = genpd_suspend_noirq; in pm_genpd_init()
1918 genpd->domain.ops.resume_noirq = genpd_resume_noirq; in pm_genpd_init()
1919 genpd->domain.ops.freeze_noirq = genpd_freeze_noirq; in pm_genpd_init()
1920 genpd->domain.ops.thaw_noirq = genpd_thaw_noirq; in pm_genpd_init()
1921 genpd->domain.ops.poweroff_noirq = genpd_poweroff_noirq; in pm_genpd_init()
1922 genpd->domain.ops.restore_noirq = genpd_restore_noirq; in pm_genpd_init()
1923 genpd->domain.ops.complete = genpd_complete; in pm_genpd_init()
1924 genpd->domain.start = genpd_dev_pm_start; in pm_genpd_init()
1926 if (genpd->flags & GENPD_FLAG_PM_CLK) { in pm_genpd_init()
1927 genpd->dev_ops.stop = pm_clk_suspend; in pm_genpd_init()
1928 genpd->dev_ops.start = pm_clk_resume; in pm_genpd_init()
1931 /* Always-on domains must be powered on at initialization. */ in pm_genpd_init()
1934 return -EINVAL; in pm_genpd_init()
1937 !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL)) in pm_genpd_init()
1938 return -ENOMEM; in pm_genpd_init()
1941 if (genpd->state_count == 0) { in pm_genpd_init()
1945 free_cpumask_var(genpd->cpus); in pm_genpd_init()
1948 } else if (!gov && genpd->state_count > 1) { in pm_genpd_init()
1949 pr_warn("%s: no governor for states\n", genpd->name); in pm_genpd_init()
1952 device_initialize(&genpd->dev); in pm_genpd_init()
1953 dev_set_name(&genpd->dev, "%s", genpd->name); in pm_genpd_init()
1956 list_add(&genpd->gpd_list_node, &gpd_list); in pm_genpd_init()
1968 return -EINVAL; in genpd_remove()
1972 if (genpd->has_provider) { in genpd_remove()
1974 pr_err("Provider present, unable to remove %s\n", genpd->name); in genpd_remove()
1975 return -EBUSY; in genpd_remove()
1978 if (!list_empty(&genpd->parent_links) || genpd->device_count) { in genpd_remove()
1980 pr_err("%s: unable to remove %s\n", __func__, genpd->name); in genpd_remove()
1981 return -EBUSY; in genpd_remove()
1984 list_for_each_entry_safe(link, l, &genpd->child_links, child_node) { in genpd_remove()
1985 list_del(&link->parent_node); in genpd_remove()
1986 list_del(&link->child_node); in genpd_remove()
1990 list_del(&genpd->gpd_list_node); in genpd_remove()
1992 cancel_work_sync(&genpd->power_off_work); in genpd_remove()
1994 free_cpumask_var(genpd->cpus); in genpd_remove()
1995 if (genpd->free_states) in genpd_remove()
1996 genpd->free_states(genpd->states, genpd->state_count); in genpd_remove()
1998 pr_debug("%s: removed %s\n", __func__, genpd->name); in genpd_remove()
2004 * pm_genpd_remove - Remove a generic I/O PM domain
2005 * @genpd: Pointer to PM domain that is to be removed.
2007 * To remove the PM domain, this function:
2008 * - Removes the PM domain as a subdomain to any parent domains,
2010 * - Removes the PM domain from the list of registered PM domains.
2012 * The PM domain will only be removed, if the associated provider has
2013 * been removed, it is not a parent to any other PM domain and has no
2031 * Device Tree based PM domain providers.
2033 * The code below implements generic device tree based PM domain providers that
2037 * devices to these domains is supposed to register a PM domain provider, which
2038 * maps a PM domain specifier retrieved from the device tree to a PM domain.
2041 * - genpd_xlate_simple() for 1:1 device tree node to PM domain mapping.
2042 * - genpd_xlate_onecell() for mapping of multiple PM domains per node by
2047 * struct of_genpd_provider - PM domain provider registration structure
2048 * @link: Entry in global list of PM domain providers
2049 * @node: Pointer to device tree node of PM domain provider
2050 * @xlate: Provider-specific xlate callback mapping a set of specifier cells
2051 * into a PM domain.
2061 /* List of registered PM domain providers. */
2067 * genpd_xlate_simple() - Xlate function for direct node-domain mapping
2068 * @genpdspec: OF phandle args to map into a PM domain
2069 * @data: xlate function private data - pointer to struct generic_pm_domain
2083 * genpd_xlate_onecell() - Xlate function using a single index.
2084 * @genpdspec: OF phandle args to map into a PM domain
2085 * @data: xlate function private data - pointer to struct genpd_onecell_data
2087 * This is a generic xlate function that can be used to model simple PM domain
2097 unsigned int idx = genpdspec->args[0]; in genpd_xlate_onecell()
2099 if (genpdspec->args_count != 1) in genpd_xlate_onecell()
2100 return ERR_PTR(-EINVAL); in genpd_xlate_onecell()
2102 if (idx >= genpd_data->num_domains) { in genpd_xlate_onecell()
2103 pr_err("%s: invalid domain index %u\n", __func__, idx); in genpd_xlate_onecell()
2104 return ERR_PTR(-EINVAL); in genpd_xlate_onecell()
2107 if (!genpd_data->domains[idx]) in genpd_xlate_onecell()
2108 return ERR_PTR(-ENOENT); in genpd_xlate_onecell()
2110 return genpd_data->domains[idx]; in genpd_xlate_onecell()
2114 * genpd_add_provider() - Register a PM domain provider for a node
2115 * @np: Device node pointer associated with the PM domain provider.
2116 * @xlate: Callback for decoding PM domain from phandle arguments.
2126 return -ENOMEM; in genpd_add_provider()
2128 cp->node = of_node_get(np); in genpd_add_provider()
2129 cp->data = data; in genpd_add_provider()
2130 cp->xlate = xlate; in genpd_add_provider()
2133 list_add(&cp->link, &of_genpd_providers); in genpd_add_provider()
2135 pr_debug("Added domain provider from %pOF\n", np); in genpd_add_provider()
2151 * of_genpd_add_provider_simple() - Register a simple PM domain provider
2152 * @np: Device node pointer associated with the PM domain provider.
2153 * @genpd: Pointer to PM domain associated with the PM domain provider.
2158 int ret = -EINVAL; in of_genpd_add_provider_simple()
2161 return -EINVAL; in of_genpd_add_provider_simple()
2168 genpd->dev.of_node = np; in of_genpd_add_provider_simple()
2171 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
2172 ret = dev_pm_opp_of_add_table(&genpd->dev); in of_genpd_add_provider_simple()
2174 if (ret != -EPROBE_DEFER) in of_genpd_add_provider_simple()
2175 dev_err(&genpd->dev, "Failed to add OPP table: %d\n", in of_genpd_add_provider_simple()
2184 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_simple()
2185 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_simple()
2190 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
2191 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_simple()
2192 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_simple()
2198 genpd->provider = &np->fwnode; in of_genpd_add_provider_simple()
2199 genpd->has_provider = true; in of_genpd_add_provider_simple()
2209 * of_genpd_add_provider_onecell() - Register a onecell PM domain provider
2210 * @np: Device node pointer associated with the PM domain provider.
2211 * @data: Pointer to the data associated with the PM domain provider.
2218 int ret = -EINVAL; in of_genpd_add_provider_onecell()
2221 return -EINVAL; in of_genpd_add_provider_onecell()
2225 if (!data->xlate) in of_genpd_add_provider_onecell()
2226 data->xlate = genpd_xlate_onecell; in of_genpd_add_provider_onecell()
2228 for (i = 0; i < data->num_domains; i++) { in of_genpd_add_provider_onecell()
2229 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2236 genpd->dev.of_node = np; in of_genpd_add_provider_onecell()
2239 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2240 ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); in of_genpd_add_provider_onecell()
2242 if (ret != -EPROBE_DEFER) in of_genpd_add_provider_onecell()
2243 dev_err(&genpd->dev, "Failed to add OPP table for index %d: %d\n", in of_genpd_add_provider_onecell()
2252 genpd->opp_table = dev_pm_opp_get_opp_table_indexed(&genpd->dev, i); in of_genpd_add_provider_onecell()
2253 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_onecell()
2256 genpd->provider = &np->fwnode; in of_genpd_add_provider_onecell()
2257 genpd->has_provider = true; in of_genpd_add_provider_onecell()
2260 ret = genpd_add_provider(np, data->xlate, data); in of_genpd_add_provider_onecell()
2269 while (i--) { in of_genpd_add_provider_onecell()
2270 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2275 genpd->provider = NULL; in of_genpd_add_provider_onecell()
2276 genpd->has_provider = false; in of_genpd_add_provider_onecell()
2278 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2279 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_onecell()
2280 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_onecell()
2291 * of_genpd_del_provider() - Remove a previously registered PM domain provider
2292 * @np: Device node pointer associated with the PM domain provider
2302 if (cp->node == np) { in of_genpd_del_provider()
2304 * For each PM domain associated with the in of_genpd_del_provider()
2306 * so that the PM domain can be safely removed. in of_genpd_del_provider()
2309 if (gpd->provider == &np->fwnode) { in of_genpd_del_provider()
2310 gpd->has_provider = false; in of_genpd_del_provider()
2312 if (!gpd->set_performance_state) in of_genpd_del_provider()
2315 dev_pm_opp_put_opp_table(gpd->opp_table); in of_genpd_del_provider()
2316 dev_pm_opp_of_remove_table(&gpd->dev); in of_genpd_del_provider()
2320 list_del(&cp->link); in of_genpd_del_provider()
2321 of_node_put(cp->node); in of_genpd_del_provider()
2332 * genpd_get_from_provider() - Look-up PM domain
2333 * @genpdspec: OF phandle args to use for look-up
2335 * Looks for a PM domain provider under the node specified by @genpdspec and if
2337 * domain.
2345 struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); in genpd_get_from_provider()
2349 return ERR_PTR(-EINVAL); in genpd_get_from_provider()
2355 if (provider->node == genpdspec->np) in genpd_get_from_provider()
2356 genpd = provider->xlate(genpdspec, provider->data); in genpd_get_from_provider()
2367 * of_genpd_add_device() - Add a device to an I/O PM domain
2368 * @genpdspec: OF phandle args to use for look-up PM domain
2371 * Looks-up an I/O PM domain based upon phandle args provided and adds
2372 * the device to the PM domain. Returns a negative error code on failure.
2397 * of_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
2398 * @parent_spec: OF phandle args to use for parent PM domain look-up
2399 * @subdomain_spec: OF phandle args to use for subdomain look-up
2401 * Looks-up a parent PM domain and subdomain based upon phandle args
2402 * provided and adds the subdomain to the parent PM domain. Returns a
2435 * of_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
2436 * @parent_spec: OF phandle args to use for parent PM domain look-up
2437 * @subdomain_spec: OF phandle args to use for subdomain look-up
2439 * Looks-up a parent PM domain and subdomain based upon phandle args
2440 * provided and removes the subdomain from the parent PM domain. Returns a
2473 * of_genpd_remove_last - Remove the last PM domain registered for a provider
2476 * Find the last PM domain that was added by a particular provider and
2477 * remove this PM domain from the list of PM domains. The provider is
2479 * domain will only be removed, if the provider associated with domain
2487 struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT); in of_genpd_remove_last()
2491 return ERR_PTR(-EINVAL); in of_genpd_remove_last()
2495 if (gpd->provider == &np->fwnode) { in of_genpd_remove_last()
2509 of_node_put(dev->of_node); in genpd_release_dev()
2518 * genpd_dev_pm_detach - Detach a device from its PM domain.
2522 * Try to locate a corresponding generic PM domain, which the device was
2535 dev_dbg(dev, "removing from PM domain %s\n", pd->name); in genpd_dev_pm_detach()
2539 if (ret != -EAGAIN) in genpd_dev_pm_detach()
2547 dev_err(dev, "failed to remove from PM domain %s: %d", in genpd_dev_pm_detach()
2548 pd->name, ret); in genpd_dev_pm_detach()
2552 /* Check if PM domain can be powered off after removing this device. */ in genpd_dev_pm_detach()
2556 if (dev->bus == &genpd_bus_type) in genpd_dev_pm_detach()
2578 ret = of_parse_phandle_with_args(dev->of_node, "power-domains", in __genpd_dev_pm_attach()
2579 "#power-domain-cells", index, &pd_args); in __genpd_dev_pm_attach()
2588 dev_dbg(dev, "%s() failed to find PM domain: %ld\n", in __genpd_dev_pm_attach()
2593 dev_dbg(dev, "adding to PM domain %s\n", pd->name); in __genpd_dev_pm_attach()
2599 if (ret != -EPROBE_DEFER) in __genpd_dev_pm_attach()
2600 dev_err(dev, "failed to add to PM domain %s: %d", in __genpd_dev_pm_attach()
2601 pd->name, ret); in __genpd_dev_pm_attach()
2605 dev->pm_domain->detach = genpd_dev_pm_detach; in __genpd_dev_pm_attach()
2606 dev->pm_domain->sync = genpd_dev_pm_sync; in __genpd_dev_pm_attach()
2617 return ret ? -EPROBE_DEFER : 1; in __genpd_dev_pm_attach()
2621 * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
2624 * Parse device's OF node to find a PM domain specifier. If such is found,
2627 * Returns 1 on successfully attached PM domain, 0 when the device don't need a
2628 * PM domain or when multiple power-domains exists for it, else a negative error
2629 * code. Note that if a power-domain exists for the device, but it cannot be
2630 * found or turned on, then return -EPROBE_DEFER to ensure that the device is
2631 * not probed and to re-try again later.
2635 if (!dev->of_node) in genpd_dev_pm_attach()
2640 * can only attach one PM domain per device. in genpd_dev_pm_attach()
2642 if (of_count_phandle_with_args(dev->of_node, "power-domains", in genpd_dev_pm_attach()
2643 "#power-domain-cells") != 1) in genpd_dev_pm_attach()
2651 * genpd_dev_pm_attach_by_id - Associate a device with one of its PM domains.
2652 * @dev: The device used to lookup the PM domain.
2653 * @index: The index of the PM domain.
2655 * Parse device's OF node to find a PM domain specifier at the provided @index.
2657 * pm_domain ops. To deal with detaching of the virtual device, the ->detach()
2660 * Returns the created virtual device if successfully attached PM domain, NULL
2661 * when the device don't need a PM domain, else an ERR_PTR() in case of
2662 * failures. If a power-domain exists for the device, but cannot be found or
2663 * turned on, then ERR_PTR(-EPROBE_DEFER) is returned to ensure that the device
2664 * is not probed and to re-try again later.
2673 if (!dev->of_node) in genpd_dev_pm_attach_by_id()
2677 num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", in genpd_dev_pm_attach_by_id()
2678 "#power-domain-cells"); in genpd_dev_pm_attach_by_id()
2685 return ERR_PTR(-ENOMEM); in genpd_dev_pm_attach_by_id()
2688 virt_dev->bus = &genpd_bus_type; in genpd_dev_pm_attach_by_id()
2689 virt_dev->release = genpd_release_dev; in genpd_dev_pm_attach_by_id()
2690 virt_dev->of_node = of_node_get(dev->of_node); in genpd_dev_pm_attach_by_id()
2698 /* Try to attach the device to the PM domain at the specified index. */ in genpd_dev_pm_attach_by_id()
2713 * genpd_dev_pm_attach_by_name - Associate a device with one of its PM domains.
2714 * @dev: The device used to lookup the PM domain.
2715 * @name: The name of the PM domain.
2717 * Parse device's OF node to find a PM domain specifier using the
2718 * power-domain-names DT property. For further description see
2725 if (!dev->of_node) in genpd_dev_pm_attach_by_name()
2728 index = of_property_match_string(dev->of_node, "power-domain-names", in genpd_dev_pm_attach_by_name()
2737 { .compatible = "domain-idle-state", },
2748 err = of_property_read_u32(state_node, "entry-latency-us", in genpd_parse_state()
2751 pr_debug(" * %pOF missing entry-latency-us property\n", in genpd_parse_state()
2753 return -EINVAL; in genpd_parse_state()
2756 err = of_property_read_u32(state_node, "exit-latency-us", in genpd_parse_state()
2759 pr_debug(" * %pOF missing exit-latency-us property\n", in genpd_parse_state()
2761 return -EINVAL; in genpd_parse_state()
2764 err = of_property_read_u32(state_node, "min-residency-us", &residency); in genpd_parse_state()
2766 genpd_state->residency_ns = 1000 * residency; in genpd_parse_state()
2768 genpd_state->power_on_latency_ns = 1000 * exit_latency; in genpd_parse_state()
2769 genpd_state->power_off_latency_ns = 1000 * entry_latency; in genpd_parse_state()
2770 genpd_state->fwnode = &state_node->fwnode; in genpd_parse_state()
2783 ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL); in genpd_iterate_idle_states()
2785 return ret == -ENOENT ? 0 : ret; in genpd_iterate_idle_states()
2788 of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) { in genpd_iterate_idle_states()
2816 * free the memory after use. If any or zero compatible domain idle states is
2837 return -ENOMEM; in of_genpd_parse_idle_states()
2842 return ret < 0 ? ret : -EINVAL; in of_genpd_parse_idle_states()
2853 * pm_genpd_opp_to_performance_state - Gets performance state of the genpd from its OPP node.
2855 * @genpd_dev: Genpd's device for which the performance-state needs to be found.
2860 * platform specific genpd->opp_to_performance_state() callback to translate
2861 * power domain OPP to performance state.
2873 if (unlikely(!genpd->opp_to_performance_state)) in pm_genpd_opp_to_performance_state()
2877 state = genpd->opp_to_performance_state(genpd, opp); in pm_genpd_opp_to_performance_state()
2918 if (dev->power.runtime_error) in rtpm_status_str()
2920 else if (dev->power.disable_depth) in rtpm_status_str()
2922 else if (dev->power.runtime_status < ARRAY_SIZE(status_lookup)) in rtpm_status_str()
2923 p = status_lookup[dev->power.runtime_status]; in rtpm_status_str()
2945 return -ERESTARTSYS; in genpd_summary_one()
2947 if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) in genpd_summary_one()
2950 snprintf(state, sizeof(state), "%s-%u", in genpd_summary_one()
2951 status_lookup[genpd->status], genpd->state_idx); in genpd_summary_one()
2954 status_lookup[genpd->status]); in genpd_summary_one()
2955 seq_printf(s, "%-30s %-15s ", genpd->name, state); in genpd_summary_one()
2960 * Also genpd->name is immutable. in genpd_summary_one()
2962 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_summary_one()
2963 seq_printf(s, "%s", link->child->name); in genpd_summary_one()
2964 if (!list_is_last(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
2968 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in genpd_summary_one()
2969 kobj_path = kobject_get_path(&pm_data->dev->kobj, in genpd_summary_one()
2975 seq_printf(s, "\n %-50s ", kobj_path); in genpd_summary_one()
2976 rtpm_status_str(s, pm_data->dev); in genpd_summary_one()
2992 seq_puts(s, "domain status children\n"); in summary_show()
2994 seq_puts(s, "----------------------------------------------------------------------\n"); in summary_show()
2998 return -ERESTARTSYS; in summary_show()
3017 struct generic_pm_domain *genpd = s->private; in status_show()
3022 return -ERESTARTSYS; in status_show()
3024 if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup))) in status_show()
3027 if (genpd->status == GENPD_STATE_OFF) in status_show()
3028 seq_printf(s, "%s-%u\n", status_lookup[genpd->status], in status_show()
3029 genpd->state_idx); in status_show()
3031 seq_printf(s, "%s\n", status_lookup[genpd->status]); in status_show()
3039 struct generic_pm_domain *genpd = s->private; in sub_domains_show()
3045 return -ERESTARTSYS; in sub_domains_show()
3047 list_for_each_entry(link, &genpd->parent_links, parent_node) in sub_domains_show()
3048 seq_printf(s, "%s\n", link->child->name); in sub_domains_show()
3056 struct generic_pm_domain *genpd = s->private; in idle_states_show()
3062 return -ERESTARTSYS; in idle_states_show()
3066 for (i = 0; i < genpd->state_count; i++) { in idle_states_show()
3070 if ((genpd->status == GENPD_STATE_OFF) && in idle_states_show()
3071 (genpd->state_idx == i)) in idle_states_show()
3072 delta = ktime_sub(ktime_get(), genpd->accounting_time); in idle_states_show()
3075 ktime_add(genpd->states[i].idle_time, delta)); in idle_states_show()
3076 seq_printf(s, "S%-13i %-14lld %-14llu %llu\n", i, msecs, in idle_states_show()
3077 genpd->states[i].usage, genpd->states[i].rejected); in idle_states_show()
3086 struct generic_pm_domain *genpd = s->private; in active_time_show()
3092 return -ERESTARTSYS; in active_time_show()
3094 if (genpd->status == GENPD_STATE_ON) in active_time_show()
3095 delta = ktime_sub(ktime_get(), genpd->accounting_time); in active_time_show()
3098 ktime_add(genpd->on_time, delta))); in active_time_show()
3106 struct generic_pm_domain *genpd = s->private; in total_idle_time_show()
3113 return -ERESTARTSYS; in total_idle_time_show()
3115 for (i = 0; i < genpd->state_count; i++) { in total_idle_time_show()
3117 if ((genpd->status == GENPD_STATE_OFF) && in total_idle_time_show()
3118 (genpd->state_idx == i)) in total_idle_time_show()
3119 delta = ktime_sub(ktime_get(), genpd->accounting_time); in total_idle_time_show()
3121 total = ktime_add(total, genpd->states[i].idle_time); in total_idle_time_show()
3134 struct generic_pm_domain *genpd = s->private; in devices_show()
3141 return -ERESTARTSYS; in devices_show()
3143 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in devices_show()
3144 kobj_path = kobject_get_path(&pm_data->dev->kobj, in devices_show()
3160 struct generic_pm_domain *genpd = s->private; in perf_state_show()
3163 return -ERESTARTSYS; in perf_state_show()
3165 seq_printf(s, "%u\n", genpd->performance_state); in perf_state_show()
3191 d = debugfs_create_dir(genpd->name, genpd_debugfs_dir); in genpd_debug_init()
3205 if (genpd->set_performance_state) in genpd_debug_init()