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