From patchwork Thu May 29 08:15:34 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: 31102 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f197.google.com (mail-ob0-f197.google.com [209.85.214.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 00E25203E6 for ; Thu, 29 May 2014 08:16:53 +0000 (UTC) Received: by mail-ob0-f197.google.com with SMTP id vb8sf59507444obc.4 for ; Thu, 29 May 2014 01:16:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=pqNyIBQF5jKPOg9cBxG3LhrH/CS3KGMAkA1vNnUoEao=; b=ALI0x4K47IjCQhiHiB9GoRQhPyAJStNV1ck+m8+OX9qrzaq/GseYC0h/sarNkXhAHG sDJtIJxtMED+/pvvlOfFYkS/dh6kammunvWZ3GEERlATs7NuBJA1r+5Ox42m5XdBWshf +doniFauIUr2/PkdtKSL6kcDQNY6I+andwgyMNBHPEnmPdHwB7gU8Lb0pJQgt8d4Pnsl /XzQB4vOftEpDOgyigh3cN8PExpSX3rgBTyXSMRw215yOehtAmjm//2Q3DCa3yl+ZtX6 hVkOBcv5lS162MJwD7ZeLqMvveJEzmkM7OEd13v4fL7qvOZu0lKRA1i82OSEHiqw62n2 /VYw== X-Gm-Message-State: ALoCoQkaI0u4/yyO9mec72IlBl0ynzZLYT0teKGMOdkt/0SwPpGftQhUG+OKKF6J2Q8jQ5EefgGF X-Received: by 10.50.73.132 with SMTP id l4mr18157779igv.5.1401351413133; Thu, 29 May 2014 01:16:53 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.89.203 with SMTP id v69ls405981qgd.6.gmail; Thu, 29 May 2014 01:16:53 -0700 (PDT) X-Received: by 10.52.94.47 with SMTP id cz15mr4342668vdb.0.1401351412968; Thu, 29 May 2014 01:16:52 -0700 (PDT) Received: from mail-vc0-x22e.google.com (mail-vc0-x22e.google.com [2607:f8b0:400c:c03::22e]) by mx.google.com with ESMTPS id d5si12664933vea.87.2014.05.29.01.16.52 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 29 May 2014 01:16:52 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c03::22e as permitted sender) client-ip=2607:f8b0:400c:c03::22e; Received: by mail-vc0-f174.google.com with SMTP id hq11so7947539vcb.19 for ; Thu, 29 May 2014 01:16:52 -0700 (PDT) X-Received: by 10.221.4.66 with SMTP id ob2mr5108811vcb.28.1401351412867; Thu, 29 May 2014 01:16:52 -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 ib8csp9499vcb; Thu, 29 May 2014 01:16:52 -0700 (PDT) X-Received: by 10.67.4.169 with SMTP id cf9mr6458141pad.45.1401351411737; Thu, 29 May 2014 01:16:51 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id gc6si27377058pac.152.2014.05.29.01.16.51 for ; Thu, 29 May 2014 01:16:51 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933808AbaE2IQl (ORCPT + 27 others); Thu, 29 May 2014 04:16:41 -0400 Received: from mail-pa0-f51.google.com ([209.85.220.51]:64945 "EHLO mail-pa0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933596AbaE2IQR (ORCPT ); Thu, 29 May 2014 04:16:17 -0400 Received: by mail-pa0-f51.google.com with SMTP id kq14so12544429pab.10 for ; Thu, 29 May 2014 01:16:16 -0700 (PDT) X-Received: by 10.66.146.105 with SMTP id tb9mr1456819pab.157.1401351376775; Thu, 29 May 2014 01:16:16 -0700 (PDT) Received: from localhost.localdomain ([14.140.216.146]) by mx.google.com with ESMTPSA id ee5sm5006897pbc.47.2014.05.29.01.16.13 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 29 May 2014 01:16:16 -0700 (PDT) From: Amit Daniel Kachhap To: linux-pm@vger.kernel.org, linux-acpi@vger.kernel.org Cc: Zhang Rui , linux-kernel@vger.kernel.org, amit.kachhap@gmail.com, edubezval@gmail.com, rjw@rjwysocki.net, linux-arm-kernel@lists.infradead.org, lenb@kernel.org Subject: [PATCH v1 6/6] ACPI: thermal: processor: Use the generic cpufreq infrastructure Date: Thu, 29 May 2014 13:45:34 +0530 Message-Id: <1401351334-11210-7-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> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.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:c03::22e 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 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch upgrades the ACPI cpufreq cooling portions to use the generic cpufreq cooling infrastructure. There should not be any functionality related changes as the same behaviour is provided by the generic cpufreq APIs with the notifier mechanism. Signed-off-by: Amit Daniel Kachhap --- drivers/acpi/processor_driver.c | 6 +- drivers/acpi/processor_thermal.c | 235 ++++++++++++++++++-------------------- include/acpi/processor.h | 3 +- 3 files changed, 115 insertions(+), 129 deletions(-) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 7f70f31..10aba4a 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -178,8 +179,7 @@ static int __acpi_processor_start(struct acpi_device *device) if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver) acpi_processor_power_init(pr); - pr->cdev = thermal_cooling_device_register("Processor", device, - &processor_cooling_ops); + pr->cdev = acpi_processor_cooling_register(device); if (IS_ERR(pr->cdev)) { result = PTR_ERR(pr->cdev); goto err_power_exit; @@ -250,7 +250,7 @@ static int acpi_processor_stop(struct device *dev) if (pr->cdev) { sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); sysfs_remove_link(&pr->cdev->device.kobj, "device"); - thermal_cooling_device_unregister(pr->cdev); + cpufreq_cooling_unregister(pr->cdev); pr->cdev = NULL; } return 0; diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index e003663..9fc4a58 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -53,27 +54,13 @@ ACPI_MODULE_NAME("processor_thermal"); static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); static unsigned int acpi_thermal_cpufreq_is_init = 0; +static struct notifier_block cpufreq_cooling_notifier_block; +static int phys_package_first_cpu(int cpu); #define reduction_pctg(cpu) \ per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) -/* - * Emulate "per package data" using per cpu data (which should really be - * provided elsewhere) - * - * Note we can lose a CPU on cpu hotunplug, in this case we forget the state - * temporarily. Fortunately that's not a big issue here (I hope) - */ -static int phys_package_first_cpu(int cpu) -{ - int i; - int id = topology_physical_package_id(cpu); - - for_each_online_cpu(i) - if (topology_physical_package_id(i) == id) - return i; - return 0; -} +static DEFINE_PER_CPU(struct acpi_device *, acpi_dev); static int cpu_has_cpufreq(unsigned int cpu) { @@ -83,30 +70,6 @@ static int cpu_has_cpufreq(unsigned int cpu) return 1; } -static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, - unsigned long event, void *data) -{ - struct cpufreq_policy *policy = data; - unsigned long max_freq = 0; - - if (event != CPUFREQ_ADJUST) - goto out; - - max_freq = ( - policy->cpuinfo.max_freq * - (100 - reduction_pctg(policy->cpu) * 20) - ) / 100; - - cpufreq_verify_within_limits(policy, 0, max_freq); - - out: - return 0; -} - -static struct notifier_block acpi_thermal_cpufreq_notifier_block = { - .notifier_call = acpi_thermal_cpufreq_notifier, -}; - static int cpufreq_get_max_state(unsigned int cpu) { if (!cpu_has_cpufreq(cpu)) @@ -123,34 +86,31 @@ static int cpufreq_get_cur_state(unsigned int cpu) return reduction_pctg(cpu); } -static int cpufreq_set_cur_state(unsigned int cpu, int state) +static int acpi_processor_freq_level(unsigned int cpu, int state) { - int i; + struct cpufreq_policy policy; + unsigned long max_freq = 0; + int level = 0; - if (!cpu_has_cpufreq(cpu)) + if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu)) return 0; reduction_pctg(cpu) = state; + max_freq = ( + policy.cpuinfo.max_freq * + (100 - reduction_pctg(cpu) * 20) + ) / 100; - /* - * Update all the CPUs in the same package because they all - * contribute to the temperature and often share the same - * frequency. - */ - for_each_online_cpu(i) { - if (topology_physical_package_id(i) == - topology_physical_package_id(cpu)) - cpufreq_update_policy(i); - } - return 0; + level = cpufreq_cooling_get_level(phys_package_first_cpu(cpu), + max_freq, GET_LEVEL_FLOOR); + return level; } void acpi_thermal_cpufreq_init(void) { int i; - i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, - CPUFREQ_POLICY_NOTIFIER); + i = thermal_cooling_register_notifier(&cpufreq_cooling_notifier_block); if (!i) acpi_thermal_cpufreq_is_init = 1; } @@ -158,31 +118,30 @@ void acpi_thermal_cpufreq_init(void) void acpi_thermal_cpufreq_exit(void) { if (acpi_thermal_cpufreq_is_init) - cpufreq_unregister_notifier - (&acpi_thermal_cpufreq_notifier_block, - CPUFREQ_POLICY_NOTIFIER); + thermal_cooling_unregister_notifier( + &cpufreq_cooling_notifier_block); acpi_thermal_cpufreq_is_init = 0; } -#else /* ! CONFIG_CPU_FREQ */ -static int cpufreq_get_max_state(unsigned int cpu) -{ - return 0; -} - -static int cpufreq_get_cur_state(unsigned int cpu) +/* + * Emulate "per package data" using per cpu data (which should really be + * provided elsewhere) + * + * Note we can lose a CPU on cpu hotunplug, in this case we forget the state + * temporarily. Fortunately that's not a big issue here (I hope) + */ +static int phys_package_first_cpu(int cpu) { - return 0; -} + int i; + int id = topology_physical_package_id(cpu); -static int cpufreq_set_cur_state(unsigned int cpu, int state) -{ + for_each_online_cpu(i) + if (topology_physical_package_id(i) == id) + return i; return 0; } -#endif - /* thermal cooling device callbacks */ static int acpi_processor_max_state(struct acpi_processor *pr) { @@ -198,57 +157,22 @@ static int acpi_processor_max_state(struct acpi_processor *pr) return max_state; } -static int -processor_get_max_state(struct thermal_cooling_device *cdev, - unsigned long *state) -{ - struct acpi_device *device = cdev->devdata; - struct acpi_processor *pr; - - if (!device) - return -EINVAL; - - pr = acpi_driver_data(device); - if (!pr) - return -EINVAL; - - *state = acpi_processor_max_state(pr); - return 0; -} -static int -processor_get_cur_state(struct thermal_cooling_device *cdev, - unsigned long *cur_state) +static int acpi_processor_cur_state(struct acpi_processor *pr) { - struct acpi_device *device = cdev->devdata; - struct acpi_processor *pr; - - if (!device) - return -EINVAL; - - pr = acpi_driver_data(device); - if (!pr) - return -EINVAL; - - *cur_state = cpufreq_get_cur_state(pr->id); + int cur_state = 0; + cur_state = cpufreq_get_cur_state(pr->id); if (pr->flags.throttling) - *cur_state += pr->throttling.state; - return 0; + cur_state += pr->throttling.state; + return cur_state; } -static int -processor_set_cur_state(struct thermal_cooling_device *cdev, - unsigned long state) +static int acpi_processor_set_cur_state(struct acpi_processor *pr, + struct thermal_cooling_status *cooling, unsigned long event) { - struct acpi_device *device = cdev->devdata; - struct acpi_processor *pr; - int result = 0; - int max_pstate; - - if (!device) - return -EINVAL; + int result = 0, level = 0; + int max_pstate, state = cooling->new_state; - pr = acpi_driver_data(device); if (!pr) return -EINVAL; @@ -257,20 +181,81 @@ processor_set_cur_state(struct thermal_cooling_device *cdev, if (state > acpi_processor_max_state(pr)) return -EINVAL; - if (state <= max_pstate) { + if (state <= max_pstate && event == COOLING_SET_STATE_PRE) { if (pr->flags.throttling && pr->throttling.state) result = acpi_processor_set_throttling(pr, 0, false); - cpufreq_set_cur_state(pr->id, state); - } else { - cpufreq_set_cur_state(pr->id, max_pstate); + } else if (state > max_pstate && event == COOLING_SET_STATE_POST) { result = acpi_processor_set_throttling(pr, state - max_pstate, false); } + + level = acpi_processor_freq_level(pr->id, state); + cooling->new_state = level; + return result; } -const struct thermal_cooling_device_ops processor_cooling_ops = { - .get_max_state = processor_get_max_state, - .get_cur_state = processor_get_cur_state, - .set_cur_state = processor_set_cur_state, +static int acpi_cpufreq_cooling_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct thermal_cooling_status *cooling = data; + struct acpi_device *device = NULL; + struct acpi_processor *pr; + int i; + + for_each_online_cpu(i) + if (per_cpu(acpi_dev, i) == cooling->devdata) { + device = cooling->devdata; + break; + } + + if (device == NULL) + return 0; /* notfier for some other client */ + + pr = acpi_driver_data(device); + switch (event) { + case COOLING_SET_STATE_PRE: + case COOLING_SET_STATE_POST: + acpi_processor_set_cur_state(pr, cooling, event); + break; + case COOLING_GET_MAX_STATE: + cooling->max_state = acpi_processor_max_state(pr); + break; + case COOLING_GET_CUR_STATE: + cooling->cur_state = acpi_processor_cur_state(pr); + break; + default: + return -EINVAL; + } + return 0; +} + +static struct notifier_block cpufreq_cooling_notifier_block = { + .notifier_call = acpi_cpufreq_cooling_notifier, }; + +struct thermal_cooling_device * +acpi_processor_cooling_register(struct acpi_device *device) +{ + struct thermal_cooling_device *cdev; + struct acpi_processor *pr = acpi_driver_data(device); + int cpu = phys_package_first_cpu(pr->id); + int i; + int id = topology_physical_package_id(cpu); + struct cpumask cpus; + + for_each_online_cpu(i) + if (topology_physical_package_id(i) == id) + cpumask_set_cpu(i, &cpus); + + cdev = cpufreq_cooling_register(&cpus, (void *)device); + per_cpu(acpi_dev, id) = device; + return cdev; +} +#else /* ! CONFIG_CPU_FREQ */ +struct thermal_cooling_device * +acpi_processor_cooling_register(struct acpi_device *device) +{ + return NULL; +} +#endif diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 6eb1d3c..d6e8f67 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -348,7 +348,8 @@ static inline void acpi_processor_syscore_exit(void) {} /* in processor_thermal.c */ int acpi_processor_get_limit_info(struct acpi_processor *pr); -extern const struct thermal_cooling_device_ops processor_cooling_ops; +struct thermal_cooling_device * +acpi_processor_cooling_register(struct acpi_device *device); #ifdef CONFIG_CPU_FREQ void acpi_thermal_cpufreq_init(void); void acpi_thermal_cpufreq_exit(void);