@@ -450,6 +450,7 @@ static struct qm_typical_qos_table shaper_cbs_s[] = {
450450};
451451
452452static void qm_irqs_unregister (struct hisi_qm * qm );
453+ static int qm_reset_device (struct hisi_qm * qm );
453454
454455static u32 qm_get_hw_error_status (struct hisi_qm * qm )
455456{
@@ -4108,6 +4109,22 @@ static int qm_controller_reset_prepare(struct hisi_qm *qm)
41084109 return 0 ;
41094110}
41104111
4112+ static int qm_master_ooo_check (struct hisi_qm * qm )
4113+ {
4114+ u32 val ;
4115+ int ret ;
4116+
4117+ /* Check the ooo register of the device before resetting the device. */
4118+ writel (ACC_MASTER_GLOBAL_CTRL_SHUTDOWN , qm -> io_base + ACC_MASTER_GLOBAL_CTRL );
4119+ ret = readl_relaxed_poll_timeout (qm -> io_base + ACC_MASTER_TRANS_RETURN ,
4120+ val , (val == ACC_MASTER_TRANS_RETURN_RW ),
4121+ POLL_PERIOD , POLL_TIMEOUT );
4122+ if (ret )
4123+ pci_warn (qm -> pdev , "Bus lock! Please reset system.\n" );
4124+
4125+ return ret ;
4126+ }
4127+
41114128static void qm_dev_ecc_mbit_handle (struct hisi_qm * qm )
41124129{
41134130 u32 nfe_enb = 0 ;
@@ -4130,11 +4147,10 @@ static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
41304147 }
41314148}
41324149
4133- static int qm_soft_reset (struct hisi_qm * qm )
4150+ static int qm_soft_reset_prepare (struct hisi_qm * qm )
41344151{
41354152 struct pci_dev * pdev = qm -> pdev ;
41364153 int ret ;
4137- u32 val ;
41384154
41394155 /* Ensure all doorbells and mailboxes received by QM */
41404156 ret = qm_check_req_recv (qm );
@@ -4156,29 +4172,23 @@ static int qm_soft_reset(struct hisi_qm *qm)
41564172 }
41574173
41584174 qm_dev_ecc_mbit_handle (qm );
4159-
4160- /* OOO register set and check */
4161- writel (ACC_MASTER_GLOBAL_CTRL_SHUTDOWN ,
4162- qm -> io_base + ACC_MASTER_GLOBAL_CTRL );
4163-
4164- /* If bus lock, reset chip */
4165- ret = readl_relaxed_poll_timeout (qm -> io_base + ACC_MASTER_TRANS_RETURN ,
4166- val ,
4167- (val == ACC_MASTER_TRANS_RETURN_RW ),
4168- POLL_PERIOD , POLL_TIMEOUT );
4169- if (ret ) {
4170- pci_emerg (pdev , "Bus lock! Please reset system.\n" );
4175+ ret = qm_master_ooo_check (qm );
4176+ if (ret )
41714177 return ret ;
4172- }
41734178
41744179 if (qm -> err_ini -> close_sva_prefetch )
41754180 qm -> err_ini -> close_sva_prefetch (qm );
41764181
41774182 ret = qm_set_pf_mse (qm , false);
4178- if (ret ) {
4183+ if (ret )
41794184 pci_err (pdev , "Fails to disable pf MSE bit.\n" );
4180- return ret ;
4181- }
4185+
4186+ return ret ;
4187+ }
4188+
4189+ static int qm_reset_device (struct hisi_qm * qm )
4190+ {
4191+ struct pci_dev * pdev = qm -> pdev ;
41824192
41834193 /* The reset related sub-control registers are not in PCI BAR */
41844194 if (ACPI_HANDLE (& pdev -> dev )) {
@@ -4197,12 +4207,23 @@ static int qm_soft_reset(struct hisi_qm *qm)
41974207 pci_err (pdev , "Reset step %llu failed!\n" , value );
41984208 return - EIO ;
41994209 }
4200- } else {
4201- pci_err (pdev , "No reset method!\n" );
4202- return - EINVAL ;
4210+
4211+ return 0 ;
42034212 }
42044213
4205- return 0 ;
4214+ pci_err (pdev , "No reset method!\n" );
4215+ return - EINVAL ;
4216+ }
4217+
4218+ static int qm_soft_reset (struct hisi_qm * qm )
4219+ {
4220+ int ret ;
4221+
4222+ ret = qm_soft_reset_prepare (qm );
4223+ if (ret )
4224+ return ret ;
4225+
4226+ return qm_reset_device (qm );
42064227}
42074228
42084229static int qm_vf_reset_done (struct hisi_qm * qm )
@@ -5155,6 +5176,35 @@ static int qm_get_pci_res(struct hisi_qm *qm)
51555176 return ret ;
51565177}
51575178
5179+ static int qm_clear_device (struct hisi_qm * qm )
5180+ {
5181+ acpi_handle handle = ACPI_HANDLE (& qm -> pdev -> dev );
5182+ int ret ;
5183+
5184+ if (qm -> fun_type == QM_HW_VF )
5185+ return 0 ;
5186+
5187+ /* Device does not support reset, return */
5188+ if (!qm -> err_ini -> err_info_init )
5189+ return 0 ;
5190+ qm -> err_ini -> err_info_init (qm );
5191+
5192+ if (!handle )
5193+ return 0 ;
5194+
5195+ /* No reset method, return */
5196+ if (!acpi_has_method (handle , qm -> err_info .acpi_rst ))
5197+ return 0 ;
5198+
5199+ ret = qm_master_ooo_check (qm );
5200+ if (ret ) {
5201+ writel (0x0 , qm -> io_base + ACC_MASTER_GLOBAL_CTRL );
5202+ return ret ;
5203+ }
5204+
5205+ return qm_reset_device (qm );
5206+ }
5207+
51585208static int hisi_qm_pci_init (struct hisi_qm * qm )
51595209{
51605210 struct pci_dev * pdev = qm -> pdev ;
@@ -5184,8 +5234,14 @@ static int hisi_qm_pci_init(struct hisi_qm *qm)
51845234 goto err_get_pci_res ;
51855235 }
51865236
5237+ ret = qm_clear_device (qm );
5238+ if (ret )
5239+ goto err_free_vectors ;
5240+
51875241 return 0 ;
51885242
5243+ err_free_vectors :
5244+ pci_free_irq_vectors (pdev );
51895245err_get_pci_res :
51905246 qm_put_pci_res (qm );
51915247err_disable_pcidev :
@@ -5486,26 +5542,16 @@ static int qm_prepare_for_suspend(struct hisi_qm *qm)
54865542{
54875543 struct pci_dev * pdev = qm -> pdev ;
54885544 int ret ;
5489- u32 val ;
54905545
54915546 ret = qm -> ops -> set_msi (qm , false);
54925547 if (ret ) {
54935548 pci_err (pdev , "failed to disable MSI before suspending!\n" );
54945549 return ret ;
54955550 }
54965551
5497- /* shutdown OOO register */
5498- writel (ACC_MASTER_GLOBAL_CTRL_SHUTDOWN ,
5499- qm -> io_base + ACC_MASTER_GLOBAL_CTRL );
5500-
5501- ret = readl_relaxed_poll_timeout (qm -> io_base + ACC_MASTER_TRANS_RETURN ,
5502- val ,
5503- (val == ACC_MASTER_TRANS_RETURN_RW ),
5504- POLL_PERIOD , POLL_TIMEOUT );
5505- if (ret ) {
5506- pci_emerg (pdev , "Bus lock! Please reset system.\n" );
5552+ ret = qm_master_ooo_check (qm );
5553+ if (ret )
55075554 return ret ;
5508- }
55095555
55105556 ret = qm_set_pf_mse (qm , false);
55115557 if (ret )
0 commit comments