1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2024 Linaro Ltd.
7 #include <linux/cleanup.h>
8 #include <linux/debugfs.h>
9 #include <linux/device.h>
10 #include <linux/err.h>
11 #include <linux/export.h>
12 #include <linux/idr.h>
13 #include <linux/kernel.h>
14 #include <linux/kref.h>
15 #include <linux/list.h>
16 #include <linux/lockdep.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
19 #include <linux/property.h>
20 #include <linux/pwrseq/consumer.h>
21 #include <linux/pwrseq/provider.h>
22 #include <linux/radix-tree.h>
23 #include <linux/rwsem.h>
24 #include <linux/slab.h>
27 * Power-sequencing framework for linux.
29 * This subsystem allows power sequence providers to register a set of targets
30 * that consumers may request and power-up/down.
34 * Unit - a unit is a discreet chunk of a power sequence. For instance one unit
35 * may enable a set of regulators, another may enable a specific GPIO. Units
36 * can define dependencies in the form of other units that must be enabled
37 * before it itself can be.
39 * Target - a target is a set of units (composed of the "final" unit and its
40 * dependencies) that a consumer selects by its name when requesting a handle
41 * to the power sequencer. Via the dependency system, multiple targets may
42 * share the same parts of a power sequence but ignore parts that are
45 * Descriptor - a handle passed by the pwrseq core to every consumer that
46 * serves as the entry point to the provider layer. It ensures coherence
47 * between different users and keeps reference counting consistent.
49 * Each provider must define a .match() callback whose role is to determine
50 * whether a potential consumer is in fact associated with this sequencer.
51 * This allows creating abstraction layers on top of regular device-tree
52 * resources like regulators, clocks and other nodes connected to the consumer
56 static DEFINE_IDA(pwrseq_ida
);
59 * Protects the device list on the pwrseq bus from concurrent modifications
60 * but allows simultaneous read-only access.
62 static DECLARE_RWSEM(pwrseq_sem
);
65 * struct pwrseq_unit - Private power-sequence unit data.
66 * @ref: Reference count for this object. When it goes to 0, the object is
68 * @name: Name of this target.
69 * @list: Link to siblings on the list of all units of a single sequencer.
70 * @deps: List of units on which this unit depends.
71 * @enable: Callback running the part of the power-on sequence provided by
73 * @disable: Callback running the part of the power-off sequence provided
75 * @enable_count: Current number of users that enabled this unit. May be the
76 * consumer of the power sequencer or other units that depend
82 struct list_head list
;
83 struct list_head deps
;
84 pwrseq_power_state_func enable
;
85 pwrseq_power_state_func disable
;
86 unsigned int enable_count
;
89 static struct pwrseq_unit
*pwrseq_unit_new(const struct pwrseq_unit_data
*data
)
91 struct pwrseq_unit
*unit
;
93 unit
= kzalloc(sizeof(*unit
), GFP_KERNEL
);
97 unit
->name
= kstrdup_const(data
->name
, GFP_KERNEL
);
103 kref_init(&unit
->ref
);
104 INIT_LIST_HEAD(&unit
->deps
);
105 unit
->enable
= data
->enable
;
106 unit
->disable
= data
->disable
;
111 static struct pwrseq_unit
*pwrseq_unit_get(struct pwrseq_unit
*unit
)
113 kref_get(&unit
->ref
);
118 static void pwrseq_unit_release(struct kref
*ref
);
120 static void pwrseq_unit_put(struct pwrseq_unit
*unit
)
122 kref_put(&unit
->ref
, pwrseq_unit_release
);
126 * struct pwrseq_unit_dep - Wrapper around a reference to the unit structure
127 * allowing to keep it on multiple dependency lists
128 * in different units.
129 * @list: Siblings on the list.
130 * @unit: Address of the referenced unit.
132 struct pwrseq_unit_dep
{
133 struct list_head list
;
134 struct pwrseq_unit
*unit
;
137 static struct pwrseq_unit_dep
*pwrseq_unit_dep_new(struct pwrseq_unit
*unit
)
139 struct pwrseq_unit_dep
*dep
;
141 dep
= kzalloc(sizeof(*dep
), GFP_KERNEL
);
150 static void pwrseq_unit_dep_free(struct pwrseq_unit_dep
*ref
)
152 pwrseq_unit_put(ref
->unit
);
156 static void pwrseq_unit_free_deps(struct list_head
*list
)
158 struct pwrseq_unit_dep
*dep
, *next
;
160 list_for_each_entry_safe(dep
, next
, list
, list
) {
161 list_del(&dep
->list
);
162 pwrseq_unit_dep_free(dep
);
166 static void pwrseq_unit_release(struct kref
*ref
)
168 struct pwrseq_unit
*unit
= container_of(ref
, struct pwrseq_unit
, ref
);
170 pwrseq_unit_free_deps(&unit
->deps
);
171 list_del(&unit
->list
);
172 kfree_const(unit
->name
);
177 * struct pwrseq_target - Private power-sequence target data.
178 * @list: Siblings on the list of all targets exposed by a power sequencer.
179 * @name: Name of the target.
180 * @unit: Final unit for this target.
181 * @post_enable: Callback run after the target unit has been enabled, *after*
182 * the state lock has been released. It's useful for implementing
183 * boot-up delays without blocking other users from powering up
184 * using the same power sequencer.
186 struct pwrseq_target
{
187 struct list_head list
;
189 struct pwrseq_unit
*unit
;
190 pwrseq_power_state_func post_enable
;
193 static struct pwrseq_target
*
194 pwrseq_target_new(const struct pwrseq_target_data
*data
)
196 struct pwrseq_target
*target
;
198 target
= kzalloc(sizeof(*target
), GFP_KERNEL
);
202 target
->name
= kstrdup_const(data
->name
, GFP_KERNEL
);
208 target
->post_enable
= data
->post_enable
;
213 static void pwrseq_target_free(struct pwrseq_target
*target
)
215 if (!IS_ERR_OR_NULL(target
->unit
))
216 pwrseq_unit_put(target
->unit
);
217 kfree_const(target
->name
);
222 * struct pwrseq_device - Private power sequencing data.
223 * @dev: Device struct associated with this sequencer.
225 * @owner: Prevents removal of active power sequencing providers.
226 * @rw_lock: Protects the device from being unregistered while in use.
227 * @state_lock: Prevents multiple users running the power sequence at the same
229 * @match: Power sequencer matching callback.
230 * @targets: List of targets exposed by this sequencer.
231 * @units: List of all units supported by this sequencer.
233 struct pwrseq_device
{
236 struct module
*owner
;
237 struct rw_semaphore rw_lock
;
238 struct mutex state_lock
;
239 pwrseq_match_func match
;
240 struct list_head targets
;
241 struct list_head units
;
244 static struct pwrseq_device
*to_pwrseq_device(struct device
*dev
)
246 return container_of(dev
, struct pwrseq_device
, dev
);
249 static struct pwrseq_device
*pwrseq_device_get(struct pwrseq_device
*pwrseq
)
251 get_device(&pwrseq
->dev
);
256 static void pwrseq_device_put(struct pwrseq_device
*pwrseq
)
258 put_device(&pwrseq
->dev
);
262 * struct pwrseq_desc - Wraps access to the pwrseq_device and ensures that one
263 * user cannot break the reference counting for others.
264 * @pwrseq: Reference to the power sequencing device.
265 * @target: Reference to the target this descriptor allows to control.
266 * @powered_on: Power state set by the holder of the descriptor (not necessarily
267 * corresponding to the actual power state of the device).
270 struct pwrseq_device
*pwrseq
;
271 struct pwrseq_target
*target
;
275 static const struct bus_type pwrseq_bus
= {
279 static void pwrseq_release(struct device
*dev
)
281 struct pwrseq_device
*pwrseq
= to_pwrseq_device(dev
);
282 struct pwrseq_target
*target
, *pos
;
284 list_for_each_entry_safe(target
, pos
, &pwrseq
->targets
, list
) {
285 list_del(&target
->list
);
286 pwrseq_target_free(target
);
289 mutex_destroy(&pwrseq
->state_lock
);
290 ida_free(&pwrseq_ida
, pwrseq
->id
);
294 static const struct device_type pwrseq_device_type
= {
295 .name
= "power_sequencer",
296 .release
= pwrseq_release
,
299 static int pwrseq_check_unit_deps(const struct pwrseq_unit_data
*data
,
300 struct radix_tree_root
*visited_units
)
302 const struct pwrseq_unit_data
*tmp
, **cur
;
305 ret
= radix_tree_insert(visited_units
, (unsigned long)data
,
310 for (cur
= data
->deps
; cur
&& *cur
; cur
++) {
311 tmp
= radix_tree_lookup(visited_units
, (unsigned long)*cur
);
313 WARN(1, "Circular dependency in power sequencing flow detected!\n");
317 ret
= pwrseq_check_unit_deps(*cur
, visited_units
);
325 static int pwrseq_check_target_deps(const struct pwrseq_target_data
*data
)
327 struct radix_tree_root visited_units
;
328 struct radix_tree_iter iter
;
335 INIT_RADIX_TREE(&visited_units
, GFP_KERNEL
);
336 ret
= pwrseq_check_unit_deps(data
->unit
, &visited_units
);
337 radix_tree_for_each_slot(slot
, &visited_units
, &iter
, 0)
338 radix_tree_delete(&visited_units
, iter
.index
);
343 static int pwrseq_unit_setup_deps(const struct pwrseq_unit_data
**data
,
344 struct list_head
*dep_list
,
345 struct list_head
*unit_list
,
346 struct radix_tree_root
*processed_units
);
348 static struct pwrseq_unit
*
349 pwrseq_unit_setup(const struct pwrseq_unit_data
*data
,
350 struct list_head
*unit_list
,
351 struct radix_tree_root
*processed_units
)
353 struct pwrseq_unit
*unit
;
356 unit
= radix_tree_lookup(processed_units
, (unsigned long)data
);
358 return pwrseq_unit_get(unit
);
360 unit
= pwrseq_unit_new(data
);
362 return ERR_PTR(-ENOMEM
);
365 ret
= pwrseq_unit_setup_deps(data
->deps
, &unit
->deps
,
366 unit_list
, processed_units
);
368 pwrseq_unit_put(unit
);
373 ret
= radix_tree_insert(processed_units
, (unsigned long)data
, unit
);
375 pwrseq_unit_put(unit
);
379 list_add_tail(&unit
->list
, unit_list
);
384 static int pwrseq_unit_setup_deps(const struct pwrseq_unit_data
**data
,
385 struct list_head
*dep_list
,
386 struct list_head
*unit_list
,
387 struct radix_tree_root
*processed_units
)
389 const struct pwrseq_unit_data
*pos
;
390 struct pwrseq_unit_dep
*dep
;
391 struct pwrseq_unit
*unit
;
394 for (i
= 0; data
[i
]; i
++) {
397 unit
= pwrseq_unit_setup(pos
, unit_list
, processed_units
);
399 return PTR_ERR(unit
);
401 dep
= pwrseq_unit_dep_new(unit
);
403 pwrseq_unit_put(unit
);
407 list_add_tail(&dep
->list
, dep_list
);
413 static int pwrseq_do_setup_targets(const struct pwrseq_target_data
**data
,
414 struct pwrseq_device
*pwrseq
,
415 struct radix_tree_root
*processed_units
)
417 const struct pwrseq_target_data
*pos
;
418 struct pwrseq_target
*target
;
421 for (i
= 0; data
[i
]; i
++) {
424 ret
= pwrseq_check_target_deps(pos
);
428 target
= pwrseq_target_new(pos
);
432 target
->unit
= pwrseq_unit_setup(pos
->unit
, &pwrseq
->units
,
434 if (IS_ERR(target
->unit
)) {
435 ret
= PTR_ERR(target
->unit
);
436 pwrseq_target_free(target
);
440 list_add_tail(&target
->list
, &pwrseq
->targets
);
446 static int pwrseq_setup_targets(const struct pwrseq_target_data
**targets
,
447 struct pwrseq_device
*pwrseq
)
449 struct radix_tree_root processed_units
;
450 struct radix_tree_iter iter
;
454 INIT_RADIX_TREE(&processed_units
, GFP_KERNEL
);
455 ret
= pwrseq_do_setup_targets(targets
, pwrseq
, &processed_units
);
456 radix_tree_for_each_slot(slot
, &processed_units
, &iter
, 0)
457 radix_tree_delete(&processed_units
, iter
.index
);
463 * pwrseq_device_register() - Register a new power sequencer.
464 * @config: Configuration of the new power sequencing device.
466 * The config structure is only used during the call and can be freed after
467 * the function returns. The config structure *must* have the parent device
468 * as well as the match() callback and at least one target set.
471 * Returns the address of the new pwrseq device or ERR_PTR() on failure.
473 struct pwrseq_device
*
474 pwrseq_device_register(const struct pwrseq_config
*config
)
476 struct pwrseq_device
*pwrseq
;
479 if (!config
->parent
|| !config
->match
|| !config
->targets
||
481 return ERR_PTR(-EINVAL
);
483 pwrseq
= kzalloc(sizeof(*pwrseq
), GFP_KERNEL
);
485 return ERR_PTR(-ENOMEM
);
487 pwrseq
->dev
.type
= &pwrseq_device_type
;
488 pwrseq
->dev
.bus
= &pwrseq_bus
;
489 pwrseq
->dev
.parent
= config
->parent
;
490 device_set_node(&pwrseq
->dev
, dev_fwnode(config
->parent
));
491 dev_set_drvdata(&pwrseq
->dev
, config
->drvdata
);
493 id
= ida_alloc(&pwrseq_ida
, GFP_KERNEL
);
502 * From this point onwards the device's release() callback is
503 * responsible for freeing resources.
505 device_initialize(&pwrseq
->dev
);
507 ret
= dev_set_name(&pwrseq
->dev
, "pwrseq.%d", pwrseq
->id
);
511 pwrseq
->owner
= config
->owner
?: THIS_MODULE
;
512 pwrseq
->match
= config
->match
;
514 init_rwsem(&pwrseq
->rw_lock
);
515 mutex_init(&pwrseq
->state_lock
);
516 INIT_LIST_HEAD(&pwrseq
->targets
);
517 INIT_LIST_HEAD(&pwrseq
->units
);
519 ret
= pwrseq_setup_targets(config
->targets
, pwrseq
);
523 scoped_guard(rwsem_write
, &pwrseq_sem
) {
524 ret
= device_add(&pwrseq
->dev
);
532 pwrseq_device_put(pwrseq
);
535 EXPORT_SYMBOL_GPL(pwrseq_device_register
);
538 * pwrseq_device_unregister() - Unregister the power sequencer.
539 * @pwrseq: Power sequencer to unregister.
541 void pwrseq_device_unregister(struct pwrseq_device
*pwrseq
)
543 struct device
*dev
= &pwrseq
->dev
;
544 struct pwrseq_target
*target
;
546 scoped_guard(mutex
, &pwrseq
->state_lock
) {
547 guard(rwsem_write
)(&pwrseq
->rw_lock
);
549 list_for_each_entry(target
, &pwrseq
->targets
, list
)
550 WARN(target
->unit
->enable_count
,
551 "REMOVING POWER SEQUENCER WITH ACTIVE USERS\n");
553 guard(rwsem_write
)(&pwrseq_sem
);
558 pwrseq_device_put(pwrseq
);
560 EXPORT_SYMBOL_GPL(pwrseq_device_unregister
);
562 static void devm_pwrseq_device_unregister(void *data
)
564 struct pwrseq_device
*pwrseq
= data
;
566 pwrseq_device_unregister(pwrseq
);
570 * devm_pwrseq_device_register() - Managed variant of pwrseq_device_register().
571 * @dev: Managing device.
572 * @config: Configuration of the new power sequencing device.
575 * Returns the address of the new pwrseq device or ERR_PTR() on failure.
577 struct pwrseq_device
*
578 devm_pwrseq_device_register(struct device
*dev
,
579 const struct pwrseq_config
*config
)
581 struct pwrseq_device
*pwrseq
;
584 pwrseq
= pwrseq_device_register(config
);
588 ret
= devm_add_action_or_reset(dev
, devm_pwrseq_device_unregister
,
595 EXPORT_SYMBOL_GPL(devm_pwrseq_device_register
);
598 * pwrseq_device_get_drvdata() - Get the driver private data associated with
600 * @pwrseq: Power sequencer object.
603 * Address of the private driver data.
605 void *pwrseq_device_get_drvdata(struct pwrseq_device
*pwrseq
)
607 return dev_get_drvdata(&pwrseq
->dev
);
609 EXPORT_SYMBOL_GPL(pwrseq_device_get_drvdata
);
611 struct pwrseq_match_data
{
612 struct pwrseq_desc
*desc
;
617 static int pwrseq_match_device(struct device
*pwrseq_dev
, void *data
)
619 struct pwrseq_device
*pwrseq
= to_pwrseq_device(pwrseq_dev
);
620 struct pwrseq_match_data
*match_data
= data
;
621 struct pwrseq_target
*target
;
624 lockdep_assert_held_read(&pwrseq_sem
);
626 guard(rwsem_read
)(&pwrseq
->rw_lock
);
627 if (!device_is_registered(&pwrseq
->dev
))
630 ret
= pwrseq
->match(pwrseq
, match_data
->dev
);
634 /* We got the matching device, let's find the right target. */
635 list_for_each_entry(target
, &pwrseq
->targets
, list
) {
636 if (strcmp(target
->name
, match_data
->target
))
639 match_data
->desc
->target
= target
;
643 * This device does not have this target. No point in deferring as it
644 * will not get a new target dynamically later.
646 if (!match_data
->desc
->target
)
649 if (!try_module_get(pwrseq
->owner
))
650 return -EPROBE_DEFER
;
652 match_data
->desc
->pwrseq
= pwrseq_device_get(pwrseq
);
658 * pwrseq_get() - Get the power sequencer associated with this device.
659 * @dev: Device for which to get the sequencer.
660 * @target: Name of the target exposed by the sequencer this device wants to
664 * New power sequencer descriptor for use by the consumer driver or ERR_PTR()
667 struct pwrseq_desc
*pwrseq_get(struct device
*dev
, const char *target
)
669 struct pwrseq_match_data match_data
;
672 struct pwrseq_desc
*desc
__free(kfree
) = kzalloc(sizeof(*desc
),
675 return ERR_PTR(-ENOMEM
);
677 match_data
.desc
= desc
;
678 match_data
.dev
= dev
;
679 match_data
.target
= target
;
681 guard(rwsem_read
)(&pwrseq_sem
);
683 ret
= bus_for_each_dev(&pwrseq_bus
, NULL
, &match_data
,
684 pwrseq_match_device
);
688 /* No device matched. */
689 return ERR_PTR(-EPROBE_DEFER
);
693 EXPORT_SYMBOL_GPL(pwrseq_get
);
696 * pwrseq_put() - Release the power sequencer descriptor.
697 * @desc: Descriptor to release.
699 void pwrseq_put(struct pwrseq_desc
*desc
)
701 struct pwrseq_device
*pwrseq
;
706 pwrseq
= desc
->pwrseq
;
708 if (desc
->powered_on
)
709 pwrseq_power_off(desc
);
712 module_put(pwrseq
->owner
);
713 pwrseq_device_put(pwrseq
);
715 EXPORT_SYMBOL_GPL(pwrseq_put
);
717 static void devm_pwrseq_put(void *data
)
719 struct pwrseq_desc
*desc
= data
;
725 * devm_pwrseq_get() - Managed variant of pwrseq_get().
726 * @dev: Device for which to get the sequencer and which also manages its
728 * @target: Name of the target exposed by the sequencer this device wants to
732 * New power sequencer descriptor for use by the consumer driver or ERR_PTR()
735 struct pwrseq_desc
*devm_pwrseq_get(struct device
*dev
, const char *target
)
737 struct pwrseq_desc
*desc
;
740 desc
= pwrseq_get(dev
, target
);
744 ret
= devm_add_action_or_reset(dev
, devm_pwrseq_put
, desc
);
750 EXPORT_SYMBOL_GPL(devm_pwrseq_get
);
752 static int pwrseq_unit_enable(struct pwrseq_device
*pwrseq
,
753 struct pwrseq_unit
*target
);
754 static int pwrseq_unit_disable(struct pwrseq_device
*pwrseq
,
755 struct pwrseq_unit
*target
);
757 static int pwrseq_unit_enable_deps(struct pwrseq_device
*pwrseq
,
758 struct list_head
*list
)
760 struct pwrseq_unit_dep
*pos
;
763 list_for_each_entry(pos
, list
, list
) {
764 ret
= pwrseq_unit_enable(pwrseq
, pos
->unit
);
766 list_for_each_entry_continue_reverse(pos
, list
, list
)
767 pwrseq_unit_disable(pwrseq
, pos
->unit
);
775 static int pwrseq_unit_disable_deps(struct pwrseq_device
*pwrseq
,
776 struct list_head
*list
)
778 struct pwrseq_unit_dep
*pos
;
781 list_for_each_entry_reverse(pos
, list
, list
) {
782 ret
= pwrseq_unit_disable(pwrseq
, pos
->unit
);
784 list_for_each_entry_continue(pos
, list
, list
)
785 pwrseq_unit_enable(pwrseq
, pos
->unit
);
793 static int pwrseq_unit_enable(struct pwrseq_device
*pwrseq
,
794 struct pwrseq_unit
*unit
)
798 lockdep_assert_held_read(&pwrseq
->rw_lock
);
799 lockdep_assert_held(&pwrseq
->state_lock
);
801 if (unit
->enable_count
!= 0) {
802 unit
->enable_count
++;
806 ret
= pwrseq_unit_enable_deps(pwrseq
, &unit
->deps
);
808 dev_err(&pwrseq
->dev
,
809 "Failed to enable dependencies before power-on for target '%s': %d\n",
815 ret
= unit
->enable(pwrseq
);
817 dev_err(&pwrseq
->dev
,
818 "Failed to enable target '%s': %d\n",
820 pwrseq_unit_disable_deps(pwrseq
, &unit
->deps
);
825 unit
->enable_count
++;
830 static int pwrseq_unit_disable(struct pwrseq_device
*pwrseq
,
831 struct pwrseq_unit
*unit
)
835 lockdep_assert_held_read(&pwrseq
->rw_lock
);
836 lockdep_assert_held(&pwrseq
->state_lock
);
838 if (unit
->enable_count
== 0) {
839 WARN(1, "Unmatched power-off for target '%s'\n",
844 if (unit
->enable_count
!= 1) {
845 unit
->enable_count
--;
850 ret
= unit
->disable(pwrseq
);
852 dev_err(&pwrseq
->dev
,
853 "Failed to disable target '%s': %d\n",
859 ret
= pwrseq_unit_disable_deps(pwrseq
, &unit
->deps
);
861 dev_err(&pwrseq
->dev
,
862 "Failed to disable dependencies after power-off for target '%s': %d\n",
865 unit
->enable(pwrseq
);
869 unit
->enable_count
--;
875 * pwrseq_power_on() - Issue a power-on request on behalf of the consumer
877 * @desc: Descriptor referencing the power sequencer.
879 * This function tells the power sequencer that the consumer wants to be
880 * powered-up. The sequencer may already have powered-up the device in which
881 * case the function returns 0. If the power-up sequence is already in
882 * progress, the function will block until it's done and return 0. If this is
883 * the first request, the device will be powered up.
886 * 0 on success, negative error number on failure.
888 int pwrseq_power_on(struct pwrseq_desc
*desc
)
890 struct pwrseq_device
*pwrseq
;
891 struct pwrseq_target
*target
;
892 struct pwrseq_unit
*unit
;
897 if (!desc
|| desc
->powered_on
)
900 pwrseq
= desc
->pwrseq
;
901 target
= desc
->target
;
904 guard(rwsem_read
)(&pwrseq
->rw_lock
);
905 if (!device_is_registered(&pwrseq
->dev
))
908 scoped_guard(mutex
, &pwrseq
->state_lock
) {
909 ret
= pwrseq_unit_enable(pwrseq
, unit
);
911 desc
->powered_on
= true;
914 if (target
->post_enable
) {
915 ret
= target
->post_enable(pwrseq
);
917 pwrseq_unit_disable(pwrseq
, unit
);
918 desc
->powered_on
= false;
924 EXPORT_SYMBOL_GPL(pwrseq_power_on
);
927 * pwrseq_power_off() - Issue a power-off request on behalf of the consumer
929 * @desc: Descriptor referencing the power sequencer.
931 * This undoes the effects of pwrseq_power_on(). It issues a power-off request
932 * on behalf of the consumer and when the last remaining user does so, the
933 * power-down sequence will be started. If one is in progress, the function
934 * will block until it's complete and then return.
937 * 0 on success, negative error number on failure.
939 int pwrseq_power_off(struct pwrseq_desc
*desc
)
941 struct pwrseq_device
*pwrseq
;
942 struct pwrseq_unit
*unit
;
947 if (!desc
|| !desc
->powered_on
)
950 pwrseq
= desc
->pwrseq
;
951 unit
= desc
->target
->unit
;
953 guard(rwsem_read
)(&pwrseq
->rw_lock
);
954 if (!device_is_registered(&pwrseq
->dev
))
957 guard(mutex
)(&pwrseq
->state_lock
);
959 ret
= pwrseq_unit_disable(pwrseq
, unit
);
961 desc
->powered_on
= false;
965 EXPORT_SYMBOL_GPL(pwrseq_power_off
);
967 #if IS_ENABLED(CONFIG_DEBUG_FS)
969 struct pwrseq_debugfs_count_ctx
{
974 static int pwrseq_debugfs_seq_count(struct device
*dev
, void *data
)
976 struct pwrseq_debugfs_count_ctx
*ctx
= data
;
980 return ctx
->index
-- ? 0 : 1;
983 static void *pwrseq_debugfs_seq_start(struct seq_file
*seq
, loff_t
*pos
)
985 struct pwrseq_debugfs_count_ctx ctx
;
991 * We're holding the lock for the entire printout so no need to fiddle
992 * with device reference count.
994 down_read(&pwrseq_sem
);
996 bus_for_each_dev(&pwrseq_bus
, NULL
, &ctx
, pwrseq_debugfs_seq_count
);
1003 static void *pwrseq_debugfs_seq_next(struct seq_file
*seq
, void *data
,
1006 struct device
*curr
= data
;
1010 struct device
*next
__free(put_device
) =
1011 bus_find_next_device(&pwrseq_bus
, curr
);
1015 static void pwrseq_debugfs_seq_show_target(struct seq_file
*seq
,
1016 struct pwrseq_target
*target
)
1018 seq_printf(seq
, " target: [%s] (target unit: [%s])\n",
1019 target
->name
, target
->unit
->name
);
1022 static void pwrseq_debugfs_seq_show_unit(struct seq_file
*seq
,
1023 struct pwrseq_unit
*unit
)
1025 struct pwrseq_unit_dep
*ref
;
1027 seq_printf(seq
, " unit: [%s] - enable count: %u\n",
1028 unit
->name
, unit
->enable_count
);
1030 if (list_empty(&unit
->deps
))
1033 seq_puts(seq
, " dependencies:\n");
1034 list_for_each_entry(ref
, &unit
->deps
, list
)
1035 seq_printf(seq
, " [%s]\n", ref
->unit
->name
);
1038 static int pwrseq_debugfs_seq_show(struct seq_file
*seq
, void *data
)
1040 struct device
*dev
= data
;
1041 struct pwrseq_device
*pwrseq
= to_pwrseq_device(dev
);
1042 struct pwrseq_target
*target
;
1043 struct pwrseq_unit
*unit
;
1045 seq_printf(seq
, "%s:\n", dev_name(dev
));
1047 seq_puts(seq
, " targets:\n");
1048 list_for_each_entry(target
, &pwrseq
->targets
, list
)
1049 pwrseq_debugfs_seq_show_target(seq
, target
);
1051 seq_puts(seq
, " units:\n");
1052 list_for_each_entry(unit
, &pwrseq
->units
, list
)
1053 pwrseq_debugfs_seq_show_unit(seq
, unit
);
1058 static void pwrseq_debugfs_seq_stop(struct seq_file
*seq
, void *data
)
1060 up_read(&pwrseq_sem
);
1063 static const struct seq_operations pwrseq_debugfs_sops
= {
1064 .start
= pwrseq_debugfs_seq_start
,
1065 .next
= pwrseq_debugfs_seq_next
,
1066 .show
= pwrseq_debugfs_seq_show
,
1067 .stop
= pwrseq_debugfs_seq_stop
,
1069 DEFINE_SEQ_ATTRIBUTE(pwrseq_debugfs
);
1071 static struct dentry
*pwrseq_debugfs_dentry
;
1073 #endif /* CONFIG_DEBUG_FS */
1075 static int __init
pwrseq_init(void)
1079 ret
= bus_register(&pwrseq_bus
);
1081 pr_err("Failed to register the power sequencer bus\n");
1085 #if IS_ENABLED(CONFIG_DEBUG_FS)
1086 pwrseq_debugfs_dentry
= debugfs_create_file("pwrseq", 0444, NULL
, NULL
,
1087 &pwrseq_debugfs_fops
);
1088 #endif /* CONFIG_DEBUG_FS */
1092 subsys_initcall(pwrseq_init
);
1094 static void __exit
pwrseq_exit(void)
1096 #if IS_ENABLED(CONFIG_DEBUG_FS)
1097 debugfs_remove_recursive(pwrseq_debugfs_dentry
);
1098 #endif /* CONFIG_DEBUG_FS */
1100 bus_unregister(&pwrseq_bus
);
1102 module_exit(pwrseq_exit
);
1104 MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
1105 MODULE_DESCRIPTION("Power Sequencing subsystem core");
1106 MODULE_LICENSE("GPL");