From: Stanley Chu <stanley.chu@mediatek.com> To: linux-scsi@vger.kernel.org, martin.petersen@oracle.com, avri.altman@wdc.com, alim.akhtar@samsung.com, pedrom.sousa@synopsys.com Cc: marc.w.gonzalez@free.fr, andy.teng@mediatek.com, chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, evgreen@chromium.org, linux-mediatek@lists.infradead.org, peter.wang@mediatek.com, matthias.bgg@gmail.com, Stanley Chu <stanley.chu@mediatek.com>, linux-arm-kernel@lists.infradead.org, beanhuo@micron.com Subject: [PATCH v3 2/3] scsi: ufs: Add error-handling of Auto-Hibernate Date: Mon, 20 May 2019 16:32:17 +0800 [thread overview] Message-ID: <1558341138-18043-3-git-send-email-stanley.chu@mediatek.com> (raw) In-Reply-To: <1558341138-18043-1-git-send-email-stanley.chu@mediatek.com> Currently auto-hibernate is activated if host supports auto-hibern8 capability. However error-handling is not implemented, which makes the feature somewhat risky. If either "Hibernate Enter" or "Hibernate Exit" fail during auto-hibernate flow, the corresponding interrupt "UIC_HIBERNATE_ENTER" or "UIC_HIBERNATE_EXIT" shall be raised according to UFS specification. This patch adds auto-hibernate error-handling: - Monitor "Hibernate Enter" and "Hibernate Exit" interrupts after auto-hibernate feature is activated. - If fail happens, trigger error-handling just like "manual-hibernate" fail and apply the same recovery flow: schedule UFS error handler in ufshcd_check_errors(), and then do host reset and restore in UFS error handler. Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Reviewed-by: Bean Huo <beanhuo@micron.com> Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com> --- drivers/scsi/ufs/ufshcd.c | 31 +++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 5 +++++ drivers/scsi/ufs/ufshci.h | 3 +++ 3 files changed, 39 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ba04d07df279..2123b0bbb1c2 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5254,6 +5254,7 @@ static void ufshcd_err_handler(struct work_struct *work) goto skip_err_handling; } if ((hba->saved_err & INT_FATAL_ERRORS) || + (hba->saved_err & UFSHCD_UIC_AH8_ERROR_MASK) || ((hba->saved_err & UIC_ERROR) && (hba->saved_uic_err & (UFSHCD_UIC_DL_PA_INIT_ERROR | UFSHCD_UIC_DL_NAC_RECEIVED_ERROR | @@ -5413,6 +5414,23 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba) __func__, hba->uic_error); } +static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, + u32 intr_mask) +{ + if (!ufshcd_is_auto_hibern8_supported(hba)) + return false; + + if (!(intr_mask & UFSHCD_UIC_AH8_ERROR_MASK)) + return false; + + if (hba->active_uic_cmd && + (hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_ENTER || + hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) + return false; + + return true; +} + /** * ufshcd_check_errors - Check for errors that need s/w attention * @hba: per-adapter instance @@ -5431,6 +5449,15 @@ static void ufshcd_check_errors(struct ufs_hba *hba) queue_eh_work = true; } + if (hba->errors & UFSHCD_UIC_AH8_ERROR_MASK) { + dev_err(hba->dev, + "%s: Auto Hibern8 %s failed - status: 0x%08x, upmcrs: 0x%08x\n", + __func__, (hba->errors & UIC_HIBERNATE_ENTER) ? + "Enter" : "Exit", + hba->errors, ufshcd_get_upmcrs(hba)); + queue_eh_work = true; + } + if (queue_eh_work) { /* * update the transfer error masks to sticky bits, let's do this @@ -5493,6 +5520,10 @@ static void ufshcd_tmc_handler(struct ufs_hba *hba) static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) { hba->errors = UFSHCD_ERROR_MASK & intr_status; + + if (ufshcd_is_auto_hibern8_error(hba, intr_status)) + hba->errors |= (UFSHCD_UIC_AH8_ERROR_MASK & intr_status); + if (hba->errors) ufshcd_check_errors(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index ecfa898b9ccc..994d73d03207 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -740,6 +740,11 @@ return true; #endif } +static inline bool ufshcd_is_auto_hibern8_supported(struct ufs_hba *hba) +{ + return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT); +} + #define ufshcd_writel(hba, val, reg) \ writel((val), (hba)->mmio_base + (reg)) #define ufshcd_readl(hba, reg) \ diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 6fa889de5ee5..4bcb205f2077 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -148,6 +148,9 @@ enum { UIC_HIBERNATE_EXIT |\ UIC_POWER_MODE) +#define UFSHCD_UIC_AH8_ERROR_MASK (UIC_HIBERNATE_ENTER |\ + UIC_HIBERNATE_EXIT) + #define UFSHCD_UIC_MASK (UIC_COMMAND_COMPL | UFSHCD_UIC_PWR_MASK) #define UFSHCD_ERROR_MASK (UIC_ERROR |\ -- 2.18.0
WARNING: multiple messages have this Message-ID (diff)
From: Stanley Chu <stanley.chu@mediatek.com> To: <linux-scsi@vger.kernel.org>, <martin.petersen@oracle.com>, <avri.altman@wdc.com>, <alim.akhtar@samsung.com>, <pedrom.sousa@synopsys.com> Cc: marc.w.gonzalez@free.fr, andy.teng@mediatek.com, chun-hung.wu@mediatek.com, kuohong.wang@mediatek.com, evgreen@chromium.org, linux-mediatek@lists.infradead.org, peter.wang@mediatek.com, matthias.bgg@gmail.com, Stanley Chu <stanley.chu@mediatek.com>, linux-arm-kernel@lists.infradead.org, beanhuo@micron.com Subject: [PATCH v3 2/3] scsi: ufs: Add error-handling of Auto-Hibernate Date: Mon, 20 May 2019 16:32:17 +0800 [thread overview] Message-ID: <1558341138-18043-3-git-send-email-stanley.chu@mediatek.com> (raw) In-Reply-To: <1558341138-18043-1-git-send-email-stanley.chu@mediatek.com> Currently auto-hibernate is activated if host supports auto-hibern8 capability. However error-handling is not implemented, which makes the feature somewhat risky. If either "Hibernate Enter" or "Hibernate Exit" fail during auto-hibernate flow, the corresponding interrupt "UIC_HIBERNATE_ENTER" or "UIC_HIBERNATE_EXIT" shall be raised according to UFS specification. This patch adds auto-hibernate error-handling: - Monitor "Hibernate Enter" and "Hibernate Exit" interrupts after auto-hibernate feature is activated. - If fail happens, trigger error-handling just like "manual-hibernate" fail and apply the same recovery flow: schedule UFS error handler in ufshcd_check_errors(), and then do host reset and restore in UFS error handler. Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Reviewed-by: Bean Huo <beanhuo@micron.com> Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com> --- drivers/scsi/ufs/ufshcd.c | 31 +++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd.h | 5 +++++ drivers/scsi/ufs/ufshci.h | 3 +++ 3 files changed, 39 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ba04d07df279..2123b0bbb1c2 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5254,6 +5254,7 @@ static void ufshcd_err_handler(struct work_struct *work) goto skip_err_handling; } if ((hba->saved_err & INT_FATAL_ERRORS) || + (hba->saved_err & UFSHCD_UIC_AH8_ERROR_MASK) || ((hba->saved_err & UIC_ERROR) && (hba->saved_uic_err & (UFSHCD_UIC_DL_PA_INIT_ERROR | UFSHCD_UIC_DL_NAC_RECEIVED_ERROR | @@ -5413,6 +5414,23 @@ static void ufshcd_update_uic_error(struct ufs_hba *hba) __func__, hba->uic_error); } +static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, + u32 intr_mask) +{ + if (!ufshcd_is_auto_hibern8_supported(hba)) + return false; + + if (!(intr_mask & UFSHCD_UIC_AH8_ERROR_MASK)) + return false; + + if (hba->active_uic_cmd && + (hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_ENTER || + hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) + return false; + + return true; +} + /** * ufshcd_check_errors - Check for errors that need s/w attention * @hba: per-adapter instance @@ -5431,6 +5449,15 @@ static void ufshcd_check_errors(struct ufs_hba *hba) queue_eh_work = true; } + if (hba->errors & UFSHCD_UIC_AH8_ERROR_MASK) { + dev_err(hba->dev, + "%s: Auto Hibern8 %s failed - status: 0x%08x, upmcrs: 0x%08x\n", + __func__, (hba->errors & UIC_HIBERNATE_ENTER) ? + "Enter" : "Exit", + hba->errors, ufshcd_get_upmcrs(hba)); + queue_eh_work = true; + } + if (queue_eh_work) { /* * update the transfer error masks to sticky bits, let's do this @@ -5493,6 +5520,10 @@ static void ufshcd_tmc_handler(struct ufs_hba *hba) static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) { hba->errors = UFSHCD_ERROR_MASK & intr_status; + + if (ufshcd_is_auto_hibern8_error(hba, intr_status)) + hba->errors |= (UFSHCD_UIC_AH8_ERROR_MASK & intr_status); + if (hba->errors) ufshcd_check_errors(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index ecfa898b9ccc..994d73d03207 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -740,6 +740,11 @@ return true; #endif } +static inline bool ufshcd_is_auto_hibern8_supported(struct ufs_hba *hba) +{ + return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT); +} + #define ufshcd_writel(hba, val, reg) \ writel((val), (hba)->mmio_base + (reg)) #define ufshcd_readl(hba, reg) \ diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 6fa889de5ee5..4bcb205f2077 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -148,6 +148,9 @@ enum { UIC_HIBERNATE_EXIT |\ UIC_POWER_MODE) +#define UFSHCD_UIC_AH8_ERROR_MASK (UIC_HIBERNATE_ENTER |\ + UIC_HIBERNATE_EXIT) + #define UFSHCD_UIC_MASK (UIC_COMMAND_COMPL | UFSHCD_UIC_PWR_MASK) #define UFSHCD_ERROR_MASK (UIC_ERROR |\ -- 2.18.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-05-20 8:32 UTC|newest] Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-20 8:32 [PATCH v3 0/3] scsi: ufs: Add error handling of Auto-Hibernate Stanley Chu 2019-05-20 8:32 ` Stanley Chu 2019-05-20 8:32 ` [PATCH v3 1/3] scsi: ufs: Do not overwrite Auto-Hibernate timer Stanley Chu 2019-05-20 8:32 ` Stanley Chu 2019-05-20 8:32 ` Stanley Chu [this message] 2019-05-20 8:32 ` [PATCH v3 2/3] scsi: ufs: Add error-handling of Auto-Hibernate Stanley Chu 2019-05-20 9:51 ` Avri Altman 2019-05-20 9:51 ` Avri Altman 2019-05-20 14:05 ` Stanley Chu 2019-05-20 14:05 ` Stanley Chu [not found] ` <1558341138-18043-1-git-send-email-stanley.chu-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org> 2019-05-20 8:32 ` [PATCH v3 3/3] scsi: ufs: Use re-factored Auto-Hibernate function Stanley Chu 2019-05-20 8:32 ` Stanley Chu
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1558341138-18043-3-git-send-email-stanley.chu@mediatek.com \ --to=stanley.chu@mediatek.com \ --cc=alim.akhtar@samsung.com \ --cc=andy.teng@mediatek.com \ --cc=avri.altman@wdc.com \ --cc=beanhuo@micron.com \ --cc=chun-hung.wu@mediatek.com \ --cc=evgreen@chromium.org \ --cc=kuohong.wang@mediatek.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-mediatek@lists.infradead.org \ --cc=linux-scsi@vger.kernel.org \ --cc=marc.w.gonzalez@free.fr \ --cc=martin.petersen@oracle.com \ --cc=matthias.bgg@gmail.com \ --cc=pedrom.sousa@synopsys.com \ --cc=peter.wang@mediatek.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.