1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #ifndef _UFSHCD_PRIV_H_
4 #define _UFSHCD_PRIV_H_
5
6 #include <linux/pm_runtime.h>
7 #include <ufs/ufshcd.h>
8
ufshcd_is_user_access_allowed(struct ufs_hba * hba)9 static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba)
10 {
11 return !hba->shutting_down;
12 }
13
14 void ufshcd_schedule_eh_work(struct ufs_hba *hba);
15
ufshcd_keep_autobkops_enabled_except_suspend(struct ufs_hba * hba)16 static inline bool ufshcd_keep_autobkops_enabled_except_suspend(
17 struct ufs_hba *hba)
18 {
19 return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND;
20 }
21
ufshcd_wb_get_query_index(struct ufs_hba * hba)22 static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba)
23 {
24 if (hba->dev_info.wb_buffer_type == WB_BUF_MODE_LU_DEDICATED)
25 return hba->dev_info.wb_dedicated_lu;
26 return 0;
27 }
28
29 #ifdef CONFIG_SCSI_UFS_HWMON
30 void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask);
31 void ufs_hwmon_remove(struct ufs_hba *hba);
32 void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask);
33 #else
ufs_hwmon_probe(struct ufs_hba * hba,u8 mask)34 static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {}
ufs_hwmon_remove(struct ufs_hba * hba)35 static inline void ufs_hwmon_remove(struct ufs_hba *hba) {}
ufs_hwmon_notify_event(struct ufs_hba * hba,u8 ee_mask)36 static inline void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) {}
37 #endif
38
39 int ufshcd_read_desc_param(struct ufs_hba *hba,
40 enum desc_idn desc_id,
41 int desc_index,
42 u8 param_offset,
43 u8 *param_read_buf,
44 u8 param_size);
45 int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode,
46 enum attr_idn idn, u8 index, u8 selector,
47 u32 *attr_val);
48 int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
49 enum attr_idn idn, u8 index, u8 selector, u32 *attr_val);
50 int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
51 enum flag_idn idn, u8 index, bool *flag_res);
52 void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit);
53
54 #define SD_ASCII_STD true
55 #define SD_RAW false
56 int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index,
57 u8 **buf, bool ascii);
58
59 int ufshcd_hold(struct ufs_hba *hba, bool async);
60 void ufshcd_release(struct ufs_hba *hba);
61
62 void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
63 int *desc_length);
64
65 int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd);
66
67 int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
68 struct utp_upiu_req *req_upiu,
69 struct utp_upiu_req *rsp_upiu,
70 int msgcode,
71 u8 *desc_buff, int *buff_len,
72 enum query_opcode desc_op);
73
74 int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable);
75
76 /* Wrapper functions for safely calling variant operations */
ufshcd_get_var_name(struct ufs_hba * hba)77 static inline const char *ufshcd_get_var_name(struct ufs_hba *hba)
78 {
79 if (hba->vops)
80 return hba->vops->name;
81 return "";
82 }
83
ufshcd_vops_exit(struct ufs_hba * hba)84 static inline void ufshcd_vops_exit(struct ufs_hba *hba)
85 {
86 if (hba->vops && hba->vops->exit)
87 return hba->vops->exit(hba);
88 }
89
ufshcd_vops_get_ufs_hci_version(struct ufs_hba * hba)90 static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
91 {
92 if (hba->vops && hba->vops->get_ufs_hci_version)
93 return hba->vops->get_ufs_hci_version(hba);
94
95 return ufshcd_readl(hba, REG_UFS_VERSION);
96 }
97
ufshcd_vops_clk_scale_notify(struct ufs_hba * hba,bool up,enum ufs_notify_change_status status)98 static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba,
99 bool up, enum ufs_notify_change_status status)
100 {
101 if (hba->vops && hba->vops->clk_scale_notify)
102 return hba->vops->clk_scale_notify(hba, up, status);
103 return 0;
104 }
105
ufshcd_vops_event_notify(struct ufs_hba * hba,enum ufs_event_type evt,void * data)106 static inline void ufshcd_vops_event_notify(struct ufs_hba *hba,
107 enum ufs_event_type evt,
108 void *data)
109 {
110 if (hba->vops && hba->vops->event_notify)
111 hba->vops->event_notify(hba, evt, data);
112 }
113
ufshcd_vops_setup_clocks(struct ufs_hba * hba,bool on,enum ufs_notify_change_status status)114 static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on,
115 enum ufs_notify_change_status status)
116 {
117 if (hba->vops && hba->vops->setup_clocks)
118 return hba->vops->setup_clocks(hba, on, status);
119 return 0;
120 }
121
ufshcd_vops_hce_enable_notify(struct ufs_hba * hba,bool status)122 static inline int ufshcd_vops_hce_enable_notify(struct ufs_hba *hba,
123 bool status)
124 {
125 if (hba->vops && hba->vops->hce_enable_notify)
126 return hba->vops->hce_enable_notify(hba, status);
127
128 return 0;
129 }
ufshcd_vops_link_startup_notify(struct ufs_hba * hba,bool status)130 static inline int ufshcd_vops_link_startup_notify(struct ufs_hba *hba,
131 bool status)
132 {
133 if (hba->vops && hba->vops->link_startup_notify)
134 return hba->vops->link_startup_notify(hba, status);
135
136 return 0;
137 }
138
ufshcd_vops_pwr_change_notify(struct ufs_hba * hba,enum ufs_notify_change_status status,struct ufs_pa_layer_attr * dev_max_params,struct ufs_pa_layer_attr * dev_req_params)139 static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba,
140 enum ufs_notify_change_status status,
141 struct ufs_pa_layer_attr *dev_max_params,
142 struct ufs_pa_layer_attr *dev_req_params)
143 {
144 if (hba->vops && hba->vops->pwr_change_notify)
145 return hba->vops->pwr_change_notify(hba, status,
146 dev_max_params, dev_req_params);
147
148 return -ENOTSUPP;
149 }
150
ufshcd_vops_setup_task_mgmt(struct ufs_hba * hba,int tag,u8 tm_function)151 static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba,
152 int tag, u8 tm_function)
153 {
154 if (hba->vops && hba->vops->setup_task_mgmt)
155 return hba->vops->setup_task_mgmt(hba, tag, tm_function);
156 }
157
ufshcd_vops_hibern8_notify(struct ufs_hba * hba,enum uic_cmd_dme cmd,enum ufs_notify_change_status status)158 static inline void ufshcd_vops_hibern8_notify(struct ufs_hba *hba,
159 enum uic_cmd_dme cmd,
160 enum ufs_notify_change_status status)
161 {
162 if (hba->vops && hba->vops->hibern8_notify)
163 return hba->vops->hibern8_notify(hba, cmd, status);
164 }
165
ufshcd_vops_apply_dev_quirks(struct ufs_hba * hba)166 static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba)
167 {
168 if (hba->vops && hba->vops->apply_dev_quirks)
169 return hba->vops->apply_dev_quirks(hba);
170 return 0;
171 }
172
ufshcd_vops_fixup_dev_quirks(struct ufs_hba * hba)173 static inline void ufshcd_vops_fixup_dev_quirks(struct ufs_hba *hba)
174 {
175 if (hba->vops && hba->vops->fixup_dev_quirks)
176 hba->vops->fixup_dev_quirks(hba);
177 }
178
ufshcd_vops_suspend(struct ufs_hba * hba,enum ufs_pm_op op,enum ufs_notify_change_status status)179 static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op,
180 enum ufs_notify_change_status status)
181 {
182 if (hba->vops && hba->vops->suspend)
183 return hba->vops->suspend(hba, op, status);
184
185 return 0;
186 }
187
ufshcd_vops_resume(struct ufs_hba * hba,enum ufs_pm_op op)188 static inline int ufshcd_vops_resume(struct ufs_hba *hba, enum ufs_pm_op op)
189 {
190 if (hba->vops && hba->vops->resume)
191 return hba->vops->resume(hba, op);
192
193 return 0;
194 }
195
ufshcd_vops_dbg_register_dump(struct ufs_hba * hba)196 static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
197 {
198 if (hba->vops && hba->vops->dbg_register_dump)
199 hba->vops->dbg_register_dump(hba);
200 }
201
ufshcd_vops_device_reset(struct ufs_hba * hba)202 static inline int ufshcd_vops_device_reset(struct ufs_hba *hba)
203 {
204 if (hba->vops && hba->vops->device_reset)
205 return hba->vops->device_reset(hba);
206
207 return -EOPNOTSUPP;
208 }
209
ufshcd_vops_config_scaling_param(struct ufs_hba * hba,struct devfreq_dev_profile * p,struct devfreq_simple_ondemand_data * data)210 static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba,
211 struct devfreq_dev_profile *p,
212 struct devfreq_simple_ondemand_data *data)
213 {
214 if (hba->vops && hba->vops->config_scaling_param)
215 hba->vops->config_scaling_param(hba, p, data);
216 }
217
218 extern struct ufs_pm_lvl_states ufs_pm_lvl_states[];
219
220 /**
221 * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN
222 * @scsi_lun: scsi LUN id
223 *
224 * Returns UPIU LUN id
225 */
ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)226 static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
227 {
228 if (scsi_is_wlun(scsi_lun))
229 return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID)
230 | UFS_UPIU_WLUN_ID;
231 else
232 return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID;
233 }
234
235 int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask);
236 int ufshcd_write_ee_control(struct ufs_hba *hba);
237 int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask,
238 u16 set, u16 clr);
239
ufshcd_update_ee_drv_mask(struct ufs_hba * hba,u16 set,u16 clr)240 static inline int ufshcd_update_ee_drv_mask(struct ufs_hba *hba,
241 u16 set, u16 clr)
242 {
243 return ufshcd_update_ee_control(hba, &hba->ee_drv_mask,
244 &hba->ee_usr_mask, set, clr);
245 }
246
ufshcd_update_ee_usr_mask(struct ufs_hba * hba,u16 set,u16 clr)247 static inline int ufshcd_update_ee_usr_mask(struct ufs_hba *hba,
248 u16 set, u16 clr)
249 {
250 return ufshcd_update_ee_control(hba, &hba->ee_usr_mask,
251 &hba->ee_drv_mask, set, clr);
252 }
253
ufshcd_rpm_get_sync(struct ufs_hba * hba)254 static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba)
255 {
256 return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev);
257 }
258
ufshcd_rpm_put_sync(struct ufs_hba * hba)259 static inline int ufshcd_rpm_put_sync(struct ufs_hba *hba)
260 {
261 return pm_runtime_put_sync(&hba->ufs_device_wlun->sdev_gendev);
262 }
263
ufshcd_rpm_get_noresume(struct ufs_hba * hba)264 static inline void ufshcd_rpm_get_noresume(struct ufs_hba *hba)
265 {
266 pm_runtime_get_noresume(&hba->ufs_device_wlun->sdev_gendev);
267 }
268
ufshcd_rpm_resume(struct ufs_hba * hba)269 static inline int ufshcd_rpm_resume(struct ufs_hba *hba)
270 {
271 return pm_runtime_resume(&hba->ufs_device_wlun->sdev_gendev);
272 }
273
ufshcd_rpm_put(struct ufs_hba * hba)274 static inline int ufshcd_rpm_put(struct ufs_hba *hba)
275 {
276 return pm_runtime_put(&hba->ufs_device_wlun->sdev_gendev);
277 }
278
279 /**
280 * ufs_is_valid_unit_desc_lun - checks if the given LUN has a unit descriptor
281 * @dev_info: pointer of instance of struct ufs_dev_info
282 * @lun: LU number to check
283 * @return: true if the lun has a matching unit descriptor, false otherwise
284 */
ufs_is_valid_unit_desc_lun(struct ufs_dev_info * dev_info,u8 lun,u8 param_offset)285 static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info,
286 u8 lun, u8 param_offset)
287 {
288 if (!dev_info || !dev_info->max_lu_supported) {
289 pr_err("Max General LU supported by UFS isn't initialized\n");
290 return false;
291 }
292 /* WB is available only for the logical unit from 0 to 7 */
293 if (param_offset == UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS)
294 return lun < UFS_UPIU_MAX_WB_LUN_ID;
295 return lun == UFS_UPIU_RPMB_WLUN || (lun < dev_info->max_lu_supported);
296 }
297
298 #endif /* _UFSHCD_PRIV_H_ */
299