ac.c revision 4d8316d5ea4dcf0bf15d8a06d539ed7c99e9cfbe
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * acpi_ac.c - ACPI AC Adapter Driver ($Revision: 27 $) 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or (at 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * your option) any later version. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, but 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WITHOUT ANY WARRANTY; without even the implied warranty of 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * General Public License for more details. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License along 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with this program; if not, write to the Free Software Foundation, Inc., 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/proc_fs.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/seq_file.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi_bus.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi_drivers.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_COMPONENT 0x00020000 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_CLASS "ac_adapter" 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_HID "ACPI0003" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_DRIVER_NAME "ACPI AC Adapter Driver" 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_DEVICE_NAME "AC Adapter" 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_FILE_STATE "state" 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_NOTIFY_STATUS 0x80 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_STATUS_OFFLINE 0x00 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_STATUS_ONLINE 0x01 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_STATUS_UNKNOWN 0xFF 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT ACPI_AC_COMPONENT 474be44fcd3bf648b782f4460fd06dfae6c42ded4bLen BrownACPI_MODULE_NAME("acpi_ac") 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 494be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown MODULE_AUTHOR("Paul Diefenbaugh"); 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 533f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsendextern struct proc_dir_entry *acpi_lock_ac_dir(void); 543f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsendextern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); 553f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend 564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_add(struct acpi_device *device); 574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_remove(struct acpi_device *device, int type); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int acpi_ac_open_fs(struct inode *inode, struct file *file); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct acpi_driver acpi_ac_driver = { 614be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .name = ACPI_AC_DRIVER_NAME, 624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .class = ACPI_AC_CLASS, 634be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .ids = ACPI_AC_HID, 644be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .ops = { 654be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .add = acpi_ac_add, 664be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .remove = acpi_ac_remove, 674be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown }, 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct acpi_ac { 71af96179a8298832cc58be212d0e4988d8a1e11bfPatrick Mochel struct acpi_device * device; 724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown unsigned long state; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 75d75080328affb4b268da430b7074cc8139cc662aArjan van de Venstatic const struct file_operations acpi_ac_fops = { 764be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .open = acpi_ac_open_fs, 774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .read = seq_read, 784be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .llseek = seq_lseek, 794be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .release = single_release, 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* -------------------------------------------------------------------------- 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AC Adapter Management 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -------------------------------------------------------------------------- */ 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 864be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_get_state(struct acpi_ac *ac) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status = AE_OK; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 92d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EINVAL; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 94a6ba5ebef91a59fabd45962e576c02468dbcd33fPatrick Mochel status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE(status)) { 96a6fc67202e0224e6c9d1d285cc0b444bce887ed5Thomas Renninger ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ac->state = ACPI_AC_STATUS_UNKNOWN; 98d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1004be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 101d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* -------------------------------------------------------------------------- 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FS Interface (/proc) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -------------------------------------------------------------------------- */ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic struct proc_dir_entry *acpi_ac_dir; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int acpi_ac_seq_show(struct seq_file *seq, void *offset) 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_ac *ac = (struct acpi_ac *)seq->private; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 116d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_ac_get_state(ac)) { 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); 120d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "state: "); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (ac->state) { 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_AC_STATUS_OFFLINE: 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "off-line\n"); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_AC_STATUS_ONLINE: 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "on-line\n"); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "unknown\n"); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 136d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1384be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int acpi_ac_open_fs(struct inode *inode, struct file *file) 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return single_open(file, acpi_ac_seq_show, PDE(inode)->data); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_add_fs(struct acpi_device *device) 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1464be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct proc_dir_entry *entry = NULL; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!acpi_device_dir(device)) { 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1514be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_ac_dir); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!acpi_device_dir(device)) 153d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_device_dir(device)->owner = THIS_MODULE; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 'state' [R] */ 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry = create_proc_entry(ACPI_AC_FILE_STATE, 1594be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown S_IRUGO, acpi_device_dir(device)); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!entry) 161d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry->proc_fops = &acpi_ac_fops; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry->data = acpi_driver_data(device); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry->owner = THIS_MODULE; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 168d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1714be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_remove_fs(struct acpi_device *device) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_device_dir(device)) { 1754be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device)); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_device_dir(device) = NULL; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* -------------------------------------------------------------------------- 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Driver Model 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -------------------------------------------------------------------------- */ 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1884be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic void acpi_ac_notify(acpi_handle handle, u32 event, void *data) 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1904be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_ac *ac = (struct acpi_ac *)data; 1914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_device *device = NULL; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 195d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 197af96179a8298832cc58be212d0e4988d8a1e11bfPatrick Mochel device = ac->device; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (event) { 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_AC_NOTIFY_STATUS: 20003d782524e2d0511317769521c8d5daadbab8482Christian Lupien case ACPI_NOTIFY_BUS_CHECK: 20103d782524e2d0511317769521c8d5daadbab8482Christian Lupien case ACPI_NOTIFY_DEVICE_CHECK: 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ac_get_state(ac); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_bus_generate_event(device, event, (u32) ac->state); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ACPI_DEBUG_PRINT((ACPI_DB_INFO, 2074be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown "Unsupported event [0x%x]\n", event)); 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2144be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_add(struct acpi_device *device) 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2164be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown int result = 0; 2174be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status = AE_OK; 2184be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_ac *ac = NULL; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!device) 222d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EINVAL; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ac = kmalloc(sizeof(struct acpi_ac), GFP_KERNEL); 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 226d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENOMEM; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(ac, 0, sizeof(struct acpi_ac)); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 229af96179a8298832cc58be212d0e4988d8a1e11bfPatrick Mochel ac->device = device; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(acpi_device_class(device), ACPI_AC_CLASS); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_driver_data(device) = ac; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_ac_get_state(ac); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto end; 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_ac_add_fs(device); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto end; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 242a6ba5ebef91a59fabd45962e576c02468dbcd33fPatrick Mochel status = acpi_install_notify_handler(device->handle, 24303d782524e2d0511317769521c8d5daadbab8482Christian Lupien ACPI_ALL_NOTIFY, acpi_ac_notify, 2444be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown ac); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE(status)) { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -ENODEV; 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto end; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2504be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 2514be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_device_name(device), acpi_device_bid(device), 2524be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown ac->state ? "on-line" : "off-line"); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown end: 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ac_remove_fs(device); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ac); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 260d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return result; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2634be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_remove(struct acpi_device *device, int type) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2654be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status = AE_OK; 2664be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_ac *ac = NULL; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!device || !acpi_driver_data(device)) 270d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EINVAL; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2724be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown ac = (struct acpi_ac *)acpi_driver_data(device); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 274a6ba5ebef91a59fabd45962e576c02468dbcd33fPatrick Mochel status = acpi_remove_notify_handler(device->handle, 27503d782524e2d0511317769521c8d5daadbab8482Christian Lupien ACPI_ALL_NOTIFY, acpi_ac_notify); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ac_remove_fs(device); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ac); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2844be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int __init acpi_ac_init(void) 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2863f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend int result; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2884d8316d5ea4dcf0bf15d8a06d539ed7c99e9cfbePavel Machek if (acpi_disabled) 2894d8316d5ea4dcf0bf15d8a06d539ed7c99e9cfbePavel Machek return -ENODEV; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2913f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend acpi_ac_dir = acpi_lock_ac_dir(); 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!acpi_ac_dir) 293d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_bus_register_driver(&acpi_ac_driver); 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result < 0) { 2973f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend acpi_unlock_ac_dir(acpi_ac_dir); 298d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3044be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic void __exit acpi_ac_exit(void) 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_bus_unregister_driver(&acpi_ac_driver); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3093f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend acpi_unlock_ac_dir(acpi_ac_dir); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(acpi_ac_init); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(acpi_ac_exit); 316