Commit d9ef02e5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'thermal-6.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

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
......@@ -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).
......
......@@ -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)
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment