From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751987AbbFNDUu (ORCPT ); Sat, 13 Jun 2015 23:20:50 -0400 Received: from m50-138.163.com ([123.125.50.138]:35013 "EHLO m50-138.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751412AbbFNDUk (ORCPT ); Sat, 13 Jun 2015 23:20:40 -0400 Message-ID: <557CF1D6.4090506@163.com> Date: Sun, 14 Jun 2015 11:15:34 +0800 From: Caesar Wang User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: Ulf Hansson , Caesar Wang CC: Mark Rutland , "devicetree@vger.kernel.org" , Ian Campbell , Kevin Hilman , Russell King - ARM Linux , =?UTF-8?B?SGVpa28gU3TDvA==?= =?UTF-8?B?Ym5lcg==?= , =?UTF-8?B?UGF3ZcWCIE1vbGw=?= , "linux-doc@vger.kernel.org" , "jinkun.hong" , Linus Walleij , Randy Dunlap , Tomasz Figa , "linux-kernel@vger.kernel.org" , "open list:ARM/Rockchip SoC..." , Rob Herring , Mark Brown , Doug Anderson , Kumar Gala , Grant Likely , Dmitry Torokhov , "linux-arm-kernel@lists.infradead.org" Subject: Re: [PATCH v14 2/3] power-domain: rockchip: add power domain driver References: <1429862868-14218-1-git-send-email-wxt@rock-chips.com> <1429862868-14218-3-git-send-email-wxt@rock-chips.com> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-CM-TRANSID: C9GowAC318PW8XxV_V9pCw--.1880S3 X-Coremail-Antispam: 1Uf129KBjvAXoW3Kr4xurWkGFW5AF1xGr1fXrb_yoW8Cw17Xo W3tF4Sqrn7Jr4UCrWUt348tryFk34kKFs7Aw1q9rsrCr1Yy3Wjgw4DGFWFvF4ruF4jkF1x A3WxAFsxAFW0yrWfn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxU-zBTUUUUU X-Originating-IP: [220.250.50.109] X-CM-SenderInfo: 5vdv3yhhz03qqrwthudrp/1tbiwBoZlVD+cP4y2gAAse Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Ulf, Thanks for your comments.:-) 在 2015年05月28日 18:38, Ulf Hansson 写道: > On 24 April 2015 at 10:07, Caesar Wang wrote: >> In order to meet high performance and low power requirements, a power >> management unit is designed or saving power when RK3288 in low power >> mode. >> The RK3288 PMU is dedicated for managing the power ot the whole chip. >> >> Signed-off-by: jinkun.hong >> Signed-off-by: Caesar Wang >> --- >> >> arch/arm/mach-rockchip/Kconfig | 1 + >> arch/arm/mach-rockchip/Makefile | 1 + >> arch/arm/mach-rockchip/pm_domains.c | 506 ++++++++++++++++++++++++++++++++++++ >> 3 files changed, 508 insertions(+) >> create mode 100644 arch/arm/mach-rockchip/pm_domains.c >> >> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig >> index ae4eb7c..578206b 100644 >> --- a/arch/arm/mach-rockchip/Kconfig >> +++ b/arch/arm/mach-rockchip/Kconfig >> @@ -15,6 +15,7 @@ config ARCH_ROCKCHIP >> select ROCKCHIP_TIMER >> select ARM_GLOBAL_TIMER >> select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK >> + select PM_GENERIC_DOMAINS if PM >> help >> Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs >> containing the RK2928, RK30xx and RK31xx series. >> diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile >> index 5c3a9b2..9c902d3 100644 >> --- a/arch/arm/mach-rockchip/Makefile >> +++ b/arch/arm/mach-rockchip/Makefile >> @@ -1,5 +1,6 @@ >> CFLAGS_platsmp.o := -march=armv7-a >> >> obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o >> +obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o >> obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o >> obj-$(CONFIG_SMP) += headsmp.o platsmp.o >> diff --git a/arch/arm/mach-rockchip/pm_domains.c b/arch/arm/mach-rockchip/pm_domains.c >> new file mode 100644 >> index 0000000..92d2569 >> --- /dev/null >> +++ b/arch/arm/mach-rockchip/pm_domains.c >> @@ -0,0 +1,506 @@ >> +/* >> + * Rockchip Generic power domain support. >> + * >> + * Copyright (c) 2014 ROCKCHIP, Co. Ltd. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include > clk-provider.h, why? The following is needed. _clk_get_name(clk) > >> +#include >> +#include >> +#include > Same comment as in patch1. I don't find this header. OK. Perhaps, Making a mistake. the missing the patch in here.(https://patchwork.kernel.org/patch/6266881/) >> + >> +struct rockchip_domain_info { >> + int pwr_mask; >> + int status_mask; >> + int req_mask; >> + int idle_mask; >> + int ack_mask; >> +}; >> + >> +struct rockchip_pmu_info { >> + u32 pwr_offset; >> + u32 status_offset; >> + u32 req_offset; >> + u32 idle_offset; >> + u32 ack_offset; >> + >> + u32 core_pwrcnt_offset; >> + u32 gpu_pwrcnt_offset; >> + >> + unsigned int core_power_transition_time; >> + unsigned int gpu_power_transition_time; >> + >> + int num_domains; >> + const struct rockchip_domain_info *domain_info; >> +}; >> + >> +struct rockchip_pm_domain { >> + struct generic_pm_domain genpd; >> + const struct rockchip_domain_info *info; >> + struct rockchip_pmu *pmu; >> + int num_clks; >> + struct clk *clks[]; >> +}; >> + >> +struct rockchip_pmu { >> + struct device *dev; >> + struct regmap *regmap; >> + const struct rockchip_pmu_info *info; >> + struct mutex mutex; /* mutex lock for pmu */ >> + struct genpd_onecell_data genpd_data; >> + struct generic_pm_domain *domains[]; >> +}; >> + >> +#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd) >> + >> +#define DOMAIN(pwr, status, req, idle, ack) \ >> +{ \ >> + .pwr_mask = BIT(pwr), \ >> + .status_mask = BIT(status), \ >> + .req_mask = BIT(req), \ >> + .idle_mask = BIT(idle), \ >> + .ack_mask = BIT(ack), \ >> +} >> + >> +#define DOMAIN_RK3288(pwr, status, req) \ >> + DOMAIN(pwr, status, req, req, (req) + 16) >> + >> +static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) >> +{ >> + struct rockchip_pmu *pmu = pd->pmu; >> + const struct rockchip_domain_info *pd_info = pd->info; >> + unsigned int val; >> + >> + regmap_read(pmu->regmap, pmu->info->idle_offset, &val); >> + return (val & pd_info->idle_mask) == pd_info->idle_mask; >> +} >> + >> +static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, >> + bool idle) >> +{ >> + const struct rockchip_domain_info *pd_info = pd->info; >> + struct rockchip_pmu *pmu = pd->pmu; >> + unsigned int val; >> + >> + regmap_update_bits(pmu->regmap, pmu->info->req_offset, >> + pd_info->req_mask, idle ? -1U : 0); >> + >> + dsb(); >> + >> + do { >> + regmap_read(pmu->regmap, pmu->info->ack_offset, &val); >> + } while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0)); >> + >> + while (rockchip_pmu_domain_is_idle(pd) != idle) >> + cpu_relax(); >> + >> + return 0; >> +} >> + >> +static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd) >> +{ >> + struct rockchip_pmu *pmu = pd->pmu; >> + unsigned int val; >> + >> + regmap_read(pmu->regmap, pmu->info->status_offset, &val); >> + >> + /* 1'b0: power on, 1'b1: power off */ >> + return !(val & pd->info->status_mask); >> +} >> + >> +static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, >> + bool on) >> +{ >> + struct rockchip_pmu *pmu = pd->pmu; >> + >> + regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, >> + pd->info->pwr_mask, on ? 0 : -1U); >> + >> + dsb(); >> + >> + while (rockchip_pmu_domain_is_on(pd) != on) >> + cpu_relax(); >> +} >> + >> +static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) >> +{ >> + int i; >> + >> + mutex_lock(&pd->pmu->mutex); > I don't quite understand why you need a lock, what are you protecting and why? Says: [ 3551.678762] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3551.899180] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3551.905958] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3551.912832] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3551.919730] rockchip_pd_power:139: mutex_lock [ 3551.924130] rockchip_pd_power:167,mutex_unlock [ 3563.827295] rockchip_pd_power:139: mutex_lock [ 3563.831753] rockchip_pd_power:167,mutex_unlock [ 3563.836216] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3564.058989] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3564.065659] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3564.072354] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3564.079047] rockchip_pd_power:139: mutex_lock [ 3564.083426] rockchip_pd_power:167,mutex_unlock [ 3611.665726] rockchip_pd_power:139: mutex_lock [ 3611.670206] rockchip_pd_power:167,mutex_unlock [ 3611.674692] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3611.899160] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3611.905938] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3611.912818] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3611.919689] rockchip_pd_power:139: mutex_lock [ 3611.924090] rockchip_pd_power:167,mutex_unlock [ 3623.848296] rockchip_pd_power:139: mutex_lock [ 3623.852752] rockchip_pd_power:167,mutex_unlock >> + >> + if (rockchip_pmu_domain_is_on(pd) != power_on) { >> + for (i = 0; i < pd->num_clks; i++) >> + clk_enable(pd->clks[i]); >> + >> + if (!power_on) { >> + /* FIXME: add code to save AXI_QOS */ >> + >> + /* if powering down, idle request to NIU first */ >> + rockchip_pmu_set_idle_request(pd, true); >> + } >> + >> + rockchip_do_pmu_set_power_domain(pd, power_on); >> + >> + if (power_on) { >> + /* if powering up, leave idle mode */ >> + rockchip_pmu_set_idle_request(pd, false); >> + >> + /* FIXME: add code to restore AXI_QOS */ >> + } >> + >> + for (i = pd->num_clks - 1; i >= 0; i--) >> + clk_disable(pd->clks[i]); >> + } >> + >> + mutex_unlock(&pd->pmu->mutex); >> + return 0; >> +} >> + >> +static int rockchip_pd_power_on(struct generic_pm_domain *domain) >> +{ >> + struct rockchip_pm_domain *pd = to_rockchip_pd(domain); >> + >> + return rockchip_pd_power(pd, true); >> +} >> + >> +static int rockchip_pd_power_off(struct generic_pm_domain *domain) >> +{ >> + struct rockchip_pm_domain *pd = to_rockchip_pd(domain); >> + >> + return rockchip_pd_power(pd, false); >> +} >> + >> +static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd, >> + struct device *dev) >> +{ >> + struct clk *clk; >> + int i; >> + int error; >> + >> + dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name); >> + >> + error = pm_clk_create(dev); >> + if (error) { >> + dev_err(dev, "pm_clk_create failed %d\n", error); >> + return error; >> + } >> + >> + i = 0; >> + while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) { > This loop adds all available device clocks to the PM clock list. I > wonder if this could be considered as a common thing and if so, we > might want to extend the pm_clk API with this. There are several reasons as follows: Firstly, the clocks need be turned off to save power when the system enter the suspend state. So we need to enumerate the clocks in the dts. In order to power domain can turn on and off. Secondly, the reset-circuit should reset be synchronous on rk3288, then sync revoked. So we need to enable clocks of all devices. >> + dev_dbg(dev, "adding clock '%s' to list of PM clocks\n", >> + __clk_get_name(clk)); >> + error = pm_clk_add_clk(dev, clk); >> + clk_put(clk); >> + if (error) { >> + dev_err(dev, "pm_clk_add_clk failed %d\n", error); >> + pm_clk_destroy(dev); >> + return error; >> + } >> + } >> + >> + return 0; >> +} >> + >> +static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd, >> + struct device *dev) >> +{ >> + dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name); >> + >> + pm_clk_destroy(dev); >> +} >> + >> +static int rockchip_pd_start_dev(struct device *dev) >> +{ >> + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); >> + >> + dev_dbg(dev, "starting device in power domain '%s'\n", genpd->name); >> + >> + return pm_clk_resume(dev); >> +} >> + >> +static int rockchip_pd_stop_dev(struct device *dev) >> +{ >> + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); >> + >> + dev_dbg(dev, "stopping device in power domain '%s'\n", genpd->name); >> + >> + return pm_clk_suspend(dev); >> +} >> + >> +static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, >> + struct device_node *node) >> +{ >> + const struct rockchip_domain_info *pd_info; >> + struct rockchip_pm_domain *pd; >> + struct clk *clk; >> + int clk_cnt; >> + int i; >> + u32 id; >> + int error; >> + >> + error = of_property_read_u32(node, "reg", &id); >> + if (error) { >> + dev_err(pmu->dev, >> + "%s: failed to retrieve domain id (reg): %d\n", >> + node->name, error); >> + return -EINVAL; >> + } >> + >> + if (id >= pmu->info->num_domains) { >> + dev_err(pmu->dev, "%s: invalid domain id %d\n", >> + node->name, id); >> + return -EINVAL; >> + } >> + >> + pd_info = &pmu->info->domain_info[id]; >> + if (!pd_info) { >> + dev_err(pmu->dev, "%s: undefined domain id %d\n", >> + node->name, id); >> + return -EINVAL; >> + } >> + >> + clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells"); >> + pd = devm_kzalloc(pmu->dev, >> + sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]), >> + GFP_KERNEL); >> + if (!pd) >> + return -ENOMEM; >> + >> + pd->info = pd_info; >> + pd->pmu = pmu; >> + >> + for (i = 0; i < clk_cnt; i++) { > This loop is similar to the one when creates the PM clock list in the > rockchip_pd_attach_dev(). > > What's the reason you don't want to use pm clk for these clocks? > Ditto. >> + clk = of_clk_get(node, i); >> + if (IS_ERR(clk)) { >> + error = PTR_ERR(clk); >> + dev_err(pmu->dev, >> + "%s: failed to get clk %s (index %d): %d\n", >> + node->name, __clk_get_name(clk), i, error); >> + goto err_out; >> + } >> + >> + error = clk_prepare(clk); >> + if (error) { >> + dev_err(pmu->dev, >> + "%s: failed to prepare clk %s (index %d): %d\n", >> + node->name, __clk_get_name(clk), i, error); >> + clk_put(clk); >> + goto err_out; >> + } >> + >> + pd->clks[pd->num_clks++] = clk; >> + >> + dev_dbg(pmu->dev, "added clock '%s' to domain '%s'\n", >> + __clk_get_name(clk), node->name); >> + } >> + >> + error = rockchip_pd_power(pd, true); >> + if (error) { >> + dev_err(pmu->dev, >> + "failed to power on domain '%s': %d\n", >> + node->name, error); >> + goto err_out; >> + } >> + >> + pd->genpd.name = node->name; >> + pd->genpd.power_off = rockchip_pd_power_off; >> + pd->genpd.power_on = rockchip_pd_power_on; >> + pd->genpd.attach_dev = rockchip_pd_attach_dev; >> + pd->genpd.detach_dev = rockchip_pd_detach_dev; >> + pd->genpd.dev_ops.start = rockchip_pd_start_dev; >> + pd->genpd.dev_ops.stop = rockchip_pd_stop_dev; > Instead of assigning the ->stop|start() callbacks, which do > pm_clk_suspend|resume(), just set the genpd->flags to > GENPD_FLAG_PM_CLK, and genpd will fix this for you. > Ditto. >> + pm_genpd_init(&pd->genpd, NULL, false); >> + >> + pmu->genpd_data.domains[id] = &pd->genpd; >> + return 0; >> + >> +err_out: >> + while (--i >= 0) { >> + clk_unprepare(pd->clks[i]); >> + clk_put(pd->clks[i]); >> + } >> + return error; >> +} >> + >> +static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd) >> +{ >> + int i; >> + >> + for (i = 0; i < pd->num_clks; i++) { >> + clk_unprepare(pd->clks[i]); > If you converted these clocks to be dealt with via the PM clk API, > pm_clk_destoy() would have replaced this loop. > >> + clk_put(pd->clks[i]); >> + } >> + >> + /* devm will free our memory */ >> +} >> + >> +static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu) >> +{ >> + struct generic_pm_domain *genpd; >> + struct rockchip_pm_domain *pd; >> + int i; >> + >> + for (i = 0; i < pmu->genpd_data.num_domains; i++) { >> + genpd = pmu->genpd_data.domains[i]; >> + if (genpd) { >> + pd = to_rockchip_pd(genpd); >> + rockchip_pm_remove_one_domain(pd); >> + } >> + } >> + >> + /* devm will free our memory */ >> +} >> + >> +static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu, >> + u32 domain_reg_offset, >> + unsigned int count) >> +{ >> + /* First configure domain power down transition count ... */ >> + regmap_write(pmu->regmap, domain_reg_offset, count); >> + /* ... and then power up count. */ >> + regmap_write(pmu->regmap, domain_reg_offset + 4, count); >> +} >> + >> +static int rockchip_pm_domain_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct device_node *np = dev->of_node; >> + struct device_node *node; >> + struct rockchip_pmu *pmu; >> + const struct of_device_id *match; >> + const struct rockchip_pmu_info *pmu_info; >> + int error; >> + >> + if (!np) { >> + dev_err(dev, "device tree node not found\n"); >> + return -ENXIO;/ > Nitpick: > It's more common to return -ENODEV here, you might want to change. OK. Thanks, Caesar >> + } >> + >> + match = of_match_device(dev->driver->of_match_table, dev); >> + if (!match || !match->data) { >> + dev_err(dev, "missing pmu data\n"); >> + return -EINVAL; >> + } >> + >> + pmu_info = match->data; >> + >> + pmu = devm_kzalloc(dev, >> + sizeof(*pmu) + >> + pmu_info->num_domains * sizeof(pmu->domains[0]), >> + GFP_KERNEL); >> + if (!pmu) >> + return -ENOMEM; >> + >> + pmu->dev = &pdev->dev; >> + mutex_init(&pmu->mutex); >> + >> + pmu->info = pmu_info; >> + >> + pmu->genpd_data.domains = pmu->domains; >> + pmu->genpd_data.num_domains = pmu_info->num_domains; >> + >> + node = of_parse_phandle(np, "rockchip,pmu", 0); >> + pmu->regmap = syscon_node_to_regmap(node); >> + of_node_put(node); >> + if (IS_ERR(pmu->regmap)) { >> + error = PTR_ERR(pmu->regmap); >> + dev_err(dev, "failed to get PMU regmap: %d\n", error); >> + return error; >> + } >> + >> + /* >> + * Configure power up and down transition delays for core >> + * and GPU domains. >> + */ >> + rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset, >> + pmu_info->core_power_transition_time); >> + rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset, >> + pmu_info->gpu_power_transition_time); >> + >> + error = -ENXIO; >> + >> + for_each_available_child_of_node(np, node) { >> + error = rockchip_pm_add_one_domain(pmu, node); >> + if (error) { >> + dev_err(dev, "failed to handle node %s: %d\n", >> + node->name, error); >> + goto err_out; >> + } >> + } >> + >> + if (error) { >> + dev_dbg(dev, "no power domains defined\n"); >> + goto err_out; >> + } >> + >> + of_genpd_add_provider_onecell(np, &pmu->genpd_data); >> + >> + return 0; >> + >> +err_out: >> + rockchip_pm_domain_cleanup(pmu); >> + return error; >> +} >> + >> +static const struct rockchip_domain_info rk3288_pm_domains[] = { >> + [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2), >> + [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4), >> + [RK3288_PD_VIDEO] = DOMAIN_RK3288(8, 8, 3), >> + [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9), >> +}; >> + >> +static const struct rockchip_pmu_info rk3288_pmu = { >> + .pwr_offset = 0x08, >> + .status_offset = 0x0c, >> + .req_offset = 0x10, >> + .idle_offset = 0x14, >> + .ack_offset = 0x14, >> + >> + .core_pwrcnt_offset = 0x34, >> + .gpu_pwrcnt_offset = 0x3c, >> + >> + .core_power_transition_time = 24, /* 1us */ >> + .gpu_power_transition_time = 24, /* 1us */ >> + >> + .num_domains = ARRAY_SIZE(rk3288_pm_domains), >> + .domain_info = rk3288_pm_domains, >> +}; >> + >> +static const struct of_device_id rockchip_pm_domain_dt_match[] = { >> + { >> + .compatible = "rockchip,rk3288-power-controller", >> + .data = (void *)&rk3288_pmu, >> + }, >> + { /* sentinel */ }, >> +}; >> + >> +static struct platform_driver rockchip_pm_domain_driver = { >> + .probe = rockchip_pm_domain_probe, >> + .driver = { >> + .name = "rockchip-pm-domain", >> + .of_match_table = rockchip_pm_domain_dt_match, >> + /* >> + * We can't forcibly eject devices form power domain, >> + * so we can't really remove power domains once they >> + * were added. >> + */ >> + .suppress_bind_attrs = true, >> + }, >> +}; >> + >> +static int __init rockchip_pm_domain_drv_register(void) >> +{ >> + return platform_driver_register(&rockchip_pm_domain_driver); >> +} >> +postcore_initcall(rockchip_pm_domain_drv_register); >> -- >> 1.9.1 >> > Kind regards > Uffe > > _______________________________________________ > Linux-rockchip mailing list > Linux-rockchip@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-rockchip From mboxrd@z Thu Jan 1 00:00:00 1970 From: Caesar Wang Subject: Re: [PATCH v14 2/3] power-domain: rockchip: add power domain driver Date: Sun, 14 Jun 2015 11:15:34 +0800 Message-ID: <557CF1D6.4090506@163.com> References: <1429862868-14218-1-git-send-email-wxt@rock-chips.com> <1429862868-14218-3-git-send-email-wxt@rock-chips.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+glpar-linux-rockchip=m.gmane.org-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org To: Ulf Hansson , Caesar Wang Cc: Mark Rutland , "devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , Kevin Hilman , Russell King - ARM Linux , =?UTF-8?B?SGVpa28gU3TDvA==?= =?UTF-8?B?Ym5lcg==?= , =?UTF-8?B?UGF3ZcWCIE1vbGw=?= , Ian Campbell , "jinkun.hong" , Linus Walleij , "linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , Tomasz Figa , "linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org" , "open list:ARM/Rockchip SoC..." , Rob Herring , Mark Brown , Randy Dunlap , Doug Anderson , Kumar Gala , Grant Likely List-Id: devicetree@vger.kernel.org VWxmLAoKVGhhbmtzIGZvciB5b3VyIGNvbW1lbnRzLjotKQoKCgrlnKggMjAxNeW5tDA15pyIMjjm l6UgMTg6MzgsIFVsZiBIYW5zc29uIOWGmemBkzoKPiBPbiAyNCBBcHJpbCAyMDE1IGF0IDEwOjA3 LCBDYWVzYXIgV2FuZyA8d3h0QHJvY2stY2hpcHMuY29tPiB3cm90ZToKPj4gSW4gb3JkZXIgdG8g bWVldCBoaWdoIHBlcmZvcm1hbmNlIGFuZCBsb3cgcG93ZXIgcmVxdWlyZW1lbnRzLCBhIHBvd2Vy Cj4+IG1hbmFnZW1lbnQgdW5pdCBpcyBkZXNpZ25lZCBvciBzYXZpbmcgcG93ZXIgd2hlbiBSSzMy ODggaW4gbG93IHBvd2VyCj4+IG1vZGUuCj4+IFRoZSBSSzMyODggUE1VIGlzIGRlZGljYXRlZCBm b3IgbWFuYWdpbmcgdGhlIHBvd2VyIG90IHRoZSB3aG9sZSBjaGlwLgo+Pgo+PiBTaWduZWQtb2Zm LWJ5OiBqaW5rdW4uaG9uZyA8amlua3VuLmhvbmdAcm9jay1jaGlwcy5jb20+Cj4+IFNpZ25lZC1v ZmYtYnk6IENhZXNhciBXYW5nIDx3eHRAcm9jay1jaGlwcy5jb20+Cj4+IC0tLQo+Pgo+PiAgIGFy Y2gvYXJtL21hY2gtcm9ja2NoaXAvS2NvbmZpZyAgICAgIHwgICAxICsKPj4gICBhcmNoL2FybS9t YWNoLXJvY2tjaGlwL01ha2VmaWxlICAgICB8ICAgMSArCj4+ICAgYXJjaC9hcm0vbWFjaC1yb2Nr Y2hpcC9wbV9kb21haW5zLmMgfCA1MDYgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrCj4+ICAgMyBmaWxlcyBjaGFuZ2VkLCA1MDggaW5zZXJ0aW9ucygrKQo+PiAgIGNyZWF0ZSBt b2RlIDEwMDY0NCBhcmNoL2FybS9tYWNoLXJvY2tjaGlwL3BtX2RvbWFpbnMuYwo+Pgo+PiBkaWZm IC0tZ2l0IGEvYXJjaC9hcm0vbWFjaC1yb2NrY2hpcC9LY29uZmlnIGIvYXJjaC9hcm0vbWFjaC1y b2NrY2hpcC9LY29uZmlnCj4+IGluZGV4IGFlNGViN2MuLjU3ODIwNmIgMTAwNjQ0Cj4+IC0tLSBh L2FyY2gvYXJtL21hY2gtcm9ja2NoaXAvS2NvbmZpZwo+PiArKysgYi9hcmNoL2FybS9tYWNoLXJv Y2tjaGlwL0tjb25maWcKPj4gQEAgLTE1LDYgKzE1LDcgQEAgY29uZmlnIEFSQ0hfUk9DS0NISVAK Pj4gICAgICAgICAgc2VsZWN0IFJPQ0tDSElQX1RJTUVSCj4+ICAgICAgICAgIHNlbGVjdCBBUk1f R0xPQkFMX1RJTUVSCj4+ICAgICAgICAgIHNlbGVjdCBDTEtTUkNfQVJNX0dMT0JBTF9USU1FUl9T Q0hFRF9DTE9DSwo+PiArICAgICAgIHNlbGVjdCBQTV9HRU5FUklDX0RPTUFJTlMgaWYgUE0KPj4g ICAgICAgICAgaGVscAo+PiAgICAgICAgICAgIFN1cHBvcnQgZm9yIFJvY2tjaGlwJ3MgQ29ydGV4 LUE5IFNpbmdsZS10by1RdWFkLUNvcmUtU29Dcwo+PiAgICAgICAgICAgIGNvbnRhaW5pbmcgdGhl IFJLMjkyOCwgUkszMHh4IGFuZCBSSzMxeHggc2VyaWVzLgo+PiBkaWZmIC0tZ2l0IGEvYXJjaC9h cm0vbWFjaC1yb2NrY2hpcC9NYWtlZmlsZSBiL2FyY2gvYXJtL21hY2gtcm9ja2NoaXAvTWFrZWZp bGUKPj4gaW5kZXggNWMzYTliMi4uOWM5MDJkMyAxMDA2NDQKPj4gLS0tIGEvYXJjaC9hcm0vbWFj aC1yb2NrY2hpcC9NYWtlZmlsZQo+PiArKysgYi9hcmNoL2FybS9tYWNoLXJvY2tjaGlwL01ha2Vm aWxlCj4+IEBAIC0xLDUgKzEsNiBAQAo+PiAgIENGTEFHU19wbGF0c21wLm8gOj0gLW1hcmNoPWFy bXY3LWEKPj4KPj4gICBvYmotJChDT05GSUdfQVJDSF9ST0NLQ0hJUCkgKz0gcm9ja2NoaXAubwo+ PiArb2JqLSQoQ09ORklHX1BNX0dFTkVSSUNfRE9NQUlOUykgKz0gcG1fZG9tYWlucy5vCj4+ICAg b2JqLSQoQ09ORklHX1BNX1NMRUVQKSArPSBwbS5vIHNsZWVwLm8KPj4gICBvYmotJChDT05GSUdf U01QKSArPSBoZWFkc21wLm8gcGxhdHNtcC5vCj4+IGRpZmYgLS1naXQgYS9hcmNoL2FybS9tYWNo LXJvY2tjaGlwL3BtX2RvbWFpbnMuYyBiL2FyY2gvYXJtL21hY2gtcm9ja2NoaXAvcG1fZG9tYWlu cy5jCj4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4+IGluZGV4IDAwMDAwMDAuLjkyZDI1NjkKPj4g LS0tIC9kZXYvbnVsbAo+PiArKysgYi9hcmNoL2FybS9tYWNoLXJvY2tjaGlwL3BtX2RvbWFpbnMu Ywo+PiBAQCAtMCwwICsxLDUwNiBAQAo+PiArLyoKPj4gKyAqIFJvY2tjaGlwIEdlbmVyaWMgcG93 ZXIgZG9tYWluIHN1cHBvcnQuCj4+ICsgKgo+PiArICogQ29weXJpZ2h0IChjKSAyMDE0IFJPQ0tD SElQLCBDby4gTHRkLgo+PiArICoKPj4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJl OyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cj4+ICsgKiBpdCB1bmRlciB0 aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcwo+ PiArICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCj4+ICsgKi8K Pj4gKwo+PiArI2luY2x1ZGUgPGxpbnV4L2lvLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+ Cj4+ICsjaW5jbHVkZSA8bGludXgvcG1fY2xvY2suaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9wbV9k b21haW4uaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9vZl9hZGRyZXNzLmg+Cj4+ICsjaW5jbHVkZSA8 bGludXgvb2ZfcGxhdGZvcm0uaD4KPj4gKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KPj4gKyNpbmNs dWRlIDxsaW51eC9jbGstcHJvdmlkZXIuaD4KPiBjbGstcHJvdmlkZXIuaCwgd2h5PwoKVGhlIGZv bGxvd2luZyBpcyBuZWVkZWQuCgpfY2xrX2dldF9uYW1lKGNsaykKCgo+Cj4+ICsjaW5jbHVkZSA8 bGludXgvcmVnbWFwLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbWZkL3N5c2Nvbi5oPgo+PiArI2lu Y2x1ZGUgPGR0LWJpbmRpbmdzL3Bvd2VyLWRvbWFpbi9yazMyODguaD4KPiBTYW1lIGNvbW1lbnQg YXMgaW4gcGF0Y2gxLiBJIGRvbid0IGZpbmQgdGhpcyBoZWFkZXIuCgpPSy4KUGVyaGFwcywgTWFr aW5nIGEgbWlzdGFrZS4gdGhlIG1pc3NpbmcgdGhlIHBhdGNoIGluIApoZXJlLihodHRwczovL3Bh dGNod29yay5rZXJuZWwub3JnL3BhdGNoLzYyNjY4ODEvKQo+PiArCj4+ICtzdHJ1Y3Qgcm9ja2No aXBfZG9tYWluX2luZm8gewo+PiArICAgICAgIGludCBwd3JfbWFzazsKPj4gKyAgICAgICBpbnQg c3RhdHVzX21hc2s7Cj4+ICsgICAgICAgaW50IHJlcV9tYXNrOwo+PiArICAgICAgIGludCBpZGxl X21hc2s7Cj4+ICsgICAgICAgaW50IGFja19tYXNrOwo+PiArfTsKPj4gKwo+PiArc3RydWN0IHJv Y2tjaGlwX3BtdV9pbmZvIHsKPj4gKyAgICAgICB1MzIgcHdyX29mZnNldDsKPj4gKyAgICAgICB1 MzIgc3RhdHVzX29mZnNldDsKPj4gKyAgICAgICB1MzIgcmVxX29mZnNldDsKPj4gKyAgICAgICB1 MzIgaWRsZV9vZmZzZXQ7Cj4+ICsgICAgICAgdTMyIGFja19vZmZzZXQ7Cj4+ICsKPj4gKyAgICAg ICB1MzIgY29yZV9wd3JjbnRfb2Zmc2V0Owo+PiArICAgICAgIHUzMiBncHVfcHdyY250X29mZnNl dDsKPj4gKwo+PiArICAgICAgIHVuc2lnbmVkIGludCBjb3JlX3Bvd2VyX3RyYW5zaXRpb25fdGlt ZTsKPj4gKyAgICAgICB1bnNpZ25lZCBpbnQgZ3B1X3Bvd2VyX3RyYW5zaXRpb25fdGltZTsKPj4g Kwo+PiArICAgICAgIGludCBudW1fZG9tYWluczsKPj4gKyAgICAgICBjb25zdCBzdHJ1Y3Qgcm9j a2NoaXBfZG9tYWluX2luZm8gKmRvbWFpbl9pbmZvOwo+PiArfTsKPj4gKwo+PiArc3RydWN0IHJv Y2tjaGlwX3BtX2RvbWFpbiB7Cj4+ICsgICAgICAgc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluIGdl bnBkOwo+PiArICAgICAgIGNvbnN0IHN0cnVjdCByb2NrY2hpcF9kb21haW5faW5mbyAqaW5mbzsK Pj4gKyAgICAgICBzdHJ1Y3Qgcm9ja2NoaXBfcG11ICpwbXU7Cj4+ICsgICAgICAgaW50IG51bV9j bGtzOwo+PiArICAgICAgIHN0cnVjdCBjbGsgKmNsa3NbXTsKPj4gK307Cj4+ICsKPj4gK3N0cnVj dCByb2NrY2hpcF9wbXUgewo+PiArICAgICAgIHN0cnVjdCBkZXZpY2UgKmRldjsKPj4gKyAgICAg ICBzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7Cj4+ICsgICAgICAgY29uc3Qgc3RydWN0IHJvY2tjaGlw X3BtdV9pbmZvICppbmZvOwo+PiArICAgICAgIHN0cnVjdCBtdXRleCBtdXRleDsgLyogbXV0ZXgg bG9jayBmb3IgcG11ICovCj4+ICsgICAgICAgc3RydWN0IGdlbnBkX29uZWNlbGxfZGF0YSBnZW5w ZF9kYXRhOwo+PiArICAgICAgIHN0cnVjdCBnZW5lcmljX3BtX2RvbWFpbiAqZG9tYWluc1tdOwo+ PiArfTsKPj4gKwo+PiArI2RlZmluZSB0b19yb2NrY2hpcF9wZChncGQpIGNvbnRhaW5lcl9vZihn cGQsIHN0cnVjdCByb2NrY2hpcF9wbV9kb21haW4sIGdlbnBkKQo+PiArCj4+ICsjZGVmaW5lIERP TUFJTihwd3IsIHN0YXR1cywgcmVxLCBpZGxlLCBhY2spICAgIFwKPj4gK3sgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAo+PiArICAgICAgIC5wd3JfbWFzayA9 IEJJVChwd3IpLCAgICAgICAgICAgICAgICAgICBcCj4+ICsgICAgICAgLnN0YXR1c19tYXNrID0g QklUKHN0YXR1cyksICAgICAgICAgICAgIFwKPj4gKyAgICAgICAucmVxX21hc2sgPSBCSVQocmVx KSwgICAgICAgICAgICAgICAgICAgXAo+PiArICAgICAgIC5pZGxlX21hc2sgPSBCSVQoaWRsZSks ICAgICAgICAgICAgICAgICBcCj4+ICsgICAgICAgLmFja19tYXNrID0gQklUKGFjayksICAgICAg ICAgICAgICAgICAgIFwKPj4gK30KPj4gKwo+PiArI2RlZmluZSBET01BSU5fUkszMjg4KHB3ciwg c3RhdHVzLCByZXEpICAgICAgICAgICAgICAgIFwKPj4gKyAgICAgICBET01BSU4ocHdyLCBzdGF0 dXMsIHJlcSwgcmVxLCAocmVxKSArIDE2KQo+PiArCj4+ICtzdGF0aWMgYm9vbCByb2NrY2hpcF9w bXVfZG9tYWluX2lzX2lkbGUoc3RydWN0IHJvY2tjaGlwX3BtX2RvbWFpbiAqcGQpCj4+ICt7Cj4+ ICsgICAgICAgc3RydWN0IHJvY2tjaGlwX3BtdSAqcG11ID0gcGQtPnBtdTsKPj4gKyAgICAgICBj b25zdCBzdHJ1Y3Qgcm9ja2NoaXBfZG9tYWluX2luZm8gKnBkX2luZm8gPSBwZC0+aW5mbzsKPj4g KyAgICAgICB1bnNpZ25lZCBpbnQgdmFsOwo+PiArCj4+ICsgICAgICAgcmVnbWFwX3JlYWQocG11 LT5yZWdtYXAsIHBtdS0+aW5mby0+aWRsZV9vZmZzZXQsICZ2YWwpOwo+PiArICAgICAgIHJldHVy biAodmFsICYgcGRfaW5mby0+aWRsZV9tYXNrKSA9PSBwZF9pbmZvLT5pZGxlX21hc2s7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcm9ja2NoaXBfcG11X3NldF9pZGxlX3JlcXVlc3Qoc3RydWN0 IHJvY2tjaGlwX3BtX2RvbWFpbiAqcGQsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgYm9vbCBpZGxlKQo+PiArewo+PiArICAgICAgIGNvbnN0IHN0cnVjdCByb2Nr Y2hpcF9kb21haW5faW5mbyAqcGRfaW5mbyA9IHBkLT5pbmZvOwo+PiArICAgICAgIHN0cnVjdCBy b2NrY2hpcF9wbXUgKnBtdSA9IHBkLT5wbXU7Cj4+ICsgICAgICAgdW5zaWduZWQgaW50IHZhbDsK Pj4gKwo+PiArICAgICAgIHJlZ21hcF91cGRhdGVfYml0cyhwbXUtPnJlZ21hcCwgcG11LT5pbmZv LT5yZXFfb2Zmc2V0LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICBwZF9pbmZvLT5yZXFf bWFzaywgaWRsZSA/IC0xVSA6IDApOwo+PiArCj4+ICsgICAgICAgZHNiKCk7Cj4+ICsKPj4gKyAg ICAgICBkbyB7Cj4+ICsgICAgICAgICAgICAgICByZWdtYXBfcmVhZChwbXUtPnJlZ21hcCwgcG11 LT5pbmZvLT5hY2tfb2Zmc2V0LCAmdmFsKTsKPj4gKyAgICAgICB9IHdoaWxlICgodmFsICYgcGRf aW5mby0+YWNrX21hc2spICE9IChpZGxlID8gcGRfaW5mby0+YWNrX21hc2sgOiAwKSk7Cj4+ICsK Pj4gKyAgICAgICB3aGlsZSAocm9ja2NoaXBfcG11X2RvbWFpbl9pc19pZGxlKHBkKSAhPSBpZGxl KQo+PiArICAgICAgICAgICAgICAgY3B1X3JlbGF4KCk7Cj4+ICsKPj4gKyAgICAgICByZXR1cm4g MDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGJvb2wgcm9ja2NoaXBfcG11X2RvbWFpbl9pc19vbihz dHJ1Y3Qgcm9ja2NoaXBfcG1fZG9tYWluICpwZCkKPj4gK3sKPj4gKyAgICAgICBzdHJ1Y3Qgcm9j a2NoaXBfcG11ICpwbXUgPSBwZC0+cG11Owo+PiArICAgICAgIHVuc2lnbmVkIGludCB2YWw7Cj4+ ICsKPj4gKyAgICAgICByZWdtYXBfcmVhZChwbXUtPnJlZ21hcCwgcG11LT5pbmZvLT5zdGF0dXNf b2Zmc2V0LCAmdmFsKTsKPj4gKwo+PiArICAgICAgIC8qIDEnYjA6IHBvd2VyIG9uLCAxJ2IxOiBw b3dlciBvZmYgKi8KPj4gKyAgICAgICByZXR1cm4gISh2YWwgJiBwZC0+aW5mby0+c3RhdHVzX21h c2spOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCByb2NrY2hpcF9kb19wbXVfc2V0X3Bvd2Vy X2RvbWFpbihzdHJ1Y3Qgcm9ja2NoaXBfcG1fZG9tYWluICpwZCwKPj4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBvbikKPj4gK3sKPj4gKyAgICAgICBz dHJ1Y3Qgcm9ja2NoaXBfcG11ICpwbXUgPSBwZC0+cG11Owo+PiArCj4+ICsgICAgICAgcmVnbWFw X3VwZGF0ZV9iaXRzKHBtdS0+cmVnbWFwLCBwbXUtPmluZm8tPnB3cl9vZmZzZXQsCj4+ICsgICAg ICAgICAgICAgICAgICAgICAgICAgIHBkLT5pbmZvLT5wd3JfbWFzaywgb24gPyAwIDogLTFVKTsK Pj4gKwo+PiArICAgICAgIGRzYigpOwo+PiArCj4+ICsgICAgICAgd2hpbGUgKHJvY2tjaGlwX3Bt dV9kb21haW5faXNfb24ocGQpICE9IG9uKQo+PiArICAgICAgICAgICAgICAgY3B1X3JlbGF4KCk7 Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcm9ja2NoaXBfcGRfcG93ZXIoc3RydWN0IHJvY2tj aGlwX3BtX2RvbWFpbiAqcGQsIGJvb2wgcG93ZXJfb24pCj4+ICt7Cj4+ICsgICAgICAgaW50IGk7 Cj4+ICsKPj4gKyAgICAgICBtdXRleF9sb2NrKCZwZC0+cG11LT5tdXRleCk7Cj4gSSBkb24ndCBx dWl0ZSB1bmRlcnN0YW5kIHdoeSB5b3UgbmVlZCBhIGxvY2ssIHdoYXQgYXJlIHlvdSBwcm90ZWN0 aW5nIGFuZCB3aHk/CgpTYXlzOgpbIDM1NTEuNjc4NzYyXSBtYWxpIGZmYTMwMDAwLmdwdTogc3Rh cnRpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM1NTEuODk5MTgwXSBtYWxp IGZmYTMwMDAwLmdwdTogc3RvcHBpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1Jwpb IDM1NTEuOTA1OTU4XSBtYWxpIGZmYTMwMDAwLmdwdTogc3RhcnRpbmcgZGV2aWNlIGluIHBvd2Vy IGRvbWFpbiAncGRfZ3B1JwpbIDM1NTEuOTEyODMyXSBtYWxpIGZmYTMwMDAwLmdwdTogc3RvcHBp bmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM1NTEuOTE5NzMwXSByb2NrY2hp cF9wZF9wb3dlcjoxMzk6IG11dGV4X2xvY2sKWyAzNTUxLjkyNDEzMF0gcm9ja2NoaXBfcGRfcG93 ZXI6MTY3LG11dGV4X3VubG9jawpbIDM1NjMuODI3Mjk1XSByb2NrY2hpcF9wZF9wb3dlcjoxMzk6 IG11dGV4X2xvY2sKWyAzNTYzLjgzMTc1M10gcm9ja2NoaXBfcGRfcG93ZXI6MTY3LG11dGV4X3Vu bG9jawpbIDM1NjMuODM2MjE2XSBtYWxpIGZmYTMwMDAwLmdwdTogc3RhcnRpbmcgZGV2aWNlIGlu IHBvd2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM1NjQuMDU4OTg5XSBtYWxpIGZmYTMwMDAwLmdwdTog c3RvcHBpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM1NjQuMDY1NjU5XSBt YWxpIGZmYTMwMDAwLmdwdTogc3RhcnRpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1 JwpbIDM1NjQuMDcyMzU0XSBtYWxpIGZmYTMwMDAwLmdwdTogc3RvcHBpbmcgZGV2aWNlIGluIHBv d2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM1NjQuMDc5MDQ3XSByb2NrY2hpcF9wZF9wb3dlcjoxMzk6 IG11dGV4X2xvY2sKWyAzNTY0LjA4MzQyNl0gcm9ja2NoaXBfcGRfcG93ZXI6MTY3LG11dGV4X3Vu bG9jawpbIDM2MTEuNjY1NzI2XSByb2NrY2hpcF9wZF9wb3dlcjoxMzk6IG11dGV4X2xvY2sKWyAz NjExLjY3MDIwNl0gcm9ja2NoaXBfcGRfcG93ZXI6MTY3LG11dGV4X3VubG9jawpbIDM2MTEuNjc0 NjkyXSBtYWxpIGZmYTMwMDAwLmdwdTogc3RhcnRpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAn cGRfZ3B1JwpbIDM2MTEuODk5MTYwXSBtYWxpIGZmYTMwMDAwLmdwdTogc3RvcHBpbmcgZGV2aWNl IGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM2MTEuOTA1OTM4XSBtYWxpIGZmYTMwMDAwLmdw dTogc3RhcnRpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRfZ3B1JwpbIDM2MTEuOTEyODE4 XSBtYWxpIGZmYTMwMDAwLmdwdTogc3RvcHBpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAncGRf Z3B1JwpbIDM2MTEuOTE5Njg5XSByb2NrY2hpcF9wZF9wb3dlcjoxMzk6IG11dGV4X2xvY2sKWyAz NjExLjkyNDA5MF0gcm9ja2NoaXBfcGRfcG93ZXI6MTY3LG11dGV4X3VubG9jawpbIDM2MjMuODQ4 Mjk2XSByb2NrY2hpcF9wZF9wb3dlcjoxMzk6IG11dGV4X2xvY2sKWyAzNjIzLjg1Mjc1Ml0gcm9j a2NoaXBfcGRfcG93ZXI6MTY3LG11dGV4X3VubG9jawoKCgo+PiArCj4+ICsgICAgICAgaWYgKHJv Y2tjaGlwX3BtdV9kb21haW5faXNfb24ocGQpICE9IHBvd2VyX29uKSB7Cj4+ICsgICAgICAgICAg ICAgICBmb3IgKGkgPSAwOyBpIDwgcGQtPm51bV9jbGtzOyBpKyspCj4+ICsgICAgICAgICAgICAg ICAgICAgICAgIGNsa19lbmFibGUocGQtPmNsa3NbaV0pOwo+PiArCj4+ICsgICAgICAgICAgICAg ICBpZiAoIXBvd2VyX29uKSB7Cj4+ICsgICAgICAgICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBh ZGQgY29kZSB0byBzYXZlIEFYSV9RT1MgKi8KPj4gKwo+PiArICAgICAgICAgICAgICAgICAgICAg ICAvKiBpZiBwb3dlcmluZyBkb3duLCBpZGxlIHJlcXVlc3QgdG8gTklVIGZpcnN0ICovCj4+ICsg ICAgICAgICAgICAgICAgICAgICAgIHJvY2tjaGlwX3BtdV9zZXRfaWRsZV9yZXF1ZXN0KHBkLCB0 cnVlKTsKPj4gKyAgICAgICAgICAgICAgIH0KPj4gKwo+PiArICAgICAgICAgICAgICAgcm9ja2No aXBfZG9fcG11X3NldF9wb3dlcl9kb21haW4ocGQsIHBvd2VyX29uKTsKPj4gKwo+PiArICAgICAg ICAgICAgICAgaWYgKHBvd2VyX29uKSB7Cj4+ICsgICAgICAgICAgICAgICAgICAgICAgIC8qIGlm IHBvd2VyaW5nIHVwLCBsZWF2ZSBpZGxlIG1vZGUgKi8KPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgcm9ja2NoaXBfcG11X3NldF9pZGxlX3JlcXVlc3QocGQsIGZhbHNlKTsKPj4gKwo+PiArICAg ICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogYWRkIGNvZGUgdG8gcmVzdG9yZSBBWElfUU9T ICovCj4+ICsgICAgICAgICAgICAgICB9Cj4+ICsKPj4gKyAgICAgICAgICAgICAgIGZvciAoaSA9 IHBkLT5udW1fY2xrcyAtIDE7IGkgPj0gMDsgaS0tKQo+PiArICAgICAgICAgICAgICAgICAgICAg ICBjbGtfZGlzYWJsZShwZC0+Y2xrc1tpXSk7Cj4+ICsgICAgICAgfQo+PiArCj4+ICsgICAgICAg bXV0ZXhfdW5sb2NrKCZwZC0+cG11LT5tdXRleCk7Cj4+ICsgICAgICAgcmV0dXJuIDA7Cj4+ICt9 Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcm9ja2NoaXBfcGRfcG93ZXJfb24oc3RydWN0IGdlbmVyaWNf cG1fZG9tYWluICpkb21haW4pCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0IHJvY2tjaGlwX3BtX2Rv bWFpbiAqcGQgPSB0b19yb2NrY2hpcF9wZChkb21haW4pOwo+PiArCj4+ICsgICAgICAgcmV0dXJu IHJvY2tjaGlwX3BkX3Bvd2VyKHBkLCB0cnVlKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBy b2NrY2hpcF9wZF9wb3dlcl9vZmYoc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluICpkb21haW4pCj4+ ICt7Cj4+ICsgICAgICAgc3RydWN0IHJvY2tjaGlwX3BtX2RvbWFpbiAqcGQgPSB0b19yb2NrY2hp cF9wZChkb21haW4pOwo+PiArCj4+ICsgICAgICAgcmV0dXJuIHJvY2tjaGlwX3BkX3Bvd2VyKHBk LCBmYWxzZSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgcm9ja2NoaXBfcGRfYXR0YWNoX2Rl dihzdHJ1Y3QgZ2VuZXJpY19wbV9kb21haW4gKmdlbnBkLAo+PiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgc3RydWN0IGRldmljZSAqZGV2KQo+PiArewo+PiArICAgICAgIHN0cnVj dCBjbGsgKmNsazsKPj4gKyAgICAgICBpbnQgaTsKPj4gKyAgICAgICBpbnQgZXJyb3I7Cj4+ICsK Pj4gKyAgICAgICBkZXZfZGJnKGRldiwgImF0dGFjaGluZyB0byBwb3dlciBkb21haW4gJyVzJ1xu IiwgZ2VucGQtPm5hbWUpOwo+PiArCj4+ICsgICAgICAgZXJyb3IgPSBwbV9jbGtfY3JlYXRlKGRl dik7Cj4+ICsgICAgICAgaWYgKGVycm9yKSB7Cj4+ICsgICAgICAgICAgICAgICBkZXZfZXJyKGRl diwgInBtX2Nsa19jcmVhdGUgZmFpbGVkICVkXG4iLCBlcnJvcik7Cj4+ICsgICAgICAgICAgICAg ICByZXR1cm4gZXJyb3I7Cj4+ICsgICAgICAgfQo+PiArCj4+ICsgICAgICAgaSA9IDA7Cj4+ICsg ICAgICAgd2hpbGUgKChjbGsgPSBvZl9jbGtfZ2V0KGRldi0+b2Zfbm9kZSwgaSsrKSkgJiYgIUlT X0VSUihjbGspKSB7Cj4gVGhpcyBsb29wIGFkZHMgYWxsIGF2YWlsYWJsZSBkZXZpY2UgY2xvY2tz IHRvIHRoZSBQTSBjbG9jayBsaXN0LiBJCj4gd29uZGVyIGlmIHRoaXMgY291bGQgYmUgY29uc2lk ZXJlZCBhcyBhIGNvbW1vbiB0aGluZyBhbmQgaWYgc28sIHdlCj4gbWlnaHQgd2FudCB0byBleHRl bmQgdGhlIHBtX2NsayBBUEkgd2l0aCB0aGlzLgoKVGhlcmUgYXJlIHNldmVyYWwgcmVhc29ucyBh cyBmb2xsb3dzOgoKICAgICBGaXJzdGx5LCB0aGUgY2xvY2tzIG5lZWQgYmUgdHVybmVkIG9mZiB0 byBzYXZlIHBvd2VyIHdoZW4KICAgICB0aGUgc3lzdGVtIGVudGVyIHRoZSBzdXNwZW5kIHN0YXRl LiBTbyB3ZSBuZWVkIHRvIGVudW1lcmF0ZSB0aGUgY2xvY2tzCiAgICAgaW4gdGhlIGR0cy4gSW4g b3JkZXIgdG8gcG93ZXIgZG9tYWluIGNhbiB0dXJuIG9uIGFuZCBvZmYuCgogICAgIFNlY29uZGx5 LCB0aGUgcmVzZXQtY2lyY3VpdCBzaG91bGQgcmVzZXQgYmUgc3luY2hyb25vdXMgb24gcmszMjg4 LCAKdGhlbiBzeW5jIHJldm9rZWQuCiAgICAgU28gd2UgbmVlZCB0byBlbmFibGUgY2xvY2tzIG9m IGFsbCBkZXZpY2VzLgo+PiArICAgICAgICAgICAgICAgZGV2X2RiZyhkZXYsICJhZGRpbmcgY2xv Y2sgJyVzJyB0byBsaXN0IG9mIFBNIGNsb2Nrc1xuIiwKPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgX19jbGtfZ2V0X25hbWUoY2xrKSk7Cj4+ICsgICAgICAgICAgICAgICBlcnJvciA9IHBtX2Ns a19hZGRfY2xrKGRldiwgY2xrKTsKPj4gKyAgICAgICAgICAgICAgIGNsa19wdXQoY2xrKTsKPj4g KyAgICAgICAgICAgICAgIGlmIChlcnJvcikgewo+PiArICAgICAgICAgICAgICAgICAgICAgICBk ZXZfZXJyKGRldiwgInBtX2Nsa19hZGRfY2xrIGZhaWxlZCAlZFxuIiwgZXJyb3IpOwo+PiArICAg ICAgICAgICAgICAgICAgICAgICBwbV9jbGtfZGVzdHJveShkZXYpOwo+PiArICAgICAgICAgICAg ICAgICAgICAgICByZXR1cm4gZXJyb3I7Cj4+ICsgICAgICAgICAgICAgICB9Cj4+ICsgICAgICAg fQo+PiArCj4+ICsgICAgICAgcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJv Y2tjaGlwX3BkX2RldGFjaF9kZXYoc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluICpnZW5wZCwKPj4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgZGV2aWNlICpkZXYpCj4+ ICt7Cj4+ICsgICAgICAgZGV2X2RiZyhkZXYsICJkZXRhY2hpbmcgZnJvbSBwb3dlciBkb21haW4g JyVzJ1xuIiwgZ2VucGQtPm5hbWUpOwo+PiArCj4+ICsgICAgICAgcG1fY2xrX2Rlc3Ryb3koZGV2 KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCByb2NrY2hpcF9wZF9zdGFydF9kZXYoc3RydWN0 IGRldmljZSAqZGV2KQo+PiArewo+PiArICAgICAgIHN0cnVjdCBnZW5lcmljX3BtX2RvbWFpbiAq Z2VucGQgPSBwZF90b19nZW5wZChkZXYtPnBtX2RvbWFpbik7Cj4+ICsKPj4gKyAgICAgICBkZXZf ZGJnKGRldiwgInN0YXJ0aW5nIGRldmljZSBpbiBwb3dlciBkb21haW4gJyVzJ1xuIiwgZ2VucGQt Pm5hbWUpOwo+PiArCj4+ICsgICAgICAgcmV0dXJuIHBtX2Nsa19yZXN1bWUoZGV2KTsKPj4gK30K Pj4gKwo+PiArc3RhdGljIGludCByb2NrY2hpcF9wZF9zdG9wX2RldihzdHJ1Y3QgZGV2aWNlICpk ZXYpCj4+ICt7Cj4+ICsgICAgICAgc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluICpnZW5wZCA9IHBk X3RvX2dlbnBkKGRldi0+cG1fZG9tYWluKTsKPj4gKwo+PiArICAgICAgIGRldl9kYmcoZGV2LCAi c3RvcHBpbmcgZGV2aWNlIGluIHBvd2VyIGRvbWFpbiAnJXMnXG4iLCBnZW5wZC0+bmFtZSk7Cj4+ ICsKPj4gKyAgICAgICByZXR1cm4gcG1fY2xrX3N1c3BlbmQoZGV2KTsKPj4gK30KPj4gKwo+PiAr c3RhdGljIGludCByb2NrY2hpcF9wbV9hZGRfb25lX2RvbWFpbihzdHJ1Y3Qgcm9ja2NoaXBfcG11 ICpwbXUsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRl dmljZV9ub2RlICpub2RlKQo+PiArewo+PiArICAgICAgIGNvbnN0IHN0cnVjdCByb2NrY2hpcF9k b21haW5faW5mbyAqcGRfaW5mbzsKPj4gKyAgICAgICBzdHJ1Y3Qgcm9ja2NoaXBfcG1fZG9tYWlu ICpwZDsKPj4gKyAgICAgICBzdHJ1Y3QgY2xrICpjbGs7Cj4+ICsgICAgICAgaW50IGNsa19jbnQ7 Cj4+ICsgICAgICAgaW50IGk7Cj4+ICsgICAgICAgdTMyIGlkOwo+PiArICAgICAgIGludCBlcnJv cjsKPj4gKwo+PiArICAgICAgIGVycm9yID0gb2ZfcHJvcGVydHlfcmVhZF91MzIobm9kZSwgInJl ZyIsICZpZCk7Cj4+ICsgICAgICAgaWYgKGVycm9yKSB7Cj4+ICsgICAgICAgICAgICAgICBkZXZf ZXJyKHBtdS0+ZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAiJXM6IGZhaWxlZCB0byBy ZXRyaWV2ZSBkb21haW4gaWQgKHJlZyk6ICVkXG4iLAo+PiArICAgICAgICAgICAgICAgICAgICAg ICBub2RlLT5uYW1lLCBlcnJvcik7Cj4+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVJTlZBTDsK Pj4gKyAgICAgICB9Cj4+ICsKPj4gKyAgICAgICBpZiAoaWQgPj0gcG11LT5pbmZvLT5udW1fZG9t YWlucykgewo+PiArICAgICAgICAgICAgICAgZGV2X2VycihwbXUtPmRldiwgIiVzOiBpbnZhbGlk IGRvbWFpbiBpZCAlZFxuIiwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgbm9kZS0+bmFtZSwg aWQpOwo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+ICsgICAgICAgfQo+PiAr Cj4+ICsgICAgICAgcGRfaW5mbyA9ICZwbXUtPmluZm8tPmRvbWFpbl9pbmZvW2lkXTsKPj4gKyAg ICAgICBpZiAoIXBkX2luZm8pIHsKPj4gKyAgICAgICAgICAgICAgIGRldl9lcnIocG11LT5kZXYs ICIlczogdW5kZWZpbmVkIGRvbWFpbiBpZCAlZFxuIiwKPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgbm9kZS0+bmFtZSwgaWQpOwo+PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4+ ICsgICAgICAgfQo+PiArCj4+ICsgICAgICAgY2xrX2NudCA9IG9mX2NvdW50X3BoYW5kbGVfd2l0 aF9hcmdzKG5vZGUsICJjbG9ja3MiLCAiI2Nsb2NrLWNlbGxzIik7Cj4+ICsgICAgICAgcGQgPSBk ZXZtX2t6YWxsb2MocG11LT5kZXYsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9m KCpwZCkgKyBjbGtfY250ICogc2l6ZW9mKHBkLT5jbGtzWzBdKSwKPj4gKyAgICAgICAgICAgICAg ICAgICAgICAgICBHRlBfS0VSTkVMKTsKPj4gKyAgICAgICBpZiAoIXBkKQo+PiArICAgICAgICAg ICAgICAgcmV0dXJuIC1FTk9NRU07Cj4+ICsKPj4gKyAgICAgICBwZC0+aW5mbyA9IHBkX2luZm87 Cj4+ICsgICAgICAgcGQtPnBtdSA9IHBtdTsKPj4gKwo+PiArICAgICAgIGZvciAoaSA9IDA7IGkg PCBjbGtfY250OyBpKyspIHsKPiBUaGlzIGxvb3AgaXMgc2ltaWxhciB0byB0aGUgb25lIHdoZW4g Y3JlYXRlcyB0aGUgUE0gY2xvY2sgbGlzdCBpbiB0aGUKPiByb2NrY2hpcF9wZF9hdHRhY2hfZGV2 KCkuCj4KPiBXaGF0J3MgdGhlIHJlYXNvbiB5b3UgZG9uJ3Qgd2FudCB0byB1c2UgcG0gY2xrIGZv ciB0aGVzZSBjbG9ja3M/Cj4KCkRpdHRvLgo+PiArICAgICAgICAgICAgICAgY2xrID0gb2ZfY2xr X2dldChub2RlLCBpKTsKPj4gKyAgICAgICAgICAgICAgIGlmIChJU19FUlIoY2xrKSkgewo+PiAr ICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFBUUl9FUlIoY2xrKTsKPj4gKyAgICAgICAg ICAgICAgICAgICAgICAgZGV2X2VycihwbXUtPmRldiwKPj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAiJXM6IGZhaWxlZCB0byBnZXQgY2xrICVzIChpbmRleCAlZCk6ICVkXG4iLAo+ PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIF9fY2xrX2dldF9u YW1lKGNsayksIGksIGVycm9yKTsKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJf b3V0Owo+PiArICAgICAgICAgICAgICAgfQo+PiArCj4+ICsgICAgICAgICAgICAgICBlcnJvciA9 IGNsa19wcmVwYXJlKGNsayk7Cj4+ICsgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHsKPj4gKyAg ICAgICAgICAgICAgICAgICAgICAgZGV2X2VycihwbXUtPmRldiwKPj4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAiJXM6IGZhaWxlZCB0byBwcmVwYXJlIGNsayAlcyAoaW5kZXggJWQp OiAlZFxuIiwKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBf X2Nsa19nZXRfbmFtZShjbGspLCBpLCBlcnJvcik7Cj4+ICsgICAgICAgICAgICAgICAgICAgICAg IGNsa19wdXQoY2xrKTsKPj4gKyAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJfb3V0Owo+ PiArICAgICAgICAgICAgICAgfQo+PiArCj4+ICsgICAgICAgICAgICAgICBwZC0+Y2xrc1twZC0+ bnVtX2Nsa3MrK10gPSBjbGs7Cj4+ICsKPj4gKyAgICAgICAgICAgICAgIGRldl9kYmcocG11LT5k ZXYsICJhZGRlZCBjbG9jayAnJXMnIHRvIGRvbWFpbiAnJXMnXG4iLAo+PiArICAgICAgICAgICAg ICAgICAgICAgICBfX2Nsa19nZXRfbmFtZShjbGspLCBub2RlLT5uYW1lKTsKPj4gKyAgICAgICB9 Cj4+ICsKPj4gKyAgICAgICBlcnJvciA9IHJvY2tjaGlwX3BkX3Bvd2VyKHBkLCB0cnVlKTsKPj4g KyAgICAgICBpZiAoZXJyb3IpIHsKPj4gKyAgICAgICAgICAgICAgIGRldl9lcnIocG11LT5kZXYs Cj4+ICsgICAgICAgICAgICAgICAgICAgICAgICJmYWlsZWQgdG8gcG93ZXIgb24gZG9tYWluICcl cyc6ICVkXG4iLAo+PiArICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lLCBlcnJvcik7 Cj4+ICsgICAgICAgICAgICAgICBnb3RvIGVycl9vdXQ7Cj4+ICsgICAgICAgfQo+PiArCj4+ICsg ICAgICAgcGQtPmdlbnBkLm5hbWUgPSBub2RlLT5uYW1lOwo+PiArICAgICAgIHBkLT5nZW5wZC5w b3dlcl9vZmYgPSByb2NrY2hpcF9wZF9wb3dlcl9vZmY7Cj4+ICsgICAgICAgcGQtPmdlbnBkLnBv d2VyX29uID0gcm9ja2NoaXBfcGRfcG93ZXJfb247Cj4+ICsgICAgICAgcGQtPmdlbnBkLmF0dGFj aF9kZXYgPSByb2NrY2hpcF9wZF9hdHRhY2hfZGV2Owo+PiArICAgICAgIHBkLT5nZW5wZC5kZXRh Y2hfZGV2ID0gcm9ja2NoaXBfcGRfZGV0YWNoX2RldjsKPj4gKyAgICAgICBwZC0+Z2VucGQuZGV2 X29wcy5zdGFydCA9IHJvY2tjaGlwX3BkX3N0YXJ0X2RldjsKPj4gKyAgICAgICBwZC0+Z2VucGQu ZGV2X29wcy5zdG9wID0gcm9ja2NoaXBfcGRfc3RvcF9kZXY7Cj4gSW5zdGVhZCBvZiBhc3NpZ25p bmcgdGhlIC0+c3RvcHxzdGFydCgpIGNhbGxiYWNrcywgd2hpY2ggZG8KPiBwbV9jbGtfc3VzcGVu ZHxyZXN1bWUoKSwganVzdCBzZXQgdGhlIGdlbnBkLT5mbGFncyB0bwo+IEdFTlBEX0ZMQUdfUE1f Q0xLLCBhbmQgZ2VucGQgd2lsbCBmaXggdGhpcyBmb3IgeW91Lgo+CkRpdHRvLgoKPj4gKyAgICAg ICBwbV9nZW5wZF9pbml0KCZwZC0+Z2VucGQsIE5VTEwsIGZhbHNlKTsKPj4gKwo+PiArICAgICAg IHBtdS0+Z2VucGRfZGF0YS5kb21haW5zW2lkXSA9ICZwZC0+Z2VucGQ7Cj4+ICsgICAgICAgcmV0 dXJuIDA7Cj4+ICsKPj4gK2Vycl9vdXQ6Cj4+ICsgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7Cj4+ ICsgICAgICAgICAgICAgICBjbGtfdW5wcmVwYXJlKHBkLT5jbGtzW2ldKTsKPj4gKyAgICAgICAg ICAgICAgIGNsa19wdXQocGQtPmNsa3NbaV0pOwo+PiArICAgICAgIH0KPj4gKyAgICAgICByZXR1 cm4gZXJyb3I7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJvY2tjaGlwX3BtX3JlbW92ZV9v bmVfZG9tYWluKHN0cnVjdCByb2NrY2hpcF9wbV9kb21haW4gKnBkKQo+PiArewo+PiArICAgICAg IGludCBpOwo+PiArCj4+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IHBkLT5udW1fY2xrczsgaSsr KSB7Cj4+ICsgICAgICAgICAgICAgICBjbGtfdW5wcmVwYXJlKHBkLT5jbGtzW2ldKTsKPiBJZiB5 b3UgY29udmVydGVkIHRoZXNlIGNsb2NrcyB0byBiZSBkZWFsdCB3aXRoIHZpYSB0aGUgUE0gY2xr IEFQSSwKPiBwbV9jbGtfZGVzdG95KCkgd291bGQgaGF2ZSByZXBsYWNlZCB0aGlzIGxvb3AuCj4K Pj4gKyAgICAgICAgICAgICAgIGNsa19wdXQocGQtPmNsa3NbaV0pOwo+PiArICAgICAgIH0KPj4g Kwo+PiArICAgICAgIC8qIGRldm0gd2lsbCBmcmVlIG91ciBtZW1vcnkgKi8KPj4gK30KPj4gKwo+ PiArc3RhdGljIHZvaWQgcm9ja2NoaXBfcG1fZG9tYWluX2NsZWFudXAoc3RydWN0IHJvY2tjaGlw X3BtdSAqcG11KQo+PiArewo+PiArICAgICAgIHN0cnVjdCBnZW5lcmljX3BtX2RvbWFpbiAqZ2Vu cGQ7Cj4+ICsgICAgICAgc3RydWN0IHJvY2tjaGlwX3BtX2RvbWFpbiAqcGQ7Cj4+ICsgICAgICAg aW50IGk7Cj4+ICsKPj4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgcG11LT5nZW5wZF9kYXRhLm51 bV9kb21haW5zOyBpKyspIHsKPj4gKyAgICAgICAgICAgICAgIGdlbnBkID0gcG11LT5nZW5wZF9k YXRhLmRvbWFpbnNbaV07Cj4+ICsgICAgICAgICAgICAgICBpZiAoZ2VucGQpIHsKPj4gKyAgICAg ICAgICAgICAgICAgICAgICAgcGQgPSB0b19yb2NrY2hpcF9wZChnZW5wZCk7Cj4+ICsgICAgICAg ICAgICAgICAgICAgICAgIHJvY2tjaGlwX3BtX3JlbW92ZV9vbmVfZG9tYWluKHBkKTsKPj4gKyAg ICAgICAgICAgICAgIH0KPj4gKyAgICAgICB9Cj4+ICsKPj4gKyAgICAgICAvKiBkZXZtIHdpbGwg ZnJlZSBvdXIgbWVtb3J5ICovCj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIHJvY2tjaGlwX2Nv bmZpZ3VyZV9wZF9jbnQoc3RydWN0IHJvY2tjaGlwX3BtdSAqcG11LAo+PiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHUzMiBkb21haW5fcmVnX29mZnNldCwKPj4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgY291bnQpCj4+ICt7 Cj4+ICsgICAgICAgLyogRmlyc3QgY29uZmlndXJlIGRvbWFpbiBwb3dlciBkb3duIHRyYW5zaXRp b24gY291bnQgLi4uICovCj4+ICsgICAgICAgcmVnbWFwX3dyaXRlKHBtdS0+cmVnbWFwLCBkb21h aW5fcmVnX29mZnNldCwgY291bnQpOwo+PiArICAgICAgIC8qIC4uLiBhbmQgdGhlbiBwb3dlciB1 cCBjb3VudC4gKi8KPj4gKyAgICAgICByZWdtYXBfd3JpdGUocG11LT5yZWdtYXAsIGRvbWFpbl9y ZWdfb2Zmc2V0ICsgNCwgY291bnQpOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IHJvY2tjaGlw X3BtX2RvbWFpbl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+PiArewo+PiAr ICAgICAgIHN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7Cj4+ICsgICAgICAgc3RydWN0 IGRldmljZV9ub2RlICpucCA9IGRldi0+b2Zfbm9kZTsKPj4gKyAgICAgICBzdHJ1Y3QgZGV2aWNl X25vZGUgKm5vZGU7Cj4+ICsgICAgICAgc3RydWN0IHJvY2tjaGlwX3BtdSAqcG11Owo+PiArICAg ICAgIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgKm1hdGNoOwo+PiArICAgICAgIGNvbnN0IHN0 cnVjdCByb2NrY2hpcF9wbXVfaW5mbyAqcG11X2luZm87Cj4+ICsgICAgICAgaW50IGVycm9yOwo+ PiArCj4+ICsgICAgICAgaWYgKCFucCkgewo+PiArICAgICAgICAgICAgICAgZGV2X2VycihkZXYs ICJkZXZpY2UgdHJlZSBub2RlIG5vdCBmb3VuZFxuIik7Cj4+ICsgICAgICAgICAgICAgICByZXR1 cm4gLUVOWElPOy8KPiBOaXRwaWNrOgo+IEl0J3MgbW9yZSBjb21tb24gdG8gcmV0dXJuIC1FTk9E RVYgaGVyZSwgeW91IG1pZ2h0IHdhbnQgdG8gY2hhbmdlLgoKT0suCgpUaGFua3MsCkNhZXNhcgo+ PiArICAgICAgIH0KPj4gKwo+PiArICAgICAgIG1hdGNoID0gb2ZfbWF0Y2hfZGV2aWNlKGRldi0+ ZHJpdmVyLT5vZl9tYXRjaF90YWJsZSwgZGV2KTsKPj4gKyAgICAgICBpZiAoIW1hdGNoIHx8ICFt YXRjaC0+ZGF0YSkgewo+PiArICAgICAgICAgICAgICAgZGV2X2VycihkZXYsICJtaXNzaW5nIHBt dSBkYXRhXG4iKTsKPj4gKyAgICAgICAgICAgICAgIHJldHVybiAtRUlOVkFMOwo+PiArICAgICAg IH0KPj4gKwo+PiArICAgICAgIHBtdV9pbmZvID0gbWF0Y2gtPmRhdGE7Cj4+ICsKPj4gKyAgICAg ICBwbXUgPSBkZXZtX2t6YWxsb2MoZGV2LAo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICBz aXplb2YoKnBtdSkgKwo+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBtdV9pbmZv LT5udW1fZG9tYWlucyAqIHNpemVvZihwbXUtPmRvbWFpbnNbMF0pLAo+PiArICAgICAgICAgICAg ICAgICAgICAgICAgICBHRlBfS0VSTkVMKTsKPj4gKyAgICAgICBpZiAoIXBtdSkKPj4gKyAgICAg ICAgICAgICAgIHJldHVybiAtRU5PTUVNOwo+PiArCj4+ICsgICAgICAgcG11LT5kZXYgPSAmcGRl di0+ZGV2Owo+PiArICAgICAgIG11dGV4X2luaXQoJnBtdS0+bXV0ZXgpOwo+PiArCj4+ICsgICAg ICAgcG11LT5pbmZvID0gcG11X2luZm87Cj4+ICsKPj4gKyAgICAgICBwbXUtPmdlbnBkX2RhdGEu ZG9tYWlucyA9IHBtdS0+ZG9tYWluczsKPj4gKyAgICAgICBwbXUtPmdlbnBkX2RhdGEubnVtX2Rv bWFpbnMgPSBwbXVfaW5mby0+bnVtX2RvbWFpbnM7Cj4+ICsKPj4gKyAgICAgICBub2RlID0gb2Zf cGFyc2VfcGhhbmRsZShucCwgInJvY2tjaGlwLHBtdSIsIDApOwo+PiArICAgICAgIHBtdS0+cmVn bWFwID0gc3lzY29uX25vZGVfdG9fcmVnbWFwKG5vZGUpOwo+PiArICAgICAgIG9mX25vZGVfcHV0 KG5vZGUpOwo+PiArICAgICAgIGlmIChJU19FUlIocG11LT5yZWdtYXApKSB7Cj4+ICsgICAgICAg ICAgICAgICBlcnJvciA9IFBUUl9FUlIocG11LT5yZWdtYXApOwo+PiArICAgICAgICAgICAgICAg ZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZ2V0IFBNVSByZWdtYXA6ICVkXG4iLCBlcnJvcik7Cj4+ ICsgICAgICAgICAgICAgICByZXR1cm4gZXJyb3I7Cj4+ICsgICAgICAgfQo+PiArCj4+ICsgICAg ICAgLyoKPj4gKyAgICAgICAgKiBDb25maWd1cmUgcG93ZXIgdXAgYW5kIGRvd24gdHJhbnNpdGlv biBkZWxheXMgZm9yIGNvcmUKPj4gKyAgICAgICAgKiBhbmQgR1BVIGRvbWFpbnMuCj4+ICsgICAg ICAgICovCj4+ICsgICAgICAgcm9ja2NoaXBfY29uZmlndXJlX3BkX2NudChwbXUsIHBtdV9pbmZv LT5jb3JlX3B3cmNudF9vZmZzZXQsCj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBwbXVfaW5mby0+Y29yZV9wb3dlcl90cmFuc2l0aW9uX3RpbWUpOwo+PiArICAgICAgIHJvY2tj aGlwX2NvbmZpZ3VyZV9wZF9jbnQocG11LCBwbXVfaW5mby0+Z3B1X3B3cmNudF9vZmZzZXQsCj4+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbXVfaW5mby0+Z3B1X3Bvd2VyX3Ry YW5zaXRpb25fdGltZSk7Cj4+ICsKPj4gKyAgICAgICBlcnJvciA9IC1FTlhJTzsKPj4gKwo+PiAr ICAgICAgIGZvcl9lYWNoX2F2YWlsYWJsZV9jaGlsZF9vZl9ub2RlKG5wLCBub2RlKSB7Cj4+ICsg ICAgICAgICAgICAgICBlcnJvciA9IHJvY2tjaGlwX3BtX2FkZF9vbmVfZG9tYWluKHBtdSwgbm9k ZSk7Cj4+ICsgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHsKPj4gKyAgICAgICAgICAgICAgICAg ICAgICAgZGV2X2VycihkZXYsICJmYWlsZWQgdG8gaGFuZGxlIG5vZGUgJXM6ICVkXG4iLAo+PiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIGVycm9yKTsKPj4gKyAg ICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJfb3V0Owo+PiArICAgICAgICAgICAgICAgfQo+ PiArICAgICAgIH0KPj4gKwo+PiArICAgICAgIGlmIChlcnJvcikgewo+PiArICAgICAgICAgICAg ICAgZGV2X2RiZyhkZXYsICJubyBwb3dlciBkb21haW5zIGRlZmluZWRcbiIpOwo+PiArICAgICAg ICAgICAgICAgZ290byBlcnJfb3V0Owo+PiArICAgICAgIH0KPj4gKwo+PiArICAgICAgIG9mX2dl bnBkX2FkZF9wcm92aWRlcl9vbmVjZWxsKG5wLCAmcG11LT5nZW5wZF9kYXRhKTsKPj4gKwo+PiAr ICAgICAgIHJldHVybiAwOwo+PiArCj4+ICtlcnJfb3V0Ogo+PiArICAgICAgIHJvY2tjaGlwX3Bt X2RvbWFpbl9jbGVhbnVwKHBtdSk7Cj4+ICsgICAgICAgcmV0dXJuIGVycm9yOwo+PiArfQo+PiAr Cj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHJvY2tjaGlwX2RvbWFpbl9pbmZvIHJrMzI4OF9wbV9k b21haW5zW10gPSB7Cj4+ICsgICAgICAgW1JLMzI4OF9QRF9HUFVdICAgICAgICAgPSBET01BSU5f UkszMjg4KDksIDksIDIpLAo+PiArICAgICAgIFtSSzMyODhfUERfVklPXSAgICAgICAgID0gRE9N QUlOX1JLMzI4OCg3LCA3LCA0KSwKPj4gKyAgICAgICBbUkszMjg4X1BEX1ZJREVPXSAgICAgICA9 IERPTUFJTl9SSzMyODgoOCwgOCwgMyksCj4+ICsgICAgICAgW1JLMzI4OF9QRF9IRVZDXSAgICAg ICAgPSBET01BSU5fUkszMjg4KDE0LCAxMCwgOSksCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgY29u c3Qgc3RydWN0IHJvY2tjaGlwX3BtdV9pbmZvIHJrMzI4OF9wbXUgPSB7Cj4+ICsgICAgICAgLnB3 cl9vZmZzZXQgPSAweDA4LAo+PiArICAgICAgIC5zdGF0dXNfb2Zmc2V0ID0gMHgwYywKPj4gKyAg ICAgICAucmVxX29mZnNldCA9IDB4MTAsCj4+ICsgICAgICAgLmlkbGVfb2Zmc2V0ID0gMHgxNCwK Pj4gKyAgICAgICAuYWNrX29mZnNldCA9IDB4MTQsCj4+ICsKPj4gKyAgICAgICAuY29yZV9wd3Jj bnRfb2Zmc2V0ID0gMHgzNCwKPj4gKyAgICAgICAuZ3B1X3B3cmNudF9vZmZzZXQgPSAweDNjLAo+ PiArCj4+ICsgICAgICAgLmNvcmVfcG93ZXJfdHJhbnNpdGlvbl90aW1lID0gMjQsIC8qIDF1cyAq Lwo+PiArICAgICAgIC5ncHVfcG93ZXJfdHJhbnNpdGlvbl90aW1lID0gMjQsIC8qIDF1cyAqLwo+ PiArCj4+ICsgICAgICAgLm51bV9kb21haW5zID0gQVJSQVlfU0laRShyazMyODhfcG1fZG9tYWlu cyksCj4+ICsgICAgICAgLmRvbWFpbl9pbmZvID0gcmszMjg4X3BtX2RvbWFpbnMsCj4+ICt9Owo+ PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCByb2NrY2hpcF9wbV9kb21h aW5fZHRfbWF0Y2hbXSA9IHsKPj4gKyAgICAgICB7Cj4+ICsgICAgICAgICAgICAgICAuY29tcGF0 aWJsZSA9ICJyb2NrY2hpcCxyazMyODgtcG93ZXItY29udHJvbGxlciIsCj4+ICsgICAgICAgICAg ICAgICAuZGF0YSA9ICh2b2lkICopJnJrMzI4OF9wbXUsCj4+ICsgICAgICAgfSwKPj4gKyAgICAg ICB7IC8qIHNlbnRpbmVsICovIH0sCj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHBsYXRm b3JtX2RyaXZlciByb2NrY2hpcF9wbV9kb21haW5fZHJpdmVyID0gewo+PiArICAgICAgIC5wcm9i ZSA9IHJvY2tjaGlwX3BtX2RvbWFpbl9wcm9iZSwKPj4gKyAgICAgICAuZHJpdmVyID0gewo+PiAr ICAgICAgICAgICAgICAgLm5hbWUgICA9ICJyb2NrY2hpcC1wbS1kb21haW4iLAo+PiArICAgICAg ICAgICAgICAgLm9mX21hdGNoX3RhYmxlID0gcm9ja2NoaXBfcG1fZG9tYWluX2R0X21hdGNoLAo+ PiArICAgICAgICAgICAgICAgLyoKPj4gKyAgICAgICAgICAgICAgICAqIFdlIGNhbid0IGZvcmNp Ymx5IGVqZWN0IGRldmljZXMgZm9ybSBwb3dlciBkb21haW4sCj4+ICsgICAgICAgICAgICAgICAg KiBzbyB3ZSBjYW4ndCByZWFsbHkgcmVtb3ZlIHBvd2VyIGRvbWFpbnMgb25jZSB0aGV5Cj4+ICsg ICAgICAgICAgICAgICAgKiB3ZXJlIGFkZGVkLgo+PiArICAgICAgICAgICAgICAgICovCj4+ICsg ICAgICAgICAgICAgICAuc3VwcHJlc3NfYmluZF9hdHRycyA9IHRydWUsCj4+ICsgICAgICAgfSwK Pj4gK307Cj4+ICsKPj4gK3N0YXRpYyBpbnQgX19pbml0IHJvY2tjaGlwX3BtX2RvbWFpbl9kcnZf cmVnaXN0ZXIodm9pZCkKPj4gK3sKPj4gKyAgICAgICByZXR1cm4gcGxhdGZvcm1fZHJpdmVyX3Jl Z2lzdGVyKCZyb2NrY2hpcF9wbV9kb21haW5fZHJpdmVyKTsKPj4gK30KPj4gK3Bvc3Rjb3JlX2lu aXRjYWxsKHJvY2tjaGlwX3BtX2RvbWFpbl9kcnZfcmVnaXN0ZXIpOwo+PiAtLQo+PiAxLjkuMQo+ Pgo+IEtpbmQgcmVnYXJkcwo+IFVmZmUKPgo+IF9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCj4gTGludXgtcm9ja2NoaXAgbWFpbGluZyBsaXN0Cj4gTGludXgt cm9ja2NoaXBAbGlzdHMuaW5mcmFkZWFkLm9yZwo+IGh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3Jn L21haWxtYW4vbGlzdGluZm8vbGludXgtcm9ja2NoaXAKCgoKX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXgtcm9ja2NoaXAgbWFpbGluZyBsaXN0Ckxp bnV4LXJvY2tjaGlwQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5v cmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1yb2NrY2hpcAo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: sasukewxt@163.com (Caesar Wang) Date: Sun, 14 Jun 2015 11:15:34 +0800 Subject: [PATCH v14 2/3] power-domain: rockchip: add power domain driver In-Reply-To: References: <1429862868-14218-1-git-send-email-wxt@rock-chips.com> <1429862868-14218-3-git-send-email-wxt@rock-chips.com> Message-ID: <557CF1D6.4090506@163.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Ulf, Thanks for your comments.:-) ? 2015?05?28? 18:38, Ulf Hansson ??: > On 24 April 2015 at 10:07, Caesar Wang wrote: >> In order to meet high performance and low power requirements, a power >> management unit is designed or saving power when RK3288 in low power >> mode. >> The RK3288 PMU is dedicated for managing the power ot the whole chip. >> >> Signed-off-by: jinkun.hong >> Signed-off-by: Caesar Wang >> --- >> >> arch/arm/mach-rockchip/Kconfig | 1 + >> arch/arm/mach-rockchip/Makefile | 1 + >> arch/arm/mach-rockchip/pm_domains.c | 506 ++++++++++++++++++++++++++++++++++++ >> 3 files changed, 508 insertions(+) >> create mode 100644 arch/arm/mach-rockchip/pm_domains.c >> >> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig >> index ae4eb7c..578206b 100644 >> --- a/arch/arm/mach-rockchip/Kconfig >> +++ b/arch/arm/mach-rockchip/Kconfig >> @@ -15,6 +15,7 @@ config ARCH_ROCKCHIP >> select ROCKCHIP_TIMER >> select ARM_GLOBAL_TIMER >> select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK >> + select PM_GENERIC_DOMAINS if PM >> help >> Support for Rockchip's Cortex-A9 Single-to-Quad-Core-SoCs >> containing the RK2928, RK30xx and RK31xx series. >> diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile >> index 5c3a9b2..9c902d3 100644 >> --- a/arch/arm/mach-rockchip/Makefile >> +++ b/arch/arm/mach-rockchip/Makefile >> @@ -1,5 +1,6 @@ >> CFLAGS_platsmp.o := -march=armv7-a >> >> obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o >> +obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o >> obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o >> obj-$(CONFIG_SMP) += headsmp.o platsmp.o >> diff --git a/arch/arm/mach-rockchip/pm_domains.c b/arch/arm/mach-rockchip/pm_domains.c >> new file mode 100644 >> index 0000000..92d2569 >> --- /dev/null >> +++ b/arch/arm/mach-rockchip/pm_domains.c >> @@ -0,0 +1,506 @@ >> +/* >> + * Rockchip Generic power domain support. >> + * >> + * Copyright (c) 2014 ROCKCHIP, Co. Ltd. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include > clk-provider.h, why? The following is needed. _clk_get_name(clk) > >> +#include >> +#include >> +#include > Same comment as in patch1. I don't find this header. OK. Perhaps, Making a mistake. the missing the patch in here.(https://patchwork.kernel.org/patch/6266881/) >> + >> +struct rockchip_domain_info { >> + int pwr_mask; >> + int status_mask; >> + int req_mask; >> + int idle_mask; >> + int ack_mask; >> +}; >> + >> +struct rockchip_pmu_info { >> + u32 pwr_offset; >> + u32 status_offset; >> + u32 req_offset; >> + u32 idle_offset; >> + u32 ack_offset; >> + >> + u32 core_pwrcnt_offset; >> + u32 gpu_pwrcnt_offset; >> + >> + unsigned int core_power_transition_time; >> + unsigned int gpu_power_transition_time; >> + >> + int num_domains; >> + const struct rockchip_domain_info *domain_info; >> +}; >> + >> +struct rockchip_pm_domain { >> + struct generic_pm_domain genpd; >> + const struct rockchip_domain_info *info; >> + struct rockchip_pmu *pmu; >> + int num_clks; >> + struct clk *clks[]; >> +}; >> + >> +struct rockchip_pmu { >> + struct device *dev; >> + struct regmap *regmap; >> + const struct rockchip_pmu_info *info; >> + struct mutex mutex; /* mutex lock for pmu */ >> + struct genpd_onecell_data genpd_data; >> + struct generic_pm_domain *domains[]; >> +}; >> + >> +#define to_rockchip_pd(gpd) container_of(gpd, struct rockchip_pm_domain, genpd) >> + >> +#define DOMAIN(pwr, status, req, idle, ack) \ >> +{ \ >> + .pwr_mask = BIT(pwr), \ >> + .status_mask = BIT(status), \ >> + .req_mask = BIT(req), \ >> + .idle_mask = BIT(idle), \ >> + .ack_mask = BIT(ack), \ >> +} >> + >> +#define DOMAIN_RK3288(pwr, status, req) \ >> + DOMAIN(pwr, status, req, req, (req) + 16) >> + >> +static bool rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *pd) >> +{ >> + struct rockchip_pmu *pmu = pd->pmu; >> + const struct rockchip_domain_info *pd_info = pd->info; >> + unsigned int val; >> + >> + regmap_read(pmu->regmap, pmu->info->idle_offset, &val); >> + return (val & pd_info->idle_mask) == pd_info->idle_mask; >> +} >> + >> +static int rockchip_pmu_set_idle_request(struct rockchip_pm_domain *pd, >> + bool idle) >> +{ >> + const struct rockchip_domain_info *pd_info = pd->info; >> + struct rockchip_pmu *pmu = pd->pmu; >> + unsigned int val; >> + >> + regmap_update_bits(pmu->regmap, pmu->info->req_offset, >> + pd_info->req_mask, idle ? -1U : 0); >> + >> + dsb(); >> + >> + do { >> + regmap_read(pmu->regmap, pmu->info->ack_offset, &val); >> + } while ((val & pd_info->ack_mask) != (idle ? pd_info->ack_mask : 0)); >> + >> + while (rockchip_pmu_domain_is_idle(pd) != idle) >> + cpu_relax(); >> + >> + return 0; >> +} >> + >> +static bool rockchip_pmu_domain_is_on(struct rockchip_pm_domain *pd) >> +{ >> + struct rockchip_pmu *pmu = pd->pmu; >> + unsigned int val; >> + >> + regmap_read(pmu->regmap, pmu->info->status_offset, &val); >> + >> + /* 1'b0: power on, 1'b1: power off */ >> + return !(val & pd->info->status_mask); >> +} >> + >> +static void rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *pd, >> + bool on) >> +{ >> + struct rockchip_pmu *pmu = pd->pmu; >> + >> + regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, >> + pd->info->pwr_mask, on ? 0 : -1U); >> + >> + dsb(); >> + >> + while (rockchip_pmu_domain_is_on(pd) != on) >> + cpu_relax(); >> +} >> + >> +static int rockchip_pd_power(struct rockchip_pm_domain *pd, bool power_on) >> +{ >> + int i; >> + >> + mutex_lock(&pd->pmu->mutex); > I don't quite understand why you need a lock, what are you protecting and why? Says: [ 3551.678762] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3551.899180] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3551.905958] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3551.912832] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3551.919730] rockchip_pd_power:139: mutex_lock [ 3551.924130] rockchip_pd_power:167,mutex_unlock [ 3563.827295] rockchip_pd_power:139: mutex_lock [ 3563.831753] rockchip_pd_power:167,mutex_unlock [ 3563.836216] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3564.058989] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3564.065659] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3564.072354] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3564.079047] rockchip_pd_power:139: mutex_lock [ 3564.083426] rockchip_pd_power:167,mutex_unlock [ 3611.665726] rockchip_pd_power:139: mutex_lock [ 3611.670206] rockchip_pd_power:167,mutex_unlock [ 3611.674692] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3611.899160] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3611.905938] mali ffa30000.gpu: starting device in power domain 'pd_gpu' [ 3611.912818] mali ffa30000.gpu: stopping device in power domain 'pd_gpu' [ 3611.919689] rockchip_pd_power:139: mutex_lock [ 3611.924090] rockchip_pd_power:167,mutex_unlock [ 3623.848296] rockchip_pd_power:139: mutex_lock [ 3623.852752] rockchip_pd_power:167,mutex_unlock >> + >> + if (rockchip_pmu_domain_is_on(pd) != power_on) { >> + for (i = 0; i < pd->num_clks; i++) >> + clk_enable(pd->clks[i]); >> + >> + if (!power_on) { >> + /* FIXME: add code to save AXI_QOS */ >> + >> + /* if powering down, idle request to NIU first */ >> + rockchip_pmu_set_idle_request(pd, true); >> + } >> + >> + rockchip_do_pmu_set_power_domain(pd, power_on); >> + >> + if (power_on) { >> + /* if powering up, leave idle mode */ >> + rockchip_pmu_set_idle_request(pd, false); >> + >> + /* FIXME: add code to restore AXI_QOS */ >> + } >> + >> + for (i = pd->num_clks - 1; i >= 0; i--) >> + clk_disable(pd->clks[i]); >> + } >> + >> + mutex_unlock(&pd->pmu->mutex); >> + return 0; >> +} >> + >> +static int rockchip_pd_power_on(struct generic_pm_domain *domain) >> +{ >> + struct rockchip_pm_domain *pd = to_rockchip_pd(domain); >> + >> + return rockchip_pd_power(pd, true); >> +} >> + >> +static int rockchip_pd_power_off(struct generic_pm_domain *domain) >> +{ >> + struct rockchip_pm_domain *pd = to_rockchip_pd(domain); >> + >> + return rockchip_pd_power(pd, false); >> +} >> + >> +static int rockchip_pd_attach_dev(struct generic_pm_domain *genpd, >> + struct device *dev) >> +{ >> + struct clk *clk; >> + int i; >> + int error; >> + >> + dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name); >> + >> + error = pm_clk_create(dev); >> + if (error) { >> + dev_err(dev, "pm_clk_create failed %d\n", error); >> + return error; >> + } >> + >> + i = 0; >> + while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) { > This loop adds all available device clocks to the PM clock list. I > wonder if this could be considered as a common thing and if so, we > might want to extend the pm_clk API with this. There are several reasons as follows: Firstly, the clocks need be turned off to save power when the system enter the suspend state. So we need to enumerate the clocks in the dts. In order to power domain can turn on and off. Secondly, the reset-circuit should reset be synchronous on rk3288, then sync revoked. So we need to enable clocks of all devices. >> + dev_dbg(dev, "adding clock '%s' to list of PM clocks\n", >> + __clk_get_name(clk)); >> + error = pm_clk_add_clk(dev, clk); >> + clk_put(clk); >> + if (error) { >> + dev_err(dev, "pm_clk_add_clk failed %d\n", error); >> + pm_clk_destroy(dev); >> + return error; >> + } >> + } >> + >> + return 0; >> +} >> + >> +static void rockchip_pd_detach_dev(struct generic_pm_domain *genpd, >> + struct device *dev) >> +{ >> + dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name); >> + >> + pm_clk_destroy(dev); >> +} >> + >> +static int rockchip_pd_start_dev(struct device *dev) >> +{ >> + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); >> + >> + dev_dbg(dev, "starting device in power domain '%s'\n", genpd->name); >> + >> + return pm_clk_resume(dev); >> +} >> + >> +static int rockchip_pd_stop_dev(struct device *dev) >> +{ >> + struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain); >> + >> + dev_dbg(dev, "stopping device in power domain '%s'\n", genpd->name); >> + >> + return pm_clk_suspend(dev); >> +} >> + >> +static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, >> + struct device_node *node) >> +{ >> + const struct rockchip_domain_info *pd_info; >> + struct rockchip_pm_domain *pd; >> + struct clk *clk; >> + int clk_cnt; >> + int i; >> + u32 id; >> + int error; >> + >> + error = of_property_read_u32(node, "reg", &id); >> + if (error) { >> + dev_err(pmu->dev, >> + "%s: failed to retrieve domain id (reg): %d\n", >> + node->name, error); >> + return -EINVAL; >> + } >> + >> + if (id >= pmu->info->num_domains) { >> + dev_err(pmu->dev, "%s: invalid domain id %d\n", >> + node->name, id); >> + return -EINVAL; >> + } >> + >> + pd_info = &pmu->info->domain_info[id]; >> + if (!pd_info) { >> + dev_err(pmu->dev, "%s: undefined domain id %d\n", >> + node->name, id); >> + return -EINVAL; >> + } >> + >> + clk_cnt = of_count_phandle_with_args(node, "clocks", "#clock-cells"); >> + pd = devm_kzalloc(pmu->dev, >> + sizeof(*pd) + clk_cnt * sizeof(pd->clks[0]), >> + GFP_KERNEL); >> + if (!pd) >> + return -ENOMEM; >> + >> + pd->info = pd_info; >> + pd->pmu = pmu; >> + >> + for (i = 0; i < clk_cnt; i++) { > This loop is similar to the one when creates the PM clock list in the > rockchip_pd_attach_dev(). > > What's the reason you don't want to use pm clk for these clocks? > Ditto. >> + clk = of_clk_get(node, i); >> + if (IS_ERR(clk)) { >> + error = PTR_ERR(clk); >> + dev_err(pmu->dev, >> + "%s: failed to get clk %s (index %d): %d\n", >> + node->name, __clk_get_name(clk), i, error); >> + goto err_out; >> + } >> + >> + error = clk_prepare(clk); >> + if (error) { >> + dev_err(pmu->dev, >> + "%s: failed to prepare clk %s (index %d): %d\n", >> + node->name, __clk_get_name(clk), i, error); >> + clk_put(clk); >> + goto err_out; >> + } >> + >> + pd->clks[pd->num_clks++] = clk; >> + >> + dev_dbg(pmu->dev, "added clock '%s' to domain '%s'\n", >> + __clk_get_name(clk), node->name); >> + } >> + >> + error = rockchip_pd_power(pd, true); >> + if (error) { >> + dev_err(pmu->dev, >> + "failed to power on domain '%s': %d\n", >> + node->name, error); >> + goto err_out; >> + } >> + >> + pd->genpd.name = node->name; >> + pd->genpd.power_off = rockchip_pd_power_off; >> + pd->genpd.power_on = rockchip_pd_power_on; >> + pd->genpd.attach_dev = rockchip_pd_attach_dev; >> + pd->genpd.detach_dev = rockchip_pd_detach_dev; >> + pd->genpd.dev_ops.start = rockchip_pd_start_dev; >> + pd->genpd.dev_ops.stop = rockchip_pd_stop_dev; > Instead of assigning the ->stop|start() callbacks, which do > pm_clk_suspend|resume(), just set the genpd->flags to > GENPD_FLAG_PM_CLK, and genpd will fix this for you. > Ditto. >> + pm_genpd_init(&pd->genpd, NULL, false); >> + >> + pmu->genpd_data.domains[id] = &pd->genpd; >> + return 0; >> + >> +err_out: >> + while (--i >= 0) { >> + clk_unprepare(pd->clks[i]); >> + clk_put(pd->clks[i]); >> + } >> + return error; >> +} >> + >> +static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *pd) >> +{ >> + int i; >> + >> + for (i = 0; i < pd->num_clks; i++) { >> + clk_unprepare(pd->clks[i]); > If you converted these clocks to be dealt with via the PM clk API, > pm_clk_destoy() would have replaced this loop. > >> + clk_put(pd->clks[i]); >> + } >> + >> + /* devm will free our memory */ >> +} >> + >> +static void rockchip_pm_domain_cleanup(struct rockchip_pmu *pmu) >> +{ >> + struct generic_pm_domain *genpd; >> + struct rockchip_pm_domain *pd; >> + int i; >> + >> + for (i = 0; i < pmu->genpd_data.num_domains; i++) { >> + genpd = pmu->genpd_data.domains[i]; >> + if (genpd) { >> + pd = to_rockchip_pd(genpd); >> + rockchip_pm_remove_one_domain(pd); >> + } >> + } >> + >> + /* devm will free our memory */ >> +} >> + >> +static void rockchip_configure_pd_cnt(struct rockchip_pmu *pmu, >> + u32 domain_reg_offset, >> + unsigned int count) >> +{ >> + /* First configure domain power down transition count ... */ >> + regmap_write(pmu->regmap, domain_reg_offset, count); >> + /* ... and then power up count. */ >> + regmap_write(pmu->regmap, domain_reg_offset + 4, count); >> +} >> + >> +static int rockchip_pm_domain_probe(struct platform_device *pdev) >> +{ >> + struct device *dev = &pdev->dev; >> + struct device_node *np = dev->of_node; >> + struct device_node *node; >> + struct rockchip_pmu *pmu; >> + const struct of_device_id *match; >> + const struct rockchip_pmu_info *pmu_info; >> + int error; >> + >> + if (!np) { >> + dev_err(dev, "device tree node not found\n"); >> + return -ENXIO;/ > Nitpick: > It's more common to return -ENODEV here, you might want to change. OK. Thanks, Caesar >> + } >> + >> + match = of_match_device(dev->driver->of_match_table, dev); >> + if (!match || !match->data) { >> + dev_err(dev, "missing pmu data\n"); >> + return -EINVAL; >> + } >> + >> + pmu_info = match->data; >> + >> + pmu = devm_kzalloc(dev, >> + sizeof(*pmu) + >> + pmu_info->num_domains * sizeof(pmu->domains[0]), >> + GFP_KERNEL); >> + if (!pmu) >> + return -ENOMEM; >> + >> + pmu->dev = &pdev->dev; >> + mutex_init(&pmu->mutex); >> + >> + pmu->info = pmu_info; >> + >> + pmu->genpd_data.domains = pmu->domains; >> + pmu->genpd_data.num_domains = pmu_info->num_domains; >> + >> + node = of_parse_phandle(np, "rockchip,pmu", 0); >> + pmu->regmap = syscon_node_to_regmap(node); >> + of_node_put(node); >> + if (IS_ERR(pmu->regmap)) { >> + error = PTR_ERR(pmu->regmap); >> + dev_err(dev, "failed to get PMU regmap: %d\n", error); >> + return error; >> + } >> + >> + /* >> + * Configure power up and down transition delays for core >> + * and GPU domains. >> + */ >> + rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset, >> + pmu_info->core_power_transition_time); >> + rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset, >> + pmu_info->gpu_power_transition_time); >> + >> + error = -ENXIO; >> + >> + for_each_available_child_of_node(np, node) { >> + error = rockchip_pm_add_one_domain(pmu, node); >> + if (error) { >> + dev_err(dev, "failed to handle node %s: %d\n", >> + node->name, error); >> + goto err_out; >> + } >> + } >> + >> + if (error) { >> + dev_dbg(dev, "no power domains defined\n"); >> + goto err_out; >> + } >> + >> + of_genpd_add_provider_onecell(np, &pmu->genpd_data); >> + >> + return 0; >> + >> +err_out: >> + rockchip_pm_domain_cleanup(pmu); >> + return error; >> +} >> + >> +static const struct rockchip_domain_info rk3288_pm_domains[] = { >> + [RK3288_PD_GPU] = DOMAIN_RK3288(9, 9, 2), >> + [RK3288_PD_VIO] = DOMAIN_RK3288(7, 7, 4), >> + [RK3288_PD_VIDEO] = DOMAIN_RK3288(8, 8, 3), >> + [RK3288_PD_HEVC] = DOMAIN_RK3288(14, 10, 9), >> +}; >> + >> +static const struct rockchip_pmu_info rk3288_pmu = { >> + .pwr_offset = 0x08, >> + .status_offset = 0x0c, >> + .req_offset = 0x10, >> + .idle_offset = 0x14, >> + .ack_offset = 0x14, >> + >> + .core_pwrcnt_offset = 0x34, >> + .gpu_pwrcnt_offset = 0x3c, >> + >> + .core_power_transition_time = 24, /* 1us */ >> + .gpu_power_transition_time = 24, /* 1us */ >> + >> + .num_domains = ARRAY_SIZE(rk3288_pm_domains), >> + .domain_info = rk3288_pm_domains, >> +}; >> + >> +static const struct of_device_id rockchip_pm_domain_dt_match[] = { >> + { >> + .compatible = "rockchip,rk3288-power-controller", >> + .data = (void *)&rk3288_pmu, >> + }, >> + { /* sentinel */ }, >> +}; >> + >> +static struct platform_driver rockchip_pm_domain_driver = { >> + .probe = rockchip_pm_domain_probe, >> + .driver = { >> + .name = "rockchip-pm-domain", >> + .of_match_table = rockchip_pm_domain_dt_match, >> + /* >> + * We can't forcibly eject devices form power domain, >> + * so we can't really remove power domains once they >> + * were added. >> + */ >> + .suppress_bind_attrs = true, >> + }, >> +}; >> + >> +static int __init rockchip_pm_domain_drv_register(void) >> +{ >> + return platform_driver_register(&rockchip_pm_domain_driver); >> +} >> +postcore_initcall(rockchip_pm_domain_drv_register); >> -- >> 1.9.1 >> > Kind regards > Uffe > > _______________________________________________ > Linux-rockchip mailing list > Linux-rockchip at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-rockchip