From patchwork Thu Jul 19 06:31:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Rui X-Patchwork-Id: 1215601 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id C2F853FD4F for ; Thu, 19 Jul 2012 06:32:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751975Ab2GSGcM (ORCPT ); Thu, 19 Jul 2012 02:32:12 -0400 Received: from mga14.intel.com ([143.182.124.37]:41184 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752256Ab2GSGcK (ORCPT ); Thu, 19 Jul 2012 02:32:10 -0400 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga102.ch.intel.com with ESMTP; 18 Jul 2012 23:32:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.71,315,1320652800"; d="scan'208";a="170231298" Received: from rui-x220.sh.intel.com ([10.239.197.100]) by azsmga001.ch.intel.com with ESMTP; 18 Jul 2012 23:32:07 -0700 From: Zhang Rui To: linux-acpi@vger.kernel.org, linux-pm@vger.kernel.org Cc: "Rafael J. Wysocki" , Matthew Garrett , Len Brown , R Durgadoss , Eduardo Valentin , Amit Kachhap , Wei Ni , Zhang Rui Subject: [PATCH 16/16] Thermal: use plist instead of list Date: Thu, 19 Jul 2012 14:31:20 +0800 Message-Id: <1342679480-5336-17-git-send-email-rui.zhang@intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1342679480-5336-1-git-send-email-rui.zhang@intel.com> References: <1342679480-5336-1-git-send-email-rui.zhang@intel.com> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org so that the thermal manager can easily find out the deepest cooling state request for a cooling device. cdev->lock is also introduced in this patch to protect this plist. Signed-off-by: Zhang Rui --- drivers/thermal/thermal_sys.c | 84 ++++++++++++++++++++++++++--------------- include/linux/thermal.h | 4 +- 2 files changed, 57 insertions(+), 31 deletions(-) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index a40dda1..9f56250 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -54,11 +54,10 @@ struct thermal_instance { int trip; unsigned long upper; /* Highest cooling state for this trip point */ unsigned long lower; /* Lowest cooling state for this trip point */ - unsigned long target; /* expected cooling state */ char attr_name[THERMAL_NAME_LENGTH]; struct device_attribute attr; struct list_head tz_node; /* node in tz->instances */ - struct list_head cdev_node; /* node in cdev->instances */ + struct plist_node cdev_node; /* node in cdev->instances */ }; static DEFINE_IDR(thermal_tz_idr); @@ -787,7 +786,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, dev->trip = trip; dev->upper = upper; dev->lower = lower; - dev->target = -1; + plist_node_init(&dev->cdev_node, -1); result = get_idr(&tz->idr, &tz->lock, &dev->id); if (result) @@ -809,6 +808,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->instances, tz_node) if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { result = -EEXIST; @@ -816,8 +816,9 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, } if (!result) { list_add_tail(&dev->tz_node, &tz->instances); - list_add_tail(&dev->cdev_node, &cdev->instances); + plist_add(&dev->cdev_node, &cdev->instances); } + mutex_unlock(&cdev->lock); mutex_unlock(&tz->lock); if (!result) @@ -850,14 +851,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->instances, tz_node) { if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { list_del(&pos->tz_node); - list_del(&pos->cdev_node); + plist_del(&pos->cdev_node, &pos->cdev->instances); + mutex_unlock(&cdev->lock); mutex_unlock(&tz->lock); goto unbind; } } + mutex_unlock(&cdev->lock); mutex_unlock(&tz->lock); return -ENODEV; @@ -923,7 +927,8 @@ thermal_cooling_device_register(char *type, void *devdata, } strcpy(cdev->type, type); - INIT_LIST_HEAD(&cdev->instances); + plist_head_init(&cdev->instances); + mutex_init(&cdev->lock); cdev->ops = ops; cdev->updated = 1; cdev->device.class = &thermal_class; @@ -1019,26 +1024,21 @@ EXPORT_SYMBOL(thermal_cooling_device_unregister); static void thermal_zone_do_update(struct thermal_zone_device *tz) { - struct thermal_instance *instance1, *instance2; + struct thermal_instance *instance; + struct plist_node *node; struct thermal_cooling_device *cdev; - int target; - list_for_each_entry(instance1, &tz->instances, tz_node) { - cdev = instance1->cdev; + list_for_each_entry(instance, &tz->instances, tz_node) { + cdev = instance->cdev; /* cooling device has already been updated*/ if (cdev->updated) continue; - target = 0; - /* Make sure cdev enters the deepest cooling state */ - list_for_each_entry(instance2, &cdev->instances, cdev_node) { - if (instance2->target == -1) - continue; - if (instance2->target > target) - target = instance2->target; - } - cdev->ops->set_cur_state(cdev, target); + /* Deepest cooling state required */ + node = plist_last(&cdev->instances); + + cdev->ops->set_cur_state(cdev, node->prio < 0 ? 0 : node->prio); cdev->updated = 1; } } @@ -1064,7 +1064,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, { struct thermal_instance *instance; struct thermal_cooling_device *cdev = NULL; - unsigned long cur_state, max_state; + unsigned long cur_state, max_state, target_state; long trip_temp; enum thermal_trip_type trip_type; enum thermal_trend trend; @@ -1088,21 +1088,29 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, cdev->ops->get_cur_state(cdev, &cur_state); cdev->ops->get_max_state(cdev, &max_state); - + target_state = cur_state; if (trend == THERMAL_TREND_RAISING) { - cur_state = cur_state < instance->upper ? + target_state = cur_state < instance->upper ? (cur_state + 1) : instance->upper; } else if (trend == THERMAL_TREND_DROPPING) { - cur_state = cur_state > instance->lower ? + target_state = cur_state > instance->lower ? (cur_state - 1) : instance->lower; } + if (target_state == cur_state) + continue; + /* activate a passive thermal instance */ if (trip_type == THERMAL_TRIP_PASSIVE && - instance->target == -1) + instance->cdev_node.prio == -1) tz->passive++; - instance->target = cur_state; + mutex_lock(&cdev->lock); + plist_del(&instance->cdev_node, &cdev->instances); + plist_node_init(&instance->cdev_node, target_state); + plist_add(&instance->cdev_node, &cdev->instances); + mutex_unlock(&cdev->lock); + cdev->updated = 0; /* cooling device needs update */ } } else { /* below trip */ @@ -1111,20 +1119,36 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, continue; /* Do not use the deacitve thermal instance */ - if (instance->target == -1) + if (instance->cdev_node.prio == -1) continue; cdev = instance->cdev; cdev->ops->get_cur_state(cdev, &cur_state); - cur_state = cur_state > instance->lower ? + target_state = cur_state > instance->lower ? (cur_state - 1) : -1; + if (target_state == cur_state) + continue; + /* deactivate a passive thermal instance */ if (trip_type == THERMAL_TRIP_PASSIVE && - cur_state == -1) + target_state == -1) tz->passive--; - instance->target = cur_state; - cdev->updated = 0; /* cooling device needs update */ + + mutex_lock(&cdev->lock); + plist_del(&instance->cdev_node, &cdev->instances); + plist_node_init(&instance->cdev_node, target_state); + plist_add(&instance->cdev_node, &cdev->instances); + mutex_unlock(&cdev->lock); + + /* + * cooling device needs update. + * But if the target_state is -1, it means that + * the cooling device is already in cooling state 0, + * thus we do not need update + */ + if (target_state != -1) + cdev->updated = 0; } } diff --git a/include/linux/thermal.h b/include/linux/thermal.h index f725eb9..376a59e 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -28,6 +28,7 @@ #include #include #include +#include struct thermal_zone_device; struct thermal_cooling_device; @@ -93,7 +94,8 @@ struct thermal_cooling_device { void *devdata; const struct thermal_cooling_device_ops *ops; int updated; /* 1 if the cooling device does not need update */ - struct list_head instances; + struct mutex lock; + struct plist_head instances; struct list_head node; };