#if IS_ENABLED(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND)
static struct devfreq_simple_ondemand_data ufshcd_ondemand_data = {
- .upthreshold = 35,
- .downdifferential = 30,
+ .upthreshold = 70,
+ .downdifferential = 65,
.simple_scaling = 1,
};
#endif
static struct devfreq_dev_profile ufs_devfreq_profile = {
- .polling_ms = 40,
+ .polling_ms = 60,
.target = ufshcd_devfreq_target,
.get_dev_status = ufshcd_devfreq_get_dev_status,
};
}
}
+#ifdef CONFIG_TRACEPOINTS
static void __ufshcd_cmd_log(struct ufs_hba *hba, char *str, char *cmd_type,
unsigned int tag, u8 cmd_id, u8 idn, u8 lun,
sector_t lba, int transfer_len, u8 opcode)
ufshcd_add_command_trace(hba, entry, opcode);
}
+#endif
static void ufshcd_cmd_log(struct ufs_hba *hba, char *str, char *cmd_type,
unsigned int tag, u8 cmd_id, u8 idn)
{
}
+#ifdef CONFIG_TRACEPOINTS
static void __ufshcd_cmd_log(struct ufs_hba *hba, char *str, char *cmd_type,
unsigned int tag, u8 cmd_id, u8 idn, u8 lun,
sector_t lba, int transfer_len, u8 opcode)
ufshcd_add_command_trace(hba, &entry, opcode);
}
+#endif
static void ufshcd_dme_cmd_log(struct ufs_hba *hba, char *str, u8 cmd_id)
{
hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1;
hba->nutmrs =
((hba->capabilities & MASK_TASK_MANAGEMENT_REQUEST_SLOTS) >> 16) + 1;
+
+ /* disable auto hibern8 */
+ hba->capabilities &= ~MASK_AUTO_HIBERN8_SUPPORT;
}
/**
goto out_unlock;
}
- hba->dev_cmd.query.descriptor = NULL;
*buf_len = be16_to_cpu(response->upiu_res.length);
out_unlock:
+ hba->dev_cmd.query.descriptor = NULL;
mutex_unlock(&hba->dev_cmd.lock);
out:
ufshcd_release_all(hba);
* UFS device needs urgent BKOPs.
*/
if (!hba->pm_op_in_progress &&
- ufshcd_is_exception_event(lrbp->ucd_rsp_ptr))
- schedule_work(&hba->eeh_work);
+ ufshcd_is_exception_event(lrbp->ucd_rsp_ptr)) {
+ /*
+ * Prevent suspend once eeh_work is scheduled
+ * to avoid deadlock between ufshcd_suspend
+ * and exception event handler.
+ */
+ if (schedule_work(&hba->eeh_work))
+ pm_runtime_get_noresume(hba->dev);
+ }
break;
case UPIU_TRANSACTION_REJECT_UPIU:
/* TODO: handle Reject UPIU Response */
out:
ufshcd_scsi_unblock_requests(hba);
+ /*
+ * pm_runtime_get_noresume is called while scheduling
+ * eeh_work to avoid suspend racing with exception work.
+ * Hence decrement usage counter using pm_runtime_put_noidle
+ * to allow suspend on completion of exception event handler.
+ */
+ pm_runtime_put_noidle(hba->dev);
pm_runtime_put(hba->dev);
return;
}
hba = container_of(work, struct ufs_hba, rls_work);
pm_runtime_get_sync(hba->dev);
ufshcd_scsi_block_requests(hba);
+ down_write(&hba->lock);
ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
if (ret) {
dev_err(hba->dev,
hba->restore_needed = false;
out:
+ up_write(&hba->lock);
ufshcd_scsi_unblock_requests(hba);
pm_runtime_put_sync(hba->dev);
}
ufshcd_init_icc_levels(hba);
/* Add required well known logical units to scsi mid layer */
- if (ufshcd_scsi_add_wlus(hba))
+ ret = ufshcd_scsi_add_wlus(hba);
+ if (ret)
goto out;
/* Initialize devfreq after UFS device is detected */
{
int ret = 0;
+ if (!hba->is_powered)
+ goto out;
+
if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba))
goto out;