diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-04 19:47:37 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-04 19:47:37 -0700 |
commit | 746fc76b820dce8cbb17a1e5e70a1558db4d7406 (patch) | |
tree | 724898336ce5b4fd8c79d817c06b978929e28410 /drivers/ufs/core | |
parent | 328141e51e6fc79d21168bfd4e356dddc2ec7491 (diff) | |
parent | 8fcdc238ce1b492e1f57a73a2ce4131d63f45397 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"Updates to the usual drivers (ufs, qla2xx, target, lpfc, smartpqi,
mpi3mr).
The main driver change that might cause issues on down the road is the
conversion of some of our oldest surviving drivers to the DMA API
(should only affect m68k).
The only major core change is the rework of async resume; the rest are
either completely trivial or for updating deprecated APIs"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (195 commits)
scsi: target: Remove XDWRITEREAD emulated support
scsi: megaraid: Remove the static variable initialisation
scsi: ch: Do not initialise statics to 0
scsi: ufs: core: Fix spelling mistake "Cannnot" -> "Cannot"
scsi: target: iscsi: Do not require target authentication
scsi: target: iscsi: Allow AuthMethod=None
scsi: target: iscsi: Support base64 in CHAP
scsi: target: iscsi: Add support for extended CDB AHS
scsi: ufs: dt-bindings: Add SC8280XP binding
scsi: target: iscsi: Fix clang -Wformat warnings
scsi: ufs: core: Read device property for ref clock
scsi: libsas: Resume SAS host for phy reset or enable via sysfs
scsi: hisi_sas: Modify v3 HW SATA completion error processing
scsi: hisi_sas: Relocate DMA unmap of SMP task
scsi: hisi_sas: Remove unnecessary variable to hold DMA map elements
scsi: hisi_sas: Call hisi_sas_slave_configure() from slave_configure_v3_hw()
scsi: mpi3mr: Delete a stray tab
scsi: mpi3mr: Unlock on error path
scsi: mpi3mr: Reduce VD queue depth on detecting throttling
scsi: mpi3mr: Resource Based Metering
...
Diffstat (limited to 'drivers/ufs/core')
-rw-r--r-- | drivers/ufs/core/ufshcd-priv.h | 6 | ||||
-rw-r--r-- | drivers/ufs/core/ufshcd.c | 86 |
2 files changed, 58 insertions, 34 deletions
diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h index ffb01fc6de75..8f67db202d7b 100644 --- a/drivers/ufs/core/ufshcd-priv.h +++ b/drivers/ufs/core/ufshcd-priv.h @@ -215,7 +215,7 @@ static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba, hba->vops->config_scaling_param(hba, p, data); } -extern struct ufs_pm_lvl_states ufs_pm_lvl_states[]; +extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[]; /** * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN @@ -234,8 +234,8 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask); int ufshcd_write_ee_control(struct ufs_hba *hba); -int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, - u16 set, u16 clr); +int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, + const u16 *other_mask, u16 set, u16 clr); static inline int ufshcd_update_ee_drv_mask(struct ufs_hba *hba, u16 set, u16 clr) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2b40174e93ac..3bc0709a5dc2 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -64,9 +64,6 @@ /* maximum number of link-startup retries */ #define DME_LINKSTARTUP_RETRIES 3 -/* Maximum retries for Hibern8 enter */ -#define UIC_HIBERN8_ENTER_RETRIES 3 - /* maximum number of reset retries before giving up */ #define MAX_HOST_RESET_RETRIES 5 @@ -175,7 +172,7 @@ enum { #define ufshcd_clear_eh_in_progress(h) \ ((h)->eh_flags &= ~UFSHCD_EH_IN_PROGRESS) -struct ufs_pm_lvl_states ufs_pm_lvl_states[] = { +const struct ufs_pm_lvl_states ufs_pm_lvl_states[] = { [UFS_PM_LVL_0] = {UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE}, [UFS_PM_LVL_1] = {UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE}, [UFS_PM_LVL_2] = {UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE}, @@ -363,7 +360,7 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag, } static void ufshcd_add_uic_command_trace(struct ufs_hba *hba, - struct uic_command *ucmd, + const struct uic_command *ucmd, enum ufs_trace_str_t str_t) { u32 cmd; @@ -443,11 +440,11 @@ static void ufshcd_print_clk_freqs(struct ufs_hba *hba) } static void ufshcd_print_evt(struct ufs_hba *hba, u32 id, - char *err_name) + const char *err_name) { int i; bool found = false; - struct ufs_event_hist *e; + const struct ufs_event_hist *e; if (id >= UFS_EVT_CNT) return; @@ -497,7 +494,7 @@ static void ufshcd_print_evt_hist(struct ufs_hba *hba) static void ufshcd_print_trs(struct ufs_hba *hba, unsigned long bitmap, bool pr_prdt) { - struct ufshcd_lrb *lrbp; + const struct ufshcd_lrb *lrbp; int prdt_length; int tag; @@ -553,7 +550,7 @@ static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap) static void ufshcd_print_host_state(struct ufs_hba *hba) { - struct scsi_device *sdev_ufs = hba->ufs_device_wlun; + const struct scsi_device *sdev_ufs = hba->ufs_device_wlun; dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state); dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n", @@ -1109,7 +1106,7 @@ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba, */ static u32 ufshcd_pending_cmds(struct ufs_hba *hba) { - struct scsi_device *sdev; + const struct scsi_device *sdev; u32 pending = 0; lockdep_assert_held(hba->host->host_lock); @@ -2080,14 +2077,15 @@ static inline int ufshcd_monitor_opcode2dir(u8 opcode) static inline bool ufshcd_should_inform_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { - struct ufs_hba_monitor *m = &hba->monitor; + const struct ufs_hba_monitor *m = &hba->monitor; return (m->enabled && lrbp && lrbp->cmd && (!m->chunk_size || m->chunk_size == lrbp->cmd->sdb.length) && ktime_before(hba->monitor.enabled_ts, lrbp->issue_time_stamp)); } -static void ufshcd_start_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +static void ufshcd_start_monitor(struct ufs_hba *hba, + const struct ufshcd_lrb *lrbp) { int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd); unsigned long flags; @@ -2098,14 +2096,14 @@ static void ufshcd_start_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) spin_unlock_irqrestore(hba->host->host_lock, flags); } -static void ufshcd_update_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +static void ufshcd_update_monitor(struct ufs_hba *hba, const struct ufshcd_lrb *lrbp) { int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd); unsigned long flags; spin_lock_irqsave(hba->host->host_lock, flags); if (dir >= 0 && hba->monitor.nr_queued[dir] > 0) { - struct request *req = scsi_cmd_to_rq(lrbp->cmd); + const struct request *req = scsi_cmd_to_rq(lrbp->cmd); struct ufs_hba_monitor *m = &hba->monitor; ktime_t now, inc, lat; @@ -2227,6 +2225,8 @@ static inline int ufshcd_hba_capabilities(struct ufs_hba *hba) int err; hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES); + if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS) + hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT; /* nutrs and nutmrs are 0 based values */ hba->nutrs = (hba->capabilities & MASK_TRANSFER_REQUESTS_SLOTS) + 1; @@ -3095,7 +3095,7 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba, if (ret) dev_err(hba->dev, - "%s: query attribute, opcode %d, idn %d, failed with error %d after %d retires\n", + "%s: query attribute, opcode %d, idn %d, failed with error %d after %d retries\n", __func__, opcode, idn, ret, retries); return ret; } @@ -3263,7 +3263,7 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba, if (ret) dev_err(hba->dev, - "%s: query attribute, idn %d, failed with error %d after %d retires\n", + "%s: query attribute, idn %d, failed with error %d after %d retries\n", __func__, idn, ret, QUERY_REQ_RETRIES); return ret; } @@ -3834,7 +3834,7 @@ int ufshcd_dme_configure_adapt(struct ufs_hba *hba, { int ret; - if (agreed_gear != UFS_HS_G4) + if (agreed_gear < UFS_HS_G4) adapt_val = PA_NO_ADAPT; ret = ufshcd_dme_set(hba, @@ -4123,7 +4123,7 @@ out_unlock: * * Returns 0 on success, non-zero value on failure */ -static int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode) +int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode) { struct uic_command uic_cmd = {0}; int ret; @@ -4148,6 +4148,7 @@ static int ufshcd_uic_change_pwr_mode(struct ufs_hba *hba, u8 mode) out: return ret; } +EXPORT_SYMBOL_GPL(ufshcd_uic_change_pwr_mode); int ufshcd_link_recovery(struct ufs_hba *hba) { @@ -4290,8 +4291,13 @@ static int ufshcd_get_max_pwr_mode(struct ufs_hba *hba) if (hba->max_pwr_info.is_valid) return 0; - pwr_info->pwr_tx = FAST_MODE; - pwr_info->pwr_rx = FAST_MODE; + if (hba->quirks & UFSHCD_QUIRK_HIBERN_FASTAUTO) { + pwr_info->pwr_tx = FASTAUTO_MODE; + pwr_info->pwr_rx = FASTAUTO_MODE; + } else { + pwr_info->pwr_tx = FAST_MODE; + pwr_info->pwr_rx = FAST_MODE; + } pwr_info->hs_rate = PA_HS_MODE_B; /* Get the connected lane count */ @@ -4766,7 +4772,7 @@ link_startup: * but we can't be sure if the link is up until link startup * succeeds. So reset the local Uni-Pro and try again. */ - if (ret && ufshcd_hba_enable(hba)) { + if (ret && retries && ufshcd_hba_enable(hba)) { ufshcd_update_evt_hist(hba, UFS_EVT_LINK_STARTUP_FAIL, (u32)ret); @@ -4931,7 +4937,7 @@ static int ufshcd_get_lu_wp(struct ufs_hba *hba, * */ static inline void ufshcd_get_lu_power_on_wp_status(struct ufs_hba *hba, - struct scsi_device *sdev) + const struct scsi_device *sdev) { if (hba->dev_info.f_power_on_wp_en && !hba->dev_info.is_lu_power_on_wp) { @@ -5450,8 +5456,8 @@ int ufshcd_write_ee_control(struct ufs_hba *hba) return err; } -int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, - u16 set, u16 clr) +int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, + const u16 *other_mask, u16 set, u16 clr) { u16 new_mask, ee_ctrl_mask; int err = 0; @@ -7388,7 +7394,8 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) * * Returns calculated max ICC level for specific regulator */ -static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, char *buff) +static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, + const char *buff) { int i; int curr_uA; @@ -7435,7 +7442,7 @@ static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, char *buff) * Returns calculated ICC level */ static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba, - u8 *desc_buf, int len) + const u8 *desc_buf, int len) { u32 icc_level = 0; @@ -7585,7 +7592,7 @@ out: return ret; } -static void ufshcd_wb_probe(struct ufs_hba *hba, u8 *desc_buf) +static void ufshcd_wb_probe(struct ufs_hba *hba, const u8 *desc_buf) { struct ufs_dev_info *dev_info = &hba->dev_info; u8 lun; @@ -7656,7 +7663,7 @@ wb_disabled: hba->caps &= ~UFSHCD_CAP_WB_EN; } -static void ufshcd_temp_notif_probe(struct ufs_hba *hba, u8 *desc_buf) +static void ufshcd_temp_notif_probe(struct ufs_hba *hba, const u8 *desc_buf) { struct ufs_dev_info *dev_info = &hba->dev_info; u32 ext_ufs_feature; @@ -7890,7 +7897,7 @@ static int ufshcd_quirk_tune_host_pa_tactivate(struct ufs_hba *hba) u32 granularity, peer_granularity; u32 pa_tactivate, peer_pa_tactivate; u32 pa_tactivate_us, peer_pa_tactivate_us; - u8 gran_to_us_table[] = {1, 4, 8, 16, 32, 100}; + static const u8 gran_to_us_table[] = {1, 4, 8, 16, 32, 100}; ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY), &granularity); @@ -8007,7 +8014,7 @@ struct ufs_ref_clk { enum ufs_ref_clk_freq val; }; -static struct ufs_ref_clk ufs_ref_clk_freqs[] = { +static const struct ufs_ref_clk ufs_ref_clk_freqs[] = { {19200000, REF_CLK_FREQ_19_2_MHZ}, {26000000, REF_CLK_FREQ_26_MHZ}, {38400000, REF_CLK_FREQ_38_4_MHZ}, @@ -8449,7 +8456,7 @@ static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on) return ufshcd_toggle_vreg(hba->dev, info->vdd_hba, on); } -static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) +int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) { int ret = 0; @@ -8465,6 +8472,7 @@ static int ufshcd_get_vreg(struct device *dev, struct ufs_vreg *vreg) out: return ret; } +EXPORT_SYMBOL_GPL(ufshcd_get_vreg); static int ufshcd_init_vreg(struct ufs_hba *hba) { @@ -8558,6 +8566,19 @@ out: return ret; } +static enum ufs_ref_clk_freq ufshcd_parse_ref_clk_property(struct ufs_hba *hba) +{ + u32 freq; + int ret = device_property_read_u32(hba->dev, "ref-clk-freq", &freq); + + if (ret) { + dev_dbg(hba->dev, "Cannot query 'ref-clk-freq' property = %d", ret); + return REF_CLK_FREQ_INVAL; + } + + return ufs_get_bref_clk_from_hz(freq); +} + static int ufshcd_init_clocks(struct ufs_hba *hba) { int ret = 0; @@ -8651,6 +8672,9 @@ static int ufshcd_hba_init(struct ufs_hba *hba) if (err) goto out_disable_hba_vreg; + if (hba->dev_ref_clk_freq == REF_CLK_FREQ_INVAL) + hba->dev_ref_clk_freq = ufshcd_parse_ref_clk_property(hba); + err = ufshcd_setup_clocks(hba, true); if (err) goto out_disable_hba_vreg; |