sbs.c 36 KB

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