sbs.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570
  1. /*
  2. * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
  3. *
  4. * Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
  5. *
  6. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  21. *
  22. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  23. */
  24. #include <linux/init.h>
  25. #include <linux/module.h>
  26. #include <linux/moduleparam.h>
  27. #include <linux/kernel.h>
  28. #include <linux/proc_fs.h>
  29. #include <linux/seq_file.h>
  30. #include <asm/uaccess.h>
  31. #include <linux/acpi.h>
  32. #include <linux/timer.h>
  33. #include <linux/jiffies.h>
  34. #include <linux/delay.h>
  35. #include "sbshc.h"
  36. #define ACPI_SBS_COMPONENT 0x00080000
  37. #define ACPI_SBS_CLASS "sbs"
  38. #define ACPI_AC_CLASS "ac_adapter"
  39. #define ACPI_BATTERY_CLASS "battery"
  40. #define ACPI_SBS_DEVICE_NAME "Smart Battery System"
  41. #define ACPI_SBS_FILE_INFO "info"
  42. #define ACPI_SBS_FILE_STATE "state"
  43. #define ACPI_SBS_FILE_ALARM "alarm"
  44. #define ACPI_BATTERY_DIR_NAME "BAT%i"
  45. #define ACPI_AC_DIR_NAME "AC0"
  46. #define ACPI_SBC_SMBUS_ADDR 0x9
  47. #define ACPI_SBSM_SMBUS_ADDR 0xa
  48. #define ACPI_SB_SMBUS_ADDR 0xb
  49. #define ACPI_SBS_AC_NOTIFY_STATUS 0x80
  50. #define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
  51. #define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81
  52. #define _COMPONENT ACPI_SBS_COMPONENT
  53. ACPI_MODULE_NAME("sbs");
  54. MODULE_AUTHOR("Rich Townsend");
  55. MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
  56. MODULE_LICENSE("GPL");
  57. #define DEF_CAPACITY_UNIT 3
  58. #define MAH_CAPACITY_UNIT 1
  59. #define MWH_CAPACITY_UNIT 2
  60. #define CAPACITY_UNIT DEF_CAPACITY_UNIT
  61. #define REQUEST_UPDATE_MODE 1
  62. #define QUEUE_UPDATE_MODE 2
  63. #define DATA_TYPE_COMMON 0
  64. #define DATA_TYPE_INFO 1
  65. #define DATA_TYPE_STATE 2
  66. #define DATA_TYPE_ALARM 3
  67. #define DATA_TYPE_AC_STATE 4
  68. extern struct proc_dir_entry *acpi_lock_ac_dir(void);
  69. extern struct proc_dir_entry *acpi_lock_battery_dir(void);
  70. extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
  71. extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
  72. #define MAX_SBS_BAT 4
  73. #define ACPI_SBS_BLOCK_MAX 32
  74. #define UPDATE_DELAY 10
  75. /* 0 - every time, > 0 - by update_time */
  76. static unsigned int update_time = 120;
  77. static unsigned int mode = CAPACITY_UNIT;
  78. module_param(update_time, uint, 0644);
  79. module_param(mode, uint, 0444);
  80. static int acpi_sbs_add(struct acpi_device *device);
  81. static int acpi_sbs_remove(struct acpi_device *device, int type);
  82. static int acpi_sbs_resume(struct acpi_device *device);
  83. static const struct acpi_device_id sbs_device_ids[] = {
  84. {"ACPI0002", 0},
  85. {"", 0},
  86. };
  87. MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
  88. static struct acpi_driver acpi_sbs_driver = {
  89. .name = "sbs",
  90. .class = ACPI_SBS_CLASS,
  91. .ids = sbs_device_ids,
  92. .ops = {
  93. .add = acpi_sbs_add,
  94. .remove = acpi_sbs_remove,
  95. .resume = acpi_sbs_resume,
  96. },
  97. };
  98. struct acpi_battery {
  99. struct acpi_sbs *sbs;
  100. struct proc_dir_entry *proc_entry;
  101. int vscale;
  102. int ipscale;
  103. char manufacturer_name[ACPI_SBS_BLOCK_MAX];
  104. char device_name[ACPI_SBS_BLOCK_MAX];
  105. char device_chemistry[ACPI_SBS_BLOCK_MAX];
  106. u16 full_charge_capacity;
  107. u16 design_capacity;
  108. u16 design_voltage;
  109. u16 serial_number;
  110. u16 voltage_now;
  111. s16 current_now;
  112. u16 capacity_now;
  113. u16 state;
  114. u16 alarm_capacity;
  115. u16 mode;
  116. u8 id;
  117. u8 alive:1;
  118. u8 init_state:1;
  119. u8 present:1;
  120. };
  121. struct acpi_sbs {
  122. struct acpi_device *device;
  123. struct acpi_smb_hc *hc;
  124. struct mutex mutex;
  125. struct proc_dir_entry *ac_entry;
  126. struct acpi_battery battery[MAX_SBS_BAT];
  127. int zombie;
  128. struct timer_list update_timer;
  129. int run_cnt;
  130. int update_proc_flg;
  131. u8 batteries_supported;
  132. u8 manager_present:1;
  133. u8 charger_present:1;
  134. };
  135. static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
  136. static void acpi_sbs_update_time(void *data);
  137. static int sbs_zombie(struct acpi_sbs *sbs)
  138. {
  139. return (sbs->zombie);
  140. }
  141. static int sbs_mutex_lock(struct acpi_sbs *sbs)
  142. {
  143. if (sbs_zombie(sbs)) {
  144. return -ENODEV;
  145. }
  146. mutex_lock(&sbs->mutex);
  147. return 0;
  148. }
  149. static void sbs_mutex_unlock(struct acpi_sbs *sbs)
  150. {
  151. mutex_unlock(&sbs->mutex);
  152. }
  153. /* --------------------------------------------------------------------------
  154. Smart Battery System Management
  155. -------------------------------------------------------------------------- */
  156. static int acpi_check_update_proc(struct acpi_sbs *sbs)
  157. {
  158. acpi_status status = AE_OK;
  159. if (update_time == 0) {
  160. sbs->update_proc_flg = 0;
  161. return 0;
  162. }
  163. if (sbs->update_proc_flg == 0) {
  164. status = acpi_os_execute(OSL_GPE_HANDLER,
  165. acpi_sbs_update_time, sbs);
  166. if (status != AE_OK) {
  167. ACPI_EXCEPTION((AE_INFO, status,
  168. "acpi_os_execute() failed"));
  169. return 1;
  170. }
  171. sbs->update_proc_flg = 1;
  172. }
  173. return 0;
  174. }
  175. static int acpi_battery_get_present(struct acpi_battery *battery)
  176. {
  177. s16 state;
  178. int result = 0;
  179. int is_present = 0;
  180. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
  181. ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
  182. if (result) {
  183. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  184. "acpi_smbus_read() failed"));
  185. }
  186. if (!result) {
  187. is_present = (state & 0x000f) & (1 << battery->id);
  188. }
  189. battery->present = is_present;
  190. return result;
  191. }
  192. static int acpi_battery_select(struct acpi_battery *battery)
  193. {
  194. struct acpi_sbs *sbs = battery->sbs;
  195. int result = 0;
  196. s16 state;
  197. int foo;
  198. if (sbs->manager_present) {
  199. /* Take special care not to knobble other nibbles of
  200. * state (aka selector_state), since
  201. * it causes charging to halt on SBSELs */
  202. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
  203. ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&state);
  204. if (result) {
  205. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  206. "acpi_smbus_read() failed"));
  207. goto end;
  208. }
  209. foo = (state & 0x0fff) | (1 << (battery->id + 12));
  210. result = acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
  211. ACPI_SBSM_SMBUS_ADDR, 0x01, (u8 *)&foo, 2);
  212. if (result) {
  213. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  214. "acpi_smbus_write() failed"));
  215. goto end;
  216. }
  217. }
  218. end:
  219. return result;
  220. }
  221. static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
  222. {
  223. int result = 0;
  224. s16 battery_system_info;
  225. result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBSM_SMBUS_ADDR, 0x04,
  226. (u8 *)&battery_system_info);
  227. if (result) {
  228. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  229. "acpi_smbus_read() failed"));
  230. goto end;
  231. }
  232. sbs->manager_present = 1;
  233. end:
  234. return result;
  235. }
  236. static int acpi_battery_get_info(struct acpi_battery *battery)
  237. {
  238. int result = 0;
  239. s16 battery_mode;
  240. s16 specification_info;
  241. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
  242. (u8 *)&battery_mode);
  243. if (result) {
  244. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  245. "acpi_smbus_read() failed"));
  246. goto end;
  247. }
  248. battery->mode = (battery_mode & 0x8000) >> 15;
  249. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x10,
  250. (u8 *)&battery->full_charge_capacity);
  251. if (result) {
  252. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  253. "acpi_smbus_read() failed"));
  254. goto end;
  255. }
  256. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x18,
  257. (u8 *)&battery->design_capacity);
  258. if (result) {
  259. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  260. "acpi_smbus_read() failed"));
  261. goto end;
  262. }
  263. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x19,
  264. (u8 *)&battery->design_voltage);
  265. if (result) {
  266. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  267. "acpi_smbus_read() failed"));
  268. goto end;
  269. }
  270. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1a,
  271. (u8 *)&specification_info);
  272. if (result) {
  273. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  274. "acpi_smbus_read() failed"));
  275. goto end;
  276. }
  277. switch ((specification_info & 0x0f00) >> 8) {
  278. case 1:
  279. battery->vscale = 10;
  280. break;
  281. case 2:
  282. battery->vscale = 100;
  283. break;
  284. case 3:
  285. battery->vscale = 1000;
  286. break;
  287. default:
  288. battery->vscale = 1;
  289. }
  290. switch ((specification_info & 0xf000) >> 12) {
  291. case 1:
  292. battery->ipscale = 10;
  293. break;
  294. case 2:
  295. battery->ipscale = 100;
  296. break;
  297. case 3:
  298. battery->ipscale = 1000;
  299. break;
  300. default:
  301. battery->ipscale = 1;
  302. }
  303. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x1c,
  304. (u8 *)&battery->serial_number);
  305. if (result) {
  306. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  307. "acpi_smbus_read() failed"));
  308. goto end;
  309. }
  310. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x20,
  311. (u8 *)battery->manufacturer_name);
  312. if (result) {
  313. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  314. "acpi_sbs_read_str() failed"));
  315. goto end;
  316. }
  317. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x21,
  318. (u8 *)battery->device_name);
  319. if (result) {
  320. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  321. "acpi_sbs_read_str() failed"));
  322. goto end;
  323. }
  324. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_BLOCK, ACPI_SB_SMBUS_ADDR, 0x22,
  325. (u8 *)battery->device_chemistry);
  326. if (result) {
  327. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  328. "acpi_sbs_read_str() failed"));
  329. goto end;
  330. }
  331. end:
  332. return result;
  333. }
  334. static int acpi_battery_get_state(struct acpi_battery *battery)
  335. {
  336. int result = 0;
  337. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x09,
  338. (u8 *)&battery->voltage_now);
  339. if (result) {
  340. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  341. "acpi_smbus_read() failed"));
  342. goto end;
  343. }
  344. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0a,
  345. (u8 *)&battery->current_now);
  346. if (result) {
  347. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  348. "acpi_smbus_read() failed"));
  349. goto end;
  350. }
  351. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x0f,
  352. (u8 *)&battery->capacity_now);
  353. if (result) {
  354. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  355. "acpi_smbus_read() failed"));
  356. goto end;
  357. }
  358. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x16,
  359. (u8 *)&battery->state);
  360. if (result) {
  361. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  362. "acpi_smbus_read() failed"));
  363. goto end;
  364. }
  365. end:
  366. return result;
  367. }
  368. static int acpi_battery_get_alarm(struct acpi_battery *battery)
  369. {
  370. int result = 0;
  371. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
  372. (u8 *)&battery->alarm_capacity);
  373. if (result) {
  374. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  375. "acpi_smbus_read() failed"));
  376. goto end;
  377. }
  378. end:
  379. return result;
  380. }
  381. static int acpi_battery_set_alarm(struct acpi_battery *battery,
  382. unsigned long alarm)
  383. {
  384. int result = 0;
  385. s16 battery_mode;
  386. int foo;
  387. result = acpi_battery_select(battery);
  388. if (result) {
  389. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  390. "acpi_battery_select() failed"));
  391. goto end;
  392. }
  393. /* If necessary, enable the alarm */
  394. if (alarm > 0) {
  395. result =
  396. acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x03,
  397. (u8 *)&battery_mode);
  398. if (result) {
  399. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  400. "acpi_smbus_read() failed"));
  401. goto end;
  402. }
  403. battery_mode &= 0xbfff;
  404. result =
  405. acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
  406. (u8 *)&battery_mode, 2);
  407. if (result) {
  408. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  409. "acpi_smbus_write() failed"));
  410. goto end;
  411. }
  412. }
  413. foo = alarm / (battery->mode ? 10 : 1);
  414. result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD, ACPI_SB_SMBUS_ADDR, 0x01,
  415. (u8 *)&foo, 2);
  416. if (result) {
  417. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  418. "acpi_smbus_write() failed"));
  419. goto end;
  420. }
  421. end:
  422. return result;
  423. }
  424. static int acpi_battery_set_mode(struct acpi_battery *battery)
  425. {
  426. int result = 0;
  427. s16 battery_mode;
  428. if (mode == DEF_CAPACITY_UNIT) {
  429. goto end;
  430. }
  431. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
  432. ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
  433. if (result) {
  434. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  435. "acpi_smbus_read() failed"));
  436. goto end;
  437. }
  438. if (mode == MAH_CAPACITY_UNIT) {
  439. battery_mode &= 0x7fff;
  440. } else {
  441. battery_mode |= 0x8000;
  442. }
  443. result = acpi_smbus_write(battery->sbs->hc, SMBUS_READ_WORD,
  444. ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode, 2);
  445. if (result) {
  446. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  447. "acpi_smbus_write() failed"));
  448. goto end;
  449. }
  450. result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
  451. ACPI_SB_SMBUS_ADDR, 0x03, (u8 *)&battery_mode);
  452. if (result) {
  453. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  454. "acpi_smbus_read() failed"));
  455. goto end;
  456. }
  457. end:
  458. return result;
  459. }
  460. static int acpi_battery_init(struct acpi_battery *battery)
  461. {
  462. int result = 0;
  463. result = acpi_battery_select(battery);
  464. if (result) {
  465. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  466. "acpi_battery_select() failed"));
  467. goto end;
  468. }
  469. result = acpi_battery_set_mode(battery);
  470. if (result) {
  471. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  472. "acpi_battery_set_mode() failed"));
  473. goto end;
  474. }
  475. result = acpi_battery_get_info(battery);
  476. if (result) {
  477. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  478. "acpi_battery_get_info() failed"));
  479. goto end;
  480. }
  481. result = acpi_battery_get_state(battery);
  482. if (result) {
  483. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  484. "acpi_battery_get_state() failed"));
  485. goto end;
  486. }
  487. result = acpi_battery_get_alarm(battery);
  488. if (result) {
  489. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  490. "acpi_battery_get_alarm() failed"));
  491. goto end;
  492. }
  493. end:
  494. return result;
  495. }
  496. static int acpi_ac_get_present(struct acpi_sbs *sbs)
  497. {
  498. int result = 0;
  499. s16 charger_status;
  500. result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBC_SMBUS_ADDR, 0x13,
  501. (u8 *)&charger_status);
  502. if (result) {
  503. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  504. "acpi_smbus_read() failed"));
  505. goto end;
  506. }
  507. sbs->charger_present = (charger_status & 0x8000) >> 15;
  508. end:
  509. return result;
  510. }
  511. /* --------------------------------------------------------------------------
  512. FS Interface (/proc/acpi)
  513. -------------------------------------------------------------------------- */
  514. /* Generic Routines */
  515. static int
  516. acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
  517. struct proc_dir_entry *parent_dir,
  518. char *dir_name,
  519. struct file_operations *info_fops,
  520. struct file_operations *state_fops,
  521. struct file_operations *alarm_fops, void *data)
  522. {
  523. struct proc_dir_entry *entry = NULL;
  524. if (!*dir) {
  525. *dir = proc_mkdir(dir_name, parent_dir);
  526. if (!*dir) {
  527. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  528. "proc_mkdir() failed"));
  529. return -ENODEV;
  530. }
  531. (*dir)->owner = THIS_MODULE;
  532. }
  533. /* 'info' [R] */
  534. if (info_fops) {
  535. entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
  536. if (!entry) {
  537. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  538. "create_proc_entry() failed"));
  539. } else {
  540. entry->proc_fops = info_fops;
  541. entry->data = data;
  542. entry->owner = THIS_MODULE;
  543. }
  544. }
  545. /* 'state' [R] */
  546. if (state_fops) {
  547. entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
  548. if (!entry) {
  549. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  550. "create_proc_entry() failed"));
  551. } else {
  552. entry->proc_fops = state_fops;
  553. entry->data = data;
  554. entry->owner = THIS_MODULE;
  555. }
  556. }
  557. /* 'alarm' [R/W] */
  558. if (alarm_fops) {
  559. entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
  560. if (!entry) {
  561. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  562. "create_proc_entry() failed"));
  563. } else {
  564. entry->proc_fops = alarm_fops;
  565. entry->data = data;
  566. entry->owner = THIS_MODULE;
  567. }
  568. }
  569. return 0;
  570. }
  571. static void
  572. acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
  573. struct proc_dir_entry *parent_dir)
  574. {
  575. if (*dir) {
  576. remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
  577. remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
  578. remove_proc_entry(ACPI_SBS_FILE_ALARM, *dir);
  579. remove_proc_entry((*dir)->name, parent_dir);
  580. *dir = NULL;
  581. }
  582. }
  583. /* Smart Battery Interface */
  584. static struct proc_dir_entry *acpi_battery_dir = NULL;
  585. static int acpi_battery_read_info(struct seq_file *seq, void *offset)
  586. {
  587. struct acpi_battery *battery = seq->private;
  588. struct acpi_sbs *sbs = battery->sbs;
  589. int cscale;
  590. int result = 0;
  591. if (sbs_mutex_lock(sbs)) {
  592. return -ENODEV;
  593. }
  594. result = acpi_check_update_proc(sbs);
  595. if (result)
  596. goto end;
  597. if (update_time == 0) {
  598. result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
  599. if (result) {
  600. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  601. "acpi_sbs_update_run() failed"));
  602. }
  603. }
  604. if (battery->present) {
  605. seq_printf(seq, "present: yes\n");
  606. } else {
  607. seq_printf(seq, "present: no\n");
  608. goto end;
  609. }
  610. if (battery->mode) {
  611. cscale = battery->vscale * battery->ipscale;
  612. } else {
  613. cscale = battery->ipscale;
  614. }
  615. seq_printf(seq, "design capacity: %i%s\n",
  616. battery->design_capacity * cscale,
  617. battery->mode ? "0 mWh" : " mAh");
  618. seq_printf(seq, "last full capacity: %i%s\n",
  619. battery->full_charge_capacity * cscale,
  620. battery->mode ? "0 mWh" : " mAh");
  621. seq_printf(seq, "battery technology: rechargeable\n");
  622. seq_printf(seq, "design voltage: %i mV\n",
  623. battery->design_voltage * battery->vscale);
  624. seq_printf(seq, "design capacity warning: unknown\n");
  625. seq_printf(seq, "design capacity low: unknown\n");
  626. seq_printf(seq, "capacity granularity 1: unknown\n");
  627. seq_printf(seq, "capacity granularity 2: unknown\n");
  628. seq_printf(seq, "model number: %s\n",
  629. battery->device_name);
  630. seq_printf(seq, "serial number: %i\n",
  631. battery->serial_number);
  632. seq_printf(seq, "battery type: %s\n",
  633. battery->device_chemistry);
  634. seq_printf(seq, "OEM info: %s\n",
  635. battery->manufacturer_name);
  636. end:
  637. sbs_mutex_unlock(sbs);
  638. return result;
  639. }
  640. static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
  641. {
  642. return single_open(file, acpi_battery_read_info, PDE(inode)->data);
  643. }
  644. static int acpi_battery_read_state(struct seq_file *seq, void *offset)
  645. {
  646. struct acpi_battery *battery = seq->private;
  647. struct acpi_sbs *sbs = battery->sbs;
  648. int result = 0;
  649. int cscale;
  650. int foo;
  651. if (sbs_mutex_lock(sbs)) {
  652. return -ENODEV;
  653. }
  654. result = acpi_check_update_proc(sbs);
  655. if (result)
  656. goto end;
  657. if (update_time == 0) {
  658. result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
  659. if (result) {
  660. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  661. "acpi_sbs_update_run() failed"));
  662. }
  663. }
  664. if (battery->present) {
  665. seq_printf(seq, "present: yes\n");
  666. } else {
  667. seq_printf(seq, "present: no\n");
  668. goto end;
  669. }
  670. if (battery->mode) {
  671. cscale = battery->vscale * battery->ipscale;
  672. } else {
  673. cscale = battery->ipscale;
  674. }
  675. if (battery->state & 0x0010) {
  676. seq_printf(seq, "capacity state: critical\n");
  677. } else {
  678. seq_printf(seq, "capacity state: ok\n");
  679. }
  680. foo = (s16) battery->current_now * battery->ipscale;
  681. if (battery->mode) {
  682. foo = foo * battery->design_voltage / 1000;
  683. }
  684. if (battery->current_now < 0) {
  685. seq_printf(seq, "charging state: discharging\n");
  686. seq_printf(seq, "present rate: %d %s\n",
  687. -foo, battery->mode ? "mW" : "mA");
  688. } else if (battery->current_now > 0) {
  689. seq_printf(seq, "charging state: charging\n");
  690. seq_printf(seq, "present rate: %d %s\n",
  691. foo, battery->mode ? "mW" : "mA");
  692. } else {
  693. seq_printf(seq, "charging state: charged\n");
  694. seq_printf(seq, "present rate: 0 %s\n",
  695. battery->mode ? "mW" : "mA");
  696. }
  697. seq_printf(seq, "remaining capacity: %i%s\n",
  698. battery->capacity_now * cscale,
  699. battery->mode ? "0 mWh" : " mAh");
  700. seq_printf(seq, "present voltage: %i mV\n",
  701. battery->voltage_now * battery->vscale);
  702. end:
  703. sbs_mutex_unlock(sbs);
  704. return result;
  705. }
  706. static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
  707. {
  708. return single_open(file, acpi_battery_read_state, PDE(inode)->data);
  709. }
  710. static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
  711. {
  712. struct acpi_battery *battery = seq->private;
  713. struct acpi_sbs *sbs = battery->sbs;
  714. int result = 0;
  715. int cscale;
  716. if (sbs_mutex_lock(sbs)) {
  717. return -ENODEV;
  718. }
  719. result = acpi_check_update_proc(sbs);
  720. if (result)
  721. goto end;
  722. if (update_time == 0) {
  723. result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
  724. if (result) {
  725. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  726. "acpi_sbs_update_run() failed"));
  727. }
  728. }
  729. if (!battery->present) {
  730. seq_printf(seq, "present: no\n");
  731. goto end;
  732. }
  733. if (battery->mode) {
  734. cscale = battery->vscale * battery->ipscale;
  735. } else {
  736. cscale = battery->ipscale;
  737. }
  738. seq_printf(seq, "alarm: ");
  739. if (battery->alarm_capacity) {
  740. seq_printf(seq, "%i%s\n",
  741. battery->alarm_capacity * cscale,
  742. battery->mode ? "0 mWh" : " mAh");
  743. } else {
  744. seq_printf(seq, "disabled\n");
  745. }
  746. end:
  747. sbs_mutex_unlock(sbs);
  748. return result;
  749. }
  750. static ssize_t
  751. acpi_battery_write_alarm(struct file *file, const char __user * buffer,
  752. size_t count, loff_t * ppos)
  753. {
  754. struct seq_file *seq = file->private_data;
  755. struct acpi_battery *battery = seq->private;
  756. struct acpi_sbs *sbs = battery->sbs;
  757. char alarm_string[12] = { '\0' };
  758. int result, old_alarm, new_alarm;
  759. if (sbs_mutex_lock(sbs)) {
  760. return -ENODEV;
  761. }
  762. result = acpi_check_update_proc(sbs);
  763. if (result)
  764. goto end;
  765. if (!battery->present) {
  766. result = -ENODEV;
  767. goto end;
  768. }
  769. if (count > sizeof(alarm_string) - 1) {
  770. result = -EINVAL;
  771. goto end;
  772. }
  773. if (copy_from_user(alarm_string, buffer, count)) {
  774. result = -EFAULT;
  775. goto end;
  776. }
  777. alarm_string[count] = 0;
  778. old_alarm = battery->alarm_capacity;
  779. new_alarm = simple_strtoul(alarm_string, NULL, 0);
  780. result = acpi_battery_set_alarm(battery, new_alarm);
  781. if (result) {
  782. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  783. "acpi_battery_set_alarm() failed"));
  784. acpi_battery_set_alarm(battery, old_alarm);
  785. goto end;
  786. }
  787. result = acpi_battery_get_alarm(battery);
  788. if (result) {
  789. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  790. "acpi_battery_get_alarm() failed"));
  791. acpi_battery_set_alarm(battery, old_alarm);
  792. goto end;
  793. }
  794. end:
  795. sbs_mutex_unlock(sbs);
  796. if (result) {
  797. return result;
  798. } else {
  799. return count;
  800. }
  801. }
  802. static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
  803. {
  804. return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
  805. }
  806. static struct file_operations acpi_battery_info_fops = {
  807. .open = acpi_battery_info_open_fs,
  808. .read = seq_read,
  809. .llseek = seq_lseek,
  810. .release = single_release,
  811. .owner = THIS_MODULE,
  812. };
  813. static struct file_operations acpi_battery_state_fops = {
  814. .open = acpi_battery_state_open_fs,
  815. .read = seq_read,
  816. .llseek = seq_lseek,
  817. .release = single_release,
  818. .owner = THIS_MODULE,
  819. };
  820. static struct file_operations acpi_battery_alarm_fops = {
  821. .open = acpi_battery_alarm_open_fs,
  822. .read = seq_read,
  823. .write = acpi_battery_write_alarm,
  824. .llseek = seq_lseek,
  825. .release = single_release,
  826. .owner = THIS_MODULE,
  827. };
  828. /* Legacy AC Adapter Interface */
  829. static struct proc_dir_entry *acpi_ac_dir = NULL;
  830. static int acpi_ac_read_state(struct seq_file *seq, void *offset)
  831. {
  832. struct acpi_sbs *sbs = seq->private;
  833. int result;
  834. if (sbs_mutex_lock(sbs)) {
  835. return -ENODEV;
  836. }
  837. if (update_time == 0) {
  838. result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
  839. if (result) {
  840. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  841. "acpi_sbs_update_run() failed"));
  842. }
  843. }
  844. seq_printf(seq, "state: %s\n",
  845. sbs->charger_present ? "on-line" : "off-line");
  846. sbs_mutex_unlock(sbs);
  847. return 0;
  848. }
  849. static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
  850. {
  851. return single_open(file, acpi_ac_read_state, PDE(inode)->data);
  852. }
  853. static struct file_operations acpi_ac_state_fops = {
  854. .open = acpi_ac_state_open_fs,
  855. .read = seq_read,
  856. .llseek = seq_lseek,
  857. .release = single_release,
  858. .owner = THIS_MODULE,
  859. };
  860. /* --------------------------------------------------------------------------
  861. Driver Interface
  862. -------------------------------------------------------------------------- */
  863. /* Smart Battery */
  864. static int acpi_battery_add(struct acpi_sbs *sbs, int id)
  865. {
  866. int is_present;
  867. int result;
  868. char dir_name[32];
  869. struct acpi_battery *battery;
  870. battery = &sbs->battery[id];
  871. battery->alive = 0;
  872. battery->init_state = 0;
  873. battery->id = id;
  874. battery->sbs = sbs;
  875. result = acpi_battery_select(battery);
  876. if (result) {
  877. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  878. "acpi_battery_select() failed"));
  879. goto end;
  880. }
  881. result = acpi_battery_get_present(battery);
  882. if (result) {
  883. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  884. "acpi_battery_get_present() failed"));
  885. goto end;
  886. }
  887. is_present = battery->present;
  888. if (is_present) {
  889. result = acpi_battery_init(battery);
  890. if (result) {
  891. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  892. "acpi_battery_init() failed"));
  893. goto end;
  894. }
  895. battery->init_state = 1;
  896. }
  897. sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
  898. result = acpi_sbs_generic_add_fs(&battery->proc_entry,
  899. acpi_battery_dir,
  900. dir_name,
  901. &acpi_battery_info_fops,
  902. &acpi_battery_state_fops,
  903. &acpi_battery_alarm_fops, battery);
  904. if (result) {
  905. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  906. "acpi_sbs_generic_add_fs() failed"));
  907. goto end;
  908. }
  909. battery->alive = 1;
  910. printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
  911. ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
  912. sbs->battery->present ? "present" : "absent");
  913. end:
  914. return result;
  915. }
  916. static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
  917. {
  918. if (sbs->battery[id].proc_entry) {
  919. acpi_sbs_generic_remove_fs(&(sbs->battery[id].proc_entry),
  920. acpi_battery_dir);
  921. }
  922. }
  923. static int acpi_ac_add(struct acpi_sbs *sbs)
  924. {
  925. int result;
  926. result = acpi_ac_get_present(sbs);
  927. if (result) {
  928. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  929. "acpi_ac_get_present() failed"));
  930. goto end;
  931. }
  932. result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
  933. acpi_ac_dir,
  934. ACPI_AC_DIR_NAME,
  935. NULL, &acpi_ac_state_fops, NULL, sbs);
  936. if (result) {
  937. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  938. "acpi_sbs_generic_add_fs() failed"));
  939. goto end;
  940. }
  941. printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
  942. ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
  943. ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
  944. end:
  945. return result;
  946. }
  947. static void acpi_ac_remove(struct acpi_sbs *sbs)
  948. {
  949. if (sbs->ac_entry) {
  950. acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
  951. }
  952. }
  953. static void acpi_sbs_update_time_run(unsigned long data)
  954. {
  955. acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
  956. }
  957. static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
  958. {
  959. struct acpi_battery *battery;
  960. int result = 0, cnt;
  961. int old_ac_present = -1;
  962. int old_present = -1;
  963. int new_ac_present = -1;
  964. int new_present = -1;
  965. int id_min = 0, id_max = MAX_SBS_BAT - 1;
  966. char dir_name[32];
  967. int do_battery_init = 0, do_ac_init = 0;
  968. int old_remaining_capacity = 0;
  969. int update_battery = 1;
  970. int up_tm = update_time;
  971. if (sbs_zombie(sbs)) {
  972. goto end;
  973. }
  974. if (id >= 0) {
  975. id_min = id_max = id;
  976. }
  977. if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
  978. cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
  979. if (sbs->run_cnt % cnt != 0) {
  980. update_battery = 0;
  981. }
  982. }
  983. sbs->run_cnt++;
  984. if (!update_battery) {
  985. goto end;
  986. }
  987. old_ac_present = sbs->charger_present;
  988. result = acpi_ac_get_present(sbs);
  989. if (result) {
  990. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  991. "acpi_ac_get_present() failed"));
  992. }
  993. new_ac_present = sbs->charger_present;
  994. do_ac_init = (old_ac_present != new_ac_present);
  995. if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
  996. do_ac_init = 1;
  997. }
  998. if (do_ac_init) {
  999. result = acpi_bus_generate_proc_event4(ACPI_AC_CLASS,
  1000. ACPI_AC_DIR_NAME,
  1001. ACPI_SBS_AC_NOTIFY_STATUS,
  1002. new_ac_present);
  1003. if (result) {
  1004. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1005. "acpi_bus_generate_event4() failed"));
  1006. }
  1007. acpi_bus_generate_netlink_event(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
  1008. ACPI_SBS_AC_NOTIFY_STATUS,
  1009. new_ac_present);
  1010. }
  1011. if (data_type == DATA_TYPE_COMMON) {
  1012. if (!do_ac_init && !update_battery) {
  1013. goto end;
  1014. }
  1015. }
  1016. if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
  1017. goto end;
  1018. }
  1019. for (id = id_min; id <= id_max; id++) {
  1020. battery = &sbs->battery[id];
  1021. if (battery->alive == 0) {
  1022. continue;
  1023. }
  1024. old_remaining_capacity = battery->capacity_now;
  1025. old_present = battery->present;
  1026. result = acpi_battery_select(battery);
  1027. if (result) {
  1028. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1029. "acpi_battery_select() failed"));
  1030. }
  1031. result = acpi_battery_get_present(battery);
  1032. if (result) {
  1033. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1034. "acpi_battery_get_present() failed"));
  1035. }
  1036. new_present = battery->present;
  1037. do_battery_init = ((old_present != new_present)
  1038. && new_present);
  1039. if (!new_present)
  1040. goto event;
  1041. if (do_ac_init || do_battery_init) {
  1042. result = acpi_battery_init(battery);
  1043. if (result) {
  1044. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1045. "acpi_battery_init() "
  1046. "failed"));
  1047. }
  1048. }
  1049. if (sbs_zombie(sbs)) {
  1050. goto end;
  1051. }
  1052. if ((data_type == DATA_TYPE_COMMON
  1053. || data_type == DATA_TYPE_INFO)
  1054. && new_present) {
  1055. result = acpi_battery_get_info(battery);
  1056. if (result) {
  1057. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1058. "acpi_battery_get_info() failed"));
  1059. }
  1060. }
  1061. if (data_type == DATA_TYPE_INFO) {
  1062. continue;
  1063. }
  1064. if (sbs_zombie(sbs)) {
  1065. goto end;
  1066. }
  1067. if ((data_type == DATA_TYPE_COMMON
  1068. || data_type == DATA_TYPE_STATE)
  1069. && new_present) {
  1070. result = acpi_battery_get_state(battery);
  1071. if (result) {
  1072. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1073. "acpi_battery_get_state() failed"));
  1074. }
  1075. }
  1076. if (data_type == DATA_TYPE_STATE) {
  1077. goto event;
  1078. }
  1079. if (sbs_zombie(sbs)) {
  1080. goto end;
  1081. }
  1082. if ((data_type == DATA_TYPE_COMMON
  1083. || data_type == DATA_TYPE_ALARM)
  1084. && new_present) {
  1085. result = acpi_battery_get_alarm(battery);
  1086. if (result) {
  1087. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1088. "acpi_battery_get_alarm() "
  1089. "failed"));
  1090. }
  1091. }
  1092. if (data_type == DATA_TYPE_ALARM) {
  1093. continue;
  1094. }
  1095. if (sbs_zombie(sbs)) {
  1096. goto end;
  1097. }
  1098. event:
  1099. if (old_present != new_present || do_ac_init ||
  1100. old_remaining_capacity !=
  1101. battery->capacity_now) {
  1102. sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
  1103. result = acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
  1104. dir_name,
  1105. ACPI_SBS_BATTERY_NOTIFY_STATUS,
  1106. new_present);
  1107. acpi_bus_generate_netlink_event(ACPI_BATTERY_CLASS, dir_name,
  1108. ACPI_SBS_BATTERY_NOTIFY_STATUS,
  1109. new_present);
  1110. if (result) {
  1111. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1112. "acpi_bus_generate_proc_event4() "
  1113. "failed"));
  1114. }
  1115. }
  1116. }
  1117. end:
  1118. return result;
  1119. }
  1120. static void acpi_sbs_update_time(void *data)
  1121. {
  1122. struct acpi_sbs *sbs = data;
  1123. unsigned long delay = -1;
  1124. int result;
  1125. unsigned int up_tm = update_time;
  1126. if (sbs_mutex_lock(sbs))
  1127. return;
  1128. result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
  1129. if (result) {
  1130. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1131. "acpi_sbs_update_run() failed"));
  1132. }
  1133. if (sbs_zombie(sbs)) {
  1134. goto end;
  1135. }
  1136. if (!up_tm) {
  1137. if (timer_pending(&sbs->update_timer))
  1138. del_timer(&sbs->update_timer);
  1139. } else {
  1140. delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
  1141. delay = jiffies + HZ * delay;
  1142. if (timer_pending(&sbs->update_timer)) {
  1143. mod_timer(&sbs->update_timer, delay);
  1144. } else {
  1145. sbs->update_timer.data = (unsigned long)data;
  1146. sbs->update_timer.function = acpi_sbs_update_time_run;
  1147. sbs->update_timer.expires = delay;
  1148. add_timer(&sbs->update_timer);
  1149. }
  1150. }
  1151. end:
  1152. sbs_mutex_unlock(sbs);
  1153. }
  1154. static int acpi_sbs_add(struct acpi_device *device)
  1155. {
  1156. struct acpi_sbs *sbs = NULL;
  1157. int result = 0, remove_result = 0;
  1158. int id;
  1159. sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
  1160. if (!sbs) {
  1161. ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
  1162. result = -ENOMEM;
  1163. goto end;
  1164. }
  1165. mutex_init(&sbs->mutex);
  1166. sbs_mutex_lock(sbs);
  1167. sbs->device = device;
  1168. sbs->hc = acpi_driver_data(device->parent);
  1169. strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
  1170. strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
  1171. acpi_driver_data(device) = sbs;
  1172. result = acpi_ac_add(sbs);
  1173. if (result) {
  1174. ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
  1175. goto end;
  1176. }
  1177. acpi_sbsm_get_info(sbs);
  1178. if (!sbs->manager_present) {
  1179. result = acpi_battery_add(sbs, 0);
  1180. if (result) {
  1181. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1182. "acpi_battery_add() failed"));
  1183. goto end;
  1184. }
  1185. } else {
  1186. for (id = 0; id < MAX_SBS_BAT; id++) {
  1187. if ((sbs->batteries_supported & (1 << id))) {
  1188. result = acpi_battery_add(sbs, id);
  1189. if (result) {
  1190. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1191. "acpi_battery_add() failed"));
  1192. goto end;
  1193. }
  1194. }
  1195. }
  1196. }
  1197. init_timer(&sbs->update_timer);
  1198. result = acpi_check_update_proc(sbs);
  1199. if (result)
  1200. goto end;
  1201. end:
  1202. sbs_mutex_unlock(sbs);
  1203. if (result) {
  1204. remove_result = acpi_sbs_remove(device, 0);
  1205. if (remove_result) {
  1206. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1207. "acpi_sbs_remove() failed"));
  1208. }
  1209. }
  1210. return result;
  1211. }
  1212. static int acpi_sbs_remove(struct acpi_device *device, int type)
  1213. {
  1214. struct acpi_sbs *sbs;
  1215. int id;
  1216. if (!device) {
  1217. return -EINVAL;
  1218. }
  1219. sbs = acpi_driver_data(device);
  1220. if (!sbs) {
  1221. return -EINVAL;
  1222. }
  1223. sbs_mutex_lock(sbs);
  1224. sbs->zombie = 1;
  1225. del_timer_sync(&sbs->update_timer);
  1226. acpi_os_wait_events_complete(NULL);
  1227. del_timer_sync(&sbs->update_timer);
  1228. for (id = 0; id < MAX_SBS_BAT; id++) {
  1229. acpi_battery_remove(sbs, id);
  1230. }
  1231. acpi_ac_remove(sbs);
  1232. sbs_mutex_unlock(sbs);
  1233. mutex_destroy(&sbs->mutex);
  1234. kfree(sbs);
  1235. return 0;
  1236. }
  1237. static void acpi_sbs_rmdirs(void)
  1238. {
  1239. if (acpi_ac_dir) {
  1240. acpi_unlock_ac_dir(acpi_ac_dir);
  1241. acpi_ac_dir = NULL;
  1242. }
  1243. if (acpi_battery_dir) {
  1244. acpi_unlock_battery_dir(acpi_battery_dir);
  1245. acpi_battery_dir = NULL;
  1246. }
  1247. }
  1248. static int acpi_sbs_resume(struct acpi_device *device)
  1249. {
  1250. struct acpi_sbs *sbs;
  1251. if (!device)
  1252. return -EINVAL;
  1253. sbs = device->driver_data;
  1254. sbs->run_cnt = 0;
  1255. return 0;
  1256. }
  1257. static int __init acpi_sbs_init(void)
  1258. {
  1259. int result = 0;
  1260. if (acpi_disabled)
  1261. return -ENODEV;
  1262. if (mode != DEF_CAPACITY_UNIT
  1263. && mode != MAH_CAPACITY_UNIT
  1264. && mode != MWH_CAPACITY_UNIT) {
  1265. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1266. "invalid mode = %d", mode));
  1267. return -EINVAL;
  1268. }
  1269. acpi_ac_dir = acpi_lock_ac_dir();
  1270. if (!acpi_ac_dir) {
  1271. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1272. "acpi_lock_ac_dir() failed"));
  1273. return -ENODEV;
  1274. }
  1275. acpi_battery_dir = acpi_lock_battery_dir();
  1276. if (!acpi_battery_dir) {
  1277. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1278. "acpi_lock_battery_dir() failed"));
  1279. acpi_sbs_rmdirs();
  1280. return -ENODEV;
  1281. }
  1282. result = acpi_bus_register_driver(&acpi_sbs_driver);
  1283. if (result < 0) {
  1284. ACPI_EXCEPTION((AE_INFO, AE_ERROR,
  1285. "acpi_bus_register_driver() failed"));
  1286. acpi_sbs_rmdirs();
  1287. return -ENODEV;
  1288. }
  1289. return 0;
  1290. }
  1291. static void __exit acpi_sbs_exit(void)
  1292. {
  1293. acpi_bus_unregister_driver(&acpi_sbs_driver);
  1294. acpi_sbs_rmdirs();
  1295. return;
  1296. }
  1297. module_init(acpi_sbs_init);
  1298. module_exit(acpi_sbs_exit);