Merge "scsi: ufs: check for err state when polling for doorbell"

This commit is contained in:
Linux Build Service Account 2017-01-30 07:05:20 -08:00 committed by Gerrit - the friendly Code Review server
commit e0c4785094
3 changed files with 22 additions and 10 deletions

View file

@ -67,6 +67,7 @@ static int ufs_qcom_dbg_testbus_en_read(void *data, u64 *attr_val)
static int ufs_qcom_dbg_testbus_en_set(void *data, u64 attr_id) static int ufs_qcom_dbg_testbus_en_set(void *data, u64 attr_id)
{ {
struct ufs_qcom_host *host = data; struct ufs_qcom_host *host = data;
int ret = 0;
if (!host) if (!host)
return -EINVAL; return -EINVAL;
@ -76,7 +77,13 @@ static int ufs_qcom_dbg_testbus_en_set(void *data, u64 attr_id)
else else
host->dbg_print_en &= ~UFS_QCOM_DBG_PRINT_TEST_BUS_EN; host->dbg_print_en &= ~UFS_QCOM_DBG_PRINT_TEST_BUS_EN;
return ufs_qcom_testbus_config(host); pm_runtime_get_sync(host->hba->dev);
ufshcd_hold(host->hba, false);
ret = ufs_qcom_testbus_config(host);
ufshcd_release(host->hba, false);
pm_runtime_put_sync(host->hba->dev);
return ret;
} }
DEFINE_SIMPLE_ATTRIBUTE(ufs_qcom_dbg_testbus_en_ops, DEFINE_SIMPLE_ATTRIBUTE(ufs_qcom_dbg_testbus_en_ops,
@ -142,7 +149,11 @@ static ssize_t ufs_qcom_dbg_testbus_cfg_write(struct file *file,
* Sanity check of the {major, minor} tuple is done in the * Sanity check of the {major, minor} tuple is done in the
* config function * config function
*/ */
pm_runtime_get_sync(host->hba->dev);
ufshcd_hold(host->hba, false);
ret = ufs_qcom_testbus_config(host); ret = ufs_qcom_testbus_config(host);
ufshcd_release(host->hba, false);
pm_runtime_put_sync(host->hba->dev);
if (!ret) if (!ret)
dev_dbg(host->hba->dev, dev_dbg(host->hba->dev,
"%s: New configuration: major=%d, minor=%d\n", "%s: New configuration: major=%d, minor=%d\n",

View file

@ -2452,6 +2452,11 @@ static bool ufs_qcom_testbus_cfg_is_ok(struct ufs_qcom_host *host)
return true; return true;
} }
/*
* The caller of this function must make sure that the controller
* is out of runtime suspend and appropriate clocks are enabled
* before accessing.
*/
int ufs_qcom_testbus_config(struct ufs_qcom_host *host) int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
{ {
int reg; int reg;
@ -2522,8 +2527,6 @@ int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
} }
mask <<= offset; mask <<= offset;
pm_runtime_get_sync(host->hba->dev);
ufshcd_hold(host->hba, false);
ufshcd_rmwl(host->hba, TEST_BUS_SEL, ufshcd_rmwl(host->hba, TEST_BUS_SEL,
(u32)host->testbus.select_major << 19, (u32)host->testbus.select_major << 19,
REG_UFS_CFG1); REG_UFS_CFG1);
@ -2536,8 +2539,6 @@ int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
* committed before returning. * committed before returning.
*/ */
mb(); mb();
ufshcd_release(host->hba, false);
pm_runtime_put_sync(host->hba->dev);
return 0; return 0;
} }

View file

@ -4141,17 +4141,17 @@ int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba, u64 wait_timeout_us)
ufshcd_hold_all(hba); ufshcd_hold_all(hba);
spin_lock_irqsave(hba->host->host_lock, flags); spin_lock_irqsave(hba->host->host_lock, flags);
if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL) {
ret = -EBUSY;
goto out;
}
/* /*
* Wait for all the outstanding tasks/transfer requests. * Wait for all the outstanding tasks/transfer requests.
* Verify by checking the doorbell registers are clear. * Verify by checking the doorbell registers are clear.
*/ */
start = ktime_get(); start = ktime_get();
do { do {
if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL) {
ret = -EBUSY;
goto out;
}
tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL);
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
if (!tm_doorbell && !tr_doorbell) { if (!tm_doorbell && !tr_doorbell) {