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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 01955C4450A for ; Fri, 17 Jul 2026 02:38:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: Content-Type:In-Reply-To:From:References:Cc:To:Subject:MIME-Version:Date: Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=4+trae873noI6M/KTwB+mA2F5xNHhg6Nh9ODu1W4DXc=; b=29UQMYhWZ3MD5Isz7AGXCK6ys/ t6+CwzOGrhMp7n7lWyfQye4HcJBXAzT+9TAzwdUYDfsHqV8d2hCx6yh5TlX8Ef/9bD78H3uaQnI67 U44cpvDqacrMKRS1+/IVocHypiJ4pGh3Ti8YfuiviIIAsY+Zn23SsJhGM//nEJ1H0zB/VyjFJShAt FK5kv27v6vwek7iYGpRB4ARFjv4E11uF+7pe/e+TCtls4g/GKSwrbqszOJQDJUBpNghf7o885QNnI AyeGhEVNlNInu22WFf5lrxQizsB+xgyHu5DHQTWr97BciSYbWyQv7tkpkIbWvxi+XXaQGrOD2Ba67 jC9qKQTw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wkYT0-00000000yn8-26q6; Fri, 17 Jul 2026 02:38:22 +0000 Received: from mail-m1010.netease.com ([154.81.10.10]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wkYSx-00000000ymO-2fU8; Fri, 17 Jul 2026 02:38:21 +0000 Received: from [172.16.12.74] (unknown [61.154.14.86]) by smtp.qiye.163.com (Hmail) with ESMTP id 46859c9bd; Fri, 17 Jul 2026 10:38:08 +0800 (GMT+08:00) Message-ID: Date: Fri, 17 Jul 2026 10:38:08 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5 3/6] pwm: Add rockchip PWMv4 driver To: =?UTF-8?Q?Uwe_Kleine-K=C3=B6nig?= , Nicolas Frattaroli Cc: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Lee Jones , William Breathitt Gray , kernel@collabora.com, Jonas Karlman , Alexey Charkov , linux-rockchip@lists.infradead.org, linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org References: <20260420-rk3576-pwm-v5-0-ae7cfbbe5427@collabora.com> <20260420-rk3576-pwm-v5-3-ae7cfbbe5427@collabora.com> Content-Language: en-US From: Damon Ding In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-HM-Tid: 0a9f6df03d4603a8kunmde6ff62349f89 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVlDHxpDVktOQ01PQ0lJGBpNGlYVFA kWGhdVEwETFhoSFyQUDg9ZV1kYEgtZQVlNSlVKTk9VSk9VQ01ZV1kWGg8SFR0UWUFZT0tIVUpLSU 9PT0hVSktLVUpCS0tZBg++ DKIM-Signature: a=rsa-sha256; b=XgfBY9TygDAgGW+TnQhdKri9XOCiteJldFJIFc92VlZOH4m4c8Hrv1MuWydsFFtdFO+0ihNUUH4V/uzVZrx3GNcsycjs/F7cIEOxM1QmBpvQSJKfgAWTtKZbKDUy4bb2SLkMb27wtSpy+GBP0okIG6SC13XlC9URiLwuQDHxgW4=; c=relaxed/relaxed; s=default; d=rock-chips.com; v=1; bh=4+trae873noI6M/KTwB+mA2F5xNHhg6Nh9ODu1W4DXc=; h=date:mime-version:subject:message-id:from; X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260716_193820_250092_9C3FA1A1 X-CRM114-Status: GOOD ( 28.78 ) 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi Uwe, On 7/10/2026 7:02 PM, Uwe Kleine-König wrote: > Hello Nicolas, > > On Mon, Apr 20, 2026 at 03:52:40PM +0200, Nicolas Frattaroli wrote: >> [...] >> +/** >> + * rockchip_pwm_v4_round_single - convert a PWM parameter to hardware >> + * @rate: clock rate of the PWM clock, as per clk_get_rate >> + * Assumed to be <= 1GHz for overflow considerations >> + * @in_val: parameter in nanoseconds to convert >> + * >> + * Returns the rounded value, saturating at U32_MAX if too large >> + */ >> +static u32 rockchip_pwm_v4_round_single(unsigned long rate, u64 in_val) > > very picky: if you name this function rockchip_pwm_v4_ns_to_ticks it > becomes clearer what the purpose is. > >> +{ >> + u64 tmp; >> + >> + tmp = mul_u64_u64_div_u64(rate, in_val, NSEC_PER_SEC); >> + if (tmp > U32_MAX) >> + tmp = U32_MAX; >> + >> + return tmp; >> +} >> + >> +/** >> + * rockchip_pwm_v4_round_params - convert PWM parameters to hardware >> + * @rate: PWM clock rate to do the calculations at >> + * @wf: pointer to the generic &struct pwm_waveform input parameters >> + * @wfhw: pointer to the hardware-specific &struct rockchip_pwm_v4_wf output >> + * parameters that the results will be stored in >> + * >> + * Convert nanosecond-based duty/period/offset parameters to the PWM hardware's >> + * native rounded representation in number of cycles at clock rate @rate. Should >> + * any of the input parameters be out of range for the hardware, the >> + * corresponding output parameter is the maximum permissible value for said >> + * parameter with considerations to the others. >> + */ >> +static void rockchip_pwm_v4_round_params(unsigned long rate, >> + const struct pwm_waveform *wf, >> + struct rockchip_pwm_v4_wf *wfhw) >> +{ >> + wfhw->period = rockchip_pwm_v4_round_single(rate, wf->period_length_ns); >> + >> + wfhw->duty = rockchip_pwm_v4_round_single(rate, wf->duty_length_ns); >> + >> + /* As per TRM, PWM_OFFSET: "The value ranges from 0 to (period-duty)" */ > > Have you tried what happens if you break this rule? That seems like a > very arbitrary restriction that might just originate from the > documentation author. > According to the IC design, any offset value larger than (period - duty) will be clamped to (period - duty) by the hardware internally. Given this hardware limitation, the validation check Nicolas introduced does serve a practical purpose. >> + wfhw->offset = rockchip_pwm_v4_round_single(rate, wf->duty_offset_ns); >> + if (!wfhw->period) /* Don't underflow when pwm disabled */ >> + wfhw->offset = 0; >> + else if (wfhw->offset > wfhw->period - wfhw->duty) >> + wfhw->offset = wfhw->period - wfhw->duty; > > You don't enforce wfhw->period >= wfhw->duty, which however seems like a > reasonable restriction. When knowing that you can drop the explicit > check for !wfhw->period and just keep the else-if branch. > >> +} >> [...] >> +static int rockchip_pwm_v4_write_wf(struct pwm_chip *chip, struct pwm_device *pwm, >> + const void *_wfhw) >> +{ >> + struct rockchip_pwm_v4 *pc = to_rockchip_pwm_v4(chip); >> + const struct rockchip_pwm_v4_wf *wfhw = _wfhw; >> + bool was_enabled; >> + int ret; >> + >> + ret = mfpwm_acquire(pc->pwmf); >> + if (ret) >> + return ret; >> + >> + was_enabled = rockchip_pwm_v4_is_enabled(mfpwm_reg_read(pc->pwmf->base, >> + PWMV4_REG_ENABLE)); >> + >> + /* >> + * "But Nicolas", you ask with valid concerns, "why would you enable the >> + * PWM before setting all the parameter registers?" >> + * >> + * Excellent question, Mr. Reader M. Strawman! The RK3576 TRM Part 1 >> + * Section 34.6.3 specifies that this is the intended order of writes. >> + * Doing the PWM_EN and PWM_CLK_EN writes after the params but before >> + * the CTRL_UPDATE_EN, or even after the CTRL_UPDATE_EN, results in >> + * erratic behaviour where repeated turning on and off of the PWM may >> + * not turn it off under all circumstances. This is also why we don't >> + * use relaxed writes; it's not worth the footgun. > > I wonder if it's worth however to delay setting PWMV4_CTRL_UPDATE_EN > until after the clkrate is handled to (maybe) prevent glitches? I agree with your point. For the PWM enable sequence, we should enable the PWM dclk before any register operations. Conversely, when disabling PWM, it's better to carry out dclk disabling only after all register accesses are fully completed. > >> + */ >> + if (wfhw->rate) >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_ENABLE, >> + FIELD_PREP_WM16(PWMV4_EN_BOTH_MASK, >> + PWMV4_EN_BOTH_MASK)); >> + else >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_ENABLE, >> + FIELD_PREP_WM16(PWMV4_EN_BOTH_MASK, 0)); >> + >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_PERIOD, wfhw->period); >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_DUTY, wfhw->duty); >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_OFFSET, wfhw->offset); >> + >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_CTRL, PWMV4_CTRL_CONT_FLAGS); >> + >> + /* Commit new configuration to hardware output. */ >> + mfpwm_reg_write(pc->pwmf->base, PWMV4_REG_ENABLE, >> + PWMV4_CTRL_UPDATE_EN); >> + >> + if (wfhw->rate) { >> + if (!was_enabled) { >> + dev_dbg(&chip->dev, "Enabling PWM output\n"); >> + ret = clk_enable(pc->pwmf->core); >> + if (ret) >> + goto err_mfpwm_release; >> + ret = clk_set_rate_exclusive(pc->pwmf->core, wfhw->rate); >> + if (ret) { >> + clk_disable(pc->pwmf->core); >> + goto err_mfpwm_release; >> + } >> + >> + /* >> + * Output should be on now, acquire device to guarantee >> + * exclusion with other device functions while it's on. >> + * >> + * It's highly unlikely that this fails, as mfpwm has >> + * already been acquired before, and this is just a >> + * usage counter increase. Not worth the added >> + * complexity of clearing the PWMV4_REG_ENABLE again, >> + * especially considering the CTRL_UPDATE_EN behaviour. >> + */ >> + ret = mfpwm_acquire(pc->pwmf); >> + if (ret) { >> + clk_rate_exclusive_put(pc->pwmf->core); >> + clk_disable(pc->pwmf->core); >> + goto err_mfpwm_release; >> + } >> + } > > Can it happen that we have > > wfhw->rate && was_enabled && wfhw->rate != clk_get_rate() > > ? > >> + } else if (was_enabled) { >> + dev_dbg(&chip->dev, "Disabling PWM output\n"); >> + clk_rate_exclusive_put(pc->pwmf->core); >> + clk_disable(pc->pwmf->core); >> + /* Output is off now, extra release to balance extra acquire */ >> + mfpwm_release(pc->pwmf); >> + } >> + >> +err_mfpwm_release: >> + mfpwm_release(pc->pwmf); >> + >> + return ret; >> +} >> [...] >> +static int rockchip_pwm_v4_probe(struct platform_device *pdev) >> +{ >> + struct rockchip_mfpwm_func *pwmf = dev_get_platdata(&pdev->dev); >> + struct rockchip_pwm_v4 *pc; >> + struct pwm_chip *chip; >> + struct device *dev = &pdev->dev; >> + int ret; >> + >> + /* >> + * For referencing the PWM in the DT to work, we need the parent MFD >> + * device's OF node. >> + */ >> + dev->of_node_reused = true; >> + device_set_node(dev, of_fwnode_handle(dev->parent->of_node)); >> + >> + chip = devm_pwmchip_alloc(dev, 1, sizeof(*pc)); >> + if (IS_ERR(chip)) >> + return PTR_ERR(chip); >> + >> + pc = to_rockchip_pwm_v4(chip); >> + pc->pwmf = pwmf; >> + >> + ret = mfpwm_acquire(pwmf); >> + if (ret) >> + return dev_err_probe(dev, ret, "Couldn't acquire mfpwm in probe\n"); >> + >> + if (!rockchip_pwm_v4_on_and_continuous(pc)) >> + mfpwm_release(pwmf); >> + else { >> + dev_dbg(dev, "PWM was already on at probe time\n"); >> + ret = clk_enable(pwmf->core); >> + if (ret) { >> + dev_err_probe(dev, ret, "Enabling pwm clock failed\n"); >> + goto err_mfpwm_release; >> + } >> + ret = clk_rate_exclusive_get(pc->pwmf->core); >> + if (ret) { >> + dev_err_probe(dev, ret, "Protecting pwm clock failed\n"); >> + goto err_clk_disable; >> + } >> + } >> + >> + platform_set_drvdata(pdev, chip); > > This is unused. > >> + >> + chip->ops = &rockchip_pwm_v4_ops; >> + >> + ret = devm_pwmchip_add(dev, chip); >> + if (ret) { >> + dev_err_probe(dev, ret, "Failed to add PWM chip\n"); >> + if (rockchip_pwm_v4_on_and_continuous(pc)) >> + goto err_rate_put; >> + >> + return ret; >> + } >> + >> + return 0; >> + >> +err_rate_put: >> + clk_rate_exclusive_put(pwmf->core); >> +err_clk_disable: >> + clk_disable(pwmf->core); >> +err_mfpwm_release: >> + mfpwm_release(pwmf); >> + >> + return ret; >> +} > > Best regards > Uwe Best regards, Damon 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 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 smtp.lore.kernel.org (Postfix) with ESMTPS id C5B0DC44512 for ; Fri, 17 Jul 2026 02:38:26 +0000 (UTC) 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:From:References:Cc:To:Subject: MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=E11C2IW/IszGIuH+iXi3YlKbZv0Mfev01uhkhsuiHvo=; b=t+UWZnJMmGyatO m3jBLFZmPHFNsul8ayfsADiAvMGLbuBMLug1mIv6ZzLegMdh5Fna4KFRaIid+p6OuIXfzMYTXqIrq itRh0ojYwMf7G4LfrmzPoMVI+kfrndDpj0BMaIeyEXBA9joy32x8sx75bCus5Cfl31W4McxlZ084p 8fwmluDxZnIk+xVYQhgLWVfcjvtRL0hVqnGcSiUBPCnLluwvaYIXNwdxBOK/4goPyhn27/Oj1giCS EjrswBiRAm4s4PjWEX52AV+glrnd1qF0ifrsbslJ/IO+2AqrWkfjUBC8k/rXrAGO0bv1cmwDo2nNY tHeZcZsxwFR/oMwRL5xA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wkYT0-00000000yn4-1gXY; Fri, 17 Jul 2026 02:38:22 +0000 Received: from mail-m1010.netease.com ([154.81.10.10]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wkYSx-00000000ymO-2fU8; Fri, 17 Jul 2026 02:38:21 +0000 Received: from [172.16.12.74] (unknown [61.154.14.86]) by smtp.qiye.163.com (Hmail) with ESMTP id 46859c9bd; Fri, 17 Jul 2026 10:38:08 +0800 (GMT+08:00) Message-ID: Date: Fri, 17 Jul 2026 10:38:08 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v5 3/6] pwm: Add rockchip PWMv4 driver To: =?UTF-8?Q?Uwe_Kleine-K=C3=B6nig?= , Nicolas Frattaroli Cc: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Lee Jones , William Breathitt Gray , kernel@collabora.com, Jonas Karlman , Alexey Charkov , linux-rockchip@lists.infradead.org, linux-pwm@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org References: <20260420-rk3576-pwm-v5-0-ae7cfbbe5427@collabora.com> <20260420-rk3576-pwm-v5-3-ae7cfbbe5427@collabora.com> Content-Language: en-US From: Damon Ding In-Reply-To: X-HM-Tid: 0a9f6df03d4603a8kunmde6ff62349f89 X-HM-MType: 1 X-HM-Spam-Status: e1kfGhgUHx5ZQUpXWQgPGg8OCBgUHx5ZQUlOS1dZFg8aDwILHllBWSg2Ly tZV1koWUFITzdXWRgWCB1ZQUpXWS1ZQUlXWQ8JGhUIEh9ZQVlDHxpDVktOQ01PQ0lJGBpNGlYVFA kWGhdVEwETFhoSFyQUDg9ZV1kYEgtZQVlNSlVKTk9VSk9VQ01ZV1kWGg8SFR0UWUFZT0tIVUpLSU 9PT0hVSktLVUpCS0tZBg++ DKIM-Signature: a=rsa-sha256; b=XgfBY9TygDAgGW+TnQhdKri9XOCiteJldFJIFc92VlZOH4m4c8Hrv1MuWydsFFtdFO+0ihNUUH4V/uzVZrx3GNcsycjs/F7cIEOxM1QmBpvQSJKfgAWTtKZbKDUy4bb2SLkMb27wtSpy+GBP0okIG6SC13XlC9URiLwuQDHxgW4=; c=relaxed/relaxed; s=default; d=rock-chips.com; v=1; bh=4+trae873noI6M/KTwB+mA2F5xNHhg6Nh9ODu1W4DXc=; h=date:mime-version:subject:message-id:from; X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260716_193820_250092_9C3FA1A1 X-CRM114-Status: GOOD ( 28.78 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms 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-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org SGkgVXdlLAoKT24gNy8xMC8yMDI2IDc6MDIgUE0sIFV3ZSBLbGVpbmUtS8O2bmlnIHdyb3RlOgo+ IEhlbGxvIE5pY29sYXMsCj4gCj4gT24gTW9uLCBBcHIgMjAsIDIwMjYgYXQgMDM6NTI6NDBQTSAr MDIwMCwgTmljb2xhcyBGcmF0dGFyb2xpIHdyb3RlOgo+PiBbLi4uXQo+PiArLyoqCj4+ICsgKiBy b2NrY2hpcF9wd21fdjRfcm91bmRfc2luZ2xlIC0gY29udmVydCBhIFBXTSBwYXJhbWV0ZXIgdG8g aGFyZHdhcmUKPj4gKyAqIEByYXRlOiBjbG9jayByYXRlIG9mIHRoZSBQV00gY2xvY2ssIGFzIHBl ciBjbGtfZ2V0X3JhdGUKPj4gKyAqICAgICAgICBBc3N1bWVkIHRvIGJlIDw9IDFHSHogZm9yIG92 ZXJmbG93IGNvbnNpZGVyYXRpb25zCj4+ICsgKiBAaW5fdmFsOiBwYXJhbWV0ZXIgaW4gbmFub3Nl Y29uZHMgdG8gY29udmVydAo+PiArICoKPj4gKyAqIFJldHVybnMgdGhlIHJvdW5kZWQgdmFsdWUs IHNhdHVyYXRpbmcgYXQgVTMyX01BWCBpZiB0b28gbGFyZ2UKPj4gKyAqLwo+PiArc3RhdGljIHUz MiByb2NrY2hpcF9wd21fdjRfcm91bmRfc2luZ2xlKHVuc2lnbmVkIGxvbmcgcmF0ZSwgdTY0IGlu X3ZhbCkKPiAKPiB2ZXJ5IHBpY2t5OiBpZiB5b3UgbmFtZSB0aGlzIGZ1bmN0aW9uIHJvY2tjaGlw X3B3bV92NF9uc190b190aWNrcyBpdAo+IGJlY29tZXMgY2xlYXJlciB3aGF0IHRoZSBwdXJwb3Nl IGlzLgo+IAo+PiArewo+PiArCXU2NCB0bXA7Cj4+ICsKPj4gKwl0bXAgPSBtdWxfdTY0X3U2NF9k aXZfdTY0KHJhdGUsIGluX3ZhbCwgTlNFQ19QRVJfU0VDKTsKPj4gKwlpZiAodG1wID4gVTMyX01B WCkKPj4gKwkJdG1wID0gVTMyX01BWDsKPj4gKwo+PiArCXJldHVybiB0bXA7Cj4+ICt9Cj4+ICsK Pj4gKy8qKgo+PiArICogcm9ja2NoaXBfcHdtX3Y0X3JvdW5kX3BhcmFtcyAtIGNvbnZlcnQgUFdN IHBhcmFtZXRlcnMgdG8gaGFyZHdhcmUKPj4gKyAqIEByYXRlOiBQV00gY2xvY2sgcmF0ZSB0byBk byB0aGUgY2FsY3VsYXRpb25zIGF0Cj4+ICsgKiBAd2Y6IHBvaW50ZXIgdG8gdGhlIGdlbmVyaWMg JnN0cnVjdCBwd21fd2F2ZWZvcm0gaW5wdXQgcGFyYW1ldGVycwo+PiArICogQHdmaHc6IHBvaW50 ZXIgdG8gdGhlIGhhcmR3YXJlLXNwZWNpZmljICZzdHJ1Y3Qgcm9ja2NoaXBfcHdtX3Y0X3dmIG91 dHB1dAo+PiArICogICAgICAgIHBhcmFtZXRlcnMgdGhhdCB0aGUgcmVzdWx0cyB3aWxsIGJlIHN0 b3JlZCBpbgo+PiArICoKPj4gKyAqIENvbnZlcnQgbmFub3NlY29uZC1iYXNlZCBkdXR5L3Blcmlv ZC9vZmZzZXQgcGFyYW1ldGVycyB0byB0aGUgUFdNIGhhcmR3YXJlJ3MKPj4gKyAqIG5hdGl2ZSBy b3VuZGVkIHJlcHJlc2VudGF0aW9uIGluIG51bWJlciBvZiBjeWNsZXMgYXQgY2xvY2sgcmF0ZSBA cmF0ZS4gU2hvdWxkCj4+ICsgKiBhbnkgb2YgdGhlIGlucHV0IHBhcmFtZXRlcnMgYmUgb3V0IG9m IHJhbmdlIGZvciB0aGUgaGFyZHdhcmUsIHRoZQo+PiArICogY29ycmVzcG9uZGluZyBvdXRwdXQg cGFyYW1ldGVyIGlzIHRoZSBtYXhpbXVtIHBlcm1pc3NpYmxlIHZhbHVlIGZvciBzYWlkCj4+ICsg KiBwYXJhbWV0ZXIgd2l0aCBjb25zaWRlcmF0aW9ucyB0byB0aGUgb3RoZXJzLgo+PiArICovCj4+ ICtzdGF0aWMgdm9pZCByb2NrY2hpcF9wd21fdjRfcm91bmRfcGFyYW1zKHVuc2lnbmVkIGxvbmcg cmF0ZSwKPj4gKwkJCQkJIGNvbnN0IHN0cnVjdCBwd21fd2F2ZWZvcm0gKndmLAo+PiArCQkJCQkg c3RydWN0IHJvY2tjaGlwX3B3bV92NF93ZiAqd2ZodykKPj4gK3sKPj4gKwl3Zmh3LT5wZXJpb2Qg PSByb2NrY2hpcF9wd21fdjRfcm91bmRfc2luZ2xlKHJhdGUsIHdmLT5wZXJpb2RfbGVuZ3RoX25z KTsKPj4gKwo+PiArCXdmaHctPmR1dHkgPSByb2NrY2hpcF9wd21fdjRfcm91bmRfc2luZ2xlKHJh dGUsIHdmLT5kdXR5X2xlbmd0aF9ucyk7Cj4+ICsKPj4gKwkvKiBBcyBwZXIgVFJNLCBQV01fT0ZG U0VUOiAiVGhlIHZhbHVlIHJhbmdlcyBmcm9tIDAgdG8gKHBlcmlvZC1kdXR5KSIgKi8KPiAKPiBI YXZlIHlvdSB0cmllZCB3aGF0IGhhcHBlbnMgaWYgeW91IGJyZWFrIHRoaXMgcnVsZT8gVGhhdCBz ZWVtcyBsaWtlIGEKPiB2ZXJ5IGFyYml0cmFyeSByZXN0cmljdGlvbiB0aGF0IG1pZ2h0IGp1c3Qg b3JpZ2luYXRlIGZyb20gdGhlCj4gZG9jdW1lbnRhdGlvbiBhdXRob3IuCj4gCgpBY2NvcmRpbmcg dG8gdGhlIElDIGRlc2lnbiwgYW55IG9mZnNldCB2YWx1ZSBsYXJnZXIgdGhhbiAocGVyaW9kIC0g ZHV0eSkgCndpbGwgYmUgY2xhbXBlZCB0byAocGVyaW9kIC0gZHV0eSkgYnkgdGhlIGhhcmR3YXJl IGludGVybmFsbHkuIEdpdmVuIAp0aGlzIGhhcmR3YXJlIGxpbWl0YXRpb24sIHRoZSB2YWxpZGF0 aW9uIGNoZWNrIE5pY29sYXMgaW50cm9kdWNlZCBkb2VzIApzZXJ2ZSBhIHByYWN0aWNhbCBwdXJw b3NlLgoKPj4gKwl3Zmh3LT5vZmZzZXQgPSByb2NrY2hpcF9wd21fdjRfcm91bmRfc2luZ2xlKHJh dGUsIHdmLT5kdXR5X29mZnNldF9ucyk7Cj4+ICsJaWYgKCF3Zmh3LT5wZXJpb2QpIC8qIERvbid0 IHVuZGVyZmxvdyB3aGVuIHB3bSBkaXNhYmxlZCAqLwo+PiArCQl3Zmh3LT5vZmZzZXQgPSAwOwo+ PiArCWVsc2UgaWYgKHdmaHctPm9mZnNldCA+IHdmaHctPnBlcmlvZCAtIHdmaHctPmR1dHkpCj4+ ICsJCXdmaHctPm9mZnNldCA9IHdmaHctPnBlcmlvZCAtIHdmaHctPmR1dHk7Cj4gCj4gWW91IGRv bid0IGVuZm9yY2Ugd2Zody0+cGVyaW9kID49IHdmaHctPmR1dHksIHdoaWNoIGhvd2V2ZXIgc2Vl bXMgbGlrZSBhCj4gcmVhc29uYWJsZSByZXN0cmljdGlvbi4gV2hlbiBrbm93aW5nIHRoYXQgeW91 IGNhbiBkcm9wIHRoZSBleHBsaWNpdAo+IGNoZWNrIGZvciAhd2Zody0+cGVyaW9kIGFuZCBqdXN0 IGtlZXAgdGhlIGVsc2UtaWYgYnJhbmNoLgo+IAo+PiArfQo+PiBbLi4uXQo+PiArc3RhdGljIGlu dCByb2NrY2hpcF9wd21fdjRfd3JpdGVfd2Yoc3RydWN0IHB3bV9jaGlwICpjaGlwLCBzdHJ1Y3Qg cHdtX2RldmljZSAqcHdtLAo+PiArCQkJCSAgICBjb25zdCB2b2lkICpfd2ZodykKPj4gK3sKPj4g KwlzdHJ1Y3Qgcm9ja2NoaXBfcHdtX3Y0ICpwYyA9IHRvX3JvY2tjaGlwX3B3bV92NChjaGlwKTsK Pj4gKwljb25zdCBzdHJ1Y3Qgcm9ja2NoaXBfcHdtX3Y0X3dmICp3Zmh3ID0gX3dmaHc7Cj4+ICsJ Ym9vbCB3YXNfZW5hYmxlZDsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJcmV0ID0gbWZwd21fYWNx dWlyZShwYy0+cHdtZik7Cj4+ICsJaWYgKHJldCkKPj4gKwkJcmV0dXJuIHJldDsKPj4gKwo+PiAr CXdhc19lbmFibGVkID0gcm9ja2NoaXBfcHdtX3Y0X2lzX2VuYWJsZWQobWZwd21fcmVnX3JlYWQo cGMtPnB3bWYtPmJhc2UsCj4+ICsJCQkJCQkJCVBXTVY0X1JFR19FTkFCTEUpKTsKPj4gKwo+PiAr CS8qCj4+ICsJICogIkJ1dCBOaWNvbGFzIiwgeW91IGFzayB3aXRoIHZhbGlkIGNvbmNlcm5zLCAi d2h5IHdvdWxkIHlvdSBlbmFibGUgdGhlCj4+ICsJICogUFdNIGJlZm9yZSBzZXR0aW5nIGFsbCB0 aGUgcGFyYW1ldGVyIHJlZ2lzdGVycz8iCj4+ICsJICoKPj4gKwkgKiBFeGNlbGxlbnQgcXVlc3Rp b24sIE1yLiBSZWFkZXIgTS4gU3RyYXdtYW4hIFRoZSBSSzM1NzYgVFJNIFBhcnQgMQo+PiArCSAq IFNlY3Rpb24gMzQuNi4zIHNwZWNpZmllcyB0aGF0IHRoaXMgaXMgdGhlIGludGVuZGVkIG9yZGVy IG9mIHdyaXRlcy4KPj4gKwkgKiBEb2luZyB0aGUgUFdNX0VOIGFuZCBQV01fQ0xLX0VOIHdyaXRl cyBhZnRlciB0aGUgcGFyYW1zIGJ1dCBiZWZvcmUKPj4gKwkgKiB0aGUgQ1RSTF9VUERBVEVfRU4s IG9yIGV2ZW4gYWZ0ZXIgdGhlIENUUkxfVVBEQVRFX0VOLCByZXN1bHRzIGluCj4+ICsJICogZXJy YXRpYyBiZWhhdmlvdXIgd2hlcmUgcmVwZWF0ZWQgdHVybmluZyBvbiBhbmQgb2ZmIG9mIHRoZSBQ V00gbWF5Cj4+ICsJICogbm90IHR1cm4gaXQgb2ZmIHVuZGVyIGFsbCBjaXJjdW1zdGFuY2VzLiBU aGlzIGlzIGFsc28gd2h5IHdlIGRvbid0Cj4+ICsJICogdXNlIHJlbGF4ZWQgd3JpdGVzOyBpdCdz IG5vdCB3b3J0aCB0aGUgZm9vdGd1bi4KPiAKPiBJIHdvbmRlciBpZiBpdCdzIHdvcnRoIGhvd2V2 ZXIgdG8gZGVsYXkgc2V0dGluZyBQV01WNF9DVFJMX1VQREFURV9FTgo+IHVudGlsIGFmdGVyIHRo ZSBjbGtyYXRlIGlzIGhhbmRsZWQgdG8gKG1heWJlKSBwcmV2ZW50IGdsaXRjaGVzPwoKSSBhZ3Jl ZSB3aXRoIHlvdXIgcG9pbnQuIEZvciB0aGUgUFdNIGVuYWJsZSBzZXF1ZW5jZSwgd2Ugc2hvdWxk IGVuYWJsZSAKdGhlIFBXTSBkY2xrIGJlZm9yZSBhbnkgcmVnaXN0ZXIgb3BlcmF0aW9ucy4gQ29u dmVyc2VseSwgd2hlbiBkaXNhYmxpbmcgClBXTSwgaXQncyBiZXR0ZXIgdG8gY2Fycnkgb3V0IGRj bGsgZGlzYWJsaW5nIG9ubHkgYWZ0ZXIgYWxsIHJlZ2lzdGVyIAphY2Nlc3NlcyBhcmUgZnVsbHkg Y29tcGxldGVkLgoKPiAKPj4gKwkgKi8KPj4gKwlpZiAod2Zody0+cmF0ZSkKPj4gKwkJbWZwd21f cmVnX3dyaXRlKHBjLT5wd21mLT5iYXNlLCBQV01WNF9SRUdfRU5BQkxFLAo+PiArCQkJCUZJRUxE X1BSRVBfV00xNihQV01WNF9FTl9CT1RIX01BU0ssCj4+ICsJCQkJCQlQV01WNF9FTl9CT1RIX01B U0spKTsKPj4gKwllbHNlCj4+ICsJCW1mcHdtX3JlZ193cml0ZShwYy0+cHdtZi0+YmFzZSwgUFdN VjRfUkVHX0VOQUJMRSwKPj4gKwkJCQlGSUVMRF9QUkVQX1dNMTYoUFdNVjRfRU5fQk9USF9NQVNL LCAwKSk7Cj4+ICsKPj4gKwltZnB3bV9yZWdfd3JpdGUocGMtPnB3bWYtPmJhc2UsIFBXTVY0X1JF R19QRVJJT0QsIHdmaHctPnBlcmlvZCk7Cj4+ICsJbWZwd21fcmVnX3dyaXRlKHBjLT5wd21mLT5i YXNlLCBQV01WNF9SRUdfRFVUWSwgd2Zody0+ZHV0eSk7Cj4+ICsJbWZwd21fcmVnX3dyaXRlKHBj LT5wd21mLT5iYXNlLCBQV01WNF9SRUdfT0ZGU0VULCB3Zmh3LT5vZmZzZXQpOwo+PiArCj4+ICsJ bWZwd21fcmVnX3dyaXRlKHBjLT5wd21mLT5iYXNlLCBQV01WNF9SRUdfQ1RSTCwgUFdNVjRfQ1RS TF9DT05UX0ZMQUdTKTsKPj4gKwo+PiArCS8qIENvbW1pdCBuZXcgY29uZmlndXJhdGlvbiB0byBo YXJkd2FyZSBvdXRwdXQuICovCj4+ICsJbWZwd21fcmVnX3dyaXRlKHBjLT5wd21mLT5iYXNlLCBQ V01WNF9SRUdfRU5BQkxFLAo+PiArCQkJUFdNVjRfQ1RSTF9VUERBVEVfRU4pOwo+PiArCj4+ICsJ aWYgKHdmaHctPnJhdGUpIHsKPj4gKwkJaWYgKCF3YXNfZW5hYmxlZCkgewo+PiArCQkJZGV2X2Ri ZygmY2hpcC0+ZGV2LCAiRW5hYmxpbmcgUFdNIG91dHB1dFxuIik7Cj4+ICsJCQlyZXQgPSBjbGtf ZW5hYmxlKHBjLT5wd21mLT5jb3JlKTsKPj4gKwkJCWlmIChyZXQpCj4+ICsJCQkJZ290byBlcnJf bWZwd21fcmVsZWFzZTsKPj4gKwkJCXJldCA9IGNsa19zZXRfcmF0ZV9leGNsdXNpdmUocGMtPnB3 bWYtPmNvcmUsIHdmaHctPnJhdGUpOwo+PiArCQkJaWYgKHJldCkgewo+PiArCQkJCWNsa19kaXNh YmxlKHBjLT5wd21mLT5jb3JlKTsKPj4gKwkJCQlnb3RvIGVycl9tZnB3bV9yZWxlYXNlOwo+PiAr CQkJfQo+PiArCj4+ICsJCQkvKgo+PiArCQkJICogT3V0cHV0IHNob3VsZCBiZSBvbiBub3csIGFj cXVpcmUgZGV2aWNlIHRvIGd1YXJhbnRlZQo+PiArCQkJICogZXhjbHVzaW9uIHdpdGggb3RoZXIg ZGV2aWNlIGZ1bmN0aW9ucyB3aGlsZSBpdCdzIG9uLgo+PiArCQkJICoKPj4gKwkJCSAqIEl0J3Mg aGlnaGx5IHVubGlrZWx5IHRoYXQgdGhpcyBmYWlscywgYXMgbWZwd20gaGFzCj4+ICsJCQkgKiBh bHJlYWR5IGJlZW4gYWNxdWlyZWQgYmVmb3JlLCBhbmQgdGhpcyBpcyBqdXN0IGEKPj4gKwkJCSAq IHVzYWdlIGNvdW50ZXIgaW5jcmVhc2UuIE5vdCB3b3J0aCB0aGUgYWRkZWQKPj4gKwkJCSAqIGNv bXBsZXhpdHkgb2YgY2xlYXJpbmcgdGhlIFBXTVY0X1JFR19FTkFCTEUgYWdhaW4sCj4+ICsJCQkg KiBlc3BlY2lhbGx5IGNvbnNpZGVyaW5nIHRoZSBDVFJMX1VQREFURV9FTiBiZWhhdmlvdXIuCj4+ ICsJCQkgKi8KPj4gKwkJCXJldCA9IG1mcHdtX2FjcXVpcmUocGMtPnB3bWYpOwo+PiArCQkJaWYg KHJldCkgewo+PiArCQkJCWNsa19yYXRlX2V4Y2x1c2l2ZV9wdXQocGMtPnB3bWYtPmNvcmUpOwo+ PiArCQkJCWNsa19kaXNhYmxlKHBjLT5wd21mLT5jb3JlKTsKPj4gKwkJCQlnb3RvIGVycl9tZnB3 bV9yZWxlYXNlOwo+PiArCQkJfQo+PiArCQl9Cj4gCj4gQ2FuIGl0IGhhcHBlbiB0aGF0IHdlIGhh dmUKPiAKPiAJd2Zody0+cmF0ZSAmJiB3YXNfZW5hYmxlZCAmJiB3Zmh3LT5yYXRlICE9IGNsa19n ZXRfcmF0ZSgpCj4gCj4gPwo+IAo+PiArCX0gZWxzZSBpZiAod2FzX2VuYWJsZWQpIHsKPj4gKwkJ ZGV2X2RiZygmY2hpcC0+ZGV2LCAiRGlzYWJsaW5nIFBXTSBvdXRwdXRcbiIpOwo+PiArCQljbGtf cmF0ZV9leGNsdXNpdmVfcHV0KHBjLT5wd21mLT5jb3JlKTsKPj4gKwkJY2xrX2Rpc2FibGUocGMt PnB3bWYtPmNvcmUpOwo+PiArCQkvKiBPdXRwdXQgaXMgb2ZmIG5vdywgZXh0cmEgcmVsZWFzZSB0 byBiYWxhbmNlIGV4dHJhIGFjcXVpcmUgKi8KPj4gKwkJbWZwd21fcmVsZWFzZShwYy0+cHdtZik7 Cj4+ICsJfQo+PiArCj4+ICtlcnJfbWZwd21fcmVsZWFzZToKPj4gKwltZnB3bV9yZWxlYXNlKHBj LT5wd21mKTsKPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4+IFsuLi5dCj4+ICtzdGF0aWMg aW50IHJvY2tjaGlwX3B3bV92NF9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ PiArewo+PiArCXN0cnVjdCByb2NrY2hpcF9tZnB3bV9mdW5jICpwd21mID0gZGV2X2dldF9wbGF0 ZGF0YSgmcGRldi0+ZGV2KTsKPj4gKwlzdHJ1Y3Qgcm9ja2NoaXBfcHdtX3Y0ICpwYzsKPj4gKwlz dHJ1Y3QgcHdtX2NoaXAgKmNoaXA7Cj4+ICsJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRl djsKPj4gKwlpbnQgcmV0Owo+PiArCj4+ICsJLyoKPj4gKwkgKiBGb3IgcmVmZXJlbmNpbmcgdGhl IFBXTSBpbiB0aGUgRFQgdG8gd29yaywgd2UgbmVlZCB0aGUgcGFyZW50IE1GRAo+PiArCSAqIGRl dmljZSdzIE9GIG5vZGUuCj4+ICsJICovCj4+ICsJZGV2LT5vZl9ub2RlX3JldXNlZCA9IHRydWU7 Cj4+ICsJZGV2aWNlX3NldF9ub2RlKGRldiwgb2ZfZndub2RlX2hhbmRsZShkZXYtPnBhcmVudC0+ b2Zfbm9kZSkpOwo+PiArCj4+ICsJY2hpcCA9IGRldm1fcHdtY2hpcF9hbGxvYyhkZXYsIDEsIHNp emVvZigqcGMpKTsKPj4gKwlpZiAoSVNfRVJSKGNoaXApKQo+PiArCQlyZXR1cm4gUFRSX0VSUihj aGlwKTsKPj4gKwo+PiArCXBjID0gdG9fcm9ja2NoaXBfcHdtX3Y0KGNoaXApOwo+PiArCXBjLT5w d21mID0gcHdtZjsKPj4gKwo+PiArCXJldCA9IG1mcHdtX2FjcXVpcmUocHdtZik7Cj4+ICsJaWYg KHJldCkKPj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJDb3VsZG4ndCBhY3F1 aXJlIG1mcHdtIGluIHByb2JlXG4iKTsKPj4gKwo+PiArCWlmICghcm9ja2NoaXBfcHdtX3Y0X29u X2FuZF9jb250aW51b3VzKHBjKSkKPj4gKwkJbWZwd21fcmVsZWFzZShwd21mKTsKPj4gKwllbHNl IHsKPj4gKwkJZGV2X2RiZyhkZXYsICJQV00gd2FzIGFscmVhZHkgb24gYXQgcHJvYmUgdGltZVxu Iik7Cj4+ICsJCXJldCA9IGNsa19lbmFibGUocHdtZi0+Y29yZSk7Cj4+ICsJCWlmIChyZXQpIHsK Pj4gKwkJCWRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJFbmFibGluZyBwd20gY2xvY2sgZmFpbGVk XG4iKTsKPj4gKwkJCWdvdG8gZXJyX21mcHdtX3JlbGVhc2U7Cj4+ICsJCX0KPj4gKwkJcmV0ID0g Y2xrX3JhdGVfZXhjbHVzaXZlX2dldChwYy0+cHdtZi0+Y29yZSk7Cj4+ICsJCWlmIChyZXQpIHsK Pj4gKwkJCWRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJQcm90ZWN0aW5nIHB3bSBjbG9jayBmYWls ZWRcbiIpOwo+PiArCQkJZ290byBlcnJfY2xrX2Rpc2FibGU7Cj4+ICsJCX0KPj4gKwl9Cj4+ICsK Pj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBjaGlwKTsKPiAKPiBUaGlzIGlzIHVudXNl ZC4KPiAKPj4gKwo+PiArCWNoaXAtPm9wcyA9ICZyb2NrY2hpcF9wd21fdjRfb3BzOwo+PiArCj4+ ICsJcmV0ID0gZGV2bV9wd21jaGlwX2FkZChkZXYsIGNoaXApOwo+PiArCWlmIChyZXQpIHsKPj4g KwkJZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgIkZhaWxlZCB0byBhZGQgUFdNIGNoaXBcbiIpOwo+ PiArCQlpZiAocm9ja2NoaXBfcHdtX3Y0X29uX2FuZF9jb250aW51b3VzKHBjKSkKPj4gKwkJCWdv dG8gZXJyX3JhdGVfcHV0Owo+PiArCj4+ICsJCXJldHVybiByZXQ7Cj4+ICsJfQo+PiArCj4+ICsJ cmV0dXJuIDA7Cj4+ICsKPj4gK2Vycl9yYXRlX3B1dDoKPj4gKwljbGtfcmF0ZV9leGNsdXNpdmVf cHV0KHB3bWYtPmNvcmUpOwo+PiArZXJyX2Nsa19kaXNhYmxlOgo+PiArCWNsa19kaXNhYmxlKHB3 bWYtPmNvcmUpOwo+PiArZXJyX21mcHdtX3JlbGVhc2U6Cj4+ICsJbWZwd21fcmVsZWFzZShwd21m KTsKPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ICt9Cj4gCj4gQmVzdCByZWdhcmRzCj4gVXdlCgpC ZXN0IHJlZ2FyZHMsCkRhbW9uCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KTGludXgtcm9ja2NoaXAgbWFpbGluZyBsaXN0CkxpbnV4LXJvY2tjaGlwQGxp c3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0 aW5mby9saW51eC1yb2NrY2hpcAo=