Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tt.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved.
4  *
5  * Portions of this file are derived from the ipw3945 project, as well
6  * as portions of the ieee80211 subsystem header files.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of version 2 of the GNU General Public License as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20  *
21  * The full GNU General Public License is included in this distribution in the
22  * file called LICENSE.
23  *
24  * Contact Information:
25  * Intel Linux Wireless <[email protected]>
26  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27  *****************************************************************************/
28 
29 
30 #include <linux/kernel.h>
31 #include <linux/module.h>
32 #include <linux/slab.h>
33 #include <linux/init.h>
34 #include <net/mac80211.h>
35 #include "iwl-io.h"
36 #include "iwl-modparams.h"
37 #include "iwl-debug.h"
38 #include "agn.h"
39 #include "dev.h"
40 #include "commands.h"
41 #include "tt.h"
42 
43 /* default Thermal Throttling transaction table
44  * Current state | Throttling Down | Throttling Up
45  *=============================================================================
46  * Condition Nxt State Condition Nxt State Condition Nxt State
47  *-----------------------------------------------------------------------------
48  * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
49  * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
50  * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
51  * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
52  *=============================================================================
53  */
54 static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
56  {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1},
58 };
59 static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
61  {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1},
63 };
64 static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
68 };
69 static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
73 };
74 
75 /* Advance Thermal Throttling default restriction table */
76 static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
81 };
82 
84 {
85  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
86 
87  if (tt->state >= IWL_TI_1)
88  return true;
89  return false;
90 }
91 
93 {
94  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
95 
96  return tt->tt_power_mode;
97 }
98 
100 {
101  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
102  struct iwl_tt_restriction *restriction;
103 
104  if (!priv->thermal_throttle.advanced_tt)
105  return true;
106  restriction = tt->restriction + tt->state;
107  return restriction->is_ht;
108 }
109 
110 static bool iwl_within_ct_kill_margin(struct iwl_priv *priv)
111 {
112  s32 temp = priv->temperature; /* degrees CELSIUS except specified */
113  bool within_margin = false;
114 
115  if (!priv->thermal_throttle.advanced_tt)
116  within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
117  CT_KILL_THRESHOLD_LEGACY) ? true : false;
118  else
119  within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >=
120  CT_KILL_THRESHOLD) ? true : false;
121  return within_margin;
122 }
123 
124 bool iwl_check_for_ct_kill(struct iwl_priv *priv)
125 {
126  bool is_ct_kill = false;
127 
128  if (iwl_within_ct_kill_margin(priv)) {
129  iwl_tt_enter_ct_kill(priv);
130  is_ct_kill = true;
131  }
132  return is_ct_kill;
133 }
134 
136 {
137  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
138  struct iwl_tt_restriction *restriction;
139 
140  if (!priv->thermal_throttle.advanced_tt)
141  return IWL_ANT_OK_MULTI;
142  restriction = tt->restriction + tt->state;
143  return restriction->tx_stream;
144 }
145 
147 {
148  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
149  struct iwl_tt_restriction *restriction;
150 
151  if (!priv->thermal_throttle.advanced_tt)
152  return IWL_ANT_OK_MULTI;
153  restriction = tt->restriction + tt->state;
154  return restriction->rx_stream;
155 }
156 
157 #define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
158 #define CT_KILL_WAITING_DURATION (300) /* 300ms duration */
159 
160 /*
161  * toggle the bit to wake up uCode and check the temperature
162  * if the temperature is below CT, uCode will stay awake and send card
163  * state notification with CT_KILL bit clear to inform Thermal Throttling
164  * Management to change state. Otherwise, uCode will go back to sleep
165  * without doing anything, driver should continue the 5 seconds timer
166  * to wake up uCode for temperature check until temperature drop below CT
167  */
168 static void iwl_tt_check_exit_ct_kill(unsigned long data)
169 {
170  struct iwl_priv *priv = (struct iwl_priv *)data;
171  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
172  unsigned long flags;
173 
174  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
175  return;
176 
177  if (tt->state == IWL_TI_CT_KILL) {
178  if (priv->thermal_throttle.ct_kill_toggle) {
179  iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
181  priv->thermal_throttle.ct_kill_toggle = false;
182  } else {
183  iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
185  priv->thermal_throttle.ct_kill_toggle = true;
186  }
187  iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
188  spin_lock_irqsave(&priv->trans->reg_lock, flags);
189  if (likely(iwl_grab_nic_access(priv->trans)))
191  spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
192 
193  /* Reschedule the ct_kill timer to occur in
194  * CT_KILL_EXIT_DURATION seconds to ensure we get a
195  * thermal update */
196  IWL_DEBUG_TEMP(priv, "schedule ct_kill exit timer\n");
197  mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
199  }
200 }
201 
202 static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
203  bool stop)
204 {
205  if (stop) {
206  IWL_DEBUG_TEMP(priv, "Stop all queues\n");
207  if (priv->mac80211_registered)
208  ieee80211_stop_queues(priv->hw);
209  IWL_DEBUG_TEMP(priv,
210  "Schedule 5 seconds CT_KILL Timer\n");
211  mod_timer(&priv->thermal_throttle.ct_kill_exit_tm,
212  jiffies + CT_KILL_EXIT_DURATION * HZ);
213  } else {
214  IWL_DEBUG_TEMP(priv, "Wake all queues\n");
215  if (priv->mac80211_registered)
216  ieee80211_wake_queues(priv->hw);
217  }
218 }
219 
220 static void iwl_tt_ready_for_ct_kill(unsigned long data)
221 {
222  struct iwl_priv *priv = (struct iwl_priv *)data;
223  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
224 
225  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
226  return;
227 
228  /* temperature timer expired, ready to go into CT_KILL state */
229  if (tt->state != IWL_TI_CT_KILL) {
230  IWL_DEBUG_TEMP(priv, "entering CT_KILL state when "
231  "temperature timer expired\n");
232  tt->state = IWL_TI_CT_KILL;
233  set_bit(STATUS_CT_KILL, &priv->status);
234  iwl_perform_ct_kill_task(priv, true);
235  }
236 }
237 
238 static void iwl_prepare_ct_kill_task(struct iwl_priv *priv)
239 {
240  IWL_DEBUG_TEMP(priv, "Prepare to enter IWL_TI_CT_KILL\n");
241  /* make request to retrieve statistics information */
243  /* Reschedule the ct_kill wait timer */
244  mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
246 }
247 
248 #define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY)
249 #define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
250 #define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
251 
252 /*
253  * Legacy thermal throttling
254  * 1) Avoid NIC destruction due to high temperatures
255  * Chip will identify dangerously high temperatures that can
256  * harm the device and will power down
257  * 2) Avoid the NIC power down due to high temperature
258  * Throttle early enough to lower the power consumption before
259  * drastic steps are needed
260  */
261 static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
262 {
263  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
264  enum iwl_tt_state old_state;
265 
266 #ifdef CONFIG_IWLWIFI_DEBUG
267  if ((tt->tt_previous_temp) &&
268  (temp > tt->tt_previous_temp) &&
269  ((temp - tt->tt_previous_temp) >
271  IWL_DEBUG_TEMP(priv,
272  "Temperature increase %d degree Celsius\n",
273  (temp - tt->tt_previous_temp));
274  }
275 #endif
276  old_state = tt->state;
277  /* in Celsius */
278  if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
279  tt->state = IWL_TI_CT_KILL;
280  else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
281  tt->state = IWL_TI_2;
282  else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
283  tt->state = IWL_TI_1;
284  else
285  tt->state = IWL_TI_0;
286 
287 #ifdef CONFIG_IWLWIFI_DEBUG
288  tt->tt_previous_temp = temp;
289 #endif
290  /* stop ct_kill_waiting_tm timer */
291  del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
292  if (tt->state != old_state) {
293  switch (tt->state) {
294  case IWL_TI_0:
295  /*
296  * When the system is ready to go back to IWL_TI_0
297  * we only have to call iwl_power_update_mode() to
298  * do so.
299  */
300  break;
301  case IWL_TI_1:
303  break;
304  case IWL_TI_2:
306  break;
307  default:
309  break;
310  }
311  mutex_lock(&priv->mutex);
312  if (old_state == IWL_TI_CT_KILL)
314  if (tt->state != IWL_TI_CT_KILL &&
315  iwl_power_update_mode(priv, true)) {
316  /* TT state not updated
317  * try again during next temperature read
318  */
319  if (old_state == IWL_TI_CT_KILL)
320  set_bit(STATUS_CT_KILL, &priv->status);
321  tt->state = old_state;
322  IWL_ERR(priv, "Cannot update power mode, "
323  "TT state not updated\n");
324  } else {
325  if (tt->state == IWL_TI_CT_KILL) {
326  if (force) {
327  set_bit(STATUS_CT_KILL, &priv->status);
328  iwl_perform_ct_kill_task(priv, true);
329  } else {
330  iwl_prepare_ct_kill_task(priv);
331  tt->state = old_state;
332  }
333  } else if (old_state == IWL_TI_CT_KILL &&
334  tt->state != IWL_TI_CT_KILL)
335  iwl_perform_ct_kill_task(priv, false);
336  IWL_DEBUG_TEMP(priv, "Temperature state changed %u\n",
337  tt->state);
338  IWL_DEBUG_TEMP(priv, "Power Index change to %u\n",
339  tt->tt_power_mode);
340  }
341  mutex_unlock(&priv->mutex);
342  }
343 }
344 
345 /*
346  * Advance thermal throttling
347  * 1) Avoid NIC destruction due to high temperatures
348  * Chip will identify dangerously high temperatures that can
349  * harm the device and will power down
350  * 2) Avoid the NIC power down due to high temperature
351  * Throttle early enough to lower the power consumption before
352  * drastic steps are needed
353  * Actions include relaxing the power down sleep thresholds and
354  * decreasing the number of TX streams
355  * 3) Avoid throughput performance impact as much as possible
356  *
357  *=============================================================================
358  * Condition Nxt State Condition Nxt State Condition Nxt State
359  *-----------------------------------------------------------------------------
360  * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A
361  * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0
362  * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1
363  * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
364  *=============================================================================
365  */
366 static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
367 {
368  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
369  int i;
370  bool changed = false;
371  enum iwl_tt_state old_state;
372  struct iwl_tt_trans *transaction;
373 
374  old_state = tt->state;
375  for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
376  /* based on the current TT state,
377  * find the curresponding transaction table
378  * each table has (IWL_TI_STATE_MAX - 1) entries
379  * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
380  * will advance to the correct table.
381  * then based on the current temperature
382  * find the next state need to transaction to
383  * go through all the possible (IWL_TI_STATE_MAX - 1) entries
384  * in the current table to see if transaction is needed
385  */
386  transaction = tt->transaction +
387  ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
388  if (temp >= transaction->tt_low &&
389  temp <= transaction->tt_high) {
390 #ifdef CONFIG_IWLWIFI_DEBUG
391  if ((tt->tt_previous_temp) &&
392  (temp > tt->tt_previous_temp) &&
393  ((temp - tt->tt_previous_temp) >
395  IWL_DEBUG_TEMP(priv,
396  "Temperature increase %d "
397  "degree Celsius\n",
398  (temp - tt->tt_previous_temp));
399  }
400  tt->tt_previous_temp = temp;
401 #endif
402  if (old_state !=
403  transaction->next_state) {
404  changed = true;
405  tt->state =
406  transaction->next_state;
407  }
408  break;
409  }
410  }
411  /* stop ct_kill_waiting_tm timer */
412  del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
413  if (changed) {
414  if (tt->state >= IWL_TI_1) {
415  /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
417 
418  if (!iwl_ht_enabled(priv)) {
419  struct iwl_rxon_context *ctx;
420 
421  for_each_context(priv, ctx) {
422  struct iwl_rxon_cmd *rxon;
423 
424  rxon = &ctx->staging;
425 
426  /* disable HT */
427  rxon->flags &= ~(
432  }
433  } else {
434  /* check HT capability and set
435  * according to the system HT capability
436  * in case get disabled before */
437  iwl_set_rxon_ht(priv, &priv->current_ht_config);
438  }
439 
440  } else {
441  /*
442  * restore system power setting -- it will be
443  * recalculated automatically.
444  */
445 
446  /* check HT capability and set
447  * according to the system HT capability
448  * in case get disabled before */
449  iwl_set_rxon_ht(priv, &priv->current_ht_config);
450  }
451  mutex_lock(&priv->mutex);
452  if (old_state == IWL_TI_CT_KILL)
454  if (tt->state != IWL_TI_CT_KILL &&
455  iwl_power_update_mode(priv, true)) {
456  /* TT state not updated
457  * try again during next temperature read
458  */
459  IWL_ERR(priv, "Cannot update power mode, "
460  "TT state not updated\n");
461  if (old_state == IWL_TI_CT_KILL)
462  set_bit(STATUS_CT_KILL, &priv->status);
463  tt->state = old_state;
464  } else {
465  IWL_DEBUG_TEMP(priv,
466  "Thermal Throttling to new state: %u\n",
467  tt->state);
468  if (old_state != IWL_TI_CT_KILL &&
469  tt->state == IWL_TI_CT_KILL) {
470  if (force) {
471  IWL_DEBUG_TEMP(priv,
472  "Enter IWL_TI_CT_KILL\n");
473  set_bit(STATUS_CT_KILL, &priv->status);
474  iwl_perform_ct_kill_task(priv, true);
475  } else {
476  iwl_prepare_ct_kill_task(priv);
477  tt->state = old_state;
478  }
479  } else if (old_state == IWL_TI_CT_KILL &&
480  tt->state != IWL_TI_CT_KILL) {
481  IWL_DEBUG_TEMP(priv, "Exit IWL_TI_CT_KILL\n");
482  iwl_perform_ct_kill_task(priv, false);
483  }
484  }
485  mutex_unlock(&priv->mutex);
486  }
487 }
488 
489 /* Card State Notification indicated reach critical temperature
490  * if PSP not enable, no Thermal Throttling function will be performed
491  * just set the GP1 bit to acknowledge the event
492  * otherwise, go into IWL_TI_CT_KILL state
493  * since Card State Notification will not provide any temperature reading
494  * for Legacy mode
495  * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
496  * for advance mode
497  * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
498  */
499 static void iwl_bg_ct_enter(struct work_struct *work)
500 {
501  struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
502  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
503 
504  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
505  return;
506 
507  if (!iwl_is_ready(priv))
508  return;
509 
510  if (tt->state != IWL_TI_CT_KILL) {
511  IWL_ERR(priv, "Device reached critical temperature "
512  "- ucode going to sleep!\n");
513  if (!priv->thermal_throttle.advanced_tt)
514  iwl_legacy_tt_handler(priv,
516  true);
517  else
518  iwl_advance_tt_handler(priv,
519  CT_KILL_THRESHOLD + 1, true);
520  }
521 }
522 
523 /* Card State Notification indicated out of critical temperature
524  * since Card State Notification will not provide any temperature reading
525  * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
526  * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
527  */
528 static void iwl_bg_ct_exit(struct work_struct *work)
529 {
530  struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
531  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
532 
533  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
534  return;
535 
536  if (!iwl_is_ready(priv))
537  return;
538 
539  /* stop ct_kill_exit_tm timer */
540  del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
541 
542  if (tt->state == IWL_TI_CT_KILL) {
543  IWL_ERR(priv,
544  "Device temperature below critical"
545  "- ucode awake!\n");
546  /*
547  * exit from CT_KILL state
548  * reset the current temperature reading
549  */
550  priv->temperature = 0;
551  if (!priv->thermal_throttle.advanced_tt)
552  iwl_legacy_tt_handler(priv,
554  true);
555  else
556  iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD,
557  true);
558  }
559 }
560 
561 void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
562 {
563  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
564  return;
565 
566  IWL_DEBUG_TEMP(priv, "Queueing critical temperature enter.\n");
567  queue_work(priv->workqueue, &priv->ct_enter);
568 }
569 
570 void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
571 {
572  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
573  return;
574 
575  IWL_DEBUG_TEMP(priv, "Queueing critical temperature exit.\n");
576  queue_work(priv->workqueue, &priv->ct_exit);
577 }
578 
579 static void iwl_bg_tt_work(struct work_struct *work)
580 {
581  struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
582  s32 temp = priv->temperature; /* degrees CELSIUS except specified */
583 
584  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
585  return;
586 
587  if (!priv->thermal_throttle.advanced_tt)
588  iwl_legacy_tt_handler(priv, temp, false);
589  else
590  iwl_advance_tt_handler(priv, temp, false);
591 }
592 
593 void iwl_tt_handler(struct iwl_priv *priv)
594 {
595  if (test_bit(STATUS_EXIT_PENDING, &priv->status))
596  return;
597 
598  IWL_DEBUG_TEMP(priv, "Queueing thermal throttling work.\n");
599  queue_work(priv->workqueue, &priv->tt_work);
600 }
601 
602 /* Thermal throttling initialization
603  * For advance thermal throttling:
604  * Initialize Thermal Index and temperature threshold table
605  * Initialize thermal throttling restriction table
606  */
607 void iwl_tt_initialize(struct iwl_priv *priv)
608 {
609  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
610  int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
611  struct iwl_tt_trans *transaction;
612 
613  IWL_DEBUG_TEMP(priv, "Initialize Thermal Throttling\n");
614 
615  memset(tt, 0, sizeof(struct iwl_tt_mgmt));
616 
617  tt->state = IWL_TI_0;
618  init_timer(&priv->thermal_throttle.ct_kill_exit_tm);
619  priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv;
620  priv->thermal_throttle.ct_kill_exit_tm.function =
621  iwl_tt_check_exit_ct_kill;
622  init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
623  priv->thermal_throttle.ct_kill_waiting_tm.data =
624  (unsigned long)priv;
625  priv->thermal_throttle.ct_kill_waiting_tm.function =
626  iwl_tt_ready_for_ct_kill;
627  /* setup deferred ct kill work */
628  INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
629  INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
630  INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
631 
632  if (priv->cfg->base_params->adv_thermal_throttle) {
633  IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
634  tt->restriction = kcalloc(IWL_TI_STATE_MAX,
635  sizeof(struct iwl_tt_restriction),
636  GFP_KERNEL);
637  tt->transaction = kcalloc(IWL_TI_STATE_MAX *
638  (IWL_TI_STATE_MAX - 1),
639  sizeof(struct iwl_tt_trans),
640  GFP_KERNEL);
641  if (!tt->restriction || !tt->transaction) {
642  IWL_ERR(priv, "Fallback to Legacy Throttling\n");
643  priv->thermal_throttle.advanced_tt = false;
644  kfree(tt->restriction);
645  tt->restriction = NULL;
646  kfree(tt->transaction);
647  tt->transaction = NULL;
648  } else {
649  transaction = tt->transaction +
650  (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
651  memcpy(transaction, &tt_range_0[0], size);
652  transaction = tt->transaction +
653  (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
654  memcpy(transaction, &tt_range_1[0], size);
655  transaction = tt->transaction +
656  (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
657  memcpy(transaction, &tt_range_2[0], size);
658  transaction = tt->transaction +
659  (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
660  memcpy(transaction, &tt_range_3[0], size);
661  size = sizeof(struct iwl_tt_restriction) *
663  memcpy(tt->restriction,
664  &restriction_range[0], size);
665  priv->thermal_throttle.advanced_tt = true;
666  }
667  } else {
668  IWL_DEBUG_TEMP(priv, "Legacy Thermal Throttling\n");
669  priv->thermal_throttle.advanced_tt = false;
670  }
671 }
672 
673 /* cleanup thermal throttling management related memory and timer */
674 void iwl_tt_exit(struct iwl_priv *priv)
675 {
676  struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
677 
678  /* stop ct_kill_exit_tm timer if activated */
679  del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm);
680  /* stop ct_kill_waiting_tm timer if activated */
681  del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
682  cancel_work_sync(&priv->tt_work);
683  cancel_work_sync(&priv->ct_enter);
684  cancel_work_sync(&priv->ct_exit);
685 
686  if (priv->thermal_throttle.advanced_tt) {
687  /* free advance thermal throttling memory */
688  kfree(tt->restriction);
689  tt->restriction = NULL;
690  kfree(tt->transaction);
691  tt->transaction = NULL;
692  }
693 }