From patchwork Thu May 29 08:15:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amit Daniel Kachhap X-Patchwork-Id: 31104 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f198.google.com (mail-vc0-f198.google.com [209.85.220.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4E94C203E6 for ; Thu, 29 May 2014 08:18:03 +0000 (UTC) Received: by mail-vc0-f198.google.com with SMTP id ij19sf45573585vcb.1 for ; Thu, 29 May 2014 01:18:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version:sender :errors-to:x-original-sender:x-original-authentication-results :mailing-list:content-type:content-transfer-encoding; bh=+yPbikHjoz3S27/uTXr+lUL2op2A94npSmwI8TpXFKM=; b=K4BVbOCkAEt/UnSq5sjHWuX8GqbmCY+EBVPvm23OJa38o53+k+xy79gWg6Qsi22Qwj 0CGD0SPKdQkHoG0sIQLFylSOkSZa6ELobCF+J9C9BkYk+ENYp91GwKzExSWdDxoVx/uw GEHh0kBTtaqHva9xBLT6QQuUlfnusC2kIkefSU316JkwvZQSPnClfl83FlMkzKf9AlVB v6XAzbn8uMjJzB+BIDNI1/17cfbC8ey0qhYp0ApUyF53uKWkekNRQiRvhfhOFQ1oKEhR 9+yHkGQHDbhftDV3by5KEz4HbThfkQdOtV8oDmwJJYsPpiDaSH876kIpbjUfi7+HkLJi jK+Q== X-Gm-Message-State: ALoCoQmRwgrMNtK6jxNE0riNZaSLpKw5dgNQl6yKM3qZ2X2k7/aCjIzoJC3o0/pap0UI4S9JgUkv X-Received: by 10.224.147.72 with SMTP id k8mr2168926qav.5.1401351483542; Thu, 29 May 2014 01:18:03 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.34.196 with SMTP id l62ls138400qgl.35.gmail; Thu, 29 May 2014 01:18:03 -0700 (PDT) X-Received: by 10.220.82.133 with SMTP id b5mr4906003vcl.13.1401351483419; Thu, 29 May 2014 01:18:03 -0700 (PDT) Received: from mail-ve0-x22c.google.com (mail-ve0-x22c.google.com [2607:f8b0:400c:c01::22c]) by mx.google.com with ESMTPS id i5si12676375vcp.33.2014.05.29.01.18.03 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 29 May 2014 01:18:03 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c01::22c as permitted sender) client-ip=2607:f8b0:400c:c01::22c; Received: by mail-ve0-f172.google.com with SMTP id oz11so13859991veb.17 for ; Thu, 29 May 2014 01:18:03 -0700 (PDT) X-Received: by 10.221.4.66 with SMTP id ob2mr5113343vcb.28.1401351483327; Thu, 29 May 2014 01:18:03 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp9580vcb; Thu, 29 May 2014 01:18:02 -0700 (PDT) X-Received: by 10.224.51.2 with SMTP id b2mr7685706qag.49.1401351482739; Thu, 29 May 2014 01:18:02 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id x8si25924143qaj.66.2014.05.29.01.18.02 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 May 2014 01:18:02 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WpvVz-0005q4-JR; Thu, 29 May 2014 08:16:43 +0000 Received: from mail-pb0-x22a.google.com ([2607:f8b0:400e:c01::22a]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WpvVg-0005cB-UC for linux-arm-kernel@lists.infradead.org; Thu, 29 May 2014 08:16:25 +0000 Received: by mail-pb0-f42.google.com with SMTP id md12so12745153pbc.1 for ; Thu, 29 May 2014 01:16:01 -0700 (PDT) X-Received: by 10.68.194.229 with SMTP id hz5mr6403049pbc.91.1401351361861; Thu, 29 May 2014 01:16:01 -0700 (PDT) Received: from localhost.localdomain ([14.140.216.146]) by mx.google.com with ESMTPSA id ee5sm5006897pbc.47.2014.05.29.01.15.57 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 29 May 2014 01:16:01 -0700 (PDT) From: Amit Daniel Kachhap To: linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org Subject: [PATCH v1 2/6] thermal: cpu_cooling: Support passing driver private data. Date: Thu, 29 May 2014 13:45:30 +0530 Message-Id: <1401351334-11210-3-git-send-email-amit.daniel@samsung.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1401351334-11210-1-git-send-email-amit.daniel@samsung.com> References: <1401351334-11210-1-git-send-email-amit.daniel@samsung.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140529_011625_032429_43124E7C X-CRM114-Status: GOOD ( 26.20 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.3.2 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (amitdanielk[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid Cc: amit.kachhap@gmail.com, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, edubezval@gmail.com, Zhang Rui , linux-arm-kernel@lists.infradead.org, lenb@kernel.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Original-Sender: amit.daniel@samsung.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c01::22c as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=neutral (body hash did not verify) header.i=@ Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 This patch allows the caller of cpufreq cooling APIs to register along with their driver data which will be useful while receiving any cooling states notifications. This patch is in preparation to add notfication support for cpufrequency cooling changes. This change also removes the unnecessary exposing of internal housekeeping structure via thermal_cooling_device->devdata to the users of cpufreq cooling APIs. As part of this implmentation, this private local structure (cpufreq_dev) is now stored in a list and scanned for each call to cpu cooling interfaces. Signed-off-by: Amit Daniel Kachhap --- Documentation/thermal/cpu-cooling-api.txt | 3 +- drivers/thermal/cpu_cooling.c | 89 ++++++++++++++++---- drivers/thermal/db8500_cpufreq_cooling.c | 2 +- drivers/thermal/samsung/exynos_thermal_common.c | 2 +- drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +- include/linux/cpu_cooling.h | 5 +- 6 files changed, 80 insertions(+), 23 deletions(-) diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt index fca24c9..aaa07c6 100644 --- a/Documentation/thermal/cpu-cooling-api.txt +++ b/Documentation/thermal/cpu-cooling-api.txt @@ -17,13 +17,14 @@ the user. The registration APIs returns the cooling device pointer. 1.1 cpufreq registration/unregistration APIs 1.1.1 struct thermal_cooling_device *cpufreq_cooling_register( - struct cpumask *clip_cpus) + struct cpumask *clip_cpus, void *devdata) This interface function registers the cpufreq cooling device with the name "thermal-cpufreq-%x". This api can support multiple instances of cpufreq cooling devices. clip_cpus: cpumask of cpus where the frequency constraints will happen. + devdata: driver private data pointer. 1.1.2 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 16388b0..6d145d5 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -50,16 +50,18 @@ struct cpufreq_cooling_device { unsigned int cpufreq_state; unsigned int cpufreq_val; struct cpumask allowed_cpus; + struct list_head node; }; static DEFINE_IDR(cpufreq_idr); static DEFINE_MUTEX(cooling_cpufreq_lock); -static unsigned int cpufreq_dev_count; - /* notify_table passes value to the CPUFREQ_ADJUST callback function. */ #define NOTIFY_INVALID NULL static DEFINE_PER_CPU(struct cpufreq_cooling_device *, notify_device); +/* A list to hold all the cpufreq cooling devices registered */ +static LIST_HEAD(cpufreq_cooling_list); + /** * get_idr - function to get a unique id. * @idr: struct idr * handle used to create a id. @@ -98,6 +100,26 @@ static void release_idr(struct idr *idr, int id) /* Below code defines functions to be used for cpufreq as cooling device */ +/** + * cpufreq_cooling_get_info - function to cpufreq_dev for the corresponding cdev + * @cdev: pointer of the cooling device + * + * This function will loop through the cpufreq_cooling_device list and + * return the matching device + * + * Return: cpufreq_cooling_device if matched with the cdev or NULL if not + * matched. + */ +static inline struct cpufreq_cooling_device * +cpufreq_cooling_get_info(struct thermal_cooling_device *cdev) +{ + struct cpufreq_cooling_device *cpufreq_dev = NULL; + list_for_each_entry(cpufreq_dev, &cpufreq_cooling_list, node) + if (cpufreq_dev->cool_dev == cdev) + break; + return cpufreq_dev; +} + enum cpufreq_cooling_property { GET_LEVEL, GET_FREQ, @@ -349,12 +371,21 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { - struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; - struct cpumask *mask = &cpufreq_device->allowed_cpus; + struct cpufreq_cooling_device *cpufreq_device = NULL; + struct cpumask *mask = NULL; unsigned int cpu; unsigned int count = 0; int ret; + mutex_lock(&cooling_cpufreq_lock); + cpufreq_device = cpufreq_cooling_get_info(cdev); + mutex_unlock(&cooling_cpufreq_lock); + if (!cpufreq_device) { + /* Cooling device pointer not found */ + return -EINVAL; + } + + mask = &cpufreq_device->allowed_cpus; cpu = cpumask_any(mask); ret = get_property(cpu, 0, &count, GET_MAXL); @@ -378,7 +409,15 @@ static int cpufreq_get_max_state(struct thermal_cooling_device *cdev, static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state) { - struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; + struct cpufreq_cooling_device *cpufreq_device = NULL; + + mutex_lock(&cooling_cpufreq_lock); + cpufreq_device = cpufreq_cooling_get_info(cdev); + mutex_unlock(&cooling_cpufreq_lock); + if (!cpufreq_device) { + /* Cooling device pointer not found */ + return -EINVAL; + } *state = cpufreq_device->cpufreq_state; @@ -398,7 +437,15 @@ static int cpufreq_get_cur_state(struct thermal_cooling_device *cdev, static int cpufreq_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) { - struct cpufreq_cooling_device *cpufreq_device = cdev->devdata; + struct cpufreq_cooling_device *cpufreq_device = NULL; + + mutex_lock(&cooling_cpufreq_lock); + cpufreq_device = cpufreq_cooling_get_info(cdev); + mutex_unlock(&cooling_cpufreq_lock); + if (!cpufreq_device) { + /* Cooling device pointer not found */ + return -EINVAL; + } return cpufreq_apply_cooling(cpufreq_device, state); } @@ -419,6 +466,7 @@ static struct notifier_block thermal_cpufreq_notifier_block = { * __cpufreq_cooling_register - helper function to create cpufreq cooling device * @np: a valid struct device_node to the cooling device device tree node * @clip_cpus: cpumask of cpus where the frequency constraints will happen. + * @devdata: driver data pointer * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq @@ -430,7 +478,7 @@ static struct notifier_block thermal_cpufreq_notifier_block = { */ static struct thermal_cooling_device * __cpufreq_cooling_register(struct device_node *np, - const struct cpumask *clip_cpus) + const struct cpumask *clip_cpus, void *devdata) { struct thermal_cooling_device *cool_dev; struct cpufreq_cooling_device *cpufreq_dev = NULL; @@ -469,7 +517,7 @@ __cpufreq_cooling_register(struct device_node *np, snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", cpufreq_dev->id); - cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev, + cool_dev = thermal_of_cooling_device_register(np, dev_name, devdata, &cpufreq_cooling_ops); if (IS_ERR(cool_dev)) { release_idr(&cpufreq_idr, cpufreq_dev->id); @@ -481,10 +529,11 @@ __cpufreq_cooling_register(struct device_node *np, mutex_lock(&cooling_cpufreq_lock); /* Register the notifier for first cpufreq cooling device */ - if (cpufreq_dev_count == 0) + if (list_empty(&cpufreq_cooling_list)) cpufreq_register_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); - cpufreq_dev_count++; + + list_add(&cpufreq_dev->node, &cpufreq_cooling_list); mutex_unlock(&cooling_cpufreq_lock); @@ -494,6 +543,7 @@ __cpufreq_cooling_register(struct device_node *np, /** * cpufreq_cooling_register - function to create cpufreq cooling device. * @clip_cpus: cpumask of cpus where the frequency constraints will happen. + * @devdata: driver data pointer * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq @@ -503,9 +553,9 @@ __cpufreq_cooling_register(struct device_node *np, * on failure, it returns a corresponding ERR_PTR(). */ struct thermal_cooling_device * -cpufreq_cooling_register(const struct cpumask *clip_cpus) +cpufreq_cooling_register(const struct cpumask *clip_cpus, void *devdata) { - return __cpufreq_cooling_register(NULL, clip_cpus); + return __cpufreq_cooling_register(NULL, clip_cpus, devdata); } EXPORT_SYMBOL_GPL(cpufreq_cooling_register); @@ -529,7 +579,7 @@ of_cpufreq_cooling_register(struct device_node *np, if (!np) return ERR_PTR(-EINVAL); - return __cpufreq_cooling_register(np, clip_cpus); + return __cpufreq_cooling_register(np, clip_cpus, NULL); } EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); @@ -546,17 +596,22 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) if (!cdev) return; - cpufreq_dev = cdev->devdata; mutex_lock(&cooling_cpufreq_lock); - cpufreq_dev_count--; + cpufreq_dev = cpufreq_cooling_get_info(cdev); + if (!cpufreq_dev) { + /* Cooling device pointer not found */ + mutex_unlock(&cooling_cpufreq_lock); + return; + } + thermal_cooling_device_unregister(cpufreq_dev->cool_dev); + list_del(&cpufreq_dev->node); /* Unregister the notifier for the last cpufreq cooling device */ - if (cpufreq_dev_count == 0) + if (list_empty(&cpufreq_cooling_list)) cpufreq_unregister_notifier(&thermal_cpufreq_notifier_block, CPUFREQ_POLICY_NOTIFIER); mutex_unlock(&cooling_cpufreq_lock); - thermal_cooling_device_unregister(cpufreq_dev->cool_dev); release_idr(&cpufreq_idr, cpufreq_dev->id); kfree(cpufreq_dev); } diff --git a/drivers/thermal/db8500_cpufreq_cooling.c b/drivers/thermal/db8500_cpufreq_cooling.c index 786d192..abb9bdd 100644 --- a/drivers/thermal/db8500_cpufreq_cooling.c +++ b/drivers/thermal/db8500_cpufreq_cooling.c @@ -35,7 +35,7 @@ static int db8500_cpufreq_cooling_probe(struct platform_device *pdev) return -EPROBE_DEFER; cpumask_set_cpu(0, &mask_val); - cdev = cpufreq_cooling_register(&mask_val); + cdev = cpufreq_cooling_register(&mask_val, NULL); if (IS_ERR(cdev)) { dev_err(&pdev->dev, "Failed to register cooling device\n"); diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c index 3f5ad25..a7306fa 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.c +++ b/drivers/thermal/samsung/exynos_thermal_common.c @@ -369,7 +369,7 @@ int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) if (sensor_conf->cooling_data.freq_clip_count > 0) { cpumask_set_cpu(0, &mask_val); th_zone->cool_dev[th_zone->cool_dev_size] = - cpufreq_cooling_register(&mask_val); + cpufreq_cooling_register(&mask_val, NULL); if (IS_ERR(th_zone->cool_dev[th_zone->cool_dev_size])) { dev_err(sensor_conf->dev, "Failed to register cpufreq cooling device\n"); diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c index 9eec26d..7809db6 100644 --- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c @@ -409,7 +409,7 @@ int ti_thermal_register_cpu_cooling(struct ti_bandgap *bgp, int id) } /* Register cooling device */ - data->cool_dev = cpufreq_cooling_register(cpu_present_mask); + data->cool_dev = cpufreq_cooling_register(cpu_present_mask, NULL); if (IS_ERR(data->cool_dev)) { dev_err(bgp->dev, "Failed to register cpufreq cooling device\n"); diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index c303d38..aaef7d8 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -32,9 +32,10 @@ /** * cpufreq_cooling_register - function to create cpufreq cooling device. * @clip_cpus: cpumask of cpus where the frequency constraints will happen + * @devdata: driver data pointer */ struct thermal_cooling_device * -cpufreq_cooling_register(const struct cpumask *clip_cpus); +cpufreq_cooling_register(const struct cpumask *clip_cpus, void *devdata); /** * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. @@ -63,7 +64,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev); unsigned long cpufreq_cooling_get_level(unsigned int cpu, unsigned int freq); #else /* !CONFIG_CPU_THERMAL */ static inline struct thermal_cooling_device * -cpufreq_cooling_register(const struct cpumask *clip_cpus) +cpufreq_cooling_register(const struct cpumask *clip_cpus, void *devdata) { return NULL; }