Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
3f86b83
Documentation
arch
block
crypto
drivers
acorn
acpi
dispatcher
events
executer
hardware
namespace
parser
resources
sleep
tables
utilities
Kconfig
Makefile
ac.c
acpi_memhotplug.c
asus_acpi.c
battery.c
blacklist.c
bus.c
button.c
cm_sbs.c
container.c
debug.c
dock.c
ec.c
event.c
fan.c
glue.c
hotkey.c
i2c_ec.c
i2c_ec.h
ibm_acpi.c
motherboard.c
numa.c
osl.c
pci_bind.c
pci_irq.c
pci_link.c
pci_root.c
power.c
processor_core.c
processor_idle.c
processor_perflib.c
processor_thermal.c
processor_throttling.c
sbs.c
scan.c
system.c
tables.c
thermal.c
toshiba_acpi.c
utils.c
video.c
amba
atm
base
block
bluetooth
cdrom
char
clocksource
connector
cpufreq
crypto
dio
dma
edac
eisa
fc4
firmware
hwmon
i2c
ide
ieee1394
infiniband
input
isdn
leds
macintosh
mca
md
media
message
mfd
misc
mmc
mtd
net
nubus
oprofile
parisc
parport
pci
pcmcia
pnp
rapidio
rtc
s390
sbus
scsi
serial
sh
sn
spi
tc
telephony
usb
video
w1
zorro
Kconfig
Makefile
fs
include
init
ipc
kernel
lib
mm
net
scripts
security
sound
usr
.gitignore
COPYING
CREDITS
Kbuild
MAINTAINERS
Makefile
README
REPORTING-BUGS
Breadcrumbs
linux
/
drivers
/
acpi
/
ac.c
Blame
Blame
Latest commit
History
History
311 lines (243 loc) · 7.27 KB
Breadcrumbs
linux
/
drivers
/
acpi
/
ac.c
Top
File metadata and controls
Code
Blame
311 lines (243 loc) · 7.27 KB
Raw
/* * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 27 $) * * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> #define ACPI_AC_COMPONENT 0x00020000 #define ACPI_AC_CLASS "ac_adapter" #define ACPI_AC_HID "ACPI0003" #define ACPI_AC_DRIVER_NAME "ACPI AC Adapter Driver" #define ACPI_AC_DEVICE_NAME "AC Adapter" #define ACPI_AC_FILE_STATE "state" #define ACPI_AC_NOTIFY_STATUS 0x80 #define ACPI_AC_STATUS_OFFLINE 0x00 #define ACPI_AC_STATUS_ONLINE 0x01 #define ACPI_AC_STATUS_UNKNOWN 0xFF #define _COMPONENT ACPI_AC_COMPONENT ACPI_MODULE_NAME("acpi_ac") MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); MODULE_LICENSE("GPL"); extern struct proc_dir_entry *acpi_lock_ac_dir(void); extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); static int acpi_ac_add(struct acpi_device *device); static int acpi_ac_remove(struct acpi_device *device, int type); static int acpi_ac_open_fs(struct inode *inode, struct file *file); static struct acpi_driver acpi_ac_driver = { .name = ACPI_AC_DRIVER_NAME, .class = ACPI_AC_CLASS, .ids = ACPI_AC_HID, .ops = { .add = acpi_ac_add, .remove = acpi_ac_remove, }, }; struct acpi_ac { struct acpi_device * device; unsigned long state; }; static struct file_operations acpi_ac_fops = { .open = acpi_ac_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; /* -------------------------------------------------------------------------- AC Adapter Management -------------------------------------------------------------------------- */ static int acpi_ac_get_state(struct acpi_ac *ac) { acpi_status status = AE_OK; if (!ac) return -EINVAL; status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); ac->state = ACPI_AC_STATUS_UNKNOWN; return -ENODEV; } return 0; } /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ static struct proc_dir_entry *acpi_ac_dir; static int acpi_ac_seq_show(struct seq_file *seq, void *offset) { struct acpi_ac *ac = (struct acpi_ac *)seq->private; if (!ac) return 0; if (acpi_ac_get_state(ac)) { seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); return 0; } seq_puts(seq, "state: "); switch (ac->state) { case ACPI_AC_STATUS_OFFLINE: seq_puts(seq, "off-line\n"); break; case ACPI_AC_STATUS_ONLINE: seq_puts(seq, "on-line\n"); break; default: seq_puts(seq, "unknown\n"); break; } return 0; } static int acpi_ac_open_fs(struct inode *inode, struct file *file) { return single_open(file, acpi_ac_seq_show, PDE(inode)->data); } static int acpi_ac_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_ac_dir); if (!acpi_device_dir(device)) return -ENODEV; acpi_device_dir(device)->owner = THIS_MODULE; } /* 'state' [R] */ entry = create_proc_entry(ACPI_AC_FILE_STATE, S_IRUGO, acpi_device_dir(device)); if (!entry) return -ENODEV; else { entry->proc_fops = &acpi_ac_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; } return 0; } static int acpi_ac_remove_fs(struct acpi_device *device) { if (acpi_device_dir(device)) { remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device)); remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); acpi_device_dir(device) = NULL; } return 0; } /* -------------------------------------------------------------------------- Driver Model -------------------------------------------------------------------------- */ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) { struct acpi_ac *ac = (struct acpi_ac *)data; struct acpi_device *device = NULL; if (!ac) return; device = ac->device; switch (event) { case ACPI_AC_NOTIFY_STATUS: acpi_ac_get_state(ac); acpi_bus_generate_event(device, event, (u32) ac->state); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } return; } static int acpi_ac_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; struct acpi_ac *ac = NULL; if (!device) return -EINVAL; ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL); if (!ac) return -ENOMEM; memset(ac, 0, sizeof(struct acpi_ac)); ac->device = device; strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_AC_CLASS); acpi_driver_data(device) = ac; result = acpi_ac_get_state(ac); if (result) goto end; result = acpi_ac_add_fs(device); if (result) goto end; status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_ac_notify, ac); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), ac->state ? "on-line" : "off-line"); end: if (result) { acpi_ac_remove_fs(device); kfree(ac); } return result; } static int acpi_ac_remove(struct acpi_device *device, int type) { acpi_status status = AE_OK; struct acpi_ac *ac = NULL; if (!device || !acpi_driver_data(device)) return -EINVAL; ac = (struct acpi_ac *)acpi_driver_data(device); status = acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_ac_notify); acpi_ac_remove_fs(device); kfree(ac); return 0; } static int __init acpi_ac_init(void) { int result; acpi_ac_dir = acpi_lock_ac_dir(); if (!acpi_ac_dir) return -ENODEV; result = acpi_bus_register_driver(&acpi_ac_driver); if (result < 0) { acpi_unlock_ac_dir(acpi_ac_dir); return -ENODEV; } return 0; } static void __exit acpi_ac_exit(void) { acpi_bus_unregister_driver(&acpi_ac_driver); acpi_unlock_ac_dir(acpi_ac_dir); return; } module_init(acpi_ac_init); module_exit(acpi_ac_exit);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
You can’t perform that action at this time.