@@ -5692,6 +5692,124 @@ int hisi_qm_init(struct hisi_qm *qm)
56925692}
56935693EXPORT_SYMBOL_GPL (hisi_qm_init );
56945694
5695+
5696+ static int qm_prepare_for_suspend (struct hisi_qm * qm )
5697+ {
5698+ struct pci_dev * pdev = qm -> pdev ;
5699+ int ret ;
5700+ u32 val ;
5701+
5702+ ret = qm -> ops -> set_msi (qm , false);
5703+ if (ret ) {
5704+ pci_err (pdev , "failed to disable MSI before suspending!\n" );
5705+ return ret ;
5706+ }
5707+
5708+ /* shutdown OOO register */
5709+ writel (ACC_MASTER_GLOBAL_CTRL_SHUTDOWN ,
5710+ qm -> io_base + ACC_MASTER_GLOBAL_CTRL );
5711+
5712+ ret = readl_relaxed_poll_timeout (qm -> io_base + ACC_MASTER_TRANS_RETURN ,
5713+ val ,
5714+ (val == ACC_MASTER_TRANS_RETURN_RW ),
5715+ POLL_PERIOD , POLL_TIMEOUT );
5716+ if (ret ) {
5717+ pci_emerg (pdev , "Bus lock! Please reset system.\n" );
5718+ return ret ;
5719+ }
5720+
5721+ ret = qm_set_pf_mse (qm , false);
5722+ if (ret )
5723+ pci_err (pdev , "failed to disable MSE before suspending!\n" );
5724+
5725+ return ret ;
5726+ }
5727+
5728+ static int qm_rebuild_for_resume (struct hisi_qm * qm )
5729+ {
5730+ struct pci_dev * pdev = qm -> pdev ;
5731+ int ret ;
5732+
5733+ ret = qm_set_pf_mse (qm , true);
5734+ if (ret ) {
5735+ pci_err (pdev , "failed to enable MSE after resuming!\n" );
5736+ return ret ;
5737+ }
5738+
5739+ ret = qm -> ops -> set_msi (qm , true);
5740+ if (ret ) {
5741+ pci_err (pdev , "failed to enable MSI after resuming!\n" );
5742+ return ret ;
5743+ }
5744+
5745+ ret = qm_dev_hw_init (qm );
5746+ if (ret ) {
5747+ pci_err (pdev , "failed to init device after resuming\n" );
5748+ return ret ;
5749+ }
5750+
5751+ qm_cmd_init (qm );
5752+ hisi_qm_dev_err_init (qm );
5753+
5754+ return 0 ;
5755+ }
5756+
5757+ /**
5758+ * hisi_qm_suspend() - Runtime suspend of given device.
5759+ * @dev: device to suspend.
5760+ *
5761+ * Function that suspend the device.
5762+ */
5763+ int hisi_qm_suspend (struct device * dev )
5764+ {
5765+ struct pci_dev * pdev = to_pci_dev (dev );
5766+ struct hisi_qm * qm = pci_get_drvdata (pdev );
5767+ int ret ;
5768+
5769+ pci_info (pdev , "entering suspended state\n" );
5770+
5771+ ret = hisi_qm_stop (qm , QM_NORMAL );
5772+ if (ret ) {
5773+ pci_err (pdev , "failed to stop qm(%d)\n" , ret );
5774+ return ret ;
5775+ }
5776+
5777+ ret = qm_prepare_for_suspend (qm );
5778+ if (ret )
5779+ pci_err (pdev , "failed to prepare suspended(%d)\n" , ret );
5780+
5781+ return ret ;
5782+ }
5783+ EXPORT_SYMBOL_GPL (hisi_qm_suspend );
5784+
5785+ /**
5786+ * hisi_qm_resume() - Runtime resume of given device.
5787+ * @dev: device to resume.
5788+ *
5789+ * Function that resume the device.
5790+ */
5791+ int hisi_qm_resume (struct device * dev )
5792+ {
5793+ struct pci_dev * pdev = to_pci_dev (dev );
5794+ struct hisi_qm * qm = pci_get_drvdata (pdev );
5795+ int ret ;
5796+
5797+ pci_info (pdev , "resuming from suspend state\n" );
5798+
5799+ ret = qm_rebuild_for_resume (qm );
5800+ if (ret ) {
5801+ pci_err (pdev , "failed to rebuild resume(%d)\n" , ret );
5802+ return ret ;
5803+ }
5804+
5805+ ret = hisi_qm_start (qm );
5806+ if (ret )
5807+ pci_err (pdev , "failed to start qm(%d)\n" , ret );
5808+
5809+ return 0 ;
5810+ }
5811+ EXPORT_SYMBOL_GPL (hisi_qm_resume );
5812+
56955813MODULE_LICENSE ("GPL v2" );
56965814MODULE_AUTHOR ("Zhou Wang <wangzhou1@hisilicon.com>" );
56975815MODULE_DESCRIPTION ("HiSilicon Accelerator queue manager driver" );
0 commit comments