From patchwork Mon Oct 30 10:24:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 159672 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp2109095vqb; Mon, 30 Oct 2023 03:35:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFvNp3/njFX0cBYaIxWiVVPArerPXlfSMkWCSamMDzuOMgffmn2GXiXe3qPBLP0NbTk4gEG X-Received: by 2002:a9d:7993:0:b0:6cd:6727:224e with SMTP id h19-20020a9d7993000000b006cd6727224emr8051570otm.20.1698662154424; Mon, 30 Oct 2023 03:35:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698662154; cv=none; d=google.com; s=arc-20160816; b=jStLaESBdeBTnxjSH1SKVBP0gWmeEJ41z5zmdIeL3J476gt6t3pv8gzEMfGQfXa+qx B5aHu6jwGcFv8Wr6nXhACN0x90gxxBxyF/wrSrBSUGes4ZzdDqscpBR9iAoY0WiVVS6E VKamM4BS3rWXBry07o9K5Jh6PedvzA/CX/F/eXKQXvIjGxBs3kKMfM96+acVC6+VUclM SHmH2MB/yFCl9wXJokaaAMLAhuFGW9Ul+Q4IdlOZ5dnhUrVYJGudi97X2Uqip5URM6RD WeFyHKdlGrIpjViEsLwHHCUyTI7RTVdiw7pcAqqLbBT3lZX8s3XvAVMbOK+3ZYR3V4I2 qI6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=fcED4WjT67F9vTej3BnZaz4/stcnOOOgNE1CTcd6l/E=; fh=Un7JazYSm8/kcjPcd/W8jKETxQG7VjjVg/N0ak4gg3I=; b=0JWfpS0/IK9kLgI4SFrwasA4z1GC/0EcvNAwgnCEqqJARKDBLG6lVTFP0H/wkGHL4B /DzSQloupCw8H43/LexSRHma5D2fwGkOxsPTO1+NQrpnZm2DZ6mEgaDJ6kFSpiYQf1jr eYnc/FYTrOJ37OfrVyi02QaC/tsly2FQY6yWRgutCI1uX/vjSG6ZUXv5oTD9WpZJkOQp rHl2M3Yee2Qwi1baSTDk0fD0mp/aO8qK3b7oajG0Zi+hOu8l3g2f6qjuyG7kakeoAGI9 Z74+lVf0GUyiVy3FoV8QD5GGBHXzJ1aasjCB00xa01vynBru42AZ6zG+NirStNgR5HN0 c+rA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Itlp8lMv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from howler.vger.email (howler.vger.email. [23.128.96.34]) by mx.google.com with ESMTPS id bx39-20020a056a02052700b005893a7c438esi4891484pgb.689.2023.10.30.03.35.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Oct 2023 03:35:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) client-ip=23.128.96.34; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Itlp8lMv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.34 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 1B6BF807C864; Mon, 30 Oct 2023 03:35:11 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232783AbjJ3Kei (ORCPT + 31 others); Mon, 30 Oct 2023 06:34:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233380AbjJ3KeA (ORCPT ); Mon, 30 Oct 2023 06:34:00 -0400 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB21E1BF8 for ; Mon, 30 Oct 2023 03:24:27 -0700 (PDT) Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-6bd96cfb99cso3567743b3a.2 for ; Mon, 30 Oct 2023 03:24:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1698661467; x=1699266267; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fcED4WjT67F9vTej3BnZaz4/stcnOOOgNE1CTcd6l/E=; b=Itlp8lMvy58UID6ioZWhAjfk515YBZ9LFmvOBkdL2zN7Jm2YaSWVR01ZEbfPBUVxTq 0hDMWVWgzUY1XNkEKdLRMumPtPgcfzdNW/8+omNFUG6TL8kXeMgJTFA5IKV0lbL4ipxL oTOsmdmDBo19hUJ9U1nbpT2nwKrdIPe1o6V8M9cjXgVyRz6kUo3QzHsgwXBNBb3aXTtu AaWOMsKNnMuXwppR/cLUMrEEDJ15Ke7fYL2h/e03sRY/nvVIP1Mg0DDc6xZO1YKQs7Lb 5/V8Jy35sN8X+5tHRrnamvz6LdAO2stqVNlIl/awFYZArmmS+nxa35ML0gPiRbrlwX2l MXbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698661467; x=1699266267; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fcED4WjT67F9vTej3BnZaz4/stcnOOOgNE1CTcd6l/E=; b=G1fIzhJp4PyrToZ9YGYW6+cNxXXuOO3FkfiWTjmiwd4JHe/IPQPovF2+MoFM/YyCMK xatAg/0zzMuOx9xPUkbwn5xYvI6Fz/trp7ZPxP5gLUzYnXyi37yLvUdLHpQ6QtS/oVmI ymW5Dy1I6ClxD9ErhFNynv9a94IxMY2uLehPIxZscENQjk3yh9AlqtThWaMyHftUDPcb AGPbVIZrJ23/NfWXchd8hvfolIoER+58YBkHg1gj7LPNVy71yBl3xWQLXekR8wFBPH/m iFl/83G8ymIKXNZ6A6VOiWq+ug4kEPa9zAzgU2uU11Syupgm2LR5yHlHIu5djnIle+SX G9Ew== X-Gm-Message-State: AOJu0YxuGL6TKb5crlq/MXira4TpQdIMqHohYcakVbKjbGX1MM5XPA6L f76V68IfBT9rf37jAxj9mMoDnWBcDYkf45Epv8M= X-Received: by 2002:a05:6a00:21d0:b0:68e:2f6e:b4c0 with SMTP id t16-20020a056a0021d000b0068e2f6eb4c0mr7744981pfj.28.1698661466983; Mon, 30 Oct 2023 03:24:26 -0700 (PDT) Received: from localhost ([122.172.80.14]) by smtp.gmail.com with ESMTPSA id a18-20020aa78652000000b006be484e5b9bsm5600469pfo.58.2023.10.30.03.24.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Oct 2023 03:24:26 -0700 (PDT) From: Viresh Kumar To: Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Ulf Hansson , Stephan Gerhold , Konrad Dybcio , Manivannan Sadhasivam , linux-kernel@vger.kernel.org Subject: [PATCH V2 1/3] OPP: Level zero is valid Date: Mon, 30 Oct 2023 15:54:15 +0530 Message-Id: <36de122e568dcba371d3581e5f936243b405a874.1698661048.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Mon, 30 Oct 2023 03:35:11 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781176367205628540 X-GMAIL-MSGID: 1781176367205628540 The level zero can be used by some OPPs to drop performance state vote for the device. It is perfectly fine to allow the same. _set_opp_level() considers it as an invalid value currently and returns early. In order to support this properly, initialize the level field with U32_MAX, which denotes unused level field. Reported-by: Stephan Gerhold Signed-off-by: Viresh Kumar Reviewed-by: Ulf Hansson --- drivers/opp/core.c | 24 ++++++++++++++++++++---- drivers/opp/of.c | 8 +++++++- include/linux/pm_opp.h | 5 ++++- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 84f345c69ea5..f2e2aa07b431 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -201,7 +201,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq_indexed); * @opp: opp for which level value has to be returned for * * Return: level read from device tree corresponding to the opp, else - * return 0. + * return U32_MAX. */ unsigned int dev_pm_opp_get_level(struct dev_pm_opp *opp) { @@ -221,7 +221,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_level); * @index: index of the required opp * * Return: performance state read from device tree corresponding to the - * required opp, else return 0. + * required opp, else return U32_MAX. */ unsigned int dev_pm_opp_get_required_pstate(struct dev_pm_opp *opp, unsigned int index) @@ -808,6 +808,14 @@ struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, struct dev_pm_opp *opp; opp = _find_key_ceil(dev, &temp, 0, true, _read_level, NULL); + + /* False match */ + if (temp == OPP_LEVEL_UNSET) { + dev_err(dev, "%s: OPP levels aren't available\n", __func__); + dev_pm_opp_put(opp); + return ERR_PTR(-ENODEV); + } + *level = temp; return opp; } @@ -1049,12 +1057,18 @@ static int _set_opp_bw(const struct opp_table *opp_table, static int _set_performance_state(struct device *dev, struct device *pd_dev, struct dev_pm_opp *opp, int i) { - unsigned int pstate = likely(opp) ? opp->required_opps[i]->level: 0; + unsigned int pstate = 0; int ret; if (!pd_dev) return 0; + if (likely(opp)) { + pstate = opp->required_opps[i]->level; + if (pstate == OPP_LEVEL_UNSET) + return 0; + } + ret = dev_pm_domain_set_performance_state(pd_dev, pstate); if (ret) { dev_err(dev, "Failed to set performance state of %s: %d (%d)\n", @@ -1135,7 +1149,7 @@ static int _set_opp_level(struct device *dev, struct opp_table *opp_table, int ret = 0; if (opp) { - if (!opp->level) + if (opp->level == OPP_LEVEL_UNSET) return 0; level = opp->level; @@ -1867,6 +1881,8 @@ struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table) INIT_LIST_HEAD(&opp->node); + opp->level = OPP_LEVEL_UNSET; + return opp; } diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 81fa27599d58..85fad7ca0007 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -1393,8 +1393,14 @@ int of_get_required_opp_performance_state(struct device_node *np, int index) opp = _find_opp_of_np(opp_table, required_np); if (opp) { - pstate = opp->level; + if (opp->level == OPP_LEVEL_UNSET) { + pr_err("%s: OPP levels aren't available for %pOF\n", + __func__, np); + } else { + pstate = opp->level; + } dev_pm_opp_put(opp); + } dev_pm_opp_put_opp_table(opp_table); diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index ccd97bcef269..af53101a1383 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -92,9 +92,12 @@ struct dev_pm_opp_config { struct device ***virt_devs; }; +#define OPP_LEVEL_UNSET U32_MAX + /** * struct dev_pm_opp_data - The data to use to initialize an OPP. - * @level: The performance level for the OPP. + * @level: The performance level for the OPP. Set level to OPP_LEVEL_UNSET if + * level field isn't used. * @freq: The clock rate in Hz for the OPP. * @u_volt: The voltage in uV for the OPP. */ From patchwork Mon Oct 30 10:24:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 159669 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp2108695vqb; Mon, 30 Oct 2023 03:35:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFG+lDT/5ejSmHyPaIWOOv9Qb2q4EO3zDWef9qwsJ5CnFr3A1v8bpKzXC61Cwk5lKQQp9D9 X-Received: by 2002:a17:90b:3101:b0:27d:661f:59ac with SMTP id gc1-20020a17090b310100b0027d661f59acmr6290604pjb.38.1698662101093; Mon, 30 Oct 2023 03:35:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698662101; cv=none; d=google.com; s=arc-20160816; b=V/oAk8Rw5V90iHhkFmON7MSFfqZSG0UlnmsByb2aEKKTGYtQbaVivNWMnjqaaXTFrk H38weoQx2YDxRRBre5oQJfe6PwjBvAIyxBkOee1Yj2oZsHSvymnEUIYCWcCg0Vlf1fmd 7ni6uV9oVYQ1UelM4Gfb032Ol9k9M6gOAb9I/LGXLDj9NE6RGwq/dCELIvYl8xAB1ZGY ZhAIaHF9oAIwPGZDY1AbfFFK3wNu5zSxWZ6zZxd73NAYZedKhIilI0NqHxB2epIDOb80 sN1HXSzZ35dYt0tci5wMOwNt3iF/aEjSVeEk5HVkGvpC+DrvuI1ArUbvYfu/2PowXg7l s79w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=RtcQW3aXfAlTqsT2Zd28zglQGGMRvlM92lJnVAtaLXI=; fh=lVFod2Nh/bVLd9f3LnZD5svEoMpRA0jQsUMvfqIGMU8=; b=NSzAvCmbR1Jc/oKWIK5qoTQyFHxhLsd4kncj7o0dus6/dv1rBYT5qJz8AeNY4Q26sN ZvsGMIaQhuaSNI/fioukLcaGHBmytOAI0y4MBbYRE+TI4HwnIw8uisgh1w+vEoNKuGep TF32+IDebaRJbts8VJnWXMFft9dpdqABGsu0fDrVOOvlkgw++lumE5H5UIUWX8GVSjof AEybR1bvEBWYhdEtLZA5Ik+BQucxYJZn9+THayn3ptvrGlWXj7y078XeTdwsLoj73TN1 PXr4IuYoeCak+vf9Ik00OWFs6OK13MU1AfLLUUQAel3qDbno6QH1dAHLP7t9/P+x8rvb lvRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bCBs+dxR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id y13-20020a17090aca8d00b0027d1aed872dsi4698720pjt.95.2023.10.30.03.35.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Oct 2023 03:35:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=bCBs+dxR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id A7BED80AD098; Mon, 30 Oct 2023 03:34:48 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232535AbjJ3KeZ (ORCPT + 31 others); Mon, 30 Oct 2023 06:34:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45496 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232929AbjJ3Kdq (ORCPT ); Mon, 30 Oct 2023 06:33:46 -0400 Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3832D1FFF for ; Mon, 30 Oct 2023 03:24:31 -0700 (PDT) Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1c9e072472bso27963925ad.2 for ; Mon, 30 Oct 2023 03:24:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1698661470; x=1699266270; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RtcQW3aXfAlTqsT2Zd28zglQGGMRvlM92lJnVAtaLXI=; b=bCBs+dxR5upVHY3kIoBkFu6WzFKGSi5xa3qGQQdGMTMPoFMjzKPlRT37J3VLfAnlvz zwy8r6PAuZyI+f4/4N7Ni02ImjLdZppWh2gS5RKbx0dFk1siENju9669EGKIyKK6Grkh C9R1wpl2JGyhIBn0Htp10KZbrkHJqeX8J1awpCOWmR+OjP3TmaV5DqCV+cnSNEF+GhEy 6npFGPJ9Vd2lqBhK2BD9te1Eay//gq6YbWABcBg1S/UB4W6lPQQW5/+fXl/lCWVflzb+ oVzuXXA7aO78rtrOV3gLFQvdE1XQEjJ9hfL2Hca7UpzCt4ovlFKn/jt5weQf5Q6vVJMa RGcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698661470; x=1699266270; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RtcQW3aXfAlTqsT2Zd28zglQGGMRvlM92lJnVAtaLXI=; b=i/X2H8H99186g4eunr+WJCrH1Kj43unVNXyo277TdqAYFN81p6YxSHG2dOM1MamgWR uqdGOvbmWb2PW1/OstYp115TcHRGFgy3HGcd7rXuvMsXelU/9DNlN9sfAKhy7MZIg7Rp XxbOVjG/HwYGn5cx+KLP6OcTeS26fDG0sJjMRk2Oxrxxsp4ILij9MQJ1plj45mdv83r+ AvM3UypYiYEcNpmlzbP6MQ2bxOsrzsDIR5OyX3P7TjIjKUYhUHWb35EBtPGJcR0K5aTq 1X4/SVP9R7nwoBVl23L2Sx+D/xNWvrTLeNF6u4lraiWhKlA9H+HLTTCxoiL6Y5yDFk3I nIBQ== X-Gm-Message-State: AOJu0Yw8ekvCLvZcjxo5UGO1o7/L4HFpQ5m8O3OKKESlxvs4s70Oeb4o vbB8GPptsZk6grZ9vchki8b1GA== X-Received: by 2002:a17:902:e0c5:b0:1ca:8b90:1cbd with SMTP id e5-20020a170902e0c500b001ca8b901cbdmr6303726pla.0.1698661470519; Mon, 30 Oct 2023 03:24:30 -0700 (PDT) Received: from localhost ([122.172.80.14]) by smtp.gmail.com with ESMTPSA id ix9-20020a170902f80900b001cc1dff5b86sm5919271plb.244.2023.10.30.03.24.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Oct 2023 03:24:30 -0700 (PDT) From: Viresh Kumar To: Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , Ulf Hansson , Stephan Gerhold , Konrad Dybcio , Manivannan Sadhasivam , linux-kernel@vger.kernel.org Subject: [PATCH V2 2/3] OPP: Use _set_opp_level() for single genpd case Date: Mon, 30 Oct 2023 15:54:16 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Mon, 30 Oct 2023 03:34:48 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781176311330957162 X-GMAIL-MSGID: 1781176311330957162 There are two genpd (as required-opp) cases that we need to handle, devices with a single genpd and ones with multiple genpds. The multiple genpds case is clear, where the OPP core calls dev_pm_domain_attach_by_name() for them and uses the virtual devices returned by this helper to call dev_pm_domain_set_performance_state() later to change the performance state. The single genpd case however requires special handling as we need to use the same `dev` structure (instead of a virtual one provided by genpd core) for setting the performance state via dev_pm_domain_set_performance_state(). As we move towards more generic code to take care of the required OPPs, where we will recursively call dev_pm_opp_set_opp() for all the required OPPs, the above special case becomes a problem. Eventually we want to handle all performance state changes via _set_opp_level(), so lets move the single genpd case to that right away. Signed-off-by: Viresh Kumar Reviewed-by: Ulf Hansson --- drivers/opp/core.c | 6 ++++-- drivers/opp/of.c | 25 ++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index f2e2aa07b431..aeb216f7e978 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1088,10 +1088,12 @@ static int _opp_set_required_opps_generic(struct device *dev, static int _opp_set_required_opps_genpd(struct device *dev, struct opp_table *opp_table, struct dev_pm_opp *opp, bool scaling_down) { - struct device **genpd_virt_devs = - opp_table->genpd_virt_devs ? opp_table->genpd_virt_devs : &dev; + struct device **genpd_virt_devs = opp_table->genpd_virt_devs; int index, target, delta, ret; + if (!genpd_virt_devs) + return 0; + /* Scaling up? Set required OPPs in normal order, else reverse */ if (!scaling_down) { index = 0; diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 85fad7ca0007..4b7191440bdf 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -296,7 +296,7 @@ void _of_clear_opp(struct opp_table *opp_table, struct dev_pm_opp *opp) of_node_put(opp->np); } -static int _link_required_opps(struct dev_pm_opp *opp, +static int _link_required_opps(struct dev_pm_opp *opp, struct opp_table *opp_table, struct opp_table *required_table, int index) { struct device_node *np; @@ -314,6 +314,25 @@ static int _link_required_opps(struct dev_pm_opp *opp, return -ENODEV; } + /* + * There are two genpd (as required-opp) cases that we need to handle, + * devices with a single genpd and ones with multiple genpds. + * + * The single genpd case requires special handling as we need to use the + * same `dev` structure (instead of a virtual one provided by genpd + * core) for setting the performance state. Lets treat this as a case + * where the OPP's level is directly available without required genpd + * link in the DT. + * + * Just update the `level` with the right value, which + * dev_pm_opp_set_opp() will take care of in the normal path itself. + */ + if (required_table->is_genpd && opp_table->required_opp_count == 1 && + !opp_table->genpd_virt_devs) { + if (!WARN_ON(opp->level != OPP_LEVEL_UNSET)) + opp->level = opp->required_opps[0]->level; + } + return 0; } @@ -338,7 +357,7 @@ static int _of_opp_alloc_required_opps(struct opp_table *opp_table, if (IS_ERR_OR_NULL(required_table)) continue; - ret = _link_required_opps(opp, required_table, i); + ret = _link_required_opps(opp, opp_table, required_table, i); if (ret) goto free_required_opps; } @@ -359,7 +378,7 @@ static int lazy_link_required_opps(struct opp_table *opp_table, int ret; list_for_each_entry(opp, &opp_table->opp_list, node) { - ret = _link_required_opps(opp, new_table, index); + ret = _link_required_opps(opp, opp_table, new_table, index); if (ret) return ret; } From patchwork Mon Oct 30 10:24:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 159671 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:d641:0:b0:403:3b70:6f57 with SMTP id cy1csp2109003vqb; Mon, 30 Oct 2023 03:35:43 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHia8k5v+80T2GqBt9HXSdF5YikZ13sR8e45A3cjZLZiG6SKzt952egmvvdo4mitaL4dagm X-Received: by 2002:a05:6358:72a4:b0:168:e95c:88b8 with SMTP id w36-20020a05635872a400b00168e95c88b8mr8354739rwf.12.1698662142742; Mon, 30 Oct 2023 03:35:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698662142; cv=none; d=google.com; s=arc-20160816; b=lpk4VERaU/YeYyY64lQUTYq0V5MbXNxzxGFt5c8ove65EPN0i4rzC+Kev+oQKTDS6k zAgh7nFTkl6udmNhSEVrkctc9mRo/G44BRKb1UA15rsVS6fttPoaeiiXix62F2BzpQ08 HYQHjfk5uyW7YnbHKD8Jz4ckn8CZmZXgUa26Nh3Ktdsn4Wr7uzpluiNRnJ+FUSKZk1TP 60O+Bvyl0Cl2JtKbCqT29vD1LPdtJL1FEDSVY02fpZjmUcWHD6NYcChjQHPF+EnMeBt4 SokQraD3taylpHKd3vdrauvTSuHiSl2JvUB4J2aNwXzaold+jDkf4FngZiNyaQY0ZlJ+ iOAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=XMQpfaIN/InMDdlUgLVw00qMYeBzvuSBSwDJAWk5R1M=; fh=Un7JazYSm8/kcjPcd/W8jKETxQG7VjjVg/N0ak4gg3I=; b=ISTm+N2CjdlUmRW2jSO7h0M75BOz3CpVf8oZjpNo/V/jpNqoUGzC+dveQxIfb96mmw Fq97iiOkcLqckE32AuvtAsjENpuYyaXBYYv5qoC1bUJr8JCMVZGNbtEb/NcY07hzn3hv r1xu/S7DgS2sIR7gAzORAojPgs3NX/n2YjUAdgUeq85VCJ3K6xINrIVwOr+wIFvm9e3s MIMXXbe/Md4x/0QZUkXrF0d1RaSLwwRxvaWuAVVDd1H2wLAH7r1cTHKUqchri5foyviz Z0TeAyv/vTusDPgYxF+cF1nBe8QSlNzqUwttfMDs52w6BWvv8haY7an0Oe0aaKQq6qvC gh0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=oCUeA4Km; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from fry.vger.email (fry.vger.email. [2620:137:e000::3:8]) by mx.google.com with ESMTPS id h71-20020a63834a000000b00565f24af893si4778525pge.22.2023.10.30.03.35.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Oct 2023 03:35:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) client-ip=2620:137:e000::3:8; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=oCUeA4Km; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:8 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by fry.vger.email (Postfix) with ESMTP id A2D328075166; Mon, 30 Oct 2023 03:35:13 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at fry.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232739AbjJ3Kee (ORCPT + 31 others); Mon, 30 Oct 2023 06:34:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232959AbjJ3Kdr (ORCPT ); Mon, 30 Oct 2023 06:33:47 -0400 Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 310A4268C for ; Mon, 30 Oct 2023 03:24:35 -0700 (PDT) Received: by mail-pf1-x434.google.com with SMTP id d2e1a72fcca58-6b2018a11efso4261015b3a.0 for ; Mon, 30 Oct 2023 03:24:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1698661474; x=1699266274; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XMQpfaIN/InMDdlUgLVw00qMYeBzvuSBSwDJAWk5R1M=; b=oCUeA4KmBkrswknc6d17Clp/+tyKG0EstfVXthyYPjpZi8QT1Jujy3XSVqhobFxUFi qgE+lNUbZbU1Atyz4AoQHob70M6gzP3xwkDlIX2H0SBUnMYM50tMW82kRsA5mIah5DBv xX/4v8UsA5KaUvaMh8/gwe43lfXRKA8SXfWizrFLQKqyywp4K0t+bHxrxAGzWkIqgswm IwNuBgxMCYpsAkGbKJQokFq5J4d1gYDpUCeOigFklGwIqB2JhvT2cJGF9+AlOTf8xpiF yf8oGw+4Gui4wX5+q/1MVP/zlRoeDVPx5tOewG0xOBlR0++hwWWeFwVf7xov3R3x0j2z ZhBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698661474; x=1699266274; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XMQpfaIN/InMDdlUgLVw00qMYeBzvuSBSwDJAWk5R1M=; b=cia/r/rB1W6DbcM0sTvnGoxiMW9rgbZH3nGPqnc09/CfgzywmPl+lrjggBXDGxY2z3 5SH0HWL7VVki995WcHr2j/UhVsS5Q2UxORXvHLp6uuEotPYnjy0nBkmxC9zhXzOb2GLX mbboX0kIhNjFaqF7HJSo8kC9OLHn6nSsBT3dqoHTYHagrXY5CDDdvsMlUdvHumhOD9eV x2OjVIzOUULBM9Bs0XK3WW1CXKmqbvMWWS5b3SsyqkJdGlwCidx0BgzsBHOiJ7KoLibC RJpGXJ7KnbFVrM6j16rxVkau+86d4XJ84Sz7tF62eazWiNA+aRhUvkv59buBAs3i/xSv Ekxw== X-Gm-Message-State: AOJu0YyRHU1AaTh9oilee0nswBoJzUD/6nxyJ9A0mcUdVkre7Dfpjq3o ZUXeex71iQ9HYXMvsC1pPT2DIA== X-Received: by 2002:a05:6a00:1883:b0:6bd:d884:df00 with SMTP id x3-20020a056a00188300b006bdd884df00mr11107938pfh.9.1698661474434; Mon, 30 Oct 2023 03:24:34 -0700 (PDT) Received: from localhost ([122.172.80.14]) by smtp.gmail.com with ESMTPSA id p15-20020a62ab0f000000b0068fe76cdc62sm5762682pff.93.2023.10.30.03.24.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Oct 2023 03:24:33 -0700 (PDT) From: Viresh Kumar To: Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , Ulf Hansson , Stephan Gerhold , Konrad Dybcio , Manivannan Sadhasivam , linux-kernel@vger.kernel.org Subject: [PATCH V2 3/3] OPP: Call dev_pm_opp_set_opp() for required OPPs Date: Mon, 30 Oct 2023 15:54:17 +0530 Message-Id: <4141588b94ac5ca6733397398f0084ca56a129a8.1698661048.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on fry.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (fry.vger.email [0.0.0.0]); Mon, 30 Oct 2023 03:35:13 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781176355122214075 X-GMAIL-MSGID: 1781176355122214075 Configuring the required OPP was never properly implemented, we just took an exception for genpds and configured them directly, while leaving out all other required OPP types. Now that a standard call to dev_pm_opp_set_opp() takes care of configuring the opp->level too, the special handling for genpds can be avoided by simply calling dev_pm_opp_set_opp() for the required OPPs, which shall eventually configure the corresponding level for genpds. This also makes it possible for us to configure other type of required OPPs (no concrete users yet though), via the same path. This is how other frameworks take care of parent nodes, like clock, regulators, etc, where we recursively call the same helper. In order to call dev_pm_opp_set_opp() for the virtual genpd devices, they must share the OPP table of the genpd. Call _add_opp_dev() for them to get that done. This commit also extends the struct dev_pm_opp_config to pass required devices, for non-genpd cases, which can be used to call dev_pm_opp_set_opp() for the non-genpd required devices. Signed-off-by: Viresh Kumar Reviewed-by: Ulf Hansson --- drivers/opp/core.c | 168 ++++++++++++++++++++--------------------- drivers/opp/of.c | 17 +++-- drivers/opp/opp.h | 8 +- include/linux/pm_opp.h | 7 +- 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index aeb216f7e978..e08375ed50aa 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1054,48 +1054,22 @@ static int _set_opp_bw(const struct opp_table *opp_table, return 0; } -static int _set_performance_state(struct device *dev, struct device *pd_dev, - struct dev_pm_opp *opp, int i) -{ - unsigned int pstate = 0; - int ret; - - if (!pd_dev) - return 0; - - if (likely(opp)) { - pstate = opp->required_opps[i]->level; - if (pstate == OPP_LEVEL_UNSET) - return 0; - } - - ret = dev_pm_domain_set_performance_state(pd_dev, pstate); - if (ret) { - dev_err(dev, "Failed to set performance state of %s: %d (%d)\n", - dev_name(pd_dev), pstate, ret); - } - - return ret; -} - -static int _opp_set_required_opps_generic(struct device *dev, - struct opp_table *opp_table, struct dev_pm_opp *opp, bool scaling_down) -{ - dev_err(dev, "setting required-opps isn't supported for non-genpd devices\n"); - return -ENOENT; -} - -static int _opp_set_required_opps_genpd(struct device *dev, - struct opp_table *opp_table, struct dev_pm_opp *opp, bool scaling_down) +/* This is only called for PM domain for now */ +static int _set_required_opps(struct device *dev, struct opp_table *opp_table, + struct dev_pm_opp *opp, bool up) { - struct device **genpd_virt_devs = opp_table->genpd_virt_devs; + struct device **devs = opp_table->required_devs; int index, target, delta, ret; - if (!genpd_virt_devs) + if (!devs) return 0; + /* required-opps not fully initialized yet */ + if (lazy_linking_pending(opp_table)) + return -EBUSY; + /* Scaling up? Set required OPPs in normal order, else reverse */ - if (!scaling_down) { + if (up) { index = 0; target = opp_table->required_opp_count; delta = 1; @@ -1106,9 +1080,11 @@ static int _opp_set_required_opps_genpd(struct device *dev, } while (index != target) { - ret = _set_performance_state(dev, genpd_virt_devs[index], opp, index); - if (ret) - return ret; + if (devs[index]) { + ret = dev_pm_opp_set_opp(devs[index], opp->required_opps[index]); + if (ret) + return ret; + } index += delta; } @@ -1116,34 +1092,6 @@ static int _opp_set_required_opps_genpd(struct device *dev, return 0; } -/* This is only called for PM domain for now */ -static int _set_required_opps(struct device *dev, struct opp_table *opp_table, - struct dev_pm_opp *opp, bool up) -{ - /* required-opps not fully initialized yet */ - if (lazy_linking_pending(opp_table)) - return -EBUSY; - - if (opp_table->set_required_opps) - return opp_table->set_required_opps(dev, opp_table, opp, up); - - return 0; -} - -/* Update set_required_opps handler */ -void _update_set_required_opps(struct opp_table *opp_table) -{ - /* Already set */ - if (opp_table->set_required_opps) - return; - - /* All required OPPs will belong to genpd or none */ - if (opp_table->required_opp_tables[0]->is_genpd) - opp_table->set_required_opps = _opp_set_required_opps_genpd; - else - opp_table->set_required_opps = _opp_set_required_opps_generic; -} - static int _set_opp_level(struct device *dev, struct opp_table *opp_table, struct dev_pm_opp *opp) { @@ -2406,19 +2354,13 @@ static void _opp_detach_genpd(struct opp_table *opp_table) { int index; - if (!opp_table->genpd_virt_devs) - return; - for (index = 0; index < opp_table->required_opp_count; index++) { - if (!opp_table->genpd_virt_devs[index]) + if (!opp_table->required_devs[index]) continue; - dev_pm_domain_detach(opp_table->genpd_virt_devs[index], false); - opp_table->genpd_virt_devs[index] = NULL; + dev_pm_domain_detach(opp_table->required_devs[index], false); + opp_table->required_devs[index] = NULL; } - - kfree(opp_table->genpd_virt_devs); - opp_table->genpd_virt_devs = NULL; } /* @@ -2445,14 +2387,14 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, int index = 0, ret = -EINVAL; const char * const *name = names; - if (opp_table->genpd_virt_devs) - return 0; + if (!opp_table->required_devs) { + dev_err(dev, "Required OPPs not available, can't attach genpd\n"); + return -EINVAL; + } - opp_table->genpd_virt_devs = kcalloc(opp_table->required_opp_count, - sizeof(*opp_table->genpd_virt_devs), - GFP_KERNEL); - if (!opp_table->genpd_virt_devs) - return -ENOMEM; + /* Checking only the first one is enough ? */ + if (opp_table->required_devs[0]) + return 0; while (*name) { if (index >= opp_table->required_opp_count) { @@ -2468,13 +2410,25 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, goto err; } - opp_table->genpd_virt_devs[index] = virt_dev; + /* + * Add the virtual genpd device as a user of the OPP table, so + * we can call dev_pm_opp_set_opp() on it directly. + * + * This will be automatically removed when the OPP table is + * removed, don't need to handle that here. + */ + if (!_add_opp_dev(virt_dev, opp_table->required_opp_tables[index])) { + ret = -ENOMEM; + goto err; + } + + opp_table->required_devs[index] = virt_dev; index++; name++; } if (virt_devs) - *virt_devs = opp_table->genpd_virt_devs; + *virt_devs = opp_table->required_devs; return 0; @@ -2484,10 +2438,42 @@ static int _opp_attach_genpd(struct opp_table *opp_table, struct device *dev, } +static int _opp_set_required_devs(struct opp_table *opp_table, + struct device *dev, + struct device **required_devs) +{ + int i; + + if (!opp_table->required_devs) { + dev_err(dev, "Required OPPs not available, can't set required devs\n"); + return -EINVAL; + } + + /* Another device that shares the OPP table has set the required devs ? */ + if (opp_table->required_devs[0]) + return 0; + + for (i = 0; i < opp_table->required_opp_count; i++) + opp_table->required_devs[i] = required_devs[i]; + + return 0; +} + +static void _opp_put_required_devs(struct opp_table *opp_table) +{ + int i; + + for (i = 0; i < opp_table->required_opp_count; i++) + opp_table->required_devs[i] = NULL; +} + static void _opp_clear_config(struct opp_config_data *data) { - if (data->flags & OPP_CONFIG_GENPD) + if (data->flags & OPP_CONFIG_REQUIRED_DEVS) + _opp_put_required_devs(data->opp_table); + else if (data->flags & OPP_CONFIG_GENPD) _opp_detach_genpd(data->opp_table); + if (data->flags & OPP_CONFIG_REGULATOR) _opp_put_regulators(data->opp_table); if (data->flags & OPP_CONFIG_SUPPORTED_HW) @@ -2601,12 +2587,22 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) /* Attach genpds */ if (config->genpd_names) { + if (config->required_devs) + goto err; + ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, config->virt_devs); if (ret) goto err; data->flags |= OPP_CONFIG_GENPD; + } else if (config->required_devs) { + ret = _opp_set_required_devs(opp_table, dev, + config->required_devs); + if (ret) + goto err; + + data->flags |= OPP_CONFIG_REQUIRED_DEVS; } ret = xa_alloc(&opp_configs, &id, data, XA_LIMIT(1, INT_MAX), diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 4b7191440bdf..78eea989092f 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -165,7 +165,7 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, struct opp_table **required_opp_tables; struct device_node *required_np, *np; bool lazy = false; - int count, i; + int count, i, size; /* Traversing the first OPP node is all we need */ np = of_get_next_available_child(opp_np, NULL); @@ -179,12 +179,13 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, if (count <= 0) goto put_np; - required_opp_tables = kcalloc(count, sizeof(*required_opp_tables), - GFP_KERNEL); + size = sizeof(*required_opp_tables) + sizeof(*opp_table->required_devs); + required_opp_tables = kcalloc(count, size, GFP_KERNEL); if (!required_opp_tables) goto put_np; opp_table->required_opp_tables = required_opp_tables; + opp_table->required_devs = (void *)(required_opp_tables + count); opp_table->required_opp_count = count; for (i = 0; i < count; i++) { @@ -208,8 +209,6 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, mutex_lock(&opp_table_lock); list_add(&opp_table->lazy, &lazy_opp_tables); mutex_unlock(&opp_table_lock); - } else { - _update_set_required_opps(opp_table); } goto put_np; @@ -326,9 +325,14 @@ static int _link_required_opps(struct dev_pm_opp *opp, struct opp_table *opp_tab * * Just update the `level` with the right value, which * dev_pm_opp_set_opp() will take care of in the normal path itself. + * + * There is another case though, where a genpd's OPP table has + * required-opps set to a parent genpd. The OPP core expects the user to + * set the respective required `struct device` pointer via + * dev_pm_opp_set_config(). */ if (required_table->is_genpd && opp_table->required_opp_count == 1 && - !opp_table->genpd_virt_devs) { + !opp_table->required_devs[0]) { if (!WARN_ON(opp->level != OPP_LEVEL_UNSET)) opp->level = opp->required_opps[0]->level; } @@ -441,7 +445,6 @@ static void lazy_link_required_opp_table(struct opp_table *new_table) /* All required opp-tables found, remove from lazy list */ if (!lazy) { - _update_set_required_opps(opp_table); list_del_init(&opp_table->lazy); list_for_each_entry(opp, &opp_table->opp_list, node) diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 08366f90f16b..23dcb2fbf8c3 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -35,6 +35,7 @@ extern struct list_head opp_tables; #define OPP_CONFIG_PROP_NAME BIT(3) #define OPP_CONFIG_SUPPORTED_HW BIT(4) #define OPP_CONFIG_GENPD BIT(5) +#define OPP_CONFIG_REQUIRED_DEVS BIT(6) /** * struct opp_config_data - data for set config operations @@ -160,9 +161,9 @@ enum opp_table_access { * @rate_clk_single: Currently configured frequency for single clk. * @current_opp: Currently configured OPP for the table. * @suspend_opp: Pointer to OPP to be used during device suspend. - * @genpd_virt_devs: List of virtual devices for multiple genpd support. * @required_opp_tables: List of device OPP tables that are required by OPPs in * this table. + * @required_devs: List of devices for required OPP tables. * @required_opp_count: Number of required devices. * @supported_hw: Array of version number to support. * @supported_hw_count: Number of elements in supported_hw array. @@ -180,7 +181,6 @@ enum opp_table_access { * @path_count: Number of interconnect paths * @enabled: Set to true if the device's resources are enabled/configured. * @is_genpd: Marks if the OPP table belongs to a genpd. - * @set_required_opps: Helper responsible to set required OPPs. * @dentry: debugfs dentry pointer of the real device directory (not links). * @dentry_name: Name of the real dentry. * @@ -211,8 +211,8 @@ struct opp_table { struct dev_pm_opp *current_opp; struct dev_pm_opp *suspend_opp; - struct device **genpd_virt_devs; struct opp_table **required_opp_tables; + struct device **required_devs; unsigned int required_opp_count; unsigned int *supported_hw; @@ -229,8 +229,6 @@ struct opp_table { unsigned int path_count; bool enabled; bool is_genpd; - int (*set_required_opps)(struct device *dev, - struct opp_table *opp_table, struct dev_pm_opp *opp, bool scaling_down); #ifdef CONFIG_DEBUG_FS struct dentry *dentry; diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index af53101a1383..81dff7facdc9 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -74,8 +74,10 @@ typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_table, * @supported_hw_count: Number of elements in the array. * @regulator_names: Array of pointers to the names of the regulator, NULL terminated. * @genpd_names: Null terminated array of pointers containing names of genpd to - * attach. - * @virt_devs: Pointer to return the array of virtual devices. + * attach. Mutually exclusive with required_devs. + * @virt_devs: Pointer to return the array of genpd virtual devices. Mutually + * exclusive with required_devs. + * @required_devs: Required OPP devices. Mutually exclusive with genpd_names/virt_devs. * * This structure contains platform specific OPP configurations for the device. */ @@ -90,6 +92,7 @@ struct dev_pm_opp_config { const char * const *regulator_names; const char * const *genpd_names; struct device ***virt_devs; + struct device **required_devs; }; #define OPP_LEVEL_UNSET U32_MAX