2013-05-19 19:14:41 +03:00
/******************************************************************************
*
* This file is provided under a dual BSD / GPLv2 license . When using or
* redistributing this file , you may do so under either license .
*
* GPL LICENSE SUMMARY
*
2013-12-30 13:15:54 +02:00
* Copyright ( c ) 2013 - 2014 Intel Corporation . All rights reserved .
2014-07-24 14:05:26 +02:00
* Copyright ( c ) 2013 - 2014 Intel Mobile Communications GmbH
2013-05-19 19:14:41 +03:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but
* WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 ,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING .
*
* Contact Information :
2015-11-17 15:39:56 +02:00
* Intel Linux Wireless < linuxwifi @ intel . com >
2013-05-19 19:14:41 +03:00
* Intel Corporation , 5200 N . E . Elam Young Parkway , Hillsboro , OR 97124 - 6497
*
* BSD LICENSE
*
2013-12-30 13:15:54 +02:00
* Copyright ( c ) 2012 - 2014 Intel Corporation . All rights reserved .
2014-07-24 14:05:26 +02:00
* Copyright ( c ) 2013 - 2014 Intel Mobile Communications GmbH
2015-07-13 14:50:47 +03:00
* Copyright ( c ) 2015 Intel Deutschland GmbH
2013-05-19 19:14:41 +03:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in
* the documentation and / or other materials provided with the
* distribution .
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "mvm.h"
2014-09-04 12:29:15 +03:00
# define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
static void iwl_mvm_enter_ctkill ( struct iwl_mvm * mvm )
2013-05-19 19:14:41 +03:00
{
2014-12-15 14:15:15 +02:00
struct iwl_mvm_tt_mgmt * tt = & mvm - > thermal_throttle ;
2015-04-19 12:26:39 +03:00
u32 duration = tt - > params . ct_kill_duration ;
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
if ( test_bit ( IWL_MVM_STATUS_HW_CTKILL , & mvm - > status ) )
return ;
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
IWL_ERR ( mvm , " Enter CT Kill \n " ) ;
iwl_mvm_set_hw_ctkill_state ( mvm , true ) ;
2013-05-19 19:14:41 +03:00
2014-12-15 14:15:15 +02:00
tt - > throttle = false ;
tt - > dynamic_smps = false ;
2014-09-04 12:29:15 +03:00
/* Don't schedule an exit work if we're in test mode, since
* the temperature will not change unless we manually set it
* again ( or disable testing ) .
*/
if ( ! mvm - > temperature_test )
2014-12-15 14:15:15 +02:00
schedule_delayed_work ( & tt - > ct_kill_exit ,
2014-09-04 12:29:15 +03:00
round_jiffies_relative ( duration * HZ ) ) ;
2013-05-19 19:14:41 +03:00
}
2014-09-04 12:29:15 +03:00
static void iwl_mvm_exit_ctkill ( struct iwl_mvm * mvm )
2013-05-19 19:14:41 +03:00
{
2014-09-04 12:29:15 +03:00
if ( ! test_bit ( IWL_MVM_STATUS_HW_CTKILL , & mvm - > status ) )
return ;
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
IWL_ERR ( mvm , " Exit CT Kill \n " ) ;
iwl_mvm_set_hw_ctkill_state ( mvm , false ) ;
2013-05-19 19:14:41 +03:00
}
2014-11-04 16:17:46 +02:00
void iwl_mvm_tt_temp_changed ( struct iwl_mvm * mvm , u32 temp )
{
/* ignore the notification if we are in test mode */
if ( mvm - > temperature_test )
return ;
if ( mvm - > temperature = = temp )
return ;
mvm - > temperature = temp ;
iwl_mvm_tt_handler ( mvm ) ;
}
static int iwl_mvm_temp_notif_parse ( struct iwl_mvm * mvm ,
struct iwl_rx_packet * pkt )
2013-05-19 19:14:41 +03:00
{
2014-09-04 12:29:15 +03:00
struct iwl_dts_measurement_notif * notif ;
int len = iwl_rx_packet_payload_len ( pkt ) ;
2014-11-04 16:17:46 +02:00
int temp ;
2014-09-04 12:29:15 +03:00
if ( WARN_ON_ONCE ( len ! = sizeof ( * notif ) ) ) {
IWL_ERR ( mvm , " Invalid DTS_MEASUREMENT_NOTIFICATION \n " ) ;
2014-11-04 16:17:46 +02:00
return - EINVAL ;
2014-09-04 12:29:15 +03:00
}
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
notif = ( void * ) pkt - > data ;
2013-05-19 19:14:41 +03:00
2014-11-04 16:17:46 +02:00
temp = le32_to_cpu ( notif - > temp ) ;
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
/* shouldn't be negative, but since it's s32, make sure it isn't */
2014-11-04 16:17:46 +02:00
if ( WARN_ON_ONCE ( temp < 0 ) )
temp = 0 ;
IWL_DEBUG_TEMP ( mvm , " DTS_MEASUREMENT_NOTIFICATION - %d \n " , temp ) ;
return temp ;
}
static bool iwl_mvm_temp_notif_wait ( struct iwl_notif_wait_data * notif_wait ,
struct iwl_rx_packet * pkt , void * data )
{
struct iwl_mvm * mvm =
container_of ( notif_wait , struct iwl_mvm , notif_wait ) ;
int * temp = data ;
int ret ;
ret = iwl_mvm_temp_notif_parse ( mvm , pkt ) ;
if ( ret < 0 )
return true ;
* temp = ret ;
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
return true ;
2013-05-19 19:14:41 +03:00
}
2015-06-23 21:22:09 +02:00
void iwl_mvm_temp_notif ( struct iwl_mvm * mvm , struct iwl_rx_cmd_buffer * rxb )
2014-11-06 10:34:49 +02:00
{
struct iwl_rx_packet * pkt = rxb_addr ( rxb ) ;
int temp ;
/* the notification is handled synchronously in ctkill, so skip here */
if ( test_bit ( IWL_MVM_STATUS_HW_CTKILL , & mvm - > status ) )
2015-06-23 21:22:09 +02:00
return ;
2014-11-06 10:34:49 +02:00
temp = iwl_mvm_temp_notif_parse ( mvm , pkt ) ;
if ( temp < 0 )
2015-06-23 21:22:09 +02:00
return ;
2014-11-06 10:34:49 +02:00
iwl_mvm_tt_temp_changed ( mvm , temp ) ;
}
2014-09-04 12:29:15 +03:00
static int iwl_mvm_get_temp_cmd ( struct iwl_mvm * mvm )
2013-05-19 19:14:41 +03:00
{
2014-09-04 12:29:15 +03:00
struct iwl_dts_measurement_cmd cmd = {
. flags = cpu_to_le32 ( DTS_TRIGGER_CMD_FLAGS_TEMP ) ,
2013-05-19 19:14:41 +03:00
} ;
2015-10-06 12:22:47 +03:00
struct iwl_ext_dts_measurement_cmd extcmd = {
. control_mode = cpu_to_le32 ( DTS_AUTOMATIC ) ,
} ;
2015-09-01 19:34:38 +03:00
u32 cmdid ;
if ( fw_has_api ( & mvm - > fw - > ucode_capa , IWL_UCODE_TLV_API_WIDE_CMD_HDR ) )
cmdid = iwl_cmd_id ( CMD_DTS_MEASUREMENT_TRIGGER_WIDE ,
PHY_OPS_GROUP , 0 ) ;
else
cmdid = CMD_DTS_MEASUREMENT_TRIGGER ;
2015-10-06 12:22:47 +03:00
if ( ! fw_has_capa ( & mvm - > fw - > ucode_capa ,
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE ) )
return iwl_mvm_send_cmd_pdu ( mvm , cmdid , 0 , sizeof ( cmd ) , & cmd ) ;
return iwl_mvm_send_cmd_pdu ( mvm , cmdid , 0 , sizeof ( extcmd ) , & extcmd ) ;
2013-05-19 19:14:41 +03:00
}
2014-09-04 15:58:47 +03:00
int iwl_mvm_get_temp ( struct iwl_mvm * mvm )
2013-05-19 19:14:41 +03:00
{
2014-09-04 12:29:15 +03:00
struct iwl_notification_wait wait_temp_notif ;
2015-09-01 19:34:38 +03:00
static u16 temp_notif [ ] = { WIDE_ID ( PHY_OPS_GROUP ,
DTS_MEASUREMENT_NOTIF_WIDE ) } ;
2014-09-04 12:29:15 +03:00
int ret , temp ;
2013-05-19 19:14:41 +03:00
2015-09-01 19:34:38 +03:00
if ( ! fw_has_api ( & mvm - > fw - > ucode_capa , IWL_UCODE_TLV_API_WIDE_CMD_HDR ) )
temp_notif [ 0 ] = DTS_MEASUREMENT_NOTIFICATION ;
2014-09-04 12:29:15 +03:00
lockdep_assert_held ( & mvm - > mutex ) ;
2014-08-20 17:26:58 +03:00
2014-09-04 12:29:15 +03:00
iwl_init_notification_wait ( & mvm - > notif_wait , & wait_temp_notif ,
temp_notif , ARRAY_SIZE ( temp_notif ) ,
2014-11-04 16:17:46 +02:00
iwl_mvm_temp_notif_wait , & temp ) ;
2014-08-20 17:58:20 +03:00
2014-09-04 12:29:15 +03:00
ret = iwl_mvm_get_temp_cmd ( mvm ) ;
if ( ret ) {
IWL_ERR ( mvm , " Failed to get the temperature (err=%d) \n " , ret ) ;
iwl_remove_notification ( & mvm - > notif_wait , & wait_temp_notif ) ;
return ret ;
}
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
ret = iwl_wait_notification ( & mvm - > notif_wait , & wait_temp_notif ,
IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT ) ;
if ( ret ) {
IWL_ERR ( mvm , " Getting the temperature timed out \n " ) ;
return ret ;
}
2014-08-20 17:26:58 +03:00
2014-09-04 12:29:15 +03:00
return temp ;
2013-05-19 19:14:41 +03:00
}
static void check_exit_ctkill ( struct work_struct * work )
{
struct iwl_mvm_tt_mgmt * tt ;
struct iwl_mvm * mvm ;
u32 duration ;
s32 temp ;
tt = container_of ( work , struct iwl_mvm_tt_mgmt , ct_kill_exit . work ) ;
mvm = container_of ( tt , struct iwl_mvm , thermal_throttle ) ;
2015-04-19 12:26:39 +03:00
duration = tt - > params . ct_kill_duration ;
2013-05-19 19:14:41 +03:00
2014-09-04 12:29:15 +03:00
mutex_lock ( & mvm - > mutex ) ;
if ( __iwl_mvm_mac_start ( mvm ) )
goto reschedule ;
2014-07-01 18:38:38 +03:00
/* make sure the device is available for direct read/writes */
2014-09-04 12:29:15 +03:00
if ( iwl_mvm_ref_sync ( mvm , IWL_MVM_REF_CHECK_CTKILL ) ) {
__iwl_mvm_mac_stop ( mvm ) ;
2014-07-01 18:38:38 +03:00
goto reschedule ;
2014-09-04 12:29:15 +03:00
}
2014-07-01 18:38:38 +03:00
2014-09-04 12:29:15 +03:00
temp = iwl_mvm_get_temp ( mvm ) ;
2013-05-19 19:14:41 +03:00
2014-07-01 18:38:38 +03:00
iwl_mvm_unref ( mvm , IWL_MVM_REF_CHECK_CTKILL ) ;
2014-09-04 12:29:15 +03:00
__iwl_mvm_mac_stop ( mvm ) ;
if ( temp < 0 )
2013-05-19 19:14:41 +03:00
goto reschedule ;
2014-09-04 12:29:15 +03:00
2013-05-19 19:14:41 +03:00
IWL_DEBUG_TEMP ( mvm , " NIC temperature: %d \n " , temp ) ;
2015-04-19 12:26:39 +03:00
if ( temp < = tt - > params . ct_kill_exit ) {
2014-09-04 12:29:15 +03:00
mutex_unlock ( & mvm - > mutex ) ;
2013-05-19 19:14:41 +03:00
iwl_mvm_exit_ctkill ( mvm ) ;
return ;
}
reschedule :
2014-09-04 12:29:15 +03:00
mutex_unlock ( & mvm - > mutex ) ;
2013-05-19 19:14:41 +03:00
schedule_delayed_work ( & mvm - > thermal_throttle . ct_kill_exit ,
round_jiffies ( duration * HZ ) ) ;
}
static void iwl_mvm_tt_smps_iterator ( void * _data , u8 * mac ,
struct ieee80211_vif * vif )
{
struct iwl_mvm * mvm = _data ;
enum ieee80211_smps_mode smps_mode ;
lockdep_assert_held ( & mvm - > mutex ) ;
if ( mvm - > thermal_throttle . dynamic_smps )
smps_mode = IEEE80211_SMPS_DYNAMIC ;
else
smps_mode = IEEE80211_SMPS_AUTOMATIC ;
2013-06-04 12:28:51 +03:00
if ( vif - > type ! = NL80211_IFTYPE_STATION )
return ;
2013-05-19 19:14:41 +03:00
iwl_mvm_update_smps ( mvm , vif , IWL_MVM_SMPS_REQ_TT , smps_mode ) ;
}
static void iwl_mvm_tt_tx_protection ( struct iwl_mvm * mvm , bool enable )
{
struct ieee80211_sta * sta ;
struct iwl_mvm_sta * mvmsta ;
int i , err ;
for ( i = 0 ; i < IWL_MVM_STATION_COUNT ; i + + ) {
sta = rcu_dereference_protected ( mvm - > fw_id_to_mac_id [ i ] ,
lockdep_is_held ( & mvm - > mutex ) ) ;
if ( IS_ERR_OR_NULL ( sta ) )
continue ;
2013-11-14 18:20:04 +01:00
mvmsta = iwl_mvm_sta_from_mac80211 ( sta ) ;
2013-05-19 19:14:41 +03:00
if ( enable = = mvmsta - > tt_tx_protection )
continue ;
2013-06-28 13:39:18 +02:00
err = iwl_mvm_tx_protection ( mvm , mvmsta , enable ) ;
2013-05-19 19:14:41 +03:00
if ( err ) {
IWL_ERR ( mvm , " Failed to %s Tx protection \n " ,
enable ? " enable " : " disable " ) ;
} else {
IWL_DEBUG_TEMP ( mvm , " %s Tx protection \n " ,
enable ? " Enable " : " Disable " ) ;
mvmsta - > tt_tx_protection = enable ;
}
}
}
2014-01-16 21:12:02 -05:00
void iwl_mvm_tt_tx_backoff ( struct iwl_mvm * mvm , u32 backoff )
2013-05-19 19:14:41 +03:00
{
struct iwl_host_cmd cmd = {
. id = REPLY_THERMAL_MNG_BACKOFF ,
. len = { sizeof ( u32 ) , } ,
. data = { & backoff , } ,
} ;
2014-01-16 21:12:02 -05:00
backoff = max ( backoff , mvm - > thermal_throttle . min_backoff ) ;
2013-05-19 19:14:41 +03:00
if ( iwl_mvm_send_cmd ( mvm , & cmd ) = = 0 ) {
IWL_DEBUG_TEMP ( mvm , " Set Thermal Tx backoff to: %u \n " ,
backoff ) ;
mvm - > thermal_throttle . tx_backoff = backoff ;
} else {
IWL_ERR ( mvm , " Failed to change Thermal Tx backoff \n " ) ;
}
}
void iwl_mvm_tt_handler ( struct iwl_mvm * mvm )
{
2015-04-19 12:26:39 +03:00
struct iwl_tt_params * params = & mvm - > thermal_throttle . params ;
2013-05-19 19:14:41 +03:00
struct iwl_mvm_tt_mgmt * tt = & mvm - > thermal_throttle ;
s32 temperature = mvm - > temperature ;
2013-06-18 14:28:56 +03:00
bool throttle_enable = false ;
2013-05-19 19:14:41 +03:00
int i ;
u32 tx_backoff ;
IWL_DEBUG_TEMP ( mvm , " NIC temperature: %d \n " , mvm - > temperature ) ;
if ( params - > support_ct_kill & & temperature > = params - > ct_kill_entry ) {
iwl_mvm_enter_ctkill ( mvm ) ;
return ;
}
2014-08-20 17:26:58 +03:00
if ( params - > support_ct_kill & &
2015-04-19 12:26:39 +03:00
temperature < = params - > ct_kill_exit ) {
2014-08-20 17:26:58 +03:00
iwl_mvm_exit_ctkill ( mvm ) ;
return ;
}
2013-05-19 19:14:41 +03:00
if ( params - > support_dynamic_smps ) {
if ( ! tt - > dynamic_smps & &
temperature > = params - > dynamic_smps_entry ) {
IWL_DEBUG_TEMP ( mvm , " Enable dynamic SMPS \n " ) ;
tt - > dynamic_smps = true ;
ieee80211_iterate_active_interfaces_atomic (
mvm - > hw , IEEE80211_IFACE_ITER_NORMAL ,
iwl_mvm_tt_smps_iterator , mvm ) ;
2013-06-18 14:28:56 +03:00
throttle_enable = true ;
2013-05-19 19:14:41 +03:00
} else if ( tt - > dynamic_smps & &
temperature < = params - > dynamic_smps_exit ) {
IWL_DEBUG_TEMP ( mvm , " Disable dynamic SMPS \n " ) ;
tt - > dynamic_smps = false ;
ieee80211_iterate_active_interfaces_atomic (
mvm - > hw , IEEE80211_IFACE_ITER_NORMAL ,
iwl_mvm_tt_smps_iterator , mvm ) ;
}
}
if ( params - > support_tx_protection ) {
2013-06-18 14:28:56 +03:00
if ( temperature > = params - > tx_protection_entry ) {
2013-05-19 19:14:41 +03:00
iwl_mvm_tt_tx_protection ( mvm , true ) ;
2013-06-18 14:28:56 +03:00
throttle_enable = true ;
} else if ( temperature < = params - > tx_protection_exit ) {
2013-05-19 19:14:41 +03:00
iwl_mvm_tt_tx_protection ( mvm , false ) ;
2013-06-18 14:28:56 +03:00
}
2013-05-19 19:14:41 +03:00
}
if ( params - > support_tx_backoff ) {
2014-04-01 16:44:21 +03:00
tx_backoff = tt - > min_backoff ;
2013-05-19 19:14:41 +03:00
for ( i = 0 ; i < TT_TX_BACKOFF_SIZE ; i + + ) {
if ( temperature < params - > tx_backoff [ i ] . temperature )
break ;
2014-04-01 16:44:21 +03:00
tx_backoff = max ( tt - > min_backoff ,
params - > tx_backoff [ i ] . backoff ) ;
2013-05-19 19:14:41 +03:00
}
2014-04-01 16:44:21 +03:00
if ( tx_backoff ! = tt - > min_backoff )
2013-06-18 14:28:56 +03:00
throttle_enable = true ;
2013-05-19 19:14:41 +03:00
if ( tt - > tx_backoff ! = tx_backoff )
iwl_mvm_tt_tx_backoff ( mvm , tx_backoff ) ;
}
2013-06-18 14:28:56 +03:00
if ( ! tt - > throttle & & throttle_enable ) {
IWL_WARN ( mvm ,
" Due to high temperature thermal throttling initiated \n " ) ;
tt - > throttle = true ;
2014-04-02 21:37:57 +03:00
} else if ( tt - > throttle & & ! tt - > dynamic_smps & &
tt - > tx_backoff = = tt - > min_backoff & &
2013-06-18 14:28:56 +03:00
temperature < = params - > tx_protection_exit ) {
IWL_WARN ( mvm ,
" Temperature is back to normal thermal throttling stopped \n " ) ;
tt - > throttle = false ;
}
2013-05-19 19:14:41 +03:00
}
2015-04-19 12:26:39 +03:00
static const struct iwl_tt_params iwl_mvm_default_tt_params = {
2013-05-19 19:14:41 +03:00
. ct_kill_entry = 118 ,
. ct_kill_exit = 96 ,
. ct_kill_duration = 5 ,
. dynamic_smps_entry = 114 ,
. dynamic_smps_exit = 110 ,
. tx_protection_entry = 114 ,
. tx_protection_exit = 108 ,
. tx_backoff = {
{ . temperature = 112 , . backoff = 200 } ,
{ . temperature = 113 , . backoff = 600 } ,
{ . temperature = 114 , . backoff = 1200 } ,
{ . temperature = 115 , . backoff = 2000 } ,
{ . temperature = 116 , . backoff = 4000 } ,
{ . temperature = 117 , . backoff = 10000 } ,
} ,
. support_ct_kill = true ,
. support_dynamic_smps = true ,
. support_tx_protection = true ,
. support_tx_backoff = true ,
} ;
2014-01-16 21:12:02 -05:00
void iwl_mvm_tt_initialize ( struct iwl_mvm * mvm , u32 min_backoff )
2013-05-19 19:14:41 +03:00
{
struct iwl_mvm_tt_mgmt * tt = & mvm - > thermal_throttle ;
IWL_DEBUG_TEMP ( mvm , " Initialize Thermal Throttling \n " ) ;
2013-07-24 14:49:18 +03:00
2015-04-19 12:26:39 +03:00
if ( mvm - > cfg - > thermal_params )
tt - > params = * mvm - > cfg - > thermal_params ;
2013-07-24 14:49:18 +03:00
else
2015-04-19 12:26:39 +03:00
tt - > params = iwl_mvm_default_tt_params ;
2013-07-24 14:49:18 +03:00
2013-06-18 14:28:56 +03:00
tt - > throttle = false ;
2014-12-15 14:15:15 +02:00
tt - > dynamic_smps = false ;
2014-01-16 21:12:02 -05:00
tt - > min_backoff = min_backoff ;
2013-05-19 19:14:41 +03:00
INIT_DELAYED_WORK ( & tt - > ct_kill_exit , check_exit_ctkill ) ;
}
void iwl_mvm_tt_exit ( struct iwl_mvm * mvm )
{
cancel_delayed_work_sync ( & mvm - > thermal_throttle . ct_kill_exit ) ;
IWL_DEBUG_TEMP ( mvm , " Exit Thermal Throttling \n " ) ;
}