xref: /linux/Documentation/driver-api/pwrseq.rst (revision 8b7e0a6c443e855374a426dcdfd0a19912d70df3)
1*8b7e0a6cSBartosz Golaszewski.. SPDX-License-Identifier: GPL-2.0-only
2*8b7e0a6cSBartosz Golaszewski.. Copyright 2024 Linaro Ltd.
3*8b7e0a6cSBartosz Golaszewski
4*8b7e0a6cSBartosz Golaszewski====================
5*8b7e0a6cSBartosz GolaszewskiPower Sequencing API
6*8b7e0a6cSBartosz Golaszewski====================
7*8b7e0a6cSBartosz Golaszewski
8*8b7e0a6cSBartosz Golaszewski:Author: Bartosz Golaszewski
9*8b7e0a6cSBartosz Golaszewski
10*8b7e0a6cSBartosz GolaszewskiIntroduction
11*8b7e0a6cSBartosz Golaszewski============
12*8b7e0a6cSBartosz Golaszewski
13*8b7e0a6cSBartosz GolaszewskiThis framework is designed to abstract complex power-up sequences that are
14*8b7e0a6cSBartosz Golaszewskishared between multiple logical devices in the linux kernel.
15*8b7e0a6cSBartosz Golaszewski
16*8b7e0a6cSBartosz GolaszewskiThe intention is to allow consumers to obtain a power sequencing handle
17*8b7e0a6cSBartosz Golaszewskiexposed by the power sequence provider and delegate the actual requesting and
18*8b7e0a6cSBartosz Golaszewskicontrol of the underlying resources as well as to allow the provider to
19*8b7e0a6cSBartosz Golaszewskimitigate any potential conflicts between multiple users behind the scenes.
20*8b7e0a6cSBartosz Golaszewski
21*8b7e0a6cSBartosz GolaszewskiGlossary
22*8b7e0a6cSBartosz Golaszewski--------
23*8b7e0a6cSBartosz Golaszewski
24*8b7e0a6cSBartosz GolaszewskiThe power sequencing API uses a number of terms specific to the subsystem:
25*8b7e0a6cSBartosz Golaszewski
26*8b7e0a6cSBartosz GolaszewskiUnit
27*8b7e0a6cSBartosz Golaszewski
28*8b7e0a6cSBartosz Golaszewski    A unit is a discreet chunk of a power sequence. For instance one unit may
29*8b7e0a6cSBartosz Golaszewski    enable a set of regulators, another may enable a specific GPIO. Units can
30*8b7e0a6cSBartosz Golaszewski    define dependencies in the form of other units that must be enabled before
31*8b7e0a6cSBartosz Golaszewski    it itself can be.
32*8b7e0a6cSBartosz Golaszewski
33*8b7e0a6cSBartosz GolaszewskiTarget
34*8b7e0a6cSBartosz Golaszewski
35*8b7e0a6cSBartosz Golaszewski    A target is a set of units (composed of the "final" unit and its
36*8b7e0a6cSBartosz Golaszewski    dependencies) that a consumer selects by its name when requesting a handle
37*8b7e0a6cSBartosz Golaszewski    to the power sequencer. Via the dependency system, multiple targets may
38*8b7e0a6cSBartosz Golaszewski    share the same parts of a power sequence but ignore parts that are
39*8b7e0a6cSBartosz Golaszewski    irrelevant.
40*8b7e0a6cSBartosz Golaszewski
41*8b7e0a6cSBartosz GolaszewskiDescriptor
42*8b7e0a6cSBartosz Golaszewski
43*8b7e0a6cSBartosz Golaszewski    A handle passed by the pwrseq core to every consumer that serves as the
44*8b7e0a6cSBartosz Golaszewski    entry point to the provider layer. It ensures coherence between different
45*8b7e0a6cSBartosz Golaszewski    users and keeps reference counting consistent.
46*8b7e0a6cSBartosz Golaszewski
47*8b7e0a6cSBartosz GolaszewskiConsumer interface
48*8b7e0a6cSBartosz Golaszewski==================
49*8b7e0a6cSBartosz Golaszewski
50*8b7e0a6cSBartosz GolaszewskiThe consumer API is aimed to be as simple as possible. The driver interested in
51*8b7e0a6cSBartosz Golaszewskigetting a descriptor from the power sequencer should call pwrseq_get() and
52*8b7e0a6cSBartosz Golaszewskispecify the name of the target it wants to reach in the sequence after calling
53*8b7e0a6cSBartosz Golaszewskipwrseq_power_up(). The descriptor can be released by calling pwrseq_put() and
54*8b7e0a6cSBartosz Golaszewskithe consumer can request the powering down of its target with
55*8b7e0a6cSBartosz Golaszewskipwrseq_power_off(). Note that there is no guarantee that pwrseq_power_off()
56*8b7e0a6cSBartosz Golaszewskiwill have any effect as there may be multiple users of the underlying resources
57*8b7e0a6cSBartosz Golaszewskiwho may keep them active.
58*8b7e0a6cSBartosz Golaszewski
59*8b7e0a6cSBartosz GolaszewskiProvider interface
60*8b7e0a6cSBartosz Golaszewski==================
61*8b7e0a6cSBartosz Golaszewski
62*8b7e0a6cSBartosz GolaszewskiThe provider API is admittedly not nearly as straightforward as the one for
63*8b7e0a6cSBartosz Golaszewskiconsumers but it makes up for it in flexibility.
64*8b7e0a6cSBartosz Golaszewski
65*8b7e0a6cSBartosz GolaszewskiEach provider can logically split the power-up sequence into descrete chunks
66*8b7e0a6cSBartosz Golaszewski(units) and define their dependencies. They can then expose named targets that
67*8b7e0a6cSBartosz Golaszewskiconsumers may use as the final point in the sequence that they wish to reach.
68*8b7e0a6cSBartosz Golaszewski
69*8b7e0a6cSBartosz GolaszewskiTo that end the providers fill out a set of configuration structures and
70*8b7e0a6cSBartosz Golaszewskiregister with the pwrseq subsystem by calling pwrseq_device_register().
71*8b7e0a6cSBartosz Golaszewski
72*8b7e0a6cSBartosz GolaszewskiDynamic consumer matching
73*8b7e0a6cSBartosz Golaszewski-------------------------
74*8b7e0a6cSBartosz Golaszewski
75*8b7e0a6cSBartosz GolaszewskiThe main difference between pwrseq and other linux kernel providers is the
76*8b7e0a6cSBartosz Golaszewskimechanism for dynamic matching of consumers and providers. Every power sequence
77*8b7e0a6cSBartosz Golaszewskiprovider driver must implement the `match()` callback and pass it to the pwrseq
78*8b7e0a6cSBartosz Golaszewskicore when registering with the subsystems.
79*8b7e0a6cSBartosz Golaszewski
80*8b7e0a6cSBartosz GolaszewskiWhen a client requests a sequencer handle, the core will call this callback for
81*8b7e0a6cSBartosz Golaszewskievery registered provider and let it flexibly figure out whether the proposed
82*8b7e0a6cSBartosz Golaszewskiclient device is indeed its consumer. For example: if the provider binds to the
83*8b7e0a6cSBartosz Golaszewskidevice-tree node representing a power management unit of a chipset and the
84*8b7e0a6cSBartosz Golaszewskiconsumer driver controls one of its modules, the provider driver may parse the
85*8b7e0a6cSBartosz Golaszewskirelevant regulator supply properties in device tree and see if they lead from
86*8b7e0a6cSBartosz Golaszewskithe PMU to the consumer.
87*8b7e0a6cSBartosz Golaszewski
88*8b7e0a6cSBartosz GolaszewskiAPI reference
89*8b7e0a6cSBartosz Golaszewski=============
90*8b7e0a6cSBartosz Golaszewski
91*8b7e0a6cSBartosz Golaszewski.. kernel-doc:: include/linux/pwrseq/provider.h
92*8b7e0a6cSBartosz Golaszewski   :internal:
93*8b7e0a6cSBartosz Golaszewski
94*8b7e0a6cSBartosz Golaszewski.. kernel-doc:: drivers/power/sequencing/core.c
95*8b7e0a6cSBartosz Golaszewski   :export:
96