From patchwork Fri Jan 23 12:10:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 5693241 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6228DC058D for ; Fri, 23 Jan 2015 12:11:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2D9F9202BE for ; Fri, 23 Jan 2015 12:11:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D44D4202C8 for ; Fri, 23 Jan 2015 12:11:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755120AbbAWMLA (ORCPT ); Fri, 23 Jan 2015 07:11:00 -0500 Received: from mailout3.samsung.com ([203.254.224.33]:19955 "EHLO mailout3.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755171AbbAWMK7 (ORCPT ); Fri, 23 Jan 2015 07:10:59 -0500 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NIM005ULPU9CBA0@mailout3.samsung.com>; Fri, 23 Jan 2015 21:10:57 +0900 (KST) X-AuditID: cbfee61a-f79c06d000004e71-50-54c23a51cd7c Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id F9.AA.20081.15A32C45; Fri, 23 Jan 2015 21:10:57 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NIM00LXWPT1NR80@mmp1.samsung.com>; Fri, 23 Jan 2015 21:10:57 +0900 (KST) From: Lukasz Majewski To: Eduardo Valentin , Zhang Rui , Kukjin Kim , Kukjin Kim Cc: Linux PM list , "linux-samsung-soc@vger.kernel.org" , Bartlomiej Zolnierkiewicz , Lukasz Majewski , Amit Daniel Kachhap , Abhilash Kesavan , Abhilash Kesavan , Chanwoo Choi , Viresh Kumar , Lukasz Majewski Subject: [PATCH v6 07/18] thermal: exynos: Modify exynos thermal code to use device tree for cpu cooling configuration Date: Fri, 23 Jan 2015 13:10:00 +0100 Message-id: <1422015010-11918-8-git-send-email-l.majewski@samsung.com> X-Mailer: git-send-email 1.7.10.4 In-reply-to: <1422015010-11918-1-git-send-email-l.majewski@samsung.com> References: <1421666462-7606-1-git-send-email-l.majewski@samsung.com> <1422015010-11918-1-git-send-email-l.majewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFtrPLMWRmVeSWpSXmKPExsVy+t9jAd1Aq0MhBg1nuS0er1nMZNFwNcRi 44z1rBbXvzxntZh/5RqrxZq/Sha9C66yWfQ/fs1s8eYRt8Wbh5sZLT73HmG0mHF+H5PFk4d9 bBYbv3o48HnsnHWX3WPxnpdMHptWdbJ53Lm2h81j3bS3zB59W1YxenzeJBfAHsVlk5Kak1mW WqRvl8CV8ejMYvaC7T4V/97PYWtgXGbbxcjJISFgIvGh8wMrhC0mceHeerYuRi4OIYFFjBKz Dh9ngnC6mCS+dj5iAqliE9CT+Hz3KZgtIjCBUeL/qmiQImaBx8wSc97vZwZJCAtUSJz7dBas iEVAVWLztmdgK3gF3CRW7wBZAbJOUaL72QQwm1PAXeL9vj/MENuaGCXOTbrKNoGRdwEjwypG 0dSC5ILipPRcQ73ixNzi0rx0veT83E2M4GB9JrWDcWWDxSFGAQ5GJR7ehi0HQ4RYE8uKK3MP MUpwMCuJ8FprHgoR4k1JrKxKLcqPLyrNSS0+xCjNwaIkzqtk3xYiJJCeWJKanZpakFoEk2Xi 4JRqYORWXbcrN3iVyap9L62vdgqzVyrpvc3mLaiZn7zLh1ly772jgmZH9bhWzHTVPXWuRvNY R3iO8OqG3DO2nts1/KZ2fK89n5EaXJRaWv2A886DoCNz1bdv4tyYx1ebmKJjKW+TtvD3iwdN 3xf+MTHT3mzb8iHuS+HpqAlnTcS3C1R0uO95/UJJRomlOCPRUIu5qDgRAI9MIIBSAgAA Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Up till now exynos_tmu_data.c was used for storing CPU cooling configuration data. Now the Exynos thermal core code uses device tree to get this data. For this purpose generic thermal code for configuring CPU cooling was used. Signed-off-by: Lukasz Majewski --- Changes for v2: - None Changes for v3: - Rewrite code responsible for registering CPU cooling device to not depend on explicit "/cpus/cpu@0" path since now Exynos SoCs use new cpu node names (e.g. cpu@A00). New approach iterates over "cpus" node children. - Patch title changed to thermal: exynos Changes for v4: - None Changes for v5: - None Changes for v6: - Remove exynos cpufreq related code (exynos-cpufreq.c) from this commit --- drivers/thermal/samsung/exynos_thermal_common.c | 122 ++++++++++++++---------- drivers/thermal/samsung/exynos_tmu.c | 7 -- drivers/thermal/samsung/exynos_tmu.h | 5 - drivers/thermal/samsung/exynos_tmu_data.c | 42 +------- 4 files changed, 73 insertions(+), 103 deletions(-) diff --git a/drivers/thermal/samsung/exynos_thermal_common.c b/drivers/thermal/samsung/exynos_thermal_common.c index 6dc3815..00aa688 100644 --- a/drivers/thermal/samsung/exynos_thermal_common.c +++ b/drivers/thermal/samsung/exynos_thermal_common.c @@ -133,47 +133,62 @@ static int exynos_get_crit_temp(struct thermal_zone_device *thermal, static int exynos_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { - int ret = 0, i, tab_size, level; - struct freq_clip_table *tab_ptr, *clip_data; struct exynos_thermal_zone *th_zone = thermal->devdata; struct thermal_sensor_conf *data = th_zone->sensor_conf; + struct device_node *child, *gchild, *np; + struct of_phandle_args cooling_spec; + unsigned long max, state = 0; + int ret = 0, i = 0; - tab_ptr = (struct freq_clip_table *)data->cooling_data.freq_data; - tab_size = data->cooling_data.freq_clip_count; - - if (tab_ptr == NULL || tab_size == 0) + /* + * Below code is necessary to skip binding when cpufreq's + * frequency table is not yet initialized. + */ + cdev->ops->get_max_state(cdev, &state); + if (!state && !th_zone->cool_dev_size) { + th_zone->cool_dev_size = 1; + th_zone->cool_dev[0] = cdev; + th_zone->bind = false; return 0; + } - /* find the cooling device registered*/ - for (i = 0; i < th_zone->cool_dev_size; i++) - if (cdev == th_zone->cool_dev[i]) - break; + np = of_find_node_by_path("/thermal-zones/cpu-thermal"); + if (!np) { + pr_err("failed to find thmerla-zones/cpu-thermal node\n"); + return -ENOENT; + } - /* No matching cooling device */ - if (i == th_zone->cool_dev_size) - return 0; + child = of_get_child_by_name(np, "cooling-maps"); - /* Bind the thermal zone to the cpufreq cooling device */ - for (i = 0; i < tab_size; i++) { - clip_data = (struct freq_clip_table *)&(tab_ptr[i]); - level = cpufreq_cooling_get_level(0, clip_data->freq_clip_max); - if (level == THERMAL_CSTATE_INVALID) - return 0; - switch (GET_ZONE(i)) { - case MONITOR_ZONE: - case WARN_ZONE: - if (thermal_zone_bind_cooling_device(thermal, i, cdev, - level, 0)) { - dev_err(data->dev, - "error unbinding cdev inst=%d\n", i); - ret = -EINVAL; - } - th_zone->bind = true; - break; - default: + for_each_child_of_node(child, gchild) { + ret = of_parse_phandle_with_args(gchild, "cooling-device", + "#cooling-cells", + 0, &cooling_spec); + if (ret < 0) { + pr_err("missing cooling_device property\n"); + goto end; + } + + if (cooling_spec.args_count < 2) { ret = -EINVAL; + goto end; } + + max = cooling_spec.args[0]; + if (thermal_zone_bind_cooling_device(thermal, i, cdev, + max, 0)) { + dev_err(data->dev, + "thermal error unbinding cdev inst=%d\n", i); + + ret = -EINVAL; + goto end; + } + i++; } + th_zone->bind = true; +end: + of_node_put(child); + of_node_put(np); return ret; } @@ -182,16 +197,12 @@ static int exynos_bind(struct thermal_zone_device *thermal, static int exynos_unbind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { - int ret = 0, i, tab_size; + int ret = 0, i; struct exynos_thermal_zone *th_zone = thermal->devdata; struct thermal_sensor_conf *data = th_zone->sensor_conf; + struct device_node *child, *gchild, *np; - if (th_zone->bind == false) - return 0; - - tab_size = data->cooling_data.freq_clip_count; - - if (tab_size == 0) + if (th_zone->bind == false || !th_zone->cool_dev_size) return 0; /* find the cooling device registered*/ @@ -203,23 +214,30 @@ static int exynos_unbind(struct thermal_zone_device *thermal, if (i == th_zone->cool_dev_size) return 0; - /* Bind the thermal zone to the cpufreq cooling device */ - for (i = 0; i < tab_size; i++) { - switch (GET_ZONE(i)) { - case MONITOR_ZONE: - case WARN_ZONE: - if (thermal_zone_unbind_cooling_device(thermal, i, - cdev)) { - dev_err(data->dev, - "error unbinding cdev inst=%d\n", i); - ret = -EINVAL; - } - th_zone->bind = false; - break; - default: + np = of_find_node_by_path("/thermal-zones/cpu-thermal"); + if (!np) { + pr_err("failed to find thmerla-zones/cpu-thermal node\n"); + return -ENOENT; + } + + child = of_get_child_by_name(np, "cooling-maps"); + + i = 0; + for_each_child_of_node(child, gchild) { + if (thermal_zone_unbind_cooling_device(thermal, i, + cdev)) { + dev_err(data->dev, + "error unbinding cdev inst=%d\n", i); ret = -EINVAL; + goto end; } + i++; } + th_zone->bind = false; +end: + of_node_put(child); + of_node_put(np); + return ret; } diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c index 5000727..ae30f6a 100644 --- a/drivers/thermal/samsung/exynos_tmu.c +++ b/drivers/thermal/samsung/exynos_tmu.c @@ -916,13 +916,6 @@ static int exynos_tmu_probe(struct platform_device *pdev) sensor_conf->trip_data.trigger_falling = pdata->threshold_falling; - sensor_conf->cooling_data.freq_clip_count = pdata->freq_tab_count; - for (i = 0; i < pdata->freq_tab_count; i++) { - sensor_conf->cooling_data.freq_data[i].freq_clip_max = - pdata->freq_tab[i].freq_clip_max; - sensor_conf->cooling_data.freq_data[i].temp_level = - pdata->freq_tab[i].temp_level; - } sensor_conf->dev = &pdev->dev; /* Register the sensor with thermal management interface */ ret = exynos_register_thermal(sensor_conf); diff --git a/drivers/thermal/samsung/exynos_tmu.h b/drivers/thermal/samsung/exynos_tmu.h index 7f880d2..627dec9 100644 --- a/drivers/thermal/samsung/exynos_tmu.h +++ b/drivers/thermal/samsung/exynos_tmu.h @@ -83,9 +83,6 @@ enum soc_type { * @second_point_trim: temp value of the second point trimming * @default_temp_offset: default temperature offset in case of no trimming * @cal_type: calibration type for temperature - * @freq_clip_table: Table representing frequency reduction percentage. - * @freq_tab_count: Count of the above table as frequency reduction may - * applicable to only some of the trigger levels. * * This structure is required for configuration of exynos_tmu driver. */ @@ -111,8 +108,6 @@ struct exynos_tmu_platform_data { enum soc_type type; u32 cal_type; u32 cal_mode; - struct freq_clip_table freq_tab[4]; - unsigned int freq_tab_count; }; /** diff --git a/drivers/thermal/samsung/exynos_tmu_data.c b/drivers/thermal/samsung/exynos_tmu_data.c index b239100..a993f3d 100644 --- a/drivers/thermal/samsung/exynos_tmu_data.c +++ b/drivers/thermal/samsung/exynos_tmu_data.c @@ -47,15 +47,6 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .first_point_trim = 25, .second_point_trim = 85, .default_temp_offset = 50, - .freq_tab[0] = { - .freq_clip_max = 800 * 1000, - .temp_level = 85, - }, - .freq_tab[1] = { - .freq_clip_max = 200 * 1000, - .temp_level = 100, - }, - .freq_tab_count = 2, .type = SOC_ARCH_EXYNOS4210, }, }, @@ -87,16 +78,7 @@ struct exynos_tmu_init_data const exynos4210_default_tmu_data = { .max_efuse_value = 100, \ .first_point_trim = 25, \ .second_point_trim = 85, \ - .default_temp_offset = 50, \ - .freq_tab[0] = { \ - .freq_clip_max = 800 * 1000, \ - .temp_level = 70, \ - }, \ - .freq_tab[1] = { \ - .freq_clip_max = 400 * 1000, \ - .temp_level = 95, \ - }, \ - .freq_tab_count = 2 + .default_temp_offset = 50 struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .tmu_data = { @@ -133,16 +115,7 @@ struct exynos_tmu_init_data const exynos3250_default_tmu_data = { .max_efuse_value = 100, \ .first_point_trim = 25, \ .second_point_trim = 85, \ - .default_temp_offset = 50, \ - .freq_tab[0] = { \ - .freq_clip_max = 1400 * 1000, \ - .temp_level = 70, \ - }, \ - .freq_tab[1] = { \ - .freq_clip_max = 400 * 1000, \ - .temp_level = 95, \ - }, \ - .freq_tab_count = 2 + .default_temp_offset = 50 struct exynos_tmu_init_data const exynos4412_default_tmu_data = { .tmu_data = { @@ -189,16 +162,7 @@ struct exynos_tmu_init_data const exynos5250_default_tmu_data = { .max_efuse_value = 100, \ .first_point_trim = 25, \ .second_point_trim = 85, \ - .default_temp_offset = 50, \ - .freq_tab[0] = { \ - .freq_clip_max = 800 * 1000, \ - .temp_level = 85, \ - }, \ - .freq_tab[1] = { \ - .freq_clip_max = 200 * 1000, \ - .temp_level = 103, \ - }, \ - .freq_tab_count = 2, \ + .default_temp_offset = 50, #define EXYNOS5260_TMU_DATA \ __EXYNOS5260_TMU_DATA \