]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/power/common/v2_0/doc/power.sgml
Initial revision
[karo-tx-redboot.git] / packages / services / power / common / v2_0 / doc / power.sgml
1 <!-- DOCTYPE reference  PUBLIC "-//OASIS//DTD DocBook V3.1//EN" -->
2
3 <!-- {{{ Banner                         -->
4
5 <!-- =============================================================== -->
6 <!--                                                                 -->
7 <!--     power.sgml                                                  -->
8 <!--                                                                 -->
9 <!--     Generic power management documentation.                     -->
10 <!--                                                                 -->
11 <!-- =============================================================== -->
12 <!-- ####COPYRIGHTBEGIN####                                          -->
13 <!--                                                                 -->
14 <!-- =============================================================== -->
15 <!-- Copyright (C) 2001, 2002 Red Hat, Inc.                          -->
16 <!-- This material may be distributed only subject to the terms      -->
17 <!-- and conditions set forth in the Open Publication License, v1.0  -->
18 <!-- or later (the latest version is presently available at          -->
19 <!-- http://www.opencontent.org/openpub/)                            -->
20 <!-- Distribution of the work or derivative of the work in any       -->
21 <!-- standard (paper) book form is prohibited unless prior           -->
22 <!-- permission obtained from the copyright holder                   -->
23 <!-- =============================================================== -->
24 <!--                                                                 -->      
25 <!-- ####COPYRIGHTEND####                                            -->
26 <!-- =============================================================== -->
27 <!-- #####DESCRIPTIONBEGIN####                                       -->
28 <!--                                                                 -->
29 <!-- Author(s):   bartv                                              -->
30 <!-- Contact(s):  bartv                                              -->
31 <!-- Date:        2001/06/26                                         -->
32 <!-- Version:     0.01                                               -->
33 <!--                                                                 -->
34 <!-- ####DESCRIPTIONEND####                                          -->
35 <!-- =============================================================== -->
36
37 <!-- }}} -->
38 <part id="services-power">
39 <!-- reference id="services-power" -->
40   <title>eCos Power Management Support</title>
41
42 <!-- {{{ Intro                          -->
43
44 <refentry id="power-intro">
45 <refmeta>
46 <refentrytitle>Introduction</refentrytitle>
47 </refmeta>
48 <refnamediv>
49 <refname>Introduction</refname>
50 <refpurpose>eCos support for Power Management</refpurpose>
51 </refnamediv>
52
53 <!-- {{{ Intro                          -->
54
55 <refsect1 id="power-intro-intro">
56 <title>Introduction</title>
57 <para>
58 The eCos Power Management package provides a framework for
59 incorporating power management facilities in an embedded application.
60 However its functionality is deliberately limited.
61 </para>
62 <orderedlist>
63 <listitem>
64 <para>
65 The package does not contain any support for controlling the current
66 power mode of any given processor, device or board. Instead it is the
67 responsibility of the appropriate HAL or device driver package to
68 implement such support, by implementing <firstterm>power
69 controllers</firstterm>. The power management package groups these
70 power controllers together and provides an interface for manipulating
71 them.
72 </para>
73 </listitem>
74 <listitem>
75 <para>
76 The package does not contain any power management policy support.
77 Specifically, including this package in an application does not by
78 itself ever cause the system to go into low-power mode. Instead it is
79 the responsibility of a separate policy module, provided by
80 higher-level application code or by some other package, to decide when
81 it would be appropriate to switch from one power mode to another. The
82 power management package then provides the mechanisms for making it
83 happen.
84 </para>
85 </listitem>
86 </orderedlist>
87 </refsect1>
88
89 <!-- }}} -->
90 <!-- {{{ including                      -->
91
92 <refsect1 id="power-intro-include">
93 <title>Including Power Management</title>
94 <para>
95 The power management package is never included automatically in an
96 eCos configuration: it is not part of any target specification or of
97 any template. Instead it must be added explicitly to a configuration
98 if the intended application requires power management functionality.
99 When using the command-line <command>ecosconfig</command> tool this
100 can be achieved using a command such as:
101 </para>
102 <screen>
103 $ ecosconfig add power
104 </screen>
105 <para>
106 The generic eCos user documentation should be consulted for more
107 information on how to use the various tools. The functionality
108 provided by the power management package is defined in the header file
109 <filename class="headerfile">cyg/power/power.h</filename>. This header
110 file can be used by both C and C++ code.
111 </para>
112
113 </refsect1>
114
115 <!-- }}} -->
116 <!-- {{{ modes                          -->
117
118 <refsect1 id="power-intro-modes">
119 <title>Power Modes</title>
120 <para>
121 There are four defined modes of operation:
122 </para>
123 <variablelist>
124
125 <varlistentry><term>active</term>
126 <listitem>
127 <para>
128 The system is fully operational, and power consumption is expected to
129 be high.
130 </para>
131 </listitem>
132 </varlistentry>
133
134 <varlistentry><term>idle</term>
135 <listitem>
136 <para>
137 There has been little or no activity for a short period of time. It is
138 up to the policy module to determine what constitutes a short period
139 of time, but typically it will be some tenths of a second or some
140 small number of seconds. A possible action when entering idle mode is
141 to reduce the system's clock speed, thus reducing the power drawn by
142 the cpu.
143 </para>
144 <para>
145 Note that typically this power mode is not entered automatically
146 whenever the idle thread starts running. Instead it is entered when
147 the policy module discovers that for a certain period of time the
148 system has been spending most of its time in the idle thread.
149 Theoretically it is possible to implement a policy module that would
150 cause a switch to idle mode as soon as the idle thread starts running,
151 but that could result in a great many power mode changes for no
152 immediate benefit.
153 </para>
154 </listitem>
155 </varlistentry>
156
157 <varlistentry><term>sleep</term>
158 <listitem>
159 <para>
160 The system has been idle for a significant period of time, perhaps
161 some tens of seconds. It is desirable to shut down any hardware that
162 is drawing a significant amount of power, for example a screen
163 backlight.
164 </para>
165 </listitem>
166 </varlistentry>
167
168 <varlistentry><term>off</term>
169 <listitem>
170 <para>
171 The system is powered down. Power consumption should be minimized.
172 Some special action may be needed before the system comes back up, for
173 example the user may need to press a specific button.
174 </para>
175 </listitem>
176 </varlistentry>
177
178 </variablelist>
179
180 <para>
181 The exact transitions that will happen are decided by the policy
182 module. One policy module might include transitions from active to
183 idle, from idle to sleep, from sleep to off, and from any of idle,
184 sleep or off directly back to active. Another policy module might
185 only use the active and off states, bypassing the intermediate ones.
186 </para>
187
188 </refsect1>
189
190 <!-- }}} -->
191 <!-- {{{ Power Controllers              -->
192
193 <refsect1 id="power-intro-controllers">
194 <title>Power Controllers</title>
195 <para>
196 The power management package operates primarily on power controllers.
197 The main functionality provided by a power controller is to switch the
198 power mode for some part of the system, for example the lcd display or
199 the cpu. A power controller consists primarily of a function which
200 will be invoked to switch the power mode for the part of the overall
201 system being controlled, plus some auxiliary data. A typical system
202 will include a number of different power controllers:
203 </para>
204 <orderedlist>
205 <listitem>
206 <para>
207 Usually there will be one power controller
208 <varname>power_controller_cpu</varname> associated with the processor
209 or with the target platform, and provided by the corresponding HAL
210 package. It is this controller which is responsible for switching off
211 the system when entering the <type>off</type> mode, which makes it
212 somewhat special: attempting to switch off the cpu before other
213 devices like the lcd display does not make sense because the cpu would
214 no longer be executing any instructions for the latter operation.
215 Therefore this power controller has to be invoked last when switching
216 to a lower-power mode, and similarly when switching back to a
217 higher-power mode it will be invoked first.
218 </para>
219 <para>
220 It should be noted that providing power management support is not a
221 hard requirement when porting eCos to a new processor or platform, and
222 many eCos ports predate the availability of power management support.
223 Therefore for any given platform it is distinctly possible that
224 <varname>power_controller_cpu</varname> is not yet provided, and if
225 full power management functionality is desired then the appropriate
226 HAL package would have to be extended first. System developers should
227 examine the relevant HAL documentation and sources to determine what
228 is actually available.
229 </para>
230 </listitem>
231 <listitem>
232 <para>
233 Some or all of the device drivers will supply their own power
234 controllers, as part of the device driver package. It is not required
235 that all device drivers provide power controllers. In some cases,
236 especially for devices that are integrated with the processor,
237 <varname>power_controller_cpu</varname> will take care of the
238 integrated devices as a side effect. In other cases the hardware may
239 not provide any functionality that allows power consumption to be
240 controlled. For any given device driver it is also possible that no
241 power controller exists either because it was not required when the
242 driver was written, or because the driver predates the availability of
243 power management. Again the relevant documentation and sources should
244 be consulted for further information.
245 </para>
246 </listitem>
247 <listitem>
248 <para>
249 There may be power controllers which are not associated directly with
250 any specific hardware. For example a TCP/IP stack could provide a
251 power controller so that it gets informed when the system has been
252 reactivated: by looking at the system clock it can determine for how
253 long the system has been switched off; using this information it can
254 then recover from expired dhcp leases, or even to shut down any stream
255 connections that may have become invalid (although arguably the stack
256 should have refused to go to <type>off</type> mode while there were
257 open connections).
258 </para>
259 </listitem>
260 </orderedlist>
261 </refsect1>
262
263 <!-- }}} -->
264 <!-- {{{ Basic Operation                -->
265
266 <refsect1 id="power-intro-operation">
267 <title>Basic Operation</title>
268 <para>
269 By default the Power Management package creates a thread during
270 initialization. It is also possible for the package to be used without
271 such a thread, for example in configurations which do not include a
272 full kernel, and this alternative is described below. When a separate
273 thread is used the stacksize and priority for this thread can be
274 controlled by configuration options
275 <varname>CYGNUM_POWER_THREAD_STACKSIZE</varname> and
276 <varname>CYGNUM_POWER_THREAD_PRIORITY</varname>. Typically the thread
277 will just wait on a semaphore internal to the package, and will do
278 nothing until some other part of the system requests a change to the
279 power mode.
280 </para>
281 <para>
282 At some point the policy module will decide that the system should
283 move into a lower-power mode, for example from active to idle. This is
284 achieved by calling the function <function>power_set_mode</function>,
285 provided by the power management package and declared in <filename
286 class="headerfile">cyg/power/power.h</filename>, with a single
287 argument, <literal>PowerMode_Idle</literal>. This function manipulates
288 some internal state and posts the semaphore, thus waking up the power
289 management thread. Note that the function returns before the mode
290 change has completed, and in fact depending on thread priorities this
291 return may happen before any power controller has been invoked.
292 </para>
293 <para>
294 When the power management thread wakes up it examines the internal
295 state to figure out what it should be doing. In this case it is
296 supposed to change the global power mode, so it will iterate over all
297 the power controllers requesting each one to switch to the
298 <type>idle</type> mode. It is up to each power controller to handle
299 this request appropriately. Optionally the thread will invoke a
300 callback function after processing each power controller, so that
301 higher-level code such as the policy module can more easily keep
302 track of the actual state of each controller. Once the thread has
303 iterated through all the power controllers it will again wait on the
304 internal semaphore for the next request to arrive.
305 </para>
306 <note>
307 <para>
308 At present the power management thread always runs at a single
309 priority, which defaults to a low priority. A possible future
310 enhancement would be to support two separate priorities. When
311 switching to a lower-powered mode the thread would run at a low
312 priority as before, thus allowing other threads to run and get a
313 chance to cancel this mode change. When switching to a higher-powered
314 mode the thread would run at a high priority. This could be especially
315 important when moving out of the <type>off</type> state: for example
316 it would ensure that all device drivers get a chance to wake up before
317 ordinary application threads get to run again and possibly attempt I/O
318 operations.
319 </para>
320 </note>
321 <para>
322 Although usually calls to <function>power_set_mode</function> will
323 come from just one place in the policy module, this is not a hard
324 requirement. It is possible for multiple threads to call this
325 function, with no need for any synchronization. If the power
326 management thread is in the middle of performing a mode change and a
327 new request comes in, the thread will detect this, abort the current
328 operation, and start iterating through the power controllers again
329 with the new mode. This check happens between every power controller
330 invocation. Usefully this makes it possible for power controllers
331 themselves to manipulate power modes: a power controller is invoked to
332 change mode; for some reason it determines that the new mode is
333 inappropriate; it calls <function>power_set_mode</function> to move
334 the system back to another mode; when the power controller returns
335 this event will be detected; the power management thread will abort
336 the current mode change, and start the new one.
337 </para>
338 <para>
339 In addition to changing the power mode for the system as a whole,
340 individual controllers can be manipulated using the function
341 <function>power_set_controller_mode</function>. For example, while the
342 system as a whole might be in <type>active</type> mode certain devices
343 might be kept in <type>sleep</type> mode until they are explicitly
344 activated. It is possible to mix concurrent calls to
345 <function>power_set_mode</function> and
346 <function>power_set_controller_mode</function>, and when a power
347 controller is invoked it may use
348 <function>power_set_controller_mode</function> to request further
349 changes to its own or to another controller's mode as required.
350 </para>
351 <para>
352 There are some scenarios where the power management package should not
353 use its own thread. One scenario is if the configuration is
354 specifically for a single-threaded application such as RedBoot.
355 Another scenario is if the policy module already involves a separate
356 thread: it may make more sense if the various power management
357 operations are synchronous with respect to the calling thread. The use
358 of a separate thread inside the power management package is controlled
359 by the configuration option <varname>CYGPKG_POWER_THREAD</varname>,
360 which is active only if the kernel package is present and enabled by
361 default.
362 </para>
363 <para>
364 If no separate power management thread is used then obviously the
365 implementations of <function>power_set_mode</function> and
366 <function>power_set_controller_mode</function> will be somewhat
367 different: instead of waking up a separate thread to do the work,
368 these functions will now manipulate the power controllers directly. If
369 the system does still involve multiple threads then only one thread
370 may call <function>power_set_mode</function> or
371 <function>power_set_controller_mode</function> at a time: the power
372 management package will not provide any synchronization, that must
373 happen at a higher level. However when a power controller is invoked
374 it can still call these functions as required.
375 </para>
376 </refsect1>
377
378 <!-- }}} -->
379
380 </refentry>
381
382 <!-- }}} -->
383 <!-- {{{ Power Management Info          -->
384
385 <refentry id="power-info">
386 <refmeta>
387 <refentrytitle>Power Management Information</refentrytitle>
388 </refmeta>
389 <refnamediv>
390 <refname>Obtaining Power Management Information</refname>
391 <refpurpose>finding out about the various power controllers in the system</refpurpose>
392 </refnamediv>
393
394 <refsynopsisdiv>
395 <funcsynopsis>
396 <funcsynopsisinfo>
397 #include &lt;cyg/power/power.h&gt;
398
399 extern PowerController __POWER__[], __POWER_END__;
400 extern PowerController power_controller_cpu;
401 extern cyg_handle_t    power_thread_handle;
402 </funcsynopsisinfo>
403
404 <funcprototype>
405   <funcdef>
406     PowerMode <function>power_get_mode</function>
407   </funcdef>
408   <void>
409 </funcprototype>
410 <funcprototype>
411   <funcdef>
412     PowerMode <function>power_get_desired_mode</function>
413   </funcdef>
414   <void>
415 </funcprototype>
416 <funcprototype>
417   <funcdef>
418     PowerMode <function>power_get_controller_mode</function>
419   </funcdef>
420   <paramdef>
421     PowerController* <parameter>controller</parameter>
422   </paramdef>
423 </funcprototype>
424 <funcprototype>
425   <funcdef>
426     PowerMode <function>power_get_controller_desired_mode</function>
427   </funcdef>
428   <paramdef>
429     PowerController* <parameter>controller</parameter>
430   </paramdef>
431 </funcprototype>
432 <funcprototype>
433   <funcdef>
434     const char* <function>power_get_controller_id</function>
435   </funcdef>
436   <paramdef>
437     PowerController* <parameter>controller</parameter>
438   </paramdef>
439 </funcprototype>
440 </funcsynopsis>
441 </refsynopsisdiv>
442
443 <refsect1 id="power-info-access">
444 <title>Accessing Power Controllers</title>
445 <para>
446 All the power controllers in a system are held in a table, filled in
447 at link-time. The symbols <varname>__POWER__</varname> and
448 <varname>__POWER_END</varname> can be used to iterate through this
449 table, for example:
450 </para>
451 <programlisting>
452 PowerController* controller;
453 for (controller  = &amp;(__POWER__[0]);
454      controller != &amp;(__POWER_END__);
455      controller++) {
456
457      &hellip;
458 }
459 </programlisting>
460 <para>
461 Each controller has an associated priority, controlling the order in
462 which they appear in the table. Typically a software-only component
463 such as a TCP/IP stack would use a small number for the priority, so
464 that it appears near the start of the table, whereas a device driver
465 would be nearer the back of the table. When switching to a
466 lower-powered mode the power management package will iterate through
467 this table from front to back, thus ensuring that for example the
468 TCP/IP stack gets a chance to shut down before the underlying ethernet
469 or other hardware that the stack depends on. Similarly when switching
470 to a higher-powered mode the power management package will iterate
471 through this table from back to front.
472 </para>
473 <para>
474 In most systems there will be one special controller,
475 <varname>power_controller_cpu</varname>, which should be provided by
476 one of the architectural, variant or platform HAL packages. This
477 controller will always be the last entry in the table. It is
478 responsible for the final power down operation when switching to
479 <type>off</type> mode. Other packages such as device drivers may or
480 may not declare variable identifiers for their power controllers,
481 allowing those controllers to be accessed by name as well as by their
482 entries in the global table.
483 </para>
484 </refsect1>
485
486 <refsect1 id="power-info-global">
487 <title>Global Power Modes</title>
488 <para>
489 The function <function>power_get_mode</function> can be called at any
490 time to determine the current power mode for the system as a whole.
491 The return value will be one of <literal>PowerMode_Active</literal>,
492 <literal>PowerMode_Idle</literal>, <literal>PowerMode_Sleep</literal>
493 or <literal>PowerMode_Off</literal>. In normal circumstances it is
494 unlikely that <literal>PowerMode_Off</literal> would be returned since
495 that mode generally means that the cpu is no longer running.
496 </para>
497 <para>
498 The function <function>power_get_desired_mode</function> returns the
499 power mode that the system should be running at. Most of the time this
500 will be the same value as returned by
501 <function>power_get_mode</function>. However a different value may be
502 returned when in the middle of changing power modes. For example, if
503 the current thread runs at a higher priority than the power management
504 thread then the latter may have been pre-empted in the middle of a
505 mode change: <function>power_get_mode</function> will return the mode
506 the system was running at before the mode change started, and
507 <function>power_get_desired_mode</function> will return the mode the
508 system should end up in when the mode change completes, barring
509 further calls to <function>power_set_mode</function>.
510 </para>
511 </refsect1>
512
513 <refsect1 id="power-info-individual">
514 <title>Individual Controller Power Modes</title>
515 <para>
516 The power management package keeps track of the current and desired
517 modes for each power controller, as well as the modes for the system as
518 a whole. The function <function>power_get_controller_mode</function>
519 takes a single argument, a pointer to a power controller, and returns
520 the power mode that controller is currently running at. Similarly
521 <function>power_get_controller_desired_mode</function> returns the
522 power mode that controller should be running at. Most of the time the
523 current and desired modes for a given controller will be the same, and
524 will also be the same as the global power mode. However if the power
525 management thread is preeempted in the middle of a mode change then
526 some of the controllers will have been updated to the desired global
527 mode, whereas others will still be at the old mode. The power
528 management package also provides functionality for manipulating
529 <link linkend="power-change-controller">
530 individual controllers</link>, and for <link
531 linkend="power-attached">detaching</link> controllers from
532 global mode changes.
533 </para>
534 </refsect1>
535
536 <refsect1 id="power-info-ids">
537 <title>Power Controller Identification</title>
538 <para>
539 In some scenarios the power management package will run completely
540 automated, and there is no need to identify individual power
541 controllers. Any form of identification such as a string
542 description would serve no purpose, but would still consume memory in
543 the final system. In other scenarios it may be very desirable to
544 provide some means of identification. For example, while still
545 debugging it may be useful to see a simple string when printing the
546 contents of a power controller structure. Alternatively, if the
547 application is expected to provide some sort of user interface that
548 gives control over which parts of the system are enabled or disabled,
549 a string identifier for each controller would be useful. To cope with
550 these scenarios the power management package provides a configuration
551 option <varname>CYGIMP_POWER_PROVIDE_STRINGS</varname>. When enabled,
552 each power controller will contain a pointer to a constant string
553 which can be accessed via a function
554 <function>power_get_controller_id</function>. When disabled the system
555 will not contain these strings, and the function will not be provided.
556 The following code illustrates how to use this function.
557 </para>
558 <programlisting>
559 #include &lt;stdio.h&gt;
560 #include &lt;pkgconf/system.h&gt;
561 #ifndef CYGPKG_POWER
562 # error The power management package is not present.
563 #endif
564 #include &lt;pkgconf/power.h&gt;
565 #ifndef CYGIMP_POWER_PROVIDE_STRINGS
566 # error Power controller identifiers are not available.
567 #endif
568 #include &lt;cyg/power/power.h&gt;
569
570 static const char*
571 mode_to_string(PowerMode mode)
572 {
573     const char* result;
574     switch(mode) {
575       case PowerMode_Active : result = "active"; break;
576       case PowerMode_Idle   : result = "idle"; break;
577       case PowerMode_Sleep  : result = "sleep"; break;
578       case PowerMode_Off    : result = "off"; break;
579       default               : result = "&lt;unknown&gt;"; break;
580     }
581     return result;
582 }
583
584 int
585 main(int argc, char** argv)
586 {
587     PowerController* controller;
588
589     for (controller = &amp;(__POWER__[0]);
590          controller != &amp;(__POWER_END__);
591          controller++) {
592         printf("Controller @ %p: %s, %s\n", controller,
593                power_get_controller_id(controller),
594                mode_to_string(power_get_controller_mode(controller)));
595     }
596     return 0;
597 }
598 </programlisting>
599 </refsect1>
600 <refsect1 id="power-info-thread">
601 <title>The Power Management Thread</title>
602 <para>
603 If the power management package is configured to use a separate thread
604 then a handle for that thread is made available to higher-level code
605 via the variable <varname>power_thread_handle</varname>. This handle
606 can be used for a variety of purposes, including manipulating that
607 thread's priority.
608 </para>
609 </refsect1>
610
611 </refentry>
612
613 <!-- }}} -->
614 <!-- {{{ Changing Power Modes           -->
615
616 <refentry id="power-change">
617 <refmeta>
618 <refentrytitle>Changing Power Modes</refentrytitle>
619 </refmeta>
620 <refnamediv>
621 <refname>Changing Power Modes</refname>
622 <refpurpose>reducing or increasing power consumption as needed</refpurpose>
623 </refnamediv>
624
625 <refsynopsisdiv>
626 <funcsynopsis>
627 <funcsynopsisinfo>
628 #include &lt;cyg/power/power.h&gt;
629 </funcsynopsisinfo>
630
631 <funcprototype>
632   <funcdef>
633     void <function>power_set_mode</function>
634   </funcdef>
635   <paramdef>
636     PowerMode <parameter>new_mode</parameter>
637   </paramdef>
638 </funcprototype>
639 <funcprototype>
640   <funcdef>
641     void <function>power_set_controller_mode</function>
642   </funcdef>
643   <paramdef>
644     PowerController* <parameter>controller</parameter>
645   </paramdef>
646   <paramdef>
647     PowerMode <parameter>new_mode</parameter>
648   </paramdef>
649 </funcprototype>
650 <funcprototype>
651   <funcdef>
652     void <function>power_set_controller_mode_now</function>
653   </funcdef>
654   <paramdef>
655     PowerController* <parameter>controller</parameter>
656   </paramdef>
657   <paramdef>
658     PowerMode <parameter>new_mode</parameter>
659   </paramdef>
660 </funcprototype>
661 </funcsynopsis>
662 </refsynopsisdiv>
663
664 <refsect1 id="power-change-global">
665 <title>Changing the Global Power Mode</title>
666 <para>
667 The primary functionality supported by the power management package is
668 to change the system's global power mode. This is achieved by calling
669 the function <function>power_set_mode</function> with a single
670 argument, which should be one of <literal>PowerMode_Active</literal>,
671 <literal>PowerMode_Idle</literal>, <literal>PowerMode_Sleep</literal>
672 or <literal>PowerMode_Off</literal>. Typically this function will only
673 be invoked in certain scenarios:
674 </para>
675 <orderedlist>
676 <listitem>
677 <para>
678 A typical system will contain a policy module which is primarily
679 responsible for initiating power mode changes, and a thread inside the
680 power management package. The policy module will call
681 <function>power_set_mode</function>, which has the effect of
682 manipulating some internal state in the power management package and
683 waking up its thread. When this thread gets scheduled to run (its
684 priority is controlled by a configuration option), it will iterate
685 over the power controllers and invoke each controller to change its
686 power mode. There is support for a <link
687 linkend="power-policy-callback">callback function</link>, and for
688 <link linkend="power-attached">detached</link> power controllers.
689 </para>
690 </listitem>
691 <listitem>
692 <para>
693 After a call to <function>power_set_mode</function> but before the
694 power management thread has had a chance to iterate over all the
695 controllers, or even before the thread has been rescheduled at all,
696 the policy module may decide that a different power mode would be more
697 appropriate for the current situation and calls
698 <function>power_set_mode</function> again. This has the effect of
699 aborting the previous mode change, followed by the power management
700 thread iterating over the power controllers again for the new mode.
701 </para>
702 </listitem>
703 <listitem>
704 <para>
705 If there is no single policy module responsible for power mode
706 changes, any code can call <function>power_set_mode</function>. If
707 there are multiple calls in quick succession, earlier calls will
708 be aborted and the system should end up in the power mode
709 corresponding to the last call
710 </para>
711 </listitem>
712 <listitem>
713 <para>
714 As a special case, it is possible for a power controller to call
715 <function>power_set_mode</function> when invoked by the power
716 management thread. For example a power controller could decide that it
717 is inappropriate for the system to go to sleep because the device it
718 is associated with is still busy. The effect is as if the policy
719 module had called <function>power_set_mode</function> again before 
720 the mode change had completed.
721 </para>
722 </listitem>
723 </orderedlist>
724 <para>
725 If the power management package has been configured not to use a
726 separate thread then obviously the behaviour is somewhat different.
727 The call to <function>power_set_mode</function> will now iterate over
728 the various power controllers immediately, rather than leaving this to
729 a separate thread, and the whole mode change completes before
730 <function>power_set_mode</function> returns. If some other thread or a
731 DSR calls <function>power_set_mode</function> concurrently the
732 behaviour of the system is undefined. However, it is still legal for a
733 power controller to call <function>power_set_mode</function>:
734 effectively this is a recursive call; it is detected by the system,
735 and internal state is updated; the recursive
736 <function>power_set_mode</function> call now returns, and when the
737 power controller returns back to the original
738 <function>power_set_mode</function> call it detects what has happened,
739 aborts the previous mode change, and starts a new mode change as
740 requested by the controller.
741 </para>
742 <para>
743 <function>power_set_mode</function> is normally invoked from thread
744 context. If a separate power management thread is used it can be
745 invoked safely from DSR context. If the system is configured not to
746 use such a thread, it may or may not be safe to invoke this function
747 from DSR context: essentially the function just iterates through
748 the various power controllers, and the documentation or source code of
749 each controller present in the current system will have to be examined
750 to determine whether or not this can happen safely in DSR context.
751 <function>power_set_mode</function> should never be invoked from
752 ISR context.
753 </para>
754 </refsect1>
755
756 <refsect1 id="power-change-controller">
757 <title>Manipulating an Individual Power Controller</title>
758 <para>
759 In some cases it is desirable to set the power mode of an individual
760 controller separately from the mode for the system as a whole. For
761 example if a device is not currently being used then the associated
762 power controller could be set to <literal>PowerMode_Off</literal>,
763 even while the system as a whole is still active. This can be achieved
764 by calling the function
765 <function>power_set_controller_mode</function>. It takes two
766 arguments: the first identifies a particular controller; the second
767 specifies the desired new power mode for that controller. The function
768 operates in much the same way as <function>power_set_mode</function>,
769 for example if a separate power management thread is being used then
770 <function>power_set_controller_mode</function> operates by
771 manipulating some internal state and waking up that thread. The
772 limitations are also much the same as for
773 <function>power_set_mode</function>, so for example
774 <function>power_set_controller_mode</function> should not be invoked
775 from inside ISRs.
776 </para>
777 <para>
778 Manipulating individual controllers is often used in conjunction with
779 the function <link
780 linkend="power-attached"><function>power_set_controller_attached</function></link>,
781 allowing the policy module to specify which controllers are affected
782 by global mode changes.
783 </para>
784 </refsect1>
785
786 <refsect1 id="power-change-controller-now">
787 <title>Direct Manipulation of a Power Controller</title>
788 <para>
789 In exceptional circumstances it may be necessary to invoke a power
790 controller directly, bypassing the power management thread and
791 higher-level functionality such as <link
792 linkend="power-policy-callback">callback functions</link>. The
793 function <function>power_set_controller_mode_now</function> allows
794 this. It takes two arguments, a controller and a mode, just like
795 <function>power_set_controller_mode</function>.
796 </para>
797 <para>
798 Use of <function>power_set_controller_mode_now</function> is
799 dangerous. For example no attempt is made to synchronise with any
800 other power mode changes that might be happening concurrently. A
801 possible use is when the system gets woken up out of
802 <type>sleep</type> mode: depending on the hardware, on which power
803 controllers are present, and on the application code it may be
804 necessary to wake up some power controllers immediately before the
805 system as a whole is ready to run again.
806 </para>
807 </refsect1>
808
809 </refentry>
810
811 <!-- }}} -->
812 <!-- {{{ Policy support                 -->
813
814 <refentry id="power-policy">
815 <refmeta>
816 <refentrytitle>Support for Policy Modules</refentrytitle>
817 </refmeta>
818 <refnamediv>
819 <refname>Support for Policy Modules</refname>
820 <refpurpose>closer integration with higher-level code</refpurpose>
821 </refnamediv>
822
823 <refsynopsisdiv>
824 <funcsynopsis>
825 <funcsynopsisinfo>
826 #include &lt;cyg/power/power.h&gt;
827 </funcsynopsisinfo>
828
829 <funcprototype>
830   <funcdef>
831     void <function>power_set_policy_callback</function>
832   </funcdef>
833   <paramdef>
834     void (*)(PowerController*, PowerMode, PowerMode, PowerMode, PowerMode) <parameter>callback</parameter>
835   </paramdef>
836 </funcprototype>
837 <funcprototype>
838   <funcdef>
839     void (*)(PowerController*, PowerMode, PowerMode, PowerMode, PowerMode) <function>power_get_policy_callback</function>
840   </funcdef>
841   <void>
842 </funcprototype>
843 <funcprototype>
844   <funcdef>
845     CYG_ADDRWORD <function>power_get_controller_policy_data</function>
846   </funcdef>
847   <paramdef>
848     PowerController* <parameter>controller</parameter>
849   </paramdef>
850 </funcprototype>
851 <funcprototype>
852   <funcdef>
853     void <function>power_set_controller_policy_data</function>
854   </funcdef>
855   <paramdef>
856     PowerController* <parameter>controller</parameter>
857   </paramdef>
858   <paramdef>
859     CYG_ADDRWORD <parameter>data</parameter>
860   </paramdef>
861 </funcprototype>
862
863 </funcsynopsis>
864 </refsynopsisdiv>
865
866 <refsect1 id="power-policy-callback">
867 <title>Policy Callbacks</title>
868 <para>
869 The use of a separate thread to perform power mode changes in typical
870 configurations can cause problems for some policy modules.
871 Specifically, the policy module can request a mode change for the
872 system as a whole or for an individual controller, but it does not
873 know when the power management thread actually gets scheduled to run
874 again and carry out the request. Although it would be possible for the
875 policy module to perform some sort of polling, in general that is
876 undesirable.
877 </para>
878 <para>
879 To avoid such problems the policy module can install a callback
880 function using <function>power_set_policy_callback</function>. The
881 current callback function can be retrieved using
882 <function>power_get_policy_callback</function>. If a callback function
883 has been installed then it will be called by the power management
884 package whenever a power controller has been invoked to perform a mode
885 change. The callback will be called in the context of the power
886 management thread, so usually it will have to make use of thread
887 synchronisation primitives to interact with the main policy module. It
888 is passed five arguments:
889 </para>
890 <orderedlist>
891 <listitem>
892 <para>
893 The power controller that has just been invoked to perform a mode
894 change. 
895 </para>
896 </listitem>
897 <listitem>
898 <para>
899 The mode this controller was running at before the invocation.
900 </para>
901 </listitem>
902 <listitem>
903 <para>
904 The current mode this controller is now running at.
905 </para>
906 </listitem>
907 <listitem>
908 <para>
909 The desired mode before the power controller was invoked. Usually this
910 will be the same as the current mode, unless the controller has
911 decided for some reason that this was inappropriate.
912 </para>
913 </listitem>
914 <listitem>
915 <para>
916 The current desired mode. This will differ from the previous argument
917 only if there has was another call to
918 <function>power_set_mode</function> or
919 <function>power_set_controller_mode</function> while the power
920 controller was being invoked, probably by the power controller itself.
921 </para>
922 </listitem>
923 </orderedlist>
924 <para>
925 A simple example of a policy callback function would be:
926 </para>
927 <programlisting>
928 static void
929 power_callback(
930     PowerController* controller,
931     PowerMode old_mode,
932     PowerMode new_mode,
933     PowerMode old_desired_mode,
934     powerMode new_desired_mode)
935 {
936     printf("Power mode change: %s, %s -> %d\n",
937         power_get_controller_id(controller),
938         mode_to_string(old_mode),
939         mode_to_string(new_mode));
940
941     CYG_UNUSED_PARAM(PowerMode, old_desired_mode);
942     CYG_UNUSED_PARAM(PowerMode, new_desired_mode);
943 }
944
945 int
946 main(int argc, char** argv)
947 {
948     &hellip;
949     power_set_policy_callback(&amp;power_callback);
950     &hellip;
951 }
952 </programlisting>
953 <para>
954 If <function>power_set_controller_mode_now</function> is used to
955 manipulate an individual controller the policy callback will not be
956 invoked. This function may get called from any context including DSRs,
957 and even if there is already a call to the policy callback happening
958 in some other context, so invoking the callback would usually be
959 unsafe.
960 </para>
961 <para>
962 If the power management package has not been configured to use a
963 separate thread then <function>power_set_mode</function> and
964 <function>power_set_controller_mode</function> will manipulate the
965 power controllers immediately and invoke the policy callback
966 afterwards. Therefore the policy callback will typically run in the
967 same context as the main policy module.
968 </para>
969 </refsect1>
970
971 <refsect1 id="power-policy-data">
972 <title>Policy-specific Controller Data</title>
973 <para>
974 Some policy modules may want to associate some additional data with
975 each power controller. This could be achieved by for example
976 maintaining a hash table or similar data structure, but for
977 convenience the power management package allows higher-level code,
978 typically the policy module, to store and retrieve one word of data in
979 each power controller. The function
980 <function>power_set_controller_policy_data</function> takes two
981 arguments, a pointer to a power controller and a
982 <type>CYG_ADDRWORD</type> of data: by appropriate use of casts this
983 word could be an integer or a pointer to some data structure. The
984 matching function
985 <function>power_get_controller_policy_data</function> retrieves the
986 word previously installed, and can be cast back to an integer or
987 pointer. The default value for the policy data is 0.
988 </para>
989 <para>
990 For example the following code fragment stores a simple index value in
991 each power controller. This could then be retrieved by the policy
992 callback.
993 </para>
994 <programlisting>
995     unsigned int     i = 0;
996     PowerController* controller;
997
998     for (controller = &amp;(__POWER__[0]);
999          controller != &amp;(__POWER_END__);
1000          controller++) {
1001         power_set_controller_policy_data(controller, (CYG_ADDRWORD) i++);
1002     }
1003 </programlisting>
1004 <para>
1005 Not all policy modules will require per-controller data. The
1006 configuration option
1007 <varname>CYGIMP_POWER_PROVIDE_POLICY_DATA</varname> can be used to
1008 control this functionality, thus avoiding wasting a small amount of
1009 memory inside each power controller structure.
1010 </para>
1011
1012 </refsect1>
1013 </refentry>
1014
1015 <!-- }}} -->
1016 <!-- {{{ Attached/detached controllers  -->
1017
1018 <refentry id="power-attached">
1019 <refmeta>
1020 <refentrytitle>Attached and Detached Controllers</refentrytitle>
1021 </refmeta>
1022 <refnamediv>
1023 <refname>Attached and Detached Controllers</refname>
1024 <refpurpose>control which power controllers are affected by global changes</refpurpose>
1025 </refnamediv>
1026
1027 <refsynopsisdiv>
1028 <funcsynopsis>
1029 <funcsynopsisinfo>
1030 #include &lt;cyg/power/power.h&gt;
1031 </funcsynopsisinfo>
1032 <funcprototype>
1033   <funcdef>
1034     cyg_bool <function>power_get_controller_attached</function>
1035   </funcdef>
1036   <paramdef>
1037     PowerController* <parameter>controller</parameter>
1038   </paramdef>
1039 </funcprototype>
1040 <funcprototype>
1041   <funcdef>
1042     void <function>power_set_controller_attached</function>
1043   </funcdef>
1044   <paramdef>
1045     PowerController* <parameter>controller</parameter>
1046   </paramdef>
1047   <paramdef>
1048     cyg_bool <parameter>new_state</parameter>
1049   </paramdef>
1050 </funcprototype>
1051 </funcsynopsis>
1052 </refsynopsisdiv>
1053
1054 <refsect1>
1055 <title>Detaching Power Controllers</title>
1056 <para>
1057 By default the global operation <function>power_set_mode</function>
1058 affects all power controllers. There may be circumstances when this is
1059 not desirable. For example if a particular device is not currently
1060 being used then it can be left switched off: the rest of the system
1061 could be moving between <type>active</type>, <type>idle</type> and
1062 <type>sleep</type> modes, but there is no point in invoking the power
1063 controller for the unused device. To support this the power management
1064 package supports the concept of attached and detached controllers. By
1065 default all controllers are attached, and hence will be affected by
1066 global mode changes. A specific controller can be detached using the
1067 function <function>power_set_controller_attached</function>. This
1068 function takes two arguments, one to specify a particular controller
1069 and another to specify the desired new state.
1070 <function>power_get_controller_attached</function> can be used to
1071 determine whether or not a specific controller is currently attached.
1072 </para>
1073 <para>
1074 The attached or detached state of a controller only affects what
1075 happens during a global mode change, in other words following a call
1076 to <function>power_set_mode</function>. It is still possible to
1077 manipulate a detached controller using
1078 <function>power_set_controller_mode</function> or
1079 <function>power_set_controller_mode_now</function>.
1080 </para>
1081
1082 </refsect1>
1083 </refentry>
1084
1085 <!-- }}} -->
1086 <!-- {{{ Implementing                   -->
1087
1088 <refentry id="power-controller">
1089 <refmeta>
1090 <refentrytitle>Implementing a Power Controller</refentrytitle>
1091 </refmeta>
1092 <refnamediv>
1093 <refname>Implementing a Power Controller</refname>
1094 <refpurpose>adding power management support to device drivers and
1095 other packages</refpurpose>
1096 </refnamediv>
1097
1098 <refsect1>
1099 <title>Implementing a Power Controller</title>
1100 <para>
1101 A system will have some number of power controllers. Usually there
1102 will be one power controller for the cpu,
1103 <varname>power_controller_cpu</varname>, typically provided by one of
1104 the HAL packages and responsible for managing the processor itself and
1105 associated critical components such as memory. Some or all of the
1106 device drivers will provide power controllers, allowing the power
1107 consumption of the associated devices to be controlled. There may be
1108 some arbitrary number of other controllers present in the system. The
1109 power management package does not impose any restrictions on the
1110 number or nature of the power controllers in the system, other than
1111 insisting that at most one <varname>power_controller_cpu</varname> be
1112 provided.
1113 </para>
1114 <para>
1115 Each power controller involves a single data structure of type
1116 <structname>PowerController</structname>, defined in the header file
1117 <filename class="headerfile">cyg/power/power.h</filename>. These data
1118 structures should all be placed in the table
1119 <literal>__POWER__</literal>, so that the power management package and
1120 other code can easily locate all the controllers in the system. This
1121 table is constructed at link-time, avoiding code-size or run-time
1122 overheads. To facilitate this the package provides two macros which
1123 should be used to define a power controller,
1124 <literal>POWER_CONTROLLER()</literal> and
1125 <literal>POWER_CONTROLLER_CPU()</literal>.
1126 </para>
1127 <para>
1128 The macro <literal>POWER_CONTROLLER</literal> takes four arguments:
1129 </para>
1130 <orderedlist>
1131 <listitem>
1132 <para>
1133 A variable name. This can be used to access the power controller
1134 directly, as well as via the table.
1135 </para>
1136 </listitem>
1137 <listitem>
1138 <para>
1139 A priority. The table of power controllers is sorted, such that power
1140 controllers with a numerically lower priority come earlier in the
1141 table. The special controller <varname>power_controller_cpu</varname>
1142 always comes at the end of the table. When moving from a high-power
1143 mode to a lower-powered mode, the power management package iterates
1144 through the table from front to back. When moving to a higher-powered
1145 mode the reverse direction is used. The intention is that the power
1146 controller for a software-only package such as a TCP/IP stack should
1147 appear near the start of the table, whereas the controllers for the
1148 ethernet and similar devices would be near the end of the table. Hence
1149 when the policy module initiates a mode change to a lower-powered mode
1150 the TCP/IP stack gets a chance to cancel this mode change, before the
1151 devices it depends on are powered down. Similarly when moving to a
1152 higher-powered mode the devices will be re-activated before any
1153 software that depends on those devices.
1154 </para>
1155 <para>
1156 The header file <filename
1157 class="headerfile">cyg/power/power.h</filename> defines three
1158 priorities <literal>PowerPri_Early</literal>,
1159 <literal>PowerPri_Typical</literal> and
1160 <literal>PowerPri_Late</literal>. For most controllers one of these
1161 priorities, possibly with a small number added or subtracted, will
1162 give sufficient control. If an application developer is uncertain
1163 about the relative priorities of the various controllers, a simple
1164 <link linkend="power-info-ids">test program</link> that iterates over
1165 the table will quickly eliminate any confusion.
1166 </para>
1167 </listitem>
1168 <listitem>
1169 <para>
1170 A constant string identifier. If the system has been configured
1171 without support for such identifiers
1172 (<varname>CYGIMP_POWER_PROVIDE_STRINGS</varname>) then this identifer
1173 will be discarded at compile-time. Otherwise it will be made available
1174 to higher-level code using the function
1175 <function>power_get_controller_id</function>. 
1176 </para>
1177 </listitem>
1178 <listitem>
1179 <para>
1180 A function pointer. This will be invoked to perform actual mode
1181 changes, as described below.
1182 </para>
1183 </listitem>
1184 </orderedlist>
1185 <para>
1186 A typical example of the use of the
1187 <literal>POWER_CONTROLLER</literal> macro would be as follows:
1188 </para>
1189 <programlisting>
1190 #include &lt;pkgconf/system.h&gt;
1191
1192 #ifdef CYGPKG_POWER
1193 # include &lt;cyg/power/power.h&gt;
1194
1195 static void
1196 xyzzy_device_power_mode_change(
1197     PowerController* controller,
1198     PowerMode        desired_mode,
1199     PowerModeChange  change)
1200 {
1201    // Do the work
1202 }
1203
1204 static POWER_CONTROLLER(xyzzy_power_controller, \
1205                         PowerPri_Late,          \
1206                         "xyzzy device",         \
1207                         &amp;xyzzy_device_power_mode_change);
1208 #endif
1209 </programlisting>
1210 <para>
1211 This creates a variable <varname>xyzzy_power_controller</varname>,
1212 which is a power controller data structure that will end up near the
1213 end of the table of power controllers. Higher-level code can
1214 iterate through this table and report the string <literal>"xyzzy
1215 device"</literal> to the user. Whenever there is a mode change
1216 operation that affects this controller, the function
1217 <function>xyzzy_device_power_mode_change</function> will be invoked.
1218 The variable is declared static so this controller cannot be
1219 manipulated by name in any other code. Alternatively, if the variable
1220 had not been declared static other code could manipulate this
1221 controller by name as well as through the table, especially if the
1222 package for the xyzzy device driver explicitly declared this
1223 variable in an exported header file. Obviously exporting the variable
1224 involves a slight risk of a name clash at link time.
1225 </para>
1226 <para>
1227 The above code explicitly checks for the presence of the power
1228 management package before including that package's header file or
1229 providing any related functionality. Since power management
1230 functionality is optional, such checks are recommended.
1231 </para>
1232 <para>
1233 The macro <literal>POWER_CONTROLLER_CPU</literal> only takes two
1234 arguments, a string identifier and a mode change function pointer.
1235 This macro always instantiates a variable
1236 <varname>power_controller_cpu</varname> so there is no need to provide
1237 a variable name. The resulting power controller structure always
1238 appears at the end of the table, so there is no need to specify a
1239 priority. Typical usage of the <literal>POWER_CONTROLLER_CPU</literal>
1240 macro would be:
1241 </para>
1242 <programlisting>
1243 static void
1244 wumpus_processor_power_mode_change(
1245     PowerController* controller,
1246     PowerMode        desired_mode,
1247     PowerModeChange  change)
1248 {
1249    // Do the work
1250 }
1251
1252 POWER_CONTROLLER_CPU("wumpus processor", \
1253                      &amp;wumpus_processor_power_mode_change);
1254 </programlisting>
1255 <para>
1256 This defines a power controller structure
1257 <varname>power_controller_cpu</varname>. It should not be declared
1258 static since higher-level code may well want to manipulate the cpu's
1259 power mode directly, and the variable is declared by the power
1260 management package's header file.
1261 </para>
1262 <para>
1263 Some care has to be taken to ensure that the power controllers
1264 actually end up in the final executable. If a power controller
1265 variable ends up in an ordinary library and is never referenced
1266 directly then typically the linker will believe that the variable is
1267 not needed and it will not end up in the executable. For eCos packages
1268 this can be achieved in the CDL, by specifying that the containing
1269 source file should end up in <filename>libextras.a</filename> rather
1270 than the default <filename>libtarget.a</filename>:
1271 </para>
1272 <programlisting>
1273 cdl_package CYGPKG_HAL_WUMPUS_ARCH {
1274     &hellip;
1275     compile -library=libextras.a data.c
1276 }
1277 </programlisting>
1278 <para>
1279 If the file <filename>data.c</filename> instantiates a power
1280 controller this is now guaranteed to end up in the final executable,
1281 as intended. Typically HAL and device driver packages will already
1282 have some data that must not be eliminated by the linker, so they will
1283 already contain a file that gets built into
1284 <filename>libextras.a</filename>. For power controllers defined inside
1285 application code it is important that the power controllers end up in
1286 <filename>.o</filename> object files rather than in
1287 <filename>.a</filename> library archive files.
1288 </para>
1289 <para>
1290 All the real work of a power controller is done by the mode change
1291 function. If the power management package has been configured to use a
1292 separate thread then this mode change function will be invoked by that
1293 thread (except for the special case of <link
1294 linkend="power-change-controller-now"><function>power_set_controller_mode_now</function></link>). 
1295 If no separate thread is used then the mode change function will be
1296 invoked directly by <function>power_set_mode</function> or
1297 <function>power_set_controller_mode</function>.
1298 </para>
1299 <para>
1300 The mode change function will be invoked with three arguments. The
1301 first argument identifies the power controller. Usually this argument
1302 is not actually required since a given mode change function will only
1303 ever be invoked for a single power controller. For example,
1304 <function>xyzzy_device_power_mode_change</function> will only ever be
1305 used in conjunction with <varname>xyzzy_power_controller</varname>.
1306 However there may be some packages which contain multiple controllers,
1307 all of which can share a single mode change function, and in that case
1308 it is essential to identify the specific controller. The second
1309 argument specifies the mode the controller should switch to, if
1310 possible: it will be one of <literal>PowerMode_Active</literal>,
1311 <literal>PowerMode_Idle</literal>, <literal>PowerMode_Sleep</literal>
1312 or <literal>PowerMode_Off</literal>. The final argument will be one of
1313 <literal>PowerModeChange_Controller</literal>,
1314 PowerModeChange_ControllerNow, or
1315 <literal>PowerModeChange_Global</literal>, and identifies the call
1316 that caused this invocation. For example, if the mode change function
1317 was invoked because of a call to <function>power_set_mode</function>
1318 then this argument will be <literal>PowerModeChange_Global</literal>.
1319 It is up to each controller to decide how to interpret this final
1320 argument. A typical controller might reject a global request to switch
1321 to <type>off</type> mode if the associated device is still busy, but
1322 if the request was aimed specifically at this controller then it could
1323 instead abort any current I/O operations and switch off the device.
1324 </para>
1325 <para>
1326 The <structname>PowerController</structname> data structure contains
1327 one field, <structfield>mode</structfield>, that needs to be updated
1328 by the power mode change function. At all times it should indicate the
1329 current mode for this controller. When a mode change is requested the
1330 desired mode is passed as the second argument. The exact operation of
1331 the power mode change function depends very much on what is being
1332 controlled and the current circumstances, but some guidelines are
1333 possible:
1334 </para>
1335 <orderedlist>
1336 <listitem>
1337 <para>
1338 If the request can be satisfied without obvious detriment, do so and
1339 update the <structfield>mode</structfield> field. Reducing the power
1340 consumption of a device that is not currently being used is generally
1341 harmless.
1342 </para>
1343 </listitem>
1344 <listitem>
1345 <para>
1346 If a request is a no-op, for example if the system is switching
1347 from <type>idle</type> to <type>sleep</type> mode and the controller
1348 does not distinguish between these modes, simply act as if the request
1349 was satisfied.
1350 </para>
1351 </listitem>
1352 <listitem>
1353 <para>
1354 If a request is felt to be unsafe, for example shutting down a
1355 device that is still in use, then the controller may decide
1356 to reject this request. This is especially true if the request was a
1357 global mode change as opposed to one intended specifically for this
1358 controller: in the latter case the policy module should be given due
1359 deference. There are a number of ways in which a request can be
1360 rejected:
1361 </para>
1362 <orderedlist>
1363 <listitem>
1364 <para>
1365 If the request cannot be satisfied immediately but may be feasible in
1366 a short while, leave the <structfield>mode</structfield> field
1367 unchanged. Higher-level code in the policy module can interpret this
1368 as a hint to retry the operation a little bit later. This approach is
1369 also useful if the mode change can be started but will take some time
1370 to complete, for example shutting down a socket connection, and
1371 additional processing will be needed later on.
1372 </para>
1373 </listitem>
1374 <listitem>
1375 <para>
1376 If the request is felt to be inappropriate, for example switching off
1377 a device that is still in use, the mode change function can
1378 call <function>power_set_controller_mode</function> to reset the
1379 desired mode for this controller back to the current mode.
1380 Higher-level code can then interpret this as a hint that there is more
1381 activity in the system than had been apparent.
1382 </para>
1383 </listitem>
1384 <listitem>
1385 <para>
1386 For a global mode change, if the new mode is felt to be inappropriate
1387 then the power controller can call <function>power_set_mode</function>
1388 to indicate this. An example of this would be the policy module
1389 deciding to switch off the whole unit while there is still I/O
1390 activity.
1391 </para>
1392 </listitem>
1393 </orderedlist>
1394 </listitem>
1395 </orderedlist>
1396 <para>
1397 Mode change functions should not directly manipulate any other fields
1398 in the <structname>PowerController</structname> data structure. If it
1399 is necessary to keep track of additional data then static variables
1400 can be used.
1401 </para>
1402 <para>
1403 It should be noted that the above are only guidelines. Their
1404 application in any given situation may be unclear. In addition the
1405 detailed requirements of specific systems will vary, so even if the
1406 power controller for a given device driver follows the above
1407 guidelines exactly it may turn out that slightly different behaviour
1408 would be more appropriate for the actual system that is being
1409 developed. Fortunately the open source nature of
1410 <productname>eCos</productname> allows system developers to fine-tune
1411 power controllers to meet their exact requirements.
1412 </para>
1413
1414 </refsect1>
1415 </refentry>
1416
1417 <!-- }}} -->
1418
1419 <!-- /reference -->
1420 </part>