linux/drivers/thermal/intel/therm_throt.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Thermal throttle event support code (such as syslog messaging and rate
 * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c).
 *
 * This allows consistent reporting of CPU thermal throttle events.
 *
 * Maintains a counter in /sys that keeps track of the number of thermal
 * events, such that the user knows how bad the thermal problem might be
 * (since the logging to syslog is rate limited).
 *
 * Author: Dmitriy Zavin ([email protected])
 *
 * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c.
 *          Inspired by Ross Biro's and Al Borchers' counter code.
 */
#include <linux/interrupt.h>
#include <linux/notifier.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/percpu.h>
#include <linux/export.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/cpu.h>

#include <asm/processor.h>
#include <asm/thermal.h>
#include <asm/traps.h>
#include <asm/apic.h>
#include <asm/irq.h>
#include <asm/msr.h>

#include "intel_hfi.h"
#include "thermal_interrupt.h"

/* How long to wait between reporting thermal events */
#define CHECK_INTERVAL

#define THERMAL_THROTTLING_EVENT
#define POWER_LIMIT_EVENT

/**
 * struct _thermal_state - Represent the current thermal event state
 * @next_check:			Stores the next timestamp, when it is allowed
 *				to log the next warning message.
 * @last_interrupt_time:	Stores the timestamp for the last threshold
 *				high event.
 * @therm_work:			Delayed workqueue structure
 * @count:			Stores the current running count for thermal
 *				or power threshold interrupts.
 * @last_count:			Stores the previous running count for thermal
 *				or power threshold interrupts.
 * @max_time_ms:		This shows the maximum amount of time CPU was
 *				in throttled state for a single thermal
 *				threshold high to low state.
 * @total_time_ms:		This is a cumulative time during which CPU was
 *				in the throttled state.
 * @rate_control_active:	Set when a throttling message is logged.
 *				This is used for the purpose of rate-control.
 * @new_event:			Stores the last high/low status of the
 *				THERM_STATUS_PROCHOT or
 *				THERM_STATUS_POWER_LIMIT.
 * @level:			Stores whether this _thermal_state instance is
 *				for a CORE level or for PACKAGE level.
 * @sample_index:		Index for storing the next sample in the buffer
 *				temp_samples[].
 * @sample_count:		Total number of samples collected in the buffer
 *				temp_samples[].
 * @average:			The last moving average of temperature samples
 * @baseline_temp:		Temperature at which thermal threshold high
 *				interrupt was generated.
 * @temp_samples:		Storage for temperature samples to calculate
 *				moving average.
 *
 * This structure is used to represent data related to thermal state for a CPU.
 * There is a separate storage for core and package level for each CPU.
 */
struct _thermal_state {};

struct thermal_state {};

/* Callback to handle core threshold interrupts */
int (*platform_thermal_notify)(__u64 msr_val);
EXPORT_SYMBOL();

/* Callback to handle core package threshold_interrupts */
int (*platform_thermal_package_notify)(__u64 msr_val);
EXPORT_SYMBOL_GPL();

/* Callback support of rate control, return true, if
 * callback has rate control */
bool (*platform_thermal_package_rate_control)(void);
EXPORT_SYMBOL_GPL();


static DEFINE_PER_CPU(struct thermal_state, thermal_state);

static atomic_t therm_throt_en	=;

static u32 lvtthmr_init __read_mostly;

#ifdef CONFIG_SYSFS
#define define_therm_throt_device_one_ro(_name)				\

#define define_therm_throt_device_show_func(event, name)

define_therm_throt_device_show_func(core_throttle, count);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(core_power_limit, count);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(package_throttle, count);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(package_power_limit, count);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(core_throttle, max_time_ms);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(package_throttle, max_time_ms);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(core_throttle, total_time_ms);
define_therm_throt_device_one_ro();

define_therm_throt_device_show_func(package_throttle, total_time_ms);
define_therm_throt_device_one_ro();

static struct attribute *thermal_throttle_attrs[] =;

static const struct attribute_group thermal_attr_group =;
#endif /* CONFIG_SYSFS */

#define THERM_THROT_POLL_INTERVAL
#define THERM_STATUS_PROCHOT_LOG

static u64 therm_intr_core_clear_mask;
static u64 therm_intr_pkg_clear_mask;

static void thermal_intr_init_core_clear_mask(void)
{}

static void thermal_intr_init_pkg_clear_mask(void)
{}

/*
 * Clear the bits in package thermal status register for bit = 1
 * in bitmask
 */
void thermal_clear_package_intr_status(int level, u64 bit_mask)
{}
EXPORT_SYMBOL_GPL();

static void get_therm_status(int level, bool *proc_hot, u8 *temp)
{}

static void __maybe_unused throttle_active_work(struct work_struct *work)
{}

/***
 * therm_throt_process - Process thermal throttling event from interrupt
 * @curr: Whether the condition is current or not (boolean), since the
 *        thermal interrupt normally gets called both when the thermal
 *        event begins and once the event has ended.
 *
 * This function is called by the thermal interrupt after the
 * IRQ has been acknowledged.
 *
 * It will take care of rate limiting and printing messages to the syslog.
 */
static void therm_throt_process(bool new_event, int event, int level)
{}

static int thresh_event_valid(int level, int event)
{}

static bool int_pln_enable;
static int __init int_pln_enable_setup(char *s)
{}
__setup();

#ifdef CONFIG_SYSFS
/* Add/Remove thermal_throttle interface for CPU device: */
static int thermal_throttle_add_dev(struct device *dev, unsigned int cpu)
{}

static void thermal_throttle_remove_dev(struct device *dev)
{}

/* Get notified when a cpu comes on/off. Be hotplug friendly. */
static int thermal_throttle_online(unsigned int cpu)
{}

static int thermal_throttle_offline(unsigned int cpu)
{}

static __init int thermal_throttle_init_device(void)
{}
device_initcall(thermal_throttle_init_device);

#endif /* CONFIG_SYSFS */

static void notify_package_thresholds(__u64 msr_val)
{}

static void notify_thresholds(__u64 msr_val)
{}

void __weak notify_hwp_interrupt(void)
{}

/* Thermal transition interrupt handler */
void intel_thermal_interrupt(void)
{}

/* Thermal monitoring depends on APIC, ACPI and clock modulation */
static int intel_thermal_supported(struct cpuinfo_x86 *c)
{}

bool x86_thermal_enabled(void)
{}

void __init therm_lvt_init(void)
{}

void intel_init_thermal(struct cpuinfo_x86 *c)
{}