From: Reinette Chatre <reinette.chatre@intel.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net,
Wey-Yi Guy <wey-yi.w.guy@intel.com>,
Reinette Chatre <reinette.chatre@intel.com>
Subject: [PATCH 09/16] iwlwifi: fix thermal throttling locking problem
Date: Fri, 7 Aug 2009 15:41:45 -0700 [thread overview]
Message-ID: <1249684912-22936-10-git-send-email-reinette.chatre@intel.com> (raw)
In-Reply-To: <1249684912-22936-1-git-send-email-reinette.chatre@intel.com>
From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Move all the thermal throttling functions to background task to make
sure do not change power and rx chain in interrupt handler.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 3 ++
drivers/net/wireless/iwlwifi/iwl-power.c | 57 +++++++++++++++++++++++++++--
2 files changed, 56 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 61f9523..35d07a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1197,6 +1197,9 @@ struct iwl_priv {
struct work_struct report_work;
struct work_struct request_scan;
struct work_struct beacon_update;
+ struct work_struct tt_work;
+ struct work_struct ct_enter;
+ struct work_struct ct_exit;
struct tasklet_struct irq_tasklet;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 594b5c2..9c05af7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -481,6 +481,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
tt->tt_power_mode = IWL_POWER_INDEX_5;
break;
}
+ mutex_lock(&priv->mutex);
if (iwl_power_update_mode(priv, true)) {
/* TT state not updated
* try again during next temperature read
@@ -499,6 +500,7 @@ static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
tt->tt_power_mode);
}
+ mutex_unlock(&priv->mutex);
}
}
@@ -609,6 +611,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
* in case get disabled before */
iwl_set_rxon_ht(priv, &priv->current_ht_config);
}
+ mutex_lock(&priv->mutex);
if (iwl_power_update_mode(priv, true)) {
/* TT state not updated
* try again during next temperature read
@@ -631,6 +634,7 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
iwl_perform_ct_kill_task(priv, false);
}
}
+ mutex_unlock(&priv->mutex);
}
}
@@ -644,13 +648,17 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
* for advance mode
* pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
*/
-void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
+static void iwl_bg_ct_enter(struct work_struct *work)
{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter);
struct iwl_tt_mgmt *tt = &priv->power_data.tt;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ if (!iwl_is_ready(priv))
+ return;
+
if (tt->state != IWL_TI_CT_KILL) {
IWL_ERR(priv, "Device reached critical temperature "
"- ucode going to sleep!\n");
@@ -662,20 +670,23 @@ void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
CT_KILL_THRESHOLD + 1);
}
}
-EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
/* Card State Notification indicated out of critical temperature
* since Card State Notification will not provide any temperature reading
* so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
* to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
*/
-void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
+static void iwl_bg_ct_exit(struct work_struct *work)
{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit);
struct iwl_tt_mgmt *tt = &priv->power_data.tt;
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
+ if (!iwl_is_ready(priv))
+ return;
+
/* stop ct_kill_exit_tm timer */
del_timer_sync(&priv->power_data.ct_kill_exit_tm);
@@ -690,10 +701,30 @@ void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD);
}
}
+
+void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n");
+ queue_work(priv->workqueue, &priv->ct_enter);
+}
+EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
+
+void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n");
+ queue_work(priv->workqueue, &priv->ct_exit);
+}
EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
-void iwl_tt_handler(struct iwl_priv *priv)
+static void iwl_bg_tt_work(struct work_struct *work)
{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work);
s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -707,6 +738,15 @@ void iwl_tt_handler(struct iwl_priv *priv)
else
iwl_advance_tt_handler(priv, temp);
}
+
+void iwl_tt_handler(struct iwl_priv *priv)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n");
+ queue_work(priv->workqueue, &priv->tt_work);
+}
EXPORT_SYMBOL(iwl_tt_handler);
/* Thermal throttling initialization
@@ -731,6 +771,12 @@ void iwl_tt_initialize(struct iwl_priv *priv)
init_timer(&priv->power_data.ct_kill_exit_tm);
priv->power_data.ct_kill_exit_tm.data = (unsigned long)priv;
priv->power_data.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill;
+
+ /* setup deferred ct kill work */
+ INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
+ INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
+ INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
+
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_6x00:
case CSR_HW_REV_TYPE_6x50:
@@ -782,6 +828,9 @@ void iwl_tt_exit(struct iwl_priv *priv)
/* stop ct_kill_exit_tm timer if activated */
del_timer_sync(&priv->power_data.ct_kill_exit_tm);
+ cancel_work_sync(&priv->tt_work);
+ cancel_work_sync(&priv->ct_enter);
+ cancel_work_sync(&priv->ct_exit);
if (priv->power_data.adv_tt) {
/* free advance thermal throttling memory */
--
1.5.6.3
next prev parent reply other threads:[~2009-08-07 22:41 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-07 22:41 [PATCH 0/16] iwlwifi driver updates 07/08/2009 Reinette Chatre
2009-08-07 22:41 ` [PATCH 01/16] iwlwifi: re-introduce per device debugging Reinette Chatre
2009-08-07 22:41 ` [PATCH 02/16] iwlwifi: name changed from "fat" to "ht40" Reinette Chatre
2009-08-07 22:41 ` [PATCH 03/16] iwlwifi: new debugging feature for dumping data traffic Reinette Chatre
2009-08-07 22:41 ` [PATCH 04/16] iwlwifi: Traffic type and counter for debugFs Reinette Chatre
2009-08-07 22:41 ` [PATCH 05/16] iwlwifi: tx/rx queue pointer information Reinette Chatre
2009-08-07 22:41 ` [PATCH 06/16] iwlwifi: uCode statistics notification counter Reinette Chatre
2009-08-07 22:41 ` [PATCH 07/16] iwlwifi: Display sensitivity and chain noise information Reinette Chatre
2009-08-07 22:41 ` [PATCH 08/16] iwlwifi: revert uCode Alive notification with timeout Reinette Chatre
2009-08-07 22:41 ` Reinette Chatre [this message]
2009-08-07 22:41 ` [PATCH 10/16] iwlwifi: fix legacy thermal throttling power index Reinette Chatre
2009-08-07 22:41 ` [PATCH 11/16] iwlwifi: handle the case when set power fail Reinette Chatre
2009-08-07 22:41 ` [PATCH 12/16] iwlwifi: refactor some thermal throttle code Reinette Chatre
2009-08-07 22:41 ` [PATCH 13/16] iwlwifi: fix missing EXPORT_SYMBOL Reinette Chatre
2009-08-07 22:41 ` [PATCH 14/16] iwlwifi: display correct critical temperature infomation Reinette Chatre
2009-08-07 22:41 ` [PATCH 15/16] iwlwifi: automatically adjust sleep level Reinette Chatre
2009-08-07 22:41 ` [PATCH 16/16] iwlwifi: disable powersave mode Reinette Chatre
2009-08-08 8:25 ` Kalle Valo
2009-08-08 19:36 ` reinette chatre
2009-08-12 18:54 ` Kalle Valo
2009-08-12 21:53 ` reinette chatre
2009-08-14 17:20 ` Kalle Valo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1249684912-22936-10-git-send-email-reinette.chatre@intel.com \
--to=reinette.chatre@intel.com \
--cc=ipw3945-devel@lists.sourceforge.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=wey-yi.w.guy@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).