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 ...@@ -4,8 +4,6 @@ Generic Thermal Sysfs driver How To
Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com> Written by Sujith Thomas <sujith.thomas@intel.com>, Zhang Rui <rui.zhang@intel.com>
Updated: 2 January 2008
Copyright (c) 2008 Intel Corporation Copyright (c) 2008 Intel Corporation
...@@ -38,23 +36,23 @@ temperature) and throttle appropriate devices. ...@@ -38,23 +36,23 @@ temperature) and throttle appropriate devices.
:: ::
struct thermal_zone_device struct thermal_zone_device *
*thermal_zone_device_register(char *type, thermal_zone_device_register_with_trips(const char *type,
int trips, int mask, void *devdata, const struct thermal_trip *trips,
struct thermal_zone_device_ops *ops, int num_trips, void *devdata,
const struct thermal_zone_params *tzp, const struct thermal_zone_device_ops *ops,
int passive_delay, int polling_delay)) const struct thermal_zone_params *tzp,
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 /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: type:
the thermal zone type. the thermal zone type.
trips: trips:
the total number of trip points this thermal zone supports. the table of trip points for this thermal zone.
mask:
Bit string: If 'n'th bit is set, then trip point 'n' is writable.
devdata: devdata:
device private data device private data
ops: ops:
...@@ -67,32 +65,29 @@ temperature) and throttle appropriate devices. ...@@ -67,32 +65,29 @@ temperature) and throttle appropriate devices.
.get_temp: .get_temp:
get the current temperature of the thermal zone. get the current temperature of the thermal zone.
.set_trips: .set_trips:
set the trip points window. Whenever the current temperature set the trip points window. Whenever the current temperature
is updated, the trip points immediately below and above the is updated, the trip points immediately below and above the
current temperature are found. current temperature are found.
.get_mode: .change_mode:
get the current mode (enabled/disabled) of the thermal zone. change the mode (enabled/disabled) of the thermal zone.
.set_trip_temp:
- "enabled" means the kernel thermal management is set the temperature of a given trip point.
enabled. .get_crit_temp:
- "disabled" will prevent kernel thermal driver action get the critical temperature for this thermal zone.
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.
.set_emul_temp: .set_emul_temp:
set the emulation temperature which helps in debugging set the emulation temperature which helps in debugging
different threshold temperature points. 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: tzp:
thermal zone platform parameters. thermal zone platform parameters.
passive_delay: passive_delay:
number of milliseconds to wait between polls when number of milliseconds to wait between polls when performing passive
performing passive cooling. cooling.
polling_delay: polling_delay:
number of milliseconds to wait between polls when checking number of milliseconds to wait between polls when checking
whether trip points have been crossed (0 for interrupt driven systems). whether trip points have been crossed (0 for interrupt driven systems).
......
...@@ -278,20 +278,32 @@ static struct thermal_zone_params tzone_params = { ...@@ -278,20 +278,32 @@ static struct thermal_zone_params tzone_params = {
static bool msi_irq; 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) 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); count = pci_alloc_irq_vectors(pdev, 1, MSI_THERMAL_MAX, PCI_IRQ_MSI | PCI_IRQ_MSIX);
if (ret < 0) { if (count < 0) {
dev_err(&pdev->dev, "Failed to allocate vectors!\n"); 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, dev_info(&pdev->dev, "msi enabled:%d msix enabled:%d\n", pdev->msi_enabled,
pdev->msix_enabled); pdev->msix_enabled);
for (i = 0; i < MSI_THERMAL_MAX; i++) { for (i = 0; i < count; i++) {
irq = pci_irq_vector(pdev, i); irq = pci_irq_vector(pdev, i);
ret = devm_request_threaded_irq(&pdev->dev, irq, proc_thermal_irq_handler, 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 ...@@ -310,7 +322,7 @@ static int proc_thermal_setup_msi(struct pci_dev *pdev, struct proc_thermal_pci
return 0; return 0;
err_free_msi_vectors: err_free_msi_vectors:
pci_free_irq_vectors(pdev); proc_thermal_free_msi(pdev, pci_info);
return ret; return ret;
} }
...@@ -397,7 +409,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -397,7 +409,7 @@ static int proc_thermal_pci_probe(struct pci_dev *pdev, const struct pci_device_
err_free_vectors: err_free_vectors:
if (msi_irq) if (msi_irq)
pci_free_irq_vectors(pdev); proc_thermal_free_msi(pdev, pci_info);
err_ret_tzone: err_ret_tzone:
thermal_zone_device_unregister(pci_info->tzone); thermal_zone_device_unregister(pci_info->tzone);
err_del_legacy: err_del_legacy:
...@@ -419,6 +431,9 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev) ...@@ -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_THRES_0, 0);
proc_thermal_mmio_write(pci_info, PROC_THERMAL_MMIO_INT_ENABLE_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); thermal_zone_device_unregister(pci_info->tzone);
proc_thermal_mmio_remove(pdev, pci_info->proc_priv); proc_thermal_mmio_remove(pdev, pci_info->proc_priv);
if (!pci_info->no_legacy) if (!pci_info->no_legacy)
......
...@@ -88,10 +88,10 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz) ...@@ -88,10 +88,10 @@ void thermal_zone_set_trips(struct thermal_zone_device *tz)
return; return;
for_each_trip_desc(tz, td) { 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; low = td->threshold;
if (td->threshold > tz->temperature && td->threshold < high) if (td->threshold >= tz->temperature && td->threshold < high)
high = td->threshold; 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