Lines Matching +full:domain +full:- +full:idle +full:- +full:states

1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/base/power/domain.c - Common code related to device power domains.
35 __routine = genpd->dev_ops.callback; \
54 mutex_lock(&genpd->mlock); in genpd_lock_mtx()
60 mutex_lock_nested(&genpd->mlock, depth); in genpd_lock_nested_mtx()
65 return mutex_lock_interruptible(&genpd->mlock); in genpd_lock_interruptible_mtx()
70 return mutex_unlock(&genpd->mlock); in genpd_unlock_mtx()
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()
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()
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()
110 __releases(&genpd->slock) in genpd_unlock_spin()
112 spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags); in genpd_unlock_spin()
122 #define genpd_lock(p) p->lock_ops->lock(p)
123 #define genpd_lock_nested(p, d) p->lock_ops->lock_nested(p, d)
124 #define genpd_lock_interruptible(p) p->lock_ops->lock_interruptible(p)
125 #define genpd_unlock(p) p->lock_ops->unlock(p)
127 #define genpd_status_on(genpd) (genpd->status == GENPD_STATE_ON)
128 #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE)
129 #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
130 #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
131 #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
132 #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
142 * Warn once if an IRQ safe device is attached to a domain, which in irq_safe_dev_in_sleep_domain()
144 * configuration for PM, but it doesn't matter for an always on domain. in irq_safe_dev_in_sleep_domain()
150 dev_warn_once(dev, "PM domain %s will not be powered off\n", in irq_safe_dev_in_sleep_domain()
151 genpd->name); in irq_safe_dev_in_sleep_domain()
159 * Get the generic PM domain for a particular struct device.
160 * This validates the struct device pointer, the PM domain pointer,
161 * and checks that the PM domain pointer is a real generic PM domain.
166 if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain)) in dev_to_genpd_safe()
169 /* A genpd's always have its ->runtime_suspend() callback assigned. */ in dev_to_genpd_safe()
170 if (dev->pm_domain->ops.runtime_suspend == genpd_runtime_suspend) in dev_to_genpd_safe()
171 return pd_to_genpd(dev->pm_domain); in dev_to_genpd_safe()
178 * attached to the device is a genpd domain.
182 if (IS_ERR_OR_NULL(dev->pm_domain)) in dev_to_genpd()
183 return ERR_PTR(-EINVAL); in dev_to_genpd()
185 return pd_to_genpd(dev->pm_domain); in dev_to_genpd()
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()
212 atomic_inc(&genpd->sd_count); in genpd_sd_counter_inc()
228 d = debugfs_lookup(genpd->name, genpd_debugfs_dir); in genpd_debug_remove()
237 if (now <= genpd->accounting_time) in genpd_update_accounting()
240 delta = now - genpd->accounting_time; in genpd_update_accounting()
243 * If genpd->status is active, it means we are just in genpd_update_accounting()
244 * out of off and so update the idle time and vice in genpd_update_accounting()
247 if (genpd->status == GENPD_STATE_ON) in genpd_update_accounting()
248 genpd->states[genpd->state_idx].idle_time += delta; in genpd_update_accounting()
250 genpd->on_time += delta; in genpd_update_accounting()
252 genpd->accounting_time = now; in genpd_update_accounting()
268 if (state == genpd->performance_state) in _genpd_reeval_performance_state()
272 if (state > genpd->performance_state) in _genpd_reeval_performance_state()
275 /* Traverse all devices within the domain */ in _genpd_reeval_performance_state()
276 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in _genpd_reeval_performance_state()
279 if (pd_data->performance_state > state) in _genpd_reeval_performance_state()
280 state = pd_data->performance_state; in _genpd_reeval_performance_state()
284 * Traverse all sub-domains within the domain. This can be in _genpd_reeval_performance_state()
285 * done without any additional locking as the link->performance_state in _genpd_reeval_performance_state()
286 * field is protected by the parent genpd->lock, which is already taken. in _genpd_reeval_performance_state()
288 * Also note that link->performance_state (subdomain's performance state in _genpd_reeval_performance_state()
289 * requirement to parent domain) is different from in _genpd_reeval_performance_state()
290 * link->child->performance_state (current performance state requirement in _genpd_reeval_performance_state()
291 * of the devices/sub-domains of the subdomain) and so can have a in _genpd_reeval_performance_state()
294 * Note that we also take vote from powered-off sub-domains into account in _genpd_reeval_performance_state()
297 list_for_each_entry(link, &genpd->parent_links, parent_node) { in _genpd_reeval_performance_state()
298 if (link->performance_state > state) in _genpd_reeval_performance_state()
299 state = link->performance_state; in _genpd_reeval_performance_state()
309 if (!parent->set_performance_state) in genpd_xlate_performance_state()
312 return dev_pm_opp_xlate_performance_state(genpd->opp_table, in genpd_xlate_performance_state()
313 parent->opp_table, in genpd_xlate_performance_state()
324 if (state == genpd->performance_state) in _genpd_set_performance_state()
328 list_for_each_entry(link, &genpd->child_links, child_node) { in _genpd_set_performance_state()
329 parent = link->parent; in _genpd_set_performance_state()
340 link->prev_performance_state = link->performance_state; in _genpd_set_performance_state()
341 link->performance_state = parent_state; in _genpd_set_performance_state()
346 link->performance_state = link->prev_performance_state; in _genpd_set_performance_state()
354 if (genpd->set_performance_state) { in _genpd_set_performance_state()
355 ret = genpd->set_performance_state(genpd, state); in _genpd_set_performance_state()
360 genpd->performance_state = state; in _genpd_set_performance_state()
365 list_for_each_entry_continue_reverse(link, &genpd->child_links, in _genpd_set_performance_state()
367 parent = link->parent; in _genpd_set_performance_state()
371 parent_state = link->prev_performance_state; in _genpd_set_performance_state()
372 link->performance_state = parent_state; in _genpd_set_performance_state()
378 parent->name, parent_state); in _genpd_set_performance_state()
394 prev_state = gpd_data->performance_state; in genpd_set_performance_state()
398 gpd_data->performance_state = state; in genpd_set_performance_state()
403 gpd_data->performance_state = prev_state; in genpd_set_performance_state()
410 unsigned int prev_state = dev_gpd_data(dev)->performance_state; in genpd_drop_performance_state()
426 * dev_pm_genpd_set_performance_state- Set performance state of device's power
427 * domain.
429 * @dev: Device for which the performance-state needs to be set.
447 return -ENODEV; in dev_pm_genpd_set_performance_state()
449 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_set_performance_state()
450 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_set_performance_state()
451 return -EINVAL; in dev_pm_genpd_set_performance_state()
455 dev_gpd_data(dev)->rpm_pstate = state; in dev_pm_genpd_set_performance_state()
459 dev_gpd_data(dev)->rpm_pstate = 0; in dev_pm_genpd_set_performance_state()
468 * dev_pm_genpd_set_next_wakeup - Notify PM framework of an impending wakeup.
480 * about that, so stale @next will be ignored when powering off the domain.
491 td = to_gpd_data(dev->power.subsys_data->domain_data)->td; in dev_pm_genpd_set_next_wakeup()
493 td->next_wakeup = next; in dev_pm_genpd_set_next_wakeup()
499 unsigned int state_idx = genpd->state_idx; in _genpd_power_on()
505 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_on()
512 if (!genpd->power_on) in _genpd_power_on()
515 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode; in _genpd_power_on()
517 ret = genpd->power_on(genpd); in _genpd_power_on()
525 ret = genpd->power_on(genpd); in _genpd_power_on()
530 if (elapsed_ns <= genpd->states[state_idx].power_on_latency_ns) in _genpd_power_on()
533 genpd->states[state_idx].power_on_latency_ns = elapsed_ns; in _genpd_power_on()
534 genpd->gd->max_off_time_changed = true; in _genpd_power_on()
535 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", in _genpd_power_on()
536 genpd->name, "on", elapsed_ns); in _genpd_power_on()
539 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_on()
542 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_on()
549 unsigned int state_idx = genpd->state_idx; in _genpd_power_off()
555 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_off()
562 if (!genpd->power_off) in _genpd_power_off()
565 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode; in _genpd_power_off()
567 ret = genpd->power_off(genpd); in _genpd_power_off()
575 ret = genpd->power_off(genpd); in _genpd_power_off()
580 if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) in _genpd_power_off()
583 genpd->states[state_idx].power_off_latency_ns = elapsed_ns; in _genpd_power_off()
584 genpd->gd->max_off_time_changed = true; in _genpd_power_off()
585 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", in _genpd_power_off()
586 genpd->name, "off", elapsed_ns); in _genpd_power_off()
589 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_off()
593 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_off()
598 * genpd_queue_power_off_work - Queue up the execution of genpd_power_off().
599 * @genpd: PM domain to power off.
606 queue_work(pm_wq, &genpd->power_off_work); in genpd_queue_power_off_work()
610 * genpd_power_off - Remove power from a given PM domain.
611 * @genpd: PM domain to power down.
612 * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the
615 * be RPM_SUSPENDED, while it tries to power off the PM domain.
630 * Do not try to power off the domain in the following situations: in genpd_power_off()
631 * (1) The domain is already in the "power off" state. in genpd_power_off()
634 if (!genpd_status_on(genpd) || genpd->prepared_count > 0) in genpd_power_off()
638 * Abort power off for the PM domain in the following situations: in genpd_power_off()
639 * (1) The domain is configured as always on. in genpd_power_off()
640 * (2) When the domain has a subdomain being powered on. in genpd_power_off()
644 atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
645 return -EBUSY; in genpd_power_off()
648 * The children must be in their deepest (powered-off) states to allow in genpd_power_off()
653 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_power_off()
654 struct generic_pm_domain *child = link->child; in genpd_power_off()
655 if (child->state_idx < child->state_count - 1) in genpd_power_off()
656 return -EBUSY; in genpd_power_off()
659 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in genpd_power_off()
661 * Do not allow PM domain to be powered off, when an IRQ safe in genpd_power_off()
662 * device is part of a non-IRQ safe domain. in genpd_power_off()
664 if (!pm_runtime_suspended(pdd->dev) || in genpd_power_off()
665 irq_safe_dev_in_sleep_domain(pdd->dev, genpd)) in genpd_power_off()
670 return -EBUSY; in genpd_power_off()
672 if (genpd->gov && genpd->gov->power_down_ok) { in genpd_power_off()
673 if (!genpd->gov->power_down_ok(&genpd->domain)) in genpd_power_off()
674 return -EAGAIN; in genpd_power_off()
678 if (!genpd->gov) in genpd_power_off()
679 genpd->state_idx = 0; in genpd_power_off()
681 /* Don't power off, if a child domain is waiting to power on. */ in genpd_power_off()
682 if (atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
683 return -EBUSY; in genpd_power_off()
687 genpd->states[genpd->state_idx].rejected++; in genpd_power_off()
691 genpd->status = GENPD_STATE_OFF; in genpd_power_off()
693 genpd->states[genpd->state_idx].usage++; in genpd_power_off()
695 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_off()
696 genpd_sd_counter_dec(link->parent); in genpd_power_off()
697 genpd_lock_nested(link->parent, depth + 1); in genpd_power_off()
698 genpd_power_off(link->parent, false, depth + 1); in genpd_power_off()
699 genpd_unlock(link->parent); in genpd_power_off()
706 * genpd_power_on - Restore power to a given PM domain and its parents.
707 * @genpd: PM domain to power up.
726 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_on()
727 struct generic_pm_domain *parent = link->parent; in genpd_power_on()
745 genpd->status = GENPD_STATE_ON; in genpd_power_on()
752 &genpd->child_links, in genpd_power_on()
754 genpd_sd_counter_dec(link->parent); in genpd_power_on()
755 genpd_lock_nested(link->parent, depth + 1); in genpd_power_on()
756 genpd_power_off(link->parent, false, depth + 1); in genpd_power_on()
757 genpd_unlock(link->parent); in genpd_power_on()
777 dev = gpd_data->base.dev; in genpd_dev_pm_qos_notifier()
780 struct generic_pm_domain *genpd = ERR_PTR(-ENODATA); in genpd_dev_pm_qos_notifier()
784 spin_lock_irq(&dev->power.lock); in genpd_dev_pm_qos_notifier()
786 pdd = dev->power.subsys_data ? in genpd_dev_pm_qos_notifier()
787 dev->power.subsys_data->domain_data : NULL; in genpd_dev_pm_qos_notifier()
789 td = to_gpd_data(pdd)->td; in genpd_dev_pm_qos_notifier()
791 td->constraint_changed = true; in genpd_dev_pm_qos_notifier()
796 spin_unlock_irq(&dev->power.lock); in genpd_dev_pm_qos_notifier()
800 genpd->gd->max_off_time_changed = true; in genpd_dev_pm_qos_notifier()
804 dev = dev->parent; in genpd_dev_pm_qos_notifier()
805 if (!dev || dev->power.ignore_children) in genpd_dev_pm_qos_notifier()
813 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
828 * __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
835 if (dev->type && dev->type->pm) in __genpd_runtime_suspend()
836 cb = dev->type->pm->runtime_suspend; in __genpd_runtime_suspend()
837 else if (dev->class && dev->class->pm) in __genpd_runtime_suspend()
838 cb = dev->class->pm->runtime_suspend; in __genpd_runtime_suspend()
839 else if (dev->bus && dev->bus->pm) in __genpd_runtime_suspend()
840 cb = dev->bus->pm->runtime_suspend; in __genpd_runtime_suspend()
844 if (!cb && dev->driver && dev->driver->pm) in __genpd_runtime_suspend()
845 cb = dev->driver->pm->runtime_suspend; in __genpd_runtime_suspend()
851 * __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
858 if (dev->type && dev->type->pm) in __genpd_runtime_resume()
859 cb = dev->type->pm->runtime_resume; in __genpd_runtime_resume()
860 else if (dev->class && dev->class->pm) in __genpd_runtime_resume()
861 cb = dev->class->pm->runtime_resume; in __genpd_runtime_resume()
862 else if (dev->bus && dev->bus->pm) in __genpd_runtime_resume()
863 cb = dev->bus->pm->runtime_resume; in __genpd_runtime_resume()
867 if (!cb && dev->driver && dev->driver->pm) in __genpd_runtime_resume()
868 cb = dev->driver->pm->runtime_resume; in __genpd_runtime_resume()
874 * genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
878 * pm_domain field points to the domain member of an object of type
879 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
886 struct gpd_timing_data *td = gpd_data->td; in genpd_runtime_suspend()
896 return -EINVAL; in genpd_runtime_suspend()
899 * A runtime PM centric subsystem/driver may re-use the runtime PM in genpd_runtime_suspend()
904 suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL; in genpd_runtime_suspend()
906 return -EBUSY; in genpd_runtime_suspend()
925 if (elapsed_ns > td->suspend_latency_ns) { in genpd_runtime_suspend()
926 td->suspend_latency_ns = elapsed_ns; in genpd_runtime_suspend()
929 genpd->gd->max_off_time_changed = true; in genpd_runtime_suspend()
930 td->constraint_changed = true; in genpd_runtime_suspend()
936 * IRQs disabled, so suspend only if the PM domain also is irq_safe. in genpd_runtime_suspend()
942 gpd_data->rpm_pstate = genpd_drop_performance_state(dev); in genpd_runtime_suspend()
950 * genpd_runtime_resume - Resume a device belonging to I/O PM domain.
954 * pm_domain field points to the domain member of an object of type
955 * struct generic_pm_domain representing a PM domain consisting of I/O devices.
961 struct gpd_timing_data *td = gpd_data->td; in genpd_runtime_resume()
971 return -EINVAL; in genpd_runtime_resume()
974 * As we don't power off a non IRQ safe domain, which holds in genpd_runtime_resume()
983 genpd_restore_performance_state(dev, gpd_data->rpm_pstate); in genpd_runtime_resume()
1005 if (elapsed_ns > td->resume_latency_ns) { in genpd_runtime_resume()
1006 td->resume_latency_ns = elapsed_ns; in genpd_runtime_resume()
1009 genpd->gd->max_off_time_changed = true; in genpd_runtime_resume()
1010 td->constraint_changed = true; in genpd_runtime_resume()
1021 gpd_data->rpm_pstate = genpd_drop_performance_state(dev); in genpd_runtime_resume()
1038 * genpd_power_off_unused - Power off all PM domains with no devices in use.
1063 * genpd_sync_power_off - Synchronously power off a PM domain and its parents.
1064 * @genpd: PM domain to power off, if possible.
1068 * Check if the given PM domain can be powered off (during system suspend or
1083 if (genpd->suspended_count != genpd->device_count in genpd_sync_power_off()
1084 || atomic_read(&genpd->sd_count) > 0) in genpd_sync_power_off()
1087 /* Check that the children are in their deepest (powered-off) state. */ in genpd_sync_power_off()
1088 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_sync_power_off()
1089 struct generic_pm_domain *child = link->child; in genpd_sync_power_off()
1090 if (child->state_idx < child->state_count - 1) in genpd_sync_power_off()
1095 genpd->state_idx = genpd->state_count - 1; in genpd_sync_power_off()
1099 genpd->status = GENPD_STATE_OFF; in genpd_sync_power_off()
1101 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_off()
1102 genpd_sd_counter_dec(link->parent); in genpd_sync_power_off()
1105 genpd_lock_nested(link->parent, depth + 1); in genpd_sync_power_off()
1107 genpd_sync_power_off(link->parent, use_lock, depth + 1); in genpd_sync_power_off()
1110 genpd_unlock(link->parent); in genpd_sync_power_off()
1115 * genpd_sync_power_on - Synchronously power on a PM domain and its parents.
1116 * @genpd: PM domain to power on.
1132 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_on()
1133 genpd_sd_counter_inc(link->parent); in genpd_sync_power_on()
1136 genpd_lock_nested(link->parent, depth + 1); in genpd_sync_power_on()
1138 genpd_sync_power_on(link->parent, use_lock, depth + 1); in genpd_sync_power_on()
1141 genpd_unlock(link->parent); in genpd_sync_power_on()
1145 genpd->status = GENPD_STATE_ON; in genpd_sync_power_on()
1149 * genpd_prepare - Start power transition of a device in a PM domain.
1152 * Start a power transition of a device (during a system-wide power transition)
1153 * under the assumption that its pm_domain field points to the domain member of
1154 * an object of type struct generic_pm_domain representing a PM domain
1166 return -EINVAL; in genpd_prepare()
1170 if (genpd->prepared_count++ == 0) in genpd_prepare()
1171 genpd->suspended_count = 0; in genpd_prepare()
1179 genpd->prepared_count--; in genpd_prepare()
1189 * genpd_finish_suspend - Completion of suspend or hibernation of device in an
1190 * I/O pm domain.
1194 * Stop the device and remove power from the domain if all devices in it have
1204 return -EINVAL; in genpd_finish_suspend()
1216 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_suspend()
1229 genpd->suspended_count++; in genpd_finish_suspend()
1237 * genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
1240 * Stop the device and remove power from the domain if all devices in it have
1251 * genpd_resume_noirq - Start of resume of device in an I/O PM domain.
1254 * Restore power to the device's PM domain, if necessary, and start the device.
1265 return -EINVAL; in genpd_resume_noirq()
1272 genpd->suspended_count--; in genpd_resume_noirq()
1275 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_resume_noirq()
1286 * genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
1290 * pm_domain field points to the domain member of an object of type
1291 * struct generic_pm_domain representing a power domain consisting of I/O
1303 return -EINVAL; in genpd_freeze_noirq()
1309 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_freeze_noirq()
1317 * genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
1320 * Start the device, unless power has been removed from the domain already
1332 return -EINVAL; in genpd_thaw_noirq()
1334 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_thaw_noirq()
1345 * genpd_poweroff_noirq - Completion of hibernation of device in an
1346 * I/O PM domain.
1349 * Stop the device and remove power from the domain if all devices in it have
1360 * genpd_restore_noirq - Start of restore of device in an I/O PM domain.
1363 * Make sure the domain will be in the same power state as before the
1375 return -EINVAL; in genpd_restore_noirq()
1379 * first time for the given domain in the present cycle. in genpd_restore_noirq()
1382 if (genpd->suspended_count++ == 0) { in genpd_restore_noirq()
1384 * The boot kernel might put the domain into arbitrary state, in genpd_restore_noirq()
1388 genpd->status = GENPD_STATE_OFF; in genpd_restore_noirq()
1394 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_restore_noirq()
1405 * genpd_complete - Complete power transition of a device in a power domain.
1408 * Complete a power transition of a device (during a system-wide power
1410 * domain member of an object of type struct generic_pm_domain representing
1411 * a power domain consisting of I/O devices.
1427 genpd->prepared_count--; in genpd_complete()
1428 if (!genpd->prepared_count) in genpd_complete()
1449 genpd->suspended_count++; in genpd_switch_state()
1453 genpd->suspended_count--; in genpd_switch_state()
1461 * dev_pm_genpd_suspend - Synchronously try to suspend the genpd for @dev
1466 * suspend-to-idle to suspend a corresponding CPU device that is attached to a
1476 * dev_pm_genpd_resume - Synchronously try to resume the genpd for @dev
1480 * during the syscore resume phase. It may also be called during suspend-to-idle
1515 ret = -ENOMEM; in genpd_alloc_dev_data()
1519 gpd_data->base.dev = dev; in genpd_alloc_dev_data()
1520 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; in genpd_alloc_dev_data()
1526 ret = -ENOMEM; in genpd_alloc_dev_data()
1530 td->constraint_changed = true; in genpd_alloc_dev_data()
1531 td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS; in genpd_alloc_dev_data()
1532 td->next_wakeup = KTIME_MAX; in genpd_alloc_dev_data()
1533 gpd_data->td = td; in genpd_alloc_dev_data()
1536 spin_lock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1538 if (dev->power.subsys_data->domain_data) in genpd_alloc_dev_data()
1539 ret = -EINVAL; in genpd_alloc_dev_data()
1541 dev->power.subsys_data->domain_data = &gpd_data->base; in genpd_alloc_dev_data()
1543 spin_unlock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1551 kfree(gpd_data->td); in genpd_alloc_dev_data()
1561 spin_lock_irq(&dev->power.lock); in genpd_free_dev_data()
1563 dev->power.subsys_data->domain_data = NULL; in genpd_free_dev_data()
1565 spin_unlock_irq(&dev->power.lock); in genpd_free_dev_data()
1567 kfree(gpd_data->td); in genpd_free_dev_data()
1580 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_update_cpumask()
1581 struct generic_pm_domain *parent = link->parent; in genpd_update_cpumask()
1589 cpumask_set_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1591 cpumask_clear_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1611 return -1; in genpd_get_cpu()
1618 return -1; in genpd_get_cpu()
1624 struct genpd_governor_data *gd = genpd->gd; in genpd_add_device()
1631 return -EINVAL; in genpd_add_device()
1637 gpd_data->cpu = genpd_get_cpu(genpd, base_dev); in genpd_add_device()
1639 ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; in genpd_add_device()
1645 genpd_set_cpumask(genpd, gpd_data->cpu); in genpd_add_device()
1646 dev_pm_domain_set(dev, &genpd->domain); in genpd_add_device()
1648 genpd->device_count++; in genpd_add_device()
1650 gd->max_off_time_changed = true; in genpd_add_device()
1652 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); in genpd_add_device()
1659 dev_pm_qos_add_notifier(dev, &gpd_data->nb, in genpd_add_device()
1666 * pm_genpd_add_device - Add a device to an I/O PM domain.
1667 * @genpd: PM domain to add the device to.
1691 pdd = dev->power.subsys_data->domain_data; in genpd_remove_device()
1693 dev_pm_qos_remove_notifier(dev, &gpd_data->nb, in genpd_remove_device()
1698 if (genpd->prepared_count > 0) { in genpd_remove_device()
1699 ret = -EAGAIN; in genpd_remove_device()
1703 genpd->device_count--; in genpd_remove_device()
1704 if (genpd->gd) in genpd_remove_device()
1705 genpd->gd->max_off_time_changed = true; in genpd_remove_device()
1707 genpd_clear_cpumask(genpd, gpd_data->cpu); in genpd_remove_device()
1710 list_del_init(&pdd->list_node); in genpd_remove_device()
1714 if (genpd->detach_dev) in genpd_remove_device()
1715 genpd->detach_dev(genpd, dev); in genpd_remove_device()
1723 dev_pm_qos_add_notifier(dev, &gpd_data->nb, DEV_PM_QOS_RESUME_LATENCY); in genpd_remove_device()
1729 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1737 return -EINVAL; in pm_genpd_remove_device()
1744 * dev_pm_genpd_add_notifier - Add a genpd power on/off notifier for @dev
1751 * sent when genpd is powering on/off the PM domain.
1766 return -ENODEV; in dev_pm_genpd_add_notifier()
1768 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_add_notifier()
1769 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_add_notifier()
1770 return -EINVAL; in dev_pm_genpd_add_notifier()
1772 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_add_notifier()
1773 if (gpd_data->power_nb) in dev_pm_genpd_add_notifier()
1774 return -EEXIST; in dev_pm_genpd_add_notifier()
1777 ret = raw_notifier_chain_register(&genpd->power_notifiers, nb); in dev_pm_genpd_add_notifier()
1781 dev_warn(dev, "failed to add notifier for PM domain %s\n", in dev_pm_genpd_add_notifier()
1782 genpd->name); in dev_pm_genpd_add_notifier()
1786 gpd_data->power_nb = nb; in dev_pm_genpd_add_notifier()
1792 * dev_pm_genpd_remove_notifier - Remove a genpd power on/off notifier for @dev
1812 return -ENODEV; in dev_pm_genpd_remove_notifier()
1814 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_remove_notifier()
1815 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_remove_notifier()
1816 return -EINVAL; in dev_pm_genpd_remove_notifier()
1818 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_remove_notifier()
1819 if (!gpd_data->power_nb) in dev_pm_genpd_remove_notifier()
1820 return -ENODEV; in dev_pm_genpd_remove_notifier()
1823 ret = raw_notifier_chain_unregister(&genpd->power_notifiers, in dev_pm_genpd_remove_notifier()
1824 gpd_data->power_nb); in dev_pm_genpd_remove_notifier()
1828 dev_warn(dev, "failed to remove notifier for PM domain %s\n", in dev_pm_genpd_remove_notifier()
1829 genpd->name); in dev_pm_genpd_remove_notifier()
1833 gpd_data->power_nb = NULL; in dev_pm_genpd_remove_notifier()
1846 return -EINVAL; in genpd_add_subdomain()
1849 * If the domain can be powered on/off in an IRQ safe in genpd_add_subdomain()
1855 genpd->name, subdomain->name); in genpd_add_subdomain()
1856 return -EINVAL; in genpd_add_subdomain()
1861 return -ENOMEM; in genpd_add_subdomain()
1867 ret = -EINVAL; in genpd_add_subdomain()
1871 list_for_each_entry(itr, &genpd->parent_links, parent_node) { in genpd_add_subdomain()
1872 if (itr->child == subdomain && itr->parent == genpd) { in genpd_add_subdomain()
1873 ret = -EINVAL; in genpd_add_subdomain()
1878 link->parent = genpd; in genpd_add_subdomain()
1879 list_add_tail(&link->parent_node, &genpd->parent_links); in genpd_add_subdomain()
1880 link->child = subdomain; in genpd_add_subdomain()
1881 list_add_tail(&link->child_node, &subdomain->child_links); in genpd_add_subdomain()
1894 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1895 * @genpd: Leader PM domain to add the subdomain to.
1912 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1913 * @genpd: Leader PM domain to remove the subdomain from.
1920 int ret = -EINVAL; in pm_genpd_remove_subdomain()
1923 return -EINVAL; in pm_genpd_remove_subdomain()
1928 if (!list_empty(&subdomain->parent_links) || subdomain->device_count) { in pm_genpd_remove_subdomain()
1930 genpd->name, subdomain->name); in pm_genpd_remove_subdomain()
1931 ret = -EBUSY; in pm_genpd_remove_subdomain()
1935 list_for_each_entry_safe(link, l, &genpd->parent_links, parent_node) { in pm_genpd_remove_subdomain()
1936 if (link->child != subdomain) in pm_genpd_remove_subdomain()
1939 list_del(&link->parent_node); in pm_genpd_remove_subdomain()
1940 list_del(&link->child_node); in pm_genpd_remove_subdomain()
1957 static void genpd_free_default_power_state(struct genpd_power_state *states, in genpd_free_default_power_state() argument
1960 kfree(states); in genpd_free_default_power_state()
1969 return -ENOMEM; in genpd_set_default_power_state()
1971 genpd->states = state; in genpd_set_default_power_state()
1972 genpd->state_count = 1; in genpd_set_default_power_state()
1973 genpd->free_states = genpd_free_default_power_state; in genpd_set_default_power_state()
1984 !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL)) in genpd_alloc_data()
1985 return -ENOMEM; in genpd_alloc_data()
1987 if (genpd->gov) { in genpd_alloc_data()
1990 ret = -ENOMEM; in genpd_alloc_data()
1994 gd->max_off_time_ns = -1; in genpd_alloc_data()
1995 gd->max_off_time_changed = true; in genpd_alloc_data()
1996 gd->next_wakeup = KTIME_MAX; in genpd_alloc_data()
1999 /* Use only one "off" state if there were no states declared */ in genpd_alloc_data()
2000 if (genpd->state_count == 0) { in genpd_alloc_data()
2006 genpd->gd = gd; in genpd_alloc_data()
2011 free_cpumask_var(genpd->cpus); in genpd_alloc_data()
2019 free_cpumask_var(genpd->cpus); in genpd_free_data()
2020 if (genpd->free_states) in genpd_free_data()
2021 genpd->free_states(genpd->states, genpd->state_count); in genpd_free_data()
2022 kfree(genpd->gd); in genpd_free_data()
2027 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) { in genpd_lock_init()
2028 spin_lock_init(&genpd->slock); in genpd_lock_init()
2029 genpd->lock_ops = &genpd_spin_ops; in genpd_lock_init()
2031 mutex_init(&genpd->mlock); in genpd_lock_init()
2032 genpd->lock_ops = &genpd_mtx_ops; in genpd_lock_init()
2037 * pm_genpd_init - Initialize a generic I/O PM domain object.
2038 * @genpd: PM domain object to initialize.
2039 * @gov: PM domain governor to associate with the domain (may be NULL).
2040 * @is_off: Initial value of the domain's power_is_off field.
2050 return -EINVAL; in pm_genpd_init()
2052 INIT_LIST_HEAD(&genpd->parent_links); in pm_genpd_init()
2053 INIT_LIST_HEAD(&genpd->child_links); in pm_genpd_init()
2054 INIT_LIST_HEAD(&genpd->dev_list); in pm_genpd_init()
2055 RAW_INIT_NOTIFIER_HEAD(&genpd->power_notifiers); in pm_genpd_init()
2057 genpd->gov = gov; in pm_genpd_init()
2058 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); in pm_genpd_init()
2059 atomic_set(&genpd->sd_count, 0); in pm_genpd_init()
2060 genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON; in pm_genpd_init()
2061 genpd->device_count = 0; in pm_genpd_init()
2062 genpd->provider = NULL; in pm_genpd_init()
2063 genpd->has_provider = false; in pm_genpd_init()
2064 genpd->accounting_time = ktime_get_mono_fast_ns(); in pm_genpd_init()
2065 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; in pm_genpd_init()
2066 genpd->domain.ops.runtime_resume = genpd_runtime_resume; in pm_genpd_init()
2067 genpd->domain.ops.prepare = genpd_prepare; in pm_genpd_init()
2068 genpd->domain.ops.suspend_noirq = genpd_suspend_noirq; in pm_genpd_init()
2069 genpd->domain.ops.resume_noirq = genpd_resume_noirq; in pm_genpd_init()
2070 genpd->domain.ops.freeze_noirq = genpd_freeze_noirq; in pm_genpd_init()
2071 genpd->domain.ops.thaw_noirq = genpd_thaw_noirq; in pm_genpd_init()
2072 genpd->domain.ops.poweroff_noirq = genpd_poweroff_noirq; in pm_genpd_init()
2073 genpd->domain.ops.restore_noirq = genpd_restore_noirq; in pm_genpd_init()
2074 genpd->domain.ops.complete = genpd_complete; in pm_genpd_init()
2075 genpd->domain.start = genpd_dev_pm_start; in pm_genpd_init()
2077 if (genpd->flags & GENPD_FLAG_PM_CLK) { in pm_genpd_init()
2078 genpd->dev_ops.stop = pm_clk_suspend; in pm_genpd_init()
2079 genpd->dev_ops.start = pm_clk_resume; in pm_genpd_init()
2082 /* The always-on governor works better with the corresponding flag. */ in pm_genpd_init()
2084 genpd->flags |= GENPD_FLAG_RPM_ALWAYS_ON; in pm_genpd_init()
2086 /* Always-on domains must be powered on at initialization. */ in pm_genpd_init()
2089 pr_err("always-on PM domain %s is not on\n", genpd->name); in pm_genpd_init()
2090 return -EINVAL; in pm_genpd_init()
2093 /* Multiple states but no governor doesn't make sense. */ in pm_genpd_init()
2094 if (!gov && genpd->state_count > 1) in pm_genpd_init()
2095 pr_warn("%s: no governor for states\n", genpd->name); in pm_genpd_init()
2101 device_initialize(&genpd->dev); in pm_genpd_init()
2102 dev_set_name(&genpd->dev, "%s", genpd->name); in pm_genpd_init()
2105 list_add(&genpd->gpd_list_node, &gpd_list); in pm_genpd_init()
2118 return -EINVAL; in genpd_remove()
2122 if (genpd->has_provider) { in genpd_remove()
2124 pr_err("Provider present, unable to remove %s\n", genpd->name); in genpd_remove()
2125 return -EBUSY; in genpd_remove()
2128 if (!list_empty(&genpd->parent_links) || genpd->device_count) { in genpd_remove()
2130 pr_err("%s: unable to remove %s\n", __func__, genpd->name); in genpd_remove()
2131 return -EBUSY; in genpd_remove()
2134 list_for_each_entry_safe(link, l, &genpd->child_links, child_node) { in genpd_remove()
2135 list_del(&link->parent_node); in genpd_remove()
2136 list_del(&link->child_node); in genpd_remove()
2140 list_del(&genpd->gpd_list_node); in genpd_remove()
2143 cancel_work_sync(&genpd->power_off_work); in genpd_remove()
2146 pr_debug("%s: removed %s\n", __func__, genpd->name); in genpd_remove()
2152 * pm_genpd_remove - Remove a generic I/O PM domain
2153 * @genpd: Pointer to PM domain that is to be removed.
2155 * To remove the PM domain, this function:
2156 * - Removes the PM domain as a subdomain to any parent domains,
2158 * - Removes the PM domain from the list of registered PM domains.
2160 * The PM domain will only be removed, if the associated provider has
2161 * been removed, it is not a parent to any other PM domain and has no
2179 * Device Tree based PM domain providers.
2181 * The code below implements generic device tree based PM domain providers that
2185 * devices to these domains is supposed to register a PM domain provider, which
2186 * maps a PM domain specifier retrieved from the device tree to a PM domain.
2189 * - genpd_xlate_simple() for 1:1 device tree node to PM domain mapping.
2190 * - genpd_xlate_onecell() for mapping of multiple PM domains per node by
2195 * struct of_genpd_provider - PM domain provider registration structure
2196 * @link: Entry in global list of PM domain providers
2197 * @node: Pointer to device tree node of PM domain provider
2198 * @xlate: Provider-specific xlate callback mapping a set of specifier cells
2199 * into a PM domain.
2209 /* List of registered PM domain providers. */
2215 * genpd_xlate_simple() - Xlate function for direct node-domain mapping
2216 * @genpdspec: OF phandle args to map into a PM domain
2217 * @data: xlate function private data - pointer to struct generic_pm_domain
2231 * genpd_xlate_onecell() - Xlate function using a single index.
2232 * @genpdspec: OF phandle args to map into a PM domain
2233 * @data: xlate function private data - pointer to struct genpd_onecell_data
2235 * This is a generic xlate function that can be used to model simple PM domain
2245 unsigned int idx = genpdspec->args[0]; in genpd_xlate_onecell()
2247 if (genpdspec->args_count != 1) in genpd_xlate_onecell()
2248 return ERR_PTR(-EINVAL); in genpd_xlate_onecell()
2250 if (idx >= genpd_data->num_domains) { in genpd_xlate_onecell()
2251 pr_err("%s: invalid domain index %u\n", __func__, idx); in genpd_xlate_onecell()
2252 return ERR_PTR(-EINVAL); in genpd_xlate_onecell()
2255 if (!genpd_data->domains[idx]) in genpd_xlate_onecell()
2256 return ERR_PTR(-ENOENT); in genpd_xlate_onecell()
2258 return genpd_data->domains[idx]; in genpd_xlate_onecell()
2262 * genpd_add_provider() - Register a PM domain provider for a node
2263 * @np: Device node pointer associated with the PM domain provider.
2264 * @xlate: Callback for decoding PM domain from phandle arguments.
2274 return -ENOMEM; in genpd_add_provider()
2276 cp->node = of_node_get(np); in genpd_add_provider()
2277 cp->data = data; in genpd_add_provider()
2278 cp->xlate = xlate; in genpd_add_provider()
2279 fwnode_dev_initialized(&np->fwnode, true); in genpd_add_provider()
2282 list_add(&cp->link, &of_genpd_providers); in genpd_add_provider()
2284 pr_debug("Added domain provider from %pOF\n", np); in genpd_add_provider()
2307 * of_genpd_add_provider_simple() - Register a simple PM domain provider
2308 * @np: Device node pointer associated with the PM domain provider.
2309 * @genpd: Pointer to PM domain associated with the PM domain provider.
2317 return -EINVAL; in of_genpd_add_provider_simple()
2320 return -EINVAL; in of_genpd_add_provider_simple()
2322 genpd->dev.of_node = np; in of_genpd_add_provider_simple()
2325 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
2326 ret = dev_pm_opp_of_add_table(&genpd->dev); in of_genpd_add_provider_simple()
2328 return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n"); in of_genpd_add_provider_simple()
2334 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_simple()
2335 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_simple()
2340 if (genpd->set_performance_state) { in of_genpd_add_provider_simple()
2341 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_simple()
2342 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_simple()
2348 genpd->provider = &np->fwnode; in of_genpd_add_provider_simple()
2349 genpd->has_provider = true; in of_genpd_add_provider_simple()
2356 * of_genpd_add_provider_onecell() - Register a onecell PM domain provider
2357 * @np: Device node pointer associated with the PM domain provider.
2358 * @data: Pointer to the data associated with the PM domain provider.
2365 int ret = -EINVAL; in of_genpd_add_provider_onecell()
2368 return -EINVAL; in of_genpd_add_provider_onecell()
2370 if (!data->xlate) in of_genpd_add_provider_onecell()
2371 data->xlate = genpd_xlate_onecell; in of_genpd_add_provider_onecell()
2373 for (i = 0; i < data->num_domains; i++) { in of_genpd_add_provider_onecell()
2374 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2381 genpd->dev.of_node = np; in of_genpd_add_provider_onecell()
2384 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2385 ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); in of_genpd_add_provider_onecell()
2387 dev_err_probe(&genpd->dev, ret, in of_genpd_add_provider_onecell()
2396 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_onecell()
2397 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_onecell()
2400 genpd->provider = &np->fwnode; in of_genpd_add_provider_onecell()
2401 genpd->has_provider = true; in of_genpd_add_provider_onecell()
2404 ret = genpd_add_provider(np, data->xlate, data); in of_genpd_add_provider_onecell()
2411 while (i--) { in of_genpd_add_provider_onecell()
2412 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2417 genpd->provider = NULL; in of_genpd_add_provider_onecell()
2418 genpd->has_provider = false; in of_genpd_add_provider_onecell()
2420 if (genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2421 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_onecell()
2422 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_onecell()
2431 * of_genpd_del_provider() - Remove a previously registered PM domain provider
2432 * @np: Device node pointer associated with the PM domain provider
2442 if (cp->node == np) { in of_genpd_del_provider()
2444 * For each PM domain associated with the in of_genpd_del_provider()
2446 * so that the PM domain can be safely removed. in of_genpd_del_provider()
2449 if (gpd->provider == &np->fwnode) { in of_genpd_del_provider()
2450 gpd->has_provider = false; in of_genpd_del_provider()
2452 if (!gpd->set_performance_state) in of_genpd_del_provider()
2455 dev_pm_opp_put_opp_table(gpd->opp_table); in of_genpd_del_provider()
2456 dev_pm_opp_of_remove_table(&gpd->dev); in of_genpd_del_provider()
2460 fwnode_dev_initialized(&cp->node->fwnode, false); in of_genpd_del_provider()
2461 list_del(&cp->link); in of_genpd_del_provider()
2462 of_node_put(cp->node); in of_genpd_del_provider()
2473 * genpd_get_from_provider() - Look-up PM domain
2474 * @genpdspec: OF phandle args to use for look-up
2476 * Looks for a PM domain provider under the node specified by @genpdspec and if
2478 * domain.
2486 struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); in genpd_get_from_provider()
2490 return ERR_PTR(-EINVAL); in genpd_get_from_provider()
2496 if (provider->node == genpdspec->np) in genpd_get_from_provider()
2497 genpd = provider->xlate(genpdspec, provider->data); in genpd_get_from_provider()
2508 * of_genpd_add_device() - Add a device to an I/O PM domain
2509 * @genpdspec: OF phandle args to use for look-up PM domain
2512 * Looks-up an I/O PM domain based upon phandle args provided and adds
2513 * the device to the PM domain. Returns a negative error code on failure.
2538 * of_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
2539 * @parent_spec: OF phandle args to use for parent PM domain look-up
2540 * @subdomain_spec: OF phandle args to use for subdomain look-up
2542 * Looks-up a parent PM domain and subdomain based upon phandle args
2543 * provided and adds the subdomain to the parent PM domain. Returns a
2571 return ret == -ENOENT ? -EPROBE_DEFER : ret; in of_genpd_add_subdomain()
2576 * of_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
2577 * @parent_spec: OF phandle args to use for parent PM domain look-up
2578 * @subdomain_spec: OF phandle args to use for subdomain look-up
2580 * Looks-up a parent PM domain and subdomain based upon phandle args
2581 * provided and removes the subdomain from the parent PM domain. Returns a
2614 * of_genpd_remove_last - Remove the last PM domain registered for a provider
2617 * Find the last PM domain that was added by a particular provider and
2618 * remove this PM domain from the list of PM domains. The provider is
2620 * domain will only be removed, if the provider associated with domain
2628 struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT); in of_genpd_remove_last()
2632 return ERR_PTR(-EINVAL); in of_genpd_remove_last()
2636 if (gpd->provider == &np->fwnode) { in of_genpd_remove_last()
2650 of_node_put(dev->of_node); in genpd_release_dev()
2659 * genpd_dev_pm_detach - Detach a device from its PM domain.
2663 * Try to locate a corresponding generic PM domain, which the device was
2676 dev_dbg(dev, "removing from PM domain %s\n", pd->name); in genpd_dev_pm_detach()
2679 if (dev_gpd_data(dev)->default_pstate) { in genpd_dev_pm_detach()
2681 dev_gpd_data(dev)->default_pstate = 0; in genpd_dev_pm_detach()
2686 if (ret != -EAGAIN) in genpd_dev_pm_detach()
2694 dev_err(dev, "failed to remove from PM domain %s: %d", in genpd_dev_pm_detach()
2695 pd->name, ret); in genpd_dev_pm_detach()
2699 /* Check if PM domain can be powered off after removing this device. */ in genpd_dev_pm_detach()
2703 if (dev->bus == &genpd_bus_type) in genpd_dev_pm_detach()
2726 ret = of_parse_phandle_with_args(dev->of_node, "power-domains", in __genpd_dev_pm_attach()
2727 "#power-domain-cells", index, &pd_args); in __genpd_dev_pm_attach()
2736 dev_dbg(dev, "%s() failed to find PM domain: %ld\n", in __genpd_dev_pm_attach()
2741 dev_dbg(dev, "adding to PM domain %s\n", pd->name); in __genpd_dev_pm_attach()
2747 return dev_err_probe(dev, ret, "failed to add to PM domain %s\n", pd->name); in __genpd_dev_pm_attach()
2749 dev->pm_domain->detach = genpd_dev_pm_detach; in __genpd_dev_pm_attach()
2750 dev->pm_domain->sync = genpd_dev_pm_sync; in __genpd_dev_pm_attach()
2760 return -EPROBE_DEFER; in __genpd_dev_pm_attach()
2764 pstate = of_get_required_opp_performance_state(dev->of_node, index); in __genpd_dev_pm_attach()
2765 if (pstate < 0 && pstate != -ENODEV && pstate != -EOPNOTSUPP) { in __genpd_dev_pm_attach()
2772 dev_gpd_data(dev)->default_pstate = pstate; in __genpd_dev_pm_attach()
2777 dev_err(dev, "failed to set required performance state for power-domain %s: %d\n", in __genpd_dev_pm_attach()
2778 pd->name, ret); in __genpd_dev_pm_attach()
2784 * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
2787 * Parse device's OF node to find a PM domain specifier. If such is found,
2790 * Returns 1 on successfully attached PM domain, 0 when the device don't need a
2791 * PM domain or when multiple power-domains exists for it, else a negative error
2792 * code. Note that if a power-domain exists for the device, but it cannot be
2793 * found or turned on, then return -EPROBE_DEFER to ensure that the device is
2794 * not probed and to re-try again later.
2798 if (!dev->of_node) in genpd_dev_pm_attach()
2803 * can only attach one PM domain per device. in genpd_dev_pm_attach()
2805 if (of_count_phandle_with_args(dev->of_node, "power-domains", in genpd_dev_pm_attach()
2806 "#power-domain-cells") != 1) in genpd_dev_pm_attach()
2814 * genpd_dev_pm_attach_by_id - Associate a device with one of its PM domains.
2815 * @dev: The device used to lookup the PM domain.
2816 * @index: The index of the PM domain.
2818 * Parse device's OF node to find a PM domain specifier at the provided @index.
2820 * pm_domain ops. To deal with detaching of the virtual device, the ->detach()
2823 * Returns the created virtual device if successfully attached PM domain, NULL
2824 * when the device don't need a PM domain, else an ERR_PTR() in case of
2825 * failures. If a power-domain exists for the device, but cannot be found or
2826 * turned on, then ERR_PTR(-EPROBE_DEFER) is returned to ensure that the device
2827 * is not probed and to re-try again later.
2836 if (!dev->of_node) in genpd_dev_pm_attach_by_id()
2840 num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", in genpd_dev_pm_attach_by_id()
2841 "#power-domain-cells"); in genpd_dev_pm_attach_by_id()
2848 return ERR_PTR(-ENOMEM); in genpd_dev_pm_attach_by_id()
2851 virt_dev->bus = &genpd_bus_type; in genpd_dev_pm_attach_by_id()
2852 virt_dev->release = genpd_release_dev; in genpd_dev_pm_attach_by_id()
2853 virt_dev->of_node = of_node_get(dev->of_node); in genpd_dev_pm_attach_by_id()
2861 /* Try to attach the device to the PM domain at the specified index. */ in genpd_dev_pm_attach_by_id()
2876 * genpd_dev_pm_attach_by_name - Associate a device with one of its PM domains.
2877 * @dev: The device used to lookup the PM domain.
2878 * @name: The name of the PM domain.
2880 * Parse device's OF node to find a PM domain specifier using the
2881 * power-domain-names DT property. For further description see
2888 if (!dev->of_node) in genpd_dev_pm_attach_by_name()
2891 index = of_property_match_string(dev->of_node, "power-domain-names", in genpd_dev_pm_attach_by_name()
2900 { .compatible = "domain-idle-state", },
2911 err = of_property_read_u32(state_node, "entry-latency-us", in genpd_parse_state()
2914 pr_debug(" * %pOF missing entry-latency-us property\n", in genpd_parse_state()
2916 return -EINVAL; in genpd_parse_state()
2919 err = of_property_read_u32(state_node, "exit-latency-us", in genpd_parse_state()
2922 pr_debug(" * %pOF missing exit-latency-us property\n", in genpd_parse_state()
2924 return -EINVAL; in genpd_parse_state()
2927 err = of_property_read_u32(state_node, "min-residency-us", &residency); in genpd_parse_state()
2929 genpd_state->residency_ns = 1000 * residency; in genpd_parse_state()
2931 genpd_state->power_on_latency_ns = 1000 * exit_latency; in genpd_parse_state()
2932 genpd_state->power_off_latency_ns = 1000 * entry_latency; in genpd_parse_state()
2933 genpd_state->fwnode = &state_node->fwnode; in genpd_parse_state()
2939 struct genpd_power_state *states) in genpd_iterate_idle_states() argument
2946 ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL); in genpd_iterate_idle_states()
2948 return ret == -ENOENT ? 0 : ret; in genpd_iterate_idle_states()
2951 of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) { in genpd_iterate_idle_states()
2959 if (states) { in genpd_iterate_idle_states()
2960 ret = genpd_parse_state(&states[i], np); in genpd_iterate_idle_states()
2962 pr_err("Parsing idle state node %pOF failed with err %d\n", in genpd_iterate_idle_states()
2975 * of_genpd_parse_idle_states: Return array of idle states for the genpd.
2978 * @states: The pointer to which the state array will be saved.
2981 * Returns the device states parsed from the OF node. The memory for the states
2983 * free the memory after use. If any or zero compatible domain idle states is
2987 struct genpd_power_state **states, int *n) in of_genpd_parse_idle_states() argument
2997 *states = NULL; in of_genpd_parse_idle_states()
3004 return -ENOMEM; in of_genpd_parse_idle_states()
3009 return ret < 0 ? ret : -EINVAL; in of_genpd_parse_idle_states()
3012 *states = st; in of_genpd_parse_idle_states()
3020 * pm_genpd_opp_to_performance_state - Gets performance state of the genpd from its OPP node.
3022 * @genpd_dev: Genpd's device for which the performance-state needs to be found.
3027 * platform specific genpd->opp_to_performance_state() callback to translate
3028 * power domain OPP to performance state.
3040 if (unlikely(!genpd->opp_to_performance_state)) in pm_genpd_opp_to_performance_state()
3044 state = genpd->opp_to_performance_state(genpd, opp); in pm_genpd_opp_to_performance_state()
3077 if (dev->power.runtime_error) in rtpm_status_str()
3079 else if (dev->power.disable_depth) in rtpm_status_str()
3081 else if (dev->power.runtime_status < ARRAY_SIZE(status_lookup)) in rtpm_status_str()
3082 p = status_lookup[dev->power.runtime_status]; in rtpm_status_str()
3086 seq_printf(s, "%-25s ", p); in rtpm_status_str()
3093 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in perf_status_str()
3094 seq_put_decimal_ull(s, "", gpd_data->performance_state); in perf_status_str()
3112 return -ERESTARTSYS; in genpd_summary_one()
3114 if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) in genpd_summary_one()
3117 snprintf(state, sizeof(state), "%s-%u", in genpd_summary_one()
3118 status_lookup[genpd->status], genpd->state_idx); in genpd_summary_one()
3121 status_lookup[genpd->status]); in genpd_summary_one()
3122 seq_printf(s, "%-30s %-50s %u", genpd->name, state, genpd->performance_state); in genpd_summary_one()
3127 * Also genpd->name is immutable. in genpd_summary_one()
3129 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_summary_one()
3130 if (list_is_first(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
3132 seq_printf(s, "%s", link->child->name); in genpd_summary_one()
3133 if (!list_is_last(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
3137 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in genpd_summary_one()
3138 kobj_path = kobject_get_path(&pm_data->dev->kobj, in genpd_summary_one()
3144 seq_printf(s, "\n %-50s ", kobj_path); in genpd_summary_one()
3145 rtpm_status_str(s, pm_data->dev); in genpd_summary_one()
3146 perf_status_str(s, pm_data->dev); in genpd_summary_one()
3162 …seq_puts(s, "domain status children pe… in summary_show()
3164 …seq_puts(s, "-------------------------------------------------------------------------------------… in summary_show()
3168 return -ERESTARTSYS; in summary_show()
3187 struct generic_pm_domain *genpd = s->private; in status_show()
3192 return -ERESTARTSYS; in status_show()
3194 if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup))) in status_show()
3197 if (genpd->status == GENPD_STATE_OFF) in status_show()
3198 seq_printf(s, "%s-%u\n", status_lookup[genpd->status], in status_show()
3199 genpd->state_idx); in status_show()
3201 seq_printf(s, "%s\n", status_lookup[genpd->status]); in status_show()
3209 struct generic_pm_domain *genpd = s->private; in sub_domains_show()
3215 return -ERESTARTSYS; in sub_domains_show()
3217 list_for_each_entry(link, &genpd->parent_links, parent_node) in sub_domains_show()
3218 seq_printf(s, "%s\n", link->child->name); in sub_domains_show()
3226 struct generic_pm_domain *genpd = s->private; in idle_states_show()
3233 return -ERESTARTSYS; in idle_states_show()
3237 for (i = 0; i < genpd->state_count; i++) { in idle_states_show()
3238 idle_time += genpd->states[i].idle_time; in idle_states_show()
3240 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) { in idle_states_show()
3242 if (now > genpd->accounting_time) { in idle_states_show()
3243 delta = now - genpd->accounting_time; in idle_states_show()
3249 seq_printf(s, "S%-13i %-14llu %-14llu %llu\n", i, idle_time, in idle_states_show()
3250 genpd->states[i].usage, genpd->states[i].rejected); in idle_states_show()
3259 struct generic_pm_domain *genpd = s->private; in active_time_show()
3265 return -ERESTARTSYS; in active_time_show()
3267 if (genpd->status == GENPD_STATE_ON) { in active_time_show()
3269 if (now > genpd->accounting_time) in active_time_show()
3270 delta = now - genpd->accounting_time; in active_time_show()
3273 on_time = genpd->on_time + delta; in active_time_show()
3283 struct generic_pm_domain *genpd = s->private; in total_idle_time_show()
3290 return -ERESTARTSYS; in total_idle_time_show()
3292 for (i = 0; i < genpd->state_count; i++) { in total_idle_time_show()
3293 total += genpd->states[i].idle_time; in total_idle_time_show()
3295 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) { in total_idle_time_show()
3297 if (now > genpd->accounting_time) { in total_idle_time_show()
3298 delta = now - genpd->accounting_time; in total_idle_time_show()
3314 struct generic_pm_domain *genpd = s->private; in devices_show()
3321 return -ERESTARTSYS; in devices_show()
3323 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in devices_show()
3324 kobj_path = kobject_get_path(&pm_data->dev->kobj, in devices_show()
3340 struct generic_pm_domain *genpd = s->private; in perf_state_show()
3343 return -ERESTARTSYS; in perf_state_show()
3345 seq_printf(s, "%u\n", genpd->performance_state); in perf_state_show()
3367 d = debugfs_create_dir(genpd->name, genpd_debugfs_dir); in genpd_debug_add()
3381 if (genpd->set_performance_state) in genpd_debug_add()