Commit 281cfec5 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'thermal-intel'

Merge updates of Intel thermal drivers for 6.11-rc1:

 - Switch Intel thermal drivers to new Intel CPU model defines (Tony
   Luck).

 - Clean up the int3400 and int3403 drivers (Erick Archer and David Alan
   Gilbert).

 - Improve intel_pch_thermal kernel log messages printed during suspend
   to idle (Zhang Rui).

 - Make the intel_tcc_cooling driver use a model-specific bitmask for
   TCC offset (Ricardo Neri).

 - Add DLVR and MSI interrupt support for the Lunar Lake platform to the
   int340x thermal driver (Srinivas Pandruvada).

 - Enable workload type hints (WLT) support and power floor interrupt
   support for the Lunar Lake platform in int340x ((Srinivas Pandruvada).

 - Make the HFI thermal driver use package scope for HFI instances as
   per the Intel SDM (Zhang Rui).

* thermal-intel:
  thermal: intel: hfi: Give HFI instances package scope
  thermal: intel: int340x: Enable WLT and power floor support for Lunar Lake
  thermal: intel: int340x: Support MSI interrupt for Lunar Lake
  thermal: intel: int340x: Remove unnecessary calls to free irq
  thermal: intel: int340x: Add DLVR support for Lunar Lake
  thermal: intel: int340x: Capability to map user space to firmware values
  thermal: intel: int340x: Cleanup of DLVR sysfs on driver remove
  thermal: intel: intel_tcc_cooling: Use a model-specific bitmask for TCC offset
  thermal: intel: intel_tcc: Add model checks for temperature registers
  thermal: intel: intel_pch: Improve cooling log
  thermal: int3403: remove unused struct 'int3403_performance_state'
  thermal: int3400: Use sizeof(*pointer) instead of sizeof(type)
  thermal: intel: intel_soc_dts_thermal: Switch to new Intel CPU model defines
  thermal: intel: intel_tcc_cooling: Switch to new Intel CPU model defines
parents ab33da3a b7553676
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -571,7 +571,7 @@ static int int3400_thermal_probe(struct platform_device *pdev)
	if (!adev)
		return -ENODEV;

	priv = kzalloc(sizeof(struct int3400_thermal_priv), GFP_KERNEL);
	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

+0 −11
Original line number Diff line number Diff line
@@ -25,17 +25,6 @@ struct int3403_sensor {
	struct int34x_thermal_zone *int340x_zone;
};

struct int3403_performance_state {
	u64 performance;
	u64 power;
	u64 latency;
	u64 linear;
	u64 control;
	u64 raw_performace;
	char *raw_unit;
	int reserved;
};

struct int3403_cdev {
	struct thermal_cooling_device *cdev;
	unsigned long max_state;
+2 −1
Original line number Diff line number Diff line
@@ -440,7 +440,8 @@ void proc_thermal_mmio_remove(struct pci_dev *pdev, struct proc_thermal_device *
		proc_thermal_rapl_remove();

	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR ||
	    proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS)
	    proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS ||
	    proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DLVR)
		proc_thermal_rfim_remove(pdev);

	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_POWER_FLOOR)
+1 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ struct rapl_mmio_regs {
#define PROC_THERMAL_FEATURE_DLVR	0x10
#define PROC_THERMAL_FEATURE_WT_HINT	0x20
#define PROC_THERMAL_FEATURE_POWER_FLOOR	0x40
#define PROC_THERMAL_FEATURE_MSI_SUPPORT	0x80

#if IS_ENABLED(CONFIG_PROC_THERMAL_MMIO_RAPL)
int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv);
+90 −25
Original line number Diff line number Diff line
@@ -63,6 +63,18 @@ static struct proc_thermal_mmio_info proc_thermal_mmio_info[] = {
	{ PROC_THERMAL_MMIO_INT_STATUS_1, 0x7200, 8, 0x01 },
};

/* List of supported MSI IDs (sources) */
enum proc_thermal_msi_ids {
	PKG_THERMAL,
	DDR_THERMAL,
	THERM_POWER_FLOOR,
	WORKLOAD_CHANGE,
	MSI_THERMAL_MAX
};

/* Stores IRQ associated with a MSI ID */
static int proc_thermal_msi_map[MSI_THERMAL_MAX];

#define B0D4_THERMAL_NOTIFY_DELAY	1000
static int notify_delay_ms = B0D4_THERMAL_NOTIFY_DELAY;

@@ -146,22 +158,41 @@ static irqreturn_t proc_thermal_irq_thread_handler(int irq, void *devid)
	return IRQ_HANDLED;
}

static int proc_thermal_match_msi_irq(int irq)
{
	int i;

	if (!use_msi)
		goto msi_fail;

	for (i = 0; i < MSI_THERMAL_MAX; i++) {
		if (proc_thermal_msi_map[i] == irq)
			return i;
	}

msi_fail:
	return -EOPNOTSUPP;
}

static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
{
	struct proc_thermal_pci *pci_info = devid;
	struct proc_thermal_device *proc_priv;
	int ret = IRQ_NONE;
	int ret = IRQ_NONE, msi_id;
	u32 status;

	proc_priv = pci_info->proc_priv;

	msi_id = proc_thermal_match_msi_irq(irq);

	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_WT_HINT) {
		if (proc_thermal_check_wt_intr(pci_info->proc_priv))
		if (msi_id == WORKLOAD_CHANGE || proc_thermal_check_wt_intr(pci_info->proc_priv))
			ret = IRQ_WAKE_THREAD;
	}

	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_POWER_FLOOR) {
		if (proc_thermal_check_power_floor_intr(pci_info->proc_priv))
		if (msi_id == THERM_POWER_FLOOR ||
		    proc_thermal_check_power_floor_intr(pci_info->proc_priv))
			ret = IRQ_WAKE_THREAD;
	}

@@ -171,7 +202,7 @@ static irqreturn_t proc_thermal_irq_handler(int irq, void *devid)
	 * interrupt before scheduling work function for thermal threshold.
	 */
	proc_thermal_mmio_read(pci_info, PROC_THERMAL_MMIO_INT_STATUS_0, &status);
	if (status) {
	if (msi_id == PKG_THERMAL || status) {
		/* Disable enable interrupt flag */
		proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);
		pkg_thermal_schedule_work(&pci_info->work);
@@ -245,6 +276,45 @@ static struct thermal_zone_params tzone_params = {
	.no_hwmon = true,
};

static bool msi_irq;

static int proc_thermal_setup_msi(struct pci_dev *pdev, struct proc_thermal_pci *pci_info)
{
	int ret, i, irq;

	ret = pci_alloc_irq_vectors(pdev, 1, MSI_THERMAL_MAX, PCI_IRQ_MSI | PCI_IRQ_MSIX);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to allocate vectors!\n");
		return ret;
	}

	dev_info(&pdev->dev, "msi enabled:%d msix enabled:%d\n", pdev->msi_enabled,
		 pdev->msix_enabled);

	for (i = 0; i < MSI_THERMAL_MAX; i++) {
		irq =  pci_irq_vector(pdev, i);

		ret = devm_request_threaded_irq(&pdev->dev, irq, proc_thermal_irq_handler,
						proc_thermal_irq_thread_handler,
						0, KBUILD_MODNAME, pci_info);
		if (ret) {
			dev_err(&pdev->dev, "Request IRQ %d failed\n", irq);
			goto err_free_msi_vectors;
		}

		proc_thermal_msi_map[i] = irq;
	}

	msi_irq = true;

	return 0;

err_free_msi_vectors:
	pci_free_irq_vectors(pdev);

	return ret;
}

static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct proc_thermal_device *proc_priv;
@@ -254,7 +324,6 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
		.flags = THERMAL_TRIP_FLAG_RW_TEMP,
	};
	int irq_flag = 0, irq, ret;
	bool msi_irq = false;

	proc_priv = devm_kzalloc(&pdev->dev, sizeof(*proc_priv), GFP_KERNEL);
	if (!proc_priv)
@@ -300,27 +369,24 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
		goto err_del_legacy;
	}

	if (use_msi && (pdev->msi_enabled || pdev->msix_enabled)) {
		/* request and enable interrupt */
		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
		if (ret < 0) {
			dev_err(&pdev->dev, "Failed to allocate vectors!\n");
			goto err_ret_tzone;
		}
	if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_MSI_SUPPORT)
		use_msi = true;

		irq =  pci_irq_vector(pdev, 0);
		msi_irq = true;
	if (use_msi) {
		ret = proc_thermal_setup_msi(pdev, pci_info);
		if (ret)
			goto err_ret_tzone;
	} else {
		irq_flag = IRQF_SHARED;
		irq = pdev->irq;
	}

	ret = devm_request_threaded_irq(&pdev->dev, irq,
					proc_thermal_irq_handler, proc_thermal_irq_thread_handler,
					irq_flag, KBUILD_MODNAME, pci_info);
		ret = devm_request_threaded_irq(&pdev->dev, irq, proc_thermal_irq_handler,
						proc_thermal_irq_thread_handler, irq_flag,
						KBUILD_MODNAME, pci_info);
		if (ret) {
			dev_err(&pdev->dev, "Request IRQ %d failed\n", pdev->irq);
		goto err_free_vectors;
			goto err_ret_tzone;
		}
	}

	ret = thermal_zone_device_enable(pci_info->tzone);
@@ -353,9 +419,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev)
	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_THRES_0, 0);
	proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_0, 0);

	devm_free_irq(&pdev->dev, pdev->irq, pci_info);
	pci_free_irq_vectors(pdev);

	thermal_zone_device_unregister(pci_info->tzone);
	proc_thermal_mmio_remove(pdev, pci_info->proc_priv);
	if (!pci_info->no_legacy)
@@ -409,7 +472,9 @@ static SIMPLE_DEV_PM_OPS(proc_thermal_pci_pm, proc_thermal_pci_suspend,
static const struct pci_device_id proc_thermal_pci_ids[] = {
	{ PCI_DEVICE_DATA(INTEL, ADL_THERMAL, PROC_THERMAL_FEATURE_RAPL |
	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_WT_REQ) },
	{ PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_RAPL) },
	{ PCI_DEVICE_DATA(INTEL, LNLM_THERMAL, PROC_THERMAL_FEATURE_MSI_SUPPORT |
	  PROC_THERMAL_FEATURE_RAPL | PROC_THERMAL_FEATURE_DLVR |
	  PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) },
	{ PCI_DEVICE_DATA(INTEL, MTLP_THERMAL, PROC_THERMAL_FEATURE_RAPL |
	  PROC_THERMAL_FEATURE_FIVR | PROC_THERMAL_FEATURE_DVFS | PROC_THERMAL_FEATURE_DLVR |
	  PROC_THERMAL_FEATURE_WT_HINT | PROC_THERMAL_FEATURE_POWER_FLOOR) },
Loading