@@ -63,6 +63,18 @@ static struct proc_thermal_mmio_info proc_thermal_mmio_info[] = {
6363 { PROC_THERMAL_MMIO_INT_STATUS_1 , 0x7200 , 8 , 0x01 },
6464};
6565
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+
6678#define B0D4_THERMAL_NOTIFY_DELAY 1000
6779static int notify_delay_ms = B0D4_THERMAL_NOTIFY_DELAY ;
6880
@@ -146,22 +158,41 @@ static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid)
146158 return IRQ_HANDLED ;
147159}
148160
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+
149177static irqreturn_t proc_thermal_irq_handler (int irq , void * devid )
150178{
151179 struct proc_thermal_pci * pci_info = devid ;
152180 struct proc_thermal_device * proc_priv ;
153- int ret = IRQ_NONE ;
181+ int ret = IRQ_NONE , msi_id ;
154182 u32 status ;
155183
156184 proc_priv = pci_info -> proc_priv ;
157185
186+ msi_id = proc_thermal_match_msi_irq (irq );
187+
158188 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 ))
160190 ret = IRQ_WAKE_THREAD ;
161191 }
162192
163193 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 ))
165196 ret = IRQ_WAKE_THREAD ;
166197 }
167198
@@ -171,7 +202,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
171202 * interrupt before scheduling work function for thermal threshold.
172203 */
173204 proc_thermal_mmio_read (pci_info , PROC_THERMAL_MMIO_INT_STATUS_0 , & status );
174- if (status ) {
205+ if (msi_id == PKG_THERMAL || status ) {
175206 /* Disable enable interrupt flag */
176207 proc_thermal_mmio_write (pci_info , PROC_THERMAL_MMIO_INT_ENABLE_0 , 0 );
177208 pkg_thermal_schedule_work (& pci_info -> work );
@@ -244,6 +275,45 @@ static struct thermal_zone_params tzone_params = {
244275 .no_hwmon = true,
245276};
246277
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+
247317static int proc_thermal_pci_probe (struct pci_dev * pdev , const struct pci_device_id * id )
248318{
249319 struct proc_thermal_device * proc_priv ;
@@ -253,7 +323,6 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
253323 .flags = THERMAL_TRIP_FLAG_RW_TEMP ,
254324 };
255325 int irq_flag = 0 , irq , ret ;
256- bool msi_irq = false;
257326
258327 proc_priv = devm_kzalloc (& pdev -> dev , sizeof (* proc_priv ), GFP_KERNEL );
259328 if (!proc_priv )
@@ -299,27 +368,24 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
299368 goto err_del_legacy ;
300369 }
301370
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;
309373
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 ;
312378 } else {
313379 irq_flag = IRQF_SHARED ;
314380 irq = pdev -> irq ;
315- }
316381
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+ }
323389 }
324390
325391 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,
405471static const struct pci_device_id proc_thermal_pci_ids [] = {
406472 { PCI_DEVICE_DATA (INTEL , ADL_THERMAL , PROC_THERMAL_FEATURE_RAPL |
407473 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 ) },
410476 { PCI_DEVICE_DATA (INTEL , MTLP_THERMAL , PROC_THERMAL_FEATURE_RAPL |
411477 PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
412478 PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR ) },
0 commit comments