Skip to content

Commit 7a9a8c5

Browse files
spandruvadarafaeljw
authored andcommitted
thermal: intel: int340x: Support MSI interrupt for Lunar Lake
The legacy PCI interrupt is no longer supported for processor thermal device on Lunar Lake. The support is via MSI. Add feature PROC_THERMAL_FEATURE_MSI_SUPPORT to support MSI feature per generation. Define this feature for Lunar Lake processors. There are 4 MSI sources: 0 - Package thermal 1 - DDR Thermal 2 - Power floor interrupt 3 - Workload type hint On interrupt, check the source and call the corresponding handler. Here don't need to call proc_thermal_check_wt_intr() and proc_thermal_check_power_floor_intr() to check if the interrupt is for those sources as there is a dedicated MSI interrupt. Signed-off-by: Srinivas Pandruvada <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent a264cee commit 7a9a8c5

File tree

2 files changed

+90
-23
lines changed

2 files changed

+90
-23
lines changed

drivers/thermal/intel/int340x_thermal/processor_thermal_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct rapl_mmio_regs {
6565
#define PROC_THERMAL_FEATURE_DLVR 0x10
6666
#define PROC_THERMAL_FEATURE_WT_HINT 0x20
6767
#define PROC_THERMAL_FEATURE_POWER_FLOOR 0x40
68+
#define PROC_THERMAL_FEATURE_MSI_SUPPORT 0x80
6869

6970
#if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
7071
int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);

drivers/thermal/intel/int340x_thermal/processor_thermal_device_pci.c

Lines changed: 89 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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
6779
static 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+
149177
static 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+
247317
static 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,
405471
static 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

Comments
 (0)