mutex_unlock(&trans_pcie->mutex);
 }
 
-static void iwl_pcie_set_ltr(struct iwl_trans *trans)
+static bool iwl_pcie_set_ltr(struct iwl_trans *trans)
 {
        u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
                      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
             trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
            !trans->trans_cfg->integrated) {
                iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
-       } else if (trans->trans_cfg->integrated &&
-                  trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
+               return true;
+       }
+
+       if (trans->trans_cfg->integrated &&
+           trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
                iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
                iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
+               return true;
+       }
+
+       if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
+               /* First clear the interrupt, just in case */
+               iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD,
+                           MSIX_HW_INT_CAUSES_REG_IML);
+               /* In this case, unfortunately the same ROM bug exists in the
+                * device (not setting LTR correctly), but we don't have control
+                * over the settings from the host due to some hardware security
+                * features. The only workaround we've been able to come up with
+                * so far is to try to keep the CPU and device busy by polling
+                * it and the IML (image loader) completed interrupt.
+                */
+               return false;
+       }
+
+       /* nothing needs to be done on other devices */
+       return true;
+}
+
+static void iwl_pcie_spin_for_iml(struct iwl_trans *trans)
+{
+/* in practice, this seems to complete in around 20-30ms at most, wait 100 */
+#define IML_WAIT_TIMEOUT       (HZ / 10)
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       unsigned long end_time = jiffies + IML_WAIT_TIMEOUT;
+       u32 value, loops = 0;
+       bool irq = false;
+
+       if (WARN_ON(!trans_pcie->iml))
+               return;
+
+       value = iwl_read32(trans, CSR_LTR_LAST_MSG);
+       IWL_DEBUG_INFO(trans, "Polling for IML load - CSR_LTR_LAST_MSG=0x%x\n",
+                      value);
+
+       while (time_before(jiffies, end_time)) {
+               if (iwl_read32(trans, CSR_MSIX_HW_INT_CAUSES_AD) &
+                               MSIX_HW_INT_CAUSES_REG_IML) {
+                       irq = true;
+                       break;
+               }
+               /* Keep the CPU and device busy. */
+               value = iwl_read32(trans, CSR_LTR_LAST_MSG);
+               loops++;
        }
+
+       IWL_DEBUG_INFO(trans,
+                      "Polled for IML load: irq=%d, loops=%d, CSR_LTR_LAST_MSG=0x%x\n",
+                      irq, loops, value);
+
+       /* We don't fail here even if we timed out - maybe we get lucky and the
+        * interrupt comes in later (and we get alive from firmware) and then
+        * we're all happy - but if not we'll fail on alive timeout or get some
+        * other error out.
+        */
 }
 
 int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
                                 const struct fw_img *fw, bool run_in_rfkill)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-       bool hw_rfkill;
+       bool hw_rfkill, keep_ram_busy;
        int ret;
 
        /* This may fail if AMT took ownership of the device */
        if (ret)
                goto out;
 
-       iwl_pcie_set_ltr(trans);
+       keep_ram_busy = !iwl_pcie_set_ltr(trans);
 
        if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_BZ) {
                iwl_write32(trans, CSR_FUNC_SCRATCH, CSR_FUNC_SCRATCH_INIT_VALUE);
                iwl_write_prph(trans, UREG_CPU_INIT_RUN, 1);
        }
 
+       if (keep_ram_busy)
+               iwl_pcie_spin_for_iml(trans);
+
        /* re-check RF-Kill state since we may have missed the interrupt */
        hw_rfkill = iwl_pcie_check_hw_rf_kill(trans);
        if (hw_rfkill && !run_in_rfkill)