/******************************************************************************
 *
 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
 * 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 "src/iwlwifi/mvm/mvm.h"

#if 0  // NEEDS_PORTING
#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ

void iwl_mvm_enter_ctkill(struct iwl_mvm* mvm) {
    struct iwl_mvm_tt_mgmt* tt = &mvm->thermal_throttle;
    uint32_t duration = tt->params.ct_kill_duration;

    if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) { return; }

    IWL_ERR(mvm, "Enter CT Kill\n");
    iwl_mvm_set_hw_ctkill_state(mvm, true);

    if (!iwl_mvm_is_tt_in_fw(mvm)) {
        tt->throttle = false;
        tt->dynamic_smps = false;
    }

    /* 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) {
        schedule_delayed_work(&tt->ct_kill_exit, round_jiffies_relative(duration * HZ));
    }
}

static void iwl_mvm_exit_ctkill(struct iwl_mvm* mvm) {
    if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) { return; }

    IWL_ERR(mvm, "Exit CT Kill\n");
    iwl_mvm_set_hw_ctkill_state(mvm, false);
}

void iwl_mvm_tt_temp_changed(struct iwl_mvm* mvm, uint32_t 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) {
    struct iwl_dts_measurement_notif_v1* notif_v1;
    int len = iwl_rx_packet_payload_len(pkt);
    int temp;

    /* we can use notif_v1 only, because v2 only adds an additional
     * parameter, which is not used in this function.
     */
    if (WARN_ON_ONCE(len < sizeof(*notif_v1))) {
        IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n");
        return -EINVAL;
    }

    notif_v1 = (void*)pkt->data;

    temp = le32_to_cpu(notif_v1->temp);

    /* shouldn't be negative, but since it's int32_t, make sure it isn't */
    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;

    return true;
}

void iwl_mvm_temp_notif(struct iwl_mvm* mvm, struct iwl_rx_cmd_buffer* rxb) {
    struct iwl_rx_packet* pkt = rxb_addr(rxb);
    struct iwl_dts_measurement_notif_v2* notif_v2;
    int len = iwl_rx_packet_payload_len(pkt);
    int temp;
    uint32_t ths_crossed;

    /* the notification is handled synchronously in ctkill, so skip here */
    if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) { return; }

    temp = iwl_mvm_temp_notif_parse(mvm, pkt);

    if (!iwl_mvm_is_tt_in_fw(mvm)) {
        if (temp >= 0) { iwl_mvm_tt_temp_changed(mvm, temp); }
        return;
    }

    if (WARN_ON_ONCE(len < sizeof(*notif_v2))) {
        IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n");
        return;
    }

    notif_v2 = (void*)pkt->data;
    ths_crossed = le32_to_cpu(notif_v2->threshold_idx);

    /* 0xFF in ths_crossed means the notification is not related
     * to a trip, so we can ignore it here.
     */
    if (ths_crossed == 0xFF) { return; }

    IWL_DEBUG_TEMP(mvm, "Temp = %d Threshold crossed = %d\n", temp, ths_crossed);

#ifdef CONFIG_THERMAL
    if (WARN_ON(ths_crossed >= IWL_MAX_DTS_TRIPS)) { return; }

    if (mvm->tz_device.tzone) {
        struct iwl_mvm_thermal_device* tz_dev = &mvm->tz_device;

        thermal_notify_framework(tz_dev->tzone, tz_dev->fw_trips_index[ths_crossed]);
    }
#endif  /* CONFIG_THERMAL */
}

void iwl_mvm_ct_kill_notif(struct iwl_mvm* mvm, struct iwl_rx_cmd_buffer* rxb) {
    struct iwl_rx_packet* pkt = rxb_addr(rxb);
    struct ct_kill_notif* notif;
    int len = iwl_rx_packet_payload_len(pkt);

    if (WARN_ON_ONCE(len != sizeof(*notif))) {
        IWL_ERR(mvm, "Invalid CT_KILL_NOTIFICATION\n");
        return;
    }

    notif = (struct ct_kill_notif*)pkt->data;
    IWL_DEBUG_TEMP(mvm, "CT Kill notification temperature = %d\n", notif->temperature);

    iwl_mvm_enter_ctkill(mvm);
}

static int iwl_mvm_get_temp_cmd(struct iwl_mvm* mvm) {
    struct iwl_dts_measurement_cmd cmd = {
        .flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
    };
    struct iwl_ext_dts_measurement_cmd extcmd = {
        .control_mode = cpu_to_le32(DTS_AUTOMATIC),
    };
    uint32_t cmdid;

    cmdid = iwl_cmd_id(CMD_DTS_MEASUREMENT_TRIGGER_WIDE, PHY_OPS_GROUP, 0);

    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);
}

int iwl_mvm_get_temp(struct iwl_mvm* mvm, int32_t* temp) {
    struct iwl_notification_wait wait_temp_notif;
    static uint16_t temp_notif[] = {WIDE_ID(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE)};
    int ret;

    iwl_assert_lock_held(&mvm->mutex);

    iwl_init_notification_wait(&mvm->notif_wait, &wait_temp_notif, temp_notif,
                               ARRAY_SIZE(temp_notif), iwl_mvm_temp_notif_wait, temp);

    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;
    }

    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;
}

static void check_exit_ctkill(struct work_struct* work) {
    struct iwl_mvm_tt_mgmt* tt;
    struct iwl_mvm* mvm;
    uint32_t duration;
    int32_t temp;
    int ret;

    tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work);
    mvm = container_of(tt, struct iwl_mvm, thermal_throttle);

    if (iwl_mvm_is_tt_in_fw(mvm)) {
        iwl_mvm_exit_ctkill(mvm);

        return;
    }

    duration = tt->params.ct_kill_duration;

    mutex_lock(&mvm->mutex);

    if (__iwl_mvm_mac_start(mvm)) { goto reschedule; }

    /* make sure the device is available for direct read/writes */
    if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) {
        __iwl_mvm_mac_stop(mvm);
        goto reschedule;
    }

    ret = iwl_mvm_get_temp(mvm, &temp);

    iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL);

    __iwl_mvm_mac_stop(mvm);

    if (ret) { goto reschedule; }

    IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp);

    if (temp <= tt->params.ct_kill_exit) {
        mutex_unlock(&mvm->mutex);
        iwl_mvm_exit_ctkill(mvm);
        return;
    }

reschedule:
    mutex_unlock(&mvm->mutex);
    schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, round_jiffies(duration * HZ));
}

static void iwl_mvm_tt_smps_iterator(void* _data, uint8_t* mac, struct ieee80211_vif* vif) {
    struct iwl_mvm* mvm = _data;
    enum ieee80211_smps_mode smps_mode;

    iwl_assert_lock_held(&mvm->mutex);

    if (mvm->thermal_throttle.dynamic_smps) {
        smps_mode = IEEE80211_SMPS_DYNAMIC;
    } else {
        smps_mode = IEEE80211_SMPS_AUTOMATIC;
    }

    if (vif->type != NL80211_IFTYPE_STATION) { return; }

    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 iwl_mvm_sta* mvmsta;
    int i, err;

    for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
        mvmsta = iwl_mvm_sta_from_staid_protected(mvm, i);
        if (!mvmsta) { continue; }

        if (enable == mvmsta->tt_tx_protection) { continue; }
        err = iwl_mvm_tx_protection(mvm, mvmsta, enable);
        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;
        }
    }
}
#endif  // NEEDS_PORTING

void iwl_mvm_tt_tx_backoff(struct iwl_mvm* mvm, uint32_t backoff) {
  struct iwl_host_cmd cmd = {
      .id = REPLY_THERMAL_MNG_BACKOFF,
      .len =
          {
              sizeof(uint32_t),
          },
      .data =
          {
              &backoff,
          },
  };

  backoff = MAX(backoff, mvm->thermal_throttle.min_backoff);

  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");
  }
}

#if 0  // NEEDS_PORTING
void iwl_mvm_tt_handler(struct iwl_mvm* mvm) {
    struct iwl_tt_params* params = &mvm->thermal_throttle.params;
    struct iwl_mvm_tt_mgmt* tt = &mvm->thermal_throttle;
    int32_t temperature = mvm->temperature;
    bool throttle_enable = false;
    int i;
    uint32_t 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;
    }

    if (params->support_ct_kill && temperature <= params->ct_kill_exit) {
        iwl_mvm_exit_ctkill(mvm);
        return;
    }

    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);
            throttle_enable = true;
        } 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) {
        if (temperature >= params->tx_protection_entry) {
            iwl_mvm_tt_tx_protection(mvm, true);
            throttle_enable = true;
        } else if (temperature <= params->tx_protection_exit) {
            iwl_mvm_tt_tx_protection(mvm, false);
        }
    }

    if (params->support_tx_backoff) {
        tx_backoff = tt->min_backoff;
        for (i = 0; i < TT_TX_BACKOFF_SIZE; i++) {
            if (temperature < params->tx_backoff[i].temperature) { break; }
            tx_backoff = max(tt->min_backoff, params->tx_backoff[i].backoff);
        }
        if (tx_backoff != tt->min_backoff) { throttle_enable = true; }
        if (tt->tx_backoff != tx_backoff) { iwl_mvm_tt_tx_backoff(mvm, tx_backoff); }
    }

    if (!tt->throttle && throttle_enable) {
        IWL_WARN(mvm, "Due to high temperature thermal throttling initiated\n");
        tt->throttle = true;
    } else if (tt->throttle && !tt->dynamic_smps && tt->tx_backoff == tt->min_backoff &&
               temperature <= params->tx_protection_exit) {
        IWL_WARN(mvm, "Temperature is back to normal thermal throttling stopped\n");
        tt->throttle = false;
    }
}

static const struct iwl_tt_params iwl_mvm_default_tt_params = {
    .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,
};

/* budget in mWatt */
static const uint32_t iwl_mvm_cdev_budgets[] = {
    2000, /* cooling state 0 */
    1800, /* cooling state 1 */
    1600, /* cooling state 2 */
    1400, /* cooling state 3 */
    1200, /* cooling state 4 */
    1000, /* cooling state 5 */
    900,  /* cooling state 6 */
    800,  /* cooling state 7 */
    700,  /* cooling state 8 */
    650,  /* cooling state 9 */
    600,  /* cooling state 10 */
    550,  /* cooling state 11 */
    500,  /* cooling state 12 */
    450,  /* cooling state 13 */
    400,  /* cooling state 14 */
    350,  /* cooling state 15 */
    300,  /* cooling state 16 */
    250,  /* cooling state 17 */
    200,  /* cooling state 18 */
    150,  /* cooling state 19 */
};

int iwl_mvm_ctdp_command(struct iwl_mvm* mvm, uint32_t op, uint32_t state) {
    struct iwl_mvm_ctdp_cmd cmd = {
        .operation = cpu_to_le32(op),
        .budget = cpu_to_le32(iwl_mvm_cdev_budgets[state]),
        .window_size = 0,
    };
    int ret;
    uint32_t status;

    iwl_assert_lock_held(&mvm->mutex);

    status = 0;
    ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP, CTDP_CONFIG_CMD), sizeof(cmd),
                                      &cmd, &status);

    if (ret) {
        IWL_ERR(mvm, "cTDP command failed (err=%d)\n", ret);
        return ret;
    }

    switch (op) {
    case CTDP_CMD_OPERATION_START:
#ifdef CONFIG_THERMAL
        mvm->cooling_dev.cur_state = state;
#endif /* CONFIG_THERMAL */
        break;
    case CTDP_CMD_OPERATION_REPORT:
        IWL_DEBUG_TEMP(mvm, "cTDP avg energy in mWatt = %d\n", status);
        /* when the function is called with CTDP_CMD_OPERATION_REPORT
         * option the function should return the average budget value
         * that is received from the FW.
         * The budget can't be less or equal to 0, so it's possible
         * to distinguish between error values and budgets.
         */
        return status;
    case CTDP_CMD_OPERATION_STOP:
        IWL_DEBUG_TEMP(mvm, "cTDP stopped successfully\n");
        break;
    }

    return 0;
}

#ifdef CONFIG_THERMAL
static int compare_temps(const void* a, const void* b) {
    return ((int16_t)le16_to_cpu(*(__le16*)a) - (int16_t)le16_to_cpu(*(__le16*)b));
}

int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm* mvm) {
    struct temp_report_ths_cmd cmd = {0};
    int ret, i, j, idx = 0;

    iwl_assert_lock_held(&mvm->mutex);

    if (!mvm->tz_device.tzone) { return -EINVAL; }

    /* The driver holds array of temperature trips that are unsorted
     * and uncompressed, the FW should get it compressed and sorted
     */

    /* compress temp_trips to cmd array, remove uninitialized values*/
    for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
        if (mvm->tz_device.temp_trips[i] != S16_MIN) {
            cmd.thresholds[idx++] = cpu_to_le16(mvm->tz_device.temp_trips[i]);
        }
    }
    cmd.num_temps = cpu_to_le32(idx);

    if (!idx) { goto send; }

    /*sort cmd array*/
    sort(cmd.thresholds, idx, sizeof(int16_t), compare_temps, NULL);

    /* we should save the indexes of trips because we sort
     * and compress the orginal array
     */
    for (i = 0; i < idx; i++) {
        for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
            if (le16_to_cpu(cmd.thresholds[i]) == mvm->tz_device.temp_trips[j]) {
                mvm->tz_device.fw_trips_index[i] = j;
            }
        }
    }

send:
    ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP, TEMP_REPORTING_THRESHOLDS_CMD), 0,
                               sizeof(cmd), &cmd);
    if (ret) { IWL_ERR(mvm, "TEMP_REPORT_THS_CMD command failed (err=%d)\n", ret); }

    return ret;
}

static int iwl_mvm_tzone_get_temp(struct thermal_zone_device* device, int* temperature) {
    struct iwl_mvm* mvm = (struct iwl_mvm*)device->devdata;
    int ret;
    int temp;

    mutex_lock(&mvm->mutex);

    if (!iwl_mvm_firmware_running(mvm) || mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
        ret = -ENODATA;
        goto out;
    }

    ret = iwl_mvm_get_temp(mvm, &temp);
    if (ret) { goto out; }

    *temperature = temp * 1000;

out:
    mutex_unlock(&mvm->mutex);
    return ret;
}

static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device* device, int trip, int* temp) {
    struct iwl_mvm* mvm = (struct iwl_mvm*)device->devdata;

    if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) { return -EINVAL; }

    *temp = mvm->tz_device.temp_trips[trip] * 1000;

    return 0;
}

static int iwl_mvm_tzone_get_trip_type(struct thermal_zone_device* device, int trip,
                                       enum thermal_trip_type* type) {
    if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) { return -EINVAL; }

    *type = THERMAL_TRIP_PASSIVE;

    return 0;
}

static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device* device, int trip, int temp) {
    struct iwl_mvm* mvm = (struct iwl_mvm*)device->devdata;
    struct iwl_mvm_thermal_device* tzone;
    int i, ret;
    int16_t temperature;

    mutex_lock(&mvm->mutex);

    if (!iwl_mvm_firmware_running(mvm) || mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
        ret = -EIO;
        goto out;
    }

    if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
        ret = -EINVAL;
        goto out;
    }

    if ((temp / 1000) > S16_MAX) {
        ret = -EINVAL;
        goto out;
    }

    temperature = (int16_t)(temp / 1000);
    tzone = &mvm->tz_device;

    if (!tzone) {
        ret = -EIO;
        goto out;
    }

    /* no updates*/
    if (tzone->temp_trips[trip] == temperature) {
        ret = 0;
        goto out;
    }

    /* already existing temperature */
    for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
        if (tzone->temp_trips[i] == temperature) {
            ret = -EINVAL;
            goto out;
        }
    }

    tzone->temp_trips[trip] = temperature;

    ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
out:
    mutex_unlock(&mvm->mutex);
    return ret;
}

static struct thermal_zone_device_ops tzone_ops = {
    .get_temp = iwl_mvm_tzone_get_temp,
    .get_trip_temp = iwl_mvm_tzone_get_trip_temp,
    .get_trip_type = iwl_mvm_tzone_get_trip_type,
    .set_trip_temp = iwl_mvm_tzone_set_trip_temp,
};

/* make all trips writable */
#define IWL_WRITABLE_TRIPS_MSK (BIT(IWL_MAX_DTS_TRIPS) - 1)

static void iwl_mvm_thermal_zone_register(struct iwl_mvm* mvm) {
    int i;
    char name[] = "iwlwifi";

    if (!iwl_mvm_is_tt_in_fw(mvm)) {
        mvm->tz_device.tzone = NULL;

        return;
    }

    BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);

    mvm->tz_device.tzone = thermal_zone_device_register(
        name, IWL_MAX_DTS_TRIPS, IWL_WRITABLE_TRIPS_MSK, mvm, &tzone_ops, NULL, 0, 0);
    if (IS_ERR(mvm->tz_device.tzone)) {
        IWL_DEBUG_TEMP(mvm, "Failed to register to thermal zone (err = %ld)\n",
                       PTR_ERR(mvm->tz_device.tzone));
        mvm->tz_device.tzone = NULL;
        return;
    }

    /* 0 is a valid temperature,
     * so initialize the array with S16_MIN which invalid temperature
     */
    for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
        mvm->tz_device.temp_trips[i] = S16_MIN;
    }
}

static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device* cdev, unsigned long* state) {
    *state = ARRAY_SIZE(iwl_mvm_cdev_budgets) - 1;

    return 0;
}

static int iwl_mvm_tcool_get_cur_state(struct thermal_cooling_device* cdev, unsigned long* state) {
    struct iwl_mvm* mvm = (struct iwl_mvm*)(cdev->devdata);

    *state = mvm->cooling_dev.cur_state;

    return 0;
}

static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device* cdev,
                                       unsigned long new_state) {
    struct iwl_mvm* mvm = (struct iwl_mvm*)(cdev->devdata);
    int ret;

    mutex_lock(&mvm->mutex);

    if (!iwl_mvm_firmware_running(mvm) || mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
        ret = -EIO;
        goto unlock;
    }

    if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) {
        ret = -EINVAL;
        goto unlock;
    }

    ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START, new_state);

unlock:
    mutex_unlock(&mvm->mutex);
    return ret;
}

static const struct thermal_cooling_device_ops tcooling_ops = {
    .get_max_state = iwl_mvm_tcool_get_max_state,
    .get_cur_state = iwl_mvm_tcool_get_cur_state,
    .set_cur_state = iwl_mvm_tcool_set_cur_state,
};

static void iwl_mvm_cooling_device_register(struct iwl_mvm* mvm) {
    char name[] = "iwlwifi";

    if (!iwl_mvm_is_ctdp_supported(mvm)) { return; }

    BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);

    mvm->cooling_dev.cdev = thermal_cooling_device_register(name, mvm, &tcooling_ops);

    if (IS_ERR(mvm->cooling_dev.cdev)) {
        IWL_DEBUG_TEMP(mvm, "Failed to register to cooling device (err = %ld)\n",
                       PTR_ERR(mvm->cooling_dev.cdev));
        mvm->cooling_dev.cdev = NULL;
        return;
    }
}

static void iwl_mvm_thermal_zone_unregister(struct iwl_mvm* mvm) {
    if (!iwl_mvm_is_tt_in_fw(mvm) || !mvm->tz_device.tzone) { return; }

    IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n");
    if (mvm->tz_device.tzone) {
        thermal_zone_device_unregister(mvm->tz_device.tzone);
        mvm->tz_device.tzone = NULL;
    }
}

static void iwl_mvm_cooling_device_unregister(struct iwl_mvm* mvm) {
    if (!iwl_mvm_is_ctdp_supported(mvm) || !mvm->cooling_dev.cdev) { return; }

    IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n");
    if (mvm->cooling_dev.cdev) {
        thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
        mvm->cooling_dev.cdev = NULL;
    }
}
#endif  /* CONFIG_THERMAL */
#endif  // NEEDS_PORTING

void iwl_mvm_thermal_initialize(struct iwl_mvm* mvm, uint32_t min_backoff) {
#if 0  // NEEDS_PORTING
    struct iwl_mvm_tt_mgmt* tt = &mvm->thermal_throttle;

    IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");

    if (mvm->cfg->thermal_params) {
        tt->params = *mvm->cfg->thermal_params;
    } else {
        tt->params = iwl_mvm_default_tt_params;
    }

    tt->throttle = false;
    tt->dynamic_smps = false;
    tt->min_backoff = min_backoff;
    INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);

#ifdef CONFIG_THERMAL
    iwl_mvm_cooling_device_register(mvm);
    iwl_mvm_thermal_zone_register(mvm);
#endif
    mvm->init_status |= IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE;
#endif  // NEEDS_PORTING
}

void iwl_mvm_thermal_exit(struct iwl_mvm* mvm) {
  if (!(mvm->init_status & IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE)) {
    return;
  }

#if 0   // NEEDS_PORTING
    cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit);
    IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n");
#endif  // NEEDS_PORTING

#ifdef CONFIG_THERMAL
  iwl_mvm_cooling_device_unregister(mvm);
  iwl_mvm_thermal_zone_unregister(mvm);
#endif
  mvm->init_status &= ~IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE;
}
