aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2016-02-28 03:15:08 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2016-03-06 15:01:32 -0500
commit91f66a3c672065a3aca387ca7e0028504bb8f457 (patch)
tree1a52a183c41716c38b87ec89d5575223f92f45f3 /drivers/net/wireless/intel/iwlwifi/mvm/tt.c
parente5f91d91ac2e09f93f58ab8f6813d12f2b3afa03 (diff)
iwlwifi: mvm: avoid panics with thermal device usage
Thermal zone device registration can fail, and in this case we don't want to remove WiFi functionality. This is why the thermal zone registration function is void, and the flows continue even if the thermal zone device registration failed. Same applies for the cooling device. This means that we at least need to remember that the thermal zone device didn't register properly and take the minimal precautions to avoid panic'ing when we access it. This was missing. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/tt.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tt.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 999bcb898be8..0a02e9835d6b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -211,10 +211,14 @@ void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
211 * the firmware and hence to take the mutex. 211 * the firmware and hence to take the mutex.
212 * Avoid the deadlock by unlocking the mutex here. 212 * Avoid the deadlock by unlocking the mutex here.
213 */ 213 */
214 mutex_unlock(&mvm->mutex); 214 if (mvm->tz_device.tzone) {
215 thermal_notify_framework(mvm->tz_device.tzone, 215 struct iwl_mvm_thermal_device *tz_dev = &mvm->tz_device;
216 mvm->tz_device.fw_trips_index[ths_crossed]); 216
217 mutex_lock(&mvm->mutex); 217 mutex_unlock(&mvm->mutex);
218 thermal_notify_framework(tz_dev->tzone,
219 tz_dev->fw_trips_index[ths_crossed]);
220 mutex_lock(&mvm->mutex);
221 }
218#endif /* CONFIG_THERMAL */ 222#endif /* CONFIG_THERMAL */
219} 223}
220 224
@@ -520,16 +524,20 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
520 524
521 lockdep_assert_held(&mvm->mutex); 525 lockdep_assert_held(&mvm->mutex);
522 526
527 if (!mvm->tz_device.tzone)
528 return -EINVAL;
529
523 /* The driver holds array of temperature trips that are unsorted 530 /* The driver holds array of temperature trips that are unsorted
524 * and uncompressed, the FW should get it compressed and sorted 531 * and uncompressed, the FW should get it compressed and sorted
525 */ 532 */
526 533
527 /* compress temp_trips to cmd array, remove uninitialized values*/ 534 /* compress temp_trips to cmd array, remove uninitialized values*/
528 for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) 535 for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
529 if (mvm->tz_device.temp_trips[i] != S16_MIN) { 536 if (mvm->tz_device.temp_trips[i] != S16_MIN) {
530 cmd.thresholds[idx++] = 537 cmd.thresholds[idx++] =
531 cpu_to_le16(mvm->tz_device.temp_trips[i]); 538 cpu_to_le16(mvm->tz_device.temp_trips[i]);
532 } 539 }
540 }
533 cmd.num_temps = cpu_to_le32(idx); 541 cmd.num_temps = cpu_to_le32(idx);
534 542
535 if (!idx) 543 if (!idx)
@@ -696,6 +704,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
696 IWL_DEBUG_TEMP(mvm, 704 IWL_DEBUG_TEMP(mvm,
697 "Failed to register to thermal zone (err = %ld)\n", 705 "Failed to register to thermal zone (err = %ld)\n",
698 PTR_ERR(mvm->tz_device.tzone)); 706 PTR_ERR(mvm->tz_device.tzone));
707 mvm->tz_device.tzone = NULL;
699 return; 708 return;
700 } 709 }
701 710
@@ -750,6 +759,10 @@ int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget)
750 return ret; 759 return ret;
751 } 760 }
752 761
762 /* can happen if the registration failed */
763 if (!mvm->cooling_dev.cdev)
764 return -EINVAL;
765
753 if (op == CTDP_CMD_OPERATION_START) 766 if (op == CTDP_CMD_OPERATION_START)
754 mvm->cooling_dev.cur_state = budget; 767 mvm->cooling_dev.cur_state = budget;
755 768
@@ -812,15 +825,12 @@ static struct thermal_cooling_device_ops tcooling_ops = {
812 .set_cur_state = iwl_mvm_tcool_set_cur_state, 825 .set_cur_state = iwl_mvm_tcool_set_cur_state,
813}; 826};
814 827
815int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm) 828static void iwl_mvm_cooling_device_register(struct iwl_mvm *mvm)
816{ 829{
817 char name[] = "iwlwifi"; 830 char name[] = "iwlwifi";
818 831
819 if (!iwl_mvm_is_ctdp_supported(mvm)) { 832 if (!iwl_mvm_is_ctdp_supported(mvm))
820 mvm->cooling_dev.cdev = NULL; 833 return;
821
822 return 0;
823 }
824 834
825 BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH); 835 BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
826 836
@@ -833,34 +843,29 @@ int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm)
833 IWL_DEBUG_TEMP(mvm, 843 IWL_DEBUG_TEMP(mvm,
834 "Failed to register to cooling device (err = %ld)\n", 844 "Failed to register to cooling device (err = %ld)\n",
835 PTR_ERR(mvm->cooling_dev.cdev)); 845 PTR_ERR(mvm->cooling_dev.cdev));
836 return PTR_ERR(mvm->cooling_dev.cdev); 846 mvm->cooling_dev.cdev = NULL;
847 return;
837 } 848 }
838
839 return 0;
840} 849}
841 850
842static void iwl_mvm_thermal_zone_unregister(struct iwl_mvm *mvm) 851static void iwl_mvm_thermal_zone_unregister(struct iwl_mvm *mvm)
843{ 852{
844 if (!iwl_mvm_is_tt_in_fw(mvm)) 853 if (!iwl_mvm_is_tt_in_fw(mvm) || !mvm->tz_device.tzone)
845 return; 854 return;
846 855
847 if (mvm->tz_device.tzone) { 856 IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n");
848 IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n"); 857 thermal_zone_device_unregister(mvm->tz_device.tzone);
849 thermal_zone_device_unregister(mvm->tz_device.tzone); 858 mvm->tz_device.tzone = NULL;
850 mvm->tz_device.tzone = NULL;
851 }
852} 859}
853 860
854static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm) 861static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm)
855{ 862{
856 if (!iwl_mvm_is_ctdp_supported(mvm)) 863 if (!iwl_mvm_is_ctdp_supported(mvm) || !mvm->cooling_dev.cdev)
857 return; 864 return;
858 865
859 if (mvm->cooling_dev.cdev) { 866 IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n");
860 IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n"); 867 thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
861 thermal_cooling_device_unregister(mvm->cooling_dev.cdev); 868 mvm->cooling_dev.cdev = NULL;
862 mvm->cooling_dev.cdev = NULL;
863 }
864} 869}
865#endif /* CONFIG_THERMAL */ 870#endif /* CONFIG_THERMAL */
866 871