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, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 1C6EDC433F5 for ; Tue, 14 Sep 2021 15:46:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DE35360F3A for ; Tue, 14 Sep 2021 15:46:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234588AbhINPsM (ORCPT ); Tue, 14 Sep 2021 11:48:12 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:50392 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234464AbhINPsM (ORCPT ); Tue, 14 Sep 2021 11:48:12 -0400 Received: from [IPv6:2a01:e0a:4cb:a870:ea21:e288:63eb:50f2] (unknown [IPv6:2a01:e0a:4cb:a870:ea21:e288:63eb:50f2]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 3ABC91F42C5F; Tue, 14 Sep 2021 16:46:52 +0100 (BST) Subject: Re: [PATCH v4 10/18] soc: imx: add i.MX8M blk-ctrl driver To: Lucas Stach , Shawn Guo Cc: Rob Herring , Fabio Estevam , NXP Linux Team , Adam Ford , Frieder Schrempf , Marek Vasut , Tim Harvey , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, patchwork-lst@pengutronix.de References: <20210910202640.980366-1-l.stach@pengutronix.de> <20210910202640.980366-11-l.stach@pengutronix.de> From: Benjamin Gaignard Message-ID: <5b5609e9-cbba-79be-218c-0dd508e26ecf@collabora.com> Date: Tue, 14 Sep 2021 17:46:49 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <20210910202640.980366-11-l.stach@pengutronix.de> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Le 10/09/2021 à 22:26, Lucas Stach a écrit : > This adds a driver for the blk-ctrl blocks found in the i.MX8M* line of > SoCs. The blk-ctrl is a top-level peripheral located in the various *MIX > power domains and interacts with the GPC power controller to provide the > peripherals in the power domain access to the NoC and ensures that those > peripherals are properly reset when their respective power domain is > brought back to life. > > Software needs to do different things to make the bus handshake happen > after the GPC *MIX domain is powered up and before it is powered down. > As the requirements are quite different between the various blk-ctrls > there is a callback function provided to hook in the proper sequence. > > The peripheral domains are quite uniform, they handle the soft clock > enables and resets in the blk-ctrl address space and sequencing with the > upstream GPC power domains. Hi Lucas, I have tried to use your patches for IMX8MQ but it seems that the hardware have different architecture. On IMX8MQ there is only one VPU domain for G1 and G2 and that doesn't match with your implementation where it is needed to have "bus" and devices power domain. From what I experiment in current IMX8MQ implementation of blk-ctrl (inside VPU driver) enabling the 3 clocks (bus, G1, G2) is needed to reset the VPUs. Do you think you can update your design to take care of these hardware variations ? Regards, Benjamin > > Signed-off-by: Lucas Stach > Acked-by: Frieder Schrempf > Reviewed-by: Philipp Zabel > --- > This commit includes the full code to drive the VPUMIX domain on the > i.MX8MM, as the skeleton driver would probably be harder to review > without the context provided by one blk-ctrl implementation. Other > blk-ctrl implementations will follow, based on this overall structure. > > v4: > - fix commit message typos > - fix superfluous whitespace > - constify clk_names more > --- > drivers/soc/imx/Makefile | 1 + > drivers/soc/imx/imx8m-blk-ctrl.c | 453 +++++++++++++++++++++++++++++++ > 2 files changed, 454 insertions(+) > create mode 100644 drivers/soc/imx/imx8m-blk-ctrl.c > > diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile > index 078dc918f4f3..8a707077914c 100644 > --- a/drivers/soc/imx/Makefile > +++ b/drivers/soc/imx/Makefile > @@ -5,3 +5,4 @@ endif > obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o > obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o > obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o > +obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o > diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c > new file mode 100644 > index 000000000000..f2d74669d683 > --- /dev/null > +++ b/drivers/soc/imx/imx8m-blk-ctrl.c > @@ -0,0 +1,453 @@ > +// SPDX-License-Identifier: GPL-2.0+ > + > +/* > + * Copyright 2021 Pengutronix, Lucas Stach > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#define BLK_SFT_RSTN 0x0 > +#define BLK_CLK_EN 0x4 > + > +struct imx8m_blk_ctrl_domain; > + > +struct imx8m_blk_ctrl { > + struct device *dev; > + struct notifier_block power_nb; > + struct device *bus_power_dev; > + struct regmap *regmap; > + struct imx8m_blk_ctrl_domain *domains; > + struct genpd_onecell_data onecell_data; > +}; > + > +struct imx8m_blk_ctrl_domain_data { > + const char *name; > + const char * const *clk_names; > + int num_clks; > + const char *gpc_name; > + u32 rst_mask; > + u32 clk_mask; > +}; > + > +#define DOMAIN_MAX_CLKS 3 > + > +struct imx8m_blk_ctrl_domain { > + struct generic_pm_domain genpd; > + const struct imx8m_blk_ctrl_domain_data *data; > + struct clk_bulk_data clks[DOMAIN_MAX_CLKS]; > + struct device *power_dev; > + struct imx8m_blk_ctrl *bc; > +}; > + > +struct imx8m_blk_ctrl_data { > + int max_reg; > + notifier_fn_t power_notifier_fn; > + const struct imx8m_blk_ctrl_domain_data *domains; > + int num_domains; > +}; > + > +static inline struct imx8m_blk_ctrl_domain * > +to_imx8m_blk_ctrl_domain(struct generic_pm_domain *genpd) > +{ > + return container_of(genpd, struct imx8m_blk_ctrl_domain, genpd); > +} > + > +static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd) > +{ > + struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd); > + const struct imx8m_blk_ctrl_domain_data *data = domain->data; > + struct imx8m_blk_ctrl *bc = domain->bc; > + int ret; > + > + /* make sure bus domain is awake */ > + ret = pm_runtime_get_sync(bc->bus_power_dev); > + if (ret < 0) { > + pm_runtime_put_noidle(bc->bus_power_dev); > + dev_err(bc->dev, "failed to power up bus domain\n"); > + return ret; > + } > + > + /* put devices into reset */ > + regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); > + > + /* enable upstream and blk-ctrl clocks to allow reset to propagate */ > + ret = clk_bulk_prepare_enable(data->num_clks, domain->clks); Maybe the clocks should be enabled before clear BLK_SFT_RSTN ? > + if (ret) { > + dev_err(bc->dev, "failed to enable clocks\n"); > + goto bus_put; > + } > + regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); > + > + /* power up upstream GPC domain */ > + ret = pm_runtime_get_sync(domain->power_dev); > + if (ret < 0) { > + dev_err(bc->dev, "failed to power up peripheral domain\n"); > + goto clk_disable; > + } > + > + /* wait for reset to propagate */ > + udelay(5); > + > + /* release reset */ > + regmap_set_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); > + > + /* disable upstream clocks */ > + clk_bulk_disable_unprepare(data->num_clks, domain->clks); > + > + return 0; > + > +clk_disable: > + clk_bulk_disable_unprepare(data->num_clks, domain->clks); > +bus_put: > + pm_runtime_put(bc->bus_power_dev); > + > + return ret; > +} > + > +static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd) > +{ > + struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd); > + const struct imx8m_blk_ctrl_domain_data *data = domain->data; > + struct imx8m_blk_ctrl *bc = domain->bc; > + > + /* put devices into reset and disable clocks */ > + regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); > + regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); > + > + /* power down upstream GPC domain */ > + pm_runtime_put(domain->power_dev); > + > + /* allow bus domain to suspend */ > + pm_runtime_put(bc->bus_power_dev); > + > + return 0; > +} > + > +static struct generic_pm_domain * > +imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data) > +{ > + struct genpd_onecell_data *onecell_data = data; > + unsigned int index = args->args[0]; > + > + if (args->args_count != 1 || > + index > onecell_data->num_domains) > + return ERR_PTR(-EINVAL); > + > + return onecell_data->domains[index]; > +} > + > +static struct lock_class_key blk_ctrl_genpd_lock_class; > + > +static int imx8m_blk_ctrl_probe(struct platform_device *pdev) > +{ > + const struct imx8m_blk_ctrl_data *bc_data; > + struct device *dev = &pdev->dev; > + struct imx8m_blk_ctrl *bc; > + void __iomem *base; > + int i, ret; > + > + struct regmap_config regmap_config = { > + .reg_bits = 32, > + .val_bits = 32, > + .reg_stride = 4, > + }; > + > + bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL); > + if (!bc) > + return -ENOMEM; > + > + bc->dev = dev; > + > + bc_data = of_device_get_match_data(dev); > + > + base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(base)) > + return PTR_ERR(base); > + > + regmap_config.max_register = bc_data->max_reg; > + bc->regmap = devm_regmap_init_mmio(dev, base, ®map_config); > + if (IS_ERR(bc->regmap)) > + return dev_err_probe(dev, PTR_ERR(bc->regmap), > + "failed to init regmap\n"); > + > + bc->domains = devm_kcalloc(dev, bc_data->num_domains, > + sizeof(struct imx8m_blk_ctrl_domain), > + GFP_KERNEL); > + if (!bc->domains) > + return -ENOMEM; > + > + bc->onecell_data.num_domains = bc_data->num_domains; > + bc->onecell_data.xlate = imx8m_blk_ctrl_xlate; > + bc->onecell_data.domains = > + devm_kcalloc(dev, bc_data->num_domains, > + sizeof(struct generic_pm_domain *), GFP_KERNEL); > + if (!bc->onecell_data.domains) > + return -ENOMEM; > + > + bc->bus_power_dev = genpd_dev_pm_attach_by_name(dev, "bus"); > + if (IS_ERR(bc->bus_power_dev)) > + return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev), > + "failed to attach power domain\n"); > + > + for (i = 0; i < bc_data->num_domains; i++) { > + const struct imx8m_blk_ctrl_domain_data *data = &bc_data->domains[i]; > + struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; > + int j; > + > + domain->data = data; > + > + for (j = 0; j < data->num_clks; j++) > + domain->clks[j].id = data->clk_names[j]; > + > + ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); > + if (ret) { > + dev_err_probe(dev, ret, "failed to get clock\n"); > + goto cleanup_pds; > + } > + > + domain->power_dev = > + dev_pm_domain_attach_by_name(dev, data->gpc_name); > + if (IS_ERR(domain->power_dev)) { > + dev_err_probe(dev, PTR_ERR(domain->power_dev), > + "failed to attach power domain\n"); > + ret = PTR_ERR(domain->power_dev); > + goto cleanup_pds; > + } > + > + domain->genpd.name = data->name; > + domain->genpd.power_on = imx8m_blk_ctrl_power_on; > + domain->genpd.power_off = imx8m_blk_ctrl_power_off; > + domain->bc = bc; > + > + ret = pm_genpd_init(&domain->genpd, NULL, true); > + if (ret) { > + dev_err_probe(dev, ret, "failed to init power domain\n"); > + dev_pm_domain_detach(domain->power_dev, true); > + goto cleanup_pds; > + } > + > + /* > + * We use runtime PM to trigger power on/off of the upstream GPC > + * domain, as a strict hierarchical parent/child power domain > + * setup doesn't allow us to meet the sequencing requirements. > + * This means we have nested locking of genpd locks, without the > + * nesting being visible at the genpd level, so we need a > + * separate lock class to make lockdep aware of the fact that > + * this are separate domain locks that can be nested without a > + * self-deadlock. > + */ > + lockdep_set_class(&domain->genpd.mlock, > + &blk_ctrl_genpd_lock_class); > + > + bc->onecell_data.domains[i] = &domain->genpd; > + } > + > + ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data); > + if (ret) { > + dev_err_probe(dev, ret, "failed to add power domain provider\n"); > + goto cleanup_pds; > + } > + > + bc->power_nb.notifier_call = bc_data->power_notifier_fn; > + ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb); > + if (ret) { > + dev_err_probe(dev, ret, "failed to add power notifier\n"); > + goto cleanup_provider; > + } > + > + dev_set_drvdata(dev, bc); > + > + return 0; > + > +cleanup_provider: > + of_genpd_del_provider(dev->of_node); > +cleanup_pds: > + for (i--; i >= 0; i--) { > + pm_genpd_remove(&bc->domains[i].genpd); > + dev_pm_domain_detach(bc->domains[i].power_dev, true); > + } > + > + dev_pm_domain_detach(bc->bus_power_dev, true); > + > + return ret; > +} > + > +static int imx8m_blk_ctrl_remove(struct platform_device *pdev) > +{ > + struct imx8m_blk_ctrl *bc = dev_get_drvdata(&pdev->dev); > + int i; > + > + of_genpd_del_provider(pdev->dev.of_node); > + > + for (i = 0; bc->onecell_data.num_domains; i++) { > + struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; > + > + pm_genpd_remove(&domain->genpd); > + dev_pm_domain_detach(domain->power_dev, true); > + } > + > + dev_pm_genpd_remove_notifier(bc->bus_power_dev); > + > + dev_pm_domain_detach(bc->bus_power_dev, true); > + > + return 0; > +} > + > +#ifdef CONFIG_PM_SLEEP > +static int imx8m_blk_ctrl_suspend(struct device *dev) > +{ > + struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev); > + int ret, i; > + > + /* > + * This may look strange, but is done so the generic PM_SLEEP code > + * can power down our domains and more importantly power them up again > + * after resume, without tripping over our usage of runtime PM to > + * control the upstream GPC domains. Things happen in the right order > + * in the system suspend/resume paths due to the device parent/child > + * hierarchy. > + */ > + ret = pm_runtime_get_sync(bc->bus_power_dev); > + if (ret < 0) { > + pm_runtime_put_noidle(bc->bus_power_dev); > + return ret; > + } > + > + for (i = 0; i < bc->onecell_data.num_domains; i++) { > + struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; > + > + ret = pm_runtime_get_sync(domain->power_dev); > + if (ret < 0) { > + pm_runtime_put_noidle(domain->power_dev); > + goto out_fail; > + } > + } > + > + return 0; > + > +out_fail: > + for (i--; i >= 0; i--) > + pm_runtime_put(bc->domains[i].power_dev); > + > + pm_runtime_put(bc->bus_power_dev); > + > + return ret; > +} > + > +static int imx8m_blk_ctrl_resume(struct device *dev) > +{ > + struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev); > + int i; > + > + for (i = 0; i < bc->onecell_data.num_domains; i++) > + pm_runtime_put(bc->domains[i].power_dev); > + > + pm_runtime_put(bc->bus_power_dev); > + > + return 0; > +} > +#endif > + > +static const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = { > + SET_SYSTEM_SLEEP_PM_OPS(imx8m_blk_ctrl_suspend, imx8m_blk_ctrl_resume) > +}; > + > +static int imx8mm_vpu_power_notifier(struct notifier_block *nb, > + unsigned long action, void *data) > +{ > + struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, > + power_nb); > + > + if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) > + return NOTIFY_OK; > + > + /* > + * The ADB in the VPUMIX domain has no separate reset and clock > + * enable bits, but is ungated together with the VPU clocks. To > + * allow the handshake with the GPC to progress we put the VPUs > + * in reset and ungate the clocks. > + */ > + regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1) | BIT(2)); > + regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1) | BIT(2)); > + > + if (action == GENPD_NOTIFY_ON) { > + /* > + * On power up we have no software backchannel to the GPC to > + * wait for the ADB handshake to happen, so we just delay for a > + * bit. On power down the GPC driver waits for the handshake. > + */ > + udelay(5); > + > + /* set "fuse" bits to enable the VPUs */ > + regmap_set_bits(bc->regmap, 0x8, 0xffffffff); > + regmap_set_bits(bc->regmap, 0xc, 0xffffffff); > + regmap_set_bits(bc->regmap, 0x10, 0xffffffff); > + regmap_set_bits(bc->regmap, 0x14, 0xffffffff); > + } > + > + return NOTIFY_OK; > +} > + > +static const struct imx8m_blk_ctrl_domain_data imx8m_vpu_blk_ctl_domain_data[] = { > + [IMX8MM_VPUBLK_PD_G1] = { > + .name = "vpublk-g1", > + .clk_names = (const char *[]){ "g1", }, > + .num_clks = 1, > + .gpc_name = "g1", > + .rst_mask = BIT(1), > + .clk_mask = BIT(1), > + }, > + [IMX8MM_VPUBLK_PD_G2] = { > + .name = "vpublk-g2", > + .clk_names = (const char *[]){ "g2", }, > + .num_clks = 1, > + .gpc_name = "g2", > + .rst_mask = BIT(0), > + .clk_mask = BIT(0), > + }, > + [IMX8MM_VPUBLK_PD_H1] = { > + .name = "vpublk-h1", > + .clk_names = (const char *[]){ "h1", }, > + .num_clks = 1, > + .gpc_name = "h1", > + .rst_mask = BIT(2), > + .clk_mask = BIT(2), > + }, > +}; > + > +static const struct imx8m_blk_ctrl_data imx8m_vpu_blk_ctl_dev_data = { > + .max_reg = 0x18, > + .power_notifier_fn = imx8mm_vpu_power_notifier, > + .domains = imx8m_vpu_blk_ctl_domain_data, > + .num_domains = ARRAY_SIZE(imx8m_vpu_blk_ctl_domain_data), > +}; > + > +static const struct of_device_id imx8m_blk_ctrl_of_match[] = { > + { > + .compatible = "fsl,imx8mm-vpu-blk-ctrl", > + .data = &imx8m_vpu_blk_ctl_dev_data > + }, { > + /* Sentinel */ > + } > +}; > +MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match); > + > +static struct platform_driver imx8m_blk_ctrl_driver = { > + .probe = imx8m_blk_ctrl_probe, > + .remove = imx8m_blk_ctrl_remove, > + .driver = { > + .name = "imx8m-blk-ctrl", > + .pm = &imx8m_blk_ctrl_pm_ops, > + .of_match_table = imx8m_blk_ctrl_of_match, > + }, > +}; > +module_platform_driver(imx8m_blk_ctrl_driver); 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.6 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,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 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 D8153C433F5 for ; Tue, 14 Sep 2021 15:49:04 +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 A231061166 for ; Tue, 14 Sep 2021 15:49:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org A231061166 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=collabora.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-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:Cc:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=1T/AUZgV4hmq5FHHv0pKYl5MBsbk6xef92beX6srTrY=; b=VI83eNoboL1h2j3OAKaFE26Dyr eu7HkX4ewvuLF/RwexG438dSrIG9f4SuRu6QkRt3g3K3jWPBPa6VQUAePOP2yJ5ENkQB/C1EbQYSh KU5u9rOsV4O3aUKpXWc/vZogluuVFSbO1BIfniY9KTsXX9DNZtljYkJKYXXp6oERYAGGCDhiRrUT+ 5NSJlhVGCSC5ifheK1CfQA7Sckdfofc9SOn1V9SPN46Enm8hGiZY69yZ7/kIaKo+ej7ErU+QEfcT1 +M5O/JZbT5u7A3AMZdw9xDydO3zxkYsHWIYrCos/wPMI+UlhrnlOuua7yE7DTP6udHphbJPdPP0oo O7DFEL4w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mQAeE-006GwC-9N; Tue, 14 Sep 2021 15:47:02 +0000 Received: from bhuna.collabora.co.uk ([2a00:1098:0:82:1000:25:2eeb:e3e3]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mQAe8-006GuN-Iw for linux-arm-kernel@lists.infradead.org; Tue, 14 Sep 2021 15:46:59 +0000 Received: from [IPv6:2a01:e0a:4cb:a870:ea21:e288:63eb:50f2] (unknown [IPv6:2a01:e0a:4cb:a870:ea21:e288:63eb:50f2]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 3ABC91F42C5F; Tue, 14 Sep 2021 16:46:52 +0100 (BST) Subject: Re: [PATCH v4 10/18] soc: imx: add i.MX8M blk-ctrl driver To: Lucas Stach , Shawn Guo Cc: Rob Herring , Fabio Estevam , NXP Linux Team , Adam Ford , Frieder Schrempf , Marek Vasut , Tim Harvey , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de, patchwork-lst@pengutronix.de References: <20210910202640.980366-1-l.stach@pengutronix.de> <20210910202640.980366-11-l.stach@pengutronix.de> From: Benjamin Gaignard Message-ID: <5b5609e9-cbba-79be-218c-0dd508e26ecf@collabora.com> Date: Tue, 14 Sep 2021 17:46:49 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <20210910202640.980366-11-l.stach@pengutronix.de> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210914_084656_943900_CB976EDF X-CRM114-Status: GOOD ( 50.67 ) 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-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org CkxlIDEwLzA5LzIwMjEgw6AgMjI6MjYsIEx1Y2FzIFN0YWNoIGEgw6ljcml0wqA6Cj4gVGhpcyBh ZGRzIGEgZHJpdmVyIGZvciB0aGUgYmxrLWN0cmwgYmxvY2tzIGZvdW5kIGluIHRoZSBpLk1YOE0q IGxpbmUgb2YKPiBTb0NzLiBUaGUgYmxrLWN0cmwgaXMgYSB0b3AtbGV2ZWwgcGVyaXBoZXJhbCBs b2NhdGVkIGluIHRoZSB2YXJpb3VzICpNSVgKPiBwb3dlciBkb21haW5zIGFuZCBpbnRlcmFjdHMg d2l0aCB0aGUgR1BDIHBvd2VyIGNvbnRyb2xsZXIgdG8gcHJvdmlkZSB0aGUKPiBwZXJpcGhlcmFs cyBpbiB0aGUgcG93ZXIgZG9tYWluIGFjY2VzcyB0byB0aGUgTm9DIGFuZCBlbnN1cmVzIHRoYXQg dGhvc2UKPiBwZXJpcGhlcmFscyBhcmUgcHJvcGVybHkgcmVzZXQgd2hlbiB0aGVpciByZXNwZWN0 aXZlIHBvd2VyIGRvbWFpbiBpcwo+IGJyb3VnaHQgYmFjayB0byBsaWZlLgo+Cj4gU29mdHdhcmUg bmVlZHMgdG8gZG8gZGlmZmVyZW50IHRoaW5ncyB0byBtYWtlIHRoZSBidXMgaGFuZHNoYWtlIGhh cHBlbgo+IGFmdGVyIHRoZSBHUEMgKk1JWCBkb21haW4gaXMgcG93ZXJlZCB1cCBhbmQgYmVmb3Jl IGl0IGlzIHBvd2VyZWQgZG93bi4KPiBBcyB0aGUgcmVxdWlyZW1lbnRzIGFyZSBxdWl0ZSBkaWZm ZXJlbnQgYmV0d2VlbiB0aGUgdmFyaW91cyBibGstY3RybHMKPiB0aGVyZSBpcyBhIGNhbGxiYWNr IGZ1bmN0aW9uIHByb3ZpZGVkIHRvIGhvb2sgaW4gdGhlIHByb3BlciBzZXF1ZW5jZS4KPgo+IFRo ZSBwZXJpcGhlcmFsIGRvbWFpbnMgYXJlIHF1aXRlIHVuaWZvcm0sIHRoZXkgaGFuZGxlIHRoZSBz b2Z0IGNsb2NrCj4gZW5hYmxlcyBhbmQgcmVzZXRzIGluIHRoZSBibGstY3RybCBhZGRyZXNzIHNw YWNlIGFuZCBzZXF1ZW5jaW5nIHdpdGggdGhlCj4gdXBzdHJlYW0gR1BDIHBvd2VyIGRvbWFpbnMu CgpIaSBMdWNhcywKCkkgaGF2ZSB0cmllZCB0byB1c2UgeW91ciBwYXRjaGVzIGZvciBJTVg4TVEg YnV0IGl0IHNlZW1zIHRoYXQgdGhlIGhhcmR3YXJlCmhhdmUgZGlmZmVyZW50IGFyY2hpdGVjdHVy ZS4KT24gSU1YOE1RIHRoZXJlIGlzIG9ubHkgb25lIFZQVSBkb21haW4gZm9yIEcxIGFuZCBHMiBh bmQgdGhhdCBkb2Vzbid0IG1hdGNoCndpdGggeW91ciBpbXBsZW1lbnRhdGlvbiB3aGVyZSBpdCBp cyBuZWVkZWQgdG8gaGF2ZSAiYnVzIiBhbmQgZGV2aWNlcyBwb3dlciBkb21haW4uCiBGcm9tIHdo YXQgSSBleHBlcmltZW50IGluIGN1cnJlbnQgSU1YOE1RIGltcGxlbWVudGF0aW9uIG9mIGJsay1j dHJsIChpbnNpZGUgVlBVIGRyaXZlcikKZW5hYmxpbmcgdGhlIDMgY2xvY2tzIChidXMsIEcxLCBH MikgaXMgbmVlZGVkIHRvIHJlc2V0IHRoZSBWUFVzLgoKRG8geW91IHRoaW5rIHlvdSBjYW4gdXBk YXRlIHlvdXIgZGVzaWduIHRvIHRha2UgY2FyZSBvZiB0aGVzZSBoYXJkd2FyZSB2YXJpYXRpb25z ID8KClJlZ2FyZHMsCkJlbmphbWluCgo+Cj4gU2lnbmVkLW9mZi1ieTogTHVjYXMgU3RhY2ggPGwu c3RhY2hAcGVuZ3V0cm9uaXguZGU+Cj4gQWNrZWQtYnk6IEZyaWVkZXIgU2NocmVtcGYgPGZyaWVk ZXIuc2NocmVtcGZAa29udHJvbi5kZT4KPiBSZXZpZXdlZC1ieTogUGhpbGlwcCBaYWJlbCA8cC56 YWJlbEBwZW5ndXRyb25peC5kZT4KPiAtLS0KPiBUaGlzIGNvbW1pdCBpbmNsdWRlcyB0aGUgZnVs bCBjb2RlIHRvIGRyaXZlIHRoZSBWUFVNSVggZG9tYWluIG9uIHRoZQo+IGkuTVg4TU0sIGFzIHRo ZSBza2VsZXRvbiBkcml2ZXIgd291bGQgcHJvYmFibHkgYmUgaGFyZGVyIHRvIHJldmlldwo+IHdp dGhvdXQgdGhlIGNvbnRleHQgcHJvdmlkZWQgYnkgb25lIGJsay1jdHJsIGltcGxlbWVudGF0aW9u LiBPdGhlcgo+IGJsay1jdHJsIGltcGxlbWVudGF0aW9ucyB3aWxsIGZvbGxvdywgYmFzZWQgb24g dGhpcyBvdmVyYWxsIHN0cnVjdHVyZS4KPgo+IHY0Ogo+IC0gZml4IGNvbW1pdCBtZXNzYWdlIHR5 cG9zCj4gLSBmaXggc3VwZXJmbHVvdXMgd2hpdGVzcGFjZQo+IC0gY29uc3RpZnkgY2xrX25hbWVz IG1vcmUKPiAtLS0KPiAgIGRyaXZlcnMvc29jL2lteC9NYWtlZmlsZSAgICAgICAgIHwgICAxICsK PiAgIGRyaXZlcnMvc29jL2lteC9pbXg4bS1ibGstY3RybC5jIHwgNDUzICsrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysKPiAgIDIgZmlsZXMgY2hhbmdlZCwgNDU0IGluc2VydGlvbnMoKykK PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3NvYy9pbXgvaW14OG0tYmxrLWN0cmwuYwo+ Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvc29jL2lteC9NYWtlZmlsZSBiL2RyaXZlcnMvc29jL2lt eC9NYWtlZmlsZQo+IGluZGV4IDA3OGRjOTE4ZjRmMy4uOGE3MDcwNzc5MTRjIDEwMDY0NAo+IC0t LSBhL2RyaXZlcnMvc29jL2lteC9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvc29jL2lteC9NYWtl ZmlsZQo+IEBAIC01LDMgKzUsNCBAQCBlbmRpZgo+ICAgb2JqLSQoQ09ORklHX0hBVkVfSU1YX0dQ QykgKz0gZ3BjLm8KPiAgIG9iai0kKENPTkZJR19JTVhfR1BDVjJfUE1fRE9NQUlOUykgKz0gZ3Bj djIubwo+ICAgb2JqLSQoQ09ORklHX1NPQ19JTVg4TSkgKz0gc29jLWlteDhtLm8KPiArb2JqLSQo Q09ORklHX1NPQ19JTVg4TSkgKz0gaW14OG0tYmxrLWN0cmwubwo+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL3NvYy9pbXgvaW14OG0tYmxrLWN0cmwuYyBiL2RyaXZlcnMvc29jL2lteC9pbXg4bS1ibGst Y3RybC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLmYyZDc0 NjY5ZDY4Mwo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL3NvYy9pbXgvaW14OG0tYmxr LWN0cmwuYwo+IEBAIC0wLDAgKzEsNDUzIEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVy OiBHUEwtMi4wKwo+ICsKPiArLyoKPiArICogQ29weXJpZ2h0IDIwMjEgUGVuZ3V0cm9uaXgsIEx1 Y2FzIFN0YWNoIDxrZXJuZWxAcGVuZ3V0cm9uaXguZGU+Cj4gKyAqLwo+ICsKPiArI2luY2x1ZGUg PGxpbnV4L2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRl IDxsaW51eC9vZl9kZXZpY2UuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5o Pgo+ICsjaW5jbHVkZSA8bGludXgvcG1fZG9tYWluLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9wbV9y dW50aW1lLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4KPiArI2luY2x1ZGUgPGxpbnV4 L2Nsay5oPgo+ICsKPiArI2luY2x1ZGUgPGR0LWJpbmRpbmdzL3Bvd2VyL2lteDhtbS1wb3dlci5o Pgo+ICsKPiArI2RlZmluZSBCTEtfU0ZUX1JTVE4JMHgwCj4gKyNkZWZpbmUgQkxLX0NMS19FTgkw eDQKPiArCj4gK3N0cnVjdCBpbXg4bV9ibGtfY3RybF9kb21haW47Cj4gKwo+ICtzdHJ1Y3QgaW14 OG1fYmxrX2N0cmwgewo+ICsJc3RydWN0IGRldmljZSAqZGV2Owo+ICsJc3RydWN0IG5vdGlmaWVy X2Jsb2NrIHBvd2VyX25iOwo+ICsJc3RydWN0IGRldmljZSAqYnVzX3Bvd2VyX2RldjsKPiArCXN0 cnVjdCByZWdtYXAgKnJlZ21hcDsKPiArCXN0cnVjdCBpbXg4bV9ibGtfY3RybF9kb21haW4gKmRv bWFpbnM7Cj4gKwlzdHJ1Y3QgZ2VucGRfb25lY2VsbF9kYXRhIG9uZWNlbGxfZGF0YTsKPiArfTsK PiArCj4gK3N0cnVjdCBpbXg4bV9ibGtfY3RybF9kb21haW5fZGF0YSB7Cj4gKwljb25zdCBjaGFy ICpuYW1lOwo+ICsJY29uc3QgY2hhciAqIGNvbnN0ICpjbGtfbmFtZXM7Cj4gKwlpbnQgbnVtX2Ns a3M7Cj4gKwljb25zdCBjaGFyICpncGNfbmFtZTsKPiArCXUzMiByc3RfbWFzazsKPiArCXUzMiBj bGtfbWFzazsKPiArfTsKPiArCj4gKyNkZWZpbmUgRE9NQUlOX01BWF9DTEtTIDMKPiArCj4gK3N0 cnVjdCBpbXg4bV9ibGtfY3RybF9kb21haW4gewo+ICsJc3RydWN0IGdlbmVyaWNfcG1fZG9tYWlu IGdlbnBkOwo+ICsJY29uc3Qgc3RydWN0IGlteDhtX2Jsa19jdHJsX2RvbWFpbl9kYXRhICpkYXRh Owo+ICsJc3RydWN0IGNsa19idWxrX2RhdGEgY2xrc1tET01BSU5fTUFYX0NMS1NdOwo+ICsJc3Ry dWN0IGRldmljZSAqcG93ZXJfZGV2Owo+ICsJc3RydWN0IGlteDhtX2Jsa19jdHJsICpiYzsKPiAr fTsKPiArCj4gK3N0cnVjdCBpbXg4bV9ibGtfY3RybF9kYXRhIHsKPiArCWludCBtYXhfcmVnOwo+ ICsJbm90aWZpZXJfZm5fdCBwb3dlcl9ub3RpZmllcl9mbjsKPiArCWNvbnN0IHN0cnVjdCBpbXg4 bV9ibGtfY3RybF9kb21haW5fZGF0YSAqZG9tYWluczsKPiArCWludCBudW1fZG9tYWluczsKPiAr fTsKPiArCj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGlteDhtX2Jsa19jdHJsX2RvbWFpbiAqCj4g K3RvX2lteDhtX2Jsa19jdHJsX2RvbWFpbihzdHJ1Y3QgZ2VuZXJpY19wbV9kb21haW4gKmdlbnBk KQo+ICt7Cj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGdlbnBkLCBzdHJ1Y3QgaW14OG1fYmxrX2N0 cmxfZG9tYWluLCBnZW5wZCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgaW14OG1fYmxrX2N0cmxf cG93ZXJfb24oc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluICpnZW5wZCkKPiArewo+ICsJc3RydWN0 IGlteDhtX2Jsa19jdHJsX2RvbWFpbiAqZG9tYWluID0gdG9faW14OG1fYmxrX2N0cmxfZG9tYWlu KGdlbnBkKTsKPiArCWNvbnN0IHN0cnVjdCBpbXg4bV9ibGtfY3RybF9kb21haW5fZGF0YSAqZGF0 YSA9IGRvbWFpbi0+ZGF0YTsKPiArCXN0cnVjdCBpbXg4bV9ibGtfY3RybCAqYmMgPSBkb21haW4t PmJjOwo+ICsJaW50IHJldDsKPiArCj4gKwkvKiBtYWtlIHN1cmUgYnVzIGRvbWFpbiBpcyBhd2Fr ZSAqLwo+ICsJcmV0ID0gcG1fcnVudGltZV9nZXRfc3luYyhiYy0+YnVzX3Bvd2VyX2Rldik7Cj4g KwlpZiAocmV0IDwgMCkgewo+ICsJCXBtX3J1bnRpbWVfcHV0X25vaWRsZShiYy0+YnVzX3Bvd2Vy X2Rldik7Cj4gKwkJZGV2X2VycihiYy0+ZGV2LCAiZmFpbGVkIHRvIHBvd2VyIHVwIGJ1cyBkb21h aW5cbiIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJLyogcHV0IGRldmljZXMgaW50 byByZXNldCAqLwo+ICsJcmVnbWFwX2NsZWFyX2JpdHMoYmMtPnJlZ21hcCwgQkxLX1NGVF9SU1RO LCBkYXRhLT5yc3RfbWFzayk7Cj4gKwo+ICsJLyogZW5hYmxlIHVwc3RyZWFtIGFuZCBibGstY3Ry bCBjbG9ja3MgdG8gYWxsb3cgcmVzZXQgdG8gcHJvcGFnYXRlICovCj4gKwlyZXQgPSBjbGtfYnVs a19wcmVwYXJlX2VuYWJsZShkYXRhLT5udW1fY2xrcywgZG9tYWluLT5jbGtzKTsKCk1heWJlIHRo ZSBjbG9ja3Mgc2hvdWxkIGJlIGVuYWJsZWQgYmVmb3JlIGNsZWFyIEJMS19TRlRfUlNUTiA/Cgo+ ICsJaWYgKHJldCkgewo+ICsJCWRldl9lcnIoYmMtPmRldiwgImZhaWxlZCB0byBlbmFibGUgY2xv Y2tzXG4iKTsKPiArCQlnb3RvIGJ1c19wdXQ7Cj4gKwl9Cj4gKwlyZWdtYXBfc2V0X2JpdHMoYmMt PnJlZ21hcCwgQkxLX0NMS19FTiwgZGF0YS0+Y2xrX21hc2spOwo+ICsKPiArCS8qIHBvd2VyIHVw IHVwc3RyZWFtIEdQQyBkb21haW4gKi8KPiArCXJldCA9IHBtX3J1bnRpbWVfZ2V0X3N5bmMoZG9t YWluLT5wb3dlcl9kZXYpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlkZXZfZXJyKGJjLT5kZXYs ICJmYWlsZWQgdG8gcG93ZXIgdXAgcGVyaXBoZXJhbCBkb21haW5cbiIpOwo+ICsJCWdvdG8gY2xr X2Rpc2FibGU7Cj4gKwl9Cj4gKwo+ICsJLyogd2FpdCBmb3IgcmVzZXQgdG8gcHJvcGFnYXRlICov Cj4gKwl1ZGVsYXkoNSk7Cj4gKwo+ICsJLyogcmVsZWFzZSByZXNldCAqLwo+ICsJcmVnbWFwX3Nl dF9iaXRzKGJjLT5yZWdtYXAsIEJMS19TRlRfUlNUTiwgZGF0YS0+cnN0X21hc2spOwo+ICsKPiAr CS8qIGRpc2FibGUgdXBzdHJlYW0gY2xvY2tzICovCj4gKwljbGtfYnVsa19kaXNhYmxlX3VucHJl cGFyZShkYXRhLT5udW1fY2xrcywgZG9tYWluLT5jbGtzKTsKPiArCj4gKwlyZXR1cm4gMDsKPiAr Cj4gK2Nsa19kaXNhYmxlOgo+ICsJY2xrX2J1bGtfZGlzYWJsZV91bnByZXBhcmUoZGF0YS0+bnVt X2Nsa3MsIGRvbWFpbi0+Y2xrcyk7Cj4gK2J1c19wdXQ6Cj4gKwlwbV9ydW50aW1lX3B1dChiYy0+ YnVzX3Bvd2VyX2Rldik7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGljIGlu dCBpbXg4bV9ibGtfY3RybF9wb3dlcl9vZmYoc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluICpnZW5w ZCkKPiArewo+ICsJc3RydWN0IGlteDhtX2Jsa19jdHJsX2RvbWFpbiAqZG9tYWluID0gdG9faW14 OG1fYmxrX2N0cmxfZG9tYWluKGdlbnBkKTsKPiArCWNvbnN0IHN0cnVjdCBpbXg4bV9ibGtfY3Ry bF9kb21haW5fZGF0YSAqZGF0YSA9IGRvbWFpbi0+ZGF0YTsKPiArCXN0cnVjdCBpbXg4bV9ibGtf Y3RybCAqYmMgPSBkb21haW4tPmJjOwo+ICsKPiArCS8qIHB1dCBkZXZpY2VzIGludG8gcmVzZXQg YW5kIGRpc2FibGUgY2xvY2tzICovCj4gKwlyZWdtYXBfY2xlYXJfYml0cyhiYy0+cmVnbWFwLCBC TEtfU0ZUX1JTVE4sIGRhdGEtPnJzdF9tYXNrKTsKPiArCXJlZ21hcF9jbGVhcl9iaXRzKGJjLT5y ZWdtYXAsIEJMS19DTEtfRU4sIGRhdGEtPmNsa19tYXNrKTsKPiArCj4gKwkvKiBwb3dlciBkb3du IHVwc3RyZWFtIEdQQyBkb21haW4gKi8KPiArCXBtX3J1bnRpbWVfcHV0KGRvbWFpbi0+cG93ZXJf ZGV2KTsKPiArCj4gKwkvKiBhbGxvdyBidXMgZG9tYWluIHRvIHN1c3BlbmQgKi8KPiArCXBtX3J1 bnRpbWVfcHV0KGJjLT5idXNfcG93ZXJfZGV2KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiArc3RhdGljIHN0cnVjdCBnZW5lcmljX3BtX2RvbWFpbiAqCj4gK2lteDhtX2Jsa19jdHJsX3hs YXRlKHN0cnVjdCBvZl9waGFuZGxlX2FyZ3MgKmFyZ3MsIHZvaWQgKmRhdGEpCj4gK3sKPiArCXN0 cnVjdCBnZW5wZF9vbmVjZWxsX2RhdGEgKm9uZWNlbGxfZGF0YSA9IGRhdGE7Cj4gKwl1bnNpZ25l ZCBpbnQgaW5kZXggPSBhcmdzLT5hcmdzWzBdOwo+ICsKPiArCWlmIChhcmdzLT5hcmdzX2NvdW50 ICE9IDEgfHwKPiArCSAgICBpbmRleCA+IG9uZWNlbGxfZGF0YS0+bnVtX2RvbWFpbnMpCj4gKwkJ cmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gKwo+ICsJcmV0dXJuIG9uZWNlbGxfZGF0YS0+ZG9t YWluc1tpbmRleF07Cj4gK30KPiArCj4gK3N0YXRpYyBzdHJ1Y3QgbG9ja19jbGFzc19rZXkgYmxr X2N0cmxfZ2VucGRfbG9ja19jbGFzczsKPiArCj4gK3N0YXRpYyBpbnQgaW14OG1fYmxrX2N0cmxf cHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJY29uc3Qgc3RydWN0 IGlteDhtX2Jsa19jdHJsX2RhdGEgKmJjX2RhdGE7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAm cGRldi0+ZGV2Owo+ICsJc3RydWN0IGlteDhtX2Jsa19jdHJsICpiYzsKPiArCXZvaWQgX19pb21l bSAqYmFzZTsKPiArCWludCBpLCByZXQ7Cj4gKwo+ICsJc3RydWN0IHJlZ21hcF9jb25maWcgcmVn bWFwX2NvbmZpZyA9IHsKPiArCQkucmVnX2JpdHMJPSAzMiwKPiArCQkudmFsX2JpdHMJPSAzMiwK PiArCQkucmVnX3N0cmlkZQk9IDQsCj4gKwl9Owo+ICsKPiArCWJjID0gZGV2bV9remFsbG9jKGRl diwgc2l6ZW9mKCpiYyksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFiYykKPiArCQlyZXR1cm4gLUVO T01FTTsKPiArCj4gKwliYy0+ZGV2ID0gZGV2Owo+ICsKPiArCWJjX2RhdGEgPSBvZl9kZXZpY2Vf Z2V0X21hdGNoX2RhdGEoZGV2KTsKPiArCj4gKwliYXNlID0gZGV2bV9wbGF0Zm9ybV9pb3JlbWFw X3Jlc291cmNlKHBkZXYsIDApOwo+ICsJaWYgKElTX0VSUihiYXNlKSkKPiArCQlyZXR1cm4gUFRS X0VSUihiYXNlKTsKPiArCj4gKwlyZWdtYXBfY29uZmlnLm1heF9yZWdpc3RlciA9IGJjX2RhdGEt Pm1heF9yZWc7Cj4gKwliYy0+cmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9tbWlvKGRldiwgYmFz ZSwgJnJlZ21hcF9jb25maWcpOwo+ICsJaWYgKElTX0VSUihiYy0+cmVnbWFwKSkKPiArCQlyZXR1 cm4gZGV2X2Vycl9wcm9iZShkZXYsIFBUUl9FUlIoYmMtPnJlZ21hcCksCj4gKwkJCQkgICAgICJm YWlsZWQgdG8gaW5pdCByZWdtYXBcbiIpOwo+ICsKPiArCWJjLT5kb21haW5zID0gZGV2bV9rY2Fs bG9jKGRldiwgYmNfZGF0YS0+bnVtX2RvbWFpbnMsCj4gKwkJCQkgICBzaXplb2Yoc3RydWN0IGlt eDhtX2Jsa19jdHJsX2RvbWFpbiksCj4gKwkJCQkgICBHRlBfS0VSTkVMKTsKPiArCWlmICghYmMt PmRvbWFpbnMpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJYmMtPm9uZWNlbGxfZGF0YS5u dW1fZG9tYWlucyA9IGJjX2RhdGEtPm51bV9kb21haW5zOwo+ICsJYmMtPm9uZWNlbGxfZGF0YS54 bGF0ZSA9IGlteDhtX2Jsa19jdHJsX3hsYXRlOwo+ICsJYmMtPm9uZWNlbGxfZGF0YS5kb21haW5z ID0KPiArCQlkZXZtX2tjYWxsb2MoZGV2LCBiY19kYXRhLT5udW1fZG9tYWlucywKPiArCQkJICAg ICBzaXplb2Yoc3RydWN0IGdlbmVyaWNfcG1fZG9tYWluICopLCBHRlBfS0VSTkVMKTsKPiArCWlm ICghYmMtPm9uZWNlbGxfZGF0YS5kb21haW5zKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiAr CWJjLT5idXNfcG93ZXJfZGV2ID0gZ2VucGRfZGV2X3BtX2F0dGFjaF9ieV9uYW1lKGRldiwgImJ1 cyIpOwo+ICsJaWYgKElTX0VSUihiYy0+YnVzX3Bvd2VyX2RldikpCj4gKwkJcmV0dXJuIGRldl9l cnJfcHJvYmUoZGV2LCBQVFJfRVJSKGJjLT5idXNfcG93ZXJfZGV2KSwKPiArCQkJCSAgICAgImZh aWxlZCB0byBhdHRhY2ggcG93ZXIgZG9tYWluXG4iKTsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwg YmNfZGF0YS0+bnVtX2RvbWFpbnM7IGkrKykgewo+ICsJCWNvbnN0IHN0cnVjdCBpbXg4bV9ibGtf Y3RybF9kb21haW5fZGF0YSAqZGF0YSA9ICZiY19kYXRhLT5kb21haW5zW2ldOwo+ICsJCXN0cnVj dCBpbXg4bV9ibGtfY3RybF9kb21haW4gKmRvbWFpbiA9ICZiYy0+ZG9tYWluc1tpXTsKPiArCQlp bnQgajsKPiArCj4gKwkJZG9tYWluLT5kYXRhID0gZGF0YTsKPiArCj4gKwkJZm9yIChqID0gMDsg aiA8IGRhdGEtPm51bV9jbGtzOyBqKyspCj4gKwkJCWRvbWFpbi0+Y2xrc1tqXS5pZCA9IGRhdGEt PmNsa19uYW1lc1tqXTsKPiArCj4gKwkJcmV0ID0gZGV2bV9jbGtfYnVsa19nZXQoZGV2LCBkYXRh LT5udW1fY2xrcywgZG9tYWluLT5jbGtzKTsKPiArCQlpZiAocmV0KSB7Cj4gKwkJCWRldl9lcnJf cHJvYmUoZGV2LCByZXQsICJmYWlsZWQgdG8gZ2V0IGNsb2NrXG4iKTsKPiArCQkJZ290byBjbGVh bnVwX3BkczsKPiArCQl9Cj4gKwo+ICsJCWRvbWFpbi0+cG93ZXJfZGV2ID0KPiArCQkJZGV2X3Bt X2RvbWFpbl9hdHRhY2hfYnlfbmFtZShkZXYsIGRhdGEtPmdwY19uYW1lKTsKPiArCQlpZiAoSVNf RVJSKGRvbWFpbi0+cG93ZXJfZGV2KSkgewo+ICsJCQlkZXZfZXJyX3Byb2JlKGRldiwgUFRSX0VS Uihkb21haW4tPnBvd2VyX2RldiksCj4gKwkJCQkgICAgICAiZmFpbGVkIHRvIGF0dGFjaCBwb3dl ciBkb21haW5cbiIpOwo+ICsJCQlyZXQgPSBQVFJfRVJSKGRvbWFpbi0+cG93ZXJfZGV2KTsKPiAr CQkJZ290byBjbGVhbnVwX3BkczsKPiArCQl9Cj4gKwo+ICsJCWRvbWFpbi0+Z2VucGQubmFtZSA9 IGRhdGEtPm5hbWU7Cj4gKwkJZG9tYWluLT5nZW5wZC5wb3dlcl9vbiA9IGlteDhtX2Jsa19jdHJs X3Bvd2VyX29uOwo+ICsJCWRvbWFpbi0+Z2VucGQucG93ZXJfb2ZmID0gaW14OG1fYmxrX2N0cmxf cG93ZXJfb2ZmOwo+ICsJCWRvbWFpbi0+YmMgPSBiYzsKPiArCj4gKwkJcmV0ID0gcG1fZ2VucGRf aW5pdCgmZG9tYWluLT5nZW5wZCwgTlVMTCwgdHJ1ZSk7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQlk ZXZfZXJyX3Byb2JlKGRldiwgcmV0LCAiZmFpbGVkIHRvIGluaXQgcG93ZXIgZG9tYWluXG4iKTsK PiArCQkJZGV2X3BtX2RvbWFpbl9kZXRhY2goZG9tYWluLT5wb3dlcl9kZXYsIHRydWUpOwo+ICsJ CQlnb3RvIGNsZWFudXBfcGRzOwo+ICsJCX0KPiArCj4gKwkJLyoKPiArCQkgKiBXZSB1c2UgcnVu dGltZSBQTSB0byB0cmlnZ2VyIHBvd2VyIG9uL29mZiBvZiB0aGUgdXBzdHJlYW0gR1BDCj4gKwkJ ICogZG9tYWluLCBhcyBhIHN0cmljdCBoaWVyYXJjaGljYWwgcGFyZW50L2NoaWxkIHBvd2VyIGRv bWFpbgo+ICsJCSAqIHNldHVwIGRvZXNuJ3QgYWxsb3cgdXMgdG8gbWVldCB0aGUgc2VxdWVuY2lu ZyByZXF1aXJlbWVudHMuCj4gKwkJICogVGhpcyBtZWFucyB3ZSBoYXZlIG5lc3RlZCBsb2NraW5n IG9mIGdlbnBkIGxvY2tzLCB3aXRob3V0IHRoZQo+ICsJCSAqIG5lc3RpbmcgYmVpbmcgdmlzaWJs ZSBhdCB0aGUgZ2VucGQgbGV2ZWwsIHNvIHdlIG5lZWQgYQo+ICsJCSAqIHNlcGFyYXRlIGxvY2sg Y2xhc3MgdG8gbWFrZSBsb2NrZGVwIGF3YXJlIG9mIHRoZSBmYWN0IHRoYXQKPiArCQkgKiB0aGlz IGFyZSBzZXBhcmF0ZSBkb21haW4gbG9ja3MgdGhhdCBjYW4gYmUgbmVzdGVkIHdpdGhvdXQgYQo+ ICsJCSAqIHNlbGYtZGVhZGxvY2suCj4gKwkJICovCj4gKwkJbG9ja2RlcF9zZXRfY2xhc3MoJmRv bWFpbi0+Z2VucGQubWxvY2ssCj4gKwkJCQkgICZibGtfY3RybF9nZW5wZF9sb2NrX2NsYXNzKTsK PiArCj4gKwkJYmMtPm9uZWNlbGxfZGF0YS5kb21haW5zW2ldID0gJmRvbWFpbi0+Z2VucGQ7Cj4g Kwl9Cj4gKwo+ICsJcmV0ID0gb2ZfZ2VucGRfYWRkX3Byb3ZpZGVyX29uZWNlbGwoZGV2LT5vZl9u b2RlLCAmYmMtPm9uZWNlbGxfZGF0YSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X2Vycl9wcm9i ZShkZXYsIHJldCwgImZhaWxlZCB0byBhZGQgcG93ZXIgZG9tYWluIHByb3ZpZGVyXG4iKTsKPiAr CQlnb3RvIGNsZWFudXBfcGRzOwo+ICsJfQo+ICsKPiArCWJjLT5wb3dlcl9uYi5ub3RpZmllcl9j YWxsID0gYmNfZGF0YS0+cG93ZXJfbm90aWZpZXJfZm47Cj4gKwlyZXQgPSBkZXZfcG1fZ2VucGRf YWRkX25vdGlmaWVyKGJjLT5idXNfcG93ZXJfZGV2LCAmYmMtPnBvd2VyX25iKTsKPiArCWlmIChy ZXQpIHsKPiArCQlkZXZfZXJyX3Byb2JlKGRldiwgcmV0LCAiZmFpbGVkIHRvIGFkZCBwb3dlciBu b3RpZmllclxuIik7Cj4gKwkJZ290byBjbGVhbnVwX3Byb3ZpZGVyOwo+ICsJfQo+ICsKPiArCWRl dl9zZXRfZHJ2ZGF0YShkZXYsIGJjKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArCj4gK2NsZWFudXBf cHJvdmlkZXI6Cj4gKwlvZl9nZW5wZF9kZWxfcHJvdmlkZXIoZGV2LT5vZl9ub2RlKTsKPiArY2xl YW51cF9wZHM6Cj4gKwlmb3IgKGktLTsgaSA+PSAwOyBpLS0pIHsKPiArCQlwbV9nZW5wZF9yZW1v dmUoJmJjLT5kb21haW5zW2ldLmdlbnBkKTsKPiArCQlkZXZfcG1fZG9tYWluX2RldGFjaChiYy0+ ZG9tYWluc1tpXS5wb3dlcl9kZXYsIHRydWUpOwo+ICsJfQo+ICsKPiArCWRldl9wbV9kb21haW5f ZGV0YWNoKGJjLT5idXNfcG93ZXJfZGV2LCB0cnVlKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9 Cj4gKwo+ICtzdGF0aWMgaW50IGlteDhtX2Jsa19jdHJsX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1f ZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgaW14OG1fYmxrX2N0cmwgKmJjID0gZGV2X2dl dF9kcnZkYXRhKCZwZGV2LT5kZXYpOwo+ICsJaW50IGk7Cj4gKwo+ICsJb2ZfZ2VucGRfZGVsX3By b3ZpZGVyKHBkZXYtPmRldi5vZl9ub2RlKTsKPiArCj4gKwlmb3IgKGkgPSAwOyBiYy0+b25lY2Vs bF9kYXRhLm51bV9kb21haW5zOyBpKyspIHsKPiArCQlzdHJ1Y3QgaW14OG1fYmxrX2N0cmxfZG9t YWluICpkb21haW4gPSAmYmMtPmRvbWFpbnNbaV07Cj4gKwo+ICsJCXBtX2dlbnBkX3JlbW92ZSgm ZG9tYWluLT5nZW5wZCk7Cj4gKwkJZGV2X3BtX2RvbWFpbl9kZXRhY2goZG9tYWluLT5wb3dlcl9k ZXYsIHRydWUpOwo+ICsJfQo+ICsKPiArCWRldl9wbV9nZW5wZF9yZW1vdmVfbm90aWZpZXIoYmMt PmJ1c19wb3dlcl9kZXYpOwo+ICsKPiArCWRldl9wbV9kb21haW5fZGV0YWNoKGJjLT5idXNfcG93 ZXJfZGV2LCB0cnVlKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArI2lmZGVmIENPTkZJ R19QTV9TTEVFUAo+ICtzdGF0aWMgaW50IGlteDhtX2Jsa19jdHJsX3N1c3BlbmQoc3RydWN0IGRl dmljZSAqZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgaW14OG1fYmxrX2N0cmwgKmJjID0gZGV2X2dldF9k cnZkYXRhKGRldik7Cj4gKwlpbnQgcmV0LCBpOwo+ICsKPiArCS8qCj4gKwkgKiBUaGlzIG1heSBs b29rIHN0cmFuZ2UsIGJ1dCBpcyBkb25lIHNvIHRoZSBnZW5lcmljIFBNX1NMRUVQIGNvZGUKPiAr CSAqIGNhbiBwb3dlciBkb3duIG91ciBkb21haW5zIGFuZCBtb3JlIGltcG9ydGFudGx5IHBvd2Vy IHRoZW0gdXAgYWdhaW4KPiArCSAqIGFmdGVyIHJlc3VtZSwgd2l0aG91dCB0cmlwcGluZyBvdmVy IG91ciB1c2FnZSBvZiBydW50aW1lIFBNIHRvCj4gKwkgKiBjb250cm9sIHRoZSB1cHN0cmVhbSBH UEMgZG9tYWlucy4gVGhpbmdzIGhhcHBlbiBpbiB0aGUgcmlnaHQgb3JkZXIKPiArCSAqIGluIHRo ZSBzeXN0ZW0gc3VzcGVuZC9yZXN1bWUgcGF0aHMgZHVlIHRvIHRoZSBkZXZpY2UgcGFyZW50L2No aWxkCj4gKwkgKiBoaWVyYXJjaHkuCj4gKwkgKi8KPiArCXJldCA9IHBtX3J1bnRpbWVfZ2V0X3N5 bmMoYmMtPmJ1c19wb3dlcl9kZXYpOwo+ICsJaWYgKHJldCA8IDApIHsKPiArCQlwbV9ydW50aW1l X3B1dF9ub2lkbGUoYmMtPmJ1c19wb3dlcl9kZXYpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4g Kwo+ICsJZm9yIChpID0gMDsgaSA8IGJjLT5vbmVjZWxsX2RhdGEubnVtX2RvbWFpbnM7IGkrKykg ewo+ICsJCXN0cnVjdCBpbXg4bV9ibGtfY3RybF9kb21haW4gKmRvbWFpbiA9ICZiYy0+ZG9tYWlu c1tpXTsKPiArCj4gKwkJcmV0ID0gcG1fcnVudGltZV9nZXRfc3luYyhkb21haW4tPnBvd2VyX2Rl dik7Cj4gKwkJaWYgKHJldCA8IDApIHsKPiArCQkJcG1fcnVudGltZV9wdXRfbm9pZGxlKGRvbWFp bi0+cG93ZXJfZGV2KTsKPiArCQkJZ290byBvdXRfZmFpbDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJ cmV0dXJuIDA7Cj4gKwo+ICtvdXRfZmFpbDoKPiArCWZvciAoaS0tOyBpID49IDA7IGktLSkKPiAr CQlwbV9ydW50aW1lX3B1dChiYy0+ZG9tYWluc1tpXS5wb3dlcl9kZXYpOwo+ICsKPiArCXBtX3J1 bnRpbWVfcHV0KGJjLT5idXNfcG93ZXJfZGV2KTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4g Kwo+ICtzdGF0aWMgaW50IGlteDhtX2Jsa19jdHJsX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYp Cj4gK3sKPiArCXN0cnVjdCBpbXg4bV9ibGtfY3RybCAqYmMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2 KTsKPiArCWludCBpOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBiYy0+b25lY2VsbF9kYXRhLm51 bV9kb21haW5zOyBpKyspCj4gKwkJcG1fcnVudGltZV9wdXQoYmMtPmRvbWFpbnNbaV0ucG93ZXJf ZGV2KTsKPiArCj4gKwlwbV9ydW50aW1lX3B1dChiYy0+YnVzX3Bvd2VyX2Rldik7Cj4gKwo+ICsJ cmV0dXJuIDA7Cj4gK30KPiArI2VuZGlmCj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGRldl9w bV9vcHMgaW14OG1fYmxrX2N0cmxfcG1fb3BzID0gewo+ICsJU0VUX1NZU1RFTV9TTEVFUF9QTV9P UFMoaW14OG1fYmxrX2N0cmxfc3VzcGVuZCwgaW14OG1fYmxrX2N0cmxfcmVzdW1lKQo+ICt9Owo+ ICsKPiArc3RhdGljIGludCBpbXg4bW1fdnB1X3Bvd2VyX25vdGlmaWVyKHN0cnVjdCBub3RpZmll cl9ibG9jayAqbmIsCj4gKwkJCQkgICAgIHVuc2lnbmVkIGxvbmcgYWN0aW9uLCB2b2lkICpkYXRh KQo+ICt7Cj4gKwlzdHJ1Y3QgaW14OG1fYmxrX2N0cmwgKmJjID0gY29udGFpbmVyX29mKG5iLCBz dHJ1Y3QgaW14OG1fYmxrX2N0cmwsCj4gKwkJCQkJCSBwb3dlcl9uYik7Cj4gKwo+ICsJaWYgKGFj dGlvbiAhPSBHRU5QRF9OT1RJRllfT04gJiYgYWN0aW9uICE9IEdFTlBEX05PVElGWV9QUkVfT0ZG KQo+ICsJCXJldHVybiBOT1RJRllfT0s7Cj4gKwo+ICsJLyoKPiArCSAqIFRoZSBBREIgaW4gdGhl IFZQVU1JWCBkb21haW4gaGFzIG5vIHNlcGFyYXRlIHJlc2V0IGFuZCBjbG9jawo+ICsJICogZW5h YmxlIGJpdHMsIGJ1dCBpcyB1bmdhdGVkIHRvZ2V0aGVyIHdpdGggdGhlIFZQVSBjbG9ja3MuIFRv Cj4gKwkgKiBhbGxvdyB0aGUgaGFuZHNoYWtlIHdpdGggdGhlIEdQQyB0byBwcm9ncmVzcyB3ZSBw dXQgdGhlIFZQVXMKPiArCSAqIGluIHJlc2V0IGFuZCB1bmdhdGUgdGhlIGNsb2Nrcy4KPiArCSAq Lwo+ICsJcmVnbWFwX2NsZWFyX2JpdHMoYmMtPnJlZ21hcCwgQkxLX1NGVF9SU1ROLCBCSVQoMCkg fCBCSVQoMSkgfCBCSVQoMikpOwo+ICsJcmVnbWFwX3NldF9iaXRzKGJjLT5yZWdtYXAsIEJMS19D TEtfRU4sIEJJVCgwKSB8IEJJVCgxKSB8IEJJVCgyKSk7Cj4gKwo+ICsJaWYgKGFjdGlvbiA9PSBH RU5QRF9OT1RJRllfT04pIHsKPiArCQkvKgo+ICsJCSAqIE9uIHBvd2VyIHVwIHdlIGhhdmUgbm8g c29mdHdhcmUgYmFja2NoYW5uZWwgdG8gdGhlIEdQQyB0bwo+ICsJCSAqIHdhaXQgZm9yIHRoZSBB REIgaGFuZHNoYWtlIHRvIGhhcHBlbiwgc28gd2UganVzdCBkZWxheSBmb3IgYQo+ICsJCSAqIGJp dC4gT24gcG93ZXIgZG93biB0aGUgR1BDIGRyaXZlciB3YWl0cyBmb3IgdGhlIGhhbmRzaGFrZS4K PiArCQkgKi8KPiArCQl1ZGVsYXkoNSk7Cj4gKwo+ICsJCS8qIHNldCAiZnVzZSIgYml0cyB0byBl bmFibGUgdGhlIFZQVXMgKi8KPiArCQlyZWdtYXBfc2V0X2JpdHMoYmMtPnJlZ21hcCwgMHg4LCAw eGZmZmZmZmZmKTsKPiArCQlyZWdtYXBfc2V0X2JpdHMoYmMtPnJlZ21hcCwgMHhjLCAweGZmZmZm ZmZmKTsKPiArCQlyZWdtYXBfc2V0X2JpdHMoYmMtPnJlZ21hcCwgMHgxMCwgMHhmZmZmZmZmZik7 Cj4gKwkJcmVnbWFwX3NldF9iaXRzKGJjLT5yZWdtYXAsIDB4MTQsIDB4ZmZmZmZmZmYpOwo+ICsJ fQo+ICsKPiArCXJldHVybiBOT1RJRllfT0s7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1 Y3QgaW14OG1fYmxrX2N0cmxfZG9tYWluX2RhdGEgaW14OG1fdnB1X2Jsa19jdGxfZG9tYWluX2Rh dGFbXSA9IHsKPiArCVtJTVg4TU1fVlBVQkxLX1BEX0cxXSA9IHsKPiArCQkubmFtZSA9ICJ2cHVi bGstZzEiLAo+ICsJCS5jbGtfbmFtZXMgPSAoY29uc3QgY2hhciAqW10peyAiZzEiLCB9LAo+ICsJ CS5udW1fY2xrcyA9IDEsCj4gKwkJLmdwY19uYW1lID0gImcxIiwKPiArCQkucnN0X21hc2sgPSBC SVQoMSksCj4gKwkJLmNsa19tYXNrID0gQklUKDEpLAo+ICsJfSwKPiArCVtJTVg4TU1fVlBVQkxL X1BEX0cyXSA9IHsKPiArCQkubmFtZSA9ICJ2cHVibGstZzIiLAo+ICsJCS5jbGtfbmFtZXMgPSAo Y29uc3QgY2hhciAqW10peyAiZzIiLCB9LAo+ICsJCS5udW1fY2xrcyA9IDEsCj4gKwkJLmdwY19u YW1lID0gImcyIiwKPiArCQkucnN0X21hc2sgPSBCSVQoMCksCj4gKwkJLmNsa19tYXNrID0gQklU KDApLAo+ICsJfSwKPiArCVtJTVg4TU1fVlBVQkxLX1BEX0gxXSA9IHsKPiArCQkubmFtZSA9ICJ2 cHVibGstaDEiLAo+ICsJCS5jbGtfbmFtZXMgPSAoY29uc3QgY2hhciAqW10peyAiaDEiLCB9LAo+ ICsJCS5udW1fY2xrcyA9IDEsCj4gKwkJLmdwY19uYW1lID0gImgxIiwKPiArCQkucnN0X21hc2sg PSBCSVQoMiksCj4gKwkJLmNsa19tYXNrID0gQklUKDIpLAo+ICsJfSwKPiArfTsKPiArCj4gK3N0 YXRpYyBjb25zdCBzdHJ1Y3QgaW14OG1fYmxrX2N0cmxfZGF0YSBpbXg4bV92cHVfYmxrX2N0bF9k ZXZfZGF0YSA9IHsKPiArCS5tYXhfcmVnID0gMHgxOCwKPiArCS5wb3dlcl9ub3RpZmllcl9mbiA9 IGlteDhtbV92cHVfcG93ZXJfbm90aWZpZXIsCj4gKwkuZG9tYWlucyA9IGlteDhtX3ZwdV9ibGtf Y3RsX2RvbWFpbl9kYXRhLAo+ICsJLm51bV9kb21haW5zID0gQVJSQVlfU0laRShpbXg4bV92cHVf YmxrX2N0bF9kb21haW5fZGF0YSksCj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9m X2RldmljZV9pZCBpbXg4bV9ibGtfY3RybF9vZl9tYXRjaFtdID0gewo+ICsJewo+ICsJCS5jb21w YXRpYmxlID0gImZzbCxpbXg4bW0tdnB1LWJsay1jdHJsIiwKPiArCQkuZGF0YSA9ICZpbXg4bV92 cHVfYmxrX2N0bF9kZXZfZGF0YQo+ICsJfSwgewo+ICsJCS8qIFNlbnRpbmVsICovCj4gKwl9Cj4g K307Cj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGlteDhtX2Jsa19jdHJsX29mX21hdGNoKTsK PiArCj4gK3N0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGlteDhtX2Jsa19jdHJsX2RyaXZl ciA9IHsKPiArCS5wcm9iZSA9IGlteDhtX2Jsa19jdHJsX3Byb2JlLAo+ICsJLnJlbW92ZSA9IGlt eDhtX2Jsa19jdHJsX3JlbW92ZSwKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAiaW14OG0t YmxrLWN0cmwiLAo+ICsJCS5wbSA9ICZpbXg4bV9ibGtfY3RybF9wbV9vcHMsCj4gKwkJLm9mX21h dGNoX3RhYmxlID0gaW14OG1fYmxrX2N0cmxfb2ZfbWF0Y2gsCj4gKwl9LAo+ICt9Owo+ICttb2R1 bGVfcGxhdGZvcm1fZHJpdmVyKGlteDhtX2Jsa19jdHJsX2RyaXZlcik7CgpfX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxp bmcgbGlzdApsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3Rz LmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==