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=-8.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE, SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43E5DC12002 for ; Fri, 16 Jul 2021 05:51:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A700613DF for ; Fri, 16 Jul 2021 05:51:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234591AbhGPFyV convert rfc822-to-8bit (ORCPT ); Fri, 16 Jul 2021 01:54:21 -0400 Received: from guitar.tcltek.co.il ([192.115.133.116]:54848 "EHLO mx.tkos.co.il" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234484AbhGPFyT (ORCPT ); Fri, 16 Jul 2021 01:54:19 -0400 Received: from tarshish (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx.tkos.co.il (Postfix) with ESMTPS id AF55144011A; Fri, 16 Jul 2021 08:51:15 +0300 (IDT) References: <1173e7b0b58730fd187871d9e14a02cab85158cc.1626176145.git.baruch@tkos.co.il> <20210714201839.kfyqcyvowekc4ejs@pengutronix.de> User-agent: mu4e 1.4.15; emacs 27.1 From: Baruch Siach To: Uwe =?utf-8?Q?Kleine-K=C3=B6nig?= Cc: Thierry Reding , Lee Jones , Andy Gross , Bjorn Andersson , Balaji Prakash J , Rob Herring , Robert Marko , Kathiravan T , linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Subject: Re: [PATCH v5 2/4] pwm: driver for qualcomm ipq6018 pwm block In-reply-to: <20210714201839.kfyqcyvowekc4ejs@pengutronix.de> Date: Fri, 16 Jul 2021 08:51:20 +0300 Message-ID: <87eebyst5z.fsf@tarshish> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Hi Uwe, Thanks again for your detailed review. I have a few comments and questions below. On Wed, Jul 14 2021, Uwe Kleine-König wrote: > On Tue, Jul 13, 2021 at 02:35:43PM +0300, Baruch Siach wrote: >> --- /dev/null >> +++ b/drivers/pwm/pwm-ipq.c >> @@ -0,0 +1,278 @@ >> +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 >> +/* >> + * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define IPQ_PWM_MAX_DEVICES 4 > > This is only used once. Just doing > > pwm->chip.npwm = 4; > > is better in my book. Does "MAX" suggest that there are variants with > less PWMs? I have no idea. I guess not. I'll drop this macro in v6. > >> +/* The frequency range supported is 1Hz to 100MHz */ > > A space between number and unit is usual and makes this better readable. Quick 'git grep' indicates that '[[:digit:]]\+MHz' is a little more popular than '[[:digit:]]\+ MHz' in kernel code. But OK, not a big deal. >> +#define IPQ_PWM_CLK_SRC_FREQ (100*1000*1000) >> +#define IPQ_PWM_MIN_PERIOD_NS (NSEC_PER_SEC / IPQ_PWM_CLK_SRC_FREQ) > > You're assuming here that the parent clock runs at exactly the set rate. > Is this a sensible assumption? If this division didn't have an integer > result there would be rounding issues. The code only uses this for period validity check. It saves us some code for run-time division. >> +#define IPQ_PWM_MAX_PERIOD_NS ((u64)NSEC_PER_SEC) >> + >> +/* >> + * The max value specified for each field is based on the number of bits >> + * in the pwm control register for that field >> + */ >> +#define IPQ_PWM_MAX_DIV 0xFFFF >> + >> +#define IPQ_PWM_CFG_REG0 0 /*PWM_DIV PWM_HI*/ >> +#define IPQ_PWM_REG0_PWM_DIV GENMASK(15, 0) >> +#define IPQ_PWM_REG0_HI_DURATION GENMASK(31, 16) >> + >> +#define IPQ_PWM_CFG_REG1 1 /*ENABLE UPDATE PWM_PRE_DIV*/ >> +#define IPQ_PWM_REG1_PRE_DIV GENMASK(15, 0) >> +/* >> + * Enable bit is set to enable output toggling in pwm device. >> + * Update bit is set to reflect the changed divider and high duration >> + * values in register. >> + */ >> +#define IPQ_PWM_REG1_UPDATE BIT(30) >> +#define IPQ_PWM_REG1_ENABLE BIT(31) >> + >> + >> +struct ipq_pwm_chip { >> + struct pwm_chip chip; >> + struct clk *clk; >> + struct regmap *regmap; >> + u32 regmap_off; >> +}; >> + >> +static struct ipq_pwm_chip *to_ipq_pwm_chip(struct pwm_chip *chip) >> +{ >> + return container_of(chip, struct ipq_pwm_chip, chip); >> +} >> + >> +static unsigned ipq_pwm_reg_offset(struct pwm_device *pwm, unsigned reg) >> +{ >> + return ((pwm->hwpwm * 2) + reg) * 4; >> +} >> + >> +static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned reg) >> +{ >> + struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip); >> + unsigned int off = ipq_chip->regmap_off + ipq_pwm_reg_offset(pwm, reg); > > I already stumbled about this in v4 but thought I'd let you do it. As > I stumbled again I'll say something now: > > I would do the register stuff as follows: > > /* Each PWM has two registers, the offset for PWM #i is at 8 * #i */ > #define IPQ_PWM_CFG_REG0 0 > #define IPQ_PWM_CFG_REG1 4 > > and then do: > > static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned reg) > { > struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip); > unsigned int off = ipq_chip->regmap_off + 8 * pwm->hwpwm + reg; > > ... > > this is a bit easier to understand IMHO, but might be subjective. I let > you decide if you want to change that or stay with your approach. > >> + unsigned int val; >> + >> + regmap_read(ipq_chip->regmap, off, &val); >> + >> + return val; >> +} >> + >> +static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned reg, >> + unsigned val) >> +{ >> + struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(pwm->chip); >> + unsigned int off = ipq_chip->regmap_off + ipq_pwm_reg_offset(pwm, reg); >> + >> + regmap_write(ipq_chip->regmap, off, val); >> +} >> + >> +static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div, >> + unsigned int pwm_div, u64 period_ns, u64 duty_ns, >> + bool enable) >> +{ >> + unsigned long hi_dur; >> + unsigned long long quotient; >> + unsigned long val = 0; >> + >> + /* >> + * high duration = pwm duty * (pwm div + 1) >> + * pwm duty = duty_ns / period_ns >> + */ >> + quotient = (pwm_div + 1) * duty_ns; >> + hi_dur = div64_u64(quotient, period_ns); > > this division should use the actual period, not the target period. > Otherwise the result might be to small. > >> + val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) | >> + FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div); >> + ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG0, val); >> + >> + val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div); >> + ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val); >> + >> + /* Enable needs a separate write to REG1 */ >> + val |= IPQ_PWM_REG1_UPDATE; > > Setting this bit results in the two writes above being configured > atomically so that no mixed settings happen to the output, right? I guess so. I have no access to hardware documentation, mind you. I first tried to do only one write to REG1, but it had no effect. The existence of the UPDATE bit also indicates that hardware works as you suggest. > Does the hardware complete the currently running cycle on > reconfiguration? No idea. >> + if (enable) >> + val |= IPQ_PWM_REG1_ENABLE; >> + else >> + val &= ~IPQ_PWM_REG1_ENABLE; > > The else branch has no effect as val is initialized as zero above, so > please drop it. > >> + ipq_pwm_reg_write(pwm, IPQ_PWM_CFG_REG1, val); > > How does the hardware behave with the ENABLE bit unset? Does it drive > the pin to zero? Yes. That's what experimentation here shows. The pin is pulled up, but the PWM keeps it low. >> +} >> + >> +static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, >> + const struct pwm_state *state) >> +{ >> + struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip); >> + unsigned long freq; >> + unsigned int pre_div, pwm_div, close_pre_div, close_pwm_div; >> + long long diff; >> + unsigned long rate = clk_get_rate(ipq_chip->clk); >> + unsigned long min_diff = rate; >> + uint64_t fin_ps; >> + u64 period_ns, duty_ns; > > You have to refuse the request if state->polarity != > PWM_POLARITY_NORMAL. > >> + >> + if (state->period < IPQ_PWM_MIN_PERIOD_NS) > > It's strange that you assume here the hardcoded 100 MHz but below you > use clk_get_rate(ipq_chip->clk). As I said above, this is meant to save code for the less critical case. Should I use clk_get_rate() here as well? If we go with assigned-clock-rates, as you suggest below, we'll have to do that anyway. > >> + return -ERANGE; >> + >> + period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS); >> + duty_ns = min(state->duty_cycle, period_ns); >> + >> + /* freq in Hz for period in nano second */ >> + freq = div64_u64(NSEC_PER_SEC, period_ns); >> + fin_ps = div64_u64(NSEC_PER_SEC * 1000ULL, rate); > > I don't understand that factor 1000. This just cancels with the 1000 in > the calculation of pwm_div below?! Maybe this is to soften the precision > loss? That is my understanding of the code intent. >> + close_pre_div = IPQ_PWM_MAX_DIV; >> + close_pwm_div = IPQ_PWM_MAX_DIV; >> + >> + for (pre_div = 0; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) { >> + pwm_div = DIV64_U64_ROUND_CLOSEST(period_ns * 1000, >> + fin_ps * (pre_div + 1)); > > Having fin_ps in the divisor results in loss of precision. When ever the > closest rounding division rounds down diff becomes negative below. So > you should round up here. > > Also if you do: > > pwm_div = round_up((period_ns * rate) / (NSEC_PER_SEC * (pre_div + 1))) > > there is no relevant loss of precision. (You might have to care for > period_ns * rate overflowing though or argue why it doesn't overflow.) Looks better. > >> + pwm_div--; >> + if (pwm_div > IPQ_PWM_MAX_DIV) >> + continue; > > This check can be dropped if the loop (depending on the other parameters) > does not start with pre_div = 0 but some bigger number. That is, calculate the minimum pre_div value for which the division above always produces pwm_div in range, right? > >> + diff = ((uint64_t)freq * (pre_div + 1) * (pwm_div + 1)) >> + - (uint64_t)rate; >> + >> + if (diff < 0) /* period larger than requested */ >> + continue; >> + if (diff == 0) { /* bingo */ >> + close_pre_div = pre_div; >> + close_pwm_div = pwm_div; >> + break; >> + } >> + if (diff < min_diff) { >> + min_diff = diff; >> + close_pre_div = pre_div; >> + close_pwm_div = pwm_div; > > I would call these best_..._div, not close_..._div which makes the > purpose clearer. > > A big pre_div results in a coarse resolution for duty_cycle. This makes > other similar drivers chose to hardcode pwm_div to its max value. At > least you should ensure that pre_div <= pwm_div. > >> + } >> + } >> + >> + /* config divider values for the closest possible frequency */ >> + config_div_and_duty(pwm, close_pre_div, close_pwm_div, >> + period_ns, duty_ns, state->enabled); >> + >> + return 0; >> +} >> + >> +static void ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, >> + struct pwm_state *state) >> +{ >> + struct ipq_pwm_chip *ipq_chip = to_ipq_pwm_chip(chip); >> + unsigned long rate = clk_get_rate(ipq_chip->clk); >> + unsigned int pre_div, pwm_div, hi_dur; >> + u64 effective_div, hi_div; >> + u32 reg0, reg1; >> + >> + reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG0); >> + reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_CFG_REG1); >> + >> + state->polarity = PWM_POLARITY_NORMAL; >> + state->enabled = reg1 & IPQ_PWM_REG1_ENABLE; >> + >> + pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0); >> + hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0); >> + pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1); >> + effective_div = (pre_div + 1) * (pwm_div + 1); > > Please add a comment here that with pre_div and pwm_div <= 0xffff the > multiplication below doesn't overflow > >> + state->period = div64_u64(effective_div * NSEC_PER_SEC, rate); >> + >> + hi_div = hi_dur * (pre_div + 1); > > This suggests that the hardware cannot do 100% relative duty cycle if > pwm_div == 0xffff? I suggest to clamp pwm_div to 0xfffe then. What is "100% relative duty"? How does pwm_div clamping helps? >> + state->duty_cycle = div64_u64(hi_div * NSEC_PER_SEC, rate); >> +} >> + >> +static struct pwm_ops ipq_pwm_ops = { > > const please > >> + .apply = ipq_pwm_apply, >> + .get_state = ipq_pwm_get_state, >> + .owner = THIS_MODULE, >> +}; >> + >> +static int ipq_pwm_probe(struct platform_device *pdev) >> +{ >> + struct ipq_pwm_chip *pwm; >> + struct device *dev = &pdev->dev; >> + struct of_phandle_args args; >> + int ret; >> + >> + pwm = devm_kzalloc(dev, sizeof(*pwm), GFP_KERNEL); >> + if (!pwm) >> + return -ENOMEM; >> + >> + platform_set_drvdata(pdev, pwm); >> + >> + ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,pwm-regs", >> + 1, 0, &args); >> + if (ret) >> + return dev_err_probe(dev, ret, "regs parse failed"); >> + >> + pwm->regmap = syscon_node_to_regmap(args.np); >> + of_node_put(args.np); >> + if (IS_ERR(pwm->regmap)) >> + return dev_err_probe(dev, PTR_ERR(pwm->regmap), >> + "regs map failed"); >> + pwm->regmap_off = args.args[0]; > > Does this have to be so complicated? Why doesn't the normal approach > with the pwm being a child of the syscon device and reg = <...> work > here? I'll do that in v6. That's what Bjorn originally suggested in response to v2. > >> + pwm->clk = devm_clk_get(dev, "core"); >> + if (IS_ERR(pwm->clk)) >> + return dev_err_probe(dev, PTR_ERR(pwm->clk), >> + "failed to get core clock"); >> + >> + ret = clk_set_rate(pwm->clk, IPQ_PWM_CLK_SRC_FREQ); >> + if (ret) >> + return dev_err_probe(dev, ret, "clock rate set failed"); > > Would it make more sense to set this in the device tree using > assigned-clock-rate? That's 'assigned-clock-rates' I believe. I'll try that. > >> + ret = clk_prepare_enable(pwm->clk); >> + if (ret) >> + return dev_err_probe(dev, ret, "clock enable failed"); >> + >> + pwm->chip.dev = dev; >> + pwm->chip.ops = &ipq_pwm_ops; >> + pwm->chip.npwm = IPQ_PWM_MAX_DEVICES; >> + >> + ret = pwmchip_add(&pwm->chip); >> + if (ret < 0) { >> + dev_err_probe(dev, ret, "pwmchip_add() failed\n"); >> + clk_disable_unprepare(pwm->clk); >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> +static int ipq_pwm_remove(struct platform_device *pdev) >> +{ >> + struct ipq_pwm_chip *pwm = platform_get_drvdata(pdev); >> + >> + clk_disable_unprepare(pwm->clk); >> + pwmchip_remove(&pwm->chip); > > This is the wrong order. Until pwmchip_remove() returns the PWM must stay > functional, so disable the clock only after pwmchip_remove(). > >> + >> + return 0; >> +} >> + >> +static const struct of_device_id pwm_ipq_dt_match[] = { >> + { .compatible = "qcom,ipq6018-pwm", }, >> + {} >> +}; >> +MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match); >> + >> +static struct platform_driver ipq_pwm_driver = { >> + .driver = { >> + .name = "ipq-pwm", >> + .of_match_table = pwm_ipq_dt_match, >> + }, >> + .probe = ipq_pwm_probe, >> + .remove = ipq_pwm_remove, >> +}; >> + >> +module_platform_driver(ipq_pwm_driver); >> + >> +MODULE_LICENSE("Dual BSD/GPL"); > > Best regards > Uwe -- ~. .~ Tk Open Systems =}------------------------------------------------ooO--U--Ooo------------{= - baruch@tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il - 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=-9.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 812C9C07E95 for ; Fri, 16 Jul 2021 05:53:40 +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 3F910613E9 for ; Fri, 16 Jul 2021 05:53:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3F910613E9 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=tkos.co.il Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date: In-reply-to:Subject:Cc:To:From:References:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=w9sx+Qcq0vXtah9nZpqyk0tOFkGamcDSLRhuLufCJ0w=; b=UKFjHMrxefvX/kW0Pvo1xMXnn9 bHfmovaPgql5+suSczbVAcmERigvGY9qiqZ50jB7qCffVnOul7yoBmMTWb0PmeLqHEco87pyHxHHw cg5RVDb8wAQx7JaPLPHq/I+F/5TDLz8wm3IU5kAlneIaD5Pv1sL8CvkK1fmkJCe2bAvA8iUm9R+NF dSpEtgov9q1oz3fqzPsQ1P9aSJtjLl+cyViRfnP/NRIkgyrLftpckfjiEG1zGWcMTfFr+ko1X3Wmx B1IK9L4SIbPyMBa1ku+j+Fo6VZ+AHeuOjMVnGxnNS7gBQF2DG3Gny3zorUPsbxTjBKGNu7PhWU0Di XSWWJGhA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1m4Gl4-003Hdh-Mm; Fri, 16 Jul 2021 05:51:34 +0000 Received: from guitar.tcltek.co.il ([192.115.133.116] helo=mx.tkos.co.il) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1m4Gky-003Hbz-K4 for linux-arm-kernel@lists.infradead.org; Fri, 16 Jul 2021 05:51:31 +0000 Received: from tarshish (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx.tkos.co.il (Postfix) with ESMTPS id AF55144011A; Fri, 16 Jul 2021 08:51:15 +0300 (IDT) References: <1173e7b0b58730fd187871d9e14a02cab85158cc.1626176145.git.baruch@tkos.co.il> <20210714201839.kfyqcyvowekc4ejs@pengutronix.de> User-agent: mu4e 1.4.15; emacs 27.1 From: Baruch Siach To: Uwe =?utf-8?Q?Kleine-K=C3=B6nig?= Cc: Thierry Reding , Lee Jones , Andy Gross , Bjorn Andersson , Balaji Prakash J , Rob Herring , Robert Marko , Kathiravan T , linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de Subject: Re: [PATCH v5 2/4] pwm: driver for qualcomm ipq6018 pwm block In-reply-to: <20210714201839.kfyqcyvowekc4ejs@pengutronix.de> Date: Fri, 16 Jul 2021 08:51:20 +0300 Message-ID: <87eebyst5z.fsf@tarshish> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210715_225129_209704_D1AFB990 X-CRM114-Status: GOOD ( 57.00 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgVXdlLAoKVGhhbmtzIGFnYWluIGZvciB5b3VyIGRldGFpbGVkIHJldmlldy4KCkkgaGF2ZSBh IGZldyBjb21tZW50cyBhbmQgcXVlc3Rpb25zIGJlbG93LgoKT24gV2VkLCBKdWwgMTQgMjAyMSwg VXdlIEtsZWluZS1Lw7ZuaWcgd3JvdGU6Cj4gT24gVHVlLCBKdWwgMTMsIDIwMjEgYXQgMDI6MzU6 NDNQTSArMDMwMCwgQmFydWNoIFNpYWNoIHdyb3RlOgo+PiAtLS0gL2Rldi9udWxsCj4+ICsrKyBi L2RyaXZlcnMvcHdtL3B3bS1pcHEuYwo+PiBAQCAtMCwwICsxLDI3OCBAQAo+PiArLy8gU1BEWC1M aWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZSBPUiBHUEwtMi4wCj4+ICsvKgo+PiArICog Q29weXJpZ2h0IChjKSAyMDE2LTIwMTcsIDIwMjAgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCBy aWdodHMgcmVzZXJ2ZWQuCj4+ICsgKi8KPj4gKwo+PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5o Pgo+PiArI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+PiArI2luY2x1ZGUgPGxp bnV4L3B3bS5oPgo+PiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+PiArI2luY2x1ZGUgPGxpbnV4 L2lvLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbWF0aDY0Lmg+Cj4+ICsjaW5jbHVkZSA8bGludXgv b2ZfZGV2aWNlLmg+Cj4+ICsjaW5jbHVkZSA8bGludXgvbWZkL3N5c2Nvbi5oPgo+PiArI2luY2x1 ZGUgPGxpbnV4L3JlZ21hcC5oPgo+PiArCj4+ICsjZGVmaW5lIElQUV9QV01fTUFYX0RFVklDRVMJ NAo+Cj4gVGhpcyBpcyBvbmx5IHVzZWQgb25jZS4gSnVzdCBkb2luZwo+Cj4gCXB3bS0+Y2hpcC5u cHdtID0gNDsKPgo+IGlzIGJldHRlciBpbiBteSBib29rLiBEb2VzICJNQVgiIHN1Z2dlc3QgdGhh dCB0aGVyZSBhcmUgdmFyaWFudHMgd2l0aAo+IGxlc3MgUFdNcz8KCkkgaGF2ZSBubyBpZGVhLiBJ IGd1ZXNzIG5vdC4gSSdsbCBkcm9wIHRoaXMgbWFjcm8gaW4gdjYuCgo+Cj4+ICsvKiBUaGUgZnJl cXVlbmN5IHJhbmdlIHN1cHBvcnRlZCBpcyAxSHogdG8gMTAwTUh6ICovCj4KPiBBIHNwYWNlIGJl dHdlZW4gbnVtYmVyIGFuZCB1bml0IGlzIHVzdWFsIGFuZCBtYWtlcyB0aGlzIGJldHRlciByZWFk YWJsZS4KClF1aWNrICdnaXQgZ3JlcCcgaW5kaWNhdGVzIHRoYXQgJ1tbOmRpZ2l0Ol1dXCtNSHon IGlzIGEgbGl0dGxlIG1vcmUKcG9wdWxhciB0aGFuICdbWzpkaWdpdDpdXVwrIE1IeicgaW4ga2Vy bmVsIGNvZGUuIEJ1dCBPSywgbm90IGEgYmlnIGRlYWwuCgo+PiArI2RlZmluZSBJUFFfUFdNX0NM S19TUkNfRlJFUQkoMTAwKjEwMDAqMTAwMCkKPj4gKyNkZWZpbmUgSVBRX1BXTV9NSU5fUEVSSU9E X05TCShOU0VDX1BFUl9TRUMgLyBJUFFfUFdNX0NMS19TUkNfRlJFUSkKPgo+IFlvdSdyZSBhc3N1 bWluZyBoZXJlIHRoYXQgdGhlIHBhcmVudCBjbG9jayBydW5zIGF0IGV4YWN0bHkgdGhlIHNldCBy YXRlLgo+IElzIHRoaXMgYSBzZW5zaWJsZSBhc3N1bXB0aW9uPyBJZiB0aGlzIGRpdmlzaW9uIGRp ZG4ndCBoYXZlIGFuIGludGVnZXIKPiByZXN1bHQgdGhlcmUgd291bGQgYmUgcm91bmRpbmcgaXNz dWVzLgoKVGhlIGNvZGUgb25seSB1c2VzIHRoaXMgZm9yIHBlcmlvZCB2YWxpZGl0eSBjaGVjay4g SXQgc2F2ZXMgdXMgc29tZSBjb2RlCmZvciBydW4tdGltZSBkaXZpc2lvbi4KCj4+ICsjZGVmaW5l IElQUV9QV01fTUFYX1BFUklPRF9OUwkoKHU2NClOU0VDX1BFUl9TRUMpCj4+ICsKPj4gKy8qCj4+ ICsgKiBUaGUgbWF4IHZhbHVlIHNwZWNpZmllZCBmb3IgZWFjaCBmaWVsZCBpcyBiYXNlZCBvbiB0 aGUgbnVtYmVyIG9mIGJpdHMKPj4gKyAqIGluIHRoZSBwd20gY29udHJvbCByZWdpc3RlciBmb3Ig dGhhdCBmaWVsZAo+PiArICovCj4+ICsjZGVmaW5lIElQUV9QV01fTUFYX0RJVgkJMHhGRkZGCj4+ ICsKPj4gKyNkZWZpbmUgSVBRX1BXTV9DRkdfUkVHMCAwIC8qUFdNX0RJViBQV01fSEkqLwo+PiAr I2RlZmluZSBJUFFfUFdNX1JFRzBfUFdNX0RJVgkJR0VOTUFTSygxNSwgMCkKPj4gKyNkZWZpbmUg SVBRX1BXTV9SRUcwX0hJX0RVUkFUSU9OCUdFTk1BU0soMzEsIDE2KQo+PiArCj4+ICsjZGVmaW5l IElQUV9QV01fQ0ZHX1JFRzEgMSAvKkVOQUJMRSBVUERBVEUgUFdNX1BSRV9ESVYqLwo+PiArI2Rl ZmluZSBJUFFfUFdNX1JFRzFfUFJFX0RJVgkJR0VOTUFTSygxNSwgMCkKPj4gKy8qCj4+ICsgKiBF bmFibGUgYml0IGlzIHNldCB0byBlbmFibGUgb3V0cHV0IHRvZ2dsaW5nIGluIHB3bSBkZXZpY2Uu Cj4+ICsgKiBVcGRhdGUgYml0IGlzIHNldCB0byByZWZsZWN0IHRoZSBjaGFuZ2VkIGRpdmlkZXIg YW5kIGhpZ2ggZHVyYXRpb24KPj4gKyAqIHZhbHVlcyBpbiByZWdpc3Rlci4KPj4gKyAqLwo+PiAr I2RlZmluZSBJUFFfUFdNX1JFRzFfVVBEQVRFCQlCSVQoMzApCj4+ICsjZGVmaW5lIElQUV9QV01f UkVHMV9FTkFCTEUJCUJJVCgzMSkKPj4gKwo+PiArCj4+ICtzdHJ1Y3QgaXBxX3B3bV9jaGlwIHsK Pj4gKwlzdHJ1Y3QgcHdtX2NoaXAgY2hpcDsKPj4gKwlzdHJ1Y3QgY2xrICpjbGs7Cj4+ICsJc3Ry dWN0IHJlZ21hcCAqcmVnbWFwOwo+PiArCXUzMiByZWdtYXBfb2ZmOwo+PiArfTsKPj4gKwo+PiAr c3RhdGljIHN0cnVjdCBpcHFfcHdtX2NoaXAgKnRvX2lwcV9wd21fY2hpcChzdHJ1Y3QgcHdtX2No aXAgKmNoaXApCj4+ICt7Cj4+ICsJcmV0dXJuIGNvbnRhaW5lcl9vZihjaGlwLCBzdHJ1Y3QgaXBx X3B3bV9jaGlwLCBjaGlwKTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHVuc2lnbmVkIGlwcV9wd21f cmVnX29mZnNldChzdHJ1Y3QgcHdtX2RldmljZSAqcHdtLCB1bnNpZ25lZCByZWcpCj4+ICt7Cj4+ ICsJcmV0dXJuICgocHdtLT5od3B3bSAqIDIpICsgcmVnKSAqIDQ7Cj4+ICt9Cj4+ICsKPj4gK3N0 YXRpYyB1bnNpZ25lZCBpbnQgaXBxX3B3bV9yZWdfcmVhZChzdHJ1Y3QgcHdtX2RldmljZSAqcHdt LCB1bnNpZ25lZCByZWcpCj4+ICt7Cj4+ICsJc3RydWN0IGlwcV9wd21fY2hpcCAqaXBxX2NoaXAg PSB0b19pcHFfcHdtX2NoaXAocHdtLT5jaGlwKTsKPj4gKwl1bnNpZ25lZCBpbnQgb2ZmID0gaXBx X2NoaXAtPnJlZ21hcF9vZmYgKyBpcHFfcHdtX3JlZ19vZmZzZXQocHdtLCByZWcpOwo+Cj4gSSBh bHJlYWR5IHN0dW1ibGVkIGFib3V0IHRoaXMgaW4gdjQgYnV0IHRob3VnaHQgSSdkIGxldCB5b3Ug ZG8gaXQuIEFzCj4gSSBzdHVtYmxlZCBhZ2FpbiBJJ2xsIHNheSBzb21ldGhpbmcgbm93Ogo+Cj4g SSB3b3VsZCBkbyB0aGUgcmVnaXN0ZXIgc3R1ZmYgYXMgZm9sbG93czoKPgo+IAkvKiBFYWNoIFBX TSBoYXMgdHdvIHJlZ2lzdGVycywgdGhlIG9mZnNldCBmb3IgUFdNICNpIGlzIGF0IDggKiAjaSAq Lwo+IAkjZGVmaW5lIElQUV9QV01fQ0ZHX1JFRzAJMAo+IAkjZGVmaW5lIElQUV9QV01fQ0ZHX1JF RzEJNAo+Cj4gYW5kIHRoZW4gZG86Cj4KPiAJc3RhdGljIHVuc2lnbmVkIGludCBpcHFfcHdtX3Jl Z19yZWFkKHN0cnVjdCBwd21fZGV2aWNlICpwd20sIHVuc2lnbmVkIHJlZykKPiAJewo+IAkJc3Ry dWN0IGlwcV9wd21fY2hpcCAqaXBxX2NoaXAgPSB0b19pcHFfcHdtX2NoaXAocHdtLT5jaGlwKTsK PiAJCXVuc2lnbmVkIGludCBvZmYgPSBpcHFfY2hpcC0+cmVnbWFwX29mZiArIDggKiBwd20tPmh3 cHdtICsgcmVnOwo+Cj4gCQkuLi4KPgo+IHRoaXMgaXMgYSBiaXQgZWFzaWVyIHRvIHVuZGVyc3Rh bmQgSU1ITywgYnV0IG1pZ2h0IGJlIHN1YmplY3RpdmUuIEkgbGV0Cj4geW91IGRlY2lkZSBpZiB5 b3Ugd2FudCB0byBjaGFuZ2UgdGhhdCBvciBzdGF5IHdpdGggeW91ciBhcHByb2FjaC4KPgo+PiAr CXVuc2lnbmVkIGludCB2YWw7Cj4+ICsKPj4gKwlyZWdtYXBfcmVhZChpcHFfY2hpcC0+cmVnbWFw LCBvZmYsICZ2YWwpOwo+PiArCj4+ICsJcmV0dXJuIHZhbDsKPj4gK30KPj4gKwo+PiArc3RhdGlj IHZvaWQgaXBxX3B3bV9yZWdfd3JpdGUoc3RydWN0IHB3bV9kZXZpY2UgKnB3bSwgdW5zaWduZWQg cmVnLAo+PiArCQl1bnNpZ25lZCB2YWwpCj4+ICt7Cj4+ICsJc3RydWN0IGlwcV9wd21fY2hpcCAq aXBxX2NoaXAgPSB0b19pcHFfcHdtX2NoaXAocHdtLT5jaGlwKTsKPj4gKwl1bnNpZ25lZCBpbnQg b2ZmID0gaXBxX2NoaXAtPnJlZ21hcF9vZmYgKyBpcHFfcHdtX3JlZ19vZmZzZXQocHdtLCByZWcp Owo+PiArCj4+ICsJcmVnbWFwX3dyaXRlKGlwcV9jaGlwLT5yZWdtYXAsIG9mZiwgdmFsKTsKPj4g K30KPj4gKwo+PiArc3RhdGljIHZvaWQgY29uZmlnX2Rpdl9hbmRfZHV0eShzdHJ1Y3QgcHdtX2Rl dmljZSAqcHdtLCB1bnNpZ25lZCBpbnQgcHJlX2RpdiwKPj4gKwkJCXVuc2lnbmVkIGludCBwd21f ZGl2LCB1NjQgcGVyaW9kX25zLCB1NjQgZHV0eV9ucywKPj4gKwkJCWJvb2wgZW5hYmxlKQo+PiAr ewo+PiArCXVuc2lnbmVkIGxvbmcgaGlfZHVyOwo+PiArCXVuc2lnbmVkIGxvbmcgbG9uZyBxdW90 aWVudDsKPj4gKwl1bnNpZ25lZCBsb25nIHZhbCA9IDA7Cj4+ICsKPj4gKwkvKgo+PiArCSAqIGhp Z2ggZHVyYXRpb24gPSBwd20gZHV0eSAqIChwd20gZGl2ICsgMSkKPj4gKwkgKiBwd20gZHV0eSA9 IGR1dHlfbnMgLyBwZXJpb2RfbnMKPj4gKwkgKi8KPj4gKwlxdW90aWVudCA9IChwd21fZGl2ICsg MSkgKiBkdXR5X25zOwo+PiArCWhpX2R1ciA9IGRpdjY0X3U2NChxdW90aWVudCwgcGVyaW9kX25z KTsKPgo+IHRoaXMgZGl2aXNpb24gc2hvdWxkIHVzZSB0aGUgYWN0dWFsIHBlcmlvZCwgbm90IHRo ZSB0YXJnZXQgcGVyaW9kLgo+IE90aGVyd2lzZSB0aGUgcmVzdWx0IG1pZ2h0IGJlIHRvIHNtYWxs Lgo+Cj4+ICsJdmFsID0gRklFTERfUFJFUChJUFFfUFdNX1JFRzBfSElfRFVSQVRJT04sIGhpX2R1 cikgfAo+PiArCQlGSUVMRF9QUkVQKElQUV9QV01fUkVHMF9QV01fRElWLCBwd21fZGl2KTsKPj4g KwlpcHFfcHdtX3JlZ193cml0ZShwd20sIElQUV9QV01fQ0ZHX1JFRzAsIHZhbCk7Cj4+ICsKPj4g Kwl2YWwgPSBGSUVMRF9QUkVQKElQUV9QV01fUkVHMV9QUkVfRElWLCBwcmVfZGl2KTsKPj4gKwlp cHFfcHdtX3JlZ193cml0ZShwd20sIElQUV9QV01fQ0ZHX1JFRzEsIHZhbCk7Cj4+ICsKPj4gKwkv KiBFbmFibGUgbmVlZHMgYSBzZXBhcmF0ZSB3cml0ZSB0byBSRUcxICovCj4+ICsJdmFsIHw9IElQ UV9QV01fUkVHMV9VUERBVEU7Cj4KPiBTZXR0aW5nIHRoaXMgYml0IHJlc3VsdHMgaW4gdGhlIHR3 byB3cml0ZXMgYWJvdmUgYmVpbmcgY29uZmlndXJlZAo+IGF0b21pY2FsbHkgc28gdGhhdCBubyBt aXhlZCBzZXR0aW5ncyBoYXBwZW4gdG8gdGhlIG91dHB1dCwgcmlnaHQ/CgpJIGd1ZXNzIHNvLiBJ IGhhdmUgbm8gYWNjZXNzIHRvIGhhcmR3YXJlIGRvY3VtZW50YXRpb24sIG1pbmQgeW91LiBJCmZp cnN0IHRyaWVkIHRvIGRvIG9ubHkgb25lIHdyaXRlIHRvIFJFRzEsIGJ1dCBpdCBoYWQgbm8gZWZm ZWN0LiBUaGUKZXhpc3RlbmNlIG9mIHRoZSBVUERBVEUgYml0IGFsc28gaW5kaWNhdGVzIHRoYXQg aGFyZHdhcmUgd29ya3MgYXMgeW91CnN1Z2dlc3QuCgo+IERvZXMgdGhlIGhhcmR3YXJlIGNvbXBs ZXRlIHRoZSBjdXJyZW50bHkgcnVubmluZyBjeWNsZSBvbgo+IHJlY29uZmlndXJhdGlvbj8KCk5v IGlkZWEuCgo+PiArCWlmIChlbmFibGUpCj4+ICsJCXZhbCB8PSBJUFFfUFdNX1JFRzFfRU5BQkxF Owo+PiArCWVsc2UKPj4gKwkJdmFsICY9IH5JUFFfUFdNX1JFRzFfRU5BQkxFOwo+Cj4gVGhlIGVs c2UgYnJhbmNoIGhhcyBubyBlZmZlY3QgYXMgdmFsIGlzIGluaXRpYWxpemVkIGFzIHplcm8gYWJv dmUsIHNvCj4gcGxlYXNlIGRyb3AgaXQuCj4KPj4gKwlpcHFfcHdtX3JlZ193cml0ZShwd20sIElQ UV9QV01fQ0ZHX1JFRzEsIHZhbCk7Cj4KPiBIb3cgZG9lcyB0aGUgaGFyZHdhcmUgYmVoYXZlIHdp dGggdGhlIEVOQUJMRSBiaXQgdW5zZXQ/IERvZXMgaXQgZHJpdmUKPiB0aGUgcGluIHRvIHplcm8/ CgpZZXMuIFRoYXQncyB3aGF0IGV4cGVyaW1lbnRhdGlvbiBoZXJlIHNob3dzLiBUaGUgcGluIGlz IHB1bGxlZCB1cCwgYnV0CnRoZSBQV00ga2VlcHMgaXQgbG93LgoKPj4gK30KPj4gKwo+PiArc3Rh dGljIGludCBpcHFfcHdtX2FwcGx5KHN0cnVjdCBwd21fY2hpcCAqY2hpcCwgc3RydWN0IHB3bV9k ZXZpY2UgKnB3bSwKPj4gKwkJCSBjb25zdCBzdHJ1Y3QgcHdtX3N0YXRlICpzdGF0ZSkKPj4gK3sK Pj4gKwlzdHJ1Y3QgaXBxX3B3bV9jaGlwICppcHFfY2hpcCA9IHRvX2lwcV9wd21fY2hpcChjaGlw KTsKPj4gKwl1bnNpZ25lZCBsb25nIGZyZXE7Cj4+ICsJdW5zaWduZWQgaW50IHByZV9kaXYsIHB3 bV9kaXYsIGNsb3NlX3ByZV9kaXYsIGNsb3NlX3B3bV9kaXY7Cj4+ICsJbG9uZyBsb25nIGRpZmY7 Cj4+ICsJdW5zaWduZWQgbG9uZyByYXRlID0gY2xrX2dldF9yYXRlKGlwcV9jaGlwLT5jbGspOwo+ PiArCXVuc2lnbmVkIGxvbmcgbWluX2RpZmYgPSByYXRlOwo+PiArCXVpbnQ2NF90IGZpbl9wczsK Pj4gKwl1NjQgcGVyaW9kX25zLCBkdXR5X25zOwo+Cj4gWW91IGhhdmUgdG8gcmVmdXNlIHRoZSBy ZXF1ZXN0IGlmIHN0YXRlLT5wb2xhcml0eSAhPQo+IFBXTV9QT0xBUklUWV9OT1JNQUwuCj4KPj4g Kwo+PiArCWlmIChzdGF0ZS0+cGVyaW9kIDwgSVBRX1BXTV9NSU5fUEVSSU9EX05TKQo+Cj4gSXQn cyBzdHJhbmdlIHRoYXQgeW91IGFzc3VtZSBoZXJlIHRoZSBoYXJkY29kZWQgMTAwIE1IeiBidXQg YmVsb3cgeW91Cj4gdXNlIGNsa19nZXRfcmF0ZShpcHFfY2hpcC0+Y2xrKS4KCkFzIEkgc2FpZCBh Ym92ZSwgdGhpcyBpcyBtZWFudCB0byBzYXZlIGNvZGUgZm9yIHRoZSBsZXNzIGNyaXRpY2FsCmNh c2UuIFNob3VsZCBJIHVzZSBjbGtfZ2V0X3JhdGUoKSBoZXJlIGFzIHdlbGw/IElmIHdlIGdvIHdp dGgKYXNzaWduZWQtY2xvY2stcmF0ZXMsIGFzIHlvdSBzdWdnZXN0IGJlbG93LCB3ZSdsbCBoYXZl IHRvIGRvIHRoYXQKYW55d2F5LgoKPgo+PiArCQlyZXR1cm4gLUVSQU5HRTsKPj4gKwo+PiArCXBl cmlvZF9ucyA9IG1pbihzdGF0ZS0+cGVyaW9kLCBJUFFfUFdNX01BWF9QRVJJT0RfTlMpOwo+PiAr CWR1dHlfbnMgPSBtaW4oc3RhdGUtPmR1dHlfY3ljbGUsIHBlcmlvZF9ucyk7Cj4+ICsKPj4gKwkv KiBmcmVxIGluIEh6IGZvciBwZXJpb2QgaW4gbmFubyBzZWNvbmQgKi8KPj4gKwlmcmVxID0gZGl2 NjRfdTY0KE5TRUNfUEVSX1NFQywgcGVyaW9kX25zKTsKPj4gKwlmaW5fcHMgPSBkaXY2NF91NjQo TlNFQ19QRVJfU0VDICogMTAwMFVMTCwgcmF0ZSk7Cj4KPiBJIGRvbid0IHVuZGVyc3RhbmQgdGhh dCBmYWN0b3IgMTAwMC4gVGhpcyBqdXN0IGNhbmNlbHMgd2l0aCB0aGUgMTAwMCBpbgo+IHRoZSBj YWxjdWxhdGlvbiBvZiBwd21fZGl2IGJlbG93PyEgTWF5YmUgdGhpcyBpcyB0byBzb2Z0ZW4gdGhl IHByZWNpc2lvbgo+IGxvc3M/CgpUaGF0IGlzIG15IHVuZGVyc3RhbmRpbmcgb2YgdGhlIGNvZGUg aW50ZW50LgoKPj4gKwljbG9zZV9wcmVfZGl2ID0gSVBRX1BXTV9NQVhfRElWOwo+PiArCWNsb3Nl X3B3bV9kaXYgPSBJUFFfUFdNX01BWF9ESVY7Cj4+ICsKPj4gKwlmb3IgKHByZV9kaXYgPSAwOyBw cmVfZGl2IDw9IElQUV9QV01fTUFYX0RJVjsgcHJlX2RpdisrKSB7Cj4+ICsJCXB3bV9kaXYgPSBE SVY2NF9VNjRfUk9VTkRfQ0xPU0VTVChwZXJpb2RfbnMgKiAxMDAwLAo+PiArCQkJCQkJICBmaW5f cHMgKiAocHJlX2RpdiArIDEpKTsKPgo+IEhhdmluZyBmaW5fcHMgaW4gdGhlIGRpdmlzb3IgcmVz dWx0cyBpbiBsb3NzIG9mIHByZWNpc2lvbi4gV2hlbiBldmVyIHRoZQo+IGNsb3Nlc3Qgcm91bmRp bmcgZGl2aXNpb24gcm91bmRzIGRvd24gZGlmZiBiZWNvbWVzIG5lZ2F0aXZlIGJlbG93LiBTbwo+ IHlvdSBzaG91bGQgcm91bmQgdXAgaGVyZS4KPgo+IEFsc28gaWYgeW91IGRvOgo+Cj4gCXB3bV9k aXYgPSByb3VuZF91cCgocGVyaW9kX25zICogcmF0ZSkgLyAoTlNFQ19QRVJfU0VDICogKHByZV9k aXYgKyAxKSkpCj4KPiB0aGVyZSBpcyBubyByZWxldmFudCBsb3NzIG9mIHByZWNpc2lvbi4gKFlv dSBtaWdodCBoYXZlIHRvIGNhcmUgZm9yCj4gcGVyaW9kX25zICogcmF0ZSBvdmVyZmxvd2luZyB0 aG91Z2ggb3IgYXJndWUgd2h5IGl0IGRvZXNuJ3Qgb3ZlcmZsb3cuKQoKTG9va3MgYmV0dGVyLgoK Pgo+PiArCQlwd21fZGl2LS07Cj4+ICsJCWlmIChwd21fZGl2ID4gSVBRX1BXTV9NQVhfRElWKQo+ PiArCQkJY29udGludWU7Cj4KPiBUaGlzIGNoZWNrIGNhbiBiZSBkcm9wcGVkIGlmIHRoZSBsb29w IChkZXBlbmRpbmcgb24gdGhlIG90aGVyIHBhcmFtZXRlcnMpCj4gZG9lcyBub3Qgc3RhcnQgd2l0 aCBwcmVfZGl2ID0gMCBidXQgc29tZSBiaWdnZXIgbnVtYmVyLgoKVGhhdCBpcywgY2FsY3VsYXRl IHRoZSBtaW5pbXVtIHByZV9kaXYgdmFsdWUgZm9yIHdoaWNoIHRoZSBkaXZpc2lvbgphYm92ZSBh bHdheXMgcHJvZHVjZXMgcHdtX2RpdiBpbiByYW5nZSwgcmlnaHQ/Cgo+Cj4+ICsJCWRpZmYgPSAo KHVpbnQ2NF90KWZyZXEgKiAocHJlX2RpdiArIDEpICogKHB3bV9kaXYgKyAxKSkKPj4gKwkJCS0g KHVpbnQ2NF90KXJhdGU7Cj4+ICsKPj4gKwkJaWYgKGRpZmYgPCAwKSAvKiBwZXJpb2QgbGFyZ2Vy IHRoYW4gcmVxdWVzdGVkICovCj4+ICsJCQljb250aW51ZTsKPj4gKwkJaWYgKGRpZmYgPT0gMCkg eyAvKiBiaW5nbyAqLwo+PiArCQkJY2xvc2VfcHJlX2RpdiA9IHByZV9kaXY7Cj4+ICsJCQljbG9z ZV9wd21fZGl2ID0gcHdtX2RpdjsKPj4gKwkJCWJyZWFrOwo+PiArCQl9Cj4+ICsJCWlmIChkaWZm IDwgbWluX2RpZmYpIHsKPj4gKwkJCW1pbl9kaWZmID0gZGlmZjsKPj4gKwkJCWNsb3NlX3ByZV9k aXYgPSBwcmVfZGl2Owo+PiArCQkJY2xvc2VfcHdtX2RpdiA9IHB3bV9kaXY7Cj4KPiBJIHdvdWxk IGNhbGwgdGhlc2UgYmVzdF8uLi5fZGl2LCBub3QgY2xvc2VfLi4uX2RpdiB3aGljaCBtYWtlcyB0 aGUKPiBwdXJwb3NlIGNsZWFyZXIuCj4KPiBBIGJpZyBwcmVfZGl2IHJlc3VsdHMgaW4gYSBjb2Fy c2UgcmVzb2x1dGlvbiBmb3IgZHV0eV9jeWNsZS4gVGhpcyBtYWtlcwo+IG90aGVyIHNpbWlsYXIg ZHJpdmVycyBjaG9zZSB0byBoYXJkY29kZSBwd21fZGl2IHRvIGl0cyBtYXggdmFsdWUuIEF0Cj4g bGVhc3QgeW91IHNob3VsZCBlbnN1cmUgdGhhdCBwcmVfZGl2IDw9IHB3bV9kaXYuCj4KPj4gKwkJ fQo+PiArCX0KPj4gKwo+PiArCS8qIGNvbmZpZyBkaXZpZGVyIHZhbHVlcyBmb3IgdGhlIGNsb3Nl c3QgcG9zc2libGUgZnJlcXVlbmN5ICovCj4+ICsJY29uZmlnX2Rpdl9hbmRfZHV0eShwd20sIGNs b3NlX3ByZV9kaXYsIGNsb3NlX3B3bV9kaXYsCj4+ICsJCQkgICAgcGVyaW9kX25zLCBkdXR5X25z LCBzdGF0ZS0+ZW5hYmxlZCk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3Rh dGljIHZvaWQgaXBxX3B3bV9nZXRfc3RhdGUoc3RydWN0IHB3bV9jaGlwICpjaGlwLCBzdHJ1Y3Qg cHdtX2RldmljZSAqcHdtLAo+PiArCQkJICAgICAgc3RydWN0IHB3bV9zdGF0ZSAqc3RhdGUpCj4+ ICt7Cj4+ICsJc3RydWN0IGlwcV9wd21fY2hpcCAqaXBxX2NoaXAgPSB0b19pcHFfcHdtX2NoaXAo Y2hpcCk7Cj4+ICsJdW5zaWduZWQgbG9uZyByYXRlID0gY2xrX2dldF9yYXRlKGlwcV9jaGlwLT5j bGspOwo+PiArCXVuc2lnbmVkIGludCBwcmVfZGl2LCBwd21fZGl2LCBoaV9kdXI7Cj4+ICsJdTY0 IGVmZmVjdGl2ZV9kaXYsIGhpX2RpdjsKPj4gKwl1MzIgcmVnMCwgcmVnMTsKPj4gKwo+PiArCXJl ZzAgPSBpcHFfcHdtX3JlZ19yZWFkKHB3bSwgSVBRX1BXTV9DRkdfUkVHMCk7Cj4+ICsJcmVnMSA9 IGlwcV9wd21fcmVnX3JlYWQocHdtLCBJUFFfUFdNX0NGR19SRUcxKTsKPj4gKwo+PiArCXN0YXRl LT5wb2xhcml0eSA9IFBXTV9QT0xBUklUWV9OT1JNQUw7Cj4+ICsJc3RhdGUtPmVuYWJsZWQgPSBy ZWcxICYgSVBRX1BXTV9SRUcxX0VOQUJMRTsKPj4gKwo+PiArCXB3bV9kaXYgPSBGSUVMRF9HRVQo SVBRX1BXTV9SRUcwX1BXTV9ESVYsIHJlZzApOwo+PiArCWhpX2R1ciA9IEZJRUxEX0dFVChJUFFf UFdNX1JFRzBfSElfRFVSQVRJT04sIHJlZzApOwo+PiArCXByZV9kaXYgPSBGSUVMRF9HRVQoSVBR X1BXTV9SRUcxX1BSRV9ESVYsIHJlZzEpOwo+PiArCWVmZmVjdGl2ZV9kaXYgPSAocHJlX2RpdiAr IDEpICogKHB3bV9kaXYgKyAxKTsKPgo+IFBsZWFzZSBhZGQgYSBjb21tZW50IGhlcmUgdGhhdCB3 aXRoIHByZV9kaXYgYW5kIHB3bV9kaXYgPD0gMHhmZmZmIHRoZQo+IG11bHRpcGxpY2F0aW9uIGJl bG93IGRvZXNuJ3Qgb3ZlcmZsb3cKPgo+PiArCXN0YXRlLT5wZXJpb2QgPSBkaXY2NF91NjQoZWZm ZWN0aXZlX2RpdiAqIE5TRUNfUEVSX1NFQywgcmF0ZSk7Cj4+ICsKPj4gKwloaV9kaXYgPSBoaV9k dXIgKiAocHJlX2RpdiArIDEpOwo+Cj4gVGhpcyBzdWdnZXN0cyB0aGF0IHRoZSBoYXJkd2FyZSBj YW5ub3QgZG8gMTAwJSByZWxhdGl2ZSBkdXR5IGN5Y2xlIGlmCj4gcHdtX2RpdiA9PSAweGZmZmY/ IEkgc3VnZ2VzdCB0byBjbGFtcCBwd21fZGl2IHRvIDB4ZmZmZSB0aGVuLgoKV2hhdCBpcyAiMTAw JSByZWxhdGl2ZSBkdXR5Ij8gSG93IGRvZXMgcHdtX2RpdiBjbGFtcGluZyBoZWxwcz8KCj4+ICsJ c3RhdGUtPmR1dHlfY3ljbGUgPSBkaXY2NF91NjQoaGlfZGl2ICogTlNFQ19QRVJfU0VDLCByYXRl KTsKPj4gK30KPj4gKwo+PiArc3RhdGljIHN0cnVjdCBwd21fb3BzIGlwcV9wd21fb3BzID0gewo+ Cj4gY29uc3QgcGxlYXNlCj4KPj4gKwkuYXBwbHkgPSBpcHFfcHdtX2FwcGx5LAo+PiArCS5nZXRf c3RhdGUgPSBpcHFfcHdtX2dldF9zdGF0ZSwKPj4gKwkub3duZXIgPSBUSElTX01PRFVMRSwKPj4g K307Cj4+ICsKPj4gK3N0YXRpYyBpbnQgaXBxX3B3bV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2KQo+PiArewo+PiArCXN0cnVjdCBpcHFfcHdtX2NoaXAgKnB3bTsKPj4gKwlzdHJ1 Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Owo+PiArCXN0cnVjdCBvZl9waGFuZGxlX2FyZ3Mg YXJnczsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJcHdtID0gZGV2bV9remFsbG9jKGRldiwgc2l6 ZW9mKCpwd20pLCBHRlBfS0VSTkVMKTsKPj4gKwlpZiAoIXB3bSkKPj4gKwkJcmV0dXJuIC1FTk9N RU07Cj4+ICsKPj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBwd20pOwo+PiArCj4+ICsJ cmV0ID0gb2ZfcGFyc2VfcGhhbmRsZV93aXRoX2ZpeGVkX2FyZ3MoZGV2LT5vZl9ub2RlLCAicWNv bSxwd20tcmVncyIsCj4+ICsJCQkxLCAwLCAmYXJncyk7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0 dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJyZWdzIHBhcnNlIGZhaWxlZCIpOwo+PiArCj4+ ICsJcHdtLT5yZWdtYXAgPSBzeXNjb25fbm9kZV90b19yZWdtYXAoYXJncy5ucCk7Cj4+ICsJb2Zf bm9kZV9wdXQoYXJncy5ucCk7Cj4+ICsJaWYgKElTX0VSUihwd20tPnJlZ21hcCkpCj4+ICsJCXJl dHVybiBkZXZfZXJyX3Byb2JlKGRldiwgUFRSX0VSUihwd20tPnJlZ21hcCksCj4+ICsJCQkJInJl Z3MgbWFwIGZhaWxlZCIpOwo+PiArCXB3bS0+cmVnbWFwX29mZiA9IGFyZ3MuYXJnc1swXTsKPgo+ IERvZXMgdGhpcyBoYXZlIHRvIGJlIHNvIGNvbXBsaWNhdGVkPyBXaHkgZG9lc24ndCB0aGUgbm9y bWFsIGFwcHJvYWNoCj4gd2l0aCB0aGUgcHdtIGJlaW5nIGEgY2hpbGQgb2YgdGhlIHN5c2NvbiBk ZXZpY2UgYW5kIHJlZyA9IDwuLi4+IHdvcmsKPiBoZXJlPwoKSSdsbCBkbyB0aGF0IGluIHY2LiBU aGF0J3Mgd2hhdCBCam9ybiBvcmlnaW5hbGx5IHN1Z2dlc3RlZCBpbiByZXNwb25zZQp0byB2Mi4K Cj4KPj4gKwlwd20tPmNsayA9IGRldm1fY2xrX2dldChkZXYsICJjb3JlIik7Cj4+ICsJaWYgKElT X0VSUihwd20tPmNsaykpCj4+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgUFRSX0VSUihw d20tPmNsayksCj4+ICsJCQkJImZhaWxlZCB0byBnZXQgY29yZSBjbG9jayIpOwo+PiArCj4+ICsJ cmV0ID0gY2xrX3NldF9yYXRlKHB3bS0+Y2xrLCBJUFFfUFdNX0NMS19TUkNfRlJFUSk7Cj4+ICsJ aWYgKHJldCkKPj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJjbG9jayByYXRl IHNldCBmYWlsZWQiKTsKPgo+IFdvdWxkIGl0IG1ha2UgbW9yZSBzZW5zZSB0byBzZXQgdGhpcyBp biB0aGUgZGV2aWNlIHRyZWUgdXNpbmcKPiBhc3NpZ25lZC1jbG9jay1yYXRlPwoKVGhhdCdzICdh c3NpZ25lZC1jbG9jay1yYXRlcycgSSBiZWxpZXZlLiBJJ2xsIHRyeSB0aGF0LgoKPgo+PiArCXJl dCA9IGNsa19wcmVwYXJlX2VuYWJsZShwd20tPmNsayk7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0 dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJjbG9jayBlbmFibGUgZmFpbGVkIik7Cj4+ICsK Pj4gKwlwd20tPmNoaXAuZGV2ID0gZGV2Owo+PiArCXB3bS0+Y2hpcC5vcHMgPSAmaXBxX3B3bV9v cHM7Cj4+ICsJcHdtLT5jaGlwLm5wd20gPSBJUFFfUFdNX01BWF9ERVZJQ0VTOwo+PiArCj4+ICsJ cmV0ID0gcHdtY2hpcF9hZGQoJnB3bS0+Y2hpcCk7Cj4+ICsJaWYgKHJldCA8IDApIHsKPj4gKwkJ ZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgInB3bWNoaXBfYWRkKCkgZmFpbGVkXG4iKTsKPj4gKwkJ Y2xrX2Rpc2FibGVfdW5wcmVwYXJlKHB3bS0+Y2xrKTsKPj4gKwkJcmV0dXJuIHJldDsKPj4gKwl9 Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3RhdGljIGludCBpcHFfcHdtX3Jl bW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+PiArewo+PiArCXN0cnVjdCBpcHFf cHdtX2NoaXAgKnB3bSA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+PiArCj4+ICsJY2xr X2Rpc2FibGVfdW5wcmVwYXJlKHB3bS0+Y2xrKTsKPj4gKwlwd21jaGlwX3JlbW92ZSgmcHdtLT5j aGlwKTsKPgo+IFRoaXMgaXMgdGhlIHdyb25nIG9yZGVyLiBVbnRpbCBwd21jaGlwX3JlbW92ZSgp IHJldHVybnMgdGhlIFBXTSBtdXN0IHN0YXkKPiBmdW5jdGlvbmFsLCBzbyBkaXNhYmxlIHRoZSBj bG9jayBvbmx5IGFmdGVyIHB3bWNoaXBfcmVtb3ZlKCkuCj4KPj4gKwo+PiArCXJldHVybiAwOwo+ PiArfQo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBwd21faXBxX2R0 X21hdGNoW10gPSB7Cj4+ICsJeyAuY29tcGF0aWJsZSA9ICJxY29tLGlwcTYwMTgtcHdtIiwgfSwK Pj4gKwl7fQo+PiArfTsKPj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIHB3bV9pcHFfZHRfbWF0 Y2gpOwo+PiArCj4+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBpcHFfcHdtX2RyaXZl ciA9IHsKPj4gKwkuZHJpdmVyID0gewo+PiArCQkubmFtZSA9ICJpcHEtcHdtIiwKPj4gKwkJLm9m X21hdGNoX3RhYmxlID0gcHdtX2lwcV9kdF9tYXRjaCwKPj4gKwl9LAo+PiArCS5wcm9iZSA9IGlw cV9wd21fcHJvYmUsCj4+ICsJLnJlbW92ZSA9IGlwcV9wd21fcmVtb3ZlLAo+PiArfTsKPj4gKwo+ PiArbW9kdWxlX3BsYXRmb3JtX2RyaXZlcihpcHFfcHdtX2RyaXZlcik7Cj4+ICsKPj4gK01PRFVM RV9MSUNFTlNFKCJEdWFsIEJTRC9HUEwiKTsKPgo+IEJlc3QgcmVnYXJkcwo+IFV3ZQoKCi0tIAog ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH4uIC5+ ICAgVGsgT3BlbiBTeXN0ZW1zCj19LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tb29PLS1VLS1Pb28tLS0tLS0tLS0tLS17PQogICAtIGJhcnVjaEB0a29zLmNv LmlsIC0gdGVsOiArOTcyLjUyLjM2OC40NjU2LCBodHRwOi8vd3d3LnRrb3MuY28uaWwgLQoKX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtl cm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0 dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5l bAo=