mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-15 16:06:40 +07:00
scsi: ufs: ufs-mediatek: Add host reset mechanism
Add host reset mechanism to try to recover host-side errors during recovery flow. Link: https://lore.kernel.org/r/20200908064507.30774-5-stanley.chu@mediatek.com Signed-off-by: Stanley Chu <stanley.chu@mediatek.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
9a9ddb8a3a
commit
e0f9f86262
@ -13,6 +13,7 @@
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/soc/mediatek/mtk_sip_svc.h>
|
||||
|
||||
#include "ufshcd.h"
|
||||
@ -91,16 +92,57 @@ static void ufs_mtk_crypto_enable(struct ufs_hba *hba)
|
||||
}
|
||||
}
|
||||
|
||||
static void ufs_mtk_host_reset(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
|
||||
|
||||
reset_control_assert(host->hci_reset);
|
||||
reset_control_assert(host->crypto_reset);
|
||||
reset_control_assert(host->unipro_reset);
|
||||
|
||||
usleep_range(100, 110);
|
||||
|
||||
reset_control_deassert(host->unipro_reset);
|
||||
reset_control_deassert(host->crypto_reset);
|
||||
reset_control_deassert(host->hci_reset);
|
||||
}
|
||||
|
||||
static void ufs_mtk_init_reset_control(struct ufs_hba *hba,
|
||||
struct reset_control **rc,
|
||||
char *str)
|
||||
{
|
||||
*rc = devm_reset_control_get(hba->dev, str);
|
||||
if (IS_ERR(*rc)) {
|
||||
dev_info(hba->dev, "Failed to get reset control %s: %d\n",
|
||||
str, PTR_ERR(*rc));
|
||||
*rc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ufs_mtk_init_reset(struct ufs_hba *hba)
|
||||
{
|
||||
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
|
||||
|
||||
ufs_mtk_init_reset_control(hba, &host->hci_reset,
|
||||
"hci_rst");
|
||||
ufs_mtk_init_reset_control(hba, &host->unipro_reset,
|
||||
"unipro_rst");
|
||||
ufs_mtk_init_reset_control(hba, &host->crypto_reset,
|
||||
"crypto_rst");
|
||||
}
|
||||
|
||||
static int ufs_mtk_hce_enable_notify(struct ufs_hba *hba,
|
||||
enum ufs_notify_change_status status)
|
||||
{
|
||||
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
|
||||
|
||||
if (status == PRE_CHANGE) {
|
||||
if (host->unipro_lpm)
|
||||
if (host->unipro_lpm) {
|
||||
hba->vps->hba_enable_delay_us = 0;
|
||||
else
|
||||
} else {
|
||||
hba->vps->hba_enable_delay_us = 600;
|
||||
ufs_mtk_host_reset(hba);
|
||||
}
|
||||
|
||||
if (hba->caps & UFSHCD_CAP_CRYPTO)
|
||||
ufs_mtk_crypto_enable(hba);
|
||||
@ -335,6 +377,8 @@ static int ufs_mtk_init(struct ufs_hba *hba)
|
||||
if (err)
|
||||
goto out_variant_clear;
|
||||
|
||||
ufs_mtk_init_reset(hba);
|
||||
|
||||
/* Enable runtime autosuspend */
|
||||
hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
|
||||
|
||||
|
@ -92,6 +92,9 @@ enum {
|
||||
struct ufs_mtk_host {
|
||||
struct ufs_hba *hba;
|
||||
struct phy *mphy;
|
||||
struct reset_control *hci_reset;
|
||||
struct reset_control *unipro_reset;
|
||||
struct reset_control *crypto_reset;
|
||||
bool mphy_powered_on;
|
||||
bool unipro_lpm;
|
||||
bool ref_clk_enabled;
|
||||
|
Loading…
Reference in New Issue
Block a user