Lines Matching +full:suspend +full:- +full:to +full:- +full:idle

1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* -*- linux-c -*-
4 * Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
10 * Minor enhancements and updates (to the patch set) for 1.3.x
13 * Make /proc/apm easy to format (bump driver version)
16 * (Thanks to Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de>)
43 * 1.1: support user-space standby and suspend, power off after system
46 * is only incorrect by 30-60mS (vs. 1S previously) (Gabor J. Toth
48 * screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
49 * 1.2a:Simple change to stop mysterious bug reports with SMP also added
50 * levels to the printk calls. APM is not defined for SMP machines.
54 * 1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
61 * Only try to turn off the first display device.
63 * <echter@informatik.uni-rostock.de>
66 * to reflect current state of APM BIOS.
68 * Reset interrupt 0 timer to 100Hz after suspend
78 * change APM_NOINTS to CONFIG_APM_ALLOW_INTS
82 * Try to cope with BIOS's that need to have all display
86 * the segments needed to have byte granularity.
88 * Add hack to allow power off of SMP systems by popular request.
101 * Try to blank all devices on any error.
103 * Check nr_running to detect if we are idle (from
109 * <Walter.Hofmann@physik.stud.uni-erlangen.de>).
117 * Do error notification to user mode if BIOS calls fail.
118 * Move entrypoint offset fix to ...boot/setup.S
120 * Remove smp-power-off. SMP users must now specify
121 * "apm=power-off" on the kernel command line. Suggested
130 * Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS
132 * Fix thinko in suspend() (wrong return).
133 * Notify drivers on critical suspend.
134 * Make kapmd absorb more idle time (Pavel Machek <pavel@ucw.cz>
139 * <tmh@magenta-logic.com> and <zlatko@iskon.hr>) modified by sfr.
145 * Changed to use the sysrq-register hack for registering the
153 * Exposed the disable flag to dmi so that we can handle known
156 * calling it - instead idle. (Alan Cox <alan@lxorguk.ukuu.org.uk>)
157 * If an APM idle fails log it and idle sensibly
158 * 1.15: Don't queue events to clients who open the device O_WRONLY.
162 * 1.16: Fix idle calling. (Andreas Steinmetz <ast@domdv.de> et al.)
163 * Notify listeners of standby or suspend events before notifying
164 * drivers. Return EBUSY to ioctl() if suspend is rejected.
167 * after a suspend (Thomas Hood)
174 * TODO: determine if its "boot CPU" or "CPU0" we want to lock to.
180 * Intel Order Number 241704-001. Microsoft Part Number 781-110-X01.
221 #include <linux/suspend.h>
234 #include <asm/nospec-branch.h>
245 * [no-]allow[-_]ints allow interrupts during BIOS calls
246 * [no-]broken[-_]psr BIOS has a broken GetPowerStatus call
247 * [no-]realmode[-_]power[-_]off switch to real mode before
249 * [no-]debug log some debugging messages
250 * [no-]power[-_]off power off on shutdown
251 * [no-]smp Use apm even on an SMP box
252 * bounce[-_]interval=<n> number of ticks to ignore suspend
254 * idle[-_]threshold=<n> System idle percentage above which to
255 * make APM BIOS idle calls. Set it to
256 * 100 to disable.
257 * idle[-_]period=<n> Period (in 1/100s of a second) over
258 * which the idle percentage is
272 * ?: AcerNote-950: oops on reading /proc/apm - workaround is a WIP
280 * Define as 1 to make the driver always call the APM BIOS busy
282 * idle routine. Otherwise, define as 0.
287 * Define to make the APM BIOS calls zero all data segment registers (so
289 * tries to write to arbitrary memory).
296 * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
309 * Need to poll the APM BIOS every second
314 * Ignore suspend events for this amount of time after a resume
324 * The per-file APM data
349 * idle percentage above which bios idle calls are done
366 { /* entry 1 is for APM idle */
368 .desc = "APM idle",
397 static int apm_disabled = -1;
419 * that extends up to the end of page zero (that we have reserved).
420 * This is for buggy BIOS's that refer to (real mode) segment 0x40
424 (unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
432 * the message codes that the BIOS uses to tell us about events
436 "system suspend",
442 "critical suspend",
444 "user suspend",
474 { APM_BAD_STATE, "Unable to enter requested state" },
482 * apm_error - display an APM error
486 * Write a meaningful log entry to the kernel log in the event of
510 * are saved and zeroed this means that if the BIOS tries to reference
513 * for the rest of the kernel. And it will be very obvious! :-) Doing
514 * this depends on CS referring to the same physical memory as DS so that
570 /* Error: -ENOMEM, or bits 8-15 of eax */
575 * __apm_bios_call - Make an APM BIOS 32bit call
576 * @_call: pointer to struct apm_bios_call.
583 * code is returned in AH (bits 8-15 of eax) and this function
584 * returns non-zero.
608 apm_bios_call_asm(call->func, call->ebx, call->ecx, in __apm_bios_call()
609 &call->eax, &call->ebx, &call->ecx, &call->edx, in __apm_bios_call()
610 &call->esi); in __apm_bios_call()
618 return call->eax & 0xff; in __apm_bios_call()
627 * have to worry about OOM or overhead. */ in on_cpu0()
636 /* work_on_cpu can fail with -ENOMEM */ in on_cpu0()
638 call->err = ret; in on_cpu0()
640 call->err = (call->eax >> 8) & 0xff; in on_cpu0()
646 * apm_bios_call - Make an APM BIOS 32bit call (on CPU 0)
657 * __apm_bios_call_simple - Make an APM BIOS 32bit call (on CPU 0)
658 * @_call: pointer to struct apm_bios_call.
662 * (bits 8-15 of eax) and this function returns non-zero (it can
663 * also return -ENOMEM). This is used for simpler BIOS operations.
689 error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx, in __apm_bios_call_simple()
690 &call->eax); in __apm_bios_call_simple()
701 * apm_bios_call_simple - make a simple APM BIOS 32bit call
702 * @func: APM function to invoke
710 * and this function returns non-zero. This is used for simpler
731 * apm_driver_version - APM driver version
738 * On entry val should point to a value indicating the APM driver
758 * apm_get_event - get an APM event from the BIOS
759 * @event: pointer to the event
760 * @info: point to the event information
763 * reporting. The BIOS expects to be polled at least every second
766 * problems on some laptops where a suspend event notification is
792 * set_power_state - set the power management state
793 * @what: which items to transition
794 * @state: state to transition to
799 * all) for the object to be transitioned.
801 * The state holds the state to transition to, which may in fact
816 * set_system_power_state - set system wide power state
817 * @state: which state to enter
828 * apm_do_idle - perform power saving
831 * of the OS) idle. It returns -1 in the event that the BIOS refuses
832 * to handle the idle request. On a success the function returns 1
861 return -1; in apm_do_idle()
868 * apm_do_busy - inform the BIOS the CPU is busy
870 * Request that the BIOS brings the CPU back to full performance.
886 * the CPU for some time, we want to call BIOS
887 * power management - we probably want
888 * to conserve power.
894 * apm_cpu_idle - cpu idling for APM capable Linux
897 * tries to do BIOS powermanagement based on the average system idle time.
898 * Furthermore it calls the system default idle routine.
910 unsigned int jiffies_since_last_check = jiffies - last_jiffies; in apm_cpu_idle()
920 idle_percentage = nsecs_to_jiffies(stime - last_stime); in apm_cpu_idle()
947 bucket--; in apm_cpu_idle()
960 jiffies_since_last_check = jiffies - last_jiffies; in apm_cpu_idle()
972 * apm_power_off - ask the BIOS to power off
975 * will execute even on SMP machines. In order to deal with BIOS
995 * apm_enable_power_management - enable BIOS APM power management
1020 * apm_get_power_status - get current power state
1059 * apm_engage_power_management - enable PM on a device
1090 * apm_console_blank - blank the display
1093 * Attempt to blank the console, firstly by blanking just video device
1138 return as->event_head == as->event_tail; in queue_empty()
1143 if (++as->event_tail >= APM_MAX_EVENTS) in get_queued_event()
1144 as->event_tail = 0; in get_queued_event()
1145 return as->events[as->event_tail]; in get_queued_event()
1155 for (as = user_list; as != NULL; as = as->next) { in queue_event()
1156 if ((as == sender) || (!as->reader)) in queue_event()
1158 if (++as->event_head >= APM_MAX_EVENTS) in queue_event()
1159 as->event_head = 0; in queue_event()
1161 if (as->event_head == as->event_tail) { in queue_event()
1166 if (++as->event_tail >= APM_MAX_EVENTS) in queue_event()
1167 as->event_tail = 0; in queue_event()
1169 as->events[as->event_head] = event; in queue_event()
1170 if (!as->suser || !as->writer) in queue_event()
1175 as->suspends_pending++; in queue_event()
1181 as->standbys_pending++; in queue_event()
1197 /* set the clock to HZ */ in reinit_timer()
1208 static int suspend(int vetoable) in suspend() function
1232 apm_error("suspend", err); in suspend()
1233 err = (err == APM_SUCCESS) ? 0 : -EIO; in suspend()
1243 for (as = user_list; as != NULL; as = as->next) { in suspend()
1244 as->suspend_wait = 0; in suspend()
1245 as->suspend_result = err; in suspend()
1302 apm_event_name[event - 1]); in check_events()
1332 * If we are already processing a SUSPEND, in check_events()
1333 * then further SUSPEND events from the BIOS in check_events()
1334 * will be ignored. We also return here to in check_events()
1336 * sending a SUSPEND event until something else in check_events()
1344 (void) suspend(1); in check_events()
1373 * We are not allowed to reject a critical suspend. in check_events()
1375 (void)suspend(0); in check_events()
1388 (pending_count-- <= 0)) { in apm_event_handler()
1416 * Ok, check all events, check for idle (and mark us sleeping in apm_mainloop()
1417 * so as not to count towards the load average).. in apm_mainloop()
1427 if (as == NULL || as->magic != APM_BIOS_MAGIC) { in check_apm_user()
1440 as = fp->private_data; in do_read()
1442 return -EIO; in do_read()
1444 return -EINVAL; in do_read()
1445 if ((queue_empty(as)) && (fp->f_flags & O_NONBLOCK)) in do_read()
1446 return -EAGAIN; in do_read()
1454 return -EFAULT; in do_read()
1459 as->suspends_read++; in do_read()
1464 as->standbys_read++; in do_read()
1468 i -= sizeof(event); in do_read()
1471 return count - i; in do_read()
1473 return -ERESTARTSYS; in do_read()
1481 as = fp->private_data; in do_poll()
1495 as = filp->private_data; in do_ioctl()
1497 return -EIO; in do_ioctl()
1498 if (!as->suser || !as->writer) in do_ioctl()
1499 return -EPERM; in do_ioctl()
1503 if (as->standbys_read > 0) { in do_ioctl()
1504 as->standbys_read--; in do_ioctl()
1505 as->standbys_pending--; in do_ioctl()
1506 standbys_pending--; in do_ioctl()
1515 if (as->suspends_read > 0) { in do_ioctl()
1516 as->suspends_read--; in do_ioctl()
1517 as->suspends_pending--; in do_ioctl()
1518 suspends_pending--; in do_ioctl()
1522 ret = suspend(1); in do_ioctl()
1525 as->suspend_wait = 1; in do_ioctl()
1528 as->suspend_wait == 0); in do_ioctl()
1529 ret = as->suspend_result; in do_ioctl()
1533 return -ENOTTY; in do_ioctl()
1542 as = filp->private_data; in do_release()
1545 filp->private_data = NULL; in do_release()
1546 if (as->standbys_pending > 0) { in do_release()
1547 standbys_pending -= as->standbys_pending; in do_release()
1551 if (as->suspends_pending > 0) { in do_release()
1552 suspends_pending -= as->suspends_pending; in do_release()
1554 (void) suspend(1); in do_release()
1558 user_list = as->next; in do_release()
1563 (as1 != NULL) && (as1->next != as); in do_release()
1564 as1 = as1->next) in do_release()
1569 as1->next = as->next; in do_release()
1582 return -ENOMEM; in do_open()
1584 as->magic = APM_BIOS_MAGIC; in do_open()
1585 as->event_tail = as->event_head = 0; in do_open()
1586 as->suspends_pending = as->standbys_pending = 0; in do_open()
1587 as->suspends_read = as->standbys_read = 0; in do_open()
1589 * XXX - this is a tiny bit broken, when we consider BSD in do_open()
1593 * privileged operation -- cevans in do_open()
1595 as->suser = capable(CAP_SYS_ADMIN); in do_open()
1596 as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; in do_open()
1597 as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; in do_open()
1599 as->next = user_list; in do_open()
1602 filp->private_data = as; in do_open()
1616 int percentage = -1; in proc_apm_show()
1617 int time_units = -1; in proc_apm_show()
1647 0x00: Off-line in proc_apm_show()
1648 0x01: On-line in proc_apm_show()
1666 0-100: valid in proc_apm_show()
1667 -1: Unknown in proc_apm_show()
1670 -1: Unknown in proc_apm_show()
1697 /* 2002/08/01 - WT in apm()
1698 * This is to avoid random crashes at boot time during initialization in apm()
1699 * on SMP systems in case of "apm=power-off" mode. Seen on ASUS A7M266D. in apm()
1710 * We only support BIOSs up to version 1.2 in apm()
1717 /* Fall back to an APM 1.0 connection. */ in apm()
1731 * This call causes my NEC UltraLite Versa 33/C to hang if it in apm()
1738 return -1; in apm()
1748 return -1; in apm()
1836 if ((strncmp(str, "bounce-interval=", 16) == 0) || in apm_setup()
1839 if ((strncmp(str, "idle-threshold=", 15) == 0) || in apm_setup()
1842 if ((strncmp(str, "idle-period=", 12) == 0) || in apm_setup()
1845 invert = (strncmp(str, "no-", 3) == 0) || in apm_setup()
1851 if ((strncmp(str, "power-off", 9) == 0) || in apm_setup()
1858 if ((strncmp(str, "allow-ints", 10) == 0) || in apm_setup()
1861 if ((strncmp(str, "broken-psr", 10) == 0) || in apm_setup()
1864 if ((strncmp(str, "realmode-power-off", 18) == 0) || in apm_setup()
1897 printk("%s\n", d->ident); in print_if_true()
1903 * disabled before the suspend. Linux used to get terribly confused by that.
1908 "workaround hopefully not needed.\n", d->ident); in broken_ps2_resume()
1912 /* Some bioses have a broken protected mode poweroff and need to use realmode */
1918 "Using realmode poweroff only.\n", d->ident); in set_realmode_power_off()
1923 /* Some laptops require interrupts to be enabled during APM calls */
1929 "Enabling interrupts during APM calls.\n", d->ident); in set_apm_ints()
1940 "Disabling APM.\n", d->ident); in apm_is_horked()
1950 "Disabling APM.\n", d->ident); in apm_is_horked_d850md()
1957 /* Some APM bioses hang on APM idle calls */
1963 "Disabling APM idle calls.\n", d->ident); in apm_likes_to_melt()
1972 * [ Write BIOS Code ]<------
1974 * < Does it Compile >----N--
1976 * < Does it Boot Win98 >-N--
2006 KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
2015 { /* Allow interrupts during suspend on Dell Latitude laptops*/
2027 { /* Allow interrupts during suspend on Dell Inspiron laptops*/
2047 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
2051 { /* Allow interrupts during suspend on Compaq Laptops*/
2064 apm_is_horked, "ABIT KX7-333[R]",
2066 DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
2074 apm_is_horked, "Fujitsu-Siemens",
2089 apm_is_horked, "Dell XPS-Z",
2092 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
2095 apm_is_horked, "Sharp PC-PJ/AX",
2097 DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
2108 { /* APM idle hangs */
2113 { /* APM idle hangs */
2118 { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
2124 { /* Handle problems with APM on Sony Vaio PCG-N505VX */
2130 { /* Handle problems with APM on Sony Vaio PCG-XG29 */
2136 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
2142 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
2148 { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
2154 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
2160 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
2166 { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
2172 { /* Handle problems with APM on Sony Vaio PCG-F104K */
2179 { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
2185 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
2191 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
2206 { /* Allow interrupts during suspend on IBM laptops */
2215 * Just start the APM thread. We do NOT want to do APM BIOS
2218 * most common APM BIOS problems that lead to protection errors
2233 return -ENODEV; in apm_init()
2243 return -ENODEV; in apm_init()
2252 /* User can override, but default is to trust DMI */ in apm_init()
2253 if (apm_disabled != -1) in apm_init()
2282 return -ENODEV; in apm_init()
2285 pr_notice("disabled - APM is not SMP safe.\n"); in apm_init()
2287 return -ENODEV; in apm_init()
2292 return -ENODEV; in apm_init()
2296 * Set up the long jump entry point to the APM BIOS, which is called in apm_init()
2303 * The APM 1.1 BIOS is supposed to provide limit information that it in apm_init()
2305 * not restrict themselves to their claimed limit. When this happens, in apm_init()
2310 * code to that CPU. in apm_init()
2324 pr_err("disabled - Unable to start kernel thread\n"); in apm_init()
2334 "apm: disabled - APM is not SMP safe (power off active).\n"); in apm_init()
2393 "Set the number of ticks to ignore suspend bounces");
2400 "Switch to real mode before powering off");
2403 "System idle percentage above which to make APM BIOS idle calls");
2406 "Period (in sec/100) over which to calculate the idle percentage");
2409 "Set this to enable APM use on an SMP platform. Use with caution on older systems");