From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A601175A5; Mon, 4 Aug 2025 00:32:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754267563; cv=none; b=DNxAuuaEMM0b3jMpVlBANvCXMqccGRlGkQvxGaKwSnHdO59VZcaM8vVCHWl0rnarQZmYRRSYL24XiFULeyesNIm2L9iuFCtdF5stHQ7q9amicqLod4x8B+QAflP7CJ7Iu3clMctH2THY/Ku+/RVDZKPlMDLxisns0yvzI8Y3IXs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754267563; c=relaxed/simple; bh=Bs4/OINydRglnxEUwlgHZgeJZiSHvx3ERL02s0xacnY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=F50MTCG3RLVg4ms3/t/1hUxNo184OJwBKhXyb6DLuX25N7DrZerSz4JJlb9h2F5wOckcc6un6kMO9xM0WKXRQ54YdHbWrXy0d6VdF4tMDINQFY5KQ1NIfnuxd3sJneqmKSypKUvyCaQagE7XfZgGadBMbpe3bkCLv7vcWWVo5Zk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iYfeumTu; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iYfeumTu" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A97DC4CEEB; Mon, 4 Aug 2025 00:32:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754267563; bh=Bs4/OINydRglnxEUwlgHZgeJZiSHvx3ERL02s0xacnY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iYfeumTuxr0kDBT4LD8s1ht4yevttZSZ5ZAklTr659uVaWVMIvinVgLnAOdJryvH+ Ey836D8ecWPfcJMa4fRzNrIz6yIjJ5DHTwSF2ztkO1USYAmqSF9ovbtBk/KQkaWSaC v2kqV8CjUclkV1vrVUvDOoSVAXCS7YRd0AJfCKV9GpyCxzhNx/ummU1yPCiQcjM5ZJ SE76vostJS7twleap4v5GN5Q1MaRj+XYxdVsDrfsOwkg5qRLiKaMCz9OBJO4HC0GZD oGwxkWqYHmsSeScLxNBsQcrMI/ZpXUG9PnwEDYyElnZlBTlEi3DusxbqamwioasotQ XtU5hAq33lkRg== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Nylon Chen , Zong Li , Vincent Chen , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Sasha Levin , paul.walmsley@sifive.com, samuel.holland@sifive.com, linux-pwm@vger.kernel.org, linux-riscv@lists.infradead.org Subject: [PATCH AUTOSEL 6.12 34/69] pwm: sifive: Fix PWM algorithm and clarify inverted compare behavior Date: Sun, 3 Aug 2025 20:30:44 -0400 Message-Id: <20250804003119.3620476-34-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250804003119.3620476-1-sashal@kernel.org> References: <20250804003119.3620476-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-pwm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.12.41 Content-Transfer-Encoding: 8bit From: Nylon Chen [ Upstream commit 7dbc4432ea6bf9d709391eb57f1e9fb44e99845a ] The `frac` variable represents the pulse inactive time, and the result of this algorithm is the pulse active time. Therefore, we must reverse the result. Although the SiFive Reference Manual states "pwms >= pwmcmpX -> HIGH", the hardware behavior is inverted due to a fixed XNOR with 0. As a result, the pwmcmp register actually defines the low (inactive) portion of the pulse. The reference is SiFive FU740-C000 Manual[0] Link: https://sifive.cdn.prismic.io/sifive/1a82e600-1f93-4f41-b2d8-86ed8b16acba_fu740-c000-manual-v1p6.pdf [0] Co-developed-by: Zong Li Signed-off-by: Zong Li Co-developed-by: Vincent Chen Signed-off-by: Vincent Chen Signed-off-by: Nylon Chen Link: https://lore.kernel.org/r/20250529035341.51736-3-nylon.chen@sifive.com Signed-off-by: Uwe Kleine-König Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: **Backport Status: YES** This commit should be backported to stable kernel trees. Here's my extensive analysis: ## Critical Bug Fix Analysis 1. **The commit fixes a significant functional bug** - The PWM algorithm was fundamentally broken: - The `frac` variable was incorrectly used (lines 158-161 in original, now 168-171) - The driver was writing the duty cycle value directly to PWMCMP register (line 193), but the hardware actually expects the **inactive** (low) time - This results in inverted PWM output behavior where users get the opposite duty cycle from what they request 2. **Hardware behavior discrepancy** - The commit reveals and fixes a critical mismatch between documentation and actual hardware: - The documentation states "pwms >= pwmcmpX -> HIGH" - But the hardware has a hard-tied XNOR with 0 that inverts this behavior - The driver now correctly compensates for this hardware quirk 3. **User-visible impact**: - **In `pwm_sifive_get_state()`**: The driver now correctly inverts the value read from hardware (lines 115->122-126) - **In `pwm_sifive_apply()`**: The driver now inverts the duty cycle before writing to hardware (lines 162->171) - **Polarity change**: Changed from `PWM_POLARITY_INVERSED` to `PWM_POLARITY_NORMAL` (lines 126->137, 142->152) - **Documentation fix**: Updated comment from "cannot generate 100% duty" to "cannot generate 0% duty" (lines 11->27, 160->170) 4. **The fix is relatively small and contained**: - Changes are isolated to the PWM algorithm logic - No architectural changes or new features - Simple mathematical inversion: `duty = (1U << PWM_SIFIVE_CMPWIDTH) - 1 - inactive` 5. **No risky side effects**: - The change is straightforward and mathematically correct - Doesn't affect other subsystems - Maintains the same register interface 6. **Affects all SiFive PWM users**: - Any system using SiFive FU540 or FU740 SoCs would have incorrect PWM output - This includes various RISC-V development boards and embedded systems - Users would get inverted duty cycles, potentially breaking motor controls, LED dimming, etc. 7. **Clear documentation reference**: - The commit references the official SiFive FU740-C000 Manual - Provides clear explanation of the hardware behavior mismatch The bug causes PWM outputs to be inverted from user expectations, which is a significant functional issue that would affect any system relying on proper PWM behavior for motor control, LED dimming, or other PWM- dependent functionality. The fix is clean, minimal, and addresses a clear hardware/software mismatch that exists in production systems. drivers/pwm/pwm-sifive.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/pwm/pwm-sifive.c b/drivers/pwm/pwm-sifive.c index d5b647e6be78..f3694801d3ee 100644 --- a/drivers/pwm/pwm-sifive.c +++ b/drivers/pwm/pwm-sifive.c @@ -4,11 +4,28 @@ * For SiFive's PWM IP block documentation please refer Chapter 14 of * Reference Manual : https://static.dev.sifive.com/FU540-C000-v1.0.pdf * + * PWM output inversion: According to the SiFive Reference manual + * the output of each comparator is high whenever the value of pwms is + * greater than or equal to the corresponding pwmcmpX[Reference Manual]. + * + * Figure 29 in the same manual shows that the pwmcmpXcenter bit is + * hard-tied to 0 (XNOR), which effectively inverts the comparison so that + * the output goes HIGH when `pwms < pwmcmpX`. + * + * In other words, each pwmcmp register actually defines the **inactive** + * (low) period of the pulse, not the active time exactly opposite to what + * the documentation text implies. + * + * To compensate, this driver always **inverts** the duty value when reading + * or writing pwmcmp registers , so that users interact with a conventional + * **active-high** PWM interface. + * + * * Limitations: * - When changing both duty cycle and period, we cannot prevent in * software that the output might produce a period with mixed * settings (new period length and old duty cycle). - * - The hardware cannot generate a 100% duty cycle. + * - The hardware cannot generate a 0% duty cycle. * - The hardware generates only inverted output. */ #include @@ -110,9 +127,14 @@ static int pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { struct pwm_sifive_ddata *ddata = pwm_sifive_chip_to_ddata(chip); - u32 duty, val; + u32 duty, val, inactive; - duty = readl(ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm)); + inactive = readl(ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm)); + /* + * PWM hardware uses 'inactive' counts in pwmcmp, so invert to get actual duty. + * Here, 'inactive' is the low time and we compute duty as max_count - inactive. + */ + duty = (1U << PWM_SIFIVE_CMPWIDTH) - 1 - inactive; state->enabled = duty > 0; @@ -123,7 +145,7 @@ static int pwm_sifive_get_state(struct pwm_chip *chip, struct pwm_device *pwm, state->period = ddata->real_period; state->duty_cycle = (u64)duty * ddata->real_period >> PWM_SIFIVE_CMPWIDTH; - state->polarity = PWM_POLARITY_INVERSED; + state->polarity = PWM_POLARITY_NORMAL; return 0; } @@ -137,9 +159,9 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long long num; bool enabled; int ret = 0; - u32 frac; + u32 frac, inactive; - if (state->polarity != PWM_POLARITY_INVERSED) + if (state->polarity != PWM_POLARITY_NORMAL) return -EINVAL; cur_state = pwm->state; @@ -157,8 +179,9 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, */ num = (u64)duty_cycle * (1U << PWM_SIFIVE_CMPWIDTH); frac = DIV64_U64_ROUND_CLOSEST(num, state->period); - /* The hardware cannot generate a 100% duty cycle */ + /* The hardware cannot generate a 0% duty cycle */ frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1); + inactive = (1U << PWM_SIFIVE_CMPWIDTH) - 1 - frac; mutex_lock(&ddata->lock); if (state->period != ddata->approx_period) { @@ -190,7 +213,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm, } } - writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm)); + writel(inactive, ddata->regs + PWM_SIFIVE_PWMCMP(pwm->hwpwm)); if (!state->enabled) clk_disable(ddata->clk); -- 2.39.5 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 247BEC87FCA for ; Mon, 4 Aug 2025 01:15:43 +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-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ptnfODGDimtqsgsRSPj27Ka4dezvXZwklYts/E9ctIE=; b=esVyEnEJTqBCPM juGKvO0QUL3RhJK4/c0wSoGHgNyx+IcTsqvn8Yn9/NdTVU32TDi5yz614Y4Cz23RO1j38s85c0r5v agov64771av1p5HxtsXG6frW14Sm/GkvyJrANvyv+YljyXoypppebCO9jV/u4MePfcTN7at/EItJ3 SLAhKo+3xR6h0OtpS8JuQ/W0JuydOMQQ+Dhc+tQEUHHmI8VKpknaIkGaDPSjl5BilrsPBdScVprCl QYM7+IqKeW2Jh3yJfeTE3MOibDfc53Ap7tGlVEnF/daRn8SRTA/c8T2i8nTkcgsqldvM23mrDYvvA +PkE8YeEdX3dL+kCW9+A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uijnc-00000009PGf-0mPm; Mon, 04 Aug 2025 01:15:36 +0000 Received: from nyc.source.kernel.org ([2604:1380:45d1:ec00::3]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uij88-00000009Ldu-185D for linux-riscv@lists.infradead.org; Mon, 04 Aug 2025 00:32:45 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id 5D071A4278E; Mon, 4 Aug 2025 00:32:43 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A97DC4CEEB; Mon, 4 Aug 2025 00:32:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754267563; bh=Bs4/OINydRglnxEUwlgHZgeJZiSHvx3ERL02s0xacnY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iYfeumTuxr0kDBT4LD8s1ht4yevttZSZ5ZAklTr659uVaWVMIvinVgLnAOdJryvH+ Ey836D8ecWPfcJMa4fRzNrIz6yIjJ5DHTwSF2ztkO1USYAmqSF9ovbtBk/KQkaWSaC v2kqV8CjUclkV1vrVUvDOoSVAXCS7YRd0AJfCKV9GpyCxzhNx/ummU1yPCiQcjM5ZJ SE76vostJS7twleap4v5GN5Q1MaRj+XYxdVsDrfsOwkg5qRLiKaMCz9OBJO4HC0GZD oGwxkWqYHmsSeScLxNBsQcrMI/ZpXUG9PnwEDYyElnZlBTlEi3DusxbqamwioasotQ XtU5hAq33lkRg== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: Nylon Chen , Zong Li , Vincent Chen , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Sasha Levin , paul.walmsley@sifive.com, samuel.holland@sifive.com, linux-pwm@vger.kernel.org, linux-riscv@lists.infradead.org Subject: [PATCH AUTOSEL 6.12 34/69] pwm: sifive: Fix PWM algorithm and clarify inverted compare behavior Date: Sun, 3 Aug 2025 20:30:44 -0400 Message-Id: <20250804003119.3620476-34-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250804003119.3620476-1-sashal@kernel.org> References: <20250804003119.3620476-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.12.41 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250803_173244_430989_56D2BB2A X-CRM114-Status: GOOD ( 20.42 ) X-BeenThere: linux-riscv@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-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org RnJvbTogTnlsb24gQ2hlbiA8bnlsb24uY2hlbkBzaWZpdmUuY29tPgoKWyBVcHN0cmVhbSBjb21t aXQgN2RiYzQ0MzJlYTZiZjlkNzA5MzkxZWI1N2YxZTlmYjQ0ZTk5ODQ1YSBdCgpUaGUgYGZyYWNg IHZhcmlhYmxlIHJlcHJlc2VudHMgdGhlIHB1bHNlIGluYWN0aXZlIHRpbWUsIGFuZCB0aGUgcmVz dWx0Cm9mIHRoaXMgYWxnb3JpdGhtIGlzIHRoZSBwdWxzZSBhY3RpdmUgdGltZS4gVGhlcmVmb3Jl LCB3ZSBtdXN0IHJldmVyc2UKdGhlIHJlc3VsdC4KCkFsdGhvdWdoIHRoZSBTaUZpdmUgUmVmZXJl bmNlIE1hbnVhbCBzdGF0ZXMgInB3bXMgPj0gcHdtY21wWCAtPiBISUdIIiwKdGhlIGhhcmR3YXJl IGJlaGF2aW9yIGlzIGludmVydGVkIGR1ZSB0byBhIGZpeGVkIFhOT1Igd2l0aCAwLiBBcyBhIHJl c3VsdCwKdGhlIHB3bWNtcCByZWdpc3RlciBhY3R1YWxseSBkZWZpbmVzIHRoZSBsb3cgKGluYWN0 aXZlKSBwb3J0aW9uIG9mIHRoZSBwdWxzZS4KClRoZSByZWZlcmVuY2UgaXMgU2lGaXZlIEZVNzQw LUMwMDAgTWFudWFsWzBdCgpMaW5rOiBodHRwczovL3NpZml2ZS5jZG4ucHJpc21pYy5pby9zaWZp dmUvMWE4MmU2MDAtMWY5My00ZjQxLWIyZDgtODZlZDhiMTZhY2JhX2Z1NzQwLWMwMDAtbWFudWFs LXYxcDYucGRmIFswXQoKQ28tZGV2ZWxvcGVkLWJ5OiBab25nIExpIDx6b25nLmxpQHNpZml2ZS5j b20+ClNpZ25lZC1vZmYtYnk6IFpvbmcgTGkgPHpvbmcubGlAc2lmaXZlLmNvbT4KQ28tZGV2ZWxv cGVkLWJ5OiBWaW5jZW50IENoZW4gPHZpbmNlbnQuY2hlbkBzaWZpdmUuY29tPgpTaWduZWQtb2Zm LWJ5OiBWaW5jZW50IENoZW4gPHZpbmNlbnQuY2hlbkBzaWZpdmUuY29tPgpTaWduZWQtb2ZmLWJ5 OiBOeWxvbiBDaGVuIDxueWxvbi5jaGVuQHNpZml2ZS5jb20+Ckxpbms6IGh0dHBzOi8vbG9yZS5r ZXJuZWwub3JnL3IvMjAyNTA1MjkwMzUzNDEuNTE3MzYtMy1ueWxvbi5jaGVuQHNpZml2ZS5jb20K U2lnbmVkLW9mZi1ieTogVXdlIEtsZWluZS1Lw7ZuaWcgPHVrbGVpbmVrQGtlcm5lbC5vcmc+ClNp Z25lZC1vZmYtYnk6IFNhc2hhIExldmluIDxzYXNoYWxAa2VybmVsLm9yZz4KLS0tCgpMTE0gR2Vu ZXJhdGVkIGV4cGxhbmF0aW9ucywgbWF5IGJlIGNvbXBsZXRlbHkgYm9ndXM6CgoqKkJhY2twb3J0 IFN0YXR1czogWUVTKioKClRoaXMgY29tbWl0IHNob3VsZCBiZSBiYWNrcG9ydGVkIHRvIHN0YWJs ZSBrZXJuZWwgdHJlZXMuIEhlcmUncyBteQpleHRlbnNpdmUgYW5hbHlzaXM6CgojIyBDcml0aWNh bCBCdWcgRml4IEFuYWx5c2lzCgoxLiAqKlRoZSBjb21taXQgZml4ZXMgYSBzaWduaWZpY2FudCBm dW5jdGlvbmFsIGJ1ZyoqIC0gVGhlIFBXTSBhbGdvcml0aG0KICAgd2FzIGZ1bmRhbWVudGFsbHkg YnJva2VuOgogICAtIFRoZSBgZnJhY2AgdmFyaWFibGUgd2FzIGluY29ycmVjdGx5IHVzZWQgKGxp bmVzIDE1OC0xNjEgaW4KICAgICBvcmlnaW5hbCwgbm93IDE2OC0xNzEpCiAgIC0gVGhlIGRyaXZl ciB3YXMgd3JpdGluZyB0aGUgZHV0eSBjeWNsZSB2YWx1ZSBkaXJlY3RseSB0byBQV01DTVAKICAg ICByZWdpc3RlciAobGluZSAxOTMpLCBidXQgdGhlIGhhcmR3YXJlIGFjdHVhbGx5IGV4cGVjdHMg dGhlCiAgICAgKippbmFjdGl2ZSoqIChsb3cpIHRpbWUKICAgLSBUaGlzIHJlc3VsdHMgaW4gaW52 ZXJ0ZWQgUFdNIG91dHB1dCBiZWhhdmlvciB3aGVyZSB1c2VycyBnZXQgdGhlCiAgICAgb3Bwb3Np dGUgZHV0eSBjeWNsZSBmcm9tIHdoYXQgdGhleSByZXF1ZXN0CgoyLiAqKkhhcmR3YXJlIGJlaGF2 aW9yIGRpc2NyZXBhbmN5KiogLSBUaGUgY29tbWl0IHJldmVhbHMgYW5kIGZpeGVzIGEKICAgY3Jp dGljYWwgbWlzbWF0Y2ggYmV0d2VlbiBkb2N1bWVudGF0aW9uIGFuZCBhY3R1YWwgaGFyZHdhcmU6 CiAgIC0gVGhlIGRvY3VtZW50YXRpb24gc3RhdGVzICJwd21zID49IHB3bWNtcFggLT4gSElHSCIK ICAgLSBCdXQgdGhlIGhhcmR3YXJlIGhhcyBhIGhhcmQtdGllZCBYTk9SIHdpdGggMCB0aGF0IGlu dmVydHMgdGhpcwogICAgIGJlaGF2aW9yCiAgIC0gVGhlIGRyaXZlciBub3cgY29ycmVjdGx5IGNv bXBlbnNhdGVzIGZvciB0aGlzIGhhcmR3YXJlIHF1aXJrCgozLiAqKlVzZXItdmlzaWJsZSBpbXBh Y3QqKjoKICAgLSAqKkluIGBwd21fc2lmaXZlX2dldF9zdGF0ZSgpYCoqOiBUaGUgZHJpdmVyIG5v dyBjb3JyZWN0bHkgaW52ZXJ0cwogICAgIHRoZSB2YWx1ZSByZWFkIGZyb20gaGFyZHdhcmUgKGxp bmVzIDExNS0+MTIyLTEyNikKICAgLSAqKkluIGBwd21fc2lmaXZlX2FwcGx5KClgKio6IFRoZSBk cml2ZXIgbm93IGludmVydHMgdGhlIGR1dHkgY3ljbGUKICAgICBiZWZvcmUgd3JpdGluZyB0byBo YXJkd2FyZSAobGluZXMgMTYyLT4xNzEpCiAgIC0gKipQb2xhcml0eSBjaGFuZ2UqKjogQ2hhbmdl ZCBmcm9tIGBQV01fUE9MQVJJVFlfSU5WRVJTRURgIHRvCiAgICAgYFBXTV9QT0xBUklUWV9OT1JN QUxgIChsaW5lcyAxMjYtPjEzNywgMTQyLT4xNTIpCiAgIC0gKipEb2N1bWVudGF0aW9uIGZpeCoq OiBVcGRhdGVkIGNvbW1lbnQgZnJvbSAiY2Fubm90IGdlbmVyYXRlIDEwMCUKICAgICBkdXR5IiB0 byAiY2Fubm90IGdlbmVyYXRlIDAlIGR1dHkiIChsaW5lcyAxMS0+MjcsIDE2MC0+MTcwKQoKNC4g KipUaGUgZml4IGlzIHJlbGF0aXZlbHkgc21hbGwgYW5kIGNvbnRhaW5lZCoqOgogICAtIENoYW5n ZXMgYXJlIGlzb2xhdGVkIHRvIHRoZSBQV00gYWxnb3JpdGhtIGxvZ2ljCiAgIC0gTm8gYXJjaGl0 ZWN0dXJhbCBjaGFuZ2VzIG9yIG5ldyBmZWF0dXJlcwogICAtIFNpbXBsZSBtYXRoZW1hdGljYWwg aW52ZXJzaW9uOiBgZHV0eSA9ICgxVSA8PCBQV01fU0lGSVZFX0NNUFdJRFRIKQogICAgIC0gMSAt IGluYWN0aXZlYAoKNS4gKipObyByaXNreSBzaWRlIGVmZmVjdHMqKjoKICAgLSBUaGUgY2hhbmdl IGlzIHN0cmFpZ2h0Zm9yd2FyZCBhbmQgbWF0aGVtYXRpY2FsbHkgY29ycmVjdAogICAtIERvZXNu J3QgYWZmZWN0IG90aGVyIHN1YnN5c3RlbXMKICAgLSBNYWludGFpbnMgdGhlIHNhbWUgcmVnaXN0 ZXIgaW50ZXJmYWNlCgo2LiAqKkFmZmVjdHMgYWxsIFNpRml2ZSBQV00gdXNlcnMqKjoKICAgLSBB bnkgc3lzdGVtIHVzaW5nIFNpRml2ZSBGVTU0MCBvciBGVTc0MCBTb0NzIHdvdWxkIGhhdmUgaW5j b3JyZWN0CiAgICAgUFdNIG91dHB1dAogICAtIFRoaXMgaW5jbHVkZXMgdmFyaW91cyBSSVNDLVYg ZGV2ZWxvcG1lbnQgYm9hcmRzIGFuZCBlbWJlZGRlZAogICAgIHN5c3RlbXMKICAgLSBVc2VycyB3 b3VsZCBnZXQgaW52ZXJ0ZWQgZHV0eSBjeWNsZXMsIHBvdGVudGlhbGx5IGJyZWFraW5nIG1vdG9y CiAgICAgY29udHJvbHMsIExFRCBkaW1taW5nLCBldGMuCgo3LiAqKkNsZWFyIGRvY3VtZW50YXRp b24gcmVmZXJlbmNlKio6CiAgIC0gVGhlIGNvbW1pdCByZWZlcmVuY2VzIHRoZSBvZmZpY2lhbCBT aUZpdmUgRlU3NDAtQzAwMCBNYW51YWwKICAgLSBQcm92aWRlcyBjbGVhciBleHBsYW5hdGlvbiBv ZiB0aGUgaGFyZHdhcmUgYmVoYXZpb3IgbWlzbWF0Y2gKClRoZSBidWcgY2F1c2VzIFBXTSBvdXRw dXRzIHRvIGJlIGludmVydGVkIGZyb20gdXNlciBleHBlY3RhdGlvbnMsIHdoaWNoCmlzIGEgc2ln bmlmaWNhbnQgZnVuY3Rpb25hbCBpc3N1ZSB0aGF0IHdvdWxkIGFmZmVjdCBhbnkgc3lzdGVtIHJl bHlpbmcKb24gcHJvcGVyIFBXTSBiZWhhdmlvciBmb3IgbW90b3IgY29udHJvbCwgTEVEIGRpbW1p bmcsIG9yIG90aGVyIFBXTS0KZGVwZW5kZW50IGZ1bmN0aW9uYWxpdHkuIFRoZSBmaXggaXMgY2xl YW4sIG1pbmltYWwsIGFuZCBhZGRyZXNzZXMgYQpjbGVhciBoYXJkd2FyZS9zb2Z0d2FyZSBtaXNt YXRjaCB0aGF0IGV4aXN0cyBpbiBwcm9kdWN0aW9uIHN5c3RlbXMuCgogZHJpdmVycy9wd20vcHdt LXNpZml2ZS5jIHwgMzkgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tCiAx IGZpbGUgY2hhbmdlZCwgMzEgaW5zZXJ0aW9ucygrKSwgOCBkZWxldGlvbnMoLSkKCmRpZmYgLS1n aXQgYS9kcml2ZXJzL3B3bS9wd20tc2lmaXZlLmMgYi9kcml2ZXJzL3B3bS9wd20tc2lmaXZlLmMK aW5kZXggZDViNjQ3ZTZiZTc4Li5mMzY5NDgwMWQzZWUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvcHdt L3B3bS1zaWZpdmUuYworKysgYi9kcml2ZXJzL3B3bS9wd20tc2lmaXZlLmMKQEAgLTQsMTEgKzQs MjggQEAKICAqIEZvciBTaUZpdmUncyBQV00gSVAgYmxvY2sgZG9jdW1lbnRhdGlvbiBwbGVhc2Ug cmVmZXIgQ2hhcHRlciAxNCBvZgogICogUmVmZXJlbmNlIE1hbnVhbCA6IGh0dHBzOi8vc3RhdGlj LmRldi5zaWZpdmUuY29tL0ZVNTQwLUMwMDAtdjEuMC5wZGYKICAqCisgKiBQV00gb3V0cHV0IGlu dmVyc2lvbjogQWNjb3JkaW5nIHRvIHRoZSBTaUZpdmUgUmVmZXJlbmNlIG1hbnVhbAorICogdGhl IG91dHB1dCBvZiBlYWNoIGNvbXBhcmF0b3IgaXMgaGlnaCB3aGVuZXZlciB0aGUgdmFsdWUgb2Yg cHdtcyBpcworICogZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBjb3JyZXNwb25kaW5nIHB3 bWNtcFhbUmVmZXJlbmNlIE1hbnVhbF0uCisgKgorICogRmlndXJlIDI5IGluIHRoZSBzYW1lIG1h bnVhbCBzaG93cyB0aGF0IHRoZSBwd21jbXBYY2VudGVyIGJpdCBpcworICogaGFyZC10aWVkIHRv IDAgKFhOT1IpLCB3aGljaCBlZmZlY3RpdmVseSBpbnZlcnRzIHRoZSBjb21wYXJpc29uIHNvIHRo YXQKKyAqIHRoZSBvdXRwdXQgZ29lcyBISUdIIHdoZW4gIGBwd21zIDwgcHdtY21wWGAuCisgKgor ICogSW4gb3RoZXIgd29yZHMsIGVhY2ggcHdtY21wIHJlZ2lzdGVyIGFjdHVhbGx5IGRlZmluZXMg dGhlICoqaW5hY3RpdmUqKgorICogKGxvdykgcGVyaW9kIG9mIHRoZSBwdWxzZSwgbm90IHRoZSBh Y3RpdmUgdGltZSBleGFjdGx5IG9wcG9zaXRlIHRvIHdoYXQKKyAqIHRoZSBkb2N1bWVudGF0aW9u IHRleHQgaW1wbGllcy4KKyAqCisgKiBUbyBjb21wZW5zYXRlLCB0aGlzIGRyaXZlciBhbHdheXMg KippbnZlcnRzKiogdGhlIGR1dHkgdmFsdWUgd2hlbiByZWFkaW5nCisgKiBvciB3cml0aW5nIHB3 bWNtcCByZWdpc3RlcnMgLCBzbyB0aGF0IHVzZXJzIGludGVyYWN0IHdpdGggYSBjb252ZW50aW9u YWwKKyAqICoqYWN0aXZlLWhpZ2gqKiBQV00gaW50ZXJmYWNlLgorICoKKyAqCiAgKiBMaW1pdGF0 aW9uczoKICAqIC0gV2hlbiBjaGFuZ2luZyBib3RoIGR1dHkgY3ljbGUgYW5kIHBlcmlvZCwgd2Ug Y2Fubm90IHByZXZlbnQgaW4KICAqICAgc29mdHdhcmUgdGhhdCB0aGUgb3V0cHV0IG1pZ2h0IHBy b2R1Y2UgYSBwZXJpb2Qgd2l0aCBtaXhlZAogICogICBzZXR0aW5ncyAobmV3IHBlcmlvZCBsZW5n dGggYW5kIG9sZCBkdXR5IGN5Y2xlKS4KLSAqIC0gVGhlIGhhcmR3YXJlIGNhbm5vdCBnZW5lcmF0 ZSBhIDEwMCUgZHV0eSBjeWNsZS4KKyAqIC0gVGhlIGhhcmR3YXJlIGNhbm5vdCBnZW5lcmF0ZSBh IDAlIGR1dHkgY3ljbGUuCiAgKiAtIFRoZSBoYXJkd2FyZSBnZW5lcmF0ZXMgb25seSBpbnZlcnRl ZCBvdXRwdXQuCiAgKi8KICNpbmNsdWRlIDxsaW51eC9jbGsuaD4KQEAgLTExMCw5ICsxMjcsMTQg QEAgc3RhdGljIGludCBwd21fc2lmaXZlX2dldF9zdGF0ZShzdHJ1Y3QgcHdtX2NoaXAgKmNoaXAs IHN0cnVjdCBwd21fZGV2aWNlICpwd20sCiAJCQkJc3RydWN0IHB3bV9zdGF0ZSAqc3RhdGUpCiB7 CiAJc3RydWN0IHB3bV9zaWZpdmVfZGRhdGEgKmRkYXRhID0gcHdtX3NpZml2ZV9jaGlwX3RvX2Rk YXRhKGNoaXApOwotCXUzMiBkdXR5LCB2YWw7CisJdTMyIGR1dHksIHZhbCwgaW5hY3RpdmU7CiAK LQlkdXR5ID0gcmVhZGwoZGRhdGEtPnJlZ3MgKyBQV01fU0lGSVZFX1BXTUNNUChwd20tPmh3cHdt KSk7CisJaW5hY3RpdmUgPSByZWFkbChkZGF0YS0+cmVncyArIFBXTV9TSUZJVkVfUFdNQ01QKHB3 bS0+aHdwd20pKTsKKwkvKgorCSAqIFBXTSBoYXJkd2FyZSB1c2VzICdpbmFjdGl2ZScgY291bnRz IGluIHB3bWNtcCwgc28gaW52ZXJ0IHRvIGdldCBhY3R1YWwgZHV0eS4KKwkgKiBIZXJlLCAnaW5h Y3RpdmUnIGlzIHRoZSBsb3cgdGltZSBhbmQgd2UgY29tcHV0ZSBkdXR5IGFzIG1heF9jb3VudCAt IGluYWN0aXZlLgorCSAqLworCWR1dHkgPSAoMVUgPDwgUFdNX1NJRklWRV9DTVBXSURUSCkgLSAx IC0gaW5hY3RpdmU7CiAKIAlzdGF0ZS0+ZW5hYmxlZCA9IGR1dHkgPiAwOwogCkBAIC0xMjMsNyAr MTQ1LDcgQEAgc3RhdGljIGludCBwd21fc2lmaXZlX2dldF9zdGF0ZShzdHJ1Y3QgcHdtX2NoaXAg KmNoaXAsIHN0cnVjdCBwd21fZGV2aWNlICpwd20sCiAJc3RhdGUtPnBlcmlvZCA9IGRkYXRhLT5y ZWFsX3BlcmlvZDsKIAlzdGF0ZS0+ZHV0eV9jeWNsZSA9CiAJCSh1NjQpZHV0eSAqIGRkYXRhLT5y ZWFsX3BlcmlvZCA+PiBQV01fU0lGSVZFX0NNUFdJRFRIOwotCXN0YXRlLT5wb2xhcml0eSA9IFBX TV9QT0xBUklUWV9JTlZFUlNFRDsKKwlzdGF0ZS0+cG9sYXJpdHkgPSBQV01fUE9MQVJJVFlfTk9S TUFMOwogCiAJcmV0dXJuIDA7CiB9CkBAIC0xMzcsOSArMTU5LDkgQEAgc3RhdGljIGludCBwd21f c2lmaXZlX2FwcGx5KHN0cnVjdCBwd21fY2hpcCAqY2hpcCwgc3RydWN0IHB3bV9kZXZpY2UgKnB3 bSwKIAl1bnNpZ25lZCBsb25nIGxvbmcgbnVtOwogCWJvb2wgZW5hYmxlZDsKIAlpbnQgcmV0ID0g MDsKLQl1MzIgZnJhYzsKKwl1MzIgZnJhYywgaW5hY3RpdmU7CiAKLQlpZiAoc3RhdGUtPnBvbGFy aXR5ICE9IFBXTV9QT0xBUklUWV9JTlZFUlNFRCkKKwlpZiAoc3RhdGUtPnBvbGFyaXR5ICE9IFBX TV9QT0xBUklUWV9OT1JNQUwpCiAJCXJldHVybiAtRUlOVkFMOwogCiAJY3VyX3N0YXRlID0gcHdt LT5zdGF0ZTsKQEAgLTE1Nyw4ICsxNzksOSBAQCBzdGF0aWMgaW50IHB3bV9zaWZpdmVfYXBwbHko c3RydWN0IHB3bV9jaGlwICpjaGlwLCBzdHJ1Y3QgcHdtX2RldmljZSAqcHdtLAogCSAqLwogCW51 bSA9ICh1NjQpZHV0eV9jeWNsZSAqICgxVSA8PCBQV01fU0lGSVZFX0NNUFdJRFRIKTsKIAlmcmFj ID0gRElWNjRfVTY0X1JPVU5EX0NMT1NFU1QobnVtLCBzdGF0ZS0+cGVyaW9kKTsKLQkvKiBUaGUg aGFyZHdhcmUgY2Fubm90IGdlbmVyYXRlIGEgMTAwJSBkdXR5IGN5Y2xlICovCisJLyogVGhlIGhh cmR3YXJlIGNhbm5vdCBnZW5lcmF0ZSBhIDAlIGR1dHkgY3ljbGUgKi8KIAlmcmFjID0gbWluKGZy YWMsICgxVSA8PCBQV01fU0lGSVZFX0NNUFdJRFRIKSAtIDEpOworCWluYWN0aXZlID0gKDFVIDw8 IFBXTV9TSUZJVkVfQ01QV0lEVEgpIC0gMSAtIGZyYWM7CiAKIAltdXRleF9sb2NrKCZkZGF0YS0+ bG9jayk7CiAJaWYgKHN0YXRlLT5wZXJpb2QgIT0gZGRhdGEtPmFwcHJveF9wZXJpb2QpIHsKQEAg LTE5MCw3ICsyMTMsNyBAQCBzdGF0aWMgaW50IHB3bV9zaWZpdmVfYXBwbHkoc3RydWN0IHB3bV9j aGlwICpjaGlwLCBzdHJ1Y3QgcHdtX2RldmljZSAqcHdtLAogCQl9CiAJfQogCi0Jd3JpdGVsKGZy YWMsIGRkYXRhLT5yZWdzICsgUFdNX1NJRklWRV9QV01DTVAocHdtLT5od3B3bSkpOworCXdyaXRl bChpbmFjdGl2ZSwgZGRhdGEtPnJlZ3MgKyBQV01fU0lGSVZFX1BXTUNNUChwd20tPmh3cHdtKSk7 CiAKIAlpZiAoIXN0YXRlLT5lbmFibGVkKQogCQljbGtfZGlzYWJsZShkZGF0YS0+Y2xrKTsKLS0g CjIuMzkuNQoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f CmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51eC1yaXNjdkBsaXN0cy5pbmZyYWRlYWQub3Jn Cmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcmlzY3YK