Loading drivers/scsi/ufs/debugfs.c +41 −0 Original line number Diff line number Diff line Loading @@ -917,6 +917,36 @@ DEFINE_SIMPLE_ATTRIBUTE(ufsdbg_dme_peer_read_ops, ufsdbg_dme_peer_set_attr_id, "%llu\n"); static int ufsdbg_dbg_print_en_read(void *data, u64 *attr_val) { struct ufs_hba *hba = data; if (!hba) return -EINVAL; *attr_val = (u64)hba->ufshcd_dbg_print; return 0; } static int ufsdbg_dbg_print_en_set(void *data, u64 attr_id) { struct ufs_hba *hba = data; if (!hba) return -EINVAL; if (attr_id & ~UFSHCD_DBG_PRINT_ALL) return -EINVAL; hba->ufshcd_dbg_print = (u32)attr_id; return 0; } DEFINE_SIMPLE_ATTRIBUTE(ufsdbg_dbg_print_en_ops, ufsdbg_dbg_print_en_read, ufsdbg_dbg_print_en_set, "%llu\n"); void ufsdbg_add_debugfs(struct ufs_hba *hba) { if (!hba) { Loading Loading @@ -1022,6 +1052,17 @@ void ufsdbg_add_debugfs(struct ufs_hba *hba) goto err; } hba->debugfs_files.dbg_print_en = debugfs_create_file("dbg_print_en", S_IRUSR | S_IWUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dbg_print_en_ops); if (!hba->debugfs_files.dbg_print_en) { dev_err(hba->dev, "%s: failed create dbg_print_en debugfs entry\n", __func__); goto err; } ufsdbg_setup_fault_injection(hba); return; Loading drivers/scsi/ufs/ufshcd.c +23 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,8 @@ enum { UFSHCD_INT_CLEAR, }; #define DEFAULT_UFSHCD_DBG_PRINT_EN UFSHCD_DBG_PRINT_ALL #define ufshcd_set_eh_in_progress(h) \ (h->eh_flags |= UFSHCD_EH_IN_PROGRESS) #define ufshcd_eh_in_progress(h) \ Loading Loading @@ -389,6 +391,9 @@ static void ufshcd_print_clk_freqs(struct ufs_hba *hba) struct ufs_clk_info *clki; struct list_head *head = &hba->clk_list_head; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_CLK_FREQ_EN)) return; if (!head || list_empty(head)) return; Loading @@ -405,6 +410,9 @@ static void ufshcd_print_uic_err_hist(struct ufs_hba *hba, { int i; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_UIC_ERR_HIST_EN)) return; for (i = 0; i < UIC_ERR_REG_HIST_LENGTH; i++) { int p = (i + err_hist->pos - 1) % UIC_ERR_REG_HIST_LENGTH; Loading @@ -417,6 +425,9 @@ static void ufshcd_print_uic_err_hist(struct ufs_hba *hba, static void ufshcd_print_host_regs(struct ufs_hba *hba) { if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_HOST_REGS_EN)) return; /* * hex_dump reads its data without the readl macro. This might * cause inconsistency issues on some platform, as the printed Loading Loading @@ -455,6 +466,9 @@ void ufshcd_print_trs(struct ufs_hba *hba, unsigned long bitmap, bool pr_prdt) int prdt_length; int tag; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_TRS_EN)) return; for_each_set_bit(tag, &bitmap, hba->nutrs) { lrbp = &hba->lrb[tag]; Loading Loading @@ -488,6 +502,9 @@ static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap) struct utp_task_req_desc *tmrdp; int tag; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_TMRS_EN)) return; for_each_set_bit(tag, &bitmap, hba->nutmrs) { tmrdp = &hba->utmrdl_base_addr[tag]; dev_err(hba->dev, "TM[%d] - Task Management Header", tag); Loading Loading @@ -521,6 +538,9 @@ static void ufshcd_print_pwr_info(struct ufs_hba *hba) "INVALID MODE", }; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_PWR_EN)) return; dev_err(hba->dev, "%s:[RX, TX]: gear=[%d, %d], lane[%d, %d], pwr[%s, %s], rate = %d\n", __func__, hba->pwr_info.gear_rx, hba->pwr_info.gear_tx, Loading Loading @@ -8165,6 +8185,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Get Interrupt bit mask per version */ hba->intr_mask = ufshcd_get_intr_mask(hba); /* Enable debug prints */ hba->ufshcd_dbg_print = DEFAULT_UFSHCD_DBG_PRINT_EN; err = ufshcd_set_dma_mask(hba); if (err) { dev_err(hba->dev, "set dma mask failed\n"); Loading include/linux/scsi/ufs/ufshcd.h +19 −0 Original line number Diff line number Diff line Loading @@ -294,6 +294,7 @@ struct debugfs_files { struct dentry *power_mode; struct dentry *dme_local_read; struct dentry *dme_peer_read; struct dentry *dbg_print_en; u32 dme_local_attr_id; u32 dme_peer_attr_id; #ifdef CONFIG_UFS_FAULT_INJECTION Loading Loading @@ -412,6 +413,20 @@ enum clk_gating_state { REQ_CLKS_ON, }; /* UFS Host Controller debug print bitmask */ #define UFSHCD_DBG_PRINT_CLK_FREQ_EN UFS_BIT(0) #define UFSHCD_DBG_PRINT_UIC_ERR_HIST_EN UFS_BIT(1) #define UFSHCD_DBG_PRINT_HOST_REGS_EN UFS_BIT(2) #define UFSHCD_DBG_PRINT_TRS_EN UFS_BIT(3) #define UFSHCD_DBG_PRINT_TMRS_EN UFS_BIT(4) #define UFSHCD_DBG_PRINT_PWR_EN UFS_BIT(5) #define UFSHCD_DBG_PRINT_ALL \ (UFSHCD_DBG_PRINT_CLK_FREQ_EN | \ UFSHCD_DBG_PRINT_UIC_ERR_HIST_EN | \ UFSHCD_DBG_PRINT_HOST_REGS_EN | UFSHCD_DBG_PRINT_TRS_EN | \ UFSHCD_DBG_PRINT_TMRS_EN | UFSHCD_DBG_PRINT_PWR_EN) /** * struct ufs_clk_gating - UFS clock gating related info * @gate_work: worker to turn off clocks after some delay as specified in Loading Loading @@ -577,6 +592,7 @@ struct ufshcd_pm_qos { * @hibern8_on_idle: UFS Hibern8 on idle related data * @ufs_stats: ufshcd statistics to be used via debugfs * @debugfs_files: debugfs files associated with the ufs stats * @ufshcd_dbg_print: Bitmask for enabling debug prints */ struct ufs_hba { void __iomem *mmio_base; Loading Loading @@ -750,6 +766,9 @@ struct ufs_hba { /* Number of requests aborts */ int req_abort_count; /* Bitmask for enabling debug prints */ u32 ufshcd_dbg_print; }; /* Returns true if clocks can be gated. Otherwise false */ Loading Loading
drivers/scsi/ufs/debugfs.c +41 −0 Original line number Diff line number Diff line Loading @@ -917,6 +917,36 @@ DEFINE_SIMPLE_ATTRIBUTE(ufsdbg_dme_peer_read_ops, ufsdbg_dme_peer_set_attr_id, "%llu\n"); static int ufsdbg_dbg_print_en_read(void *data, u64 *attr_val) { struct ufs_hba *hba = data; if (!hba) return -EINVAL; *attr_val = (u64)hba->ufshcd_dbg_print; return 0; } static int ufsdbg_dbg_print_en_set(void *data, u64 attr_id) { struct ufs_hba *hba = data; if (!hba) return -EINVAL; if (attr_id & ~UFSHCD_DBG_PRINT_ALL) return -EINVAL; hba->ufshcd_dbg_print = (u32)attr_id; return 0; } DEFINE_SIMPLE_ATTRIBUTE(ufsdbg_dbg_print_en_ops, ufsdbg_dbg_print_en_read, ufsdbg_dbg_print_en_set, "%llu\n"); void ufsdbg_add_debugfs(struct ufs_hba *hba) { if (!hba) { Loading Loading @@ -1022,6 +1052,17 @@ void ufsdbg_add_debugfs(struct ufs_hba *hba) goto err; } hba->debugfs_files.dbg_print_en = debugfs_create_file("dbg_print_en", S_IRUSR | S_IWUSR, hba->debugfs_files.debugfs_root, hba, &ufsdbg_dbg_print_en_ops); if (!hba->debugfs_files.dbg_print_en) { dev_err(hba->dev, "%s: failed create dbg_print_en debugfs entry\n", __func__); goto err; } ufsdbg_setup_fault_injection(hba); return; Loading
drivers/scsi/ufs/ufshcd.c +23 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,8 @@ enum { UFSHCD_INT_CLEAR, }; #define DEFAULT_UFSHCD_DBG_PRINT_EN UFSHCD_DBG_PRINT_ALL #define ufshcd_set_eh_in_progress(h) \ (h->eh_flags |= UFSHCD_EH_IN_PROGRESS) #define ufshcd_eh_in_progress(h) \ Loading Loading @@ -389,6 +391,9 @@ static void ufshcd_print_clk_freqs(struct ufs_hba *hba) struct ufs_clk_info *clki; struct list_head *head = &hba->clk_list_head; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_CLK_FREQ_EN)) return; if (!head || list_empty(head)) return; Loading @@ -405,6 +410,9 @@ static void ufshcd_print_uic_err_hist(struct ufs_hba *hba, { int i; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_UIC_ERR_HIST_EN)) return; for (i = 0; i < UIC_ERR_REG_HIST_LENGTH; i++) { int p = (i + err_hist->pos - 1) % UIC_ERR_REG_HIST_LENGTH; Loading @@ -417,6 +425,9 @@ static void ufshcd_print_uic_err_hist(struct ufs_hba *hba, static void ufshcd_print_host_regs(struct ufs_hba *hba) { if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_HOST_REGS_EN)) return; /* * hex_dump reads its data without the readl macro. This might * cause inconsistency issues on some platform, as the printed Loading Loading @@ -455,6 +466,9 @@ void ufshcd_print_trs(struct ufs_hba *hba, unsigned long bitmap, bool pr_prdt) int prdt_length; int tag; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_TRS_EN)) return; for_each_set_bit(tag, &bitmap, hba->nutrs) { lrbp = &hba->lrb[tag]; Loading Loading @@ -488,6 +502,9 @@ static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap) struct utp_task_req_desc *tmrdp; int tag; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_TMRS_EN)) return; for_each_set_bit(tag, &bitmap, hba->nutmrs) { tmrdp = &hba->utmrdl_base_addr[tag]; dev_err(hba->dev, "TM[%d] - Task Management Header", tag); Loading Loading @@ -521,6 +538,9 @@ static void ufshcd_print_pwr_info(struct ufs_hba *hba) "INVALID MODE", }; if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_PWR_EN)) return; dev_err(hba->dev, "%s:[RX, TX]: gear=[%d, %d], lane[%d, %d], pwr[%s, %s], rate = %d\n", __func__, hba->pwr_info.gear_rx, hba->pwr_info.gear_tx, Loading Loading @@ -8165,6 +8185,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Get Interrupt bit mask per version */ hba->intr_mask = ufshcd_get_intr_mask(hba); /* Enable debug prints */ hba->ufshcd_dbg_print = DEFAULT_UFSHCD_DBG_PRINT_EN; err = ufshcd_set_dma_mask(hba); if (err) { dev_err(hba->dev, "set dma mask failed\n"); Loading
include/linux/scsi/ufs/ufshcd.h +19 −0 Original line number Diff line number Diff line Loading @@ -294,6 +294,7 @@ struct debugfs_files { struct dentry *power_mode; struct dentry *dme_local_read; struct dentry *dme_peer_read; struct dentry *dbg_print_en; u32 dme_local_attr_id; u32 dme_peer_attr_id; #ifdef CONFIG_UFS_FAULT_INJECTION Loading Loading @@ -412,6 +413,20 @@ enum clk_gating_state { REQ_CLKS_ON, }; /* UFS Host Controller debug print bitmask */ #define UFSHCD_DBG_PRINT_CLK_FREQ_EN UFS_BIT(0) #define UFSHCD_DBG_PRINT_UIC_ERR_HIST_EN UFS_BIT(1) #define UFSHCD_DBG_PRINT_HOST_REGS_EN UFS_BIT(2) #define UFSHCD_DBG_PRINT_TRS_EN UFS_BIT(3) #define UFSHCD_DBG_PRINT_TMRS_EN UFS_BIT(4) #define UFSHCD_DBG_PRINT_PWR_EN UFS_BIT(5) #define UFSHCD_DBG_PRINT_ALL \ (UFSHCD_DBG_PRINT_CLK_FREQ_EN | \ UFSHCD_DBG_PRINT_UIC_ERR_HIST_EN | \ UFSHCD_DBG_PRINT_HOST_REGS_EN | UFSHCD_DBG_PRINT_TRS_EN | \ UFSHCD_DBG_PRINT_TMRS_EN | UFSHCD_DBG_PRINT_PWR_EN) /** * struct ufs_clk_gating - UFS clock gating related info * @gate_work: worker to turn off clocks after some delay as specified in Loading Loading @@ -577,6 +592,7 @@ struct ufshcd_pm_qos { * @hibern8_on_idle: UFS Hibern8 on idle related data * @ufs_stats: ufshcd statistics to be used via debugfs * @debugfs_files: debugfs files associated with the ufs stats * @ufshcd_dbg_print: Bitmask for enabling debug prints */ struct ufs_hba { void __iomem *mmio_base; Loading Loading @@ -750,6 +766,9 @@ struct ufs_hba { /* Number of requests aborts */ int req_abort_count; /* Bitmask for enabling debug prints */ u32 ufshcd_dbg_print; }; /* Returns true if clocks can be gated. Otherwise false */ Loading