Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp4737839imm; Mon, 18 Jun 2018 22:07:00 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIcKRR8EOHw19YKdEqxrQ30AZ+qx0zzJFD+ksWfz2DSFv2J8FQibtgX8O1JDedhV5O63EaC X-Received: by 2002:a65:4b04:: with SMTP id r4-v6mr13230285pgq.26.1529384820737; Mon, 18 Jun 2018 22:07:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529384820; cv=none; d=google.com; s=arc-20160816; b=ye3/KwlrllVWU/7IrFF/QgGNDfV330X2ArpYWj84Fsh06HKfqdxDkdPVTb/m7bD7Ii XIU1RqbyXyXfIK5oqc/awhjUSmYJyh+QEueJOcltIogYfOxljrH2rGu9OxfgA/dQix8D /N8X4hqycPiTkDUl58tyF4CAimjY1nJFIoL2A2a2unVQ1G5W5ot3a2u7DpHUMDcZnCGr zkESXA3ip7oGKA/vQUzOO3T6CXfjczHWr39PFY/rX6HWKdIDwdaqy8MXo6iqC0mQ+ky1 80XLXh6Xajee8mnORpBczSynsoeI+HeFE9OsPrPR4mKU5bVk0AHr2jdSQd67ejodSlgh Ba/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:references:in-reply-to:date :subject:cc:to:from:arc-authentication-results; bh=gRyKwy/LC0g4P0KMcmevnLk0GafR4xnAy/JCs+R6nuI=; b=Diwqic+fZw5sopS/b/THCQvhnHrDFWMOR8KSJPnp4pXsPOKljKz/rp831zr2199+wV m8o4xf7QfYNcUTlh6B2aMDkxskhBqVqwbj2RVz07L1cn3iLe/dGAAoqlR94Y07HpWVyY y+9eRr7t1FClJq1orOmM2PW3FmciHQMmLDQRqcmXrfKelFD2hjF3Js3f0OhFci/9Z+r0 cN/aWfsaTwbHrVhQ8guq9CxoCy8i4+BcTHdaT/WBNflCXvYa0K9PaWbQqiiN2hNg53V1 YE2BargGjFOH98sRFN1zAUrQ3642kKdpAFIAuWXFh3cFPyx8fa6NQ+Lc5dgyctL/Fipd mRYw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c18-v6si17496581pls.407.2018.06.18.22.06.47; Mon, 18 Jun 2018 22:07:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755689AbeFSFE6 (ORCPT + 99 others); Tue, 19 Jun 2018 01:04:58 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:52602 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755653AbeFSFE4 (ORCPT ); Tue, 19 Jun 2018 01:04:56 -0400 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w5J54Nck118822 for ; Tue, 19 Jun 2018 01:04:55 -0400 Received: from e06smtp04.uk.ibm.com (e06smtp04.uk.ibm.com [195.75.94.100]) by mx0a-001b2d01.pphosted.com with ESMTP id 2jprxyvax0-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 19 Jun 2018 01:04:55 -0400 Received: from localhost by e06smtp04.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 19 Jun 2018 06:04:53 +0100 Received: from b06cxnps4076.portsmouth.uk.ibm.com (9.149.109.198) by e06smtp04.uk.ibm.com (192.168.101.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Tue, 19 Jun 2018 06:04:49 +0100 Received: from d06av22.portsmouth.uk.ibm.com (d06av22.portsmouth.uk.ibm.com [9.149.105.58]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w5J54m8f33816748 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 19 Jun 2018 05:04:49 GMT Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1FACA4C044; Tue, 19 Jun 2018 05:55:50 +0100 (BST) Received: from d06av22.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E89B44C052; Tue, 19 Jun 2018 05:55:46 +0100 (BST) Received: from aksadiga.ibm (unknown [9.195.32.219]) by d06av22.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 19 Jun 2018 05:55:46 +0100 (BST) From: Akshay Adiga To: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-pm@vger.kernel.org Cc: rjw@rjwysocki.net, svaidy@linux.vnet.ibm.com, ego@linux.vnet.ibm.com, npiggin@gmail.com, mpe@ellerman.id.au, Akshay Adiga Subject: [PATCH 1/3] powernv/cpuidle: Parse dt idle properties into global structure Date: Tue, 19 Jun 2018 10:34:26 +0530 X-Mailer: git-send-email 2.5.5 In-Reply-To: <1529384668-27548-1-git-send-email-akshay.adiga@linux.vnet.ibm.com> References: <1529384668-27548-1-git-send-email-akshay.adiga@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18061905-0016-0000-0000-000001DD82BA X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18061905-0017-0000-0000-000032318B40 Message-Id: <1529384668-27548-2-git-send-email-akshay.adiga@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-06-19_02:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1805220000 definitions=main-1806190058 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Device-tree parsing happens in twice, once while deciding idle state to be used for hotplug and once during cpuidle init. Hence, parsing the device tree and caching it will reduce code duplication. Parsing code has been moved to pnv_parse_cpuidle_dt() from pnv_probe_idle_states(). Setting up things so that number of available idle states can be accessible to cpuidle-powernv driver. Hence adding nr_pnv_idle_states to track number of idle states. Signed-off-by: Akshay Adiga --- arch/powerpc/include/asm/cpuidle.h | 14 +++ arch/powerpc/platforms/powernv/idle.c | 197 ++++++++++++++++++++++++---------- 2 files changed, 152 insertions(+), 59 deletions(-) diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h index e210a83..55ee7e3 100644 --- a/arch/powerpc/include/asm/cpuidle.h +++ b/arch/powerpc/include/asm/cpuidle.h @@ -79,6 +79,20 @@ struct stop_sprs { u64 mmcra; }; +#define PNV_IDLE_NAME_LEN 16 +struct pnv_idle_states_t { + char name[PNV_IDLE_NAME_LEN]; + u32 latency_ns; + u32 residency_ns; + /* + * Register value/mask used to select different idle states. + * PMICR in POWER8 and PSSCR in POWER9 + */ + u64 pm_ctrl_reg_val; + u64 pm_ctrl_reg_mask; + u32 flags; +}; + extern u32 pnv_fastsleep_workaround_at_entry[]; extern u32 pnv_fastsleep_workaround_at_exit[]; diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 1c5d067..07be984 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -36,6 +36,8 @@ #define P9_STOP_SPR_PSSCR 855 static u32 supported_cpuidle_states; +struct pnv_idle_states_t *pnv_idle_states; +int nr_pnv_idle_states; /* * The default stop state that will be used by ppc_md.power_save @@ -625,45 +627,8 @@ int validate_psscr_val_mask(u64 *psscr_val, u64 *psscr_mask, u32 flags) static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, int dt_idle_states) { - u64 *psscr_val = NULL; - u64 *psscr_mask = NULL; - u32 *residency_ns = NULL; u64 max_residency_ns = 0; - int rc = 0, i; - - psscr_val = kcalloc(dt_idle_states, sizeof(*psscr_val), GFP_KERNEL); - psscr_mask = kcalloc(dt_idle_states, sizeof(*psscr_mask), GFP_KERNEL); - residency_ns = kcalloc(dt_idle_states, sizeof(*residency_ns), - GFP_KERNEL); - - if (!psscr_val || !psscr_mask || !residency_ns) { - rc = -1; - goto out; - } - - if (of_property_read_u64_array(np, - "ibm,cpu-idle-state-psscr", - psscr_val, dt_idle_states)) { - pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr in DT\n"); - rc = -1; - goto out; - } - - if (of_property_read_u64_array(np, - "ibm,cpu-idle-state-psscr-mask", - psscr_mask, dt_idle_states)) { - pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr-mask in DT\n"); - rc = -1; - goto out; - } - - if (of_property_read_u32_array(np, - "ibm,cpu-idle-state-residency-ns", - residency_ns, dt_idle_states)) { - pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-residency-ns in DT\n"); - rc = -1; - goto out; - } + int i; /* * Set pnv_first_deep_stop_state, pnv_deepest_stop_psscr_{val,mask}, @@ -681,31 +646,33 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, pnv_first_deep_stop_state = MAX_STOP_STATE; for (i = 0; i < dt_idle_states; i++) { int err; - u64 psscr_rl = psscr_val[i] & PSSCR_RL_MASK; + struct pnv_idle_states_t *state = &pnv_idle_states[i]; + u64 psscr_rl = state->pm_ctrl_reg_val & PSSCR_RL_MASK; - if ((flags[i] & OPAL_PM_LOSE_FULL_CONTEXT) && - (pnv_first_deep_stop_state > psscr_rl)) + if ((state->flags & OPAL_PM_LOSE_FULL_CONTEXT) && + (pnv_first_deep_stop_state > psscr_rl)) pnv_first_deep_stop_state = psscr_rl; - err = validate_psscr_val_mask(&psscr_val[i], &psscr_mask[i], - flags[i]); + err = validate_psscr_val_mask(&state->pm_ctrl_reg_val, + &state->pm_ctrl_reg_mask, + state->flags); if (err) { - report_invalid_psscr_val(psscr_val[i], err); + report_invalid_psscr_val(state->pm_ctrl_reg_val, err); continue; } - if (max_residency_ns < residency_ns[i]) { - max_residency_ns = residency_ns[i]; - pnv_deepest_stop_psscr_val = psscr_val[i]; - pnv_deepest_stop_psscr_mask = psscr_mask[i]; - pnv_deepest_stop_flag = flags[i]; + if (max_residency_ns < state->residency_ns) { + max_residency_ns = state->residency_ns; + pnv_deepest_stop_psscr_val = state->pm_ctrl_reg_val; + pnv_deepest_stop_psscr_mask = state->pm_ctrl_reg_mask; + pnv_deepest_stop_flag = state->flags; deepest_stop_found = true; } if (!default_stop_found && - (flags[i] & OPAL_PM_STOP_INST_FAST)) { - pnv_default_stop_val = psscr_val[i]; - pnv_default_stop_mask = psscr_mask[i]; + (state->flags & OPAL_PM_STOP_INST_FAST)) { + pnv_default_stop_val = state->pm_ctrl_reg_val; + pnv_default_stop_mask = state->pm_ctrl_reg_mask; default_stop_found = true; } } @@ -728,11 +695,8 @@ static int __init pnv_power9_idle_init(struct device_node *np, u32 *flags, pr_info("cpuidle-powernv: Requested Level (RL) value of first deep stop = 0x%llx\n", pnv_first_deep_stop_state); -out: - kfree(psscr_val); - kfree(psscr_mask); - kfree(residency_ns); - return rc; + + return 0; } /* @@ -776,14 +740,129 @@ static void __init pnv_probe_idle_states(void) out: kfree(flags); } -static int __init pnv_init_idle_states(void) + +/* + * This function is use to parse device-tree and populates all the information + * into pnv_idle_states structure. Also it sets up nr_pnv_idle_states and + * the number of cpuidle states discovered through device-tree. + */ + +static int pnv_parse_cpuidle_dt(void) { + struct device_node *np; + int nr_idle_states, i; + u32 *temp_u32; + u64 *temp_u64; + const char **temp_string; + + np = of_find_node_by_path("/ibm,opal/power-mgt"); + if (!np) { + pr_warn("opal: PowerMgmt Node not found\n"); + return -ENODEV; + } + nr_idle_states = of_property_count_u32_elems(np, + "ibm,cpu-idle-state-flags"); + + pnv_idle_states = kcalloc(nr_idle_states, sizeof(*pnv_idle_states), + GFP_KERNEL); + temp_u32 = kcalloc(nr_idle_states, sizeof(u32), GFP_KERNEL); + temp_u64 = kcalloc(nr_idle_states, sizeof(u64), GFP_KERNEL); + temp_string = kcalloc(nr_idle_states, sizeof(char *), GFP_KERNEL); + + /* Read flags */ + if (of_property_read_u32_array(np, + "ibm,cpu-idle-state-flags", temp_u32, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-flags in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].flags = temp_u32[i]; + /* Read latencies */ + if (of_property_read_u32_array(np, + "ibm,cpu-idle-state-latencies-ns", temp_u32, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].latency_ns = temp_u32[i]; + + /* Read residencies */ + if (of_property_read_u32_array(np, + "ibm,cpu-idle-state-residency-ns", temp_u32, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-latencies-ns in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].residency_ns = temp_u32[i]; + + /* For power9 */ + if (cpu_has_feature(CPU_FTR_ARCH_300)) { + /* Read pm_crtl_val */ + if (of_property_read_u64_array(np, + "ibm,cpu-idle-state-psscr", temp_u64, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].pm_ctrl_reg_val = temp_u64[i]; + + /* Read pm_crtl_mask */ + if (of_property_read_u64_array(np, + "ibm,cpu-idle-state-psscr-mask", temp_u64, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr-mask in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].pm_ctrl_reg_mask = temp_u64[i]; + } else { /* Power8 and Power7 */ + /* Read pm_crtl_val */ + if (of_property_read_u64_array(np, + "ibm,cpu-idle-state-pmicr", temp_u64, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].pm_ctrl_reg_val = temp_u64[i]; + + /* Read pm_crtl_mask */ + if (of_property_read_u64_array(np, + "ibm,cpu-idle-state-pmicr-mask", temp_u64, nr_idle_states)) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-psscr-mask in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + pnv_idle_states[i].pm_ctrl_reg_mask = temp_u64[i]; + + } + if (of_property_read_string_array(np, + "ibm,cpu-idle-state-names", temp_string, nr_idle_states) < 0) { + pr_warn("cpuidle-powernv: missing ibm,cpu-idle-state-names in DT\n"); + goto out; + } + for (i = 0; i < nr_idle_states; i++) + strncpy(pnv_idle_states[i].name, temp_string[i], + PNV_IDLE_NAME_LEN); + nr_pnv_idle_states = nr_idle_states; +out: + kfree(temp_u32); + kfree(temp_u64); + kfree(temp_string); + return 0; +} + +static int __init pnv_init_idle_states(void) +{ + int rc = 0; supported_cpuidle_states = 0; + /* In case we error out nr_pnv_idle_states will be zero */ + nr_pnv_idle_states = 0; if (cpuidle_disable != IDLE_NO_OVERRIDE) goto out; - + rc = pnv_parse_cpuidle_dt(); + if (rc) + return rc; pnv_probe_idle_states(); if (!(supported_cpuidle_states & OPAL_PM_SLEEP_ENABLED_ER1)) { -- 2.5.5