Loading drivers/scsi/ufs/ufs-qcom.c +74 −0 Original line number Diff line number Diff line Loading @@ -1724,6 +1724,8 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, } else { err = ufs_qcom_set_bus_vote(hba, false); } if (!err) atomic_set(&host->clks_on, on); break; } Loading Loading @@ -2561,6 +2563,8 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, ufshcd_uic_hibern8_exit(hba); } if (!err) atomic_set(&host->scale_up, scale_up); out: return err; } Loading Loading @@ -2997,9 +3001,79 @@ static ssize_t power_mode_show(struct device *dev, static DEVICE_ATTR_RO(power_mode); static ssize_t bus_speed_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_qcom_host *host = ufshcd_get_variant(hba); return scnprintf(buf, PAGE_SIZE, "%d\n", !!atomic_read(&host->scale_up)); } static DEVICE_ATTR_RO(bus_speed_mode); static ssize_t clk_status_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_qcom_host *host = ufshcd_get_variant(hba); return scnprintf(buf, PAGE_SIZE, "%d\n", !!atomic_read(&host->clks_on)); } static DEVICE_ATTR_RO(clk_status); static unsigned int ufs_qcom_gec(struct ufs_hba *hba, struct ufs_err_reg_hist *err_hist, char *err_name) { unsigned long flags; int i, cnt_err = 0; spin_lock_irqsave(hba->host->host_lock, flags); for (i = 0; i < UFS_ERR_REG_HIST_LENGTH; i++) { int p = (i + err_hist->pos) % UFS_ERR_REG_HIST_LENGTH; if (err_hist->tstamp[p] == 0) continue; dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, p, err_hist->reg[p], ktime_to_us(err_hist->tstamp[p])); ++cnt_err; } spin_unlock_irqrestore(hba->host->host_lock, flags); return cnt_err; } static ssize_t err_count_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%s: %d\n%s: %d\n%s: %d\n", "pa_err_cnt_total", ufs_qcom_gec(hba, &hba->ufs_stats.pa_err, "pa_err_cnt_total"), "dl_err_cnt_total", ufs_qcom_gec(hba, &hba->ufs_stats.dl_err, "dl_err_cnt_total"), "dme_err_cnt", ufs_qcom_gec(hba, &hba->ufs_stats.dme_err, "dme_err_cnt")); } static DEVICE_ATTR_RO(err_count); static struct attribute *ufs_qcom_sysfs_attrs[] = { &dev_attr_err_state.attr, &dev_attr_power_mode.attr, &dev_attr_bus_speed_mode.attr, &dev_attr_clk_status.attr, &dev_attr_err_count.attr, NULL }; Loading drivers/scsi/ufs/ufs-qcom.h +3 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,9 @@ struct ufs_qcom_host { /* Protect the usage of is_phy_pwr_on against racing */ struct mutex phy_mutex; bool err_occurred; /* FlashPVL entries */ atomic_t scale_up; atomic_t clks_on; }; static inline u32 Loading Loading
drivers/scsi/ufs/ufs-qcom.c +74 −0 Original line number Diff line number Diff line Loading @@ -1724,6 +1724,8 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on, } else { err = ufs_qcom_set_bus_vote(hba, false); } if (!err) atomic_set(&host->clks_on, on); break; } Loading Loading @@ -2561,6 +2563,8 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, ufshcd_uic_hibern8_exit(hba); } if (!err) atomic_set(&host->scale_up, scale_up); out: return err; } Loading Loading @@ -2997,9 +3001,79 @@ static ssize_t power_mode_show(struct device *dev, static DEVICE_ATTR_RO(power_mode); static ssize_t bus_speed_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_qcom_host *host = ufshcd_get_variant(hba); return scnprintf(buf, PAGE_SIZE, "%d\n", !!atomic_read(&host->scale_up)); } static DEVICE_ATTR_RO(bus_speed_mode); static ssize_t clk_status_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); struct ufs_qcom_host *host = ufshcd_get_variant(hba); return scnprintf(buf, PAGE_SIZE, "%d\n", !!atomic_read(&host->clks_on)); } static DEVICE_ATTR_RO(clk_status); static unsigned int ufs_qcom_gec(struct ufs_hba *hba, struct ufs_err_reg_hist *err_hist, char *err_name) { unsigned long flags; int i, cnt_err = 0; spin_lock_irqsave(hba->host->host_lock, flags); for (i = 0; i < UFS_ERR_REG_HIST_LENGTH; i++) { int p = (i + err_hist->pos) % UFS_ERR_REG_HIST_LENGTH; if (err_hist->tstamp[p] == 0) continue; dev_err(hba->dev, "%s[%d] = 0x%x at %lld us\n", err_name, p, err_hist->reg[p], ktime_to_us(err_hist->tstamp[p])); ++cnt_err; } spin_unlock_irqrestore(hba->host->host_lock, flags); return cnt_err; } static ssize_t err_count_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ufs_hba *hba = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%s: %d\n%s: %d\n%s: %d\n", "pa_err_cnt_total", ufs_qcom_gec(hba, &hba->ufs_stats.pa_err, "pa_err_cnt_total"), "dl_err_cnt_total", ufs_qcom_gec(hba, &hba->ufs_stats.dl_err, "dl_err_cnt_total"), "dme_err_cnt", ufs_qcom_gec(hba, &hba->ufs_stats.dme_err, "dme_err_cnt")); } static DEVICE_ATTR_RO(err_count); static struct attribute *ufs_qcom_sysfs_attrs[] = { &dev_attr_err_state.attr, &dev_attr_power_mode.attr, &dev_attr_bus_speed_mode.attr, &dev_attr_clk_status.attr, &dev_attr_err_count.attr, NULL }; Loading
drivers/scsi/ufs/ufs-qcom.h +3 −0 Original line number Diff line number Diff line Loading @@ -338,6 +338,9 @@ struct ufs_qcom_host { /* Protect the usage of is_phy_pwr_on against racing */ struct mutex phy_mutex; bool err_occurred; /* FlashPVL entries */ atomic_t scale_up; atomic_t clks_on; }; static inline u32 Loading