crypto: hisilicon - add runtime PM ops
Accelerator devices support runtime PM to reduce power consumption. This patch adds the runtime PM suspend/resume callbacks to the accelerator devices. Signed-off-by: Weili Qian <qianweili@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
1295292d65
commit
d7ea53395b
@ -5692,6 +5692,124 @@ err_pci_init:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(hisi_qm_init);
|
EXPORT_SYMBOL_GPL(hisi_qm_init);
|
||||||
|
|
||||||
|
|
||||||
|
static int qm_prepare_for_suspend(struct hisi_qm *qm)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = qm->pdev;
|
||||||
|
int ret;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
ret = qm->ops->set_msi(qm, false);
|
||||||
|
if (ret) {
|
||||||
|
pci_err(pdev, "failed to disable MSI before suspending!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shutdown OOO register */
|
||||||
|
writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
|
||||||
|
qm->io_base + ACC_MASTER_GLOBAL_CTRL);
|
||||||
|
|
||||||
|
ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
|
||||||
|
val,
|
||||||
|
(val == ACC_MASTER_TRANS_RETURN_RW),
|
||||||
|
POLL_PERIOD, POLL_TIMEOUT);
|
||||||
|
if (ret) {
|
||||||
|
pci_emerg(pdev, "Bus lock! Please reset system.\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qm_set_pf_mse(qm, false);
|
||||||
|
if (ret)
|
||||||
|
pci_err(pdev, "failed to disable MSE before suspending!\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int qm_rebuild_for_resume(struct hisi_qm *qm)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = qm->pdev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = qm_set_pf_mse(qm, true);
|
||||||
|
if (ret) {
|
||||||
|
pci_err(pdev, "failed to enable MSE after resuming!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qm->ops->set_msi(qm, true);
|
||||||
|
if (ret) {
|
||||||
|
pci_err(pdev, "failed to enable MSI after resuming!\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qm_dev_hw_init(qm);
|
||||||
|
if (ret) {
|
||||||
|
pci_err(pdev, "failed to init device after resuming\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
qm_cmd_init(qm);
|
||||||
|
hisi_qm_dev_err_init(qm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hisi_qm_suspend() - Runtime suspend of given device.
|
||||||
|
* @dev: device to suspend.
|
||||||
|
*
|
||||||
|
* Function that suspend the device.
|
||||||
|
*/
|
||||||
|
int hisi_qm_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(dev);
|
||||||
|
struct hisi_qm *qm = pci_get_drvdata(pdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pci_info(pdev, "entering suspended state\n");
|
||||||
|
|
||||||
|
ret = hisi_qm_stop(qm, QM_NORMAL);
|
||||||
|
if (ret) {
|
||||||
|
pci_err(pdev, "failed to stop qm(%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qm_prepare_for_suspend(qm);
|
||||||
|
if (ret)
|
||||||
|
pci_err(pdev, "failed to prepare suspended(%d)\n", ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(hisi_qm_suspend);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hisi_qm_resume() - Runtime resume of given device.
|
||||||
|
* @dev: device to resume.
|
||||||
|
*
|
||||||
|
* Function that resume the device.
|
||||||
|
*/
|
||||||
|
int hisi_qm_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(dev);
|
||||||
|
struct hisi_qm *qm = pci_get_drvdata(pdev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pci_info(pdev, "resuming from suspend state\n");
|
||||||
|
|
||||||
|
ret = qm_rebuild_for_resume(qm);
|
||||||
|
if (ret) {
|
||||||
|
pci_err(pdev, "failed to rebuild resume(%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hisi_qm_start(qm);
|
||||||
|
if (ret)
|
||||||
|
pci_err(pdev, "failed to start qm(%d)\n", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(hisi_qm_resume);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
|
MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
|
||||||
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");
|
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");
|
||||||
|
@ -431,5 +431,7 @@ void hisi_qm_dev_shutdown(struct pci_dev *pdev);
|
|||||||
void hisi_qm_wait_task_finish(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
|
void hisi_qm_wait_task_finish(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
|
||||||
int hisi_qm_alg_register(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
|
int hisi_qm_alg_register(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
|
||||||
void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
|
void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list);
|
||||||
|
int hisi_qm_resume(struct device *dev);
|
||||||
|
int hisi_qm_suspend(struct device *dev);
|
||||||
void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset);
|
void hisi_qm_regs_dump(struct seq_file *s, struct debugfs_regset32 *regset);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user