@@ -63,6 +63,18 @@ static struct proc_thermal_mmio_info proc_thermal_mmio_info[] = {
63
63
{ PROC_THERMAL_MMIO_INT_STATUS_1 , 0x7200 , 8 , 0x01 },
64
64
};
65
65
66
+ /* List of supported MSI IDs (sources) */
67
+ enum proc_thermal_msi_ids {
68
+ PKG_THERMAL ,
69
+ DDR_THERMAL ,
70
+ THERM_POWER_FLOOR ,
71
+ WORKLOAD_CHANGE ,
72
+ MSI_THERMAL_MAX
73
+ };
74
+
75
+ /* Stores IRQ associated with a MSI ID */
76
+ static int proc_thermal_msi_map [MSI_THERMAL_MAX ];
77
+
66
78
#define B0D4_THERMAL_NOTIFY_DELAY 1000
67
79
static int notify_delay_ms = B0D4_THERMAL_NOTIFY_DELAY ;
68
80
@@ -146,22 +158,41 @@ static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid)
146
158
return IRQ_HANDLED ;
147
159
}
148
160
161
+ static int proc_thermal_match_msi_irq (int irq )
162
+ {
163
+ int i ;
164
+
165
+ if (!use_msi )
166
+ goto msi_fail ;
167
+
168
+ for (i = 0 ; i < MSI_THERMAL_MAX ; i ++ ) {
169
+ if (proc_thermal_msi_map [i ] == irq )
170
+ return i ;
171
+ }
172
+
173
+ msi_fail :
174
+ return - EOPNOTSUPP ;
175
+ }
176
+
149
177
static irqreturn_t proc_thermal_irq_handler (int irq , void * devid )
150
178
{
151
179
struct proc_thermal_pci * pci_info = devid ;
152
180
struct proc_thermal_device * proc_priv ;
153
- int ret = IRQ_HANDLED ;
181
+ int ret = IRQ_NONE , msi_id ;
154
182
u32 status ;
155
183
156
184
proc_priv = pci_info -> proc_priv ;
157
185
186
+ msi_id = proc_thermal_match_msi_irq (irq );
187
+
158
188
if (proc_priv -> mmio_feature_mask & PROC_THERMAL_FEATURE_WT_HINT ) {
159
- if (proc_thermal_check_wt_intr (pci_info -> proc_priv ))
189
+ if (msi_id == WORKLOAD_CHANGE || proc_thermal_check_wt_intr (pci_info -> proc_priv ))
160
190
ret = IRQ_WAKE_THREAD ;
161
191
}
162
192
163
193
if (proc_priv -> mmio_feature_mask & PROC_THERMAL_FEATURE_POWER_FLOOR ) {
164
- if (proc_thermal_check_power_floor_intr (pci_info -> proc_priv ))
194
+ if (msi_id == THERM_POWER_FLOOR ||
195
+ proc_thermal_check_power_floor_intr (pci_info -> proc_priv ))
165
196
ret = IRQ_WAKE_THREAD ;
166
197
}
167
198
@@ -171,10 +202,11 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
171
202
* interrupt before scheduling work function for thermal threshold.
172
203
*/
173
204
proc_thermal_mmio_read (pci_info , PROC_THERMAL_MMIO_INT_STATUS_0 , & status );
174
- if (status ) {
205
+ if (msi_id == PKG_THERMAL || status ) {
175
206
/* Disable enable interrupt flag */
176
207
proc_thermal_mmio_write (pci_info , PROC_THERMAL_MMIO_INT_ENABLE_0 , 0 );
177
208
pkg_thermal_schedule_work (& pci_info -> work );
209
+ ret = IRQ_HANDLED ;
178
210
}
179
211
180
212
pci_write_config_byte (pci_info -> pdev , 0xdc , 0x01 );
@@ -193,7 +225,8 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp)
193
225
return 0 ;
194
226
}
195
227
196
- static int sys_set_trip_temp (struct thermal_zone_device * tzd , int trip , int temp )
228
+ static int sys_set_trip_temp (struct thermal_zone_device * tzd ,
229
+ const struct thermal_trip * trip , int temp )
197
230
{
198
231
struct proc_thermal_pci * pci_info = thermal_zone_device_priv (tzd );
199
232
int tjmax , _temp ;
@@ -243,6 +276,57 @@ static struct thermal_zone_params tzone_params = {
243
276
.no_hwmon = true,
244
277
};
245
278
279
+ static bool msi_irq ;
280
+
281
+ static void proc_thermal_free_msi (struct pci_dev * pdev , struct proc_thermal_pci * pci_info )
282
+ {
283
+ int i ;
284
+
285
+ for (i = 0 ; i < MSI_THERMAL_MAX ; i ++ ) {
286
+ if (proc_thermal_msi_map [i ])
287
+ devm_free_irq (& pdev -> dev , proc_thermal_msi_map [i ], pci_info );
288
+ }
289
+
290
+ pci_free_irq_vectors (pdev );
291
+ }
292
+
293
+ static int proc_thermal_setup_msi (struct pci_dev * pdev , struct proc_thermal_pci * pci_info )
294
+ {
295
+ int ret , i , irq , count ;
296
+
297
+ count = pci_alloc_irq_vectors (pdev , 1 , MSI_THERMAL_MAX , PCI_IRQ_MSI | PCI_IRQ_MSIX );
298
+ if (count < 0 ) {
299
+ dev_err (& pdev -> dev , "Failed to allocate vectors!\n" );
300
+ return count ;
301
+ }
302
+
303
+ dev_info (& pdev -> dev , "msi enabled:%d msix enabled:%d\n" , pdev -> msi_enabled ,
304
+ pdev -> msix_enabled );
305
+
306
+ for (i = 0 ; i < count ; i ++ ) {
307
+ irq = pci_irq_vector (pdev , i );
308
+
309
+ ret = devm_request_threaded_irq (& pdev -> dev , irq , proc_thermal_irq_handler ,
310
+ proc_thermal_irq_thread_handler ,
311
+ 0 , KBUILD_MODNAME , pci_info );
312
+ if (ret ) {
313
+ dev_err (& pdev -> dev , "Request IRQ %d failed\n" , irq );
314
+ goto err_free_msi_vectors ;
315
+ }
316
+
317
+ proc_thermal_msi_map [i ] = irq ;
318
+ }
319
+
320
+ msi_irq = true;
321
+
322
+ return 0 ;
323
+
324
+ err_free_msi_vectors :
325
+ proc_thermal_free_msi (pdev , pci_info );
326
+
327
+ return ret ;
328
+ }
329
+
246
330
static int proc_thermal_pci_probe (struct pci_dev * pdev , const struct pci_device_id * id )
247
331
{
248
332
struct proc_thermal_device * proc_priv ;
@@ -252,7 +336,6 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
252
336
.flags = THERMAL_TRIP_FLAG_RW_TEMP ,
253
337
};
254
338
int irq_flag = 0 , irq , ret ;
255
- bool msi_irq = false;
256
339
257
340
proc_priv = devm_kzalloc (& pdev -> dev , sizeof (* proc_priv ), GFP_KERNEL );
258
341
if (!proc_priv )
@@ -298,27 +381,24 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
298
381
goto err_del_legacy ;
299
382
}
300
383
301
- if (use_msi && (pdev -> msi_enabled || pdev -> msix_enabled )) {
302
- /* request and enable interrupt */
303
- ret = pci_alloc_irq_vectors (pdev , 1 , 1 , PCI_IRQ_ALL_TYPES );
304
- if (ret < 0 ) {
305
- dev_err (& pdev -> dev , "Failed to allocate vectors!\n" );
306
- goto err_ret_tzone ;
307
- }
384
+ if (proc_priv -> mmio_feature_mask & PROC_THERMAL_FEATURE_MSI_SUPPORT )
385
+ use_msi = true;
308
386
309
- irq = pci_irq_vector (pdev , 0 );
310
- msi_irq = true;
387
+ if (use_msi ) {
388
+ ret = proc_thermal_setup_msi (pdev , pci_info );
389
+ if (ret )
390
+ goto err_ret_tzone ;
311
391
} else {
312
392
irq_flag = IRQF_SHARED ;
313
393
irq = pdev -> irq ;
314
- }
315
394
316
- ret = devm_request_threaded_irq (& pdev -> dev , irq ,
317
- proc_thermal_irq_handler , proc_thermal_irq_thread_handler ,
318
- irq_flag , KBUILD_MODNAME , pci_info );
319
- if (ret ) {
320
- dev_err (& pdev -> dev , "Request IRQ %d failed\n" , pdev -> irq );
321
- goto err_free_vectors ;
395
+ ret = devm_request_threaded_irq (& pdev -> dev , irq , proc_thermal_irq_handler ,
396
+ proc_thermal_irq_thread_handler , irq_flag ,
397
+ KBUILD_MODNAME , pci_info );
398
+ if (ret ) {
399
+ dev_err (& pdev -> dev , "Request IRQ %d failed\n" , pdev -> irq );
400
+ goto err_ret_tzone ;
401
+ }
322
402
}
323
403
324
404
ret = thermal_zone_device_enable (pci_info -> tzone );
@@ -329,7 +409,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
329
409
330
410
err_free_vectors :
331
411
if (msi_irq )
332
- pci_free_irq_vectors (pdev );
412
+ proc_thermal_free_msi (pdev , pci_info );
333
413
err_ret_tzone :
334
414
thermal_zone_device_unregister (pci_info -> tzone );
335
415
err_del_legacy :
@@ -351,8 +431,8 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev)
351
431
proc_thermal_mmio_write (pci_info , PROC_THERMAL_MMIO_THRES_0 , 0 );
352
432
proc_thermal_mmio_write (pci_info , PROC_THERMAL_MMIO_INT_ENABLE_0 , 0 );
353
433
354
- devm_free_irq ( & pdev -> dev , pdev -> irq , pci_info );
355
- pci_free_irq_vectors (pdev );
434
+ if ( msi_irq )
435
+ proc_thermal_free_msi (pdev , pci_info );
356
436
357
437
thermal_zone_device_unregister (pci_info -> tzone );
358
438
proc_thermal_mmio_remove (pdev , pci_info -> proc_priv );
@@ -407,7 +487,9 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
407
487
static const struct pci_device_id proc_thermal_pci_ids [] = {
408
488
{ PCI_DEVICE_DATA (INTEL , ADL_THERMAL , PROC_THERMAL_FEATURE_RAPL |
409
489
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ ) },
410
- { PCI_DEVICE_DATA (INTEL , LNLM_THERMAL , PROC_THERMAL_FEATURE_RAPL ) },
490
+ { PCI_DEVICE_DATA (INTEL , LNLM_THERMAL , PROC_THERMAL_FEATURE_MSI_SUPPORT |
491
+ PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR |
492
+ PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR ) },
411
493
{ PCI_DEVICE_DATA (INTEL , MTLP_THERMAL , PROC_THERMAL_FEATURE_RAPL |
412
494
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
413
495
PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR ) },
0 commit comments