ac.c revision 48fe112744d1ff2e899a6491633ac58a3229aabf
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> 30fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/proc_fs.h> 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/seq_file.h> 338a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 3497749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 35d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy#include <linux/power_supply.h> 3697749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi_bus.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <acpi/acpi_drivers.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_CLASS "ac_adapter" 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_DEVICE_NAME "AC Adapter" 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_FILE_STATE "state" 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_NOTIFY_STATUS 0x80 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_STATUS_OFFLINE 0x00 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_STATUS_ONLINE 0x01 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ACPI_AC_STATUS_UNKNOWN 0xFF 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _COMPONENT ACPI_AC_COMPONENT 49f52fd66d2ea794010c2d7536cf8e6abed0ac4947Len BrownACPI_MODULE_NAME("ac"); 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51f52fd66d2ea794010c2d7536cf8e6abed0ac4947Len BrownMODULE_AUTHOR("Paul Diefenbaugh"); 527cda93e008e1a477970adbf82dba81a5d4f0ae40Len BrownMODULE_DESCRIPTION("ACPI AC Adapter Driver"); 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 563f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsendextern struct proc_dir_entry *acpi_lock_ac_dir(void); 573f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsendextern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); 588a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkovstatic int acpi_ac_open_fs(struct inode *inode, struct file *file); 598a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 603f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend 614be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_add(struct acpi_device *device); 624be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_remove(struct acpi_device *device, int type); 635bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiystatic int acpi_ac_resume(struct acpi_device *device); 6448fe112744d1ff2e899a6491633ac58a3229aabfBjorn Helgaasstatic void acpi_ac_notify(struct acpi_device *device, u32 event); 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 66b299c22c8c1024a5a89d19524e24b3e1d67e9eabTobias Klauserstatic const struct acpi_device_id ac_device_ids[] = { 671ba90e3a87c46500623afdc3898573e4a5ebb21bThomas Renninger {"ACPI0003", 0}, 681ba90e3a87c46500623afdc3898573e4a5ebb21bThomas Renninger {"", 0}, 691ba90e3a87c46500623afdc3898573e4a5ebb21bThomas Renninger}; 701ba90e3a87c46500623afdc3898573e4a5ebb21bThomas RenningerMODULE_DEVICE_TABLE(acpi, ac_device_ids); 711ba90e3a87c46500623afdc3898573e4a5ebb21bThomas Renninger 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct acpi_driver acpi_ac_driver = { 73c2b6705b75d9c7aff98a4602a32230639e10891cLen Brown .name = "ac", 744be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .class = ACPI_AC_CLASS, 751ba90e3a87c46500623afdc3898573e4a5ebb21bThomas Renninger .ids = ac_device_ids, 7648fe112744d1ff2e899a6491633ac58a3229aabfBjorn Helgaas .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, 774be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .ops = { 784be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .add = acpi_ac_add, 794be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .remove = acpi_ac_remove, 805bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy .resume = acpi_ac_resume, 8148fe112744d1ff2e899a6491633ac58a3229aabfBjorn Helgaas .notify = acpi_ac_notify, 824be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown }, 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct acpi_ac { 8697749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 87d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy struct power_supply charger; 8897749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 89af96179a8298832cc58be212d0e4988d8a1e11bfPatrick Mochel struct acpi_device * device; 9027663c5855b10af9ec67bc7dfba001426ba21222Matthew Wilcox unsigned long long state; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 93d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); 94d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy 95fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 96d75080328affb4b268da430b7074cc8139cc662aArjan van de Venstatic const struct file_operations acpi_ac_fops = { 97cf7acfab032ff262f42954328cdfd20a5d9aaaacDenis V. Lunev .owner = THIS_MODULE, 984be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .open = acpi_ac_open_fs, 994be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .read = seq_read, 1004be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .llseek = seq_lseek, 1014be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown .release = single_release, 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1038a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 10497749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 105d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiystatic int get_ac_property(struct power_supply *psy, 106d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy enum power_supply_property psp, 107d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy union power_supply_propval *val) 108d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy{ 109d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy struct acpi_ac *ac = to_acpi_ac(psy); 110d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy switch (psp) { 111d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy case POWER_SUPPLY_PROP_ONLINE: 112d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy val->intval = ac->state; 113d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy break; 114d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy default: 115d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy return -EINVAL; 116d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy } 117d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy return 0; 118d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy} 119d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy 120d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiystatic enum power_supply_property ac_props[] = { 121d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy POWER_SUPPLY_PROP_ONLINE, 122d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy}; 12397749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* -------------------------------------------------------------------------- 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AC Adapter Management 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -------------------------------------------------------------------------- */ 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1284be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_get_state(struct acpi_ac *ac) 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1304be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_status status = AE_OK; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 134d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EINVAL; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 136a6ba5ebef91a59fabd45962e576c02468dbcd33fPatrick Mochel status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ACPI_FAILURE(status)) { 138a6fc67202e0224e6c9d1d285cc0b444bce887ed5Thomas Renninger ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ac->state = ACPI_AC_STATUS_UNKNOWN; 140d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1424be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 143d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 146fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* -------------------------------------------------------------------------- 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FS Interface (/proc) 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -------------------------------------------------------------------------- */ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1514be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic struct proc_dir_entry *acpi_ac_dir; 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int acpi_ac_seq_show(struct seq_file *seq, void *offset) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15550dd096973f1d95aa03c6a6d9e148d706b62b68eJan Engelhardt struct acpi_ac *ac = seq->private; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 159d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_ac_get_state(ac)) { 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); 163d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "state: "); 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (ac->state) { 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_AC_STATUS_OFFLINE: 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "off-line\n"); 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_AC_STATUS_ONLINE: 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "on-line\n"); 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds seq_puts(seq, "unknown\n"); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 179d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1814be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int acpi_ac_open_fs(struct inode *inode, struct file *file) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return single_open(file, acpi_ac_seq_show, PDE(inode)->data); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1874be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_add_fs(struct acpi_device *device) 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1894be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct proc_dir_entry *entry = NULL; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!acpi_device_dir(device)) { 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1944be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_ac_dir); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!acpi_device_dir(device)) 196d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 'state' [R] */ 200cf7acfab032ff262f42954328cdfd20a5d9aaaacDenis V. Lunev entry = proc_create_data(ACPI_AC_FILE_STATE, 201cf7acfab032ff262f42954328cdfd20a5d9aaaacDenis V. Lunev S_IRUGO, acpi_device_dir(device), 202cf7acfab032ff262f42954328cdfd20a5d9aaaacDenis V. Lunev &acpi_ac_fops, acpi_driver_data(device)); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!entry) 204d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 205d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2084be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_remove_fs(struct acpi_device *device) 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (acpi_device_dir(device)) { 2124be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device)); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_device_dir(device) = NULL; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 218d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2208a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* -------------------------------------------------------------------------- 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Driver Model 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds -------------------------------------------------------------------------- */ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22648fe112744d1ff2e899a6491633ac58a3229aabfBjorn Helgaasstatic void acpi_ac_notify(struct acpi_device *device, u32 event) 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 22848fe112744d1ff2e899a6491633ac58a3229aabfBjorn Helgaas struct acpi_ac *ac = acpi_driver_data(device); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 232d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (event) { 235f163ff5176a8e9c827d8ebe044710d67d40799c3Len Brown default: 236f163ff5176a8e9c827d8ebe044710d67d40799c3Len Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO, 237f163ff5176a8e9c827d8ebe044710d67d40799c3Len Brown "Unsupported event [0x%x]\n", event)); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ACPI_AC_NOTIFY_STATUS: 23903d782524e2d0511317769521c8d5daadbab8482Christian Lupien case ACPI_NOTIFY_BUS_CHECK: 24003d782524e2d0511317769521c8d5daadbab8482Christian Lupien case ACPI_NOTIFY_DEVICE_CHECK: 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ac_get_state(ac); 24214e04fb34ffa82ee61ae69f98d8fca12d2e8e31cLen Brown acpi_bus_generate_proc_event(device, event, (u32) ac->state); 243962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui acpi_bus_generate_netlink_event(device->pnp.device_class, 2440794469da3f7b2093575cbdfc1108308dd3641ceKay Sievers dev_name(&device->dev), event, 245962ce8ca0604af0c3c5609f7613d4ec5fcfac623Zhang Rui (u32) ac->state); 24697749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 247d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 24897749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2544be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_add(struct acpi_device *device) 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2564be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown int result = 0; 2574be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_ac *ac = NULL; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!device) 261d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EINVAL; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26336bcbec7ce21e2e8b3143b11a05747330abeca70Burman Yan ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ac) 265d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENOMEM; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 267af96179a8298832cc58be212d0e4988d8a1e11bfPatrick Mochel ac->device = device; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(acpi_device_class(device), ACPI_AC_CLASS); 270db89b4f0dbab837d0f3de2c3e9427a8d5393afa3Pavel Machek device->driver_data = ac; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_ac_get_state(ac); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto end; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 276fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_ac_add_fs(device); 2788a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto end; 28197749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 282d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy ac->charger.name = acpi_device_bid(device); 283d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy ac->charger.type = POWER_SUPPLY_TYPE_MAINS; 284d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy ac->charger.properties = ac_props; 285d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy ac->charger.num_properties = ARRAY_SIZE(ac_props); 286d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy ac->charger.get_property = get_ac_property; 287d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy power_supply_register(&ac->device->dev, &ac->charger); 28897749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2904be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 2914be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown acpi_device_name(device), acpi_device_bid(device), 2924be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown ac->state ? "on-line" : "off-line"); 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2944be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown end: 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 296fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ac_remove_fs(device); 2988a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ac); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 302d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return result; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3055bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiystatic int acpi_ac_resume(struct acpi_device *device) 3065bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy{ 3075bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy struct acpi_ac *ac; 3085bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy unsigned old_state; 3095bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy if (!device || !acpi_driver_data(device)) 3105bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy return -EINVAL; 3115bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy ac = acpi_driver_data(device); 3125bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy old_state = ac->state; 3135bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy if (acpi_ac_get_state(ac)) 3145bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy return 0; 31597749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 3165bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy if (old_state != ac->state) 3175bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 31897749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 3195bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy return 0; 3205bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy} 3215bfeca3138a6031e38c566d57128ff592eb009a8Alexey Starikovskiy 3224be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int acpi_ac_remove(struct acpi_device *device, int type) 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3244be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brown struct acpi_ac *ac = NULL; 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!device || !acpi_driver_data(device)) 328d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -EINVAL; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33050dd096973f1d95aa03c6a6d9e148d706b62b68eJan Engelhardt ac = acpi_driver_data(device); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33297749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#ifdef CONFIG_ACPI_SYSFS_POWER 333d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy if (ac->charger.dev) 334d5b4a3d0efa36de31b86d5677dad6c36cb8735d7Alexey Starikovskiy power_supply_unregister(&ac->charger); 33597749cd9adbb2985e4b2aee1a59d6b970fe9c3a7Alexey Starikovskiy#endif 336fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_ac_remove_fs(device); 3388a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ac); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 342d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3454be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic int __init acpi_ac_init(void) 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3473f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend int result; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3494d8316d5ea4dcf0bf15d8a06d539ed7c99e9cfbePavel Machek if (acpi_disabled) 3504d8316d5ea4dcf0bf15d8a06d539ed7c99e9cfbePavel Machek return -ENODEV; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 352fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 3533f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend acpi_ac_dir = acpi_lock_ac_dir(); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!acpi_ac_dir) 355d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 3568a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = acpi_bus_register_driver(&acpi_ac_driver); 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result < 0) { 360fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 3613f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend acpi_unlock_ac_dir(acpi_ac_dir); 3628a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 363d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return -ENODEV; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 366d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return 0; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3694be44fcd3bf648b782f4460fd06dfae6c42ded4bLen Brownstatic void __exit acpi_ac_exit(void) 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds acpi_bus_unregister_driver(&acpi_ac_driver); 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 374fdcedbba2f98c94bfbac9f6e712ab765f997b8dcAlexey Starikovskiy#ifdef CONFIG_ACPI_PROCFS_POWER 3753f86b83243d59bb50caf5938d284d22e10d082a4Rich Townsend acpi_unlock_ac_dir(acpi_ac_dir); 3768a246ee43f4b1df3fa5cbf9c4a3d3dcad0b1e08cAndrey Borzenkov#endif 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 378d550d98d3317378d93a4869db204725d270ec812Patrick Mochel return; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(acpi_ac_init); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(acpi_ac_exit); 383