struct thermal_zone_device *tz;
bool single_cooling_dev;
struct list_head node;
+ struct list_head cooling_list;
};
struct _cooling_dev {
unsigned long int cpus[0];
};
+struct _cooling_instance {
+ struct list_head node;
+ struct _cooling_dev *cooling;
+};
+
static LIST_HEAD(tz_list);
static LIST_HEAD(cdev_list);
static DEFINE_MUTEX(tz_list_lock);
kfree(cooling);
}
+/* called with 'cdev_list_lock' taken */
+static struct _cooling_dev
+*find_registered_cooling_dev(struct thermal_cooling_device *cdev)
+{
+ struct _cooling_dev *cooling;
+
+ list_for_each_entry(cooling, &cdev_list, node)
+ if (cdev == cooling->cdev)
+ return cooling;
+
+ return NULL;
+}
+
+static bool cdev_in_instance_list(struct _thermal_zone *zone,
+ struct thermal_cooling_device *cdev)
+{
+ struct _cooling_instance *inst;
+
+ list_for_each_entry(inst, &zone->cooling_list, node)
+ if (cdev == inst->cooling->cdev)
+ return true;
+
+ return false;
+}
+
static int sched_power_gov_bind(struct thermal_zone_device *tz)
{
struct thermal_instance *inst;
struct _thermal_zone *zone;
struct _cooling_dev *cooling, *prev_cooling;
+ struct _cooling_instance *_inst, *tmp;
struct thermal_cooling_device *cdev;
int i = 0;
int cpu;
if (!zone)
return -ENOMEM;
+ INIT_LIST_HEAD(&zone->cooling_list);
+
mutex_lock(&cdev_list_lock);
list_for_each_entry(inst, &tz->thermal_instances, tz_node) {
cdev = inst->cdev;
+
+ if (cdev_in_instance_list(zone, cdev))
+ continue;
+
+ cooling = find_registered_cooling_dev(cdev);
+ if (cooling)
+ goto handle_cooling_instance;
+
if (is_cpufreq_cooling(cdev))
cpus_size = cpumask_size();
else
}
}
list_add(&cooling->node, &cdev_list);
-
- pr_info("registred new cooling device for CPUs\n");
+ pr_info("created new CPU cooling device\n");
prev_cooling = cooling;
i++;
+
+handle_cooling_instance:
+ _inst = kmalloc(sizeof(*_inst), GFP_KERNEL);
+ if (!_inst)
+ goto cleanup;
+
+ _inst->cooling = cooling;
+ list_add(&_inst->node, &zone->cooling_list);
+
+ pr_info("pinned cooling device into zone\n");
}
mutex_unlock(&cdev_list_lock);
prev_cooling = cooling;
}
mutex_unlock(&cdev_list_lock);
+
+ list_for_each_entry_safe(_inst, tmp, &zone->cooling_list, node) {
+ list_del(&_inst->node);
+ kfree(_inst);
+ }
kfree(zone);
return -ENOMEM;