>-----Original Message----- >From: SEO HOYOUNG [mailto:hy50.seo@xxxxxxxxxxx] >Sent: Monday, September 12, 2022 7:30 PM >To: linux-scsi@xxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; >alim.akhtar@xxxxxxxxxxx; avri.altman@xxxxxxx; jejb@xxxxxxxxxxxxx; >martin.petersen@xxxxxxxxxx; beanhuo@xxxxxxxxxx; >asutoshd@xxxxxxxxxxxxxx; cang@xxxxxxxxxxxxxx; bvanassche@xxxxxxx; >bhoon95.kim@xxxxxxxxxxx; kwmad.kim@xxxxxxxxxxx >Cc: SEO HOYOUNG <hy50.seo@xxxxxxxxxxx> >Subject: [PATCH v1] scsi: ufs: add a variant operation in struct >ufs_hba_variant_ops > >Add ufs_hba_variant_ops about vendor error in check_error. >It need to reset when occurred ah8 related error. >At that time could not recovery with pwr cmd. >So add vendor error check function at ufs_hba_variant_ops. > I didn't understand why you need this, looks like you are using AH8. So IS (interrupt status) bit[5], bit[6] , HIBERNATE_EXIT and HIBERNATE_ENTRY should still give you the error status? >Change-Id: I24c76a372931e702b357c86a5dc36e93ce4b5fda This is something unwanted >Signed-off-by: SEO HOYOUNG <hy50.seo@xxxxxxxxxxx> >--- > drivers/ufs/core/ufshcd-priv.h | 7 +++++++ > drivers/ufs/core/ufshcd.c | 2 ++ > drivers/ufs/host/ufs-exynos.c | 19 +++++++++++++++++++ > include/ufs/ufshcd.h | 1 + > 4 files changed, 29 insertions(+) > >diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h >index d00dba17297d..6172da4d3484 100644 >--- a/drivers/ufs/core/ufshcd-priv.h >+++ b/drivers/ufs/core/ufshcd-priv.h >@@ -221,6 +221,13 @@ static inline void >ufshcd_vops_config_scaling_param(struct ufs_hba *hba, > hba->vops->config_scaling_param(hba, p, data); } > >+static inline void ufshcd_vops_check_int_error(struct ufs_hba *hba, >+ bool *queue_eh_work) >+{ >+ if (hba->vops & hba->vops->check_int_error) >+ hba->vops->check_int_error(hba, queue_eh_work); } >+ > extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[]; > > /** >diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index >7c15cbc737b4..39ee5192f26a 100644 >--- a/drivers/ufs/core/ufshcd.c >+++ b/drivers/ufs/core/ufshcd.c >@@ -6542,6 +6542,8 @@ static irqreturn_t ufshcd_check_errors(struct >ufs_hba *hba, u32 intr_status) > queue_eh_work = true; > } > >+ ufshcd_vops_check_int_error(hba, &queue_eh_work); >+ > if (queue_eh_work) { > /* > * update the transfer error masks to sticky bits, let's do this >diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c >index eced97538082..b351b8e48b08 100644 >--- a/drivers/ufs/host/ufs-exynos.c >+++ b/drivers/ufs/host/ufs-exynos.c >@@ -67,6 +67,10 @@ > #define CLK_CTRL_EN_MASK (REFCLK_CTRL_EN |\ > UNIPRO_PCLK_CTRL_EN |\ > UNIPRO_MCLK_CTRL_EN) >+ >+#define HCI_AH8_STATE 0x50C >+#define HCI_AH8_STATE_ERROR BIT(16) >+ > /* Device fatal error */ > #define DFES_ERR_EN BIT(31) > #define DFES_DEF_L2_ERRS (UIC_DATA_LINK_LAYER_ERROR_RX_BUF_OF >|\ >@@ -1376,6 +1380,20 @@ static void exynos_ufs_hibern8_notify(struct >ufs_hba *hba, > } > } > >+static void exynos_ufs_check_int_error(struct ufs_hba *hba, bool >+*queue_eh_work) { >+ struct exynos_ufs *ufs = ufshcd_get_variant(hba); >+ >+ if (ufshcd_is_auto_hibern8_supported(hba)) { >+ val = hci_readl(ufs, HCI_AH8_STATE); >+ >+ if (val & HCI_AH8_STATE_ERROR) { >+ ufshcd_set_link_broken(hba); >+ queue_eh_work = true; >+ } >+ } >+} >+ > static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op >pm_op, > enum ufs_notify_change_status status) > { >@@ -1569,6 +1587,7 @@ static const struct ufs_hba_variant_ops >ufs_hba_exynos_ops = { > .setup_xfer_req = >exynos_ufs_specify_nexus_t_xfer_req, > .setup_task_mgmt = >exynos_ufs_specify_nexus_t_tm_req, > .hibern8_notify = exynos_ufs_hibern8_notify, >+ .check_int_error = exynos_ufs_check_int_error, > .suspend = exynos_ufs_suspend, > .resume = exynos_ufs_resume, > }; >diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index >24c97e0772bb..40078c4b9f55 100644 >--- a/include/ufs/ufshcd.h >+++ b/include/ufs/ufshcd.h >@@ -335,6 +335,7 @@ struct ufs_hba_variant_ops { > const union ufs_crypto_cfg_entry *cfg, int slot); > void (*event_notify)(struct ufs_hba *hba, > enum ufs_event_type evt, void *data); >+ void (*check_int_error)(struct ufs_hba *hba, bool >*queue_eh_work); > }; > > /* clock gating state */ >-- >2.26.0