From patchwork Fri Mar 10 13:15:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tim Gardner X-Patchwork-Id: 737411 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3vfnp754lYz9s7q; Sat, 11 Mar 2017 00:16:15 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical-com.20150623.gappssmtp.com header.i=@canonical-com.20150623.gappssmtp.com header.b="j/gnE2Rd"; dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1cmKOx-0000Gt-Uf; Fri, 10 Mar 2017 13:16:11 +0000 Received: from mail-io0-f172.google.com ([209.85.223.172]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1cmKOn-0000Eu-Lq for kernel-team@lists.ubuntu.com; Fri, 10 Mar 2017 13:16:01 +0000 Received: by mail-io0-f172.google.com with SMTP id g6so48046989ioj.1 for ; Fri, 10 Mar 2017 05:16:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical-com.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=+sm4c8Ki+PC9q/PU4DmEaTOGExhAVSkx/nG/REmYQ+g=; b=j/gnE2Rd88obnvhVrKgU8fH3WBRli+J7+n5p18TZEkZeL5KIs7aLFo2JajoXZLHKuM 1+M9DdEf7Vg+KZU0Nr4qxsyU4r43xduRDG3rrY6iZkOPMc9t3paeVib/dtWlnqo+u4eY AYHv53Mt3q3po9egjA1mBhVpTv+SAE+ff76gRGISyJ/YZonSht/xemUInfy0p0pjwVQx FugRo06XXL7iSm3S9E+aLhc2W0BSPhjGkUY8XfDrWdT7J2jd5W5t3SKEgDsoEx5ND36f I+gmx/vU3IrDUFEED36i45Pz06bV4cK3Gn+F3Px5PgRvHL/agajlubDU2z6czv2ihU/o 8Kyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=+sm4c8Ki+PC9q/PU4DmEaTOGExhAVSkx/nG/REmYQ+g=; b=Vh5SnMGaxwPm59ZsA6cf4HCAJbt5aveoqpD7RtiyrLoVLcfW4+m+vcLjy0Gq4xWVAj I/puZ922Zr+BFQAbPnkPez9bD3OuUmvBIWPMA8PnJ6y5buVDIwZGrSRoLfW1JSGi8dPZ gNQ/qb9D9iN7BwwiWQA89ynyGXZX+YNjxtW4stOJwsbT53IEIO0omFiEmNcCGJGkG/Ty CcrU6jtK4GQphanMW9lDO/VwH9/HuWtpryVQbEGUPRxYn5J9FkM//xyQZj2SfOnb5T/a DhiOkVWzrt5cFQpvECKdlZD3A1fO+uDy+vekR+Lv+PS+gicCmkqas+ULpsVDup6Q779Y pFRA== X-Gm-Message-State: AMke39k6aGdOLiqjdth8Rw+C/ekoIc7/gTv09XAarXYymiEl7v1uwCopmA6dbfvJlUKAjHuo X-Received: by 10.107.180.145 with SMTP id d139mr16546524iof.101.1489151760286; Fri, 10 Mar 2017 05:16:00 -0800 (PST) Received: from localhost.localdomain (host-98-127-250-84.bln-mt.client.bresnan.net. [98.127.250.84]) by smtp.gmail.com with ESMTPSA id h12sm4348476iod.57.2017.03.10.05.15.59 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 10 Mar 2017 05:15:59 -0800 (PST) From: Tim Gardner To: kernel-team@lists.ubuntu.com Subject: [PATCH 3/6] cpuidle:powernv: Add helper function to populate powernv idle states. Date: Fri, 10 Mar 2017 06:15:47 -0700 Message-Id: <1489151750-6289-4-git-send-email-tim.gardner@canonical.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1489151750-6289-1-git-send-email-tim.gardner@canonical.com> References: <1489151750-6289-1-git-send-email-tim.gardner@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: "Gautham R. Shenoy" BugLink: http://bugs.launchpad.net/bugs/1666197 In the current code for powernv_add_idle_states, there is a lot of code duplication while initializing an idle state in powernv_states table. Add an inline helper function to populate the powernv_states[] table for a given idle state. Invoke this for populating the "Nap", "Fastsleep" and the stop states in powernv_add_idle_states. Cherry-picked from upstream commit 9e9fc6f00a54 ("cpuidle:powernv: Add helper function to populate powernv idle states.) Signed-off-by: Gautham R. Shenoy Acked-by: Balbir Singh Acked-by: Rafael J. Wysocki Signed-off-by: Michael Ellerman Signed-off-by: Tim Gardner --- drivers/cpuidle/cpuidle-powernv.c | 89 +++++++++++++++++++++++---------------- include/linux/cpuidle.h | 1 + 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index f7ca891..0a9d67c 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -20,6 +20,10 @@ #include #include +/* + * Expose only those Hardware idle states via the cpuidle framework + * that have latency value below POWERNV_THRESHOLD_LATENCY_NS. + */ #define POWERNV_THRESHOLD_LATENCY_NS 200000 struct cpuidle_driver powernv_idle_driver = { @@ -177,6 +181,24 @@ static int powernv_cpuidle_driver_init(void) return 0; } +static inline void add_powernv_state(int index, const char *name, + unsigned int flags, + int (*idle_fn)(struct cpuidle_device *, + struct cpuidle_driver *, + int), + unsigned int target_residency, + unsigned int exit_latency, + u64 psscr_val) +{ + strlcpy(powernv_states[index].name, name, CPUIDLE_NAME_LEN); + strlcpy(powernv_states[index].desc, name, CPUIDLE_NAME_LEN); + powernv_states[index].flags = flags; + powernv_states[index].target_residency = target_residency; + powernv_states[index].exit_latency = exit_latency; + powernv_states[index].enter = idle_fn; + stop_psscr_table[index] = psscr_val; +} + static int powernv_add_idle_states(void) { struct device_node *power_mgt; @@ -246,6 +268,7 @@ static int powernv_add_idle_states(void) "ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states); for (i = 0; i < dt_idle_states; i++) { + unsigned int exit_latency, target_residency; /* * If an idle state has exit latency beyond * POWERNV_THRESHOLD_LATENCY_NS then don't use it @@ -253,28 +276,33 @@ static int powernv_add_idle_states(void) */ if (latency_ns[i] > POWERNV_THRESHOLD_LATENCY_NS) continue; + /* + * Firmware passes residency and latency values in ns. + * cpuidle expects it in us. + */ + exit_latency = latency_ns[i] / 1000; + if (!rc) + target_residency = residency_ns[i] / 1000; + else + target_residency = 0; /* - * Cpuidle accepts exit_latency and target_residency in us. - * Use default target_residency values if f/w does not expose it. + * For nap and fastsleep, use default target_residency + * values if f/w does not expose it. */ if (flags[i] & OPAL_PM_NAP_ENABLED) { + if (!rc) + target_residency = 100; /* Add NAP state */ - strcpy(powernv_states[nr_idle_states].name, "Nap"); - strcpy(powernv_states[nr_idle_states].desc, "Nap"); - powernv_states[nr_idle_states].flags = 0; - powernv_states[nr_idle_states].target_residency = 100; - powernv_states[nr_idle_states].enter = nap_loop; + add_powernv_state(nr_idle_states, "Nap", + CPUIDLE_FLAG_NONE, nap_loop, + target_residency, exit_latency, 0); } else if ((flags[i] & OPAL_PM_STOP_INST_FAST) && !(flags[i] & OPAL_PM_TIMEBASE_STOP)) { - strncpy(powernv_states[nr_idle_states].name, - names[i], CPUIDLE_NAME_LEN); - strncpy(powernv_states[nr_idle_states].desc, - names[i], CPUIDLE_NAME_LEN); - powernv_states[nr_idle_states].flags = 0; - - powernv_states[nr_idle_states].enter = stop_loop; - stop_psscr_table[nr_idle_states] = psscr_val[i]; + add_powernv_state(nr_idle_states, names[i], + CPUIDLE_FLAG_NONE, stop_loop, + target_residency, exit_latency, + psscr_val[i]); } /* @@ -284,32 +312,21 @@ static int powernv_add_idle_states(void) #ifdef CONFIG_TICK_ONESHOT if (flags[i] & OPAL_PM_SLEEP_ENABLED || flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) { + if (!rc) + target_residency = 300000; /* Add FASTSLEEP state */ - strcpy(powernv_states[nr_idle_states].name, "FastSleep"); - strcpy(powernv_states[nr_idle_states].desc, "FastSleep"); - powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP; - powernv_states[nr_idle_states].target_residency = 300000; - powernv_states[nr_idle_states].enter = fastsleep_loop; + add_powernv_state(nr_idle_states, "FastSleep", + CPUIDLE_FLAG_TIMER_STOP, + fastsleep_loop, + target_residency, exit_latency, 0); } else if ((flags[i] & OPAL_PM_STOP_INST_DEEP) && (flags[i] & OPAL_PM_TIMEBASE_STOP)) { - strncpy(powernv_states[nr_idle_states].name, - names[i], CPUIDLE_NAME_LEN); - strncpy(powernv_states[nr_idle_states].desc, - names[i], CPUIDLE_NAME_LEN); - - powernv_states[nr_idle_states].flags = CPUIDLE_FLAG_TIMER_STOP; - powernv_states[nr_idle_states].enter = stop_loop; - stop_psscr_table[nr_idle_states] = psscr_val[i]; + add_powernv_state(nr_idle_states, names[i], + CPUIDLE_FLAG_TIMER_STOP, stop_loop, + target_residency, exit_latency, + psscr_val[i]); } #endif - powernv_states[nr_idle_states].exit_latency = - ((unsigned int)latency_ns[i]) / 1000; - - if (!rc) { - powernv_states[nr_idle_states].target_residency = - ((unsigned int)residency_ns[i]) / 1000; - } - nr_idle_states++; } out: diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index bb31373..c4e10f8 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -62,6 +62,7 @@ struct cpuidle_state { }; /* Idle State Flags */ +#define CPUIDLE_FLAG_NONE (0x00) #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */ #define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */