Lines Matching +full:power +full:- +full:off +full:- +full:time +full:- +full:sec
1 // SPDX-License-Identifier: GPL-2.0-only
3 * bios-less APM driver for ARM Linux
8 * Intel Corporation, Microsoft Corporation. Advanced Power Management
25 #include <linux/apm-emulation.h>
36 * One option can be changed at boot time as follows:
37 * apm=on/off enable/disable APM
66 * NONE -1-> PENDING -2-> READ -3-> ACKED -4-> DONE -5-> NONE
67 * -6-> ACKTO -7-> NONE
68 * NONE -8-> WAIT -9-> NONE
101 * The per-file APM data
135 * "APM" events within - specifically necessary if we're going
154 * This allows machines to provide their own "apm get power status" function.
165 return q->event_head == q->event_tail; in queue_empty()
170 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; in queue_get_event()
171 return q->events[q->event_tail]; in queue_get_event()
176 q->event_head = (q->event_head + 1) % APM_MAX_EVENTS; in queue_add_event()
177 if (q->event_head == q->event_tail) { in queue_add_event()
182 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; in queue_add_event()
184 q->events[q->event_head] = event; in queue_add_event()
193 if (as->reader) in queue_event()
194 queue_add_event(&as->queue, event); in queue_event()
202 struct apm_user *as = fp->private_data; in apm_read()
207 return -EINVAL; in apm_read()
209 if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK) in apm_read()
210 return -EAGAIN; in apm_read()
212 wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue)); in apm_read()
214 while ((i >= sizeof(event)) && !queue_empty(&as->queue)) { in apm_read()
215 event = queue_get_event(&as->queue); in apm_read()
217 ret = -EFAULT; in apm_read()
222 if (as->suspend_state == SUSPEND_PENDING && in apm_read()
224 as->suspend_state = SUSPEND_READ; in apm_read()
228 i -= sizeof(event); in apm_read()
232 ret = count - i; in apm_read()
239 struct apm_user *as = fp->private_data; in apm_poll()
242 return queue_empty(&as->queue) ? 0 : EPOLLIN | EPOLLRDNORM; in apm_poll()
246 * apm_ioctl - handle APM ioctl
250 * - initiate a suspend
251 * - acknowledge a suspend read from /dev/apm_bios.
258 struct apm_user *as = filp->private_data; in apm_ioctl()
259 int err = -EINVAL; in apm_ioctl()
261 if (!as->suser || !as->writer) in apm_ioctl()
262 return -EPERM; in apm_ioctl()
268 as->suspend_result = -EINTR; in apm_ioctl()
270 switch (as->suspend_state) { in apm_ioctl()
277 as->suspend_state = SUSPEND_ACKED; in apm_ioctl()
295 as->suspend_state != SUSPEND_ACKED)) in apm_ioctl()
299 as->suspend_result = -ETIMEDOUT; in apm_ioctl()
303 as->suspend_state = SUSPEND_WAIT; in apm_ioctl()
311 as->suspend_result = pm_suspend(PM_SUSPEND_MEM); in apm_ioctl()
315 err = as->suspend_result; in apm_ioctl()
316 as->suspend_state = SUSPEND_NONE; in apm_ioctl()
326 struct apm_user *as = filp->private_data; in apm_release()
328 filp->private_data = NULL; in apm_release()
331 list_del(&as->list); in apm_release()
339 if (as->suspend_state == SUSPEND_PENDING || in apm_release()
340 as->suspend_state == SUSPEND_READ) in apm_release()
357 * XXX - this is a tiny bit broken, when we consider BSD in apm_open()
361 * privileged operation -- cevans in apm_open()
363 as->suser = capable(CAP_SYS_ADMIN); in apm_open()
364 as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; in apm_open()
365 as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; in apm_open()
368 list_add(&as->list, &apm_user_list); in apm_open()
371 filp->private_data = as; in apm_open()
374 return as ? 0 : -ENOMEM; in apm_open()
407 * 0x00: Off-line
408 * 0x01: On-line
409 * 0x02: On backup power (BIOS >= 1.1 only)
426 * 0-100: valid
427 * -1: Unknown
428 * 7) Remaining battery life (time units):
430 * -1: Unknown
431 * 8) min = minutes; sec = seconds
443 info.battery_life = -1; in proc_apm_show()
444 info.time = -1; in proc_apm_show()
445 info.units = -1; in proc_apm_show()
453 case 1: units = "sec"; break; in proc_apm_show()
460 info.time, units); in proc_apm_show()
516 /* short-cut emergency suspends */ in apm_suspend_notifier()
533 if (as->suspend_state != SUSPEND_WAIT && as->reader && in apm_suspend_notifier()
534 as->writer && as->suser) { in apm_suspend_notifier()
535 as->suspend_state = SUSPEND_PENDING; in apm_suspend_notifier()
537 queue_add_event(&as->queue, apm_event); in apm_suspend_notifier()
563 * We could time out and the userspace does the ACK in apm_suspend_notifier()
564 * right after we time out but before we enter the in apm_suspend_notifier()
570 if (as->suspend_state == SUSPEND_PENDING || in apm_suspend_notifier()
571 as->suspend_state == SUSPEND_READ) { in apm_suspend_notifier()
572 as->suspend_state = SUSPEND_ACKTO; in apm_suspend_notifier()
603 if (as->suspend_state == SUSPEND_ACKED) { in apm_suspend_notifier()
610 as->suspend_result = 0; in apm_suspend_notifier()
611 as->suspend_state = SUSPEND_DONE; in apm_suspend_notifier()
635 return -ENODEV; in apm_init()
682 MODULE_DESCRIPTION("Advanced Power Management");
689 if (strncmp(str, "off", 3) == 0) in apm_setup()
704 * apm_queue_event - queue an APM event for kapmd