@@ -37,11 +37,11 @@ static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_
3737{
3838 union cmd_response cmd_resp ;
3939
40- /* Get response with status within a max of 800 ms timeout */
40+ /* Get response with status within a max of 1600 ms timeout */
4141 if (!readl_poll_timeout (mp2 -> mmio + AMD_P2C_MSG (0 ), cmd_resp .resp ,
4242 (cmd_resp .response_v2 .response == sensor_sts &&
4343 cmd_resp .response_v2 .status == 0 && (sid == 0xff ||
44- cmd_resp .response_v2 .sensor_id == sid )), 500 , 800000 ))
44+ cmd_resp .response_v2 .sensor_id == sid )), 500 , 1600000 ))
4545 return cmd_resp .response_v2 .response ;
4646
4747 return SENSOR_DISABLED ;
@@ -53,6 +53,7 @@ static void amd_start_sensor_v2(struct amd_mp2_dev *privdata, struct amd_mp2_sen
5353
5454 cmd_base .ul = 0 ;
5555 cmd_base .cmd_v2 .cmd_id = ENABLE_SENSOR ;
56+ cmd_base .cmd_v2 .intr_disable = 1 ;
5657 cmd_base .cmd_v2 .period = info .period ;
5758 cmd_base .cmd_v2 .sensor_id = info .sensor_idx ;
5859 cmd_base .cmd_v2 .length = 16 ;
@@ -70,6 +71,7 @@ static void amd_stop_sensor_v2(struct amd_mp2_dev *privdata, u16 sensor_idx)
7071
7172 cmd_base .ul = 0 ;
7273 cmd_base .cmd_v2 .cmd_id = DISABLE_SENSOR ;
74+ cmd_base .cmd_v2 .intr_disable = 1 ;
7375 cmd_base .cmd_v2 .period = 0 ;
7476 cmd_base .cmd_v2 .sensor_id = sensor_idx ;
7577 cmd_base .cmd_v2 .length = 16 ;
@@ -83,12 +85,51 @@ static void amd_stop_all_sensor_v2(struct amd_mp2_dev *privdata)
8385 union sfh_cmd_base cmd_base ;
8486
8587 cmd_base .cmd_v2 .cmd_id = STOP_ALL_SENSORS ;
88+ cmd_base .cmd_v2 .intr_disable = 1 ;
8689 cmd_base .cmd_v2 .period = 0 ;
8790 cmd_base .cmd_v2 .sensor_id = 0 ;
8891
8992 writel (cmd_base .ul , privdata -> mmio + AMD_C2P_MSG0 );
9093}
9194
95+ static void amd_sfh_clear_intr_v2 (struct amd_mp2_dev * privdata )
96+ {
97+ if (readl (privdata -> mmio + AMD_P2C_MSG (4 ))) {
98+ writel (0 , privdata -> mmio + AMD_P2C_MSG (4 ));
99+ writel (0xf , privdata -> mmio + AMD_P2C_MSG (5 ));
100+ }
101+ }
102+
103+ static void amd_sfh_clear_intr (struct amd_mp2_dev * privdata )
104+ {
105+ if (privdata -> mp2_ops -> clear_intr )
106+ privdata -> mp2_ops -> clear_intr (privdata );
107+ }
108+
109+ static irqreturn_t amd_sfh_irq_handler (int irq , void * data )
110+ {
111+ amd_sfh_clear_intr (data );
112+
113+ return IRQ_HANDLED ;
114+ }
115+
116+ static int amd_sfh_irq_init_v2 (struct amd_mp2_dev * privdata )
117+ {
118+ int rc ;
119+
120+ pci_intx (privdata -> pdev , true);
121+
122+ rc = devm_request_irq (& privdata -> pdev -> dev , privdata -> pdev -> irq ,
123+ amd_sfh_irq_handler , 0 , DRIVER_NAME , privdata );
124+ if (rc ) {
125+ dev_err (& privdata -> pdev -> dev , "failed to request irq %d err=%d\n" ,
126+ privdata -> pdev -> irq , rc );
127+ return rc ;
128+ }
129+
130+ return 0 ;
131+ }
132+
92133void amd_start_sensor (struct amd_mp2_dev * privdata , struct amd_mp2_sensor_info info )
93134{
94135 union sfh_cmd_param cmd_param ;
@@ -193,13 +234,17 @@ static void amd_mp2_pci_remove(void *privdata)
193234 struct amd_mp2_dev * mp2 = privdata ;
194235 amd_sfh_hid_client_deinit (privdata );
195236 mp2 -> mp2_ops -> stop_all (mp2 );
237+ pci_intx (mp2 -> pdev , false);
238+ amd_sfh_clear_intr (mp2 );
196239}
197240
198241static const struct amd_mp2_ops amd_sfh_ops_v2 = {
199242 .start = amd_start_sensor_v2 ,
200243 .stop = amd_stop_sensor_v2 ,
201244 .stop_all = amd_stop_all_sensor_v2 ,
202245 .response = amd_sfh_wait_response_v2 ,
246+ .clear_intr = amd_sfh_clear_intr_v2 ,
247+ .init_intr = amd_sfh_irq_init_v2 ,
203248};
204249
205250static const struct amd_mp2_ops amd_sfh_ops = {
@@ -225,6 +270,14 @@ static void mp2_select_ops(struct amd_mp2_dev *privdata)
225270 }
226271}
227272
273+ static int amd_sfh_irq_init (struct amd_mp2_dev * privdata )
274+ {
275+ if (privdata -> mp2_ops -> init_intr )
276+ return privdata -> mp2_ops -> init_intr (privdata );
277+
278+ return 0 ;
279+ }
280+
228281static int amd_mp2_pci_probe (struct pci_dev * pdev , const struct pci_device_id * id )
229282{
230283 struct amd_mp2_dev * privdata ;
@@ -261,9 +314,20 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
261314
262315 mp2_select_ops (privdata );
263316
317+ rc = amd_sfh_irq_init (privdata );
318+ if (rc ) {
319+ dev_err (& pdev -> dev , "amd_sfh_irq_init failed\n" );
320+ return rc ;
321+ }
322+
264323 rc = amd_sfh_hid_client_init (privdata );
265- if (rc )
324+ if (rc ) {
325+ amd_sfh_clear_intr (privdata );
326+ dev_err (& pdev -> dev , "amd_sfh_hid_client_init failed\n" );
266327 return rc ;
328+ }
329+
330+ amd_sfh_clear_intr (privdata );
267331
268332 return devm_add_action_or_reset (& pdev -> dev , amd_mp2_pci_remove , privdata );
269333}
@@ -290,6 +354,9 @@ static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
290354 }
291355 }
292356
357+ schedule_delayed_work (& cl_data -> work_buffer , msecs_to_jiffies (AMD_SFH_IDLE_LOOP ));
358+ amd_sfh_clear_intr (mp2 );
359+
293360 return 0 ;
294361}
295362
@@ -312,6 +379,9 @@ static int __maybe_unused amd_mp2_pci_suspend(struct device *dev)
312379 }
313380 }
314381
382+ cancel_delayed_work_sync (& cl_data -> work_buffer );
383+ amd_sfh_clear_intr (mp2 );
384+
315385 return 0 ;
316386}
317387
0 commit comments