Lines Matching +full:cpu +full:- +full:centric
1 // SPDX-License-Identifier: GPL-2.0
3 * drivers/base/power/domain.c - Common code related to device power domains.
23 #include <linux/cpu.h>
33 __routine = genpd->dev_ops.callback; \
52 mutex_lock(&genpd->mlock); in genpd_lock_mtx()
58 mutex_lock_nested(&genpd->mlock, depth); in genpd_lock_nested_mtx()
63 return mutex_lock_interruptible(&genpd->mlock); in genpd_lock_interruptible_mtx()
68 return mutex_unlock(&genpd->mlock); in genpd_unlock_mtx()
79 __acquires(&genpd->slock) in genpd_lock_spin()
83 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_spin()
84 genpd->lock_flags = flags; in genpd_lock_spin()
89 __acquires(&genpd->slock) in genpd_lock_nested_spin()
93 spin_lock_irqsave_nested(&genpd->slock, flags, depth); in genpd_lock_nested_spin()
94 genpd->lock_flags = flags; in genpd_lock_nested_spin()
98 __acquires(&genpd->slock) in genpd_lock_interruptible_spin()
102 spin_lock_irqsave(&genpd->slock, flags); in genpd_lock_interruptible_spin()
103 genpd->lock_flags = flags; in genpd_lock_interruptible_spin()
108 __releases(&genpd->slock) in genpd_unlock_spin()
110 spin_unlock_irqrestore(&genpd->slock, genpd->lock_flags); in genpd_unlock_spin()
120 #define genpd_lock(p) p->lock_ops->lock(p)
121 #define genpd_lock_nested(p, d) p->lock_ops->lock_nested(p, d)
122 #define genpd_lock_interruptible(p) p->lock_ops->lock_interruptible(p)
123 #define genpd_unlock(p) p->lock_ops->unlock(p)
125 #define genpd_status_on(genpd) (genpd->status == GENPD_STATE_ON)
126 #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE)
127 #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON)
128 #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP)
129 #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN)
130 #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON)
131 #define genpd_is_opp_table_fw(genpd) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW)
150 genpd->name); in irq_safe_dev_in_sleep_domain()
165 if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(dev->pm_domain)) in dev_to_genpd_safe()
168 /* A genpd's always have its ->runtime_suspend() callback assigned. */ in dev_to_genpd_safe()
169 if (dev->pm_domain->ops.runtime_suspend == genpd_runtime_suspend) in dev_to_genpd_safe()
170 return pd_to_genpd(dev->pm_domain); in dev_to_genpd_safe()
181 if (IS_ERR_OR_NULL(dev->pm_domain)) in dev_to_genpd()
182 return ERR_PTR(-EINVAL); in dev_to_genpd()
184 return pd_to_genpd(dev->pm_domain); in dev_to_genpd()
203 if (!WARN_ON(atomic_read(&genpd->sd_count) == 0)) in genpd_sd_counter_dec()
204 ret = !!atomic_dec_and_test(&genpd->sd_count); in genpd_sd_counter_dec()
211 atomic_inc(&genpd->sd_count); in genpd_sd_counter_inc()
225 debugfs_lookup_and_remove(genpd->name, genpd_debugfs_dir); in genpd_debug_remove()
233 if (now <= genpd->accounting_time) in genpd_update_accounting()
236 delta = now - genpd->accounting_time; in genpd_update_accounting()
239 * If genpd->status is active, it means we are just in genpd_update_accounting()
243 if (genpd->status == GENPD_STATE_ON) in genpd_update_accounting()
244 genpd->states[genpd->state_idx].idle_time += delta; in genpd_update_accounting()
246 genpd->on_time += delta; in genpd_update_accounting()
248 genpd->accounting_time = now; in genpd_update_accounting()
264 if (state == genpd->performance_state) in _genpd_reeval_performance_state()
268 if (state > genpd->performance_state) in _genpd_reeval_performance_state()
272 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in _genpd_reeval_performance_state()
275 if (pd_data->performance_state > state) in _genpd_reeval_performance_state()
276 state = pd_data->performance_state; in _genpd_reeval_performance_state()
280 * Traverse all sub-domains within the domain. This can be in _genpd_reeval_performance_state()
281 * done without any additional locking as the link->performance_state in _genpd_reeval_performance_state()
282 * field is protected by the parent genpd->lock, which is already taken. in _genpd_reeval_performance_state()
284 * Also note that link->performance_state (subdomain's performance state in _genpd_reeval_performance_state()
286 * link->child->performance_state (current performance state requirement in _genpd_reeval_performance_state()
287 * of the devices/sub-domains of the subdomain) and so can have a in _genpd_reeval_performance_state()
290 * Note that we also take vote from powered-off sub-domains into account in _genpd_reeval_performance_state()
293 list_for_each_entry(link, &genpd->parent_links, parent_node) { in _genpd_reeval_performance_state()
294 if (link->performance_state > state) in _genpd_reeval_performance_state()
295 state = link->performance_state; in _genpd_reeval_performance_state()
305 if (!parent->set_performance_state) in genpd_xlate_performance_state()
308 return dev_pm_opp_xlate_performance_state(genpd->opp_table, in genpd_xlate_performance_state()
309 parent->opp_table, in genpd_xlate_performance_state()
320 if (state == genpd->performance_state) in _genpd_set_performance_state()
324 list_for_each_entry(link, &genpd->child_links, child_node) { in _genpd_set_performance_state()
325 parent = link->parent; in _genpd_set_performance_state()
336 link->prev_performance_state = link->performance_state; in _genpd_set_performance_state()
337 link->performance_state = parent_state; in _genpd_set_performance_state()
342 link->performance_state = link->prev_performance_state; in _genpd_set_performance_state()
350 if (genpd->set_performance_state) { in _genpd_set_performance_state()
351 ret = genpd->set_performance_state(genpd, state); in _genpd_set_performance_state()
356 genpd->performance_state = state; in _genpd_set_performance_state()
361 list_for_each_entry_continue_reverse(link, &genpd->child_links, in _genpd_set_performance_state()
363 parent = link->parent; in _genpd_set_performance_state()
367 parent_state = link->prev_performance_state; in _genpd_set_performance_state()
368 link->performance_state = parent_state; in _genpd_set_performance_state()
374 parent->name, parent_state); in _genpd_set_performance_state()
390 prev_state = gpd_data->performance_state; in genpd_set_performance_state()
394 gpd_data->performance_state = state; in genpd_set_performance_state()
399 gpd_data->performance_state = prev_state; in genpd_set_performance_state()
406 unsigned int prev_state = dev_gpd_data(dev)->performance_state; in genpd_drop_performance_state()
429 dev_gpd_data(dev)->rpm_pstate = state; in genpd_dev_pm_set_performance_state()
433 dev_gpd_data(dev)->rpm_pstate = 0; in genpd_dev_pm_set_performance_state()
441 * dev_pm_genpd_set_performance_state- Set performance state of device's power
444 * @dev: Device for which the performance-state needs to be set.
461 return -ENODEV; in dev_pm_genpd_set_performance_state()
463 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_set_performance_state()
464 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_set_performance_state()
465 return -EINVAL; in dev_pm_genpd_set_performance_state()
472 * dev_pm_genpd_set_next_wakeup - Notify PM framework of an impending wakeup.
495 td = to_gpd_data(dev->power.subsys_data->domain_data)->td; in dev_pm_genpd_set_next_wakeup()
497 td->next_wakeup = next; in dev_pm_genpd_set_next_wakeup()
502 * dev_pm_genpd_get_next_hrtimer - Return the next_hrtimer for the genpd
519 if (genpd->gd) in dev_pm_genpd_get_next_hrtimer()
520 return genpd->gd->next_hrtimer; in dev_pm_genpd_get_next_hrtimer()
527 * dev_pm_genpd_synced_poweroff - Next power off should be synchronous
546 genpd->synced_poweroff = true; in dev_pm_genpd_synced_poweroff()
553 unsigned int state_idx = genpd->state_idx; in _genpd_power_on()
559 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_on()
566 if (!genpd->power_on) in _genpd_power_on()
569 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode; in _genpd_power_on()
571 ret = genpd->power_on(genpd); in _genpd_power_on()
579 ret = genpd->power_on(genpd); in _genpd_power_on()
584 if (elapsed_ns <= genpd->states[state_idx].power_on_latency_ns) in _genpd_power_on()
587 genpd->states[state_idx].power_on_latency_ns = elapsed_ns; in _genpd_power_on()
588 genpd->gd->max_off_time_changed = true; in _genpd_power_on()
589 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", in _genpd_power_on()
590 genpd->name, "on", elapsed_ns); in _genpd_power_on()
593 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_on()
594 genpd->synced_poweroff = false; in _genpd_power_on()
597 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_on()
604 unsigned int state_idx = genpd->state_idx; in _genpd_power_off()
610 ret = raw_notifier_call_chain_robust(&genpd->power_notifiers, in _genpd_power_off()
617 if (!genpd->power_off) in _genpd_power_off()
620 timed = timed && genpd->gd && !genpd->states[state_idx].fwnode; in _genpd_power_off()
622 ret = genpd->power_off(genpd); in _genpd_power_off()
630 ret = genpd->power_off(genpd); in _genpd_power_off()
635 if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) in _genpd_power_off()
638 genpd->states[state_idx].power_off_latency_ns = elapsed_ns; in _genpd_power_off()
639 genpd->gd->max_off_time_changed = true; in _genpd_power_off()
640 pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", in _genpd_power_off()
641 genpd->name, "off", elapsed_ns); in _genpd_power_off()
644 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF, in _genpd_power_off()
648 raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL); in _genpd_power_off()
653 * genpd_queue_power_off_work - Queue up the execution of genpd_power_off().
661 queue_work(pm_wq, &genpd->power_off_work); in genpd_queue_power_off_work()
665 * genpd_power_off - Remove power from a given PM domain.
667 * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the
689 if (!genpd_status_on(genpd) || genpd->prepared_count > 0) in genpd_power_off()
699 atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
700 return -EBUSY; in genpd_power_off()
703 * The children must be in their deepest (powered-off) states to allow in genpd_power_off()
708 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_power_off()
709 struct generic_pm_domain *child = link->child; in genpd_power_off()
710 if (child->state_idx < child->state_count - 1) in genpd_power_off()
711 return -EBUSY; in genpd_power_off()
714 list_for_each_entry(pdd, &genpd->dev_list, list_node) { in genpd_power_off()
717 * device is part of a non-IRQ safe domain. in genpd_power_off()
719 if (!pm_runtime_suspended(pdd->dev) || in genpd_power_off()
720 irq_safe_dev_in_sleep_domain(pdd->dev, genpd)) in genpd_power_off()
725 return -EBUSY; in genpd_power_off()
727 if (genpd->gov && genpd->gov->power_down_ok) { in genpd_power_off()
728 if (!genpd->gov->power_down_ok(&genpd->domain)) in genpd_power_off()
729 return -EAGAIN; in genpd_power_off()
733 if (!genpd->gov) in genpd_power_off()
734 genpd->state_idx = 0; in genpd_power_off()
737 if (atomic_read(&genpd->sd_count) > 0) in genpd_power_off()
738 return -EBUSY; in genpd_power_off()
742 genpd->states[genpd->state_idx].rejected++; in genpd_power_off()
746 genpd->status = GENPD_STATE_OFF; in genpd_power_off()
748 genpd->states[genpd->state_idx].usage++; in genpd_power_off()
750 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_off()
751 genpd_sd_counter_dec(link->parent); in genpd_power_off()
752 genpd_lock_nested(link->parent, depth + 1); in genpd_power_off()
753 genpd_power_off(link->parent, false, depth + 1); in genpd_power_off()
754 genpd_unlock(link->parent); in genpd_power_off()
761 * genpd_power_on - Restore power to a given PM domain and its parents.
781 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_power_on()
782 struct generic_pm_domain *parent = link->parent; in genpd_power_on()
800 genpd->status = GENPD_STATE_ON; in genpd_power_on()
807 &genpd->child_links, in genpd_power_on()
809 genpd_sd_counter_dec(link->parent); in genpd_power_on()
810 genpd_lock_nested(link->parent, depth + 1); in genpd_power_on()
811 genpd_power_off(link->parent, false, depth + 1); in genpd_power_on()
812 genpd_unlock(link->parent); in genpd_power_on()
832 dev = gpd_data->base.dev; in genpd_dev_pm_qos_notifier()
835 struct generic_pm_domain *genpd = ERR_PTR(-ENODATA); in genpd_dev_pm_qos_notifier()
839 spin_lock_irq(&dev->power.lock); in genpd_dev_pm_qos_notifier()
841 pdd = dev->power.subsys_data ? in genpd_dev_pm_qos_notifier()
842 dev->power.subsys_data->domain_data : NULL; in genpd_dev_pm_qos_notifier()
844 td = to_gpd_data(pdd)->td; in genpd_dev_pm_qos_notifier()
846 td->constraint_changed = true; in genpd_dev_pm_qos_notifier()
851 spin_unlock_irq(&dev->power.lock); in genpd_dev_pm_qos_notifier()
855 genpd->gd->max_off_time_changed = true; in genpd_dev_pm_qos_notifier()
859 dev = dev->parent; in genpd_dev_pm_qos_notifier()
860 if (!dev || dev->power.ignore_children) in genpd_dev_pm_qos_notifier()
868 * genpd_power_off_work_fn - Power off PM domain whose subdomain count is 0.
883 * __genpd_runtime_suspend - walk the hierarchy of ->runtime_suspend() callbacks
890 if (dev->type && dev->type->pm) in __genpd_runtime_suspend()
891 cb = dev->type->pm->runtime_suspend; in __genpd_runtime_suspend()
892 else if (dev->class && dev->class->pm) in __genpd_runtime_suspend()
893 cb = dev->class->pm->runtime_suspend; in __genpd_runtime_suspend()
894 else if (dev->bus && dev->bus->pm) in __genpd_runtime_suspend()
895 cb = dev->bus->pm->runtime_suspend; in __genpd_runtime_suspend()
899 if (!cb && dev->driver && dev->driver->pm) in __genpd_runtime_suspend()
900 cb = dev->driver->pm->runtime_suspend; in __genpd_runtime_suspend()
906 * __genpd_runtime_resume - walk the hierarchy of ->runtime_resume() callbacks
913 if (dev->type && dev->type->pm) in __genpd_runtime_resume()
914 cb = dev->type->pm->runtime_resume; in __genpd_runtime_resume()
915 else if (dev->class && dev->class->pm) in __genpd_runtime_resume()
916 cb = dev->class->pm->runtime_resume; in __genpd_runtime_resume()
917 else if (dev->bus && dev->bus->pm) in __genpd_runtime_resume()
918 cb = dev->bus->pm->runtime_resume; in __genpd_runtime_resume()
922 if (!cb && dev->driver && dev->driver->pm) in __genpd_runtime_resume()
923 cb = dev->driver->pm->runtime_resume; in __genpd_runtime_resume()
929 * genpd_runtime_suspend - Suspend a device belonging to I/O PM domain.
941 struct gpd_timing_data *td = gpd_data->td; in genpd_runtime_suspend()
951 return -EINVAL; in genpd_runtime_suspend()
954 * A runtime PM centric subsystem/driver may re-use the runtime PM in genpd_runtime_suspend()
959 suspend_ok = genpd->gov ? genpd->gov->suspend_ok : NULL; in genpd_runtime_suspend()
961 return -EBUSY; in genpd_runtime_suspend()
980 if (elapsed_ns > td->suspend_latency_ns) { in genpd_runtime_suspend()
981 td->suspend_latency_ns = elapsed_ns; in genpd_runtime_suspend()
984 genpd->gd->max_off_time_changed = true; in genpd_runtime_suspend()
985 td->constraint_changed = true; in genpd_runtime_suspend()
998 gpd_data->rpm_pstate = genpd_drop_performance_state(dev); in genpd_runtime_suspend()
1005 * genpd_runtime_resume - Resume a device belonging to I/O PM domain.
1016 struct gpd_timing_data *td = gpd_data->td; in genpd_runtime_resume()
1026 return -EINVAL; in genpd_runtime_resume()
1036 genpd_restore_performance_state(dev, gpd_data->rpm_pstate); in genpd_runtime_resume()
1059 if (elapsed_ns > td->resume_latency_ns) { in genpd_runtime_resume()
1060 td->resume_latency_ns = elapsed_ns; in genpd_runtime_resume()
1063 genpd->gd->max_off_time_changed = true; in genpd_runtime_resume()
1064 td->constraint_changed = true; in genpd_runtime_resume()
1076 gpd_data->rpm_pstate = genpd_drop_performance_state(dev); in genpd_runtime_resume()
1092 * genpd_power_off_unused - Power off all PM domains with no devices in use.
1117 * genpd_sync_power_off - Synchronously power off a PM domain and its parents.
1137 if (genpd->suspended_count != genpd->device_count in genpd_sync_power_off()
1138 || atomic_read(&genpd->sd_count) > 0) in genpd_sync_power_off()
1141 /* Check that the children are in their deepest (powered-off) state. */ in genpd_sync_power_off()
1142 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_sync_power_off()
1143 struct generic_pm_domain *child = link->child; in genpd_sync_power_off()
1144 if (child->state_idx < child->state_count - 1) in genpd_sync_power_off()
1149 genpd->state_idx = genpd->state_count - 1; in genpd_sync_power_off()
1153 genpd->status = GENPD_STATE_OFF; in genpd_sync_power_off()
1155 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_off()
1156 genpd_sd_counter_dec(link->parent); in genpd_sync_power_off()
1159 genpd_lock_nested(link->parent, depth + 1); in genpd_sync_power_off()
1161 genpd_sync_power_off(link->parent, use_lock, depth + 1); in genpd_sync_power_off()
1164 genpd_unlock(link->parent); in genpd_sync_power_off()
1169 * genpd_sync_power_on - Synchronously power on a PM domain and its parents.
1186 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_sync_power_on()
1187 genpd_sd_counter_inc(link->parent); in genpd_sync_power_on()
1190 genpd_lock_nested(link->parent, depth + 1); in genpd_sync_power_on()
1192 genpd_sync_power_on(link->parent, use_lock, depth + 1); in genpd_sync_power_on()
1195 genpd_unlock(link->parent); in genpd_sync_power_on()
1199 genpd->status = GENPD_STATE_ON; in genpd_sync_power_on()
1203 * genpd_prepare - Start power transition of a device in a PM domain.
1206 * Start a power transition of a device (during a system-wide power transition)
1220 return -EINVAL; in genpd_prepare()
1224 if (genpd->prepared_count++ == 0) in genpd_prepare()
1225 genpd->suspended_count = 0; in genpd_prepare()
1233 genpd->prepared_count--; in genpd_prepare()
1243 * genpd_finish_suspend - Completion of suspend or hibernation of device in an
1261 return -EINVAL; in genpd_finish_suspend()
1270 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_suspend()
1280 genpd->suspended_count++; in genpd_finish_suspend()
1288 * genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain.
1304 * genpd_finish_resume - Completion of resume of device in an I/O PM domain.
1320 return -EINVAL; in genpd_finish_resume()
1327 genpd->suspended_count--; in genpd_finish_resume()
1330 if (genpd->dev_ops.stop && genpd->dev_ops.start && in genpd_finish_resume()
1341 * genpd_resume_noirq - Start of resume of device in an I/O PM domain.
1354 * genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain.
1372 * genpd_thaw_noirq - Early thaw of device in an I/O PM domain.
1386 * genpd_poweroff_noirq - Completion of hibernation of device in an
1403 * genpd_restore_noirq - Start of restore of device in an I/O PM domain.
1417 * genpd_complete - Complete power transition of a device in a power domain.
1420 * Complete a power transition of a device (during a system-wide power
1439 genpd->prepared_count--; in genpd_complete()
1440 if (!genpd->prepared_count) in genpd_complete()
1461 genpd->suspended_count++; in genpd_switch_state()
1465 genpd->suspended_count--; in genpd_switch_state()
1473 * dev_pm_genpd_suspend - Synchronously try to suspend the genpd for @dev
1478 * suspend-to-idle to suspend a corresponding CPU device that is attached to a
1488 * dev_pm_genpd_resume - Synchronously try to resume the genpd for @dev
1492 * during the syscore resume phase. It may also be called during suspend-to-idle
1493 * to resume a corresponding CPU device that is attached to a genpd.
1527 ret = -ENOMEM; in genpd_alloc_dev_data()
1531 gpd_data->base.dev = dev; in genpd_alloc_dev_data()
1532 gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier; in genpd_alloc_dev_data()
1538 ret = -ENOMEM; in genpd_alloc_dev_data()
1542 td->constraint_changed = true; in genpd_alloc_dev_data()
1543 td->effective_constraint_ns = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT_NS; in genpd_alloc_dev_data()
1544 td->next_wakeup = KTIME_MAX; in genpd_alloc_dev_data()
1545 gpd_data->td = td; in genpd_alloc_dev_data()
1548 spin_lock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1550 if (dev->power.subsys_data->domain_data) in genpd_alloc_dev_data()
1551 ret = -EINVAL; in genpd_alloc_dev_data()
1553 dev->power.subsys_data->domain_data = &gpd_data->base; in genpd_alloc_dev_data()
1555 spin_unlock_irq(&dev->power.lock); in genpd_alloc_dev_data()
1563 kfree(gpd_data->td); in genpd_alloc_dev_data()
1573 spin_lock_irq(&dev->power.lock); in genpd_free_dev_data()
1575 dev->power.subsys_data->domain_data = NULL; in genpd_free_dev_data()
1577 spin_unlock_irq(&dev->power.lock); in genpd_free_dev_data()
1579 kfree(gpd_data->td); in genpd_free_dev_data()
1585 int cpu, bool set, unsigned int depth) in genpd_update_cpumask() argument
1592 list_for_each_entry(link, &genpd->child_links, child_node) { in genpd_update_cpumask()
1593 struct generic_pm_domain *parent = link->parent; in genpd_update_cpumask()
1596 genpd_update_cpumask(parent, cpu, set, depth + 1); in genpd_update_cpumask()
1601 cpumask_set_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1603 cpumask_clear_cpu(cpu, genpd->cpus); in genpd_update_cpumask()
1606 static void genpd_set_cpumask(struct generic_pm_domain *genpd, int cpu) in genpd_set_cpumask() argument
1608 if (cpu >= 0) in genpd_set_cpumask()
1609 genpd_update_cpumask(genpd, cpu, true, 0); in genpd_set_cpumask()
1612 static void genpd_clear_cpumask(struct generic_pm_domain *genpd, int cpu) in genpd_clear_cpumask() argument
1614 if (cpu >= 0) in genpd_clear_cpumask()
1615 genpd_update_cpumask(genpd, cpu, false, 0); in genpd_clear_cpumask()
1620 int cpu; in genpd_get_cpu() local
1623 return -1; in genpd_get_cpu()
1625 for_each_possible_cpu(cpu) { in genpd_get_cpu()
1626 if (get_cpu_device(cpu) == dev) in genpd_get_cpu()
1627 return cpu; in genpd_get_cpu()
1630 return -1; in genpd_get_cpu()
1636 struct genpd_governor_data *gd = genpd->gd; in genpd_add_device()
1646 gpd_data->cpu = genpd_get_cpu(genpd, base_dev); in genpd_add_device()
1648 ret = genpd->attach_dev ? genpd->attach_dev(genpd, dev) : 0; in genpd_add_device()
1654 genpd_set_cpumask(genpd, gpd_data->cpu); in genpd_add_device()
1655 dev_pm_domain_set(dev, &genpd->domain); in genpd_add_device()
1657 genpd->device_count++; in genpd_add_device()
1659 gd->max_off_time_changed = true; in genpd_add_device()
1661 list_add_tail(&gpd_data->base.list_node, &genpd->dev_list); in genpd_add_device()
1668 dev_pm_qos_add_notifier(dev, &gpd_data->nb, in genpd_add_device()
1675 * pm_genpd_add_device - Add a device to an I/O PM domain.
1684 return -EINVAL; in pm_genpd_add_device()
1703 pdd = dev->power.subsys_data->domain_data; in genpd_remove_device()
1705 dev_pm_qos_remove_notifier(dev, &gpd_data->nb, in genpd_remove_device()
1710 if (genpd->prepared_count > 0) { in genpd_remove_device()
1711 ret = -EAGAIN; in genpd_remove_device()
1715 genpd->device_count--; in genpd_remove_device()
1716 if (genpd->gd) in genpd_remove_device()
1717 genpd->gd->max_off_time_changed = true; in genpd_remove_device()
1719 genpd_clear_cpumask(genpd, gpd_data->cpu); in genpd_remove_device()
1722 list_del_init(&pdd->list_node); in genpd_remove_device()
1726 if (genpd->detach_dev) in genpd_remove_device()
1727 genpd->detach_dev(genpd, dev); in genpd_remove_device()
1735 dev_pm_qos_add_notifier(dev, &gpd_data->nb, DEV_PM_QOS_RESUME_LATENCY); in genpd_remove_device()
1741 * pm_genpd_remove_device - Remove a device from an I/O PM domain.
1749 return -EINVAL; in pm_genpd_remove_device()
1756 * dev_pm_genpd_add_notifier - Add a genpd power on/off notifier for @dev
1778 return -ENODEV; in dev_pm_genpd_add_notifier()
1780 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_add_notifier()
1781 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_add_notifier()
1782 return -EINVAL; in dev_pm_genpd_add_notifier()
1784 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_add_notifier()
1785 if (gpd_data->power_nb) in dev_pm_genpd_add_notifier()
1786 return -EEXIST; in dev_pm_genpd_add_notifier()
1789 ret = raw_notifier_chain_register(&genpd->power_notifiers, nb); in dev_pm_genpd_add_notifier()
1794 genpd->name); in dev_pm_genpd_add_notifier()
1798 gpd_data->power_nb = nb; in dev_pm_genpd_add_notifier()
1804 * dev_pm_genpd_remove_notifier - Remove a genpd power on/off notifier for @dev
1824 return -ENODEV; in dev_pm_genpd_remove_notifier()
1826 if (WARN_ON(!dev->power.subsys_data || in dev_pm_genpd_remove_notifier()
1827 !dev->power.subsys_data->domain_data)) in dev_pm_genpd_remove_notifier()
1828 return -EINVAL; in dev_pm_genpd_remove_notifier()
1830 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in dev_pm_genpd_remove_notifier()
1831 if (!gpd_data->power_nb) in dev_pm_genpd_remove_notifier()
1832 return -ENODEV; in dev_pm_genpd_remove_notifier()
1835 ret = raw_notifier_chain_unregister(&genpd->power_notifiers, in dev_pm_genpd_remove_notifier()
1836 gpd_data->power_nb); in dev_pm_genpd_remove_notifier()
1841 genpd->name); in dev_pm_genpd_remove_notifier()
1845 gpd_data->power_nb = NULL; in dev_pm_genpd_remove_notifier()
1858 return -EINVAL; in genpd_add_subdomain()
1867 genpd->name, subdomain->name); in genpd_add_subdomain()
1868 return -EINVAL; in genpd_add_subdomain()
1873 return -ENOMEM; in genpd_add_subdomain()
1879 ret = -EINVAL; in genpd_add_subdomain()
1883 list_for_each_entry(itr, &genpd->parent_links, parent_node) { in genpd_add_subdomain()
1884 if (itr->child == subdomain && itr->parent == genpd) { in genpd_add_subdomain()
1885 ret = -EINVAL; in genpd_add_subdomain()
1890 link->parent = genpd; in genpd_add_subdomain()
1891 list_add_tail(&link->parent_node, &genpd->parent_links); in genpd_add_subdomain()
1892 link->child = subdomain; in genpd_add_subdomain()
1893 list_add_tail(&link->child_node, &subdomain->child_links); in genpd_add_subdomain()
1906 * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
1924 * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
1932 int ret = -EINVAL; in pm_genpd_remove_subdomain()
1935 return -EINVAL; in pm_genpd_remove_subdomain()
1940 if (!list_empty(&subdomain->parent_links) || subdomain->device_count) { in pm_genpd_remove_subdomain()
1942 genpd->name, subdomain->name); in pm_genpd_remove_subdomain()
1943 ret = -EBUSY; in pm_genpd_remove_subdomain()
1947 list_for_each_entry_safe(link, l, &genpd->parent_links, parent_node) { in pm_genpd_remove_subdomain()
1948 if (link->child != subdomain) in pm_genpd_remove_subdomain()
1951 list_del(&link->parent_node); in pm_genpd_remove_subdomain()
1952 list_del(&link->child_node); in pm_genpd_remove_subdomain()
1981 return -ENOMEM; in genpd_set_default_power_state()
1983 genpd->states = state; in genpd_set_default_power_state()
1984 genpd->state_count = 1; in genpd_set_default_power_state()
1985 genpd->free_states = genpd_free_default_power_state; in genpd_set_default_power_state()
1996 !zalloc_cpumask_var(&genpd->cpus, GFP_KERNEL)) in genpd_alloc_data()
1997 return -ENOMEM; in genpd_alloc_data()
1999 if (genpd->gov) { in genpd_alloc_data()
2002 ret = -ENOMEM; in genpd_alloc_data()
2006 gd->max_off_time_ns = -1; in genpd_alloc_data()
2007 gd->max_off_time_changed = true; in genpd_alloc_data()
2008 gd->next_wakeup = KTIME_MAX; in genpd_alloc_data()
2009 gd->next_hrtimer = KTIME_MAX; in genpd_alloc_data()
2013 if (genpd->state_count == 0) { in genpd_alloc_data()
2019 genpd->gd = gd; in genpd_alloc_data()
2024 free_cpumask_var(genpd->cpus); in genpd_alloc_data()
2032 free_cpumask_var(genpd->cpus); in genpd_free_data()
2033 if (genpd->free_states) in genpd_free_data()
2034 genpd->free_states(genpd->states, genpd->state_count); in genpd_free_data()
2035 kfree(genpd->gd); in genpd_free_data()
2040 if (genpd->flags & GENPD_FLAG_IRQ_SAFE) { in genpd_lock_init()
2041 spin_lock_init(&genpd->slock); in genpd_lock_init()
2042 genpd->lock_ops = &genpd_spin_ops; in genpd_lock_init()
2044 mutex_init(&genpd->mlock); in genpd_lock_init()
2045 genpd->lock_ops = &genpd_mtx_ops; in genpd_lock_init()
2050 * pm_genpd_init - Initialize a generic I/O PM domain object.
2063 return -EINVAL; in pm_genpd_init()
2065 INIT_LIST_HEAD(&genpd->parent_links); in pm_genpd_init()
2066 INIT_LIST_HEAD(&genpd->child_links); in pm_genpd_init()
2067 INIT_LIST_HEAD(&genpd->dev_list); in pm_genpd_init()
2068 RAW_INIT_NOTIFIER_HEAD(&genpd->power_notifiers); in pm_genpd_init()
2070 genpd->gov = gov; in pm_genpd_init()
2071 INIT_WORK(&genpd->power_off_work, genpd_power_off_work_fn); in pm_genpd_init()
2072 atomic_set(&genpd->sd_count, 0); in pm_genpd_init()
2073 genpd->status = is_off ? GENPD_STATE_OFF : GENPD_STATE_ON; in pm_genpd_init()
2074 genpd->device_count = 0; in pm_genpd_init()
2075 genpd->provider = NULL; in pm_genpd_init()
2076 genpd->has_provider = false; in pm_genpd_init()
2077 genpd->accounting_time = ktime_get_mono_fast_ns(); in pm_genpd_init()
2078 genpd->domain.ops.runtime_suspend = genpd_runtime_suspend; in pm_genpd_init()
2079 genpd->domain.ops.runtime_resume = genpd_runtime_resume; in pm_genpd_init()
2080 genpd->domain.ops.prepare = genpd_prepare; in pm_genpd_init()
2081 genpd->domain.ops.suspend_noirq = genpd_suspend_noirq; in pm_genpd_init()
2082 genpd->domain.ops.resume_noirq = genpd_resume_noirq; in pm_genpd_init()
2083 genpd->domain.ops.freeze_noirq = genpd_freeze_noirq; in pm_genpd_init()
2084 genpd->domain.ops.thaw_noirq = genpd_thaw_noirq; in pm_genpd_init()
2085 genpd->domain.ops.poweroff_noirq = genpd_poweroff_noirq; in pm_genpd_init()
2086 genpd->domain.ops.restore_noirq = genpd_restore_noirq; in pm_genpd_init()
2087 genpd->domain.ops.complete = genpd_complete; in pm_genpd_init()
2088 genpd->domain.start = genpd_dev_pm_start; in pm_genpd_init()
2089 genpd->domain.set_performance_state = genpd_dev_pm_set_performance_state; in pm_genpd_init()
2091 if (genpd->flags & GENPD_FLAG_PM_CLK) { in pm_genpd_init()
2092 genpd->dev_ops.stop = pm_clk_suspend; in pm_genpd_init()
2093 genpd->dev_ops.start = pm_clk_resume; in pm_genpd_init()
2096 /* The always-on governor works better with the corresponding flag. */ in pm_genpd_init()
2098 genpd->flags |= GENPD_FLAG_RPM_ALWAYS_ON; in pm_genpd_init()
2100 /* Always-on domains must be powered on at initialization. */ in pm_genpd_init()
2103 pr_err("always-on PM domain %s is not on\n", genpd->name); in pm_genpd_init()
2104 return -EINVAL; in pm_genpd_init()
2108 if (!gov && genpd->state_count > 1) in pm_genpd_init()
2109 pr_warn("%s: no governor for states\n", genpd->name); in pm_genpd_init()
2115 device_initialize(&genpd->dev); in pm_genpd_init()
2116 dev_set_name(&genpd->dev, "%s", genpd->name); in pm_genpd_init()
2119 list_add(&genpd->gpd_list_node, &gpd_list); in pm_genpd_init()
2132 return -EINVAL; in genpd_remove()
2136 if (genpd->has_provider) { in genpd_remove()
2138 pr_err("Provider present, unable to remove %s\n", genpd->name); in genpd_remove()
2139 return -EBUSY; in genpd_remove()
2142 if (!list_empty(&genpd->parent_links) || genpd->device_count) { in genpd_remove()
2144 pr_err("%s: unable to remove %s\n", __func__, genpd->name); in genpd_remove()
2145 return -EBUSY; in genpd_remove()
2148 list_for_each_entry_safe(link, l, &genpd->child_links, child_node) { in genpd_remove()
2149 list_del(&link->parent_node); in genpd_remove()
2150 list_del(&link->child_node); in genpd_remove()
2154 list_del(&genpd->gpd_list_node); in genpd_remove()
2157 cancel_work_sync(&genpd->power_off_work); in genpd_remove()
2160 pr_debug("%s: removed %s\n", __func__, genpd->name); in genpd_remove()
2166 * pm_genpd_remove - Remove a generic I/O PM domain
2170 * - Removes the PM domain as a subdomain to any parent domains,
2172 * - Removes the PM domain from the list of registered PM domains.
2203 * - genpd_xlate_simple() for 1:1 device tree node to PM domain mapping.
2204 * - genpd_xlate_onecell() for mapping of multiple PM domains per node by
2209 * struct of_genpd_provider - PM domain provider registration structure
2212 * @xlate: Provider-specific xlate callback mapping a set of specifier cells
2229 * genpd_xlate_simple() - Xlate function for direct node-domain mapping
2231 * @data: xlate function private data - pointer to struct generic_pm_domain
2245 * genpd_xlate_onecell() - Xlate function using a single index.
2247 * @data: xlate function private data - pointer to struct genpd_onecell_data
2259 unsigned int idx = genpdspec->args[0]; in genpd_xlate_onecell()
2261 if (genpdspec->args_count != 1) in genpd_xlate_onecell()
2262 return ERR_PTR(-EINVAL); in genpd_xlate_onecell()
2264 if (idx >= genpd_data->num_domains) { in genpd_xlate_onecell()
2266 return ERR_PTR(-EINVAL); in genpd_xlate_onecell()
2269 if (!genpd_data->domains[idx]) in genpd_xlate_onecell()
2270 return ERR_PTR(-ENOENT); in genpd_xlate_onecell()
2272 return genpd_data->domains[idx]; in genpd_xlate_onecell()
2276 * genpd_add_provider() - Register a PM domain provider for a node
2288 return -ENOMEM; in genpd_add_provider()
2290 cp->node = of_node_get(np); in genpd_add_provider()
2291 cp->data = data; in genpd_add_provider()
2292 cp->xlate = xlate; in genpd_add_provider()
2293 fwnode_dev_initialized(&np->fwnode, true); in genpd_add_provider()
2296 list_add(&cp->link, &of_genpd_providers); in genpd_add_provider()
2321 * of_genpd_add_provider_simple() - Register a simple PM domain provider
2331 return -EINVAL; in of_genpd_add_provider_simple()
2334 return -EINVAL; in of_genpd_add_provider_simple()
2336 genpd->dev.of_node = np; in of_genpd_add_provider_simple()
2339 if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { in of_genpd_add_provider_simple()
2340 ret = dev_pm_opp_of_add_table(&genpd->dev); in of_genpd_add_provider_simple()
2342 return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n"); in of_genpd_add_provider_simple()
2348 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_simple()
2349 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_simple()
2354 if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { in of_genpd_add_provider_simple()
2355 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_simple()
2356 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_simple()
2362 genpd->provider = &np->fwnode; in of_genpd_add_provider_simple()
2363 genpd->has_provider = true; in of_genpd_add_provider_simple()
2370 * of_genpd_add_provider_onecell() - Register a onecell PM domain provider
2379 int ret = -EINVAL; in of_genpd_add_provider_onecell()
2382 return -EINVAL; in of_genpd_add_provider_onecell()
2384 if (!data->xlate) in of_genpd_add_provider_onecell()
2385 data->xlate = genpd_xlate_onecell; in of_genpd_add_provider_onecell()
2387 for (i = 0; i < data->num_domains; i++) { in of_genpd_add_provider_onecell()
2388 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2395 genpd->dev.of_node = np; in of_genpd_add_provider_onecell()
2398 if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2399 ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); in of_genpd_add_provider_onecell()
2401 dev_err_probe(&genpd->dev, ret, in of_genpd_add_provider_onecell()
2410 genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); in of_genpd_add_provider_onecell()
2411 WARN_ON(IS_ERR(genpd->opp_table)); in of_genpd_add_provider_onecell()
2414 genpd->provider = &np->fwnode; in of_genpd_add_provider_onecell()
2415 genpd->has_provider = true; in of_genpd_add_provider_onecell()
2418 ret = genpd_add_provider(np, data->xlate, data); in of_genpd_add_provider_onecell()
2425 while (i--) { in of_genpd_add_provider_onecell()
2426 genpd = data->domains[i]; in of_genpd_add_provider_onecell()
2431 genpd->provider = NULL; in of_genpd_add_provider_onecell()
2432 genpd->has_provider = false; in of_genpd_add_provider_onecell()
2434 if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { in of_genpd_add_provider_onecell()
2435 dev_pm_opp_put_opp_table(genpd->opp_table); in of_genpd_add_provider_onecell()
2436 dev_pm_opp_of_remove_table(&genpd->dev); in of_genpd_add_provider_onecell()
2445 * of_genpd_del_provider() - Remove a previously registered PM domain provider
2456 if (cp->node == np) { in of_genpd_del_provider()
2463 if (gpd->provider == &np->fwnode) { in of_genpd_del_provider()
2464 gpd->has_provider = false; in of_genpd_del_provider()
2466 if (genpd_is_opp_table_fw(gpd) || !gpd->set_performance_state) in of_genpd_del_provider()
2469 dev_pm_opp_put_opp_table(gpd->opp_table); in of_genpd_del_provider()
2470 dev_pm_opp_of_remove_table(&gpd->dev); in of_genpd_del_provider()
2474 fwnode_dev_initialized(&cp->node->fwnode, false); in of_genpd_del_provider()
2475 list_del(&cp->link); in of_genpd_del_provider()
2476 of_node_put(cp->node); in of_genpd_del_provider()
2487 * genpd_get_from_provider() - Look-up PM domain
2488 * @genpdspec: OF phandle args to use for look-up
2500 struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); in genpd_get_from_provider()
2504 return ERR_PTR(-EINVAL); in genpd_get_from_provider()
2510 if (provider->node == genpdspec->np) in genpd_get_from_provider()
2511 genpd = provider->xlate(genpdspec, provider->data); in genpd_get_from_provider()
2522 * of_genpd_add_device() - Add a device to an I/O PM domain
2523 * @genpdspec: OF phandle args to use for look-up PM domain
2526 * Looks-up an I/O PM domain based upon phandle args provided and adds
2535 return -EINVAL; in of_genpd_add_device()
2555 * of_genpd_add_subdomain - Add a subdomain to an I/O PM domain.
2556 * @parent_spec: OF phandle args to use for parent PM domain look-up
2557 * @subdomain_spec: OF phandle args to use for subdomain look-up
2559 * Looks-up a parent PM domain and subdomain based upon phandle args
2588 return ret == -ENOENT ? -EPROBE_DEFER : ret; in of_genpd_add_subdomain()
2593 * of_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
2594 * @parent_spec: OF phandle args to use for parent PM domain look-up
2595 * @subdomain_spec: OF phandle args to use for subdomain look-up
2597 * Looks-up a parent PM domain and subdomain based upon phandle args
2631 * of_genpd_remove_last - Remove the last PM domain registered for a provider
2645 struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT); in of_genpd_remove_last()
2649 return ERR_PTR(-EINVAL); in of_genpd_remove_last()
2653 if (gpd->provider == &np->fwnode) { in of_genpd_remove_last()
2667 of_node_put(dev->of_node); in genpd_release_dev()
2676 * genpd_dev_pm_detach - Detach a device from its PM domain.
2693 dev_dbg(dev, "removing from PM domain %s\n", pd->name); in genpd_dev_pm_detach()
2696 if (dev_gpd_data(dev)->default_pstate) { in genpd_dev_pm_detach()
2698 dev_gpd_data(dev)->default_pstate = 0; in genpd_dev_pm_detach()
2703 if (ret != -EAGAIN) in genpd_dev_pm_detach()
2712 pd->name, ret); in genpd_dev_pm_detach()
2720 if (dev->bus == &genpd_bus_type) in genpd_dev_pm_detach()
2743 ret = of_parse_phandle_with_args(dev->of_node, "power-domains", in __genpd_dev_pm_attach()
2744 "#power-domain-cells", index, &pd_args); in __genpd_dev_pm_attach()
2758 dev_dbg(dev, "adding to PM domain %s\n", pd->name); in __genpd_dev_pm_attach()
2764 return dev_err_probe(dev, ret, "failed to add to PM domain %s\n", pd->name); in __genpd_dev_pm_attach()
2766 dev->pm_domain->detach = genpd_dev_pm_detach; in __genpd_dev_pm_attach()
2767 dev->pm_domain->sync = genpd_dev_pm_sync; in __genpd_dev_pm_attach()
2770 pstate = of_get_required_opp_performance_state(dev->of_node, index); in __genpd_dev_pm_attach()
2771 if (pstate < 0 && pstate != -ENODEV && pstate != -EOPNOTSUPP) { in __genpd_dev_pm_attach()
2778 dev_gpd_data(dev)->default_pstate = pstate; in __genpd_dev_pm_attach()
2789 if (dev_gpd_data(dev)->default_pstate) { in __genpd_dev_pm_attach()
2791 dev_gpd_data(dev)->default_pstate = 0; in __genpd_dev_pm_attach()
2795 return -EPROBE_DEFER; in __genpd_dev_pm_attach()
2801 dev_err(dev, "failed to set required performance state for power-domain %s: %d\n", in __genpd_dev_pm_attach()
2802 pd->name, ret); in __genpd_dev_pm_attach()
2808 * genpd_dev_pm_attach - Attach a device to its PM domain using DT.
2815 * PM domain or when multiple power-domains exists for it, else a negative error
2816 * code. Note that if a power-domain exists for the device, but it cannot be
2817 * found or turned on, then return -EPROBE_DEFER to ensure that the device is
2818 * not probed and to re-try again later.
2822 if (!dev->of_node) in genpd_dev_pm_attach()
2829 if (of_count_phandle_with_args(dev->of_node, "power-domains", in genpd_dev_pm_attach()
2830 "#power-domain-cells") != 1) in genpd_dev_pm_attach()
2838 * genpd_dev_pm_attach_by_id - Associate a device with one of its PM domains.
2844 * pm_domain ops. To deal with detaching of the virtual device, the ->detach()
2849 * failures. If a power-domain exists for the device, but cannot be found or
2850 * turned on, then ERR_PTR(-EPROBE_DEFER) is returned to ensure that the device
2851 * is not probed and to re-try again later.
2860 if (!dev->of_node) in genpd_dev_pm_attach_by_id()
2864 num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", in genpd_dev_pm_attach_by_id()
2865 "#power-domain-cells"); in genpd_dev_pm_attach_by_id()
2872 return ERR_PTR(-ENOMEM); in genpd_dev_pm_attach_by_id()
2875 virt_dev->bus = &genpd_bus_type; in genpd_dev_pm_attach_by_id()
2876 virt_dev->release = genpd_release_dev; in genpd_dev_pm_attach_by_id()
2877 virt_dev->of_node = of_node_get(dev->of_node); in genpd_dev_pm_attach_by_id()
2900 * genpd_dev_pm_attach_by_name - Associate a device with one of its PM domains.
2905 * power-domain-names DT property. For further description see
2912 if (!dev->of_node) in genpd_dev_pm_attach_by_name()
2915 index = of_property_match_string(dev->of_node, "power-domain-names", in genpd_dev_pm_attach_by_name()
2924 { .compatible = "domain-idle-state", },
2935 err = of_property_read_u32(state_node, "entry-latency-us", in genpd_parse_state()
2938 pr_debug(" * %pOF missing entry-latency-us property\n", in genpd_parse_state()
2940 return -EINVAL; in genpd_parse_state()
2943 err = of_property_read_u32(state_node, "exit-latency-us", in genpd_parse_state()
2946 pr_debug(" * %pOF missing exit-latency-us property\n", in genpd_parse_state()
2948 return -EINVAL; in genpd_parse_state()
2951 err = of_property_read_u32(state_node, "min-residency-us", &residency); in genpd_parse_state()
2953 genpd_state->residency_ns = 1000LL * residency; in genpd_parse_state()
2955 genpd_state->power_on_latency_ns = 1000LL * exit_latency; in genpd_parse_state()
2956 genpd_state->power_off_latency_ns = 1000LL * entry_latency; in genpd_parse_state()
2957 genpd_state->fwnode = &state_node->fwnode; in genpd_parse_state()
2970 ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL); in genpd_iterate_idle_states()
2972 return ret == -ENOENT ? 0 : ret; in genpd_iterate_idle_states()
2975 of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) { in genpd_iterate_idle_states()
3028 return -ENOMEM; in of_genpd_parse_idle_states()
3033 return ret < 0 ? ret : -EINVAL; in of_genpd_parse_idle_states()
3069 if (dev->power.runtime_error) in rtpm_status_str()
3071 else if (dev->power.disable_depth) in rtpm_status_str()
3073 else if (dev->power.runtime_status < ARRAY_SIZE(status_lookup)) in rtpm_status_str()
3074 p = status_lookup[dev->power.runtime_status]; in rtpm_status_str()
3078 seq_printf(s, "%-25s ", p); in rtpm_status_str()
3085 gpd_data = to_gpd_data(dev->power.subsys_data->domain_data); in perf_status_str()
3086 seq_put_decimal_ull(s, "", gpd_data->performance_state); in perf_status_str()
3104 return -ERESTARTSYS; in genpd_summary_one()
3106 if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) in genpd_summary_one()
3109 snprintf(state, sizeof(state), "%s-%u", in genpd_summary_one()
3110 status_lookup[genpd->status], genpd->state_idx); in genpd_summary_one()
3113 status_lookup[genpd->status]); in genpd_summary_one()
3114 seq_printf(s, "%-30s %-50s %u", genpd->name, state, genpd->performance_state); in genpd_summary_one()
3119 * Also genpd->name is immutable. in genpd_summary_one()
3121 list_for_each_entry(link, &genpd->parent_links, parent_node) { in genpd_summary_one()
3122 if (list_is_first(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
3124 seq_printf(s, "%s", link->child->name); in genpd_summary_one()
3125 if (!list_is_last(&link->parent_node, &genpd->parent_links)) in genpd_summary_one()
3129 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in genpd_summary_one()
3130 kobj_path = kobject_get_path(&pm_data->dev->kobj, in genpd_summary_one()
3136 seq_printf(s, "\n %-50s ", kobj_path); in genpd_summary_one()
3137 rtpm_status_str(s, pm_data->dev); in genpd_summary_one()
3138 perf_status_str(s, pm_data->dev); in genpd_summary_one()
3156 …seq_puts(s, "-------------------------------------------------------------------------------------… in summary_show()
3160 return -ERESTARTSYS; in summary_show()
3179 struct generic_pm_domain *genpd = s->private; in status_show()
3184 return -ERESTARTSYS; in status_show()
3186 if (WARN_ON_ONCE(genpd->status >= ARRAY_SIZE(status_lookup))) in status_show()
3189 if (genpd->status == GENPD_STATE_OFF) in status_show()
3190 seq_printf(s, "%s-%u\n", status_lookup[genpd->status], in status_show()
3191 genpd->state_idx); in status_show()
3193 seq_printf(s, "%s\n", status_lookup[genpd->status]); in status_show()
3201 struct generic_pm_domain *genpd = s->private; in sub_domains_show()
3207 return -ERESTARTSYS; in sub_domains_show()
3209 list_for_each_entry(link, &genpd->parent_links, parent_node) in sub_domains_show()
3210 seq_printf(s, "%s\n", link->child->name); in sub_domains_show()
3218 struct generic_pm_domain *genpd = s->private; in idle_states_show()
3225 return -ERESTARTSYS; in idle_states_show()
3229 for (i = 0; i < genpd->state_count; i++) { in idle_states_show()
3230 idle_time += genpd->states[i].idle_time; in idle_states_show()
3232 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) { in idle_states_show()
3234 if (now > genpd->accounting_time) { in idle_states_show()
3235 delta = now - genpd->accounting_time; in idle_states_show()
3241 seq_printf(s, "S%-13i %-14llu %-14llu %llu\n", i, idle_time, in idle_states_show()
3242 genpd->states[i].usage, genpd->states[i].rejected); in idle_states_show()
3251 struct generic_pm_domain *genpd = s->private; in active_time_show()
3257 return -ERESTARTSYS; in active_time_show()
3259 if (genpd->status == GENPD_STATE_ON) { in active_time_show()
3261 if (now > genpd->accounting_time) in active_time_show()
3262 delta = now - genpd->accounting_time; in active_time_show()
3265 on_time = genpd->on_time + delta; in active_time_show()
3275 struct generic_pm_domain *genpd = s->private; in total_idle_time_show()
3282 return -ERESTARTSYS; in total_idle_time_show()
3284 for (i = 0; i < genpd->state_count; i++) { in total_idle_time_show()
3285 total += genpd->states[i].idle_time; in total_idle_time_show()
3287 if (genpd->status == GENPD_STATE_OFF && genpd->state_idx == i) { in total_idle_time_show()
3289 if (now > genpd->accounting_time) { in total_idle_time_show()
3290 delta = now - genpd->accounting_time; in total_idle_time_show()
3306 struct generic_pm_domain *genpd = s->private; in devices_show()
3313 return -ERESTARTSYS; in devices_show()
3315 list_for_each_entry(pm_data, &genpd->dev_list, list_node) { in devices_show()
3316 kobj_path = kobject_get_path(&pm_data->dev->kobj, in devices_show()
3332 struct generic_pm_domain *genpd = s->private; in perf_state_show()
3335 return -ERESTARTSYS; in perf_state_show()
3337 seq_printf(s, "%u\n", genpd->performance_state); in perf_state_show()
3359 d = debugfs_create_dir(genpd->name, genpd_debugfs_dir); in genpd_debug_add()
3373 if (genpd->set_performance_state) in genpd_debug_add()