tzpolicy.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /****************************************************************************
  2.  *
  3.  * Module Name: tzpolicy.c -
  4.  *   $Revision: 30 $
  5.  *
  6.  ****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 Andrew Grover
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. /*
  25.  * TBD: 1. Support performance-limit control for non-processor devices
  26.  *         (those listed in _TZD, e.g. graphics).
  27.  */
  28. #include <linux/proc_fs.h>
  29. #include <linux/sysctl.h>
  30. #include <linux/pm.h>
  31. #include <acpi.h>
  32. #include <bm.h>
  33. #include "tz.h"
  34. #define _COMPONENT ACPI_THERMAL
  35. MODULE_NAME ("tzpolicy")
  36. /****************************************************************************
  37.  *                                  Globals
  38.  ****************************************************************************/
  39. void
  40. tz_policy_run (
  41. unsigned long           data);
  42. /****************************************************************************
  43.  *                              Internal Functions
  44.  ****************************************************************************/
  45. acpi_status
  46. set_performance_limit (
  47. BM_HANDLE               device_handle,
  48. u32 flag)
  49. {
  50. acpi_status             status;
  51. BM_REQUEST              request;
  52. request.status = AE_OK;
  53. request.handle = device_handle;
  54. request.command = PR_COMMAND_SET_PERF_LIMIT;
  55. request.buffer.length = sizeof(u32);
  56. request.buffer.pointer = &flag;
  57. status = bm_request(&request);
  58. if (ACPI_FAILURE(status))
  59. return status;
  60. else
  61. return request.status;
  62. }
  63. /****************************************************************************
  64.  *
  65.  * FUNCTION:    tz_policy_critical
  66.  *
  67.  * PARAMETERS:
  68.  *
  69.  * RETURN:
  70.  *
  71.  * DESCRIPTION:
  72.  *
  73.  ****************************************************************************/
  74. acpi_status
  75. tz_policy_critical(
  76. TZ_CONTEXT *tz)
  77. {
  78. FUNCTION_TRACE("tz_policy_critical");
  79. if (!tz) {
  80. return_ACPI_STATUS(AE_BAD_PARAMETER);
  81. }
  82. if (tz->policy.temperature >= tz->policy.thresholds.critical.temperature) {
  83. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Critical (S5) threshold reached.n"));
  84. /* TBD: Need method for shutting down system. */
  85. }
  86. return_ACPI_STATUS(AE_OK);
  87. }
  88. /****************************************************************************
  89.  *
  90.  * FUNCTION:    tz_policy_hot
  91.  *
  92.  * PARAMETERS:
  93.  *
  94.  * RETURN:
  95.  *
  96.  * DESCRIPTION:
  97.  *
  98.  ****************************************************************************/
  99. acpi_status
  100. tz_policy_hot(
  101. TZ_CONTEXT *tz)
  102. {
  103. FUNCTION_TRACE("tz_policy_hot");
  104. if (!tz || !tz->policy.thresholds.hot.is_valid) {
  105. return_ACPI_STATUS(AE_BAD_PARAMETER);
  106. }
  107. if (tz->policy.temperature >= tz->policy.thresholds.hot.temperature) {
  108. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Critical (S4) threshold reached.n"));
  109. /* TBD: Need method for invoking OS-level critical suspend. */
  110. }
  111. return_ACPI_STATUS(AE_OK);
  112. }
  113. /****************************************************************************
  114.  *
  115.  * FUNCTION:    tz_policy_passive
  116.  *
  117.  * PARAMETERS:
  118.  *
  119.  * RETURN:
  120.  *
  121.  * DESCRIPTION:
  122.  *
  123.  ****************************************************************************/
  124. acpi_status
  125. tz_policy_passive(
  126. TZ_CONTEXT *tz)
  127. {
  128. TZ_PASSIVE_THRESHOLD *passive = NULL;
  129. static u32 last_temperature = 0;
  130. s32 trend = 0;
  131. u32 i = 0;
  132. FUNCTION_TRACE("tz_policy_passive");
  133. if (!tz || !tz->policy.thresholds.passive.is_valid) {
  134. return_ACPI_STATUS(AE_BAD_PARAMETER);
  135. }
  136. passive = &(tz->policy.thresholds.passive);
  137. if (tz->policy.temperature >= passive->temperature) {
  138. /*
  139.  * Thermal trend?
  140.  * --------------
  141.  * Using the passive cooling equation (see the ACPI
  142.  * Specification), calculate the current thermal trend
  143.  * (a.k.a. performance delta).
  144.  */
  145. trend = passive->tc1 * (tz->policy.temperature - last_temperature) + passive->tc2 * (tz->policy.temperature - passive->temperature);
  146. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "trend[%d] = TC1[%d]*(temp[%d]-last[%d]) + TC2[%d]*(temp[%d]-passive[%d])n", trend, passive->tc1, tz->policy.temperature, last_temperature, passive->tc2, tz->policy.temperature, passive->temperature));
  147. last_temperature = tz->policy.temperature;
  148. /*
  149.  * Heating Up?
  150.  * -----------
  151.  * Decrease thermal performance limit on all passive
  152.  * cooling devices (processors).
  153.  */
  154. if (trend > 0) {
  155. for (i=0; i<passive->devices.count; i++)
  156. set_performance_limit(passive->devices.handles[i], PR_PERF_DEC);
  157. }
  158. /*
  159.  * Cooling Off?
  160.  * ------------
  161.  * Increase thermal performance limit on all passive
  162.  * cooling devices (processors).
  163.  */
  164. else if (trend < 0) {
  165. for (i=0; i<passive->devices.count; i++)
  166. set_performance_limit(passive->devices.handles[i], PR_PERF_INC);
  167. }
  168. }
  169. return_ACPI_STATUS(AE_OK);
  170. }
  171. /****************************************************************************
  172.  *
  173.  * FUNCTION:    tz_policy_active
  174.  *
  175.  * PARAMETERS:
  176.  *
  177.  * RETURN:
  178.  *
  179.  * DESCRIPTION:
  180.  *
  181.  ****************************************************************************/
  182. acpi_status
  183. tz_policy_active(
  184. TZ_CONTEXT              *tz)
  185. {
  186. acpi_status             status = AE_OK;
  187. TZ_ACTIVE_THRESHOLD *active = NULL;
  188. u32                     i,j = 0;
  189. FUNCTION_TRACE("tz_policy_active");
  190. if (!tz || !tz->policy.thresholds.active[0].is_valid) {
  191. return_ACPI_STATUS(AE_BAD_PARAMETER);
  192. }
  193. for (i=0; i<TZ_MAX_ACTIVE_THRESHOLDS; i++) {
  194. active = &(tz->policy.thresholds.active[i]);
  195. if (!active || !active->is_valid)
  196. break;
  197. /*
  198.  * Above Threshold?
  199.  * ----------------
  200.  * If not already enabled, turn ON all cooling devices
  201.  * associated with this active threshold.
  202.  */
  203. if ((tz->policy.temperature >= active->temperature) && (active->cooling_state != TZ_COOLING_ENABLED)) {
  204. for (j = 0; j < active->devices.count; j++) {
  205. status = bm_set_device_power_state(active->devices.handles[j], ACPI_STATE_D0);
  206. if (ACPI_SUCCESS(status)) {
  207. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Cooling device [%02x] now ON.n", active->devices.handles[j]));
  208. }
  209. else {
  210. ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Unable to turn ON cooling device [%02x].n", active->devices.handles[j]));
  211. }
  212. }
  213.    active->cooling_state = TZ_COOLING_ENABLED;
  214. }
  215. /*
  216.  * Below Threshold?
  217.  * ----------------
  218.  * Turn OFF all cooling devices associated with this
  219.  * threshold.  Note that by checking "if not disabled" we
  220.  * turn off all cooling devices for thresholds in the
  221.  * TZ_COOLING_STATE_UNKNOWN state, useful as a level-set
  222.  * during the first pass.
  223.  */
  224. else if (active->cooling_state != TZ_COOLING_DISABLED) {
  225. for (j = 0; j < active->devices.count; j++) {
  226. status = bm_set_device_power_state(active->devices.handles[j], ACPI_STATE_D3);
  227. if (ACPI_SUCCESS(status)) {
  228. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Cooling device [%02x] now OFF.n", active->devices.handles[j]));
  229. }
  230. else {
  231. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unable to turn OFF cooling device [%02x].n", active->devices.handles[j]));
  232. }
  233. }
  234. active->cooling_state = TZ_COOLING_DISABLED;
  235. }
  236. }
  237. return_ACPI_STATUS(AE_OK);
  238. }
  239. /****************************************************************************
  240.  *
  241.  * FUNCTION:    tz_policy_check
  242.  *
  243.  * PARAMETERS:
  244.  *
  245.  * RETURN:
  246.  *
  247.  * DESCRIPTION: Note that this function will get called whenever:
  248.  *                1. A thermal event occurs.
  249.  *                2. The polling/sampling time period expires.
  250.  *
  251.  ****************************************************************************/
  252. void
  253. tz_policy_check (
  254. void                    *context)
  255. {
  256. acpi_status             status = AE_OK;
  257. TZ_CONTEXT              *tz = NULL;
  258. TZ_POLICY *policy = NULL;
  259. TZ_THRESHOLDS *thresholds = NULL;
  260. u32                     previous_temperature = 0;
  261. u32                     previous_state = 0;
  262. u32                     active_index = 0;
  263. u32                     i = 0;
  264. u32                     sleep_time = 0;
  265. FUNCTION_TRACE("tz_policy_check");
  266. if (!context) {
  267. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.n"));
  268. return_VOID;
  269. }
  270. tz = (TZ_CONTEXT*)context;
  271. policy = &(tz->policy);
  272. thresholds = &(tz->policy.thresholds);
  273. /*
  274.  * Preserve Previous State:
  275.  * ------------------------
  276.  */
  277. previous_temperature = tz->policy.temperature;
  278. previous_state = tz->policy.state;
  279. /*
  280.  * Get Temperature:
  281.  * ----------------
  282.  */
  283. status = tz_get_temperature(tz);
  284. if (ACPI_FAILURE(status)) {
  285. return_VOID;
  286. }
  287. /*
  288.  * Calculate State:
  289.  * ----------------
  290.  */
  291. policy->state = TZ_STATE_OK;
  292. /* Critical? */
  293. if (policy->temperature >= thresholds->critical.temperature)
  294. policy->state |= TZ_STATE_CRITICAL;
  295. /* Hot? */
  296. if ((thresholds->hot.is_valid) &&  (policy->temperature >= thresholds->hot.temperature))
  297. policy->state |= TZ_STATE_CRITICAL;
  298. /* Passive? */
  299. if ((thresholds->passive.is_valid) && (policy->temperature >= thresholds->passive.temperature))
  300. policy->state |= TZ_STATE_PASSIVE;
  301. /* Active? */
  302. if (thresholds->active[0].is_valid) {
  303. for (i=0; i<TZ_MAX_ACTIVE_THRESHOLDS; i++) {
  304. if ((thresholds->active[i].is_valid) && (policy->temperature >= thresholds->active[i].temperature)) {
  305. policy->state |= TZ_STATE_ACTIVE;
  306. if (i > active_index)
  307. active_index = i;
  308. }
  309. }
  310. policy->state |= active_index;
  311. }
  312. /*
  313.  * Invoke Policy:
  314.  * --------------
  315.  * Note that policy must be invoked both when 'going into' a
  316.  * policy state (e.g. to allow fans to be turned on) and 'going
  317.  * out of' a policy state (e.g. to allow fans to be turned off);
  318.  * thus we must preserve the previous state.
  319.  */
  320. if (policy->state & TZ_STATE_CRITICAL)
  321. tz_policy_critical(tz);
  322. if (policy->state & TZ_STATE_HOT)
  323. tz_policy_hot(tz);
  324. if ((policy->state & TZ_STATE_PASSIVE) || (previous_state & TZ_STATE_PASSIVE))
  325. tz_policy_passive(tz);
  326. if ((policy->state & TZ_STATE_ACTIVE) || (previous_state & TZ_STATE_ACTIVE))
  327. tz_policy_active(tz);
  328. /*
  329.  * Calculate Sleep Time:
  330.  * ---------------------
  331.  * If we're in the passive state, use _TSP's value.  Otherwise
  332.  * use _TZP or the OS's default polling frequency.  If no polling
  333.  * frequency is specified then we'll wait forever (that is, until
  334.  * a thermal event occurs -- e.g. never poll).  Note that _TSP
  335.  * and _TZD values are given in 1/10th seconds.
  336.  */
  337. if (policy->state & TZ_STATE_PASSIVE)
  338. sleep_time = thresholds->passive.tsp * 100;
  339. else if (policy->polling_freq > 0)
  340. sleep_time = policy->polling_freq * 100;
  341. else
  342. sleep_time = WAIT_FOREVER;
  343. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Thermal_zone[%02x]: temperature[%d] state[%08x]n", tz->device_handle, policy->temperature, policy->state));
  344. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling next poll in [%d]ms.n", sleep_time));
  345. /*
  346.  * Schedule Next Poll:
  347.  * -------------------
  348.  */
  349. if (sleep_time < WAIT_FOREVER) {
  350. if (timer_pending(&(policy->timer)))
  351. mod_timer(&(policy->timer), (HZ*sleep_time)/1000);
  352. else {
  353. policy->timer.data = (unsigned long)tz;
  354. policy->timer.function = tz_policy_run;
  355. policy->timer.expires = jiffies + (HZ*sleep_time)/1000;
  356. add_timer(&(policy->timer));
  357. }
  358. }
  359. else {
  360. if (timer_pending(&(policy->timer)))
  361. del_timer(&(policy->timer));
  362. }
  363. return_VOID;
  364. }
  365. /****************************************************************************
  366.  *
  367.  * FUNCTION:    tz_policy_run
  368.  *
  369.  * PARAMETERS:
  370.  *
  371.  * RETURN:
  372.  *
  373.  * DESCRIPTION:
  374.  *
  375.  ****************************************************************************/
  376. void
  377. tz_policy_run (
  378. unsigned long           data)
  379. {
  380. acpi_status             status = AE_OK;
  381. FUNCTION_TRACE("tz_policy_run");
  382. if (!data) {
  383. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.n"));
  384. return_VOID;
  385. }
  386. /*
  387.  * Defer to Non-Interrupt Level:
  388.  * -----------------------------
  389.  * Note that all Linux kernel timers run at interrupt-level (ack!).
  390.  */
  391. status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,  tz_policy_check, (void*)data);
  392. if (ACPI_FAILURE(status)) {
  393. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Error invoking thermal policy.n"));
  394. }
  395. return_VOID;
  396. }
  397. /****************************************************************************
  398.  *
  399.  * FUNCTION:    tz_policy_add_device
  400.  *
  401.  * PARAMETERS:
  402.  *
  403.  * RETURN:
  404.  *
  405.  * DESCRIPTION:
  406.  *
  407.  ****************************************************************************/
  408. acpi_status
  409. tz_policy_add_device (
  410. TZ_CONTEXT *tz)
  411. {
  412. acpi_status             status = AE_OK;
  413. TZ_THRESHOLDS           *thresholds = NULL;
  414. u32                     i,j = 0;
  415. FUNCTION_TRACE("tz_policy_add_device");
  416. if (!tz) {
  417. return_ACPI_STATUS(AE_BAD_PARAMETER);
  418. }
  419. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding policy for thermal zone [%02x].n", tz->device_handle));
  420. /*
  421.  * Get Thresholds:
  422.  * ---------------
  423.  */
  424. status = tz_get_thresholds(tz);
  425. if (ACPI_FAILURE(status)) {
  426. return_ACPI_STATUS(status);
  427. }
  428. /*
  429.  * Initialize Policies:
  430.  * --------------------
  431.  */
  432. if (tz->policy.thresholds.passive.is_valid) {
  433. for (i=0; i<tz->policy.thresholds.passive.devices.count; i++)
  434. set_performance_limit(tz->policy.thresholds.passive.devices.handles[i], PR_PERF_MAX);
  435. tz_policy_passive(tz);
  436. }
  437. if (tz->policy.thresholds.active[0].is_valid)
  438. tz_policy_active(tz);
  439. /*
  440.  * Initialize Policy Timer:
  441.  * ------------------------
  442.  */
  443. init_timer(&(tz->policy.timer));
  444. /*
  445.  * Start Policy:
  446.  * -------------
  447.  * Run an initial check using this zone's policy.
  448.  */
  449. tz_policy_check(tz);
  450. return_ACPI_STATUS(AE_OK);
  451. }
  452. /*****************************************************************************
  453.  *
  454.  * FUNCTION:    tz_policy_remove_device
  455.  *
  456.  * PARAMETERS:
  457.  *
  458.  * RETURN:
  459.  *
  460.  * DESCRIPTION:
  461.  *
  462.  ****************************************************************************/
  463. acpi_status
  464. tz_policy_remove_device(
  465. TZ_CONTEXT *tz)
  466. {
  467. u32 i = 0;
  468. FUNCTION_TRACE("tz_remove_device");
  469. if (!tz) {
  470. return_ACPI_STATUS(AE_BAD_PARAMETER);
  471. }
  472. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing policy for thermal zone [%02x].n", tz->device_handle));
  473. /*
  474.  * Delete the thermal zone policy timer entry, if exists.
  475.  */
  476. if (timer_pending(&(tz->policy.timer)))
  477. del_timer(&(tz->policy.timer));
  478. /*
  479.  * Reset thermal performance limit on all processors back to max.
  480.  */
  481. if (tz->policy.thresholds.passive.is_valid) {
  482. for (i=0; i<tz->policy.thresholds.passive.devices.count; i++)
  483. set_performance_limit(tz->policy.thresholds.passive.devices.handles[i], PR_PERF_MAX);
  484. }
  485. return_ACPI_STATUS(AE_OK);
  486. }