#include <linux/thermal.h>
#include <linux/reboot.h>
#include <linux/string.h>
+#include <linux/workqueue.h>
#include <linux/of.h>
#include <net/netlink.h>
#include <net/genetlink.h>
static atomic_t in_suspend;
static bool power_off_triggered;
+static struct workqueue_struct *thermal_wq;
+
#ifdef CONFIG_SCHED_HMP
-#define BOUNDED_CPU 1
static void start_poll_queue(struct thermal_zone_device *tz, int delay)
{
- mod_delayed_work_on(tz->poll_queue_cpu, system_freezable_wq, &tz->poll_queue,
+ mod_delayed_work(thermal_wq, &tz->poll_queue,
msecs_to_jiffies(delay));
}
#endif
tz->trips = trips;
tz->passive_delay = passive_delay;
tz->polling_delay = polling_delay;
-#ifdef CONFIG_SCHED_HMP
- tz->poll_queue_cpu = BOUNDED_CPU;
-#endif
/* sys I/F */
/* Add nodes that are always present via .groups */
static inline void genetlink_exit(void) {}
#endif /* !CONFIG_NET */
-#ifdef CONFIG_SCHED_HMP
-static int thermal_cpu_callback(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
-{
- unsigned long cpu = (unsigned long)hcpu;
- struct thermal_zone_device *pos;
-
- switch (action) {
- case CPU_ONLINE:
- if (cpu == BOUNDED_CPU) {
- list_for_each_entry(pos, &thermal_tz_list, node) {
- pos->poll_queue_cpu = BOUNDED_CPU;
- if (pos->polling_delay) {
- start_poll_queue(pos, pos->polling_delay);
- }
- }
- }
- break;
- case CPU_DOWN_PREPARE:
- list_for_each_entry(pos, &thermal_tz_list, node) {
- if (pos->poll_queue_cpu == cpu) {
- pos->poll_queue_cpu = 0;
- if (pos->polling_delay)
- start_poll_queue(pos, pos->polling_delay);
- }
- }
- break;
- }
- return NOTIFY_OK;
-}
-
-static struct notifier_block thermal_cpu_notifier =
-{
- .notifier_call = thermal_cpu_callback,
-};
-#endif
-
static int thermal_pm_notify(struct notifier_block *nb,
unsigned long mode, void *_unused)
{
static int __init thermal_init(void)
{
int result;
+ struct workqueue_attrs attr;
+
+ attr.nice = 0;
+ attr.no_numa = true;
+ cpumask_copy(attr.cpumask, &hmp_slow_cpu_mask);
+
+ thermal_wq = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND |\
+ WQ_MEM_RECLAIM | WQ_FREEZABLE,
+ 0, "thermal_check");
+ apply_workqueue_attrs(thermal_wq, &attr);
mutex_init(&poweroff_lock);
+
result = thermal_register_governors();
if (result)
goto error;
if (result)
goto exit_netlink;
-#ifdef CONFIG_SCHED_HMP
- register_hotcpu_notifier(&thermal_cpu_notifier);
-#endif
result = register_pm_notifier(&thermal_pm_nb);
if (result)
pr_warn("Thermal: Can not register suspend notifier, return %d\n",
static void __exit thermal_exit(void)
{
unregister_pm_notifier(&thermal_pm_nb);
-#ifdef CONFIG_SCHED_HMP
- unregister_hotcpu_notifier(&thermal_cpu_notifier);
-#endif
of_thermal_destroy_zones();
genetlink_exit();
class_unregister(&thermal_class);