summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/scsi/ufs/ufshcd.h38
-rw-r--r--include/trace/events/ufs.h20
2 files changed, 58 insertions, 0 deletions
diff --git a/include/linux/scsi/ufs/ufshcd.h b/include/linux/scsi/ufs/ufshcd.h
index 7109f59f9e80..a80130c959eb 100644
--- a/include/linux/scsi/ufs/ufshcd.h
+++ b/include/linux/scsi/ufs/ufshcd.h
@@ -343,6 +343,35 @@ struct ufs_clk_gating {
int active_reqs;
};
+/* Hibern8 state */
+enum ufshcd_hibern8_on_idle_state {
+ HIBERN8_ENTERED,
+ HIBERN8_EXITED,
+ REQ_HIBERN8_ENTER,
+ REQ_HIBERN8_EXIT,
+};
+
+/**
+ * struct ufs_hibern8_on_idle - UFS Hibern8 on idle related data
+ * @enter_work: worker to put UFS link in hibern8 after some delay as
+ * specified in delay_ms
+ * @exit_work: worker to bring UFS link out of hibern8
+ * @state: the current hibern8 state
+ * @delay_ms: hibern8 enter delay in ms
+ * @is_suspended: hibern8 enter is suspended when set to 1 which can be used
+ * during suspend/resume
+ * @active_reqs: number of requests that are pending and should be waited for
+ * completion before scheduling delayed "enter_work".
+ */
+struct ufs_hibern8_on_idle {
+ struct delayed_work enter_work;
+ struct work_struct exit_work;
+ enum ufshcd_hibern8_on_idle_state state;
+ unsigned long delay_ms;
+ bool is_suspended;
+ int active_reqs;
+};
+
struct ufs_clk_scaling {
ktime_t busy_start_t;
bool is_busy_started;
@@ -450,6 +479,7 @@ enum ts_types {
* @clk_list_head: UFS host controller clocks list node head
* @pwr_info: holds current power mode
* @max_pwr_info: keeps the device max valid pwm
+ * @hibern8_on_idle: UFS Hibern8 on idle related data
*/
struct ufs_hba {
void __iomem *mmio_base;
@@ -591,6 +621,8 @@ struct ufs_hba {
struct ufs_pwr_mode_info max_pwr_info;
struct ufs_clk_gating clk_gating;
+ struct ufs_hibern8_on_idle hibern8_on_idle;
+
/* Control to enable/disable host capabilities */
u32 caps;
/* Allow dynamic clk gating */
@@ -607,6 +639,8 @@ struct ufs_hba {
* CAUTION: Enabling this might reduce overall UFS throughput.
*/
#define UFSHCD_CAP_INTR_AGGR (1 << 4)
+ /* Allow standalone Hibern8 enter on idle */
+#define UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE (1 << 5)
struct devfreq *devfreq;
struct ufs_clk_scaling clk_scaling;
@@ -630,6 +664,10 @@ static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba)
{
return hba->caps & UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
}
+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_is_intr_aggr_allowed(struct ufs_hba *hba)
{
diff --git a/include/trace/events/ufs.h b/include/trace/events/ufs.h
index 7b3d9e140272..13bf97b19a71 100644
--- a/include/trace/events/ufs.h
+++ b/include/trace/events/ufs.h
@@ -39,6 +39,26 @@ TRACE_EVENT(ufshcd_clk_gating,
__get_str(dev_name), __get_str(state))
);
+TRACE_EVENT(ufshcd_hibern8_on_idle,
+
+ TP_PROTO(const char *dev_name, const char *state),
+
+ TP_ARGS(dev_name, state),
+
+ TP_STRUCT__entry(
+ __string(dev_name, dev_name)
+ __string(state, state)
+ ),
+
+ TP_fast_assign(
+ __assign_str(dev_name, dev_name);
+ __assign_str(state, state);
+ ),
+
+ TP_printk("%s: state changed to %s",
+ __get_str(dev_name), __get_str(state))
+);
+
TRACE_EVENT(ufshcd_clk_scaling,
TP_PROTO(const char *dev_name, const char *state, const char *clk,