Loading drivers/scsi/ufs/ufs-qcom.c +3 −0 Original line number Original line Diff line number Diff line Loading @@ -2882,6 +2882,9 @@ static const struct dev_pm_ops ufs_qcom_pm_ops = { .runtime_suspend = ufshcd_pltfrm_runtime_suspend, .runtime_suspend = ufshcd_pltfrm_runtime_suspend, .runtime_resume = ufshcd_pltfrm_runtime_resume, .runtime_resume = ufshcd_pltfrm_runtime_resume, .runtime_idle = ufshcd_pltfrm_runtime_idle, .runtime_idle = ufshcd_pltfrm_runtime_idle, .freeze = ufshcd_pltfrm_freeze, .restore = ufshcd_pltfrm_restore, .thaw = ufshcd_pltfrm_thaw, }; }; static struct platform_driver ufs_qcom_pltform = { static struct platform_driver ufs_qcom_pltform = { Loading drivers/scsi/ufs/ufshcd-pltfrm.c +39 −0 Original line number Original line Diff line number Diff line Loading @@ -370,6 +370,45 @@ static void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba) } } #ifdef CONFIG_SMP #ifdef CONFIG_SMP /** * ufshcd_pltfrm_restore - restore power management function * @dev: pointer to device handle * * Returns 0 if successful * Returns non-zero otherwise */ int ufshcd_pltfrm_restore(struct device *dev) { return ufshcd_system_restore(dev_get_drvdata(dev)); } EXPORT_SYMBOL(ufshcd_pltfrm_restore); /** * ufshcd_pltfrm_freeze - freeze power management function * @dev: pointer to device handle * * Returns 0 if successful * Returns non-zero otherwise */ int ufshcd_pltfrm_freeze(struct device *dev) { return ufshcd_system_freeze(dev_get_drvdata(dev)); } EXPORT_SYMBOL(ufshcd_pltfrm_freeze); /** * ufshcd_pltfrm_thaw - freeze power management function * @dev: pointer to device handle * * Returns 0 if successful * Returns non-zero otherwise */ int ufshcd_pltfrm_thaw(struct device *dev) { return ufshcd_system_thaw(dev_get_drvdata(dev)); } EXPORT_SYMBOL(ufshcd_pltfrm_thaw); /** /** * ufshcd_pltfrm_suspend - suspend power management function * ufshcd_pltfrm_suspend - suspend power management function * @dev: pointer to device handle * @dev: pointer to device handle Loading drivers/scsi/ufs/ufshcd-pltfrm.h +4 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -27,6 +27,9 @@ int ufshcd_pltfrm_resume(struct device *dev); int ufshcd_pltfrm_runtime_suspend(struct device *dev); int ufshcd_pltfrm_runtime_suspend(struct device *dev); int ufshcd_pltfrm_runtime_resume(struct device *dev); int ufshcd_pltfrm_runtime_resume(struct device *dev); int ufshcd_pltfrm_runtime_idle(struct device *dev); int ufshcd_pltfrm_runtime_idle(struct device *dev); int ufshcd_pltfrm_freeze(struct device *dev); int ufshcd_pltfrm_restore(struct device *dev); int ufshcd_pltfrm_thaw(struct device *dev); #else /* !CONFIG_PM */ #else /* !CONFIG_PM */ Loading drivers/scsi/ufs/ufshcd.c +41 −3 Original line number Original line Diff line number Diff line Loading @@ -3817,8 +3817,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (err) { if (err) { if (err != -EAGAIN) if (err != -EAGAIN) dev_err(hba->dev, dev_err(hba->dev, "%s: failed to compose upiu %d\n", "%s: failed to compose upiu %d cmd:0x%08x lun:%d\n", __func__, err); __func__, err, cmd, lrbp->lun); lrbp->cmd = NULL; lrbp->cmd = NULL; clear_bit_unlock(tag, &hba->lrb_in_use); clear_bit_unlock(tag, &hba->lrb_in_use); Loading Loading @@ -10254,7 +10254,19 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ret = ufshcd_vreg_set_hpm(hba); ret = ufshcd_vreg_set_hpm(hba); if (ret) if (ret) goto disable_irq_and_vops_clks; goto disable_irq_and_vops_clks; if (hba->restore) { /* Configure UTRL and UTMRL base address registers */ ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), REG_UTP_TRANSFER_REQ_LIST_BASE_L); ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr), REG_UTP_TRANSFER_REQ_LIST_BASE_H); ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr), REG_UTP_TASK_REQ_LIST_BASE_L); ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr), REG_UTP_TASK_REQ_LIST_BASE_H); /* Commit the registers */ mb(); } /* /* * Call vendor specific resume callback. As these callbacks may access * Call vendor specific resume callback. As these callbacks may access * vendor specific host controller register space call them when the * vendor specific host controller register space call them when the Loading @@ -10269,6 +10281,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device))) (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device))) goto skip_dev_ops; goto skip_dev_ops; /* Resuming from hibernate, assume that link was OFF */ if (hba->restore) ufshcd_set_link_off(hba); if (ufshcd_is_link_hibern8(hba)) { if (ufshcd_is_link_hibern8(hba)) { ret = ufshcd_uic_hibern8_exit(hba); ret = ufshcd_uic_hibern8_exit(hba); if (!ret) { if (!ret) { Loading Loading @@ -10340,6 +10356,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) out: out: hba->pm_op_in_progress = 0; hba->pm_op_in_progress = 0; if (hba->restore) hba->restore = false; if (ret) if (ret) ufshcd_update_error_stats(hba, UFS_ERR_RESUME); ufshcd_update_error_stats(hba, UFS_ERR_RESUME); Loading Loading @@ -10502,6 +10521,25 @@ int ufshcd_runtime_idle(struct ufs_hba *hba) } } EXPORT_SYMBOL(ufshcd_runtime_idle); EXPORT_SYMBOL(ufshcd_runtime_idle); int ufshcd_system_freeze(struct ufs_hba *hba) { return ufshcd_system_suspend(hba); } EXPORT_SYMBOL(ufshcd_system_freeze); int ufshcd_system_restore(struct ufs_hba *hba) { hba->restore = true; return ufshcd_system_resume(hba); } EXPORT_SYMBOL(ufshcd_system_restore); int ufshcd_system_thaw(struct ufs_hba *hba) { return ufshcd_system_resume(hba); } EXPORT_SYMBOL(ufshcd_system_thaw); static inline ssize_t ufshcd_pm_lvl_store(struct device *dev, static inline ssize_t ufshcd_pm_lvl_store(struct device *dev, struct device_attribute *attr, struct device_attribute *attr, const char *buf, size_t count, const char *buf, size_t count, Loading drivers/scsi/ufs/ufshcd.h +8 −1 Original line number Original line Diff line number Diff line Loading @@ -3,7 +3,7 @@ * * * This code is based on drivers/scsi/ufs/ufshcd.h * This code is based on drivers/scsi/ufs/ufshcd.h * Copyright (C) 2011-2013 Samsung India Software Operations * Copyright (C) 2011-2013 Samsung India Software Operations * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * * Authors: * Authors: * Santosh Yaraganavi <santosh.sy@samsung.com> * Santosh Yaraganavi <santosh.sy@samsung.com> Loading Loading @@ -112,11 +112,13 @@ enum ufs_pm_op { UFS_RUNTIME_PM, UFS_RUNTIME_PM, UFS_SYSTEM_PM, UFS_SYSTEM_PM, UFS_SHUTDOWN_PM, UFS_SHUTDOWN_PM, UFS_SYSTEM_RESTORE, }; }; #define ufshcd_is_runtime_pm(op) ((op) == UFS_RUNTIME_PM) #define ufshcd_is_runtime_pm(op) ((op) == UFS_RUNTIME_PM) #define ufshcd_is_system_pm(op) ((op) == UFS_SYSTEM_PM) #define ufshcd_is_system_pm(op) ((op) == UFS_SYSTEM_PM) #define ufshcd_is_shutdown_pm(op) ((op) == UFS_SHUTDOWN_PM) #define ufshcd_is_shutdown_pm(op) ((op) == UFS_SHUTDOWN_PM) #define ufshcd_is_restore(op) ((op) == UFS_SYSTEM_RESTORE) /* Host <-> Device UniPro Link state */ /* Host <-> Device UniPro Link state */ enum uic_link_state { enum uic_link_state { Loading Loading @@ -1042,6 +1044,8 @@ struct ufs_hba { bool reinit_g4_rate_A; bool reinit_g4_rate_A; bool force_g4; bool force_g4; /* distinguish between resume and restore */ bool restore; }; }; static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba) static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba) Loading Loading @@ -1171,6 +1175,9 @@ static inline bool ufshcd_keep_autobkops_enabled_except_suspend( return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND; return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND; } } extern int ufshcd_system_thaw(struct ufs_hba *hba); extern int ufshcd_system_restore(struct ufs_hba *hba); extern int ufshcd_system_freeze(struct ufs_hba *hba); extern int ufshcd_runtime_suspend(struct ufs_hba *hba); extern int ufshcd_runtime_suspend(struct ufs_hba *hba); extern int ufshcd_runtime_resume(struct ufs_hba *hba); extern int ufshcd_runtime_resume(struct ufs_hba *hba); extern int ufshcd_runtime_idle(struct ufs_hba *hba); extern int ufshcd_runtime_idle(struct ufs_hba *hba); Loading Loading
drivers/scsi/ufs/ufs-qcom.c +3 −0 Original line number Original line Diff line number Diff line Loading @@ -2882,6 +2882,9 @@ static const struct dev_pm_ops ufs_qcom_pm_ops = { .runtime_suspend = ufshcd_pltfrm_runtime_suspend, .runtime_suspend = ufshcd_pltfrm_runtime_suspend, .runtime_resume = ufshcd_pltfrm_runtime_resume, .runtime_resume = ufshcd_pltfrm_runtime_resume, .runtime_idle = ufshcd_pltfrm_runtime_idle, .runtime_idle = ufshcd_pltfrm_runtime_idle, .freeze = ufshcd_pltfrm_freeze, .restore = ufshcd_pltfrm_restore, .thaw = ufshcd_pltfrm_thaw, }; }; static struct platform_driver ufs_qcom_pltform = { static struct platform_driver ufs_qcom_pltform = { Loading
drivers/scsi/ufs/ufshcd-pltfrm.c +39 −0 Original line number Original line Diff line number Diff line Loading @@ -370,6 +370,45 @@ static void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba) } } #ifdef CONFIG_SMP #ifdef CONFIG_SMP /** * ufshcd_pltfrm_restore - restore power management function * @dev: pointer to device handle * * Returns 0 if successful * Returns non-zero otherwise */ int ufshcd_pltfrm_restore(struct device *dev) { return ufshcd_system_restore(dev_get_drvdata(dev)); } EXPORT_SYMBOL(ufshcd_pltfrm_restore); /** * ufshcd_pltfrm_freeze - freeze power management function * @dev: pointer to device handle * * Returns 0 if successful * Returns non-zero otherwise */ int ufshcd_pltfrm_freeze(struct device *dev) { return ufshcd_system_freeze(dev_get_drvdata(dev)); } EXPORT_SYMBOL(ufshcd_pltfrm_freeze); /** * ufshcd_pltfrm_thaw - freeze power management function * @dev: pointer to device handle * * Returns 0 if successful * Returns non-zero otherwise */ int ufshcd_pltfrm_thaw(struct device *dev) { return ufshcd_system_thaw(dev_get_drvdata(dev)); } EXPORT_SYMBOL(ufshcd_pltfrm_thaw); /** /** * ufshcd_pltfrm_suspend - suspend power management function * ufshcd_pltfrm_suspend - suspend power management function * @dev: pointer to device handle * @dev: pointer to device handle Loading
drivers/scsi/ufs/ufshcd-pltfrm.h +4 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015, 2019, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -27,6 +27,9 @@ int ufshcd_pltfrm_resume(struct device *dev); int ufshcd_pltfrm_runtime_suspend(struct device *dev); int ufshcd_pltfrm_runtime_suspend(struct device *dev); int ufshcd_pltfrm_runtime_resume(struct device *dev); int ufshcd_pltfrm_runtime_resume(struct device *dev); int ufshcd_pltfrm_runtime_idle(struct device *dev); int ufshcd_pltfrm_runtime_idle(struct device *dev); int ufshcd_pltfrm_freeze(struct device *dev); int ufshcd_pltfrm_restore(struct device *dev); int ufshcd_pltfrm_thaw(struct device *dev); #else /* !CONFIG_PM */ #else /* !CONFIG_PM */ Loading
drivers/scsi/ufs/ufshcd.c +41 −3 Original line number Original line Diff line number Diff line Loading @@ -3817,8 +3817,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (err) { if (err) { if (err != -EAGAIN) if (err != -EAGAIN) dev_err(hba->dev, dev_err(hba->dev, "%s: failed to compose upiu %d\n", "%s: failed to compose upiu %d cmd:0x%08x lun:%d\n", __func__, err); __func__, err, cmd, lrbp->lun); lrbp->cmd = NULL; lrbp->cmd = NULL; clear_bit_unlock(tag, &hba->lrb_in_use); clear_bit_unlock(tag, &hba->lrb_in_use); Loading Loading @@ -10254,7 +10254,19 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ret = ufshcd_vreg_set_hpm(hba); ret = ufshcd_vreg_set_hpm(hba); if (ret) if (ret) goto disable_irq_and_vops_clks; goto disable_irq_and_vops_clks; if (hba->restore) { /* Configure UTRL and UTMRL base address registers */ ufshcd_writel(hba, lower_32_bits(hba->utrdl_dma_addr), REG_UTP_TRANSFER_REQ_LIST_BASE_L); ufshcd_writel(hba, upper_32_bits(hba->utrdl_dma_addr), REG_UTP_TRANSFER_REQ_LIST_BASE_H); ufshcd_writel(hba, lower_32_bits(hba->utmrdl_dma_addr), REG_UTP_TASK_REQ_LIST_BASE_L); ufshcd_writel(hba, upper_32_bits(hba->utmrdl_dma_addr), REG_UTP_TASK_REQ_LIST_BASE_H); /* Commit the registers */ mb(); } /* /* * Call vendor specific resume callback. As these callbacks may access * Call vendor specific resume callback. As these callbacks may access * vendor specific host controller register space call them when the * vendor specific host controller register space call them when the Loading @@ -10269,6 +10281,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device))) (ufshcd_is_card_online(hba) && !hba->sdev_ufs_device))) goto skip_dev_ops; goto skip_dev_ops; /* Resuming from hibernate, assume that link was OFF */ if (hba->restore) ufshcd_set_link_off(hba); if (ufshcd_is_link_hibern8(hba)) { if (ufshcd_is_link_hibern8(hba)) { ret = ufshcd_uic_hibern8_exit(hba); ret = ufshcd_uic_hibern8_exit(hba); if (!ret) { if (!ret) { Loading Loading @@ -10340,6 +10356,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) out: out: hba->pm_op_in_progress = 0; hba->pm_op_in_progress = 0; if (hba->restore) hba->restore = false; if (ret) if (ret) ufshcd_update_error_stats(hba, UFS_ERR_RESUME); ufshcd_update_error_stats(hba, UFS_ERR_RESUME); Loading Loading @@ -10502,6 +10521,25 @@ int ufshcd_runtime_idle(struct ufs_hba *hba) } } EXPORT_SYMBOL(ufshcd_runtime_idle); EXPORT_SYMBOL(ufshcd_runtime_idle); int ufshcd_system_freeze(struct ufs_hba *hba) { return ufshcd_system_suspend(hba); } EXPORT_SYMBOL(ufshcd_system_freeze); int ufshcd_system_restore(struct ufs_hba *hba) { hba->restore = true; return ufshcd_system_resume(hba); } EXPORT_SYMBOL(ufshcd_system_restore); int ufshcd_system_thaw(struct ufs_hba *hba) { return ufshcd_system_resume(hba); } EXPORT_SYMBOL(ufshcd_system_thaw); static inline ssize_t ufshcd_pm_lvl_store(struct device *dev, static inline ssize_t ufshcd_pm_lvl_store(struct device *dev, struct device_attribute *attr, struct device_attribute *attr, const char *buf, size_t count, const char *buf, size_t count, Loading
drivers/scsi/ufs/ufshcd.h +8 −1 Original line number Original line Diff line number Diff line Loading @@ -3,7 +3,7 @@ * * * This code is based on drivers/scsi/ufs/ufshcd.h * This code is based on drivers/scsi/ufs/ufshcd.h * Copyright (C) 2011-2013 Samsung India Software Operations * Copyright (C) 2011-2013 Samsung India Software Operations * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. * * * Authors: * Authors: * Santosh Yaraganavi <santosh.sy@samsung.com> * Santosh Yaraganavi <santosh.sy@samsung.com> Loading Loading @@ -112,11 +112,13 @@ enum ufs_pm_op { UFS_RUNTIME_PM, UFS_RUNTIME_PM, UFS_SYSTEM_PM, UFS_SYSTEM_PM, UFS_SHUTDOWN_PM, UFS_SHUTDOWN_PM, UFS_SYSTEM_RESTORE, }; }; #define ufshcd_is_runtime_pm(op) ((op) == UFS_RUNTIME_PM) #define ufshcd_is_runtime_pm(op) ((op) == UFS_RUNTIME_PM) #define ufshcd_is_system_pm(op) ((op) == UFS_SYSTEM_PM) #define ufshcd_is_system_pm(op) ((op) == UFS_SYSTEM_PM) #define ufshcd_is_shutdown_pm(op) ((op) == UFS_SHUTDOWN_PM) #define ufshcd_is_shutdown_pm(op) ((op) == UFS_SHUTDOWN_PM) #define ufshcd_is_restore(op) ((op) == UFS_SYSTEM_RESTORE) /* Host <-> Device UniPro Link state */ /* Host <-> Device UniPro Link state */ enum uic_link_state { enum uic_link_state { Loading Loading @@ -1042,6 +1044,8 @@ struct ufs_hba { bool reinit_g4_rate_A; bool reinit_g4_rate_A; bool force_g4; bool force_g4; /* distinguish between resume and restore */ bool restore; }; }; static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba) static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba) Loading Loading @@ -1171,6 +1175,9 @@ static inline bool ufshcd_keep_autobkops_enabled_except_suspend( return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND; return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND; } } extern int ufshcd_system_thaw(struct ufs_hba *hba); extern int ufshcd_system_restore(struct ufs_hba *hba); extern int ufshcd_system_freeze(struct ufs_hba *hba); extern int ufshcd_runtime_suspend(struct ufs_hba *hba); extern int ufshcd_runtime_suspend(struct ufs_hba *hba); extern int ufshcd_runtime_resume(struct ufs_hba *hba); extern int ufshcd_runtime_resume(struct ufs_hba *hba); extern int ufshcd_runtime_idle(struct ufs_hba *hba); extern int ufshcd_runtime_idle(struct ufs_hba *hba); Loading