battery.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089
  1. /*
  2. * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
  3. *
  4. * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
  5. * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  6. *
  7. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or (at
  12. * your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, write to the Free Software Foundation, Inc.,
  21. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  22. *
  23. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  24. */
  25. #include <linux/kernel.h>
  26. #include <linux/module.h>
  27. #include <linux/init.h>
  28. #include <linux/types.h>
  29. #include <linux/proc_fs.h>
  30. #include <linux/seq_file.h>
  31. #include <asm/uaccess.h>
  32. #include <acpi/acpi_bus.h>
  33. #include <acpi/acpi_drivers.h>
  34. #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
  35. #define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS"
  36. #define ACPI_BATTERY_FORMAT_BST "NNNN"
  37. #define ACPI_BATTERY_COMPONENT 0x00040000
  38. #define ACPI_BATTERY_CLASS "battery"
  39. #define ACPI_BATTERY_HID "PNP0C0A"
  40. #define ACPI_BATTERY_DEVICE_NAME "Battery"
  41. #define ACPI_BATTERY_FILE_INFO "info"
  42. #define ACPI_BATTERY_FILE_STATE "state"
  43. #define ACPI_BATTERY_FILE_ALARM "alarm"
  44. #define ACPI_BATTERY_NOTIFY_STATUS 0x80
  45. #define ACPI_BATTERY_NOTIFY_INFO 0x81
  46. #define ACPI_BATTERY_UNITS_WATTS "mW"
  47. #define ACPI_BATTERY_UNITS_AMPS "mA"
  48. #define _COMPONENT ACPI_BATTERY_COMPONENT
  49. #define ACPI_BATTERY_UPDATE_TIME 0
  50. #define ACPI_BATTERY_NONE_UPDATE 0
  51. #define ACPI_BATTERY_EASY_UPDATE 1
  52. #define ACPI_BATTERY_INIT_UPDATE 2
  53. ACPI_MODULE_NAME("battery");
  54. MODULE_AUTHOR("Paul Diefenbaugh");
  55. MODULE_DESCRIPTION("ACPI Battery Driver");
  56. MODULE_LICENSE("GPL");
  57. static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
  58. /* 0 - every time, > 0 - by update_time */
  59. module_param(update_time, uint, 0644);
  60. extern struct proc_dir_entry *acpi_lock_battery_dir(void);
  61. extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
  62. static int acpi_battery_add(struct acpi_device *device);
  63. static int acpi_battery_remove(struct acpi_device *device, int type);
  64. static int acpi_battery_resume(struct acpi_device *device);
  65. static struct acpi_driver acpi_battery_driver = {
  66. .name = "battery",
  67. .class = ACPI_BATTERY_CLASS,
  68. .ids = ACPI_BATTERY_HID,
  69. .ops = {
  70. .add = acpi_battery_add,
  71. .resume = acpi_battery_resume,
  72. .remove = acpi_battery_remove,
  73. },
  74. };
  75. struct acpi_battery_state {
  76. acpi_integer state;
  77. acpi_integer present_rate;
  78. acpi_integer remaining_capacity;
  79. acpi_integer present_voltage;
  80. };
  81. struct acpi_battery_info {
  82. acpi_integer power_unit;
  83. acpi_integer design_capacity;
  84. acpi_integer last_full_capacity;
  85. acpi_integer battery_technology;
  86. acpi_integer design_voltage;
  87. acpi_integer design_capacity_warning;
  88. acpi_integer design_capacity_low;
  89. acpi_integer battery_capacity_granularity_1;
  90. acpi_integer battery_capacity_granularity_2;
  91. acpi_string model_number;
  92. acpi_string serial_number;
  93. acpi_string battery_type;
  94. acpi_string oem_info;
  95. };
  96. struct acpi_battery_flags {
  97. u8 battery_present_prev;
  98. u8 alarm_present;
  99. u8 init_update;
  100. u8 info_update;
  101. u8 state_update;
  102. u8 alarm_update;
  103. u8 power_unit;
  104. };
  105. struct acpi_battery {
  106. struct mutex mutex;
  107. struct acpi_device *device;
  108. struct acpi_battery_flags flags;
  109. struct acpi_buffer bif_data;
  110. struct acpi_buffer bst_data;
  111. unsigned long alarm;
  112. unsigned long info_update_time;
  113. unsigned long state_update_time;
  114. unsigned long alarm_update_time;
  115. };
  116. #define acpi_battery_present(battery) battery->device->status.battery_present
  117. #define acpi_battery_present_prev(battery) battery->flags.battery_present_prev
  118. #define acpi_battery_alarm_present(battery) battery->flags.alarm_present
  119. #define acpi_battery_init_update_flag(battery) battery->flags.init_update
  120. #define acpi_battery_info_update_flag(battery) battery->flags.info_update
  121. #define acpi_battery_state_update_flag(battery) battery->flags.state_update
  122. #define acpi_battery_alarm_update_flag(battery) battery->flags.alarm_update
  123. #define acpi_battery_power_units(battery) battery->flags.power_unit ? \
  124. ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS
  125. #define acpi_battery_handle(battery) battery->device->handle
  126. #define acpi_battery_inserted(battery) (!acpi_battery_present_prev(battery) & acpi_battery_present(battery))
  127. #define acpi_battery_removed(battery) (acpi_battery_present_prev(battery) & !acpi_battery_present(battery))
  128. #define acpi_battery_bid(battery) acpi_device_bid(battery->device)
  129. #define acpi_battery_status_str(battery) acpi_battery_present(battery) ? "present" : "absent"
  130. /* --------------------------------------------------------------------------
  131. Battery Management
  132. -------------------------------------------------------------------------- */
  133. static void acpi_battery_mutex_lock(struct acpi_battery *battery)
  134. {
  135. mutex_lock(&battery->mutex);
  136. }
  137. static void acpi_battery_mutex_unlock(struct acpi_battery *battery)
  138. {
  139. mutex_unlock(&battery->mutex);
  140. }
  141. static void acpi_battery_check_result(struct acpi_battery *battery, int result)
  142. {
  143. if (!battery)
  144. return;
  145. if (result) {
  146. acpi_battery_init_update_flag(battery) = 1;
  147. }
  148. }
  149. static int acpi_battery_extract_package(struct acpi_battery *battery,
  150. union acpi_object *package,
  151. struct acpi_buffer *format,
  152. struct acpi_buffer *data,
  153. char *package_name)
  154. {
  155. acpi_status status = AE_OK;
  156. struct acpi_buffer data_null = { 0, NULL };
  157. status = acpi_extract_package(package, format, &data_null);
  158. if (status != AE_BUFFER_OVERFLOW) {
  159. ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
  160. package_name));
  161. return -ENODEV;
  162. }
  163. if (data_null.length != data->length) {
  164. if (data->pointer) {
  165. kfree(data->pointer);
  166. }
  167. data->pointer = kzalloc(data_null.length, GFP_KERNEL);
  168. if (!data->pointer) {
  169. ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
  170. return -ENOMEM;
  171. }
  172. data->length = data_null.length;
  173. }
  174. status = acpi_extract_package(package, format, data);
  175. if (ACPI_FAILURE(status)) {
  176. ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
  177. package_name));
  178. return -ENODEV;
  179. }
  180. return 0;
  181. }
  182. static int acpi_battery_get_status(struct acpi_battery *battery)
  183. {
  184. int result = 0;
  185. result = acpi_bus_get_status(battery->device);
  186. if (result) {
  187. ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
  188. return -ENODEV;
  189. }
  190. return result;
  191. }
  192. static int acpi_battery_get_info(struct acpi_battery *battery)
  193. {
  194. int result = 0;
  195. acpi_status status = 0;
  196. struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  197. struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
  198. ACPI_BATTERY_FORMAT_BIF
  199. };
  200. union acpi_object *package = NULL;
  201. struct acpi_buffer *data = NULL;
  202. struct acpi_battery_info *bif = NULL;
  203. battery->info_update_time = get_seconds();
  204. if (!acpi_battery_present(battery))
  205. return 0;
  206. /* Evalute _BIF */
  207. status =
  208. acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
  209. &buffer);
  210. if (ACPI_FAILURE(status)) {
  211. ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
  212. return -ENODEV;
  213. }
  214. package = buffer.pointer;
  215. data = &battery->bif_data;
  216. /* Extract Package Data */
  217. result =
  218. acpi_battery_extract_package(battery, package, &format, data,
  219. "_BIF");
  220. if (result)
  221. goto end;
  222. end:
  223. if (buffer.pointer) {
  224. kfree(buffer.pointer);
  225. }
  226. if (!result) {
  227. bif = data->pointer;
  228. battery->flags.power_unit = bif->power_unit;
  229. }
  230. return result;
  231. }
  232. static int acpi_battery_get_state(struct acpi_battery *battery)
  233. {
  234. int result = 0;
  235. acpi_status status = 0;
  236. struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  237. struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
  238. ACPI_BATTERY_FORMAT_BST
  239. };
  240. union acpi_object *package = NULL;
  241. struct acpi_buffer *data = NULL;
  242. battery->state_update_time = get_seconds();
  243. if (!acpi_battery_present(battery))
  244. return 0;
  245. /* Evalute _BST */
  246. status =
  247. acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
  248. &buffer);
  249. if (ACPI_FAILURE(status)) {
  250. ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
  251. return -ENODEV;
  252. }
  253. package = buffer.pointer;
  254. data = &battery->bst_data;
  255. /* Extract Package Data */
  256. result =
  257. acpi_battery_extract_package(battery, package, &format, data,
  258. "_BST");
  259. if (result)
  260. goto end;
  261. end:
  262. if (buffer.pointer) {
  263. kfree(buffer.pointer);
  264. }
  265. return result;
  266. }
  267. static int acpi_battery_get_alarm(struct acpi_battery *battery)
  268. {
  269. battery->alarm_update_time = get_seconds();
  270. return 0;
  271. }
  272. static int acpi_battery_set_alarm(struct acpi_battery *battery,
  273. unsigned long alarm)
  274. {
  275. acpi_status status = 0;
  276. union acpi_object arg0 = { ACPI_TYPE_INTEGER };
  277. struct acpi_object_list arg_list = { 1, &arg0 };
  278. battery->alarm_update_time = get_seconds();
  279. if (!acpi_battery_present(battery))
  280. return -ENODEV;
  281. if (!acpi_battery_alarm_present(battery))
  282. return -ENODEV;
  283. arg0.integer.value = alarm;
  284. status =
  285. acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
  286. &arg_list, NULL);
  287. if (ACPI_FAILURE(status))
  288. return -ENODEV;
  289. ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
  290. battery->alarm = alarm;
  291. return 0;
  292. }
  293. static int acpi_battery_init_alarm(struct acpi_battery *battery)
  294. {
  295. int result = 0;
  296. acpi_status status = AE_OK;
  297. acpi_handle handle = NULL;
  298. struct acpi_battery_info *bif = battery->bif_data.pointer;
  299. unsigned long alarm = battery->alarm;
  300. /* See if alarms are supported, and if so, set default */
  301. status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
  302. if (ACPI_SUCCESS(status)) {
  303. acpi_battery_alarm_present(battery) = 1;
  304. if (!alarm && bif) {
  305. alarm = bif->design_capacity_warning;
  306. }
  307. result = acpi_battery_set_alarm(battery, alarm);
  308. if (result)
  309. goto end;
  310. } else {
  311. acpi_battery_alarm_present(battery) = 0;
  312. }
  313. end:
  314. return result;
  315. }
  316. static int acpi_battery_init_update(struct acpi_battery *battery)
  317. {
  318. int result = 0;
  319. result = acpi_battery_get_status(battery);
  320. if (result)
  321. return result;
  322. acpi_battery_present_prev(battery) = acpi_battery_present(battery);
  323. if (acpi_battery_present(battery)) {
  324. result = acpi_battery_get_info(battery);
  325. if (result)
  326. return result;
  327. result = acpi_battery_get_state(battery);
  328. if (result)
  329. return result;
  330. acpi_battery_init_alarm(battery);
  331. }
  332. return result;
  333. }
  334. static int acpi_battery_update(struct acpi_battery *battery,
  335. int update, int *update_result_ptr)
  336. {
  337. int result = 0;
  338. int update_result = ACPI_BATTERY_NONE_UPDATE;
  339. if (!acpi_battery_present(battery)) {
  340. update = 1;
  341. }
  342. if (acpi_battery_init_update_flag(battery)) {
  343. result = acpi_battery_init_update(battery);
  344. if (result)
  345. goto end;;
  346. update_result = ACPI_BATTERY_INIT_UPDATE;
  347. } else if (update) {
  348. result = acpi_battery_get_status(battery);
  349. if (result)
  350. goto end;;
  351. if (acpi_battery_inserted(battery)
  352. || acpi_battery_removed(battery)) {
  353. result = acpi_battery_init_update(battery);
  354. if (result)
  355. goto end;;
  356. update_result = ACPI_BATTERY_INIT_UPDATE;
  357. } else {
  358. update_result = ACPI_BATTERY_EASY_UPDATE;
  359. }
  360. }
  361. end:
  362. acpi_battery_init_update_flag(battery) = (result != 0);
  363. *update_result_ptr = update_result;
  364. return result;
  365. }
  366. static void acpi_battery_notify_update(struct acpi_battery *battery)
  367. {
  368. acpi_battery_get_status(battery);
  369. if (acpi_battery_init_update_flag(battery)) {
  370. return;
  371. }
  372. if (acpi_battery_inserted(battery) || acpi_battery_removed(battery)) {
  373. acpi_battery_init_update_flag(battery) = 1;
  374. } else {
  375. acpi_battery_info_update_flag(battery) = 1;
  376. acpi_battery_state_update_flag(battery) = 1;
  377. acpi_battery_alarm_update_flag(battery) = 1;
  378. }
  379. }
  380. /* --------------------------------------------------------------------------
  381. FS Interface (/proc)
  382. -------------------------------------------------------------------------- */
  383. static struct proc_dir_entry *acpi_battery_dir;
  384. static int acpi_battery_read_info_print(struct seq_file *seq, int result)
  385. {
  386. struct acpi_battery *battery = seq->private;
  387. struct acpi_battery_info *bif = NULL;
  388. char *units = "?";
  389. if (result)
  390. goto end;
  391. if (acpi_battery_present(battery))
  392. seq_printf(seq, "present: yes\n");
  393. else {
  394. seq_printf(seq, "present: no\n");
  395. goto end;
  396. }
  397. bif = battery->bif_data.pointer;
  398. if (!bif) {
  399. ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
  400. result = -ENODEV;
  401. goto end;
  402. }
  403. /* Battery Units */
  404. units = acpi_battery_power_units(battery);
  405. if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
  406. seq_printf(seq, "design capacity: unknown\n");
  407. else
  408. seq_printf(seq, "design capacity: %d %sh\n",
  409. (u32) bif->design_capacity, units);
  410. if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
  411. seq_printf(seq, "last full capacity: unknown\n");
  412. else
  413. seq_printf(seq, "last full capacity: %d %sh\n",
  414. (u32) bif->last_full_capacity, units);
  415. switch ((u32) bif->battery_technology) {
  416. case 0:
  417. seq_printf(seq, "battery technology: non-rechargeable\n");
  418. break;
  419. case 1:
  420. seq_printf(seq, "battery technology: rechargeable\n");
  421. break;
  422. default:
  423. seq_printf(seq, "battery technology: unknown\n");
  424. break;
  425. }
  426. if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
  427. seq_printf(seq, "design voltage: unknown\n");
  428. else
  429. seq_printf(seq, "design voltage: %d mV\n",
  430. (u32) bif->design_voltage);
  431. seq_printf(seq, "design capacity warning: %d %sh\n",
  432. (u32) bif->design_capacity_warning, units);
  433. seq_printf(seq, "design capacity low: %d %sh\n",
  434. (u32) bif->design_capacity_low, units);
  435. seq_printf(seq, "capacity granularity 1: %d %sh\n",
  436. (u32) bif->battery_capacity_granularity_1, units);
  437. seq_printf(seq, "capacity granularity 2: %d %sh\n",
  438. (u32) bif->battery_capacity_granularity_2, units);
  439. seq_printf(seq, "model number: %s\n", bif->model_number);
  440. seq_printf(seq, "serial number: %s\n", bif->serial_number);
  441. seq_printf(seq, "battery type: %s\n", bif->battery_type);
  442. seq_printf(seq, "OEM info: %s\n", bif->oem_info);
  443. end:
  444. if (result)
  445. seq_printf(seq, "ERROR: Unable to read battery info\n");
  446. return result;
  447. }
  448. static int acpi_battery_read_info(struct seq_file *seq, void *offset)
  449. {
  450. struct acpi_battery *battery = seq->private;
  451. int result = 0;
  452. int update_result = ACPI_BATTERY_NONE_UPDATE;
  453. int update = 0;
  454. acpi_battery_mutex_lock(battery);
  455. update = (get_seconds() - battery->info_update_time >= update_time);
  456. update = (update | acpi_battery_info_update_flag(battery));
  457. result = acpi_battery_update(battery, update, &update_result);
  458. if (result)
  459. goto end;
  460. /* Battery Info (_BIF) */
  461. if (update_result == ACPI_BATTERY_EASY_UPDATE) {
  462. result = acpi_battery_get_info(battery);
  463. if (result)
  464. goto end;
  465. }
  466. end:
  467. result = acpi_battery_read_info_print(seq, result);
  468. acpi_battery_check_result(battery, result);
  469. acpi_battery_info_update_flag(battery) = result;
  470. acpi_battery_mutex_unlock(battery);
  471. return result;
  472. }
  473. static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
  474. {
  475. return single_open(file, acpi_battery_read_info, PDE(inode)->data);
  476. }
  477. static int acpi_battery_read_state_print(struct seq_file *seq, int result)
  478. {
  479. struct acpi_battery *battery = seq->private;
  480. struct acpi_battery_state *bst = NULL;
  481. char *units = "?";
  482. if (result)
  483. goto end;
  484. if (acpi_battery_present(battery))
  485. seq_printf(seq, "present: yes\n");
  486. else {
  487. seq_printf(seq, "present: no\n");
  488. goto end;
  489. }
  490. bst = battery->bst_data.pointer;
  491. if (!bst) {
  492. ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
  493. result = -ENODEV;
  494. goto end;
  495. }
  496. /* Battery Units */
  497. units = acpi_battery_power_units(battery);
  498. if (!(bst->state & 0x04))
  499. seq_printf(seq, "capacity state: ok\n");
  500. else
  501. seq_printf(seq, "capacity state: critical\n");
  502. if ((bst->state & 0x01) && (bst->state & 0x02)) {
  503. seq_printf(seq,
  504. "charging state: charging/discharging\n");
  505. } else if (bst->state & 0x01)
  506. seq_printf(seq, "charging state: discharging\n");
  507. else if (bst->state & 0x02)
  508. seq_printf(seq, "charging state: charging\n");
  509. else {
  510. seq_printf(seq, "charging state: charged\n");
  511. }
  512. if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
  513. seq_printf(seq, "present rate: unknown\n");
  514. else
  515. seq_printf(seq, "present rate: %d %s\n",
  516. (u32) bst->present_rate, units);
  517. if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
  518. seq_printf(seq, "remaining capacity: unknown\n");
  519. else
  520. seq_printf(seq, "remaining capacity: %d %sh\n",
  521. (u32) bst->remaining_capacity, units);
  522. if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
  523. seq_printf(seq, "present voltage: unknown\n");
  524. else
  525. seq_printf(seq, "present voltage: %d mV\n",
  526. (u32) bst->present_voltage);
  527. end:
  528. if (result) {
  529. seq_printf(seq, "ERROR: Unable to read battery state\n");
  530. }
  531. return result;
  532. }
  533. static int acpi_battery_read_state(struct seq_file *seq, void *offset)
  534. {
  535. struct acpi_battery *battery = seq->private;
  536. int result = 0;
  537. int update_result = ACPI_BATTERY_NONE_UPDATE;
  538. int update = 0;
  539. acpi_battery_mutex_lock(battery);
  540. update = (get_seconds() - battery->state_update_time >= update_time);
  541. update = (update | acpi_battery_state_update_flag(battery));
  542. result = acpi_battery_update(battery, update, &update_result);
  543. if (result)
  544. goto end;
  545. /* Battery State (_BST) */
  546. if (update_result == ACPI_BATTERY_EASY_UPDATE) {
  547. result = acpi_battery_get_state(battery);
  548. if (result)
  549. goto end;
  550. }
  551. end:
  552. result = acpi_battery_read_state_print(seq, result);
  553. acpi_battery_check_result(battery, result);
  554. acpi_battery_state_update_flag(battery) = result;
  555. acpi_battery_mutex_unlock(battery);
  556. return result;
  557. }
  558. static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
  559. {
  560. return single_open(file, acpi_battery_read_state, PDE(inode)->data);
  561. }
  562. static int acpi_battery_read_alarm_print(struct seq_file *seq, int result)
  563. {
  564. struct acpi_battery *battery = seq->private;
  565. char *units = "?";
  566. if (result)
  567. goto end;
  568. if (!acpi_battery_present(battery)) {
  569. seq_printf(seq, "present: no\n");
  570. goto end;
  571. }
  572. /* Battery Units */
  573. units = acpi_battery_power_units(battery);
  574. seq_printf(seq, "alarm: ");
  575. if (!battery->alarm)
  576. seq_printf(seq, "unsupported\n");
  577. else
  578. seq_printf(seq, "%lu %sh\n", battery->alarm, units);
  579. end:
  580. if (result)
  581. seq_printf(seq, "ERROR: Unable to read battery alarm\n");
  582. return result;
  583. }
  584. static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
  585. {
  586. struct acpi_battery *battery = seq->private;
  587. int result = 0;
  588. int update_result = ACPI_BATTERY_NONE_UPDATE;
  589. int update = 0;
  590. acpi_battery_mutex_lock(battery);
  591. update = (get_seconds() - battery->alarm_update_time >= update_time);
  592. update = (update | acpi_battery_alarm_update_flag(battery));
  593. result = acpi_battery_update(battery, update, &update_result);
  594. if (result)
  595. goto end;
  596. /* Battery Alarm */
  597. if (update_result == ACPI_BATTERY_EASY_UPDATE) {
  598. result = acpi_battery_get_alarm(battery);
  599. if (result)
  600. goto end;
  601. }
  602. end:
  603. result = acpi_battery_read_alarm_print(seq, result);
  604. acpi_battery_check_result(battery, result);
  605. acpi_battery_alarm_update_flag(battery) = result;
  606. acpi_battery_mutex_unlock(battery);
  607. return result;
  608. }
  609. static ssize_t
  610. acpi_battery_write_alarm(struct file *file,
  611. const char __user * buffer,
  612. size_t count, loff_t * ppos)
  613. {
  614. int result = 0;
  615. char alarm_string[12] = { '\0' };
  616. struct seq_file *m = file->private_data;
  617. struct acpi_battery *battery = m->private;
  618. int update_result = ACPI_BATTERY_NONE_UPDATE;
  619. if (!battery || (count > sizeof(alarm_string) - 1))
  620. return -EINVAL;
  621. acpi_battery_mutex_lock(battery);
  622. result = acpi_battery_update(battery, 1, &update_result);
  623. if (result) {
  624. result = -ENODEV;
  625. goto end;
  626. }
  627. if (!acpi_battery_present(battery)) {
  628. result = -ENODEV;
  629. goto end;
  630. }
  631. if (copy_from_user(alarm_string, buffer, count)) {
  632. result = -EFAULT;
  633. goto end;
  634. }
  635. alarm_string[count] = '\0';
  636. result = acpi_battery_set_alarm(battery,
  637. simple_strtoul(alarm_string, NULL, 0));
  638. if (result)
  639. goto end;
  640. end:
  641. acpi_battery_check_result(battery, result);
  642. if (!result)
  643. result = count;
  644. acpi_battery_mutex_unlock(battery);
  645. return result;
  646. }
  647. static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
  648. {
  649. return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
  650. }
  651. static const struct file_operations acpi_battery_info_ops = {
  652. .open = acpi_battery_info_open_fs,
  653. .read = seq_read,
  654. .llseek = seq_lseek,
  655. .release = single_release,
  656. .owner = THIS_MODULE,
  657. };
  658. static const struct file_operations acpi_battery_state_ops = {
  659. .open = acpi_battery_state_open_fs,
  660. .read = seq_read,
  661. .llseek = seq_lseek,
  662. .release = single_release,
  663. .owner = THIS_MODULE,
  664. };
  665. static const struct file_operations acpi_battery_alarm_ops = {
  666. .open = acpi_battery_alarm_open_fs,
  667. .read = seq_read,
  668. .write = acpi_battery_write_alarm,
  669. .llseek = seq_lseek,
  670. .release = single_release,
  671. .owner = THIS_MODULE,
  672. };
  673. static int acpi_battery_add_fs(struct acpi_device *device)
  674. {
  675. struct proc_dir_entry *entry = NULL;
  676. if (!acpi_device_dir(device)) {
  677. acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
  678. acpi_battery_dir);
  679. if (!acpi_device_dir(device))
  680. return -ENODEV;
  681. acpi_device_dir(device)->owner = THIS_MODULE;
  682. }
  683. /* 'info' [R] */
  684. entry = create_proc_entry(ACPI_BATTERY_FILE_INFO,
  685. S_IRUGO, acpi_device_dir(device));
  686. if (!entry)
  687. return -ENODEV;
  688. else {
  689. entry->proc_fops = &acpi_battery_info_ops;
  690. entry->data = acpi_driver_data(device);
  691. entry->owner = THIS_MODULE;
  692. }
  693. /* 'status' [R] */
  694. entry = create_proc_entry(ACPI_BATTERY_FILE_STATE,
  695. S_IRUGO, acpi_device_dir(device));
  696. if (!entry)
  697. return -ENODEV;
  698. else {
  699. entry->proc_fops = &acpi_battery_state_ops;
  700. entry->data = acpi_driver_data(device);
  701. entry->owner = THIS_MODULE;
  702. }
  703. /* 'alarm' [R/W] */
  704. entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM,
  705. S_IFREG | S_IRUGO | S_IWUSR,
  706. acpi_device_dir(device));
  707. if (!entry)
  708. return -ENODEV;
  709. else {
  710. entry->proc_fops = &acpi_battery_alarm_ops;
  711. entry->data = acpi_driver_data(device);
  712. entry->owner = THIS_MODULE;
  713. }
  714. return 0;
  715. }
  716. static int acpi_battery_remove_fs(struct acpi_device *device)
  717. {
  718. if (acpi_device_dir(device)) {
  719. remove_proc_entry(ACPI_BATTERY_FILE_ALARM,
  720. acpi_device_dir(device));
  721. remove_proc_entry(ACPI_BATTERY_FILE_STATE,
  722. acpi_device_dir(device));
  723. remove_proc_entry(ACPI_BATTERY_FILE_INFO,
  724. acpi_device_dir(device));
  725. remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
  726. acpi_device_dir(device) = NULL;
  727. }
  728. return 0;
  729. }
  730. /* --------------------------------------------------------------------------
  731. Driver Interface
  732. -------------------------------------------------------------------------- */
  733. static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
  734. {
  735. struct acpi_battery *battery = data;
  736. struct acpi_device *device = NULL;
  737. if (!battery)
  738. return;
  739. device = battery->device;
  740. switch (event) {
  741. case ACPI_BATTERY_NOTIFY_STATUS:
  742. case ACPI_BATTERY_NOTIFY_INFO:
  743. case ACPI_NOTIFY_BUS_CHECK:
  744. case ACPI_NOTIFY_DEVICE_CHECK:
  745. device = battery->device;
  746. acpi_battery_notify_update(battery);
  747. acpi_bus_generate_event(device, event,
  748. acpi_battery_present(battery));
  749. break;
  750. default:
  751. ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  752. "Unsupported event [0x%x]\n", event));
  753. break;
  754. }
  755. return;
  756. }
  757. static int acpi_battery_add(struct acpi_device *device)
  758. {
  759. int result = 0;
  760. acpi_status status = 0;
  761. struct acpi_battery *battery = NULL;
  762. if (!device)
  763. return -EINVAL;
  764. battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
  765. if (!battery)
  766. return -ENOMEM;
  767. mutex_init(&battery->mutex);
  768. acpi_battery_mutex_lock(battery);
  769. battery->device = device;
  770. strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
  771. strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
  772. acpi_driver_data(device) = battery;
  773. result = acpi_battery_get_status(battery);
  774. if (result)
  775. goto end;
  776. acpi_battery_init_update_flag(battery) = 1;
  777. result = acpi_battery_add_fs(device);
  778. if (result)
  779. goto end;
  780. status = acpi_install_notify_handler(device->handle,
  781. ACPI_ALL_NOTIFY,
  782. acpi_battery_notify, battery);
  783. if (ACPI_FAILURE(status)) {
  784. ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));
  785. result = -ENODEV;
  786. goto end;
  787. }
  788. printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
  789. ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
  790. device->status.battery_present ? "present" : "absent");
  791. end:
  792. if (result) {
  793. acpi_battery_remove_fs(device);
  794. kfree(battery);
  795. }
  796. acpi_battery_mutex_unlock(battery);
  797. return result;
  798. }
  799. static int acpi_battery_remove(struct acpi_device *device, int type)
  800. {
  801. acpi_status status = 0;
  802. struct acpi_battery *battery = NULL;
  803. if (!device || !acpi_driver_data(device))
  804. return -EINVAL;
  805. battery = acpi_driver_data(device);
  806. acpi_battery_mutex_lock(battery);
  807. status = acpi_remove_notify_handler(device->handle,
  808. ACPI_ALL_NOTIFY,
  809. acpi_battery_notify);
  810. acpi_battery_remove_fs(device);
  811. if (battery->bif_data.pointer)
  812. kfree(battery->bif_data.pointer);
  813. if (battery->bst_data.pointer)
  814. kfree(battery->bst_data.pointer);
  815. acpi_battery_mutex_unlock(battery);
  816. mutex_destroy(&battery->mutex);
  817. kfree(battery);
  818. return 0;
  819. }
  820. /* this is needed to learn about changes made in suspended state */
  821. static int acpi_battery_resume(struct acpi_device *device)
  822. {
  823. struct acpi_battery *battery;
  824. if (!device)
  825. return -EINVAL;
  826. battery = device->driver_data;
  827. acpi_battery_init_update_flag(battery) = 1;
  828. return 0;
  829. }
  830. static int __init acpi_battery_init(void)
  831. {
  832. int result;
  833. if (acpi_disabled)
  834. return -ENODEV;
  835. acpi_battery_dir = acpi_lock_battery_dir();
  836. if (!acpi_battery_dir)
  837. return -ENODEV;
  838. result = acpi_bus_register_driver(&acpi_battery_driver);
  839. if (result < 0) {
  840. acpi_unlock_battery_dir(acpi_battery_dir);
  841. return -ENODEV;
  842. }
  843. return 0;
  844. }
  845. static void __exit acpi_battery_exit(void)
  846. {
  847. acpi_bus_unregister_driver(&acpi_battery_driver);
  848. acpi_unlock_battery_dir(acpi_battery_dir);
  849. return;
  850. }
  851. module_init(acpi_battery_init);
  852. module_exit(acpi_battery_exit);