Thermal: Introduce locking for cdev.thermal_instances list.
[linux-2.6.git] / drivers / thermal / thermal_sys.c
index e2a5cb0..0165cf4 100644 (file)
@@ -799,6 +799,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
                goto remove_symbol_link;
 
        mutex_lock(&tz->lock);
+       mutex_lock(&cdev->lock);
        list_for_each_entry(pos, &tz->thermal_instances, tz_node)
            if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
                result = -EEXIST;
@@ -808,6 +809,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
                list_add_tail(&dev->tz_node, &tz->thermal_instances);
                list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
        }
+       mutex_unlock(&cdev->lock);
        mutex_unlock(&tz->lock);
 
        if (!result)
@@ -840,14 +842,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
        struct thermal_instance *pos, *next;
 
        mutex_lock(&tz->lock);
+       mutex_lock(&cdev->lock);
        list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
                if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
                        list_del(&pos->tz_node);
                        list_del(&pos->cdev_node);
+                       mutex_unlock(&cdev->lock);
                        mutex_unlock(&tz->lock);
                        goto unbind;
                }
        }
+       mutex_unlock(&cdev->lock);
        mutex_unlock(&tz->lock);
 
        return -ENODEV;
@@ -913,6 +918,7 @@ thermal_cooling_device_register(char *type, void *devdata,
        }
 
        strcpy(cdev->type, type);
+       mutex_init(&cdev->lock);
        INIT_LIST_HEAD(&cdev->thermal_instances);
        cdev->ops = ops;
        cdev->updated = true;
@@ -1016,6 +1022,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
        if (cdev->updated)
                return;
 
+       mutex_lock(&cdev->lock);
        /* Make sure cdev enters the deepest cooling state */
        list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
                if (instance->target == THERMAL_NO_TARGET)
@@ -1023,6 +1030,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
                if (instance->target > target)
                        target = instance->target;
        }
+       mutex_unlock(&cdev->lock);
        cdev->ops->set_cur_state(cdev, target);
        cdev->updated = true;
 }