diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index d696ebaacf3c0..9ffd0e91faa46 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -760,9 +760,17 @@ static int ufs_qcom_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, if (!ufs_qcom_is_link_active(hba)) ufs_qcom_disable_lane_clks(host); - - /* reset the connected UFS device during power down */ - if (ufs_qcom_is_link_off(hba) && host->device_reset) { + /* + * For some UFS vendors, skip asserting device reset here. + * These vendor parts keep drawing larger current after reset + * is asserted until it is deasserted, and the 10ms delay is + * not sufficient to prevent OCP (Over Current Protection) + * on the regulator. This is for the powerdown case, so + * the device reset can be asserted later as part of the + * platform shutdown sequence. + */ + if (ufs_qcom_is_link_off(hba) && host->device_reset && + !(hba->quirks & UFSHCD_QUIRK_SKIP_DEVICE_RESET)) { ufs_qcom_device_reset_ctrl(hba, true); /* * After sending the SSU command, asserting the rst_n @@ -1278,6 +1286,19 @@ static struct ufs_dev_quirk ufs_qcom_dev_fixups[] = { static void ufs_qcom_fixup_dev_quirks(struct ufs_hba *hba) { ufshcd_fixup_dev_quirks(hba, ufs_qcom_dev_fixups); + + /* + * Some UFS parts keep drawing larger current after reset is asserted + * until it is deasserted. The 10ms delay added after asserting HWRST + * (as done for other vendors) is not sufficient for these parts. + * + * Skip asserting device reset during UFS power down for these parts + * to prevent OCP (Over Current Protection) fault on the regulator. + * This is handled only in shutdown; the device reset will be asserted + * as part of the platform shutdown sequence. + */ + if (hba->dev_info.wmanufacturerid == UFS_VENDOR_MICRON) + hba->quirks |= UFSHCD_QUIRK_SKIP_DEVICE_RESET; } static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba) diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index cfbc75d8df836..e0ce7232c46ac 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -804,6 +804,20 @@ enum ufshcd_quirks { * delay after enabling VCC to ensure it's stable. */ UFSHCD_QUIRK_VCC_ON_DELAY = 1 << 27, + + /* + * Some UFS devices keep drawing larger current after reset is + * asserted until it is deasserted. Asserting device reset + * during UFS power down causes the device firmware to wake up and + * execute its reset routine, drawing current beyond the permissible + * limit for low-power mode (LPM). This may trigger an OCP fault on + * the regulator supplying power to UFS. + * + * Enable this quirk to skip asserting device reset during UFS power + * down. This is handled only in shutdown; the device reset will be + * asserted as part of the platform shutdown sequence. + */ + UFSHCD_QUIRK_SKIP_DEVICE_RESET = 1 << 28, }; enum ufshcd_caps {