diff --git a/drivers/soc/rockchip/rockchip_system_monitor.c b/drivers/soc/rockchip/rockchip_system_monitor.c index c2dd057a5f3e..4f3f46364355 100644 --- a/drivers/soc/rockchip/rockchip_system_monitor.c +++ b/drivers/soc/rockchip/rockchip_system_monitor.c @@ -71,6 +71,7 @@ struct system_monitor { struct thermal_zone_device *tz; struct delayed_work thermal_work; + int last_temp; int offline_cpus_temp; int temp_hysteresis; unsigned int delay; @@ -91,6 +92,7 @@ static LIST_HEAD(monitor_dev_list); static struct system_monitor *system_monitor; static atomic_t monitor_in_suspend; +static BLOCKING_NOTIFIER_HEAD(system_monitor_notifier_list); static BLOCKING_NOTIFIER_HEAD(system_status_notifier_list); int rockchip_register_system_status_notifier(struct notifier_block *nb) @@ -1448,6 +1450,31 @@ void rockchip_system_monitor_unregister(struct monitor_dev_info *info) } EXPORT_SYMBOL(rockchip_system_monitor_unregister); +int rockchip_system_monitor_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&system_monitor_notifier_list, nb); +} +EXPORT_SYMBOL(rockchip_system_monitor_register_notifier); + +void rockchip_system_monitor_unregister_notifier(struct notifier_block *nb) +{ + blocking_notifier_chain_unregister(&system_monitor_notifier_list, nb); +} +EXPORT_SYMBOL(rockchip_system_monitor_unregister_notifier); + +static int rockchip_system_monitor_temp_notify(int temp) +{ + struct system_monitor_event_data event_data; + int ret; + + event_data.temp = temp; + ret = blocking_notifier_call_chain(&system_monitor_notifier_list, + SYSTEM_MONITOR_CHANGE_TEMP, + (void *)&event_data); + + return notifier_to_errno(ret); +} + static int notify_dummy(struct thermal_zone_device *tz, int trip) { return 0; @@ -1564,7 +1591,6 @@ static void rockchip_system_monitor_thermal_update(void) { int temp, ret; struct monitor_dev_info *info; - static int last_temp = INT_MAX; ret = thermal_zone_get_temp(system_monitor->tz, &temp); if (ret || temp == THERMAL_TEMP_INVALID) @@ -1572,9 +1598,12 @@ static void rockchip_system_monitor_thermal_update(void) dev_dbg(system_monitor->dev, "temperature=%d\n", temp); - if (temp < last_temp && last_temp - temp <= 2000) + if (temp < system_monitor->last_temp && + system_monitor->last_temp - temp <= 2000) goto out; - last_temp = temp; + system_monitor->last_temp = temp; + + rockchip_system_monitor_temp_notify(temp); down_read(&mdev_list_sem); list_for_each_entry(info, &monitor_dev_list, node) @@ -1700,6 +1729,7 @@ static int monitor_pm_notify(struct notifier_block *nb, rockchip_system_monitor_thermal_update(); atomic_set(&monitor_in_suspend, 0); rockchip_system_monitor_set_cpu_uevent_suppress(false); + system_monitor->last_temp = INT_MAX; break; default: break; @@ -1819,6 +1849,7 @@ static int rockchip_system_monitor_probe(struct platform_device *pdev) rockchip_system_monitor_parse_dt(system_monitor); if (system_monitor->tz) { + system_monitor->last_temp = INT_MAX; INIT_DELAYED_WORK(&system_monitor->thermal_work, rockchip_system_monitor_thermal_check); mod_delayed_work(system_freezable_wq, diff --git a/include/soc/rockchip/rockchip_system_monitor.h b/include/soc/rockchip/rockchip_system_monitor.h index a8f500651165..e6698c054c0d 100644 --- a/include/soc/rockchip/rockchip_system_monitor.h +++ b/include/soc/rockchip/rockchip_system_monitor.h @@ -6,11 +6,23 @@ #ifndef __SOC_ROCKCHIP_SYSTEM_MONITOR_H #define __SOC_ROCKCHIP_SYSTEM_MONITOR_H +#include +#include +#include + enum monitor_dev_type { MONITOR_TPYE_CPU = 0, /* CPU */ MONITOR_TPYE_DEV, /* GPU, NPU, DMC, and so on */ }; +enum system_monitor_event_type { + SYSTEM_MONITOR_CHANGE_TEMP = 0, +}; + +struct system_monitor_event_data { + int temp; +}; + struct volt_adjust_table { unsigned int min; /* Minimum frequency in MHz */ unsigned int max; /* Maximum frequency in MHz */ @@ -148,6 +160,8 @@ int rockchip_monitor_dev_low_temp_adjust(struct monitor_dev_info *info, int rockchip_monitor_dev_high_temp_adjust(struct monitor_dev_info *info, bool is_high); int rockchip_monitor_suspend_low_temp_adjust(int cpu); +int rockchip_system_monitor_register_notifier(struct notifier_block *nb); +void rockchip_system_monitor_unregister_notifier(struct notifier_block *nb); #else static inline struct monitor_dev_info * rockchip_system_monitor_register(struct device *dev, @@ -208,6 +222,16 @@ static inline int rockchip_monitor_suspend_low_temp_adjust(int cpu) return 0; }; +static inline int +rockchip_system_monitor_register_notifier(struct notifier_block *nb) +{ + return 0; +}; + +static inline void +rockchip_system_monitor_unregister_notifier(struct notifier_block *nb) +{ +}; #endif /* CONFIG_ROCKCHIP_SYSTEM_MONITOR */ #endif