thermal.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $)
  4. *
  5. * Copyright (C) 2001, 2002 Andy Grover <[email protected]>
  6. * Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]>
  7. *
  8. * This driver fully implements the ACPI thermal policy as described in the
  9. * ACPI 2.0 Specification.
  10. *
  11. * TBD: 1. Implement passive cooling hysteresis.
  12. * 2. Enhance passive cooling (CPU) states/limit interface to support
  13. * concepts of 'multiple limiters', upper/lower limits, etc.
  14. */
  15. #define pr_fmt(fmt) "ACPI: thermal: " fmt
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <linux/dmi.h>
  19. #include <linux/init.h>
  20. #include <linux/slab.h>
  21. #include <linux/types.h>
  22. #include <linux/jiffies.h>
  23. #include <linux/kmod.h>
  24. #include <linux/reboot.h>
  25. #include <linux/device.h>
  26. #include <linux/thermal.h>
  27. #include <linux/acpi.h>
  28. #include <linux/workqueue.h>
  29. #include <linux/uaccess.h>
  30. #include <linux/units.h>
  31. #define ACPI_THERMAL_CLASS "thermal_zone"
  32. #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone"
  33. #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
  34. #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81
  35. #define ACPI_THERMAL_NOTIFY_DEVICES 0x82
  36. #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0
  37. #define ACPI_THERMAL_NOTIFY_HOT 0xF1
  38. #define ACPI_THERMAL_MODE_ACTIVE 0x00
  39. #define ACPI_THERMAL_MAX_ACTIVE 10
  40. #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
  41. MODULE_AUTHOR("Paul Diefenbaugh");
  42. MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
  43. MODULE_LICENSE("GPL");
  44. static int act;
  45. module_param(act, int, 0644);
  46. MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
  47. static int crt;
  48. module_param(crt, int, 0644);
  49. MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
  50. static int tzp;
  51. module_param(tzp, int, 0444);
  52. MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
  53. static int off;
  54. module_param(off, int, 0);
  55. MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
  56. static int psv;
  57. module_param(psv, int, 0644);
  58. MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
  59. static struct workqueue_struct *acpi_thermal_pm_queue;
  60. static int acpi_thermal_add(struct acpi_device *device);
  61. static int acpi_thermal_remove(struct acpi_device *device);
  62. static void acpi_thermal_notify(struct acpi_device *device, u32 event);
  63. static const struct acpi_device_id thermal_device_ids[] = {
  64. {ACPI_THERMAL_HID, 0},
  65. {"", 0},
  66. };
  67. MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
  68. #ifdef CONFIG_PM_SLEEP
  69. static int acpi_thermal_suspend(struct device *dev);
  70. static int acpi_thermal_resume(struct device *dev);
  71. #else
  72. #define acpi_thermal_suspend NULL
  73. #define acpi_thermal_resume NULL
  74. #endif
  75. static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume);
  76. static struct acpi_driver acpi_thermal_driver = {
  77. .name = "thermal",
  78. .class = ACPI_THERMAL_CLASS,
  79. .ids = thermal_device_ids,
  80. .ops = {
  81. .add = acpi_thermal_add,
  82. .remove = acpi_thermal_remove,
  83. .notify = acpi_thermal_notify,
  84. },
  85. .drv.pm = &acpi_thermal_pm,
  86. };
  87. struct acpi_thermal_state {
  88. u8 critical:1;
  89. u8 hot:1;
  90. u8 passive:1;
  91. u8 active:1;
  92. u8 reserved:4;
  93. int active_index;
  94. };
  95. struct acpi_thermal_state_flags {
  96. u8 valid:1;
  97. u8 enabled:1;
  98. u8 reserved:6;
  99. };
  100. struct acpi_thermal_critical {
  101. struct acpi_thermal_state_flags flags;
  102. unsigned long temperature;
  103. };
  104. struct acpi_thermal_hot {
  105. struct acpi_thermal_state_flags flags;
  106. unsigned long temperature;
  107. };
  108. struct acpi_thermal_passive {
  109. struct acpi_thermal_state_flags flags;
  110. unsigned long temperature;
  111. unsigned long tc1;
  112. unsigned long tc2;
  113. unsigned long tsp;
  114. struct acpi_handle_list devices;
  115. };
  116. struct acpi_thermal_active {
  117. struct acpi_thermal_state_flags flags;
  118. unsigned long temperature;
  119. struct acpi_handle_list devices;
  120. };
  121. struct acpi_thermal_trips {
  122. struct acpi_thermal_critical critical;
  123. struct acpi_thermal_hot hot;
  124. struct acpi_thermal_passive passive;
  125. struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
  126. };
  127. struct acpi_thermal_flags {
  128. u8 cooling_mode:1; /* _SCP */
  129. u8 devices:1; /* _TZD */
  130. u8 reserved:6;
  131. };
  132. struct acpi_thermal {
  133. struct acpi_device *device;
  134. acpi_bus_id name;
  135. unsigned long temperature;
  136. unsigned long last_temperature;
  137. unsigned long polling_frequency;
  138. volatile u8 zombie;
  139. struct acpi_thermal_flags flags;
  140. struct acpi_thermal_state state;
  141. struct acpi_thermal_trips trips;
  142. struct acpi_handle_list devices;
  143. struct thermal_zone_device *thermal_zone;
  144. int kelvin_offset; /* in millidegrees */
  145. struct work_struct thermal_check_work;
  146. struct mutex thermal_check_lock;
  147. refcount_t thermal_check_count;
  148. };
  149. /* --------------------------------------------------------------------------
  150. Thermal Zone Management
  151. -------------------------------------------------------------------------- */
  152. static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
  153. {
  154. acpi_status status = AE_OK;
  155. unsigned long long tmp;
  156. if (!tz)
  157. return -EINVAL;
  158. tz->last_temperature = tz->temperature;
  159. status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
  160. if (ACPI_FAILURE(status))
  161. return -ENODEV;
  162. tz->temperature = tmp;
  163. acpi_handle_debug(tz->device->handle, "Temperature is %lu dK\n",
  164. tz->temperature);
  165. return 0;
  166. }
  167. static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
  168. {
  169. acpi_status status = AE_OK;
  170. unsigned long long tmp;
  171. if (!tz)
  172. return -EINVAL;
  173. status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
  174. if (ACPI_FAILURE(status))
  175. return -ENODEV;
  176. tz->polling_frequency = tmp;
  177. acpi_handle_debug(tz->device->handle, "Polling frequency is %lu dS\n",
  178. tz->polling_frequency);
  179. return 0;
  180. }
  181. static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
  182. {
  183. if (!tz)
  184. return -EINVAL;
  185. if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle,
  186. "_SCP", mode)))
  187. return -ENODEV;
  188. return 0;
  189. }
  190. #define ACPI_TRIPS_CRITICAL 0x01
  191. #define ACPI_TRIPS_HOT 0x02
  192. #define ACPI_TRIPS_PASSIVE 0x04
  193. #define ACPI_TRIPS_ACTIVE 0x08
  194. #define ACPI_TRIPS_DEVICES 0x10
  195. #define ACPI_TRIPS_REFRESH_THRESHOLDS (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE)
  196. #define ACPI_TRIPS_REFRESH_DEVICES ACPI_TRIPS_DEVICES
  197. #define ACPI_TRIPS_INIT (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT | \
  198. ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \
  199. ACPI_TRIPS_DEVICES)
  200. /*
  201. * This exception is thrown out in two cases:
  202. * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid
  203. * when re-evaluating the AML code.
  204. * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change.
  205. * We need to re-bind the cooling devices of a thermal zone when this occurs.
  206. */
  207. #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, tz, str) \
  208. do { \
  209. if (flags != ACPI_TRIPS_INIT) \
  210. acpi_handle_info(tz->device->handle, \
  211. "ACPI thermal trip point %s changed\n" \
  212. "Please report to [email protected]\n", str); \
  213. } while (0)
  214. static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
  215. {
  216. acpi_status status;
  217. unsigned long long tmp;
  218. struct acpi_handle_list devices;
  219. int valid = 0;
  220. int i;
  221. /* Critical Shutdown */
  222. if (flag & ACPI_TRIPS_CRITICAL) {
  223. status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp);
  224. tz->trips.critical.temperature = tmp;
  225. /*
  226. * Treat freezing temperatures as invalid as well; some
  227. * BIOSes return really low values and cause reboots at startup.
  228. * Below zero (Celsius) values clearly aren't right for sure..
  229. * ... so lets discard those as invalid.
  230. */
  231. if (ACPI_FAILURE(status)) {
  232. tz->trips.critical.flags.valid = 0;
  233. acpi_handle_debug(tz->device->handle,
  234. "No critical threshold\n");
  235. } else if (tmp <= 2732) {
  236. pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp);
  237. tz->trips.critical.flags.valid = 0;
  238. } else {
  239. tz->trips.critical.flags.valid = 1;
  240. acpi_handle_debug(tz->device->handle,
  241. "Found critical threshold [%lu]\n",
  242. tz->trips.critical.temperature);
  243. }
  244. if (tz->trips.critical.flags.valid == 1) {
  245. if (crt == -1) {
  246. tz->trips.critical.flags.valid = 0;
  247. } else if (crt > 0) {
  248. unsigned long crt_k = celsius_to_deci_kelvin(crt);
  249. /*
  250. * Allow override critical threshold
  251. */
  252. if (crt_k > tz->trips.critical.temperature)
  253. pr_info("Critical threshold %d C\n", crt);
  254. tz->trips.critical.temperature = crt_k;
  255. }
  256. }
  257. }
  258. /* Critical Sleep (optional) */
  259. if (flag & ACPI_TRIPS_HOT) {
  260. status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp);
  261. if (ACPI_FAILURE(status)) {
  262. tz->trips.hot.flags.valid = 0;
  263. acpi_handle_debug(tz->device->handle,
  264. "No hot threshold\n");
  265. } else {
  266. tz->trips.hot.temperature = tmp;
  267. tz->trips.hot.flags.valid = 1;
  268. acpi_handle_debug(tz->device->handle,
  269. "Found hot threshold [%lu]\n",
  270. tz->trips.hot.temperature);
  271. }
  272. }
  273. /* Passive (optional) */
  274. if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
  275. flag == ACPI_TRIPS_INIT) {
  276. valid = tz->trips.passive.flags.valid;
  277. if (psv == -1) {
  278. status = AE_SUPPORT;
  279. } else if (psv > 0) {
  280. tmp = celsius_to_deci_kelvin(psv);
  281. status = AE_OK;
  282. } else {
  283. status = acpi_evaluate_integer(tz->device->handle,
  284. "_PSV", NULL, &tmp);
  285. }
  286. if (ACPI_FAILURE(status)) {
  287. tz->trips.passive.flags.valid = 0;
  288. } else {
  289. tz->trips.passive.temperature = tmp;
  290. tz->trips.passive.flags.valid = 1;
  291. if (flag == ACPI_TRIPS_INIT) {
  292. status = acpi_evaluate_integer(tz->device->handle,
  293. "_TC1", NULL, &tmp);
  294. if (ACPI_FAILURE(status))
  295. tz->trips.passive.flags.valid = 0;
  296. else
  297. tz->trips.passive.tc1 = tmp;
  298. status = acpi_evaluate_integer(tz->device->handle,
  299. "_TC2", NULL, &tmp);
  300. if (ACPI_FAILURE(status))
  301. tz->trips.passive.flags.valid = 0;
  302. else
  303. tz->trips.passive.tc2 = tmp;
  304. status = acpi_evaluate_integer(tz->device->handle,
  305. "_TSP", NULL, &tmp);
  306. if (ACPI_FAILURE(status))
  307. tz->trips.passive.flags.valid = 0;
  308. else
  309. tz->trips.passive.tsp = tmp;
  310. }
  311. }
  312. }
  313. if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) {
  314. memset(&devices, 0, sizeof(struct acpi_handle_list));
  315. status = acpi_evaluate_reference(tz->device->handle, "_PSL",
  316. NULL, &devices);
  317. if (ACPI_FAILURE(status)) {
  318. acpi_handle_info(tz->device->handle,
  319. "Invalid passive threshold\n");
  320. tz->trips.passive.flags.valid = 0;
  321. } else {
  322. tz->trips.passive.flags.valid = 1;
  323. }
  324. if (memcmp(&tz->trips.passive.devices, &devices,
  325. sizeof(struct acpi_handle_list))) {
  326. memcpy(&tz->trips.passive.devices, &devices,
  327. sizeof(struct acpi_handle_list));
  328. ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
  329. }
  330. }
  331. if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) {
  332. if (valid != tz->trips.passive.flags.valid)
  333. ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state");
  334. }
  335. /* Active (optional) */
  336. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
  337. char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
  338. valid = tz->trips.active[i].flags.valid;
  339. if (act == -1)
  340. break; /* disable all active trip points */
  341. if (flag == ACPI_TRIPS_INIT || ((flag & ACPI_TRIPS_ACTIVE) &&
  342. tz->trips.active[i].flags.valid)) {
  343. status = acpi_evaluate_integer(tz->device->handle,
  344. name, NULL, &tmp);
  345. if (ACPI_FAILURE(status)) {
  346. tz->trips.active[i].flags.valid = 0;
  347. if (i == 0)
  348. break;
  349. if (act <= 0)
  350. break;
  351. if (i == 1)
  352. tz->trips.active[0].temperature = celsius_to_deci_kelvin(act);
  353. else
  354. /*
  355. * Don't allow override higher than
  356. * the next higher trip point
  357. */
  358. tz->trips.active[i-1].temperature =
  359. (tz->trips.active[i-2].temperature <
  360. celsius_to_deci_kelvin(act) ?
  361. tz->trips.active[i-2].temperature :
  362. celsius_to_deci_kelvin(act));
  363. break;
  364. } else {
  365. tz->trips.active[i].temperature = tmp;
  366. tz->trips.active[i].flags.valid = 1;
  367. }
  368. }
  369. name[2] = 'L';
  370. if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid) {
  371. memset(&devices, 0, sizeof(struct acpi_handle_list));
  372. status = acpi_evaluate_reference(tz->device->handle,
  373. name, NULL, &devices);
  374. if (ACPI_FAILURE(status)) {
  375. acpi_handle_info(tz->device->handle,
  376. "Invalid active%d threshold\n", i);
  377. tz->trips.active[i].flags.valid = 0;
  378. } else {
  379. tz->trips.active[i].flags.valid = 1;
  380. }
  381. if (memcmp(&tz->trips.active[i].devices, &devices,
  382. sizeof(struct acpi_handle_list))) {
  383. memcpy(&tz->trips.active[i].devices, &devices,
  384. sizeof(struct acpi_handle_list));
  385. ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
  386. }
  387. }
  388. if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES))
  389. if (valid != tz->trips.active[i].flags.valid)
  390. ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "state");
  391. if (!tz->trips.active[i].flags.valid)
  392. break;
  393. }
  394. if (flag & ACPI_TRIPS_DEVICES) {
  395. memset(&devices, 0, sizeof(devices));
  396. status = acpi_evaluate_reference(tz->device->handle, "_TZD",
  397. NULL, &devices);
  398. if (ACPI_SUCCESS(status) &&
  399. memcmp(&tz->devices, &devices, sizeof(devices))) {
  400. tz->devices = devices;
  401. ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device");
  402. }
  403. }
  404. return 0;
  405. }
  406. static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
  407. {
  408. int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
  409. if (ret)
  410. return ret;
  411. valid = tz->trips.critical.flags.valid |
  412. tz->trips.hot.flags.valid |
  413. tz->trips.passive.flags.valid;
  414. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
  415. valid |= tz->trips.active[i].flags.valid;
  416. if (!valid) {
  417. pr_warn(FW_BUG "No valid trip found\n");
  418. return -ENODEV;
  419. }
  420. return 0;
  421. }
  422. /* sys I/F for generic thermal sysfs support */
  423. static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp)
  424. {
  425. struct acpi_thermal *tz = thermal->devdata;
  426. int result;
  427. if (!tz)
  428. return -EINVAL;
  429. result = acpi_thermal_get_temperature(tz);
  430. if (result)
  431. return result;
  432. *temp = deci_kelvin_to_millicelsius_with_offset(tz->temperature,
  433. tz->kelvin_offset);
  434. return 0;
  435. }
  436. static int thermal_get_trip_type(struct thermal_zone_device *thermal,
  437. int trip, enum thermal_trip_type *type)
  438. {
  439. struct acpi_thermal *tz = thermal->devdata;
  440. int i;
  441. if (!tz || trip < 0)
  442. return -EINVAL;
  443. if (tz->trips.critical.flags.valid) {
  444. if (!trip) {
  445. *type = THERMAL_TRIP_CRITICAL;
  446. return 0;
  447. }
  448. trip--;
  449. }
  450. if (tz->trips.hot.flags.valid) {
  451. if (!trip) {
  452. *type = THERMAL_TRIP_HOT;
  453. return 0;
  454. }
  455. trip--;
  456. }
  457. if (tz->trips.passive.flags.valid) {
  458. if (!trip) {
  459. *type = THERMAL_TRIP_PASSIVE;
  460. return 0;
  461. }
  462. trip--;
  463. }
  464. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++) {
  465. if (!trip) {
  466. *type = THERMAL_TRIP_ACTIVE;
  467. return 0;
  468. }
  469. trip--;
  470. }
  471. return -EINVAL;
  472. }
  473. static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
  474. int trip, int *temp)
  475. {
  476. struct acpi_thermal *tz = thermal->devdata;
  477. int i;
  478. if (!tz || trip < 0)
  479. return -EINVAL;
  480. if (tz->trips.critical.flags.valid) {
  481. if (!trip) {
  482. *temp = deci_kelvin_to_millicelsius_with_offset(
  483. tz->trips.critical.temperature,
  484. tz->kelvin_offset);
  485. return 0;
  486. }
  487. trip--;
  488. }
  489. if (tz->trips.hot.flags.valid) {
  490. if (!trip) {
  491. *temp = deci_kelvin_to_millicelsius_with_offset(
  492. tz->trips.hot.temperature,
  493. tz->kelvin_offset);
  494. return 0;
  495. }
  496. trip--;
  497. }
  498. if (tz->trips.passive.flags.valid) {
  499. if (!trip) {
  500. *temp = deci_kelvin_to_millicelsius_with_offset(
  501. tz->trips.passive.temperature,
  502. tz->kelvin_offset);
  503. return 0;
  504. }
  505. trip--;
  506. }
  507. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
  508. tz->trips.active[i].flags.valid; i++) {
  509. if (!trip) {
  510. *temp = deci_kelvin_to_millicelsius_with_offset(
  511. tz->trips.active[i].temperature,
  512. tz->kelvin_offset);
  513. return 0;
  514. }
  515. trip--;
  516. }
  517. return -EINVAL;
  518. }
  519. static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
  520. int *temperature)
  521. {
  522. struct acpi_thermal *tz = thermal->devdata;
  523. if (tz->trips.critical.flags.valid) {
  524. *temperature = deci_kelvin_to_millicelsius_with_offset(
  525. tz->trips.critical.temperature,
  526. tz->kelvin_offset);
  527. return 0;
  528. }
  529. return -EINVAL;
  530. }
  531. static int thermal_get_trend(struct thermal_zone_device *thermal,
  532. int trip, enum thermal_trend *trend)
  533. {
  534. struct acpi_thermal *tz = thermal->devdata;
  535. enum thermal_trip_type type;
  536. int i;
  537. if (thermal_get_trip_type(thermal, trip, &type))
  538. return -EINVAL;
  539. if (type == THERMAL_TRIP_ACTIVE) {
  540. int trip_temp;
  541. int temp = deci_kelvin_to_millicelsius_with_offset(
  542. tz->temperature, tz->kelvin_offset);
  543. if (thermal_get_trip_temp(thermal, trip, &trip_temp))
  544. return -EINVAL;
  545. if (temp > trip_temp) {
  546. *trend = THERMAL_TREND_RAISING;
  547. return 0;
  548. } else {
  549. /* Fall back on default trend */
  550. return -EINVAL;
  551. }
  552. }
  553. /*
  554. * tz->temperature has already been updated by generic thermal layer,
  555. * before this callback being invoked
  556. */
  557. i = tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature) +
  558. tz->trips.passive.tc2 * (tz->temperature - tz->trips.passive.temperature);
  559. if (i > 0)
  560. *trend = THERMAL_TREND_RAISING;
  561. else if (i < 0)
  562. *trend = THERMAL_TREND_DROPPING;
  563. else
  564. *trend = THERMAL_TREND_STABLE;
  565. return 0;
  566. }
  567. static void acpi_thermal_zone_device_hot(struct thermal_zone_device *thermal)
  568. {
  569. struct acpi_thermal *tz = thermal->devdata;
  570. acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
  571. dev_name(&tz->device->dev),
  572. ACPI_THERMAL_NOTIFY_HOT, 1);
  573. }
  574. static void acpi_thermal_zone_device_critical(struct thermal_zone_device *thermal)
  575. {
  576. struct acpi_thermal *tz = thermal->devdata;
  577. acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
  578. dev_name(&tz->device->dev),
  579. ACPI_THERMAL_NOTIFY_CRITICAL, 1);
  580. thermal_zone_device_critical(thermal);
  581. }
  582. static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
  583. struct thermal_cooling_device *cdev,
  584. bool bind)
  585. {
  586. struct acpi_device *device = cdev->devdata;
  587. struct acpi_thermal *tz = thermal->devdata;
  588. struct acpi_device *dev;
  589. acpi_handle handle;
  590. int i;
  591. int j;
  592. int trip = -1;
  593. int result = 0;
  594. if (tz->trips.critical.flags.valid)
  595. trip++;
  596. if (tz->trips.hot.flags.valid)
  597. trip++;
  598. if (tz->trips.passive.flags.valid) {
  599. trip++;
  600. for (i = 0; i < tz->trips.passive.devices.count; i++) {
  601. handle = tz->trips.passive.devices.handles[i];
  602. dev = acpi_fetch_acpi_dev(handle);
  603. if (dev != device)
  604. continue;
  605. if (bind)
  606. result = thermal_zone_bind_cooling_device(
  607. thermal, trip, cdev,
  608. THERMAL_NO_LIMIT,
  609. THERMAL_NO_LIMIT,
  610. THERMAL_WEIGHT_DEFAULT);
  611. else
  612. result =
  613. thermal_zone_unbind_cooling_device(
  614. thermal, trip, cdev);
  615. if (result)
  616. goto failed;
  617. }
  618. }
  619. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
  620. if (!tz->trips.active[i].flags.valid)
  621. break;
  622. trip++;
  623. for (j = 0; j < tz->trips.active[i].devices.count; j++) {
  624. handle = tz->trips.active[i].devices.handles[j];
  625. dev = acpi_fetch_acpi_dev(handle);
  626. if (dev != device)
  627. continue;
  628. if (bind)
  629. result = thermal_zone_bind_cooling_device(
  630. thermal, trip, cdev,
  631. THERMAL_NO_LIMIT,
  632. THERMAL_NO_LIMIT,
  633. THERMAL_WEIGHT_DEFAULT);
  634. else
  635. result = thermal_zone_unbind_cooling_device(
  636. thermal, trip, cdev);
  637. if (result)
  638. goto failed;
  639. }
  640. }
  641. failed:
  642. return result;
  643. }
  644. static int
  645. acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
  646. struct thermal_cooling_device *cdev)
  647. {
  648. return acpi_thermal_cooling_device_cb(thermal, cdev, true);
  649. }
  650. static int
  651. acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
  652. struct thermal_cooling_device *cdev)
  653. {
  654. return acpi_thermal_cooling_device_cb(thermal, cdev, false);
  655. }
  656. static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
  657. .bind = acpi_thermal_bind_cooling_device,
  658. .unbind = acpi_thermal_unbind_cooling_device,
  659. .get_temp = thermal_get_temp,
  660. .get_trip_type = thermal_get_trip_type,
  661. .get_trip_temp = thermal_get_trip_temp,
  662. .get_crit_temp = thermal_get_crit_temp,
  663. .get_trend = thermal_get_trend,
  664. .hot = acpi_thermal_zone_device_hot,
  665. .critical = acpi_thermal_zone_device_critical,
  666. };
  667. static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
  668. {
  669. int trips = 0;
  670. int result;
  671. acpi_status status;
  672. int i;
  673. if (tz->trips.critical.flags.valid)
  674. trips++;
  675. if (tz->trips.hot.flags.valid)
  676. trips++;
  677. if (tz->trips.passive.flags.valid)
  678. trips++;
  679. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid;
  680. i++, trips++);
  681. if (tz->trips.passive.flags.valid)
  682. tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz,
  683. &acpi_thermal_zone_ops, NULL,
  684. tz->trips.passive.tsp * 100,
  685. tz->polling_frequency * 100);
  686. else
  687. tz->thermal_zone =
  688. thermal_zone_device_register("acpitz", trips, 0, tz,
  689. &acpi_thermal_zone_ops, NULL,
  690. 0, tz->polling_frequency * 100);
  691. if (IS_ERR(tz->thermal_zone))
  692. return -ENODEV;
  693. result = sysfs_create_link(&tz->device->dev.kobj,
  694. &tz->thermal_zone->device.kobj, "thermal_zone");
  695. if (result)
  696. goto unregister_tzd;
  697. result = sysfs_create_link(&tz->thermal_zone->device.kobj,
  698. &tz->device->dev.kobj, "device");
  699. if (result)
  700. goto remove_tz_link;
  701. status = acpi_bus_attach_private_data(tz->device->handle,
  702. tz->thermal_zone);
  703. if (ACPI_FAILURE(status)) {
  704. result = -ENODEV;
  705. goto remove_dev_link;
  706. }
  707. result = thermal_zone_device_enable(tz->thermal_zone);
  708. if (result)
  709. goto acpi_bus_detach;
  710. dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
  711. tz->thermal_zone->id);
  712. return 0;
  713. acpi_bus_detach:
  714. acpi_bus_detach_private_data(tz->device->handle);
  715. remove_dev_link:
  716. sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
  717. remove_tz_link:
  718. sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
  719. unregister_tzd:
  720. thermal_zone_device_unregister(tz->thermal_zone);
  721. return result;
  722. }
  723. static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
  724. {
  725. sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
  726. sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
  727. thermal_zone_device_unregister(tz->thermal_zone);
  728. tz->thermal_zone = NULL;
  729. acpi_bus_detach_private_data(tz->device->handle);
  730. }
  731. /* --------------------------------------------------------------------------
  732. Driver Interface
  733. -------------------------------------------------------------------------- */
  734. static void acpi_queue_thermal_check(struct acpi_thermal *tz)
  735. {
  736. if (!work_pending(&tz->thermal_check_work))
  737. queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
  738. }
  739. static void acpi_thermal_notify(struct acpi_device *device, u32 event)
  740. {
  741. struct acpi_thermal *tz = acpi_driver_data(device);
  742. if (!tz)
  743. return;
  744. switch (event) {
  745. case ACPI_THERMAL_NOTIFY_TEMPERATURE:
  746. acpi_queue_thermal_check(tz);
  747. break;
  748. case ACPI_THERMAL_NOTIFY_THRESHOLDS:
  749. acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
  750. acpi_queue_thermal_check(tz);
  751. acpi_bus_generate_netlink_event(device->pnp.device_class,
  752. dev_name(&device->dev), event, 0);
  753. break;
  754. case ACPI_THERMAL_NOTIFY_DEVICES:
  755. acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
  756. acpi_queue_thermal_check(tz);
  757. acpi_bus_generate_netlink_event(device->pnp.device_class,
  758. dev_name(&device->dev), event, 0);
  759. break;
  760. default:
  761. acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n",
  762. event);
  763. break;
  764. }
  765. }
  766. /*
  767. * On some platforms, the AML code has dependency about
  768. * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx.
  769. * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after
  770. * /_CRT/_HOT/_PSV/_ACx, or else system will be power off.
  771. * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0
  772. * if _TMP has never been evaluated.
  773. *
  774. * As this dependency is totally transparent to OS, evaluate
  775. * all of them once, in the order of _CRT/_HOT/_PSV/_ACx,
  776. * _TMP, before they are actually used.
  777. */
  778. static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
  779. {
  780. acpi_handle handle = tz->device->handle;
  781. unsigned long long value;
  782. int i;
  783. acpi_evaluate_integer(handle, "_CRT", NULL, &value);
  784. acpi_evaluate_integer(handle, "_HOT", NULL, &value);
  785. acpi_evaluate_integer(handle, "_PSV", NULL, &value);
  786. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
  787. char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
  788. acpi_status status;
  789. status = acpi_evaluate_integer(handle, name, NULL, &value);
  790. if (status == AE_NOT_FOUND)
  791. break;
  792. }
  793. acpi_evaluate_integer(handle, "_TMP", NULL, &value);
  794. }
  795. static int acpi_thermal_get_info(struct acpi_thermal *tz)
  796. {
  797. int result;
  798. if (!tz)
  799. return -EINVAL;
  800. acpi_thermal_aml_dependency_fix(tz);
  801. /* Get trip points [_CRT, _PSV, etc.] (required) */
  802. result = acpi_thermal_get_trip_points(tz);
  803. if (result)
  804. return result;
  805. /* Get temperature [_TMP] (required) */
  806. result = acpi_thermal_get_temperature(tz);
  807. if (result)
  808. return result;
  809. /* Set the cooling mode [_SCP] to active cooling (default) */
  810. result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
  811. if (!result)
  812. tz->flags.cooling_mode = 1;
  813. /* Get default polling frequency [_TZP] (optional) */
  814. if (tzp)
  815. tz->polling_frequency = tzp;
  816. else
  817. acpi_thermal_get_polling_frequency(tz);
  818. return 0;
  819. }
  820. /*
  821. * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
  822. * handles temperature values with a single decimal place. As a consequence,
  823. * some implementations use an offset of 273.1 and others use an offset of
  824. * 273.2. Try to find out which one is being used, to present the most
  825. * accurate and visually appealing number.
  826. *
  827. * The heuristic below should work for all ACPI thermal zones which have a
  828. * critical trip point with a value being a multiple of 0.5 degree Celsius.
  829. */
  830. static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
  831. {
  832. if (tz->trips.critical.flags.valid &&
  833. (tz->trips.critical.temperature % 5) == 1)
  834. tz->kelvin_offset = 273100;
  835. else
  836. tz->kelvin_offset = 273200;
  837. }
  838. static void acpi_thermal_check_fn(struct work_struct *work)
  839. {
  840. struct acpi_thermal *tz = container_of(work, struct acpi_thermal,
  841. thermal_check_work);
  842. /*
  843. * In general, it is not sufficient to check the pending bit, because
  844. * subsequent instances of this function may be queued after one of them
  845. * has started running (e.g. if _TMP sleeps). Avoid bailing out if just
  846. * one of them is running, though, because it may have done the actual
  847. * check some time ago, so allow at least one of them to block on the
  848. * mutex while another one is running the update.
  849. */
  850. if (!refcount_dec_not_one(&tz->thermal_check_count))
  851. return;
  852. mutex_lock(&tz->thermal_check_lock);
  853. thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED);
  854. refcount_inc(&tz->thermal_check_count);
  855. mutex_unlock(&tz->thermal_check_lock);
  856. }
  857. static int acpi_thermal_add(struct acpi_device *device)
  858. {
  859. struct acpi_thermal *tz;
  860. int result;
  861. if (!device)
  862. return -EINVAL;
  863. tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
  864. if (!tz)
  865. return -ENOMEM;
  866. tz->device = device;
  867. strcpy(tz->name, device->pnp.bus_id);
  868. strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
  869. strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
  870. device->driver_data = tz;
  871. result = acpi_thermal_get_info(tz);
  872. if (result)
  873. goto free_memory;
  874. acpi_thermal_guess_offset(tz);
  875. result = acpi_thermal_register_thermal_zone(tz);
  876. if (result)
  877. goto free_memory;
  878. refcount_set(&tz->thermal_check_count, 3);
  879. mutex_init(&tz->thermal_check_lock);
  880. INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn);
  881. pr_info("%s [%s] (%ld C)\n", acpi_device_name(device),
  882. acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature));
  883. goto end;
  884. free_memory:
  885. kfree(tz);
  886. end:
  887. return result;
  888. }
  889. static int acpi_thermal_remove(struct acpi_device *device)
  890. {
  891. struct acpi_thermal *tz;
  892. if (!device || !acpi_driver_data(device))
  893. return -EINVAL;
  894. flush_workqueue(acpi_thermal_pm_queue);
  895. tz = acpi_driver_data(device);
  896. acpi_thermal_unregister_thermal_zone(tz);
  897. kfree(tz);
  898. return 0;
  899. }
  900. #ifdef CONFIG_PM_SLEEP
  901. static int acpi_thermal_suspend(struct device *dev)
  902. {
  903. /* Make sure the previously queued thermal check work has been done */
  904. flush_workqueue(acpi_thermal_pm_queue);
  905. return 0;
  906. }
  907. static int acpi_thermal_resume(struct device *dev)
  908. {
  909. struct acpi_thermal *tz;
  910. int i, j, power_state, result;
  911. if (!dev)
  912. return -EINVAL;
  913. tz = acpi_driver_data(to_acpi_device(dev));
  914. if (!tz)
  915. return -EINVAL;
  916. for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
  917. if (!tz->trips.active[i].flags.valid)
  918. break;
  919. tz->trips.active[i].flags.enabled = 1;
  920. for (j = 0; j < tz->trips.active[i].devices.count; j++) {
  921. result = acpi_bus_update_power(
  922. tz->trips.active[i].devices.handles[j],
  923. &power_state);
  924. if (result || (power_state != ACPI_STATE_D0)) {
  925. tz->trips.active[i].flags.enabled = 0;
  926. break;
  927. }
  928. }
  929. tz->state.active |= tz->trips.active[i].flags.enabled;
  930. }
  931. acpi_queue_thermal_check(tz);
  932. return AE_OK;
  933. }
  934. #endif
  935. static int thermal_act(const struct dmi_system_id *d) {
  936. if (act == 0) {
  937. pr_notice("%s detected: disabling all active thermal trip points\n",
  938. d->ident);
  939. act = -1;
  940. }
  941. return 0;
  942. }
  943. static int thermal_nocrt(const struct dmi_system_id *d) {
  944. pr_notice("%s detected: disabling all critical thermal trip point actions.\n",
  945. d->ident);
  946. crt = -1;
  947. return 0;
  948. }
  949. static int thermal_tzp(const struct dmi_system_id *d) {
  950. if (tzp == 0) {
  951. pr_notice("%s detected: enabling thermal zone polling\n",
  952. d->ident);
  953. tzp = 300; /* 300 dS = 30 Seconds */
  954. }
  955. return 0;
  956. }
  957. static int thermal_psv(const struct dmi_system_id *d) {
  958. if (psv == 0) {
  959. pr_notice("%s detected: disabling all passive thermal trip points\n",
  960. d->ident);
  961. psv = -1;
  962. }
  963. return 0;
  964. }
  965. static const struct dmi_system_id thermal_dmi_table[] __initconst = {
  966. /*
  967. * Award BIOS on this AOpen makes thermal control almost worthless.
  968. * http://bugzilla.kernel.org/show_bug.cgi?id=8842
  969. */
  970. {
  971. .callback = thermal_act,
  972. .ident = "AOpen i915GMm-HFS",
  973. .matches = {
  974. DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
  975. DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
  976. },
  977. },
  978. {
  979. .callback = thermal_psv,
  980. .ident = "AOpen i915GMm-HFS",
  981. .matches = {
  982. DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
  983. DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
  984. },
  985. },
  986. {
  987. .callback = thermal_tzp,
  988. .ident = "AOpen i915GMm-HFS",
  989. .matches = {
  990. DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
  991. DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
  992. },
  993. },
  994. {
  995. .callback = thermal_nocrt,
  996. .ident = "Gigabyte GA-7ZX",
  997. .matches = {
  998. DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
  999. DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
  1000. },
  1001. },
  1002. {}
  1003. };
  1004. static int __init acpi_thermal_init(void)
  1005. {
  1006. int result;
  1007. dmi_check_system(thermal_dmi_table);
  1008. if (off) {
  1009. pr_notice("thermal control disabled\n");
  1010. return -ENODEV;
  1011. }
  1012. acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm",
  1013. WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
  1014. if (!acpi_thermal_pm_queue)
  1015. return -ENODEV;
  1016. result = acpi_bus_register_driver(&acpi_thermal_driver);
  1017. if (result < 0) {
  1018. destroy_workqueue(acpi_thermal_pm_queue);
  1019. return -ENODEV;
  1020. }
  1021. return 0;
  1022. }
  1023. static void __exit acpi_thermal_exit(void)
  1024. {
  1025. acpi_bus_unregister_driver(&acpi_thermal_driver);
  1026. destroy_workqueue(acpi_thermal_pm_queue);
  1027. }
  1028. module_init(acpi_thermal_init);
  1029. module_exit(acpi_thermal_exit);