summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2014-10-15 19:11:03 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 10:57:40 -0700
commit9f06dddf5beecbcdf36535e0e587c23aaa7785f5 (patch)
treefdbf30a7a74bc165761ce8ff400bf349923cf347
parent500f7e1f339cc671ae4659575f8fbabc0614a548 (diff)
scsi: ufs: add capability to keep auto bkops always enabled
UFS device requires to perform bkops (back ground operations) periodically but host can control (via auto-bkops parameter of device) when device can perform bkops based on its performance requirements. In general, host would like to enable the device's auto-bkops only when it's not doing any regular data transfer but sometimes device may not behave properly if host keeps the auto-bkops disabled. This change adds the capability to let the device auto-bkops always enabled except suspend. Change-Id: I92c4531f88cb75a563568270584926eb73b53c98 Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
-rw-r--r--drivers/scsi/ufs/ufshcd.c33
-rw-r--r--include/linux/scsi/ufs/ufshcd.h13
2 files changed, 35 insertions, 11 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index baf93b68f7b4..5568e43612e7 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4352,18 +4352,25 @@ out:
}
/**
- * ufshcd_force_reset_auto_bkops - force enable of auto bkops
+ * ufshcd_force_reset_auto_bkops - force reset auto bkops state
* @hba: per adapter instance
*
* After a device reset the device may toggle the BKOPS_EN flag
* to default value. The s/w tracking variables should be updated
- * as well. Do this by forcing enable of auto bkops.
+ * as well. This function would change the auto-bkops state based on
+ * UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND.
*/
-static void ufshcd_force_reset_auto_bkops(struct ufs_hba *hba)
+static void ufshcd_force_reset_auto_bkops(struct ufs_hba *hba)
{
- hba->auto_bkops_enabled = false;
- hba->ee_ctrl_mask |= MASK_EE_URGENT_BKOPS;
- ufshcd_enable_auto_bkops(hba);
+ if (ufshcd_keep_autobkops_enabled_except_suspend(hba)) {
+ hba->auto_bkops_enabled = false;
+ hba->ee_ctrl_mask |= MASK_EE_URGENT_BKOPS;
+ ufshcd_enable_auto_bkops(hba);
+ } else {
+ hba->auto_bkops_enabled = true;
+ hba->ee_ctrl_mask &= ~MASK_EE_URGENT_BKOPS;
+ ufshcd_disable_auto_bkops(hba);
+ }
}
static inline int ufshcd_get_bkops_status(struct ufs_hba *hba, u32 *status)
@@ -6602,11 +6609,15 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
goto set_old_link_state;
}
- /*
- * If BKOPs operations are urgently needed at this moment then
- * keep auto-bkops enabled or else disable it.
- */
- ufshcd_urgent_bkops(hba);
+ if (ufshcd_keep_autobkops_enabled_except_suspend(hba))
+ ufshcd_enable_auto_bkops(hba);
+ else
+ /*
+ * If BKOPs operations are urgently needed at this moment then
+ * keep auto-bkops enabled or else disable it.
+ */
+ ufshcd_urgent_bkops(hba);
+
hba->clk_gating.is_suspended = false;
hba->hibern8_on_idle.is_suspended = false;
diff --git a/include/linux/scsi/ufs/ufshcd.h b/include/linux/scsi/ufs/ufshcd.h
index c83a58831b25..90b2417f87fb 100644
--- a/include/linux/scsi/ufs/ufshcd.h
+++ b/include/linux/scsi/ufs/ufshcd.h
@@ -647,6 +647,14 @@ struct ufs_hba {
#define UFSHCD_CAP_INTR_AGGR (1 << 4)
/* Allow standalone Hibern8 enter on idle */
#define UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE (1 << 5)
+ /*
+ * This capability allows the device auto-bkops to be always enabled
+ * except during suspend (both runtime and suspend).
+ * Enabling this capability means that device will always be allowed
+ * to do background operation when it's active but it might degrade
+ * the performance of ongoing read/write operations.
+ */
+#define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 5)
struct devfreq *devfreq;
struct ufs_clk_scaling clk_scaling;
@@ -674,6 +682,11 @@ static inline bool ufshcd_is_hibern8_on_idle_allowed(struct ufs_hba *hba)
{
return hba->caps & UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;
}
+static inline bool ufshcd_keep_autobkops_enabled_except_suspend(
+ struct ufs_hba *hba)
+{
+ return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND;
+}
static inline bool ufshcd_is_intr_aggr_allowed(struct ufs_hba *hba)
{