summaryrefslogtreecommitdiff
path: root/drivers/scsi/ufs/ufshcd.h
diff options
context:
space:
mode:
authorsubhashj@codeaurora.org <subhashj@codeaurora.org>2017-02-04 03:57:39 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2017-02-08 02:04:12 +0300
commit401f1e4490ee9d6e74d7514903dd01dae61488bf (patch)
tree50c71ba650c46f4d06745b84df28ae534031026d /drivers/scsi/ufs/ufshcd.h
parent6ba65588381d59ee412b7cb83752d582df731d5c (diff)
downloadlinux-401f1e4490ee9d6e74d7514903dd01dae61488bf.tar.xz
scsi: ufs: don't suspend clock scaling during clock gating
Currently we are suspending clock scaling during clock gating which doesn't allow us to have clock gating timeout lower than clock scaling polling window. If clock gating timeout is smaller than the clock scaling polling window then we will mostly suspend the clock scaling before clock scaling polling window expires and we might get stuck in same state (scaled down or scaled up) for quite a long time. And for this reason, we have clock gating timeout (150ms) greater than clock scaling polling window (100ms). We would like to have aggressive clock gating timeout even lower than the clock scaling polling window hence this change is decoupling the clock scaling suspend/resume from clock gate/ungate. We will not suspend the clock scaling as part of clock gating instead clock scaling context will schedule scaling suspend work if there are no more pending transfer requests. Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs/ufshcd.h')
-rw-r--r--drivers/scsi/ufs/ufshcd.h31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 4da2bbd617e8..7630600217a2 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -357,14 +357,37 @@ struct ufs_saved_pwr_info {
bool is_valid;
};
+/**
+ * struct ufs_clk_scaling - UFS clock scaling related data
+ * @active_reqs: number of requests that are pending. If this is zero when
+ * devfreq ->target() function is called then schedule "suspend_work" to
+ * suspend devfreq.
+ * @tot_busy_t: Total busy time in current polling window
+ * @window_start_t: Start time (in jiffies) of the current polling window
+ * @busy_start_t: Start time of current busy period
+ * @enable_attr: sysfs attribute to enable/disable clock scaling
+ * @saved_pwr_info: UFS power mode may also be changed during scaling and this
+ * one keeps track of previous power mode.
+ * @workq: workqueue to schedule devfreq suspend/resume work
+ * @suspend_work: worker to suspend devfreq
+ * @resume_work: worker to resume devfreq
+ * @is_allowed: tracks if scaling is currently allowed or not
+ * @is_busy_started: tracks if busy period has started or not
+ * @is_suspended: tracks if devfreq is suspended or not
+ */
struct ufs_clk_scaling {
- ktime_t busy_start_t;
- bool is_busy_started;
- unsigned long tot_busy_t;
+ int active_reqs;
+ unsigned long tot_busy_t;
unsigned long window_start_t;
+ ktime_t busy_start_t;
struct device_attribute enable_attr;
- bool is_allowed;
struct ufs_saved_pwr_info saved_pwr_info;
+ struct workqueue_struct *workq;
+ struct work_struct suspend_work;
+ struct work_struct resume_work;
+ bool is_allowed;
+ bool is_busy_started;
+ bool is_suspended;
};
/**