Commit d9ef02e5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull thermal control fixes from Rafael Wysocki:
 "These fix a few issues related to the MSI IRQs management in the
  int340x thermal driver, fix a thermal core issue that may lead to
  missing trip point crossing events and update the thermal core
  documentation.

  Specifics:

   - Fix MSI error path cleanup in int340x, allow it to work with a
     subset of thermal MSI IRQs if some of them are not working and make
     it free all MSI IRQs on module exit (Srinivas Pandruvada)

   - Fix a thermal core issue that may lead to missing trip point
     crossing events in some cases when thermal_zone_set_trips() is used
     and update the thermal core documentation (Rafael Wysocki)"

* tag 'thermal-6.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  thermal: core: Update thermal zone registration documentation
  thermal: trip: Avoid skipping trips in thermal_zone_set_trips()
  thermal: intel: int340x: Free MSI IRQ vectors on module exit
  thermal: intel: int340x: Allow limited thermal MSI support
  thermal: intel: int340x: Fix kernel warning during MSI cleanup
parents 041b1061 a0907422
Loading
Loading
Loading
Loading
+30 −35
Original line number Diff line number Diff line
@@ -4,8 +4,6 @@ Generic Thermal Sysfs driver How To

Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com>

Updated: 2 January 2008

Copyright (c)  2008 Intel Corporation


@@ -38,23 +36,23 @@ temperature) and throttle appropriate devices.

    ::

	struct thermal_zone_device
	*thermal_zone_device_register(char *type,
				      int trips, int mask, void *devdata,
				      struct thermal_zone_device_ops *ops,
	struct thermal_zone_device *
	thermal_zone_device_register_with_trips(const char *type,
					const struct thermal_trip *trips,
					int num_trips, void *devdata,
					const struct thermal_zone_device_ops *ops,
					const struct thermal_zone_params *tzp,
				      int passive_delay, int polling_delay))
					unsigned int passive_delay,
					unsigned int polling_delay)

    This interface function adds a new thermal zone device (sensor) to
    This interface function adds a new thermal zone device (sensor) to the
    /sys/class/thermal folder as `thermal_zone[0-*]`. It tries to bind all the
    thermal cooling devices registered at the same time.
    thermal cooling devices registered to it at the same time.

    type:
	the thermal zone type.
    trips:
	the total number of trip points this thermal zone supports.
    mask:
	Bit string: If 'n'th bit is set, then trip point 'n' is writable.
	the table of trip points for this thermal zone.
    devdata:
	device private data
    ops:
@@ -70,29 +68,26 @@ temperature) and throttle appropriate devices.
		set the trip points window. Whenever the current temperature
		is updated, the trip points immediately below and above the
		current temperature are found.
	.get_mode:
		   get the current mode (enabled/disabled) of the thermal zone.

			- "enabled" means the kernel thermal management is
			  enabled.
			- "disabled" will prevent kernel thermal driver action
			  upon trip points so that user applications can take
			  charge of thermal management.
	.set_mode:
		set the mode (enabled/disabled) of the thermal zone.
	.get_trip_type:
		get the type of certain trip point.
	.get_trip_temp:
			get the temperature above which the certain trip point
			will be fired.
	.change_mode:
		change the mode (enabled/disabled) of the thermal zone.
	.set_trip_temp:
		set the temperature of a given trip point.
	.get_crit_temp:
		get the critical temperature for this thermal zone.
	.set_emul_temp:
		set the emulation temperature which helps in debugging
		different threshold temperature points.
	.get_trend:
		get the trend of most recent zone temperature changes.
	.hot:
		hot trip point crossing handler.
	.critical:
		critical trip point crossing handler.
    tzp:
	thermal zone platform parameters.
    passive_delay:
	number of milliseconds to wait between polls when
	performing passive cooling.
	number of milliseconds to wait between polls when performing passive
	cooling.
    polling_delay:
	number of milliseconds to wait between polls when checking
	whether trip points have been crossed (0 for interrupt driven systems).
+22 −7
Original line number Diff line number Diff line
@@ -278,20 +278,32 @@ static struct thermal_zone_params tzone_params = {

static bool msi_irq;

static void proc_thermal_free_msi(struct pci_dev *pdev, struct proc_thermal_pci *pci_info)
{
	int i;

	for (i = 0; i < MSI_THERMAL_MAX; i++) {
		if (proc_thermal_msi_map[i])
			devm_free_irq(&pdev->dev, proc_thermal_msi_map[i], pci_info);
	}

	pci_free_irq_vectors(pdev);
}

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

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

	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++) {
	for (i = 0; i < count; i++) {
		irq =  pci_irq_vector(pdev, i);

		ret = devm_request_threaded_irq(&pdev->dev, irq, proc_thermal_irq_handler,
@@ -310,7 +322,7 @@ static int proc_thermal_setup_msi(struct pci_dev *pdev, struct proc_thermal_pci
	return 0;

err_free_msi_vectors:
	pci_free_irq_vectors(pdev);
	proc_thermal_free_msi(pdev, pci_info);

	return ret;
}
@@ -397,7 +409,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_

err_free_vectors:
	if (msi_irq)
		pci_free_irq_vectors(pdev);
		proc_thermal_free_msi(pdev, pci_info);
err_ret_tzone:
	thermal_zone_device_unregister(pci_info->tzone);
err_del_legacy:
@@ -419,6 +431,9 @@ 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);

	if (msi_irq)
		proc_thermal_free_msi(pdev, pci_info);

	thermal_zone_device_unregister(pci_info->tzone);
	proc_thermal_mmio_remove(pdev, pci_info->proc_priv);
	if (!pci_info->no_legacy)
+2 −2
Original line number Diff line number Diff line
@@ -88,10 +88,10 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
		return;

	for_each_trip_desc(tz, td) {
		if (td->threshold < tz->temperature && td->threshold > low)
		if (td->threshold <= tz->temperature && td->threshold > low)
			low = td->threshold;

		if (td->threshold > tz->temperature && td->threshold < high)
		if (td->threshold >= tz->temperature && td->threshold < high)
			high = td->threshold;
	}