summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-17 13:34:01 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-17 13:34:01 -0700
commitdd0fa9929b6049dc628ab0ae05b79f97557b6b5d (patch)
treec73207c104286cd522a277a9d52b9f9b86181259 /drivers
parent5699e2b539243850a47d0d563d1831a35fd51e37 (diff)
parent2d64367038ed164d75bab383e92f83eaa646f3da (diff)
Merge "scsi: ufs-qcom: avoid sleep in atomic context"
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ufs/ufs-qcom.c7
-rw-r--r--drivers/scsi/ufs/ufshcd.c16
-rw-r--r--drivers/scsi/ufs/ufshcd.h7
3 files changed, 22 insertions, 8 deletions
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 1a1dd804ffb3..873b4615d4a9 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -2567,16 +2567,19 @@ static void ufs_qcom_print_unipro_testbus(struct ufs_hba *hba)
kfree(testbus);
}
-static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
+static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba, bool no_sleep)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
struct phy *phy = host->generic_phy;
ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 16,
"HCI Vendor Specific Registers ");
+ ufs_qcom_print_hw_debug_reg_all(hba, NULL, ufs_qcom_dump_regs_wrapper);
+
+ if (no_sleep)
+ return;
/* sleep a bit intermittently as we are dumping too much data */
- ufs_qcom_print_hw_debug_reg_all(hba, NULL, ufs_qcom_dump_regs_wrapper);
usleep_range(1000, 1100);
ufs_qcom_testbus_read(hba);
usleep_range(1000, 1100);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 53fed74eaefc..862d56e78086 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -539,7 +539,7 @@ static void ufshcd_print_uic_err_hist(struct ufs_hba *hba,
}
}
-static void ufshcd_print_host_regs(struct ufs_hba *hba)
+static inline void __ufshcd_print_host_regs(struct ufs_hba *hba, bool no_sleep)
{
if (!(hba->ufshcd_dbg_print & UFSHCD_DBG_PRINT_HOST_REGS_EN))
return;
@@ -571,7 +571,12 @@ static void ufshcd_print_host_regs(struct ufs_hba *hba)
ufshcd_print_clk_freqs(hba);
- ufshcd_vops_dbg_register_dump(hba);
+ ufshcd_vops_dbg_register_dump(hba, no_sleep);
+}
+
+static void ufshcd_print_host_regs(struct ufs_hba *hba)
+{
+ __ufshcd_print_host_regs(hba, false);
}
static
@@ -5055,7 +5060,12 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
dev_err(hba->dev,
"OCS error from controller = %x for tag %d\n",
ocs, lrbp->task_tag);
- ufshcd_print_host_regs(hba);
+ /*
+ * This is called in interrupt context, hence avoid sleep
+ * while printing debug registers. Also print only the minimum
+ * debug registers needed to debug OCS failure.
+ */
+ __ufshcd_print_host_regs(hba, true);
ufshcd_print_host_state(hba);
break;
} /* end of switch */
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index cd15d67cf8d5..c0714b7bea72 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -335,7 +335,7 @@ struct ufs_hba_variant_ops {
int (*suspend)(struct ufs_hba *, enum ufs_pm_op);
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
int (*full_reset)(struct ufs_hba *);
- void (*dbg_register_dump)(struct ufs_hba *hba);
+ void (*dbg_register_dump)(struct ufs_hba *hba, bool no_sleep);
int (*update_sec_cfg)(struct ufs_hba *hba, bool restore_sec_cfg);
u32 (*get_scale_down_gear)(struct ufs_hba *);
int (*set_bus_vote)(struct ufs_hba *, bool);
@@ -1244,10 +1244,11 @@ static inline int ufshcd_vops_full_reset(struct ufs_hba *hba)
}
-static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba)
+static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba,
+ bool no_sleep)
{
if (hba->var && hba->var->vops && hba->var->vops->dbg_register_dump)
- hba->var->vops->dbg_register_dump(hba);
+ hba->var->vops->dbg_register_dump(hba, no_sleep);
}
static inline int ufshcd_vops_update_sec_cfg(struct ufs_hba *hba,