From patchwork Tue Mar 3 20:35:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 184153 Delivered-To: patches@linaro.org Received: by 2002:a92:1f12:0:0:0:0:0 with SMTP id i18csp4079699ile; Tue, 3 Mar 2020 12:36:24 -0800 (PST) X-Received: by 2002:a05:651c:8f:: with SMTP id 15mr3401095ljq.109.1583267784009; Tue, 03 Mar 2020 12:36:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1583267784; cv=none; d=google.com; s=arc-20160816; b=kxqEjdQx9bI4yGdGJ9GAR/aTP6fe95fJWGmrUQfNRQG2aRvFT0c8dyt1mWZJJAn+Y4 +wSqJxXFCEK0d1Pz8JcQz517lxrmAwmjzlYeALs3lLz4ptMPTMhsdn3grLL7dIya6CAH 4EbBD6PQzLUdySkL5/B1ytz38MpIC2GEbEG7YCgkGUsn76hKrT43LzI1OK9xccRD1Wmg LrHE6YIjmbdG0eUQthOw/fY7IxttUwdTbXLFS0/2yBip/lKaKwQOuMML5iCrhf6qhxVG +dKkxqvOXSv7uyZNx4JkPLBtde/ImrtiT4l4EMkhHDW3H27THiNSDIegMwHoARUXzedn gXJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=7PinDvT3vaZ+q6CFmJPa7CF8xALNvmK8t7KJc3O4ca4=; b=UPS/26Uy6L1ju+wFHB9LL9RuLSaaqtfcW0YNmQtibf8p1kuIXDMKSQQScgd0M99FCu uEZjSl8SD+N+bb+FI82HLGHkzASzKZcUPksMcy6f1WOeNQMFXm1b20LWIFok0s7RnKgG 9dRLr0h/2828ipuah0HtEch1gSHTPqF9iOLpZFQXAZ9MsZEV5mzFwzcjmnRSlX6klBtn 27hshlGTleQz2HAOj0oCN1fs746js7J2EXPVl8YoOrDy7SOQEEBX0qVi37Bac8k83xDk m3+6GZjHbE3NQZmMXG8VlJg5Y/+RHe6nv2Hfzyctjqyzl5XqWlDa8Rm+zeq9Sexd3wlH uH8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Fq/sp9HG"; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id v16sor8929277ljc.29.2020.03.03.12.36.23 for (Google Transport Security); Tue, 03 Mar 2020 12:36:23 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="Fq/sp9HG"; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 209.85.220.65 as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7PinDvT3vaZ+q6CFmJPa7CF8xALNvmK8t7KJc3O4ca4=; b=Fq/sp9HG47oR3mlEYYx860yS6y7Je9qVstoba2QSh8hz5l2dwmaB6g1W8Zk+yDHKzo 1qmVSw2rUW2hmBPDL+w2zNpuAAZ8uwSywAn3K6o3SPEznX1iHxralqz2M+rB5FnYlN7/ +OIDlP1SWny1pE5E8KQrWDkImEI/q7miYGDO0zz2JYVBbjJkoruHX5FRHM8RdYu5jFY7 nsX1gCXhQewE0swh1cr5Sk+B4srQFVwSeBgahNvVvvVxuda36+DCxOVHHc0cCgdwVr8c 0C3XZJEUdNwCWDAbp1hj6NVeL4kjQ62RTtg0zmYRmxAOucjwocHHMxEkQOT0Th0CTJgy XkHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7PinDvT3vaZ+q6CFmJPa7CF8xALNvmK8t7KJc3O4ca4=; b=EmXmwFORVhbSi+UkjZmrjW5AsgZB0ftKDPgC5xMWsViXEbCG4cFEdJeHZ5hzAqzMpq Ol5uvEW0fi8voCV/2NakrK4KylzNWMYgoTDdtcT54MY5y9lsF3KvVUdqtnMNs8gDMqHU rDz0g/WPIdRjfaPtDLJFAla+Sjd14M22J3Co7GhDmsqQ8u25qBOD8yHy7EUojFN4xUxe PQ1jgjxVntxHbVB33vTeTC8Y3/qCwQvtuVNsGAFn6FVMZfw5BqcduMjFboSM+MOLsfTO Kd56JKekY8+MH/Xkl/mM1iE0dj5K9N8L8Mg8gRrzz3hvPCgZykHe9H8G0Pposhu0xWAN RfLA== X-Gm-Message-State: ANhLgQ2M8TTNdhR06GBBKeGbYn39NVNFKIb0yH1tZc0SLwmkfLpDFKF9 N2FnZucuzuQ6Ud3YoOMOOTx35l3+ X-Google-Smtp-Source: ADFU+vt6uuUl+iUGLAMABwb54VVP9bXXM8EH32uRgtLikEC1RAhEd/mfOswBvrjjq1aT9X1OAg20ig== X-Received: by 2002:a2e:9e4c:: with SMTP id g12mr3324423ljk.15.1583267783555; Tue, 03 Mar 2020 12:36:23 -0800 (PST) Return-Path: Received: from localhost.localdomain (h-158-174-22-210.NA.cust.bahnhof.se. [158.174.22.210]) by smtp.gmail.com with ESMTPSA id t195sm1339532lff.0.2020.03.03.12.36.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2020 12:36:23 -0800 (PST) From: Ulf Hansson To: Sudeep Holla , Lorenzo Pieralisi , linux-pm@vger.kernel.org Cc: "Rafael J . Wysocki" , Daniel Lezcano , Lina Iyer , Vincent Guittot , Stephen Boyd , Bjorn Andersson , Benjamin Gaignard , Ulf Hansson , linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 4/4] cpuidle: psci: Allow WFI to be the only state for the hierarchical topology Date: Tue, 3 Mar 2020 21:35:59 +0100 Message-Id: <20200303203559.23995-5-ulf.hansson@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200303203559.23995-1-ulf.hansson@linaro.org> References: <20200303203559.23995-1-ulf.hansson@linaro.org> MIME-Version: 1.0 It's possible that only the WFI state is supported for the CPU, while also a shared idle state exists for a group of CPUs. When the hierarchical topology is used, the shared idle state may not be compatible with arm,idle-state, rather with "domain-idle-state", which makes dt_init_idle_driver() to return zero. This leads to that the cpuidle-psci driver bails out during initialization, avoiding to register a cpuidle driver and instead relies on the default architectural back-end (called via cpu_do_idle()). In other words, the shared idle state becomes unused. Let's fix this behaviour, by allowing the dt_init_idle_driver() to return 0 and then continue with the initialization. If it turns out that the hierarchical topology is used and we have some additional states to manage, then continue with the cpuidle driver registration, otherwise bail out as before. Reported-by: Benjamin Gaignard Fixes: a65a397f2451 ("cpuidle: psci: Add support for PM domains by using genpd") Signed-off-by: Ulf Hansson --- Changes in v2: - Convert the error code returned from psci_cpu_suspend_enter() into an expected error code by cpuidle core. --- drivers/cpuidle/cpuidle-psci.c | 48 +++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 18 deletions(-) -- 2.20.1 diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index bae9140a65a5..ae0fabec2742 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -56,16 +56,19 @@ static int psci_enter_domain_idle_state(struct cpuidle_device *dev, u32 *states = data->psci_states; struct device *pd_dev = data->dev; u32 state; - int ret; + int ret = 0; /* Do runtime PM to manage a hierarchical CPU toplogy. */ pm_runtime_put_sync_suspend(pd_dev); state = psci_get_domain_state(); - if (!state) + if (!state && states) state = states[idx]; - ret = psci_enter_state(idx, state); + if (state) + ret = psci_cpu_suspend_enter(state) ? -1 : idx; + else + cpu_do_idle(); pm_runtime_get_sync(pd_dev); @@ -180,7 +183,7 @@ static int __init psci_dt_cpu_init_topology(struct cpuidle_driver *drv, drv->states[state_count - 1].enter = psci_enter_domain_idle_state; psci_cpuidle_use_cpuhp = true; - return 0; + return 1; } static int __init psci_dt_cpu_init_idle(struct cpuidle_driver *drv, @@ -192,6 +195,13 @@ static int __init psci_dt_cpu_init_idle(struct cpuidle_driver *drv, struct device_node *state_node; struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu); + /* + * Special case when WFI is the only state, as we may still need to + * initialize data, if the hierarchical topology is used. + */ + if (!state_count) + return psci_dt_cpu_init_topology(drv, data, 1, cpu); + state_count++; /* Add WFI state too */ psci_states = kcalloc(state_count, sizeof(*psci_states), GFP_KERNEL); if (!psci_states) @@ -223,7 +233,7 @@ static int __init psci_dt_cpu_init_idle(struct cpuidle_driver *drv, /* Idle states parsed correctly, store them in the per-cpu struct. */ data->psci_states = psci_states; - return 0; + return state_count; free_mem: kfree(psci_states); @@ -282,33 +292,35 @@ static int __init psci_idle_init_cpu(int cpu) return -ENOMEM; drv->cpumask = (struct cpumask *)cpumask_of(cpu); + drv->state_count = 1; /* - * Initialize idle states data, starting at index 1, since - * by default idle state 0 is the quiescent state reached - * by the cpu by executing the wfi instruction. - * - * If no DT idle states are detected (ret == 0) let the driver - * initialization fail accordingly since there is no reason to - * initialize the idle driver if only wfi is supported, the - * default archictectural back-end already executes wfi - * on idle entry. + * Initialize idle states data, starting at index 1, since by default + * idle state 0 is the quiescent state reached by the cpu by executing + * the wfi instruction. If no DT idle states are detected (ret == 0), + * we may still use the hierarchical topology. */ ret = dt_init_idle_driver(drv, psci_idle_state_match, 1); - if (ret <= 0) { - ret = ret ? : -ENODEV; + if (ret < 0) goto out_kfree_drv; - } /* * Initialize PSCI idle states. */ ret = psci_cpu_init_idle(drv, cpu, ret); - if (ret) { + if (ret < 0) { pr_err("CPU %d failed to PSCI idle\n", cpu); goto out_kfree_drv; } + /* If there are no idle states to manage, but the wfi state and we also + * don't use the hierarchical topology, let the driver initialization + * fail. Instead, let's rely on the default architectural back-end to + * execute wfi on idle entry. + */ + if (!ret) + goto out_kfree_drv; + ret = cpuidle_register(drv, NULL); if (ret) goto out_kfree_drv;