From 02527a32e5b1664720292670e15a7d7ccf7cea99 Mon Sep 17 00:00:00 2001 From: hgchu Date: Fri, 12 Jan 2018 16:19:58 +0900 Subject: [PATCH] [COMMON] scsi: ufs: check the unipro result directly Change-Id: I322e86ad853f538f67086f1f6eefcf42a760d53c Signed-off-by: hgchu --- drivers/scsi/ufs/ufshcd.c | 22 +++++++++++++++++++--- drivers/scsi/ufs/ufshcd.h | 8 ++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 372b1049dfca..8492041e84f7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1965,6 +1965,9 @@ static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) */ static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba) { + if (hba->quirks & UFSHCD_QUIRK_GET_GENERRCODE_DIRECT) { + return ufshcd_vops_get_unipro(hba, 3); + } else return (ufshcd_readl(hba, REG_CONTROLLER_STATUS) >> 8) & 0x7; } @@ -2005,11 +2008,24 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) { int ret; unsigned long flags; + int index; - if (wait_for_completion_timeout(&uic_cmd->done, - msecs_to_jiffies(UIC_CMD_TIMEOUT))) - ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT; + if (uic_cmd->command == UIC_CMD_DME_LINK_STARTUP) + index = 0; + else if ((uic_cmd->command == UIC_CMD_DME_HIBER_ENTER)) + index = 1; + else if ((uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) + index = 2; else + index = -1; + + if (wait_for_completion_timeout(&uic_cmd->done, + msecs_to_jiffies(UIC_CMD_TIMEOUT))) { + if ((hba->quirks & UFSHCD_QUIRK_GET_GENERRCODE_DIRECT) && (index != -1)) + ret = ufshcd_vops_get_unipro(hba, index); + else + ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT; + } else ret = -ETIMEDOUT; spin_lock_irqsave(hba->host->host_lock, flags); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 12a108af216a..157bb9f2e3bb 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -339,6 +339,7 @@ struct ufs_hba_variant_ops { int (*suspend)(struct ufs_hba *, enum ufs_pm_op); int (*resume)(struct ufs_hba *, enum ufs_pm_op); void (*dbg_register_dump)(struct ufs_hba *hba); + u8 (*get_unipro_result)(struct ufs_hba *hba, int num); int (*phy_initialization)(struct ufs_hba *); }; @@ -621,6 +622,7 @@ struct ufs_hba { #define UFSHCD_QUIRK_USE_OF_HCE UFS_BIT(8) #define UFSHCI_QUIRK_SKIP_INTR_AGGR UFS_BIT(10) + #define UFSHCD_QUIRK_GET_GENERRCODE_DIRECT UFS_BIT(11) unsigned int quirks; /* Deviations from standard UFSHCI spec. */ /* Device deviations from standard UFS device spec. */ @@ -1037,5 +1039,11 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba) hba->vops->dbg_register_dump(hba); } +static inline u8 ufshcd_vops_get_unipro(struct ufs_hba *hba, int num) +{ + if (hba->vops && hba->vops->get_unipro_result) + return hba->vops->get_unipro_result(hba, num); + return 0; +} int ufshcd_read_health_desc(struct ufs_hba *hba, u8 *buf, u32 size); #endif /* End of Header */ -- 2.20.1