From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB948C4338F for ; Mon, 16 Aug 2021 13:02:20 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7A1DF63290 for ; Mon, 16 Aug 2021 13:02:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 7A1DF63290 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Date:CC:To:From:Subject:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WBa8EeZwM2cA4vCuL2JTZ5q1DEcwn2wt9d9pPiZn8MI=; b=xuz1/d65mT8Jo6 KR68wlvADKgmvbPtofypJCBV36CmGiItnivDWr4Wj5QRMO7rH/px9gZDB0cWeWjzF0ui1jypCthK2 ZBQZYdNjz/tW7jbXiqObY1lnfSjAnndqx60e9D1uDOz3s3Pr8p1gU50vIsIVy61sP3LzOcr0WY3dU cS0bCh76yjvVRNujlm2X7fb1dEtC0OMOb0pr0W/kXQNF7RatHwNGvCehr9t7hmpGVavdhnJNdEI38 pNjaOrGuysTtpamf4naHUtY9qmU8HQjt8ZC4oMgj85HB+3I9Ye+yHThtj0WwQK4eA7uR4AO7h7sQB MCEzrFQhuBNrffxhRnmg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mFcFg-00H0uj-Cc; Mon, 16 Aug 2021 13:02:04 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mFcFa-00H0px-26; Mon, 16 Aug 2021 13:02:02 +0000 X-UUID: 429be09f2ce44f5da17557c444a19e24-20210816 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=JiUWHQhw3d/c8if14OCuLpHPMoZZhOFQBgPIahZNMuE=; b=OFjMW6op+2zwuImOItFOr6TUMVAQammj9xfTOEn5GxrkKdL8ooiKKBJvBVZH5nE2oPdYyfE/FDPeOK5LcFwV1mqwW95xpKTLgO2MZN9Z57bF4M57Y74IoMdDCnKO3IAetX012eJXmyKte8U0x0DNrYOqyHTptN5fCnEyv7nnDbk=; X-UUID: 429be09f2ce44f5da17557c444a19e24-20210816 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1259682483; Mon, 16 Aug 2021 06:01:52 -0700 Received: from MTKMBS06N1.mediatek.inc (172.21.101.129) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 16 Aug 2021 05:56:36 -0700 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs06n1.mediatek.inc (172.21.101.129) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 16 Aug 2021 20:56:34 +0800 Received: from [172.21.77.33] (172.21.77.33) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 16 Aug 2021 20:56:34 +0800 Message-ID: <1629118594.3246.13.camel@mtkswgap22> Subject: Re: [PATCH v13 2/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW From: Hector Yuan To: Viresh Kumar CC: , , , "Rafael J. Wysocki" , Rob Herring , , , Date: Mon, 16 Aug 2021 20:56:34 +0800 In-Reply-To: <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7> References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com> <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com> <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210816_060158_164643_322A88B8 X-CRM114-Status: GOOD ( 38.57 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org On Tue, 2021-08-03 at 12:43 +0530, Viresh Kumar wrote: > On 30-07-21, 00:08, Hector Yuan wrote: > > From: "Hector.Yuan" > > > > Add cpufreq HW support > > Please write a proper commit log, what you are adding and which SoCs > it will apply to. Also add a full stop (.) at the end. > OK, I will write down more details > > Signed-off-by: Hector.Yuan > > --- > > drivers/cpufreq/Kconfig.arm | 12 ++ > > drivers/cpufreq/Makefile | 1 + > > drivers/cpufreq/mediatek-cpufreq-hw.c | 357 +++++++++++++++++++++++++++++++++ > > include/linux/cpufreq.h | 39 ++++ > > The changes to cpufreq.h should be done in a separate patch. > OK, will separate .h to another patch > > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c > > new file mode 100644 > > index 0000000..ca50a3a > > --- /dev/null > > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c > > @@ -0,0 +1,357 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (c) 2020 MediaTek Inc. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define LUT_MAX_ENTRIES 32U > > +#define LUT_FREQ GENMASK(11, 0) > > +#define LUT_ROW_SIZE 0x4 > > +#define CPUFREQ_HW_STATUS BIT(0) > > +#define SVS_HW_STATUS BIT(1) > > +#define POLL_USEC 1000 > > +#define TIMEOUT_USEC 300000 > > + > > +enum { > > + REG_FREQ_LUT_TABLE, > > + REG_FREQ_ENABLE, > > + REG_FREQ_PERF_STATE, > > + REG_FREQ_HW_STATE, > > + REG_EM_POWER_TBL, > > + REG_FREQ_LATENCY, > > + > > + REG_ARRAY_SIZE, > > +}; > > + > > +struct cpufreq_mtk { > > + struct cpufreq_frequency_table *table; > > + void __iomem *reg_bases[REG_ARRAY_SIZE]; > > + int nr_opp; > > + cpumask_t related_cpus; > > +}; > > + > > +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = { > > + [REG_FREQ_LUT_TABLE] = 0x0, > > + [REG_FREQ_ENABLE] = 0x84, > > + [REG_FREQ_PERF_STATE] = 0x88, > > + [REG_FREQ_HW_STATE] = 0x8c, > > + [REG_EM_POWER_TBL] = 0x90, > > + [REG_FREQ_LATENCY] = 0x110, > > +}; > > + > > +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS]; > > + > > +static int __maybe_unused > > +mtk_cpufreq_get_cpu_power(unsigned long *mW, > > + unsigned long *KHz, struct device *cpu_dev) > > +{ > > + struct cpufreq_mtk *c; > > + struct cpufreq_policy *policy; > > + int i; > > + > > + policy = cpufreq_cpu_get_raw(cpu_dev->id); > > + if (!policy) > > + return 0; > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + > > + for (i = 0; i < c->nr_opp; i++) { > > + if (c->table[i].frequency < *KHz) > > + break; > > + } > > + i--; > > + > > + *KHz = c->table[i].frequency; > > + *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] + > > + i * LUT_ROW_SIZE) / 1000; > > + > > + return 0; > > +} > > + > > +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy, > > + unsigned int index) > > +{ > > + struct cpufreq_mtk *c = policy->driver_data; > > + > > + writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]); > > + > > + return 0; > > +} > > + > > +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu) > > +{ > > + struct cpufreq_mtk *c; > > + struct cpufreq_policy *policy; > > + unsigned int index; > > + > > + policy = cpufreq_cpu_get_raw(cpu); > > + if (!policy) > > + return 0; > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + > > + index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]); > > + index = min(index, LUT_MAX_ENTRIES - 1); > > + > > + return c->table[index].frequency; > > +} > > + > > +static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy, > > + unsigned int target_freq) > > +{ > > + struct cpufreq_mtk *c = policy->driver_data; > > + unsigned int index; > > + > > + index = cpufreq_table_find_index_dl(policy, target_freq); > > + > > + writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]); > > + > > + return policy->freq_table[index].frequency; > > +} > > + > > +static int mtk_cpu_create_freq_table(struct platform_device *pdev, > > + struct cpufreq_mtk *c) > > +{ > > + struct device *dev = &pdev->dev; > > + void __iomem *base_table; > > + u32 data, i, freq, prev_freq = 0; > > + > > + c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1, > > + sizeof(*c->table), GFP_KERNEL); > > + if (!c->table) > > + return -ENOMEM; > > + > > + base_table = c->reg_bases[REG_FREQ_LUT_TABLE]; > > + > > + for (i = 0; i < LUT_MAX_ENTRIES; i++) { > > + data = readl_relaxed(base_table + (i * LUT_ROW_SIZE)); > > + freq = FIELD_GET(LUT_FREQ, data) * 1000; > > + > > + if (freq == prev_freq) > > + break; > > + > > + c->table[i].frequency = freq; > > + > > + dev_dbg(dev, "index=%d freq=%d\n", > > + i, c->table[i].frequency); > > Won't this fit in a single line ? > OK, will modify to single line > > + > > + prev_freq = freq; > > + } > > + > > + c->table[i].frequency = CPUFREQ_TABLE_END; > > + c->nr_opp = i; > > + > > + return 0; > > +} > > + > > +static int mtk_cpu_resources_init(struct platform_device *pdev, > > + unsigned int cpu, int index, > > + const u16 *offsets) > > +{ > > + struct cpufreq_mtk *c; > > + struct device *dev = &pdev->dev; > > + int ret, i; > > + void __iomem *base; > > + > > + if (mtk_freq_domain_map[cpu]) > > This should not happen anymore, isn't it ? > Will remove cpu map. > > + return 0; > > + > > + c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL); > > + if (!c) > > + return -ENOMEM; > > + > > + base = devm_platform_ioremap_resource(pdev, index); > > + if (IS_ERR(base)) > > + return PTR_ERR(base); > > + > > + for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++) > > + c->reg_bases[i] = base + offsets[i]; > > + > > + ret = of_perf_domain_get_sharing_cpumask(index, "performance-domains", > > Instead of parsing parsing "performance-domains" twice, I would rather > pass a CPU number here instead of index. > Sorry, could you give me more details? For now, will use index to parse per-cpu to related cpus.You mean pass policy->cpu or? Thanks. > > + "#performance-domain-cells", > > + &c->related_cpus); > > You could have directly passed policy->cpus here instead. > will replace it. > > + if (ret) { > > + dev_info(dev, "Domain-%d failed to get related CPUs\n", index); > > + return ret; > > + } > > + > > + ret = mtk_cpu_create_freq_table(pdev, c); > > + if (ret) { > > + dev_info(dev, "Domain-%d failed to create freq table\n", index); > > + return ret; > > + } > > + > > + mtk_freq_domain_map[cpu] = c; > > I will rather use policy->driver_data to store this now. > OK > > + > > + return 0; > > +} > > + > > +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) > > +{ > > + struct platform_device *pdev = cpufreq_get_driver_data(); > > + struct cpufreq_mtk *c; > > + struct device *cpu_dev; > > + struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power); > > + struct pm_qos_request *qos_request; > > + struct device_node *cpu_np; > > + struct of_phandle_args args; > > + const u16 *offsets; > > + unsigned int latency; > > + int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS; > > + int ret; > > It looks much more organized when the variable definitions are in > decreasing order of their length, instead of the random order as it is > right now. > OK, will sort it. > > + > > + offsets = of_device_get_match_data(&pdev->dev); > > + if (!offsets) > > + return -EINVAL; > > + > > + cpu_np = of_cpu_device_node_get(policy->cpu); > > + if (!cpu_np) { > > + dev_info(&pdev->dev, "Failed to get cpu %d device\n", > > + policy->cpu); > > + return -ENODEV; > > + } > > + > > + ret = of_parse_phandle_with_args(cpu_np, "performance-domains", > > + "#performance-domain-cells", 0, > > + &args); > > + if (ret < 0) > > What about dropping cpu_np and same later in the code as well ? > OK, Will add it. > > + return ret; > > + > > + /* Get the bases of cpufreq for domains */ > > + ret = mtk_cpu_resources_init(pdev, policy->cpu, args.args[0], offsets); > > + if (ret) { > > + dev_info(&pdev->dev, "CPUFreq resource init failed\n"); > > + return ret; > > + } > > + > > + cpu_dev = get_cpu_device(policy->cpu); > > + if (!cpu_dev) { > > + pr_err("failed to get cpu%d device\n", policy->cpu); > > + return -ENODEV; > > + } > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + if (!c) { > > + pr_err("No scaling support for CPU%d\n", policy->cpu); > > + return -ENODEV; > > + } > > + > > + cpumask_copy(policy->cpus, &c->related_cpus); > > + > > + policy->freq_table = c->table; > > + policy->driver_data = c; > > Oh you already do this, you can remove mtk_freq_domain_map array now. > OK, will remove map. > > + > > + latency = readl_relaxed(c->reg_bases[REG_FREQ_LATENCY]); > > + if (!latency) > > + latency = CPUFREQ_ETERNAL; > > + > > + /* us convert to ns */ > > + policy->cpuinfo.transition_latency = latency * 1000; > > You want to multiple CPUFREQ_ETERNAL too ? > Yes, may be different power domain with different transition latency. > > + > > + policy->fast_switch_possible = true; > > + > > + qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL); > > This is a small structure, why not allocate it on stack instead ? > For qos part, we'd like to take more time to re-consider the SW flow and put this to another patch set.Is this okay to you? > > + if (!qos_request) > > + return -ENOMEM; > > + > > + /* Let CPUs leave idle-off state for SVS CPU initializing */ > > + cpu_latency_qos_add_request(qos_request, 0); > > + > > + /* HW should be in enabled state to proceed now */ > > + writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]); > > + > > + if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig, > > + (sig & pwr_hw) == pwr_hw, POLL_USEC, > > + TIMEOUT_USEC)) { > > + if (!(sig & CPUFREQ_HW_STATUS)) { > > + pr_info("cpufreq hardware of CPU%d is not enabled\n", > > + policy->cpu); > > + return -ENODEV; > > + } > > + > > + pr_info("SVS of CPU%d is not enabled\n", policy->cpu); > > + } > > + > > + cpu_latency_qos_remove_request(qos_request); > > + > > + em_dev_register_perf_domain(cpu_dev, c->nr_opp, &em_cb, policy->cpus, true); > > + > > + kfree(qos_request); > > Why free after registering for em ? And also move the entire qos thing > into a separate routine instead of adding it to ->init(). > If you agree, we'll consider to put it in another patch set. > > + > > + return 0; > > +} > > + > > +static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) > > +{ > > + struct cpufreq_mtk *c; > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + > > + /* HW should be in paused state now */ > > + writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]); > > Please make sure each and every resource is freed here and in probe on > failures. > OK, will free all resources as probe. > > + > > + return 0; > > +} > > + > > +static struct cpufreq_driver cpufreq_mtk_hw_driver = { > > + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | > > + CPUFREQ_HAVE_GOVERNOR_PER_POLICY | > > + CPUFREQ_IS_COOLING_DEV, > > + .verify = cpufreq_generic_frequency_table_verify, > > + .target_index = mtk_cpufreq_hw_target_index, > > + .get = mtk_cpufreq_hw_get, > > + .init = mtk_cpufreq_hw_cpu_init, > > + .exit = mtk_cpufreq_hw_cpu_exit, > > + .fast_switch = mtk_cpufreq_hw_fast_switch, > > + .name = "mtk-cpufreq-hw", > > + .attr = cpufreq_generic_attr, > > +}; > > + > > +static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev) > > +{ > > + int ret; > > + > > + cpufreq_mtk_hw_driver.driver_data = pdev; > > + > > + ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver); > > + if (ret) { > > + dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n"); > > + return ret; > > + } > > + > > + return 0; > > You can do return ret here and drop the earlier return and its {}. > okay. > > +} > > + > > +static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev) > > +{ > > + return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver); > > +} > > + > > +static const struct of_device_id mtk_cpufreq_hw_match[] = { > > + { .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets }, > > + {} > > +}; > > + > > +static struct platform_driver mtk_cpufreq_hw_driver = { > > + .probe = mtk_cpufreq_hw_driver_probe, > > + .remove = mtk_cpufreq_hw_driver_remove, > > + .driver = { > > + .name = "mtk-cpufreq-hw", > > + .of_match_table = mtk_cpufreq_hw_match, > > + }, > > +}; > > +module_platform_driver(mtk_cpufreq_hw_driver); > > + > > +MODULE_DESCRIPTION("Mediatek cpufreq-hw driver"); > > +MODULE_LICENSE("GPL v2"); > > You can add Module-author as well here if you want. > OK. > > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h > > index 9fd7194..4916d70 100644 > > --- a/include/linux/cpufreq.h > > +++ b/include/linux/cpufreq.h > > @@ -13,6 +13,8 @@ > > #include > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct cpumask *cpus, > > } > > #endif > > > > +#ifdef CONFIG_CPU_FREQ > > There is another CONFIG_CPU_FREQ a few lines above, please use the > same block for this routine as well. > OK, will move it to the above. > > +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name, > > + const char *cell_name, > > + struct cpumask *cpumask) > > +{ > > + struct device_node *cpu_np; > > + struct of_phandle_args args; > > + int cpu, ret; > > + > > + for_each_possible_cpu(cpu) { > > + cpu_np = of_cpu_device_node_get(cpu); > > + if (!cpu_np) > > + continue; > > + > > + ret = of_parse_phandle_with_args(cpu_np, list_name, > > + cell_name, 0, > > + &args); > > + > > + of_node_put(cpu_np); > > + if (ret < 0) > > + continue; > > + > > + if (index == args.args[0]) > > + cpumask_set_cpu(cpu, cpumask); > > + } > > + > > + return 0; > > +} > > +#else > > +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name, > > + const char *cell_name, > > + struct cpumask *cpumask) > > +{ > > + return 0; > > return -EOPNOTSUPP; > > > +} > > +#endif > _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.2 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 422DFC4320A for ; Mon, 16 Aug 2021 12:56:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 283F46327A for ; Mon, 16 Aug 2021 12:56:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230004AbhHPM5J (ORCPT ); Mon, 16 Aug 2021 08:57:09 -0400 Received: from mailgw02.mediatek.com ([210.61.82.184]:41066 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S229876AbhHPM5I (ORCPT ); Mon, 16 Aug 2021 08:57:08 -0400 X-UUID: 1cb853232ba4410f9f0b50aee804e429-20210816 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=JiUWHQhw3d/c8if14OCuLpHPMoZZhOFQBgPIahZNMuE=; b=OFjMW6op+2zwuImOItFOr6TUMVAQammj9xfTOEn5GxrkKdL8ooiKKBJvBVZH5nE2oPdYyfE/FDPeOK5LcFwV1mqwW95xpKTLgO2MZN9Z57bF4M57Y74IoMdDCnKO3IAetX012eJXmyKte8U0x0DNrYOqyHTptN5fCnEyv7nnDbk=; X-UUID: 1cb853232ba4410f9f0b50aee804e429-20210816 Received: from mtkcas06.mediatek.inc [(172.21.101.30)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 941264848; Mon, 16 Aug 2021 20:56:35 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs06n1.mediatek.inc (172.21.101.129) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 16 Aug 2021 20:56:34 +0800 Received: from [172.21.77.33] (172.21.77.33) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 16 Aug 2021 20:56:34 +0800 Message-ID: <1629118594.3246.13.camel@mtkswgap22> Subject: Re: [PATCH v13 2/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW From: Hector Yuan To: Viresh Kumar CC: , , , "Rafael J. Wysocki" , Rob Herring , , , Date: Mon, 16 Aug 2021 20:56:34 +0800 In-Reply-To: <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7> References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com> <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com> <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-MTK: N Content-Transfer-Encoding: base64 Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org T24gVHVlLCAyMDIxLTA4LTAzIGF0IDEyOjQzICswNTMwLCBWaXJlc2ggS3VtYXIgd3JvdGU6DQo+ IE9uIDMwLTA3LTIxLCAwMDowOCwgSGVjdG9yIFl1YW4gd3JvdGU6DQo+ID4gRnJvbTogIkhlY3Rv ci5ZdWFuIiA8aGVjdG9yLnl1YW5AbWVkaWF0ZWsuY29tPg0KPiA+IA0KPiA+IEFkZCBjcHVmcmVx IEhXIHN1cHBvcnQNCj4gDQo+IFBsZWFzZSB3cml0ZSBhIHByb3BlciBjb21taXQgbG9nLCB3aGF0 IHlvdSBhcmUgYWRkaW5nIGFuZCB3aGljaCBTb0NzDQo+IGl0IHdpbGwgYXBwbHkgdG8uIEFsc28g YWRkIGEgZnVsbCBzdG9wICguKSBhdCB0aGUgZW5kLg0KPiANCk9LLCBJIHdpbGwgd3JpdGUgZG93 biBtb3JlIGRldGFpbHMNCj4gPiBTaWduZWQtb2ZmLWJ5OiBIZWN0b3IuWXVhbiA8aGVjdG9yLnl1 YW5AbWVkaWF0ZWsuY29tPg0KPiA+IC0tLQ0KPiA+ICBkcml2ZXJzL2NwdWZyZXEvS2NvbmZpZy5h cm0gICAgICAgICAgIHwgICAxMiArKw0KPiA+ICBkcml2ZXJzL2NwdWZyZXEvTWFrZWZpbGUgICAg ICAgICAgICAgIHwgICAgMSArDQo+ID4gIGRyaXZlcnMvY3B1ZnJlcS9tZWRpYXRlay1jcHVmcmVx LWh3LmMgfCAgMzU3ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKw0KPiA+ICBpbmNs dWRlL2xpbnV4L2NwdWZyZXEuaCAgICAgICAgICAgICAgIHwgICAzOSArKysrDQo+IA0KPiBUaGUg Y2hhbmdlcyB0byBjcHVmcmVxLmggc2hvdWxkIGJlIGRvbmUgaW4gYSBzZXBhcmF0ZSBwYXRjaC4N Cj4gDQpPSywgd2lsbCBzZXBhcmF0ZSAuaCB0byBhbm90aGVyIHBhdGNoDQo+ID4gZGlmZiAtLWdp dCBhL2RyaXZlcnMvY3B1ZnJlcS9tZWRpYXRlay1jcHVmcmVxLWh3LmMgYi9kcml2ZXJzL2NwdWZy ZXEvbWVkaWF0ZWstY3B1ZnJlcS1ody5jDQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gPiBp bmRleCAwMDAwMDAwLi5jYTUwYTNhDQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZl cnMvY3B1ZnJlcS9tZWRpYXRlay1jcHVmcmVxLWh3LmMNCj4gPiBAQCAtMCwwICsxLDM1NyBAQA0K PiA+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMA0KPiA+ICsvKg0KPiA+ICsg KiBDb3B5cmlnaHQgKGMpIDIwMjAgTWVkaWFUZWsgSW5jLg0KPiA+ICsgKi8NCj4gPiArDQo+ID4g KyNpbmNsdWRlIDxsaW51eC9iaXRmaWVsZC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvY3B1ZnJl cS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvZW5lcmd5X21vZGVsLmg+DQo+ID4gKyNpbmNsdWRl IDxsaW51eC9pbml0Lmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9pb3BvbGwuaD4NCj4gPiArI2lu Y2x1ZGUgPGxpbnV4L2tlcm5lbC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+DQo+ ID4gKyNpbmNsdWRlIDxsaW51eC9vZl9hZGRyZXNzLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9v Zl9wbGF0Zm9ybS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvcG1fcW9zLmg+DQo+ID4gKyNpbmNs dWRlIDxsaW51eC9zbGFiLmg+DQo+ID4gKw0KPiA+ICsjZGVmaW5lIExVVF9NQVhfRU5UUklFUwkJ CTMyVQ0KPiA+ICsjZGVmaW5lIExVVF9GUkVRCQkJR0VOTUFTSygxMSwgMCkNCj4gPiArI2RlZmlu ZSBMVVRfUk9XX1NJWkUJCQkweDQNCj4gPiArI2RlZmluZSBDUFVGUkVRX0hXX1NUQVRVUwkJQklU KDApDQo+ID4gKyNkZWZpbmUgU1ZTX0hXX1NUQVRVUwkJCUJJVCgxKQ0KPiA+ICsjZGVmaW5lIFBP TExfVVNFQwkJCTEwMDANCj4gPiArI2RlZmluZSBUSU1FT1VUX1VTRUMJCQkzMDAwMDANCj4gPiAr DQo+ID4gK2VudW0gew0KPiA+ICsJUkVHX0ZSRVFfTFVUX1RBQkxFLA0KPiA+ICsJUkVHX0ZSRVFf RU5BQkxFLA0KPiA+ICsJUkVHX0ZSRVFfUEVSRl9TVEFURSwNCj4gPiArCVJFR19GUkVRX0hXX1NU QVRFLA0KPiA+ICsJUkVHX0VNX1BPV0VSX1RCTCwNCj4gPiArCVJFR19GUkVRX0xBVEVOQ1ksDQo+ ID4gKw0KPiA+ICsJUkVHX0FSUkFZX1NJWkUsDQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdHJ1Y3Qg Y3B1ZnJlcV9tdGsgew0KPiA+ICsJc3RydWN0IGNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlICp0YWJs ZTsNCj4gPiArCXZvaWQgX19pb21lbSAqcmVnX2Jhc2VzW1JFR19BUlJBWV9TSVpFXTsNCj4gPiAr CWludCBucl9vcHA7DQo+ID4gKwljcHVtYXNrX3QgcmVsYXRlZF9jcHVzOw0KPiA+ICt9Ow0KPiA+ ICsNCj4gPiArc3RhdGljIGNvbnN0IHUxNiBjcHVmcmVxX210a19vZmZzZXRzW1JFR19BUlJBWV9T SVpFXSA9IHsNCj4gPiArCVtSRUdfRlJFUV9MVVRfVEFCTEVdCT0gMHgwLA0KPiA+ICsJW1JFR19G UkVRX0VOQUJMRV0JPSAweDg0LA0KPiA+ICsJW1JFR19GUkVRX1BFUkZfU1RBVEVdCT0gMHg4OCwN Cj4gPiArCVtSRUdfRlJFUV9IV19TVEFURV0JPSAweDhjLA0KPiA+ICsJW1JFR19FTV9QT1dFUl9U QkxdCT0gMHg5MCwNCj4gPiArCVtSRUdfRlJFUV9MQVRFTkNZXQk9IDB4MTEwLA0KPiA+ICt9Ow0K PiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBjcHVmcmVxX210ayAqbXRrX2ZyZXFfZG9tYWluX21h cFtOUl9DUFVTXTsNCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgX19tYXliZV91bnVzZWQNCj4gPiAr bXRrX2NwdWZyZXFfZ2V0X2NwdV9wb3dlcih1bnNpZ25lZCBsb25nICptVywNCj4gPiArCQkJICB1 bnNpZ25lZCBsb25nICpLSHosIHN0cnVjdCBkZXZpY2UgKmNwdV9kZXYpDQo+ID4gK3sNCj4gPiAr CXN0cnVjdCBjcHVmcmVxX210ayAqYzsNCj4gPiArCXN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9s aWN5Ow0KPiA+ICsJaW50IGk7DQo+ID4gKw0KPiA+ICsJcG9saWN5ID0gY3B1ZnJlcV9jcHVfZ2V0 X3JhdyhjcHVfZGV2LT5pZCk7DQo+ID4gKwlpZiAoIXBvbGljeSkNCj4gPiArCQlyZXR1cm4gMDsN Cj4gPiArDQo+ID4gKwljID0gbXRrX2ZyZXFfZG9tYWluX21hcFtwb2xpY3ktPmNwdV07DQo+ID4g Kw0KPiA+ICsJZm9yIChpID0gMDsgaSA8IGMtPm5yX29wcDsgaSsrKSB7DQo+ID4gKwkJaWYgKGMt PnRhYmxlW2ldLmZyZXF1ZW5jeSA8ICpLSHopDQo+ID4gKwkJCWJyZWFrOw0KPiA+ICsJfQ0KPiA+ ICsJaS0tOw0KPiA+ICsNCj4gPiArCSpLSHogPSBjLT50YWJsZVtpXS5mcmVxdWVuY3k7DQo+ID4g KwkqbVcgPSByZWFkbF9yZWxheGVkKGMtPnJlZ19iYXNlc1tSRUdfRU1fUE9XRVJfVEJMXSArDQo+ ID4gKwkJCSAgICBpICogTFVUX1JPV19TSVpFKSAvIDEwMDA7DQo+ID4gKw0KPiA+ICsJcmV0dXJu IDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NwdWZyZXFfaHdfdGFyZ2V0 X2luZGV4KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9saWN5LA0KPiA+ICsJCQkJICAgICAgIHVu c2lnbmVkIGludCBpbmRleCkNCj4gPiArew0KPiA+ICsJc3RydWN0IGNwdWZyZXFfbXRrICpjID0g cG9saWN5LT5kcml2ZXJfZGF0YTsNCj4gPiArDQo+ID4gKwl3cml0ZWxfcmVsYXhlZChpbmRleCwg Yy0+cmVnX2Jhc2VzW1JFR19GUkVRX1BFUkZfU1RBVEVdKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4g MDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHVuc2lnbmVkIGludCBtdGtfY3B1ZnJlcV9o d19nZXQodW5zaWduZWQgaW50IGNwdSkNCj4gPiArew0KPiA+ICsJc3RydWN0IGNwdWZyZXFfbXRr ICpjOw0KPiA+ICsJc3RydWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3k7DQo+ID4gKwl1bnNpZ25l ZCBpbnQgaW5kZXg7DQo+ID4gKw0KPiA+ICsJcG9saWN5ID0gY3B1ZnJlcV9jcHVfZ2V0X3Jhdyhj cHUpOw0KPiA+ICsJaWYgKCFwb2xpY3kpDQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJ YyA9IG10a19mcmVxX2RvbWFpbl9tYXBbcG9saWN5LT5jcHVdOw0KPiA+ICsNCj4gPiArCWluZGV4 ID0gcmVhZGxfcmVsYXhlZChjLT5yZWdfYmFzZXNbUkVHX0ZSRVFfUEVSRl9TVEFURV0pOw0KPiA+ ICsJaW5kZXggPSBtaW4oaW5kZXgsIExVVF9NQVhfRU5UUklFUyAtIDEpOw0KPiA+ICsNCj4gPiAr CXJldHVybiBjLT50YWJsZVtpbmRleF0uZnJlcXVlbmN5Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICtz dGF0aWMgdW5zaWduZWQgaW50IG10a19jcHVmcmVxX2h3X2Zhc3Rfc3dpdGNoKHN0cnVjdCBjcHVm cmVxX3BvbGljeSAqcG9saWN5LA0KPiA+ICsJCQkJCSAgICAgICB1bnNpZ25lZCBpbnQgdGFyZ2V0 X2ZyZXEpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBjcHVmcmVxX210ayAqYyA9IHBvbGljeS0+ZHJp dmVyX2RhdGE7DQo+ID4gKwl1bnNpZ25lZCBpbnQgaW5kZXg7DQo+ID4gKw0KPiA+ICsJaW5kZXgg PSBjcHVmcmVxX3RhYmxlX2ZpbmRfaW5kZXhfZGwocG9saWN5LCB0YXJnZXRfZnJlcSk7DQo+ID4g Kw0KPiA+ICsJd3JpdGVsX3JlbGF4ZWQoaW5kZXgsIGMtPnJlZ19iYXNlc1tSRUdfRlJFUV9QRVJG X1NUQVRFXSk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIHBvbGljeS0+ZnJlcV90YWJsZVtpbmRleF0u ZnJlcXVlbmN5Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgaW50IG10a19jcHVfY3JlYXRl X2ZyZXFfdGFibGUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiwNCj4gPiArCQkJCSAgICAg c3RydWN0IGNwdWZyZXFfbXRrICpjKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYg PSAmcGRldi0+ZGV2Ow0KPiA+ICsJdm9pZCBfX2lvbWVtICpiYXNlX3RhYmxlOw0KPiA+ICsJdTMy IGRhdGEsIGksIGZyZXEsIHByZXZfZnJlcSA9IDA7DQo+ID4gKw0KPiA+ICsJYy0+dGFibGUgPSBk ZXZtX2tjYWxsb2MoZGV2LCBMVVRfTUFYX0VOVFJJRVMgKyAxLA0KPiA+ICsJCQkJc2l6ZW9mKCpj LT50YWJsZSksIEdGUF9LRVJORUwpOw0KPiA+ICsJaWYgKCFjLT50YWJsZSkNCj4gPiArCQlyZXR1 cm4gLUVOT01FTTsNCj4gPiArDQo+ID4gKwliYXNlX3RhYmxlID0gYy0+cmVnX2Jhc2VzW1JFR19G UkVRX0xVVF9UQUJMRV07DQo+ID4gKw0KPiA+ICsJZm9yIChpID0gMDsgaSA8IExVVF9NQVhfRU5U UklFUzsgaSsrKSB7DQo+ID4gKwkJZGF0YSA9IHJlYWRsX3JlbGF4ZWQoYmFzZV90YWJsZSArIChp ICogTFVUX1JPV19TSVpFKSk7DQo+ID4gKwkJZnJlcSA9IEZJRUxEX0dFVChMVVRfRlJFUSwgZGF0 YSkgKiAxMDAwOw0KPiA+ICsNCj4gPiArCQlpZiAoZnJlcSA9PSBwcmV2X2ZyZXEpDQo+ID4gKwkJ CWJyZWFrOw0KPiA+ICsNCj4gPiArCQljLT50YWJsZVtpXS5mcmVxdWVuY3kgPSBmcmVxOw0KPiA+ ICsNCj4gPiArCQlkZXZfZGJnKGRldiwgImluZGV4PSVkIGZyZXE9JWRcbiIsDQo+ID4gKwkJCWks IGMtPnRhYmxlW2ldLmZyZXF1ZW5jeSk7DQo+IA0KPiBXb24ndCB0aGlzIGZpdCBpbiBhIHNpbmds ZSBsaW5lID8NCj4gDQpPSywgd2lsbCBtb2RpZnkgdG8gc2luZ2xlIGxpbmUNCj4gPiArDQo+ID4g KwkJcHJldl9mcmVxID0gZnJlcTsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwljLT50YWJsZVtpXS5m cmVxdWVuY3kgPSBDUFVGUkVRX1RBQkxFX0VORDsNCj4gPiArCWMtPm5yX29wcCA9IGk7DQo+ID4g Kw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2Nw dV9yZXNvdXJjZXNfaW5pdChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LA0KPiA+ICsJCQkJ ICB1bnNpZ25lZCBpbnQgY3B1LCBpbnQgaW5kZXgsDQo+ID4gKwkJCQkgIGNvbnN0IHUxNiAqb2Zm c2V0cykNCj4gPiArew0KPiA+ICsJc3RydWN0IGNwdWZyZXFfbXRrICpjOw0KPiA+ICsJc3RydWN0 IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsNCj4gPiArCWludCByZXQsIGk7DQo+ID4gKwl2b2lk IF9faW9tZW0gKmJhc2U7DQo+ID4gKw0KPiA+ICsJaWYgKG10a19mcmVxX2RvbWFpbl9tYXBbY3B1 XSkNCj4gDQo+IFRoaXMgc2hvdWxkIG5vdCBoYXBwZW4gYW55bW9yZSwgaXNuJ3QgaXQgPw0KPiAN CldpbGwgcmVtb3ZlIGNwdSBtYXAuDQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsJYyA9 IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqYyksIEdGUF9LRVJORUwpOw0KPiA+ICsJaWYgKCFj KQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiArCWJhc2UgPSBkZXZtX3BsYXRm b3JtX2lvcmVtYXBfcmVzb3VyY2UocGRldiwgaW5kZXgpOw0KPiA+ICsJaWYgKElTX0VSUihiYXNl KSkNCj4gPiArCQlyZXR1cm4gUFRSX0VSUihiYXNlKTsNCj4gPiArDQo+ID4gKwlmb3IgKGkgPSBS RUdfRlJFUV9MVVRfVEFCTEU7IGkgPCBSRUdfQVJSQVlfU0laRTsgaSsrKQ0KPiA+ICsJCWMtPnJl Z19iYXNlc1tpXSA9IGJhc2UgKyBvZmZzZXRzW2ldOw0KPiA+ICsNCj4gPiArCXJldCA9IG9mX3Bl cmZfZG9tYWluX2dldF9zaGFyaW5nX2NwdW1hc2soaW5kZXgsICJwZXJmb3JtYW5jZS1kb21haW5z IiwNCj4gDQo+IEluc3RlYWQgb2YgcGFyc2luZyBwYXJzaW5nICJwZXJmb3JtYW5jZS1kb21haW5z IiB0d2ljZSwgSSB3b3VsZCByYXRoZXINCj4gcGFzcyBhIENQVSBudW1iZXIgaGVyZSBpbnN0ZWFk IG9mIGluZGV4Lg0KPiANClNvcnJ5LCBjb3VsZCB5b3UgZ2l2ZSBtZSBtb3JlIGRldGFpbHM/IEZv ciBub3csIHdpbGwgdXNlIGluZGV4IHRvIHBhcnNlDQpwZXItY3B1IHRvIHJlbGF0ZWQgY3B1cy5Z b3UgbWVhbiBwYXNzIHBvbGljeS0+Y3B1IG9yPyBUaGFua3MuDQo+ID4gKwkJCQkJCSAiI3BlcmZv cm1hbmNlLWRvbWFpbi1jZWxscyIsDQo+ID4gKwkJCQkJCSAmYy0+cmVsYXRlZF9jcHVzKTsNCj4g DQo+IFlvdSBjb3VsZCBoYXZlIGRpcmVjdGx5IHBhc3NlZCBwb2xpY3ktPmNwdXMgaGVyZSBpbnN0 ZWFkLg0KPiANCndpbGwgcmVwbGFjZSBpdC4NCj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQlkZXZf aW5mbyhkZXYsICJEb21haW4tJWQgZmFpbGVkIHRvIGdldCByZWxhdGVkIENQVXNcbiIsIGluZGV4 KTsNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldCA9IG10a19j cHVfY3JlYXRlX2ZyZXFfdGFibGUocGRldiwgYyk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJ ZGV2X2luZm8oZGV2LCAiRG9tYWluLSVkIGZhaWxlZCB0byBjcmVhdGUgZnJlcSB0YWJsZVxuIiwg aW5kZXgpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJbXRrX2Zy ZXFfZG9tYWluX21hcFtjcHVdID0gYzsNCj4gDQo+IEkgd2lsbCByYXRoZXIgdXNlIHBvbGljeS0+ ZHJpdmVyX2RhdGEgdG8gc3RvcmUgdGhpcyBub3cuDQo+IA0KT0sNCj4gPiArDQo+ID4gKwlyZXR1 cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBtdGtfY3B1ZnJlcV9od19jcHVf aW5pdChzdHJ1Y3QgY3B1ZnJlcV9wb2xpY3kgKnBvbGljeSkNCj4gPiArew0KPiA+ICsJc3RydWN0 IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IGNwdWZyZXFfZ2V0X2RyaXZlcl9kYXRhKCk7DQo+ID4g KwlzdHJ1Y3QgY3B1ZnJlcV9tdGsgKmM7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpjcHVfZGV2Ow0K PiA+ICsJc3RydWN0IGVtX2RhdGFfY2FsbGJhY2sgZW1fY2IgPSBFTV9EQVRBX0NCKG10a19jcHVm cmVxX2dldF9jcHVfcG93ZXIpOw0KPiA+ICsJc3RydWN0IHBtX3Fvc19yZXF1ZXN0ICpxb3NfcmVx dWVzdDsNCj4gPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqY3B1X25wOw0KPiA+ICsJc3RydWN0IG9m X3BoYW5kbGVfYXJncyBhcmdzOw0KPiA+ICsJY29uc3QgdTE2ICpvZmZzZXRzOw0KPiA+ICsJdW5z aWduZWQgaW50IGxhdGVuY3k7DQo+ID4gKwlpbnQgc2lnLCBwd3JfaHcgPSBDUFVGUkVRX0hXX1NU QVRVUyB8IFNWU19IV19TVEFUVVM7DQo+ID4gKwlpbnQgcmV0Ow0KPiANCj4gSXQgbG9va3MgbXVj aCBtb3JlIG9yZ2FuaXplZCB3aGVuIHRoZSB2YXJpYWJsZSBkZWZpbml0aW9ucyBhcmUgaW4NCj4g ZGVjcmVhc2luZyBvcmRlciBvZiB0aGVpciBsZW5ndGgsIGluc3RlYWQgb2YgdGhlIHJhbmRvbSBv cmRlciBhcyBpdCBpcw0KPiByaWdodCBub3cuDQo+IA0KT0ssIHdpbGwgc29ydCBpdC4NCj4gPiAr DQo+ID4gKwlvZmZzZXRzID0gb2ZfZGV2aWNlX2dldF9tYXRjaF9kYXRhKCZwZGV2LT5kZXYpOw0K PiA+ICsJaWYgKCFvZmZzZXRzKQ0KPiA+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+ICsNCj4gPiAr CWNwdV9ucCA9IG9mX2NwdV9kZXZpY2Vfbm9kZV9nZXQocG9saWN5LT5jcHUpOw0KPiA+ICsJaWYg KCFjcHVfbnApIHsNCj4gPiArCQlkZXZfaW5mbygmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGdldCBj cHUgJWQgZGV2aWNlXG4iLA0KPiA+ICsJCQkgcG9saWN5LT5jcHUpOw0KPiA+ICsJCXJldHVybiAt RU5PREVWOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldCA9IG9mX3BhcnNlX3BoYW5kbGVfd2l0 aF9hcmdzKGNwdV9ucCwgInBlcmZvcm1hbmNlLWRvbWFpbnMiLA0KPiA+ICsJCQkJCSAiI3BlcmZv cm1hbmNlLWRvbWFpbi1jZWxscyIsIDAsDQo+ID4gKwkJCQkJICZhcmdzKTsNCj4gPiArCWlmIChy ZXQgPCAwKQ0KPiANCj4gV2hhdCBhYm91dCBkcm9wcGluZyBjcHVfbnAgYW5kIHNhbWUgbGF0ZXIg aW4gdGhlIGNvZGUgYXMgd2VsbCA/DQo+IA0KT0ssIFdpbGwgYWRkIGl0Lg0KPiA+ICsJCXJldHVy biByZXQ7DQo+ID4gKw0KPiA+ICsJLyogR2V0IHRoZSBiYXNlcyBvZiBjcHVmcmVxIGZvciBkb21h aW5zICovDQo+ID4gKwlyZXQgPSBtdGtfY3B1X3Jlc291cmNlc19pbml0KHBkZXYsIHBvbGljeS0+ Y3B1LCBhcmdzLmFyZ3NbMF0sIG9mZnNldHMpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ICsJCWRl dl9pbmZvKCZwZGV2LT5kZXYsICJDUFVGcmVxIHJlc291cmNlIGluaXQgZmFpbGVkXG4iKTsNCj4g PiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCWNwdV9kZXYgPSBnZXRfY3B1 X2RldmljZShwb2xpY3ktPmNwdSk7DQo+ID4gKwlpZiAoIWNwdV9kZXYpIHsNCj4gPiArCQlwcl9l cnIoImZhaWxlZCB0byBnZXQgY3B1JWQgZGV2aWNlXG4iLCBwb2xpY3ktPmNwdSk7DQo+ID4gKwkJ cmV0dXJuIC1FTk9ERVY7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJYyA9IG10a19mcmVxX2RvbWFp bl9tYXBbcG9saWN5LT5jcHVdOw0KPiA+ICsJaWYgKCFjKSB7DQo+ID4gKwkJcHJfZXJyKCJObyBz Y2FsaW5nIHN1cHBvcnQgZm9yIENQVSVkXG4iLCBwb2xpY3ktPmNwdSk7DQo+ID4gKwkJcmV0dXJu IC1FTk9ERVY7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJY3B1bWFza19jb3B5KHBvbGljeS0+Y3B1 cywgJmMtPnJlbGF0ZWRfY3B1cyk7DQo+ID4gKw0KPiA+ICsJcG9saWN5LT5mcmVxX3RhYmxlID0g Yy0+dGFibGU7DQo+ID4gKwlwb2xpY3ktPmRyaXZlcl9kYXRhID0gYzsNCj4gDQo+IE9oIHlvdSBh bHJlYWR5IGRvIHRoaXMsIHlvdSBjYW4gcmVtb3ZlIG10a19mcmVxX2RvbWFpbl9tYXAgYXJyYXkg bm93Lg0KPiANCk9LLCB3aWxsIHJlbW92ZSBtYXAuDQo+ID4gKw0KPiA+ICsJbGF0ZW5jeSA9IHJl YWRsX3JlbGF4ZWQoYy0+cmVnX2Jhc2VzW1JFR19GUkVRX0xBVEVOQ1ldKTsNCj4gPiArCWlmICgh bGF0ZW5jeSkNCj4gPiArCQlsYXRlbmN5ID0gQ1BVRlJFUV9FVEVSTkFMOw0KPiA+ICsNCj4gPiAr CS8qIHVzIGNvbnZlcnQgdG8gbnMgKi8NCj4gPiArCXBvbGljeS0+Y3B1aW5mby50cmFuc2l0aW9u X2xhdGVuY3kgPSBsYXRlbmN5ICogMTAwMDsNCj4gDQo+IFlvdSB3YW50IHRvIG11bHRpcGxlIENQ VUZSRVFfRVRFUk5BTCB0b28gPw0KPiANClllcywgbWF5IGJlIGRpZmZlcmVudCBwb3dlciBkb21h aW4gd2l0aCBkaWZmZXJlbnQgdHJhbnNpdGlvbiBsYXRlbmN5Lg0KPiA+ICsNCj4gPiArCXBvbGlj eS0+ZmFzdF9zd2l0Y2hfcG9zc2libGUgPSB0cnVlOw0KPiA+ICsNCj4gPiArCXFvc19yZXF1ZXN0 ID0ga3phbGxvYyhzaXplb2YoKnFvc19yZXF1ZXN0KSwgR0ZQX0tFUk5FTCk7DQo+IA0KPiBUaGlz IGlzIGEgc21hbGwgc3RydWN0dXJlLCB3aHkgbm90IGFsbG9jYXRlIGl0IG9uIHN0YWNrIGluc3Rl YWQgPw0KPiANCkZvciBxb3MgcGFydCwgd2UnZCBsaWtlIHRvIHRha2UgbW9yZSB0aW1lIHRvIHJl LWNvbnNpZGVyIHRoZSBTVyBmbG93IGFuZA0KcHV0IHRoaXMgdG8gYW5vdGhlciBwYXRjaCBzZXQu SXMgdGhpcyBva2F5IHRvIHlvdT8NCj4gPiArCWlmICghcW9zX3JlcXVlc3QpDQo+ID4gKwkJcmV0 dXJuIC1FTk9NRU07DQo+ID4gKw0KPiA+ICsJLyogTGV0IENQVXMgbGVhdmUgaWRsZS1vZmYgc3Rh dGUgZm9yIFNWUyBDUFUgaW5pdGlhbGl6aW5nICovDQo+ID4gKwljcHVfbGF0ZW5jeV9xb3NfYWRk X3JlcXVlc3QocW9zX3JlcXVlc3QsIDApOw0KPiA+ICsNCj4gPiArCS8qIEhXIHNob3VsZCBiZSBp biBlbmFibGVkIHN0YXRlIHRvIHByb2NlZWQgbm93ICovDQo+ID4gKwl3cml0ZWxfcmVsYXhlZCgw eDEsIGMtPnJlZ19iYXNlc1tSRUdfRlJFUV9FTkFCTEVdKTsNCj4gPiArDQo+ID4gKwlpZiAocmVh ZGxfcG9sbF90aW1lb3V0KGMtPnJlZ19iYXNlc1tSRUdfRlJFUV9IV19TVEFURV0sIHNpZywNCj4g PiArCQkJICAgICAgIChzaWcgJiBwd3JfaHcpID09IHB3cl9odywgUE9MTF9VU0VDLA0KPiA+ICsJ CQkgICAgICAgVElNRU9VVF9VU0VDKSkgew0KPiA+ICsJCWlmICghKHNpZyAmIENQVUZSRVFfSFdf U1RBVFVTKSkgew0KPiA+ICsJCQlwcl9pbmZvKCJjcHVmcmVxIGhhcmR3YXJlIG9mIENQVSVkIGlz IG5vdCBlbmFibGVkXG4iLA0KPiA+ICsJCQkJcG9saWN5LT5jcHUpOw0KPiA+ICsJCQlyZXR1cm4g LUVOT0RFVjsNCj4gPiArCQl9DQo+ID4gKw0KPiA+ICsJCXByX2luZm8oIlNWUyBvZiBDUFUlZCBp cyBub3QgZW5hYmxlZFxuIiwgcG9saWN5LT5jcHUpOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCWNw dV9sYXRlbmN5X3Fvc19yZW1vdmVfcmVxdWVzdChxb3NfcmVxdWVzdCk7DQo+ID4gKw0KPiA+ICsJ ZW1fZGV2X3JlZ2lzdGVyX3BlcmZfZG9tYWluKGNwdV9kZXYsIGMtPm5yX29wcCwgJmVtX2NiLCBw b2xpY3ktPmNwdXMsIHRydWUpOw0KPiA+ICsNCj4gPiArCWtmcmVlKHFvc19yZXF1ZXN0KTsNCj4g DQo+IFdoeSBmcmVlIGFmdGVyIHJlZ2lzdGVyaW5nIGZvciBlbSA/IEFuZCBhbHNvIG1vdmUgdGhl IGVudGlyZSBxb3MgdGhpbmcNCj4gaW50byBhIHNlcGFyYXRlIHJvdXRpbmUgaW5zdGVhZCBvZiBh ZGRpbmcgaXQgdG8gLT5pbml0KCkuDQo+IA0KSWYgeW91IGFncmVlLCB3ZSdsbCBjb25zaWRlciB0 byBwdXQgaXQgaW4gYW5vdGhlciBwYXRjaCBzZXQuDQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2NwdWZyZXFfaHdfY3B1X2V4aXQoc3Ry dWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBjcHVmcmVx X210ayAqYzsNCj4gPiArDQo+ID4gKwljID0gbXRrX2ZyZXFfZG9tYWluX21hcFtwb2xpY3ktPmNw dV07DQo+ID4gKw0KPiA+ICsJLyogSFcgc2hvdWxkIGJlIGluIHBhdXNlZCBzdGF0ZSBub3cgKi8N Cj4gPiArCXdyaXRlbF9yZWxheGVkKDB4MCwgYy0+cmVnX2Jhc2VzW1JFR19GUkVRX0VOQUJMRV0p Ow0KPiANCj4gUGxlYXNlIG1ha2Ugc3VyZSBlYWNoIGFuZCBldmVyeSByZXNvdXJjZSBpcyBmcmVl ZCBoZXJlIGFuZCBpbiBwcm9iZSBvbg0KPiBmYWlsdXJlcy4NCj4gDQpPSywgd2lsbCBmcmVlIGFs bCByZXNvdXJjZXMgYXMgcHJvYmUuDQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4g PiArDQo+ID4gK3N0YXRpYyBzdHJ1Y3QgY3B1ZnJlcV9kcml2ZXIgY3B1ZnJlcV9tdGtfaHdfZHJp dmVyID0gew0KPiA+ICsJLmZsYWdzCQk9IENQVUZSRVFfTkVFRF9JTklUSUFMX0ZSRVFfQ0hFQ0sg fA0KPiA+ICsJCQkgIENQVUZSRVFfSEFWRV9HT1ZFUk5PUl9QRVJfUE9MSUNZIHwNCj4gPiArCQkJ ICBDUFVGUkVRX0lTX0NPT0xJTkdfREVWLA0KPiA+ICsJLnZlcmlmeQkJPSBjcHVmcmVxX2dlbmVy aWNfZnJlcXVlbmN5X3RhYmxlX3ZlcmlmeSwNCj4gPiArCS50YXJnZXRfaW5kZXgJPSBtdGtfY3B1 ZnJlcV9od190YXJnZXRfaW5kZXgsDQo+ID4gKwkuZ2V0CQk9IG10a19jcHVmcmVxX2h3X2dldCwN Cj4gPiArCS5pbml0CQk9IG10a19jcHVmcmVxX2h3X2NwdV9pbml0LA0KPiA+ICsJLmV4aXQJCT0g bXRrX2NwdWZyZXFfaHdfY3B1X2V4aXQsDQo+ID4gKwkuZmFzdF9zd2l0Y2gJPSBtdGtfY3B1ZnJl cV9od19mYXN0X3N3aXRjaCwNCj4gPiArCS5uYW1lCQk9ICJtdGstY3B1ZnJlcS1odyIsDQo+ID4g KwkuYXR0cgkJPSBjcHVmcmVxX2dlbmVyaWNfYXR0ciwNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0 YXRpYyBpbnQgbXRrX2NwdWZyZXFfaHdfZHJpdmVyX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZp Y2UgKnBkZXYpDQo+ID4gK3sNCj4gPiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJY3B1ZnJlcV9t dGtfaHdfZHJpdmVyLmRyaXZlcl9kYXRhID0gcGRldjsNCj4gPiArDQo+ID4gKwlyZXQgPSBjcHVm cmVxX3JlZ2lzdGVyX2RyaXZlcigmY3B1ZnJlcV9tdGtfaHdfZHJpdmVyKTsNCj4gPiArCWlmIChy ZXQpIHsNCj4gPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJDUFVGcmVxIEhXIGRyaXZlciBmYWls ZWQgdG8gcmVnaXN0ZXJcbiIpOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4gKw0K PiA+ICsJcmV0dXJuIDA7DQo+IA0KPiBZb3UgY2FuIGRvIHJldHVybiByZXQgaGVyZSBhbmQgZHJv cCB0aGUgZWFybGllciByZXR1cm4gYW5kIGl0cyB7fS4NCj4gDQpva2F5Lg0KPiA+ICt9DQo+ID4g Kw0KPiA+ICtzdGF0aWMgaW50IG10a19jcHVmcmVxX2h3X2RyaXZlcl9yZW1vdmUoc3RydWN0IHBs YXRmb3JtX2RldmljZSAqcGRldikNCj4gPiArew0KPiA+ICsJcmV0dXJuIGNwdWZyZXFfdW5yZWdp c3Rlcl9kcml2ZXIoJmNwdWZyZXFfbXRrX2h3X2RyaXZlcik7DQo+ID4gK30NCj4gPiArDQo+ID4g K3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG10a19jcHVmcmVxX2h3X21hdGNoW10g PSB7DQo+ID4gKwl7IC5jb21wYXRpYmxlID0gIm1lZGlhdGVrLGNwdWZyZXEtaHciLCAuZGF0YSA9 ICZjcHVmcmVxX210a19vZmZzZXRzIH0sDQo+ID4gKwl7fQ0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr c3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbXRrX2NwdWZyZXFfaHdfZHJpdmVyID0gew0K PiA+ICsJLnByb2JlID0gbXRrX2NwdWZyZXFfaHdfZHJpdmVyX3Byb2JlLA0KPiA+ICsJLnJlbW92 ZSA9IG10a19jcHVmcmVxX2h3X2RyaXZlcl9yZW1vdmUsDQo+ID4gKwkuZHJpdmVyID0gew0KPiA+ ICsJCS5uYW1lID0gIm10ay1jcHVmcmVxLWh3IiwNCj4gPiArCQkub2ZfbWF0Y2hfdGFibGUgPSBt dGtfY3B1ZnJlcV9od19tYXRjaCwNCj4gPiArCX0sDQo+ID4gK307DQo+ID4gK21vZHVsZV9wbGF0 Zm9ybV9kcml2ZXIobXRrX2NwdWZyZXFfaHdfZHJpdmVyKTsNCj4gPiArDQo+ID4gK01PRFVMRV9E RVNDUklQVElPTigiTWVkaWF0ZWsgY3B1ZnJlcS1odyBkcml2ZXIiKTsNCj4gPiArTU9EVUxFX0xJ Q0VOU0UoIkdQTCB2MiIpOw0KPiANCj4gWW91IGNhbiBhZGQgTW9kdWxlLWF1dGhvciBhcyB3ZWxs IGhlcmUgaWYgeW91IHdhbnQuDQo+IA0KT0suDQo+ID4gZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGlu dXgvY3B1ZnJlcS5oIGIvaW5jbHVkZS9saW51eC9jcHVmcmVxLmgNCj4gPiBpbmRleCA5ZmQ3MTk0 Li40OTE2ZDcwIDEwMDY0NA0KPiA+IC0tLSBhL2luY2x1ZGUvbGludXgvY3B1ZnJlcS5oDQo+ID4g KysrIGIvaW5jbHVkZS9saW51eC9jcHVmcmVxLmgNCj4gPiBAQCAtMTMsNiArMTMsOCBAQA0KPiA+ ICAjaW5jbHVkZSA8bGludXgvY29tcGxldGlvbi5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgva29i amVjdC5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvbm90aWZpZXIuaD4NCj4gPiArI2luY2x1ZGUg PGxpbnV4L29mLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4NCj4gPiAgI2lu Y2x1ZGUgPGxpbnV4L3BtX3Fvcy5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4N Cj4gPiAgI2luY2x1ZGUgPGxpbnV4L3N5c2ZzLmg+DQo+ID4gQEAgLTEwMzYsNiArMTAzOCw0MyBA QCB2b2lkIGFyY2hfc2V0X2ZyZXFfc2NhbGUoY29uc3Qgc3RydWN0IGNwdW1hc2sgKmNwdXMsDQo+ ID4gIH0NCj4gPiAgI2VuZGlmDQo+ID4gIA0KPiA+ICsjaWZkZWYgQ09ORklHX0NQVV9GUkVRDQo+ IA0KPiBUaGVyZSBpcyBhbm90aGVyIENPTkZJR19DUFVfRlJFUSBhIGZldyBsaW5lcyBhYm92ZSwg cGxlYXNlIHVzZSB0aGUNCj4gc2FtZSBibG9jayBmb3IgdGhpcyByb3V0aW5lIGFzIHdlbGwuDQo+ IA0KT0ssIHdpbGwgbW92ZSBpdCB0byB0aGUgYWJvdmUuDQo+ID4gK3N0YXRpYyBpbmxpbmUgaW50 IG9mX3BlcmZfZG9tYWluX2dldF9zaGFyaW5nX2NwdW1hc2soaW50IGluZGV4LCBjb25zdCBjaGFy ICpsaXN0X25hbWUsDQo+ID4gKwkJCQkJCSAgICAgY29uc3QgY2hhciAqY2VsbF9uYW1lLA0KPiA+ ICsJCQkJCQkgICAgIHN0cnVjdCBjcHVtYXNrICpjcHVtYXNrKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1 Y3QgZGV2aWNlX25vZGUgKmNwdV9ucDsNCj4gPiArCXN0cnVjdCBvZl9waGFuZGxlX2FyZ3MgYXJn czsNCj4gPiArCWludCBjcHUsIHJldDsNCj4gPiArDQo+ID4gKwlmb3JfZWFjaF9wb3NzaWJsZV9j cHUoY3B1KSB7DQo+ID4gKwkJY3B1X25wID0gb2ZfY3B1X2RldmljZV9ub2RlX2dldChjcHUpOw0K PiA+ICsJCWlmICghY3B1X25wKQ0KPiA+ICsJCQljb250aW51ZTsNCj4gPiArDQo+ID4gKwkJcmV0 ID0gb2ZfcGFyc2VfcGhhbmRsZV93aXRoX2FyZ3MoY3B1X25wLCBsaXN0X25hbWUsDQo+ID4gKwkJ CQkJCSBjZWxsX25hbWUsIDAsDQo+ID4gKwkJCQkJCSAmYXJncyk7DQo+ID4gKw0KPiA+ICsJCW9m X25vZGVfcHV0KGNwdV9ucCk7DQo+ID4gKwkJaWYgKHJldCA8IDApDQo+ID4gKwkJCWNvbnRpbnVl Ow0KPiA+ICsNCj4gPiArCQlpZiAoaW5kZXggPT0gYXJncy5hcmdzWzBdKQ0KPiA+ICsJCQljcHVt YXNrX3NldF9jcHUoY3B1LCBjcHVtYXNrKTsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1cm4g MDsNCj4gPiArfQ0KPiA+ICsjZWxzZQ0KPiA+ICtzdGF0aWMgaW5saW5lIGludCBvZl9wZXJmX2Rv bWFpbl9nZXRfc2hhcmluZ19jcHVtYXNrKGludCBpbmRleCwgY29uc3QgY2hhciAqbGlzdF9uYW1l LA0KPiA+ICsJCQkJCQkgICAgIGNvbnN0IGNoYXIgKmNlbGxfbmFtZSwNCj4gPiArCQkJCQkJICAg ICBzdHJ1Y3QgY3B1bWFzayAqY3B1bWFzaykNCj4gPiArew0KPiA+ICsJcmV0dXJuIDA7DQo+IA0K PiAJcmV0dXJuIC1FT1BOT1RTVVBQOw0KPiANCj4gPiArfQ0KPiA+ICsjZW5kaWYNCj4gDQoNCg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4662EC432BE for ; Mon, 16 Aug 2021 13:04:22 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 121266328D for ; Mon, 16 Aug 2021 13:04:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 121266328D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Date:CC:To:From:Subject:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=xM9oQTRQuIqxcBfJHbmCWSBF/0wKmllntrjSIY81k40=; b=ChaZYli2p2L+O8 er0wsSV6XzyqDE79ddE9V2H2OsODvmlOAxi+6ZJGznXR0TNHSnedZpxultT4hRdkJxOFpg3jf5NYx zEQXjE3E6VU3c47hKBghrAalWzcXRdJcISNk0nyrMwG6XjA+2jSWjM1lAvEpgCC3t2W/fw2YTCdUT mMH4hmqFWDWVzYyKv6bnOMzCSv/Njm88KmIbp9nUDAfFgIz0FhriRdMOvCP3+UNYY255cSej5ceSe 0w+YKpl0SjErxc+qqOJDRZnS9iTUwwcCVvYkN+ZNxiVfJ3upjS2JfHwSO1MyrrU8CbI6LWbg1dmv8 hb1/M8OAGkYonvly0Adg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mFcFk-00H0vQ-Om; Mon, 16 Aug 2021 13:02:09 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mFcFa-00H0px-26; Mon, 16 Aug 2021 13:02:02 +0000 X-UUID: 429be09f2ce44f5da17557c444a19e24-20210816 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=JiUWHQhw3d/c8if14OCuLpHPMoZZhOFQBgPIahZNMuE=; b=OFjMW6op+2zwuImOItFOr6TUMVAQammj9xfTOEn5GxrkKdL8ooiKKBJvBVZH5nE2oPdYyfE/FDPeOK5LcFwV1mqwW95xpKTLgO2MZN9Z57bF4M57Y74IoMdDCnKO3IAetX012eJXmyKte8U0x0DNrYOqyHTptN5fCnEyv7nnDbk=; X-UUID: 429be09f2ce44f5da17557c444a19e24-20210816 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1259682483; Mon, 16 Aug 2021 06:01:52 -0700 Received: from MTKMBS06N1.mediatek.inc (172.21.101.129) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 16 Aug 2021 05:56:36 -0700 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs06n1.mediatek.inc (172.21.101.129) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 16 Aug 2021 20:56:34 +0800 Received: from [172.21.77.33] (172.21.77.33) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 16 Aug 2021 20:56:34 +0800 Message-ID: <1629118594.3246.13.camel@mtkswgap22> Subject: Re: [PATCH v13 2/2] cpufreq: mediatek-hw: Add support for CPUFREQ HW From: Hector Yuan To: Viresh Kumar CC: , , , "Rafael J. Wysocki" , Rob Herring , , , Date: Mon, 16 Aug 2021 20:56:34 +0800 In-Reply-To: <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7> References: <1627574891-26514-1-git-send-email-hector.yuan@mediatek.com> <1627574891-26514-3-git-send-email-hector.yuan@mediatek.com> <20210803071302.b4ttoqgqdq4dfmwe@vireshk-i7> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210816_060158_164643_322A88B8 X-CRM114-Status: GOOD ( 38.57 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Tue, 2021-08-03 at 12:43 +0530, Viresh Kumar wrote: > On 30-07-21, 00:08, Hector Yuan wrote: > > From: "Hector.Yuan" > > > > Add cpufreq HW support > > Please write a proper commit log, what you are adding and which SoCs > it will apply to. Also add a full stop (.) at the end. > OK, I will write down more details > > Signed-off-by: Hector.Yuan > > --- > > drivers/cpufreq/Kconfig.arm | 12 ++ > > drivers/cpufreq/Makefile | 1 + > > drivers/cpufreq/mediatek-cpufreq-hw.c | 357 +++++++++++++++++++++++++++++++++ > > include/linux/cpufreq.h | 39 ++++ > > The changes to cpufreq.h should be done in a separate patch. > OK, will separate .h to another patch > > diff --git a/drivers/cpufreq/mediatek-cpufreq-hw.c b/drivers/cpufreq/mediatek-cpufreq-hw.c > > new file mode 100644 > > index 0000000..ca50a3a > > --- /dev/null > > +++ b/drivers/cpufreq/mediatek-cpufreq-hw.c > > @@ -0,0 +1,357 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (c) 2020 MediaTek Inc. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define LUT_MAX_ENTRIES 32U > > +#define LUT_FREQ GENMASK(11, 0) > > +#define LUT_ROW_SIZE 0x4 > > +#define CPUFREQ_HW_STATUS BIT(0) > > +#define SVS_HW_STATUS BIT(1) > > +#define POLL_USEC 1000 > > +#define TIMEOUT_USEC 300000 > > + > > +enum { > > + REG_FREQ_LUT_TABLE, > > + REG_FREQ_ENABLE, > > + REG_FREQ_PERF_STATE, > > + REG_FREQ_HW_STATE, > > + REG_EM_POWER_TBL, > > + REG_FREQ_LATENCY, > > + > > + REG_ARRAY_SIZE, > > +}; > > + > > +struct cpufreq_mtk { > > + struct cpufreq_frequency_table *table; > > + void __iomem *reg_bases[REG_ARRAY_SIZE]; > > + int nr_opp; > > + cpumask_t related_cpus; > > +}; > > + > > +static const u16 cpufreq_mtk_offsets[REG_ARRAY_SIZE] = { > > + [REG_FREQ_LUT_TABLE] = 0x0, > > + [REG_FREQ_ENABLE] = 0x84, > > + [REG_FREQ_PERF_STATE] = 0x88, > > + [REG_FREQ_HW_STATE] = 0x8c, > > + [REG_EM_POWER_TBL] = 0x90, > > + [REG_FREQ_LATENCY] = 0x110, > > +}; > > + > > +static struct cpufreq_mtk *mtk_freq_domain_map[NR_CPUS]; > > + > > +static int __maybe_unused > > +mtk_cpufreq_get_cpu_power(unsigned long *mW, > > + unsigned long *KHz, struct device *cpu_dev) > > +{ > > + struct cpufreq_mtk *c; > > + struct cpufreq_policy *policy; > > + int i; > > + > > + policy = cpufreq_cpu_get_raw(cpu_dev->id); > > + if (!policy) > > + return 0; > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + > > + for (i = 0; i < c->nr_opp; i++) { > > + if (c->table[i].frequency < *KHz) > > + break; > > + } > > + i--; > > + > > + *KHz = c->table[i].frequency; > > + *mW = readl_relaxed(c->reg_bases[REG_EM_POWER_TBL] + > > + i * LUT_ROW_SIZE) / 1000; > > + > > + return 0; > > +} > > + > > +static int mtk_cpufreq_hw_target_index(struct cpufreq_policy *policy, > > + unsigned int index) > > +{ > > + struct cpufreq_mtk *c = policy->driver_data; > > + > > + writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]); > > + > > + return 0; > > +} > > + > > +static unsigned int mtk_cpufreq_hw_get(unsigned int cpu) > > +{ > > + struct cpufreq_mtk *c; > > + struct cpufreq_policy *policy; > > + unsigned int index; > > + > > + policy = cpufreq_cpu_get_raw(cpu); > > + if (!policy) > > + return 0; > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + > > + index = readl_relaxed(c->reg_bases[REG_FREQ_PERF_STATE]); > > + index = min(index, LUT_MAX_ENTRIES - 1); > > + > > + return c->table[index].frequency; > > +} > > + > > +static unsigned int mtk_cpufreq_hw_fast_switch(struct cpufreq_policy *policy, > > + unsigned int target_freq) > > +{ > > + struct cpufreq_mtk *c = policy->driver_data; > > + unsigned int index; > > + > > + index = cpufreq_table_find_index_dl(policy, target_freq); > > + > > + writel_relaxed(index, c->reg_bases[REG_FREQ_PERF_STATE]); > > + > > + return policy->freq_table[index].frequency; > > +} > > + > > +static int mtk_cpu_create_freq_table(struct platform_device *pdev, > > + struct cpufreq_mtk *c) > > +{ > > + struct device *dev = &pdev->dev; > > + void __iomem *base_table; > > + u32 data, i, freq, prev_freq = 0; > > + > > + c->table = devm_kcalloc(dev, LUT_MAX_ENTRIES + 1, > > + sizeof(*c->table), GFP_KERNEL); > > + if (!c->table) > > + return -ENOMEM; > > + > > + base_table = c->reg_bases[REG_FREQ_LUT_TABLE]; > > + > > + for (i = 0; i < LUT_MAX_ENTRIES; i++) { > > + data = readl_relaxed(base_table + (i * LUT_ROW_SIZE)); > > + freq = FIELD_GET(LUT_FREQ, data) * 1000; > > + > > + if (freq == prev_freq) > > + break; > > + > > + c->table[i].frequency = freq; > > + > > + dev_dbg(dev, "index=%d freq=%d\n", > > + i, c->table[i].frequency); > > Won't this fit in a single line ? > OK, will modify to single line > > + > > + prev_freq = freq; > > + } > > + > > + c->table[i].frequency = CPUFREQ_TABLE_END; > > + c->nr_opp = i; > > + > > + return 0; > > +} > > + > > +static int mtk_cpu_resources_init(struct platform_device *pdev, > > + unsigned int cpu, int index, > > + const u16 *offsets) > > +{ > > + struct cpufreq_mtk *c; > > + struct device *dev = &pdev->dev; > > + int ret, i; > > + void __iomem *base; > > + > > + if (mtk_freq_domain_map[cpu]) > > This should not happen anymore, isn't it ? > Will remove cpu map. > > + return 0; > > + > > + c = devm_kzalloc(dev, sizeof(*c), GFP_KERNEL); > > + if (!c) > > + return -ENOMEM; > > + > > + base = devm_platform_ioremap_resource(pdev, index); > > + if (IS_ERR(base)) > > + return PTR_ERR(base); > > + > > + for (i = REG_FREQ_LUT_TABLE; i < REG_ARRAY_SIZE; i++) > > + c->reg_bases[i] = base + offsets[i]; > > + > > + ret = of_perf_domain_get_sharing_cpumask(index, "performance-domains", > > Instead of parsing parsing "performance-domains" twice, I would rather > pass a CPU number here instead of index. > Sorry, could you give me more details? For now, will use index to parse per-cpu to related cpus.You mean pass policy->cpu or? Thanks. > > + "#performance-domain-cells", > > + &c->related_cpus); > > You could have directly passed policy->cpus here instead. > will replace it. > > + if (ret) { > > + dev_info(dev, "Domain-%d failed to get related CPUs\n", index); > > + return ret; > > + } > > + > > + ret = mtk_cpu_create_freq_table(pdev, c); > > + if (ret) { > > + dev_info(dev, "Domain-%d failed to create freq table\n", index); > > + return ret; > > + } > > + > > + mtk_freq_domain_map[cpu] = c; > > I will rather use policy->driver_data to store this now. > OK > > + > > + return 0; > > +} > > + > > +static int mtk_cpufreq_hw_cpu_init(struct cpufreq_policy *policy) > > +{ > > + struct platform_device *pdev = cpufreq_get_driver_data(); > > + struct cpufreq_mtk *c; > > + struct device *cpu_dev; > > + struct em_data_callback em_cb = EM_DATA_CB(mtk_cpufreq_get_cpu_power); > > + struct pm_qos_request *qos_request; > > + struct device_node *cpu_np; > > + struct of_phandle_args args; > > + const u16 *offsets; > > + unsigned int latency; > > + int sig, pwr_hw = CPUFREQ_HW_STATUS | SVS_HW_STATUS; > > + int ret; > > It looks much more organized when the variable definitions are in > decreasing order of their length, instead of the random order as it is > right now. > OK, will sort it. > > + > > + offsets = of_device_get_match_data(&pdev->dev); > > + if (!offsets) > > + return -EINVAL; > > + > > + cpu_np = of_cpu_device_node_get(policy->cpu); > > + if (!cpu_np) { > > + dev_info(&pdev->dev, "Failed to get cpu %d device\n", > > + policy->cpu); > > + return -ENODEV; > > + } > > + > > + ret = of_parse_phandle_with_args(cpu_np, "performance-domains", > > + "#performance-domain-cells", 0, > > + &args); > > + if (ret < 0) > > What about dropping cpu_np and same later in the code as well ? > OK, Will add it. > > + return ret; > > + > > + /* Get the bases of cpufreq for domains */ > > + ret = mtk_cpu_resources_init(pdev, policy->cpu, args.args[0], offsets); > > + if (ret) { > > + dev_info(&pdev->dev, "CPUFreq resource init failed\n"); > > + return ret; > > + } > > + > > + cpu_dev = get_cpu_device(policy->cpu); > > + if (!cpu_dev) { > > + pr_err("failed to get cpu%d device\n", policy->cpu); > > + return -ENODEV; > > + } > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + if (!c) { > > + pr_err("No scaling support for CPU%d\n", policy->cpu); > > + return -ENODEV; > > + } > > + > > + cpumask_copy(policy->cpus, &c->related_cpus); > > + > > + policy->freq_table = c->table; > > + policy->driver_data = c; > > Oh you already do this, you can remove mtk_freq_domain_map array now. > OK, will remove map. > > + > > + latency = readl_relaxed(c->reg_bases[REG_FREQ_LATENCY]); > > + if (!latency) > > + latency = CPUFREQ_ETERNAL; > > + > > + /* us convert to ns */ > > + policy->cpuinfo.transition_latency = latency * 1000; > > You want to multiple CPUFREQ_ETERNAL too ? > Yes, may be different power domain with different transition latency. > > + > > + policy->fast_switch_possible = true; > > + > > + qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL); > > This is a small structure, why not allocate it on stack instead ? > For qos part, we'd like to take more time to re-consider the SW flow and put this to another patch set.Is this okay to you? > > + if (!qos_request) > > + return -ENOMEM; > > + > > + /* Let CPUs leave idle-off state for SVS CPU initializing */ > > + cpu_latency_qos_add_request(qos_request, 0); > > + > > + /* HW should be in enabled state to proceed now */ > > + writel_relaxed(0x1, c->reg_bases[REG_FREQ_ENABLE]); > > + > > + if (readl_poll_timeout(c->reg_bases[REG_FREQ_HW_STATE], sig, > > + (sig & pwr_hw) == pwr_hw, POLL_USEC, > > + TIMEOUT_USEC)) { > > + if (!(sig & CPUFREQ_HW_STATUS)) { > > + pr_info("cpufreq hardware of CPU%d is not enabled\n", > > + policy->cpu); > > + return -ENODEV; > > + } > > + > > + pr_info("SVS of CPU%d is not enabled\n", policy->cpu); > > + } > > + > > + cpu_latency_qos_remove_request(qos_request); > > + > > + em_dev_register_perf_domain(cpu_dev, c->nr_opp, &em_cb, policy->cpus, true); > > + > > + kfree(qos_request); > > Why free after registering for em ? And also move the entire qos thing > into a separate routine instead of adding it to ->init(). > If you agree, we'll consider to put it in another patch set. > > + > > + return 0; > > +} > > + > > +static int mtk_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy) > > +{ > > + struct cpufreq_mtk *c; > > + > > + c = mtk_freq_domain_map[policy->cpu]; > > + > > + /* HW should be in paused state now */ > > + writel_relaxed(0x0, c->reg_bases[REG_FREQ_ENABLE]); > > Please make sure each and every resource is freed here and in probe on > failures. > OK, will free all resources as probe. > > + > > + return 0; > > +} > > + > > +static struct cpufreq_driver cpufreq_mtk_hw_driver = { > > + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | > > + CPUFREQ_HAVE_GOVERNOR_PER_POLICY | > > + CPUFREQ_IS_COOLING_DEV, > > + .verify = cpufreq_generic_frequency_table_verify, > > + .target_index = mtk_cpufreq_hw_target_index, > > + .get = mtk_cpufreq_hw_get, > > + .init = mtk_cpufreq_hw_cpu_init, > > + .exit = mtk_cpufreq_hw_cpu_exit, > > + .fast_switch = mtk_cpufreq_hw_fast_switch, > > + .name = "mtk-cpufreq-hw", > > + .attr = cpufreq_generic_attr, > > +}; > > + > > +static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev) > > +{ > > + int ret; > > + > > + cpufreq_mtk_hw_driver.driver_data = pdev; > > + > > + ret = cpufreq_register_driver(&cpufreq_mtk_hw_driver); > > + if (ret) { > > + dev_err(&pdev->dev, "CPUFreq HW driver failed to register\n"); > > + return ret; > > + } > > + > > + return 0; > > You can do return ret here and drop the earlier return and its {}. > okay. > > +} > > + > > +static int mtk_cpufreq_hw_driver_remove(struct platform_device *pdev) > > +{ > > + return cpufreq_unregister_driver(&cpufreq_mtk_hw_driver); > > +} > > + > > +static const struct of_device_id mtk_cpufreq_hw_match[] = { > > + { .compatible = "mediatek,cpufreq-hw", .data = &cpufreq_mtk_offsets }, > > + {} > > +}; > > + > > +static struct platform_driver mtk_cpufreq_hw_driver = { > > + .probe = mtk_cpufreq_hw_driver_probe, > > + .remove = mtk_cpufreq_hw_driver_remove, > > + .driver = { > > + .name = "mtk-cpufreq-hw", > > + .of_match_table = mtk_cpufreq_hw_match, > > + }, > > +}; > > +module_platform_driver(mtk_cpufreq_hw_driver); > > + > > +MODULE_DESCRIPTION("Mediatek cpufreq-hw driver"); > > +MODULE_LICENSE("GPL v2"); > > You can add Module-author as well here if you want. > OK. > > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h > > index 9fd7194..4916d70 100644 > > --- a/include/linux/cpufreq.h > > +++ b/include/linux/cpufreq.h > > @@ -13,6 +13,8 @@ > > #include > > #include > > #include > > +#include > > +#include > > #include > > #include > > #include > > @@ -1036,6 +1038,43 @@ void arch_set_freq_scale(const struct cpumask *cpus, > > } > > #endif > > > > +#ifdef CONFIG_CPU_FREQ > > There is another CONFIG_CPU_FREQ a few lines above, please use the > same block for this routine as well. > OK, will move it to the above. > > +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name, > > + const char *cell_name, > > + struct cpumask *cpumask) > > +{ > > + struct device_node *cpu_np; > > + struct of_phandle_args args; > > + int cpu, ret; > > + > > + for_each_possible_cpu(cpu) { > > + cpu_np = of_cpu_device_node_get(cpu); > > + if (!cpu_np) > > + continue; > > + > > + ret = of_parse_phandle_with_args(cpu_np, list_name, > > + cell_name, 0, > > + &args); > > + > > + of_node_put(cpu_np); > > + if (ret < 0) > > + continue; > > + > > + if (index == args.args[0]) > > + cpumask_set_cpu(cpu, cpumask); > > + } > > + > > + return 0; > > +} > > +#else > > +static inline int of_perf_domain_get_sharing_cpumask(int index, const char *list_name, > > + const char *cell_name, > > + struct cpumask *cpumask) > > +{ > > + return 0; > > return -EOPNOTSUPP; > > > +} > > +#endif > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel