mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
UPSTREAM: scsi: ufs: Revert "Utilize Transfer Request List Completion Notification Register"
Using the UTRLCNR register involves two MMIO accesses in the hot path while using the doorbell register only involves a single MMIO access. Since MMIO accesses take time, do not use the UTRLCNR register. The spinlock contention on the SCSI host lock that is reintroduced by this commit will be addressed later. This reverts commit6f71517296. Link: https://lore.kernel.org/r/20210722033439.26550-12-bvanassche@acm.org Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Stanley Chu <stanley.chu@mediatek.com> Cc: Can Guo <cang@codeaurora.org> Cc: Asutosh Das <asutoshd@codeaurora.org> Cc: Avri Altman <avri.altman@wdc.com> Tested-by: Bean Huo <beanhuo@micron.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> (cherry picked from commit1f522c5049) Bug: 204438323 Signed-off-by: Bart Van Assche <bvanassche@google.com> Change-Id: I84888843e7d66ddc85cd97b181112d1f6606bd5a
This commit is contained in:
committed by
Bart Van Assche
parent
b98f9da669
commit
679183fefa
@@ -2108,6 +2108,7 @@ static inline
|
||||
void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
|
||||
{
|
||||
struct ufshcd_lrb *lrbp = &hba->lrb[task_tag];
|
||||
unsigned long flags;
|
||||
|
||||
lrbp->issue_time_stamp = ktime_get();
|
||||
lrbp->compl_time_stamp = ktime_set(0, 0);
|
||||
@@ -2117,19 +2118,10 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
|
||||
ufshcd_clk_scaling_start_busy(hba);
|
||||
if (unlikely(ufshcd_should_inform_monitor(hba, lrbp)))
|
||||
ufshcd_start_monitor(hba, lrbp);
|
||||
if (ufshcd_has_utrlcnr(hba)) {
|
||||
set_bit(task_tag, &hba->outstanding_reqs);
|
||||
ufshcd_writel(hba, 1 << task_tag,
|
||||
REG_UTP_TRANSFER_REQ_DOOR_BELL);
|
||||
} else {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
set_bit(task_tag, &hba->outstanding_reqs);
|
||||
ufshcd_writel(hba, 1 << task_tag,
|
||||
REG_UTP_TRANSFER_REQ_DOOR_BELL);
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
}
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
set_bit(task_tag, &hba->outstanding_reqs);
|
||||
ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
/* Make sure that doorbell is committed immediately */
|
||||
wmb();
|
||||
}
|
||||
@@ -5301,17 +5293,17 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
|
||||
}
|
||||
|
||||
/**
|
||||
* ufshcd_trc_handler - handle transfer requests completion
|
||||
* ufshcd_transfer_req_compl - handle SCSI and query command completion
|
||||
* @hba: per adapter instance
|
||||
* @use_utrlcnr: get completed requests from UTRLCNR
|
||||
*
|
||||
* Returns
|
||||
* IRQ_HANDLED - If interrupt is valid
|
||||
* IRQ_NONE - If invalid interrupt
|
||||
*/
|
||||
static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
|
||||
static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba)
|
||||
{
|
||||
unsigned long completed_reqs = 0;
|
||||
unsigned long completed_reqs, flags;
|
||||
u32 tr_doorbell;
|
||||
|
||||
/* Resetting interrupt aggregation counters first and reading the
|
||||
* DOOR_BELL afterward allows us to handle all the completed requests.
|
||||
@@ -5324,24 +5316,10 @@ static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr)
|
||||
!(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR))
|
||||
ufshcd_reset_intr_aggr(hba);
|
||||
|
||||
if (use_utrlcnr) {
|
||||
u32 utrlcnr;
|
||||
|
||||
utrlcnr = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_LIST_COMPL);
|
||||
if (utrlcnr) {
|
||||
ufshcd_writel(hba, utrlcnr,
|
||||
REG_UTP_TRANSFER_REQ_LIST_COMPL);
|
||||
completed_reqs = utrlcnr;
|
||||
}
|
||||
} else {
|
||||
unsigned long flags;
|
||||
u32 tr_doorbell;
|
||||
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
|
||||
completed_reqs = tr_doorbell ^ hba->outstanding_reqs;
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
}
|
||||
spin_lock_irqsave(hba->host->host_lock, flags);
|
||||
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
|
||||
completed_reqs = tr_doorbell ^ hba->outstanding_reqs;
|
||||
spin_unlock_irqrestore(hba->host->host_lock, flags);
|
||||
|
||||
if (completed_reqs) {
|
||||
__ufshcd_transfer_req_compl(hba, completed_reqs);
|
||||
@@ -5824,7 +5802,7 @@ out:
|
||||
/* Complete requests that have door-bell cleared */
|
||||
static void ufshcd_complete_requests(struct ufs_hba *hba)
|
||||
{
|
||||
ufshcd_trc_handler(hba, false);
|
||||
ufshcd_transfer_req_compl(hba);
|
||||
ufshcd_tmc_handler(hba);
|
||||
}
|
||||
|
||||
@@ -6451,7 +6429,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
|
||||
retval |= ufshcd_tmc_handler(hba);
|
||||
|
||||
if (intr_status & UTP_TRANSFER_REQ_COMPL)
|
||||
retval |= ufshcd_trc_handler(hba, ufshcd_has_utrlcnr(hba));
|
||||
retval |= ufshcd_transfer_req_compl(hba);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1265,11 +1265,6 @@ static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba)
|
||||
return ufshcd_readl(hba, REG_UFS_VERSION);
|
||||
}
|
||||
|
||||
static inline bool ufshcd_has_utrlcnr(struct ufs_hba *hba)
|
||||
{
|
||||
return (hba->ufs_version >= ufshci_version(3, 0));
|
||||
}
|
||||
|
||||
static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba,
|
||||
bool up, enum ufs_notify_change_status status)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,6 @@ enum {
|
||||
REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58,
|
||||
REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C,
|
||||
REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60,
|
||||
REG_UTP_TRANSFER_REQ_LIST_COMPL = 0x64,
|
||||
REG_UTP_TASK_REQ_LIST_BASE_L = 0x70,
|
||||
REG_UTP_TASK_REQ_LIST_BASE_H = 0x74,
|
||||
REG_UTP_TASK_REQ_DOOR_BELL = 0x78,
|
||||
|
||||
Reference in New Issue
Block a user