@@ -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_NONE ;
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,7 +202,7 @@ 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 );
@@ -244,6 +275,45 @@ static struct thermal_zone_params tzone_params = {
244
275
.no_hwmon = true,
245
276
};
246
277
278
+ static bool msi_irq ;
279
+
280
+ static int proc_thermal_setup_msi (struct pci_dev * pdev , struct proc_thermal_pci * pci_info )
281
+ {
282
+ int ret , i , irq ;
283
+
284
+ ret = pci_alloc_irq_vectors (pdev , 1 , MSI_THERMAL_MAX , PCI_IRQ_MSI | PCI_IRQ_MSIX );
285
+ if (ret < 0 ) {
286
+ dev_err (& pdev -> dev , "Failed to allocate vectors!\n" );
287
+ return ret ;
288
+ }
289
+
290
+ dev_info (& pdev -> dev , "msi enabled:%d msix enabled:%d\n" , pdev -> msi_enabled ,
291
+ pdev -> msix_enabled );
292
+
293
+ for (i = 0 ; i < MSI_THERMAL_MAX ; i ++ ) {
294
+ irq = pci_irq_vector (pdev , i );
295
+
296
+ ret = devm_request_threaded_irq (& pdev -> dev , irq , proc_thermal_irq_handler ,
297
+ proc_thermal_irq_thread_handler ,
298
+ 0 , KBUILD_MODNAME , pci_info );
299
+ if (ret ) {
300
+ dev_err (& pdev -> dev , "Request IRQ %d failed\n" , irq );
301
+ goto err_free_msi_vectors ;
302
+ }
303
+
304
+ proc_thermal_msi_map [i ] = irq ;
305
+ }
306
+
307
+ msi_irq = true;
308
+
309
+ return 0 ;
310
+
311
+ err_free_msi_vectors :
312
+ pci_free_irq_vectors (pdev );
313
+
314
+ return ret ;
315
+ }
316
+
247
317
static int proc_thermal_pci_probe (struct pci_dev * pdev , const struct pci_device_id * id )
248
318
{
249
319
struct proc_thermal_device * proc_priv ;
@@ -253,7 +323,6 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
253
323
.flags = THERMAL_TRIP_FLAG_RW_TEMP ,
254
324
};
255
325
int irq_flag = 0 , irq , ret ;
256
- bool msi_irq = false;
257
326
258
327
proc_priv = devm_kzalloc (& pdev -> dev , sizeof (* proc_priv ), GFP_KERNEL );
259
328
if (!proc_priv )
@@ -299,27 +368,24 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
299
368
goto err_del_legacy ;
300
369
}
301
370
302
- if (use_msi && (pdev -> msi_enabled || pdev -> msix_enabled )) {
303
- /* request and enable interrupt */
304
- ret = pci_alloc_irq_vectors (pdev , 1 , 1 , PCI_IRQ_ALL_TYPES );
305
- if (ret < 0 ) {
306
- dev_err (& pdev -> dev , "Failed to allocate vectors!\n" );
307
- goto err_ret_tzone ;
308
- }
371
+ if (proc_priv -> mmio_feature_mask & PROC_THERMAL_FEATURE_MSI_SUPPORT )
372
+ use_msi = true;
309
373
310
- irq = pci_irq_vector (pdev , 0 );
311
- msi_irq = true;
374
+ if (use_msi ) {
375
+ ret = proc_thermal_setup_msi (pdev , pci_info );
376
+ if (ret )
377
+ goto err_ret_tzone ;
312
378
} else {
313
379
irq_flag = IRQF_SHARED ;
314
380
irq = pdev -> irq ;
315
- }
316
381
317
- ret = devm_request_threaded_irq (& pdev -> dev , irq ,
318
- proc_thermal_irq_handler , proc_thermal_irq_thread_handler ,
319
- irq_flag , KBUILD_MODNAME , pci_info );
320
- if (ret ) {
321
- dev_err (& pdev -> dev , "Request IRQ %d failed\n" , pdev -> irq );
322
- goto err_free_vectors ;
382
+ ret = devm_request_threaded_irq (& pdev -> dev , irq , proc_thermal_irq_handler ,
383
+ proc_thermal_irq_thread_handler , irq_flag ,
384
+ KBUILD_MODNAME , pci_info );
385
+ if (ret ) {
386
+ dev_err (& pdev -> dev , "Request IRQ %d failed\n" , pdev -> irq );
387
+ goto err_ret_tzone ;
388
+ }
323
389
}
324
390
325
391
ret = thermal_zone_device_enable (pci_info -> tzone );
@@ -405,8 +471,8 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
405
471
static const struct pci_device_id proc_thermal_pci_ids [] = {
406
472
{ PCI_DEVICE_DATA (INTEL , ADL_THERMAL , PROC_THERMAL_FEATURE_RAPL |
407
473
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ ) },
408
- { PCI_DEVICE_DATA (INTEL , LNLM_THERMAL , PROC_THERMAL_FEATURE_RAPL |
409
- PROC_THERMAL_FEATURE_DLVR ) },
474
+ { PCI_DEVICE_DATA (INTEL , LNLM_THERMAL , PROC_THERMAL_FEATURE_MSI_SUPPORT |
475
+ PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR ) },
410
476
{ PCI_DEVICE_DATA (INTEL , MTLP_THERMAL , PROC_THERMAL_FEATURE_RAPL |
411
477
PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
412
478
PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR ) },
0 commit comments