From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 719C92AD3C for ; Sun, 2 Aug 2026 20:34:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785702884; cv=none; b=sVv8JXZNYGJOHjasBueR7QhFWPFvUoscfmKf+PGFUireEkHmB2o+jxDcHbs3UxXi/4ZuSkQCnG46vieiEA8d8Mx3D4acxwu4H0jBcovfvE1cibBAJasAm+ccqxW8PdLVW7FI1g5ZkHW9x0yMMX0XapfvYul9AoE0EQ/InLRm3Oo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785702884; c=relaxed/simple; bh=L0mRFzceHyyVEZjtgEBEN/2/jL1ecWAiS0Nz1YsJE+0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LT2pUebdL3iMpmNDkkF0mUeWLLFvBPvd5FxsXNxIioXQFTfmYQIHVBSmSB9Q71F1IKVe/NeYbE6IdMfhJE8NjcHt1RWIZ46DCVwOiAgf98AHbcjUU9DU5DUkqOCztZUvv2v87dt5gRsxOT9I+tdFqOzoKpQo7YlE6YbN1NbYCbs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cNQkKGgF; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cNQkKGgF" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4955de8797cso7783085e9.3 for ; Sun, 02 Aug 2026 13:34:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785702880; x=1786307680; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cq0l+WIUQ3dHFQYylacYFfNzUv1KLEoLLifLFBt5J8Y=; b=cNQkKGgFAto0h58/7HGJpzH7k+e7LWnn0BtXFT34BLF4Up3CsXtfNRtLu0Sb9JftMx SiZ9aghKm4trb4tb5Z6KIAe3GxfyL+zNbsMQrvcNaiNoPUhZDcNbtpN/yt5QCX6gbE5s VcvFwKwzENx9jSvu7ovX3ZfG9igSPMXMOYsKGtI0aI5FFjapCk7hExEMH6t4XmgxzAgP rdCsbYvaD9Xpvyc9sV9mOeKCV+jdcsyXuSEdWEUwz895PkQ+TwMbb+J17BIZ2g0CKtPZ 95JS3M3fvApH7rK/FALnkkAe/ElfDZWDvVyF0au7++YCz272vXayLSr7sLSLAsBg0zod r7RQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785702880; x=1786307680; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=cq0l+WIUQ3dHFQYylacYFfNzUv1KLEoLLifLFBt5J8Y=; b=mbt6maFO9vmvOwa4yrFY1iiHI+JAr1tC5ZSyJS+CU5CYjOx26bIECcchD/dPMTqrIB jKWjtXd1fmdTPBASNbg+dOZ8nTlDTj0j105qamgCEYBW+zbvZ4zEjCPln1sXAt/MhkNt bffblpjwCFenwqgHUtvhGwWnTGJ6FBb6Tu46HFE0mP+XN2jt788uTdzMFEj78t4gEZL/ TVxhLaiVCb38id08N82gAqQpNOg6/3NuRILCpmzks2sAns0zzUU5uAhuUOz6P/5VIhsN lrJTOYci0TIIUulvt4+4nmpByYX2VyI7TM8zl1NeqBPhyPU8bAqtZBkoK5J+jlMrj8+B +ldQ== X-Forwarded-Encrypted: i=1; AHgh+RodjOnAPY/Y++jTPL+CcEHegi2u+1ipP9Yf4XEqbj8lyD47GzNBvslCsRlArXF7ZTsEQLps+RYWtgKR@vger.kernel.org X-Gm-Message-State: AOJu0YyY8ZhJVM6u4Mlb5grxXr/6NYTrNXRb6pA1ZFullc2sCLVPijf1 KyWwd49lVRYJXCxp8iRbvPHix1ZeFdwnbIwKqKFUBnsFN+uiwjBYHMG7 X-Gm-Gg: AR+sD12HTvkYhu6lUVqkIM4taCpFHAlOFIyxG36awCv84Zu1ufnCk6YRsaB+AgCLTDI lvvTlu4bDFQ2OggMfb2riJ3SObIUJMwLYE6zB4B5cte41SzpLzSVKn/sZGAsVCTlukDHPJsMxgG yeDpj2uTngyMzWc/qsD+I+osdwzItxcwk0mgL/ZuYrSsWbV9NDr6fflFfaAs7gKEgbftquNax1g 7dQqf2D+sHQfjK2hlRNkwYDhxYcj7dYfyU4w6J6txpIz30649XXwB+AmZYhsg0fKuJ3e5XUtd5E P3yBy8grT70B7KOi6/gjDDIu3G+do1g/TXHOoAsQpQL7ofmw2uG7+xIoBjF8wseMCcK7evw+7g9 tBJcjPEUxg8wMyQjO0/tvtjCqhftGKw6FF4wEZB5aNXbCGn5ko8/V4v+/rrC/olypHwplJiGU9L 1YqI16J5Kb1VtSVBMhZEOXPE4cg3IqYhwK1Ijez4ap/VKxlwcisQQJuUIjF/FuSJa9tsvm5WwU X-Received: by 2002:a05:600c:8b13:b0:498:8e6:d464 with SMTP id 5b1f17b1804b1-4980c65cd2fmr166733515e9.14.1785702879566; Sun, 02 Aug 2026 13:34:39 -0700 (PDT) Received: from [192.168.0.2] ([197.250.226.155]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49807bb45ebsm118499905e9.4.2026.08.02.13.34.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Aug 2026 13:34:38 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Sun, 02 Aug 2026 23:33:39 +0300 Subject: [PATCH v9 07/12] clk: zte: Add zx PLL support infrastructure Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Message-Id: <20260802-zx29clk-v9-7-d05530d85d28@gmail.com> References: <20260802-zx29clk-v9-0-d05530d85d28@gmail.com> In-Reply-To: <20260802-zx29clk-v9-0-d05530d85d28@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney , Vinod Koul , Neil Armstrong , Russell King , Lee Jones Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, mfd@lists.linux.dev, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=23186; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=L0mRFzceHyyVEZjtgEBEN/2/jL1ecWAiS0Nz1YsJE+0=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqb6mydClZTSFDkFcWtYpDTlA9rVKTqTu4kcA6O DR+VCUsYaqJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCam+pshsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiI6vg//aBwXMLTH1q59DlZ6uOoDh70s+9tUPYF tNF8bYCHuy+JAuanh4c08doCptw9jcR585JtuWZOQNy/WLWvhSEYsa0iXcnYVUbKyC0UQfMSAfq eothjgFqwItP4IEVZpLDbNy6cDOImicSSQgOfIxTI2V9AALqDX3Tig0RGHTFLP0+f1u7lN1aBwK nOX20klUarsZ0ieFx+7M15lvoOfdUbA6ODqesMDeC6SNxxb02XBSzxPxoibywWQ3izIh+qUE3bL D2ZnhUA2s1GQSw45IxJg9Id+6BqsVX/N1nmZyShPtPe5WX7oUNMnby43C1rpS5kQCLgbsGj/qWF 7jiac9EkdANtVp1Og29FmRtosRpbufOSXcsuTLkLI+MCQzSds5j/nEVvWg/qvYyHeoWAoUa+TYG 2t+906mVdeCVJlOt22XgiQLVfdDy+rkAZe+IDw4VI8XUmQMMp6UmeLChHmkj3RzsB5CiUpawtqG S2yy4mSvhMwgVGWUwCFX5sqMqRiy9OBTHX+4fpEw5VDrcKZIAFo9YOJt43LkNBpOdr8kM2o8xlL h3dG9nFfQ3DPLVAj5YYepnbDcDYNsqx2utj75xye96YXunPvVOLhVtX7qH7Mx4EViz86d3IMgDx RhhGO6anM0nV03O9QZsPaP3PG8Jm/tsiJ2C66bGQq/svUb+9bd2Q= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 I am guessing how much of this is reusable among other zx chips or even differently named ZTE platforms (if there are any). From reading the old zx2967 code, I think the PLL code would be reusable there, maybe with platform-specific bitmasks but otherwise the same logic. Signed-off-by: Stefan Dösinger --- Version 9: *) Take req->min_rate and req->max_rate into account when looking for possible PLL configurations (sashiko). In practice the code will still only ever encounter a fixed request to set dpll to 491.52 MHz. *) The same code style changes Brian requested on the other clk patches. Version 8: *) Document the behavior of unlocked PLLs better: They don't pass through their reference/parent, but pass through the fixed clock-26m oscillator, even if their reference clock is something else. *) dpll has working fractionals. Add this in the comment, but there is no actual code support for it - the LTE hardware doesn't need it. As for Sashiko's comments on the .set_rate implementation: In practice .set_rate will only ever set one rate, 491.52 MHz for dpll. All other PLLs are bootloader configured. Dpll could be handled by writing a magic constant into its config. I want to have the rate finding code as documentation, and maybe there is more elaborate future use for it (e.g. more flexible underclocking), but attempts to handle eventualities like rate searches or misconfigured bootloader values would be dead code. Version 7: *) Always keep unknownpll enabled when prepared so dpll can acquire a lock in its prepare() function. *) Clean up error reporting a bit (Sashiko) Version 6: *) Use abs_diff to compare target and candidate PLL rate (Sashiko). *) Use req->best_parent_rate in zx29_pll_determine_rate. Add a TODO comment about the parent rate flexibility. Version 5: Fix some issues pointed out by Sashiko: NULL dev, zx29_pll_recalc_rate error handling, disable PLL again on enable error. --- drivers/clk/zte/pll-zx.c | 568 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 565 insertions(+), 3 deletions(-) diff --git a/drivers/clk/zte/pll-zx.c b/drivers/clk/zte/pll-zx.c index fc76c6524a16..e61b462ec0b4 100644 --- a/drivers/clk/zte/pll-zx.c +++ b/drivers/clk/zte/pll-zx.c @@ -4,15 +4,577 @@ */ #include +#include +#include #include +#include #include +#include +#include #include +#include +#include #include "clk-zx.h" +/* + * This code has only been tested with zx297520v3 PLLs, but from reading the zx296718 clock code it + * looks like PLL registers are similar. ZTE's sources explain the PLL register contents only in a + * .cmm file (A Lauterbach TRACE32 script) and some unused headers in their U-Boot code dump, which + * may not be accurate. When calculating the frequencies from the default PLL configuration the + * results match the fixed rate clocks from their clock driver. + * + * The 26 MHz and 32 kHz clocks can be easily observed with the timers. The 104 MHz output can be + * observed through the UART. One 122.88 MHz clock can be observed through the TDM device. All + * others can only be indirectly inferred, e.g. by comparing CPU speed or SDIO transfer rate between + * the fixed 26 MHz oscillator and the provided PLL frequency. + * + * The formula to calculate the clock is ((ref / refdiv) * fbdiv) / postdiv1 / postdiv2. The masks + * are given below. There are a few control flags: + * + * Bit 31: Disables the PLL, but passes clock-26m through unmodified. Whether POSTDIV_OUT_DISABLE + * still matters is different between PLLs. + * Bit 30: Returns if the PLL is locked + * Bit 29: Not named in ZTE's code, but can be set. There is no obvious impact. Lock times are + * unchanged, so it doesn't influence or bypass lock detection. It doesn't raise any IRQs or + * influence GPIOs. + * Bit 27: Given its name it likely disables the Delta-Sigma Modulator, if one exists at all. The + * boot ROM sets it on every PLL. Unsetting it marginally decreases the time it takes to + * lock to the reference clock (from ~400 us to ~300 us). + * Bit 24: Bypasses the VCO, but still applies refdiv and postdiv. Doesn't matter if PLL_DISABLE=1. + * + * NB: Some PLLs have an automatic bypass logic that forwards clock-26m (REGARDLESS of reference) + * when they don't have a lock, regardless of reason. This can be triggered by disabling the PLL, + * setting an out-of-spec VCO frequency or disabling the parent. This shouldn't matter in regular + * operation, but caused me some confusion when reverse engineering the clock tree. E.g. clock-26m-> + * unknownpll(disabled) -> dpll(enabled) counterintuitively results in a 26 MHz output clock. + */ + +#define ZX29_PLL_DISABLE BIT(31) +#define ZX29_PLL_LOCKED BIT(30) +#define ZX29_PLL_LOCK_FILTER BIT(29) +#define ZX29_PLL_DSM_DISABLE BIT(27) +#define ZX29_PLL_PARENT_MASK GENMASK(26, 25) +#define ZX29_PLL_PARENT_SHIFT 25 +#define ZX29_PLL_BYPASS BIT(24) +#define ZX29_PLL_REFDIV_MASK GENMASK(23, 18) +#define ZX29_PLL_REFDIV_SHIFT 18 +#define ZX29_PLL_FBDIV_MASK GENMASK(17, 6) +#define ZX29_PLL_FBDIV_SHIFT 6 +#define ZX29_PLL_POSTDIV1_MASK GENMASK(5, 3) +#define ZX29_PLL_POSTDIV1_SHIFT 3 +#define ZX29_PLL_POSTDIV2_MASK GENMASK(2, 0) +#define ZX29_PLL_POSTDIV2_SHIFT 0 + +/* + * The second register has a 24 bit fractional value, which only matters when ZX29_PLL_DSM_DISABLE + * is not set, and only seems to matter for dpll. ZTE's firmware does not make use of the fractional + * and it is unimplemented in this driver. Experimental testing confirms that it has an impact on + * dpll. + * + * Bits 27:24 contain more flags: + * + * Bit 27: Setting ZX29_PLL_DACAP slows down the lock time and obviates the speed gained from + * !DSM_DISABLE. No other effect observed. + * + * Bit 26: ZX29_PLL_4PHASE_OUT_DISABLE is set on some PLLs on boot but not on others. It is set on + * boot on mpll and upll, but not gpll, dpll or unknownpll. I am not sure what it does + * either. The SDIO devices break if they are fed from gpll with this flag set, but they + * work OK if they are fed from mpll without this flag set. + * + * Bit 25: ZX29_PLL_POSTDIV_OUT_DISABLE seems to disable the PLL output entirely. Whether it is + * bypassed by PLL_DISABLE differs between PLLs. gpll still produces an output clock if + * PLL_DISABLE = 1 and POSTDIV_DISABLE = 1, but produces no output if PLL_DISABLE = 0 and + * POSTDIV_DISABLE = 1. The dpll feeder ("unknownpll") at 0x100 produces no output clock if + * both PLL_DISABLE and POSTDIV_DISABLE are set to 1. + * + * Bit 24: ZX29_PLL_VCO_OUT_DISABLE probably disables the output of the VCO clock without + * post-VCO-dividers, but the raw VCO output is not a possible parent of any consumer clock, + * so I could not confirm this. It does not disable the VCO entirely - that's what + * PLL_DISABLE does. + * + * A spinlock should not be needed. PLLs don't share their registers with anything else and the + * global prepare mutex and enable spinlock should be enough. Beware of conflicts in reg2 between + * POSTDIV_OUT_DISABLE and the fractional value in case you find out how fractional dividers work + * and add support for them. + */ +#define ZX29_PLL_REG2_OFFSET 4 +#define ZX29_PLL_DACAP BIT(27) +#define ZX29_PLL_4PHASE_OUT_DISABLE BIT(26) +#define ZX29_PLL_POSTDIV_OUT_DISABLE BIT(25) +#define ZX29_PLL_VCO_OUT_DISABLE BIT(24) +#define ZX29_PLL_FRACT GENMASK(23, 0) + +/* + * The VCO's frequency range is limited. The stock settings run the VCO between 960 and 1248 MHz. + * Ad-hoc testing with gpll suggests that at least this PLL remains stable down to about 7 MHz and + * up to 2 GHz and produces a clock that can be used by the SDIO controller. Attempting to run the + * mpll VCO at 624 MHz and setting postdiv1 = postdiv2 = 1 - which should result in the same output + * frequency - or running it at 1872 MHz with an effective post divider of 3 crashes the CPU. Most + * likely the PLLs become unstable outside their core range and the SDIO controller is much more + * forgiving than CPU and DRAM are. + */ +#define ZX29_PLL_VCO_MAX_FREQ (1300 * HZ_PER_MHZ) +#define ZX29_PLL_VCO_MIN_FREQ (900 * HZ_PER_MHZ) + +struct zx29_clk_pll { + struct clk_hw hw; + struct device *dev; + struct regmap *map; + u16 reg; +}; + +static inline struct zx29_clk_pll *to_zx29_clk_pll(struct clk_hw *hw) +{ + return container_of(hw, struct zx29_clk_pll, hw); +} + +static int zx29_pll_is_prepared(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + int res; + + res = regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return res; + + return !res; +} + +static int zx29_pll_prepare(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 val = 0; + int res; + + res = regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return res; + + /* Lock duration is usually between 300 us and 500 us */ + res = regmap_read_poll_timeout(pll->map, pll->reg, val, val & ZX29_PLL_LOCKED, 50, 2000); + if (res) { + regmap_set_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + dev_err(pll->dev, "%s: PLL prepare failed: %d. Config value 0x%08x\n", + clk_hw_get_name(&pll->hw), res, val); + } + return res; +} + +static void zx29_pll_unprepare(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + + regmap_set_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); +} + +static int zx29_pll_is_enabled(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + int res; + + res = regmap_test_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); + if (res < 0) + return res; + + return !res; +} + +static int zx29_pll_enable(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + + return regmap_clear_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static void zx29_pll_disable(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + + regmap_set_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static unsigned long zx29_pll_get_rate(const struct zx29_clk_pll *pll, unsigned long parent_rate, + u32 setting) +{ + unsigned long refdiv, fbdiv, postdiv1, postdiv2, freq; + const char *name = clk_hw_get_name(&pll->hw); + u64 vco; + + refdiv = (setting & ZX29_PLL_REFDIV_MASK) >> ZX29_PLL_REFDIV_SHIFT; + fbdiv = (setting & ZX29_PLL_FBDIV_MASK) >> ZX29_PLL_FBDIV_SHIFT; + postdiv1 = (setting & ZX29_PLL_POSTDIV1_MASK) >> ZX29_PLL_POSTDIV1_SHIFT; + postdiv2 = (setting & ZX29_PLL_POSTDIV2_MASK) >> ZX29_PLL_POSTDIV2_SHIFT; + dev_dbg(pll->dev, "%s: reference clock %lu Hz, PLL setting 0x%08x\n", + name, parent_rate, setting); + + if (!refdiv || !postdiv1 || !postdiv2) { + dev_err(pll->dev, "%s: divide by zero (%lu, %lu, %lu)\n", name, refdiv, postdiv1, + postdiv2); + return 0; + } + + vco = div_u64((u64)parent_rate * fbdiv, refdiv); + freq = div_u64(div_u64(vco, postdiv1), postdiv2); + dev_dbg(pll->dev, "%s: refdiv %lu fbdiv %lu\n", name, refdiv, fbdiv); + dev_dbg(pll->dev, "%s: postdiv1 %lu postdiv2 %lu\n", name, postdiv1, postdiv2); + + dev_dbg(pll->dev, "%s: %lu MHz\n", name, freq / HZ_PER_MHZ); + + return freq; +} + +static unsigned long zx29_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 val; + int res; + + res = regmap_read(pll->map, pll->reg, &val); + if (res < 0) { + dev_err(pll->dev, "%s: Failed to read PLL settings\n", clk_hw_get_name(&pll->hw)); + return 0; + } + + return zx29_pll_get_rate(pll, parent_rate, val); +} + +static u32 zx29_pll_calc_values(const struct zx29_clk_pll *pll, unsigned long parent_rate, + unsigned long rate, unsigned long min_rate, unsigned long max_rate) +{ + const unsigned int postdiv1_max = (1 << hweight32(ZX29_PLL_POSTDIV1_MASK)) - 1; + const unsigned int postdiv2_max = (1 << hweight32(ZX29_PLL_POSTDIV2_MASK)) - 1; + unsigned long fbdiv, refdiv, best_fbdiv = 0, best_refdiv = 0; + u32 postdiv1 = 0, postdiv2 = 0, i, j, setting; + const char *name = clk_hw_get_name(&pll->hw); + long best = LONG_MAX; + + /* + * This code produces the same VCO settings that the boot loader and stock firmware use for + * the standard frequencies. It has seen only very little manual testing beyond that. + * + * The goal is to find a VCO setting that gets us as close as possible to the desired output + * rate, while being within the VCO's operating limits and achievable with the input value + * range. It is iterating over possible post-VCO divider values (1-7)*(1-7) to look for + * valid VCO target frequencies and then looks for refdiv and fbdiv values to achieve the + * VCO frequency from the reference frequency. + */ + for (j = 1; j <= postdiv2_max; j++) { + for (i = 1; i <= postdiv1_max; i++) { + u64 vco = (u64)rate * i * j; + unsigned long out; + + if (vco > ZX29_PLL_VCO_MAX_FREQ || vco < ZX29_PLL_VCO_MIN_FREQ) + continue; + + rational_best_approximation(vco, parent_rate, + (1 << hweight32(ZX29_PLL_FBDIV_MASK)) - 1, + (1 << hweight32(ZX29_PLL_REFDIV_MASK)) - 1, + &fbdiv, &refdiv); + setting = fbdiv << ZX29_PLL_FBDIV_SHIFT; + setting |= refdiv << ZX29_PLL_REFDIV_SHIFT; + setting |= i << ZX29_PLL_POSTDIV1_SHIFT; + setting |= j << ZX29_PLL_POSTDIV2_SHIFT; + out = zx29_pll_get_rate(pll, parent_rate, setting); + + if (out < min_rate || out > max_rate) + continue; + + if (abs_diff(out, rate) > best) + continue; + + if (abs_diff(out, rate) < best) { + postdiv1 = i; + postdiv2 = j; + best_fbdiv = fbdiv; + best_refdiv = refdiv; + best = abs_diff(out, rate); + + if (!best) + goto search_done; + } + } + } +search_done: + + if (!postdiv1) { + dev_err(pll->dev, "Did not find a setting for %lu Hz, parent %lu Hz\n", + rate, parent_rate); + return 0; + } + + dev_dbg(pll->dev, "%s: parent rate %lu\n", name, parent_rate); + dev_dbg(pll->dev, "%s: found VCO dividers %u and %u\n", name, postdiv1, postdiv2); + dev_dbg(pll->dev, "%s: VCO target rate %lu\n", name, rate * postdiv1 * postdiv2); + + dev_dbg(pll->dev, "%s: Got fbdiv = %lu refdiv = %lu\n", name, best_fbdiv, best_refdiv); + + setting = best_fbdiv << ZX29_PLL_FBDIV_SHIFT; + setting |= best_refdiv << ZX29_PLL_REFDIV_SHIFT; + setting |= postdiv1 << ZX29_PLL_POSTDIV1_SHIFT; + setting |= postdiv2 << ZX29_PLL_POSTDIV2_SHIFT; + dev_dbg(pll->dev, "%s: Final setting 0x%08x\n", name, setting); + + return setting; +} + +static int zx29_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + unsigned long new_rate; + u32 setting; + + /* + * TODO: DPLL can switch between two parents, one of which is another PLL. Take this into + * account when searching the config space and set req->best_parent_rate. + * + * In practice it shouldn't matter though. Dpll is always configured to a fixed frequency + * and is the only clock with a switchable parent. + */ + if (!req->best_parent_rate) { + dev_err(pll->dev, "Did not expect best_parent_rate=0\n"); + return -EINVAL; + } + + setting = zx29_pll_calc_values(pll, req->best_parent_rate, req->rate, req->min_rate, + req->max_rate); + if (!setting) + return -EINVAL; + + new_rate = zx29_pll_get_rate(pll, req->best_parent_rate, setting); + if (new_rate != req->rate) { + dev_warn(pll->dev, "Did not find an exact match. Want %lu, got %lu\n", + req->rate, new_rate); + req->rate = new_rate; + } + + return 0; +} + +static int zx29_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 setting; + + /* + * TODO: Implement gradual PLL rate change. PLLs can be changed while they are running and + * downstream hardware is generally fine with that. The exception is DRAM, which reads + * incorrect values if changed too fast. + * + * Changing the mpll rate is potentially useful for over/underclocking. Gating mpll is + * unrealistic because too many devices depend on it. + */ + setting = zx29_pll_calc_values(pll, parent_rate, rate, rate, rate); + if (!setting) + return -EINVAL; + + dev_info(pll->dev, "%s: Setting new configuration: 0x%08x\n", clk_hw_get_name(hw), setting); + + return regmap_update_bits(pll->map, pll->reg, 0x00ffffff, setting); +} + +static u8 zx29_pll_get_parent(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 val; + int res; + + res = regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return 0xff; + + val = (val & ZX29_PLL_PARENT_MASK) >> ZX29_PLL_PARENT_SHIFT; + dev_dbg(pll->dev, "%s: Parent 0x%x\n", clk_hw_get_name(hw), val); + + return val; +} + +static int zx29_pll_set_parent(struct clk_hw *hw, u8 index) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + u32 idx_shift = index << ZX29_PLL_PARENT_SHIFT; + int res; + u32 val; + + res = regmap_update_bits(pll->map, pll->reg, ZX29_PLL_PARENT_MASK, idx_shift); + if (res < 0) + return res; + + res = regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return res; + + if ((val & ZX29_PLL_PARENT_MASK) != idx_shift) { + dev_err(pll->dev, "Hardware rejected PLL parent %u\n", index); + return -EINVAL; + } + + return 0; +} + +static int zx29_pll_init(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + const char *name = clk_hw_get_name(hw); + int res; + u32 val; + + dev_dbg(pll->dev, "%s: initializing\n", name); + + /* + * The fractional value is not yet implemented. It works at least with dpll, but I have + * never seen it used on actual hardware. + */ + res = regmap_read(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, &val); + if (res < 0) + return res; + + if (val & ZX29_PLL_FRACT) { + dev_warn(pll->dev, "%s: unsupported nonzero fractional value 0x%08lx\n", + name, val & ZX29_PLL_FRACT); + } + + /* + * Remove the bypass flag so we don't have to bother with it in enable/disable. I have never + * seen it set by the earlier boot stages anyhow. + */ + res = regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_BYPASS); + if (res < 0) + return res; + + res = regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res > 0) { + /* + * Set ZX29_PLL_POSTDIV_OUT_DISABLE for PLLs that have ZX29_PLL_DISABLE for + * consistency with .enable and .prepare. This ensures that .prepare doesn't + * inadvertently enable PLLs without .enable being called. + */ + res = regmap_set_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); + } + + return res; +} + +static const struct clk_ops zx29_pll_ops = { + .init = zx29_pll_init, + .is_prepared = zx29_pll_is_prepared, + .prepare = zx29_pll_prepare, + .unprepare = zx29_pll_unprepare, + .is_enabled = zx29_pll_is_enabled, + .enable = zx29_pll_enable, + .disable = zx29_pll_disable, + .recalc_rate = zx29_pll_recalc_rate, + .determine_rate = zx29_pll_determine_rate, + .get_parent = zx29_pll_get_parent, + .set_parent = zx29_pll_set_parent, + .set_rate = zx29_pll_set_rate, +}; + +/* + * A PLL that can be a parent of another PLL needs to produce an output signal when prepared, + * otherwise the downstream PLL's prepare() will fail to acquire a lock. + */ +static int zx29_pll_nodisable_init(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll = to_zx29_clk_pll(hw); + const char *name = clk_hw_get_name(hw); + int res; + u32 val; + + dev_dbg(pll->dev, "%s: initializing, prepare-is-enabled\n", name); + + res = regmap_read(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, &val); + if (res < 0) + return res; + + if (val & ZX29_PLL_FRACT) { + dev_warn(pll->dev, "%s: unsupported nonzero fractional value 0x%08lx\n", + name, val & ZX29_PLL_FRACT); + } + + res = regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_BYPASS); + if (res < 0) + return res; + + return regmap_clear_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static const struct clk_ops zx29_pll_nodisable_ops = { + .init = zx29_pll_nodisable_init, + .is_prepared = zx29_pll_is_prepared, + .prepare = zx29_pll_prepare, + .unprepare = zx29_pll_unprepare, + .recalc_rate = zx29_pll_recalc_rate, + .determine_rate = zx29_pll_determine_rate, + .get_parent = zx29_pll_get_parent, + .set_parent = zx29_pll_set_parent, + .set_rate = zx29_pll_set_rate, +}; + struct clk_hw *zx_clk_register_pll(struct device *dev, struct regmap *regmap, - const struct zx_pll_desc *desc, - struct clk_hw * const *clocks) + const struct zx_pll_desc *desc, struct clk_hw * const *clocks) { - return ERR_PTR(-ENODEV); + struct clk_parent_data parents[CLK_ZX_MAX_PARENTS]; + struct clk_init_data init = {}; + struct zx29_clk_pll *pll; + unsigned int i; + int res; + + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + if (desc->flags & CLK_ZX_PLL_PREPARE_IS_ENABLE) + init.ops = &zx29_pll_nodisable_ops; + else + init.ops = &zx29_pll_ops; + + if (WARN_ON(desc->num_parents > ARRAY_SIZE(parents))) + return ERR_PTR(-EINVAL); + + for (i = 0; i < desc->num_parents; ++i) + parents[i] = zx_get_parent(&desc->parents[i], clocks); + + init.name = desc->name; + init.parent_data = parents; + init.num_parents = desc->num_parents; + + /* + * Disallow live reparent, but allow rate changes. PLLs can handle gradual changes fine, but + * large ones cause a temporary incorrect output, which can break downstream devices. + * See zx29_pll_set_rate for considerations on that. + */ + init.flags = CLK_SET_PARENT_GATE; + pll->hw.init = &init; + pll->dev = dev; + pll->map = regmap; + pll->reg = desc->reg; + + res = devm_clk_hw_register(dev, &pll->hw); + if (res) + return ERR_PTR(res); + + /* + * Set the PLL rate only if the bootloader left it disabled. Keep the bootloader setup + * otherwise. + */ + res = regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return ERR_PTR(res); + + if (res > 0 && desc->rate) { + dev_dbg(pll->dev, "%s: setting to %lu Hz\n", desc->name, desc->rate); + res = clk_set_rate(pll->hw.clk, desc->rate); + if (res) + return ERR_PTR(dev_err_probe(dev, res, "%s: failed to set rate\n", + desc->name)); + } + + return &pll->hw; } -- 2.54.0 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 2C2C9C55162 for ; Sun, 2 Aug 2026 20:34:45 +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:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=m6ZJ7gZw7BJcritVvutPmEXxZHFyoP0BALaIVfWfP4Y=; b=3WeeVMJ2cixaYz /TGJHmr9NgIPnOZaZ70uDuEsz7lYrb6uXSOFCK6FlwDf9y4CzNQ3zx8fr8rEKts9rGgHkUvJGppZH hUck13GdLL3ILplwdJlO6LIRp60hIbs9IBz7IAGuc21Zifa9FPDG84Jit2R1TcybywoxkAJRJAxQx VYEKIOoYQvzrW+I+vCw1EujTJ05E1mKgdL4m5uIKqirqSfANNApqCSVmUztj/KBUOqGW0ZiyAJfug i0obtMcw0TKU0Jcq6BwUz/mtA/BHZRoJ48LxVo1w3SWnbxnxFj/owP3NuQdJe1Ux6xWij3n17F+FW nUit4+J0Vxiz3Ll69soQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wqctQ-0000000G1mp-3I7v; Sun, 02 Aug 2026 20:34:44 +0000 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1wqctN-0000000G1jN-3MHH for linux-phy@lists.infradead.org; Sun, 02 Aug 2026 20:34:43 +0000 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-4953de5be0aso8806795e9.0 for ; Sun, 02 Aug 2026 13:34:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785702880; x=1786307680; darn=lists.infradead.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cq0l+WIUQ3dHFQYylacYFfNzUv1KLEoLLifLFBt5J8Y=; b=V7VtTy5RHrRbcykKp3ce8/pL1FE6n7NHjhpH8Hok+ln1oFcZqhc2ioYPcWGQ27/qcR 9g6rulklHpVkJGYG3wgtBmExsxuYSxtHRzFqRsjmDGwAo0EPJ+zhXUollxzNGBu2IPd9 LXrj32KWpkN3DHvingWOjLagONi2JC0zb/Bu2L1PdsJmIeKvU9Ng/BWRGxsLx5Bq+Rh3 b40UgRN96b8FcBog/Vw5NvgbMcX6GUeCijBeyd3oQds/vsON3Ba5bnNXZAhyZbq04kMT VV2yUYthDeuFB4oOfba9NVHPK+shu/W/ZDIbcaHyXLNUum+iSU/ZGGaGlH/6ENaMrjnX DeIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785702880; x=1786307680; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=cq0l+WIUQ3dHFQYylacYFfNzUv1KLEoLLifLFBt5J8Y=; b=fQB9/TEMPsSfFiO1vlsEzeSuScyhyytMv0F/I0ZUiRNY/Ml/uIa/ZNVrN61ojz4VrS LYzLwU3Vf+2qLDrgh59I/ELwlQFouv3fSsCCr6qnO8/+D0GWokI7aPBT3oAQlDgZo43o PpxR5tgeP4Zp/atG090vOoVRAQF5EWuovvHWynuBOf3PWjUwWwv657x/DuUQA3nXHycS RVhOqpd0s7mxDQdarTwmn4mA12P7vlKH7p1K/ESvKvmVOqJyWDJgPiI+eKdu5d2OQT8Q DlEqDteOUcqEI/w3BgyxrATnwXg/wqKxE3n6uaP3cAJqkuSXCf5yfTykWDVrrYYoAWie 7Y+Q== X-Forwarded-Encrypted: i=1; AHgh+RpnD7VCejO9woinoAgPG9U7L5gn7TGi5IIqvVOvZpJsgKqJtiXaKvsnJuZJ+4mjIqyWD1XzT+xaSIw=@lists.infradead.org X-Gm-Message-State: AOJu0YwICq/fhETkwtFZlyGEKMWPle8lx6e3rlfrQJBtufs24an5XT8f 4DVLI3XduYoHsgwjsdWxwC0KptMd5NDCVEU+tR2c4Cora75cmJC7+VcT X-Gm-Gg: AR+sD13ol7E9V+oeS7bURa+4tu3TPi/XftBe/asupxDFdrZjS+iqp867AUMlLajY/FE FjOUF/oigfVVqFIYz+BTN148sI7nelQHlE8bl++tQ8rtopEcUwku8DXbB1xrFdX9qPBShQDfWac YrScj4lTRT9EeBqKDYq7Je0/ldZnVyhmPifYeCgulAziNNgLeL+gei7znytwvDDlw8HvOzT1JEs zOkBR05GN9B0oXFzNWOu7zplsp6LX99wHegJ0ndtP2qYzpHsqa4dLHtWWJ2KnQ+FHULdM1+B248 cu6GFCW+YjZDDNZoHD7RG1YeSQ/CydD/F0JD1Iufk1qYNu2ww5RFCJfPzswKEemU/1CmT6hgKmR /m+2oaXnwE1F12GcLL70t22Xiw62wwafqMuvJNtLWlzYbQdmJRyc2ZzrUSkA1y7CgjSFL26aSHH E9uMKs6jQJI+OUwWpOYKr1kedDbjcPlmw4LmZhen9Pk02CjF5I4+ao+nM7a3hvGb70e/pqzgKd X-Received: by 2002:a05:600c:8b13:b0:498:8e6:d464 with SMTP id 5b1f17b1804b1-4980c65cd2fmr166733515e9.14.1785702879566; Sun, 02 Aug 2026 13:34:39 -0700 (PDT) Received: from [192.168.0.2] ([197.250.226.155]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49807bb45ebsm118499905e9.4.2026.08.02.13.34.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 02 Aug 2026 13:34:38 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Sun, 02 Aug 2026 23:33:39 +0300 Subject: [PATCH v9 07/12] clk: zte: Add zx PLL support infrastructure MIME-Version: 1.0 Message-Id: <20260802-zx29clk-v9-7-d05530d85d28@gmail.com> References: <20260802-zx29clk-v9-0-d05530d85d28@gmail.com> In-Reply-To: <20260802-zx29clk-v9-0-d05530d85d28@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney , Vinod Koul , Neil Armstrong , Russell King , Lee Jones Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-phy@lists.infradead.org, mfd@lists.linux.dev, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=23186; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=L0mRFzceHyyVEZjtgEBEN/2/jL1ecWAiS0Nz1YsJE+0=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqb6mydClZTSFDkFcWtYpDTlA9rVKTqTu4kcA6O DR+VCUsYaqJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCam+pshsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiI6vg//aBwXMLTH1q59DlZ6uOoDh70s+9tUPYF tNF8bYCHuy+JAuanh4c08doCptw9jcR585JtuWZOQNy/WLWvhSEYsa0iXcnYVUbKyC0UQfMSAfq eothjgFqwItP4IEVZpLDbNy6cDOImicSSQgOfIxTI2V9AALqDX3Tig0RGHTFLP0+f1u7lN1aBwK nOX20klUarsZ0ieFx+7M15lvoOfdUbA6ODqesMDeC6SNxxb02XBSzxPxoibywWQ3izIh+qUE3bL D2ZnhUA2s1GQSw45IxJg9Id+6BqsVX/N1nmZyShPtPe5WX7oUNMnby43C1rpS5kQCLgbsGj/qWF 7jiac9EkdANtVp1Og29FmRtosRpbufOSXcsuTLkLI+MCQzSds5j/nEVvWg/qvYyHeoWAoUa+TYG 2t+906mVdeCVJlOt22XgiQLVfdDy+rkAZe+IDw4VI8XUmQMMp6UmeLChHmkj3RzsB5CiUpawtqG S2yy4mSvhMwgVGWUwCFX5sqMqRiy9OBTHX+4fpEw5VDrcKZIAFo9YOJt43LkNBpOdr8kM2o8xlL h3dG9nFfQ3DPLVAj5YYepnbDcDYNsqx2utj75xye96YXunPvVOLhVtX7qH7Mx4EViz86d3IMgDx RhhGO6anM0nV03O9QZsPaP3PG8Jm/tsiJ2C66bGQq/svUb+9bd2Q= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260802_133442_015695_334424C0 X-CRM114-Status: GOOD ( 38.82 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org SSBhbSBndWVzc2luZyBob3cgbXVjaCBvZiB0aGlzIGlzIHJldXNhYmxlIGFtb25nIG90aGVyIHp4 IGNoaXBzIG9yIGV2ZW4KZGlmZmVyZW50bHkgbmFtZWQgWlRFIHBsYXRmb3JtcyAoaWYgdGhlcmUg YXJlIGFueSkuIEZyb20gcmVhZGluZyB0aGUgb2xkCnp4Mjk2NyBjb2RlLCBJIHRoaW5rIHRoZSBQ TEwgY29kZSB3b3VsZCBiZSByZXVzYWJsZSB0aGVyZSwgbWF5YmUgd2l0aApwbGF0Zm9ybS1zcGVj aWZpYyBiaXRtYXNrcyBidXQgb3RoZXJ3aXNlIHRoZSBzYW1lIGxvZ2ljLgoKU2lnbmVkLW9mZi1i eTogU3RlZmFuIETDtnNpbmdlciA8c3RlZmFuZG9lc2luZ2VyQGdtYWlsLmNvbT4KCi0tLQoKVmVy c2lvbiA5OgoqKSBUYWtlIHJlcS0+bWluX3JhdGUgYW5kIHJlcS0+bWF4X3JhdGUgaW50byBhY2Nv dW50IHdoZW4gbG9va2luZyBmb3IKcG9zc2libGUgUExMIGNvbmZpZ3VyYXRpb25zIChzYXNoaWtv KS4gSW4gcHJhY3RpY2UgdGhlIGNvZGUgd2lsbCBzdGlsbApvbmx5IGV2ZXIgZW5jb3VudGVyIGEg Zml4ZWQgcmVxdWVzdCB0byBzZXQgZHBsbCB0byA0OTEuNTIgTUh6LgoKKikgVGhlIHNhbWUgY29k ZSBzdHlsZSBjaGFuZ2VzIEJyaWFuIHJlcXVlc3RlZCBvbiB0aGUgb3RoZXIgY2xrIHBhdGNoZXMu CgpWZXJzaW9uIDg6CiopIERvY3VtZW50IHRoZSBiZWhhdmlvciBvZiB1bmxvY2tlZCBQTExzIGJl dHRlcjogVGhleSBkb24ndCBwYXNzCnRocm91Z2ggdGhlaXIgcmVmZXJlbmNlL3BhcmVudCwgYnV0 IHBhc3MgdGhyb3VnaCB0aGUgZml4ZWQgY2xvY2stMjZtCm9zY2lsbGF0b3IsIGV2ZW4gaWYgdGhl aXIgcmVmZXJlbmNlIGNsb2NrIGlzIHNvbWV0aGluZyBlbHNlLgoqKSBkcGxsIGhhcyB3b3JraW5n IGZyYWN0aW9uYWxzLiBBZGQgdGhpcyBpbiB0aGUgY29tbWVudCwgYnV0IHRoZXJlIGlzCm5vIGFj dHVhbCBjb2RlIHN1cHBvcnQgZm9yIGl0IC0gdGhlIExURSBoYXJkd2FyZSBkb2Vzbid0IG5lZWQg aXQuCgpBcyBmb3IgU2FzaGlrbydzIGNvbW1lbnRzIG9uIHRoZSAuc2V0X3JhdGUgaW1wbGVtZW50 YXRpb246IEluIHByYWN0aWNlCi5zZXRfcmF0ZSB3aWxsIG9ubHkgZXZlciBzZXQgb25lIHJhdGUs IDQ5MS41MiBNSHogZm9yIGRwbGwuIEFsbCBvdGhlcgpQTExzIGFyZSBib290bG9hZGVyIGNvbmZp Z3VyZWQuIERwbGwgY291bGQgYmUgaGFuZGxlZCBieSB3cml0aW5nIGEgbWFnaWMKY29uc3RhbnQg aW50byBpdHMgY29uZmlnLgoKSSB3YW50IHRvIGhhdmUgdGhlIHJhdGUgZmluZGluZyBjb2RlIGFz IGRvY3VtZW50YXRpb24sIGFuZCBtYXliZSB0aGVyZQppcyBtb3JlIGVsYWJvcmF0ZSBmdXR1cmUg dXNlIGZvciBpdCAoZS5nLiBtb3JlIGZsZXhpYmxlIHVuZGVyY2xvY2tpbmcpLApidXQgYXR0ZW1w dHMgdG8gaGFuZGxlIGV2ZW50dWFsaXRpZXMgbGlrZSByYXRlIHNlYXJjaGVzIG9yIG1pc2NvbmZp Z3VyZWQKYm9vdGxvYWRlciB2YWx1ZXMgd291bGQgYmUgZGVhZCBjb2RlLgoKVmVyc2lvbiA3Ogoq KSBBbHdheXMga2VlcCB1bmtub3ducGxsIGVuYWJsZWQgd2hlbiBwcmVwYXJlZCBzbyBkcGxsIGNh biBhY3F1aXJlIGEKbG9jayBpbiBpdHMgcHJlcGFyZSgpIGZ1bmN0aW9uLgoqKSBDbGVhbiB1cCBl cnJvciByZXBvcnRpbmcgYSBiaXQgKFNhc2hpa28pCgpWZXJzaW9uIDY6CiopIFVzZSBhYnNfZGlm ZiB0byBjb21wYXJlIHRhcmdldCBhbmQgY2FuZGlkYXRlIFBMTCByYXRlIChTYXNoaWtvKS4KKikg VXNlIHJlcS0+YmVzdF9wYXJlbnRfcmF0ZSBpbiB6eDI5X3BsbF9kZXRlcm1pbmVfcmF0ZS4gQWRk IGEgVE9ETwpjb21tZW50IGFib3V0IHRoZSBwYXJlbnQgcmF0ZSBmbGV4aWJpbGl0eS4KClZlcnNp b24gNTogRml4IHNvbWUgaXNzdWVzIHBvaW50ZWQgb3V0IGJ5IFNhc2hpa286IE5VTEwgZGV2LAp6 eDI5X3BsbF9yZWNhbGNfcmF0ZSBlcnJvciBoYW5kbGluZywgZGlzYWJsZSBQTEwgYWdhaW4gb24g ZW5hYmxlIGVycm9yLgotLS0KIGRyaXZlcnMvY2xrL3p0ZS9wbGwtenguYyB8IDU2OCArKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQogMSBmaWxlIGNoYW5nZWQs IDU2NSBpbnNlcnRpb25zKCspLCAzIGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL2RyaXZlcnMv Y2xrL3p0ZS9wbGwtenguYyBiL2RyaXZlcnMvY2xrL3p0ZS9wbGwtenguYwppbmRleCBmYzc2YzY1 MjRhMTYuLmU2MWI0NjJlYzBiNCAxMDA2NDQKLS0tIGEvZHJpdmVycy9jbGsvenRlL3BsbC16eC5j CisrKyBiL2RyaXZlcnMvY2xrL3p0ZS9wbGwtenguYwpAQCAtNCwxNSArNCw1NzcgQEAKICAqLwog CiAjaW5jbHVkZSA8bGludXgvY2xrLXByb3ZpZGVyLmg+CisjaW5jbHVkZSA8bGludXgvY2xrLmg+ CisjaW5jbHVkZSA8bGludXgvY29udGFpbmVyX29mLmg+CiAjaW5jbHVkZSA8bGludXgvZGV2aWNl Lmg+CisjaW5jbHVkZSA8bGludXgvZXJyLmg+CiAjaW5jbHVkZSA8bGludXgvZXJybm8uaD4KKyNp bmNsdWRlIDxsaW51eC9tYXRoLmg+CisjaW5jbHVkZSA8bGludXgvcmF0aW9uYWwuaD4KICNpbmNs dWRlIDxsaW51eC9yZWdtYXAuaD4KKyNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgorI2luY2x1ZGUg PGxpbnV4L3VuaXRzLmg+CiAKICNpbmNsdWRlICJjbGstenguaCIKIAorLyoKKyAqIFRoaXMgY29k ZSBoYXMgb25seSBiZWVuIHRlc3RlZCB3aXRoIHp4Mjk3NTIwdjMgUExMcywgYnV0IGZyb20gcmVh ZGluZyB0aGUgengyOTY3MTggY2xvY2sgY29kZSBpdAorICogbG9va3MgbGlrZSBQTEwgcmVnaXN0 ZXJzIGFyZSBzaW1pbGFyLiBaVEUncyBzb3VyY2VzIGV4cGxhaW4gdGhlIFBMTCByZWdpc3RlciBj b250ZW50cyBvbmx5IGluIGEKKyAqIC5jbW0gZmlsZSAoQSBMYXV0ZXJiYWNoIFRSQUNFMzIgc2Ny aXB0KSBhbmQgc29tZSB1bnVzZWQgaGVhZGVycyBpbiB0aGVpciBVLUJvb3QgY29kZSBkdW1wLCB3 aGljaAorICogbWF5IG5vdCBiZSBhY2N1cmF0ZS4gV2hlbiBjYWxjdWxhdGluZyB0aGUgZnJlcXVl bmNpZXMgZnJvbSB0aGUgZGVmYXVsdCBQTEwgY29uZmlndXJhdGlvbiB0aGUKKyAqIHJlc3VsdHMg bWF0Y2ggdGhlIGZpeGVkIHJhdGUgY2xvY2tzIGZyb20gdGhlaXIgY2xvY2sgZHJpdmVyLgorICoK KyAqIFRoZSAyNiBNSHogYW5kIDMyIGtIeiBjbG9ja3MgY2FuIGJlIGVhc2lseSBvYnNlcnZlZCB3 aXRoIHRoZSB0aW1lcnMuIFRoZSAxMDQgTUh6IG91dHB1dCBjYW4gYmUKKyAqIG9ic2VydmVkIHRo cm91Z2ggdGhlIFVBUlQuIE9uZSAxMjIuODggTUh6IGNsb2NrIGNhbiBiZSBvYnNlcnZlZCB0aHJv dWdoIHRoZSBURE0gZGV2aWNlLiBBbGwKKyAqIG90aGVycyBjYW4gb25seSBiZSBpbmRpcmVjdGx5 IGluZmVycmVkLCBlLmcuIGJ5IGNvbXBhcmluZyBDUFUgc3BlZWQgb3IgU0RJTyB0cmFuc2ZlciBy YXRlIGJldHdlZW4KKyAqIHRoZSBmaXhlZCAyNiBNSHogb3NjaWxsYXRvciBhbmQgdGhlIHByb3Zp ZGVkIFBMTCBmcmVxdWVuY3kuCisgKgorICogVGhlIGZvcm11bGEgdG8gY2FsY3VsYXRlIHRoZSBj bG9jayBpcyAoKHJlZiAvIHJlZmRpdikgKiBmYmRpdikgLyBwb3N0ZGl2MSAvIHBvc3RkaXYyLiBU aGUgbWFza3MKKyAqIGFyZSBnaXZlbiBiZWxvdy4gVGhlcmUgYXJlIGEgZmV3IGNvbnRyb2wgZmxh Z3M6CisgKgorICogQml0IDMxOiBEaXNhYmxlcyB0aGUgUExMLCBidXQgcGFzc2VzIGNsb2NrLTI2 bSB0aHJvdWdoIHVubW9kaWZpZWQuIFdoZXRoZXIgUE9TVERJVl9PVVRfRElTQUJMRQorICogICAg ICAgICBzdGlsbCBtYXR0ZXJzIGlzIGRpZmZlcmVudCBiZXR3ZWVuIFBMTHMuCisgKiBCaXQgMzA6 IFJldHVybnMgaWYgdGhlIFBMTCBpcyBsb2NrZWQKKyAqIEJpdCAyOTogTm90IG5hbWVkIGluIFpU RSdzIGNvZGUsIGJ1dCBjYW4gYmUgc2V0LiBUaGVyZSBpcyBubyBvYnZpb3VzIGltcGFjdC4gTG9j ayB0aW1lcyBhcmUKKyAqICAgICAgICAgdW5jaGFuZ2VkLCBzbyBpdCBkb2Vzbid0IGluZmx1ZW5j ZSBvciBieXBhc3MgbG9jayBkZXRlY3Rpb24uIEl0IGRvZXNuJ3QgcmFpc2UgYW55IElSUXMgb3IK KyAqICAgICAgICAgaW5mbHVlbmNlIEdQSU9zLgorICogQml0IDI3OiBHaXZlbiBpdHMgbmFtZSBp dCBsaWtlbHkgZGlzYWJsZXMgdGhlIERlbHRhLVNpZ21hIE1vZHVsYXRvciwgaWYgb25lIGV4aXN0 cyBhdCBhbGwuIFRoZQorICogICAgICAgICBib290IFJPTSBzZXRzIGl0IG9uIGV2ZXJ5IFBMTC4g VW5zZXR0aW5nIGl0IG1hcmdpbmFsbHkgZGVjcmVhc2VzIHRoZSB0aW1lIGl0IHRha2VzIHRvCisg KiAgICAgICAgIGxvY2sgdG8gdGhlIHJlZmVyZW5jZSBjbG9jayAoZnJvbSB+NDAwIHVzIHRvIH4z MDAgdXMpLgorICogQml0IDI0OiBCeXBhc3NlcyB0aGUgVkNPLCBidXQgc3RpbGwgYXBwbGllcyBy ZWZkaXYgYW5kIHBvc3RkaXYuIERvZXNuJ3QgbWF0dGVyIGlmIFBMTF9ESVNBQkxFPTEuCisgKgor ICogTkI6IFNvbWUgUExMcyBoYXZlIGFuIGF1dG9tYXRpYyBieXBhc3MgbG9naWMgdGhhdCBmb3J3 YXJkcyBjbG9jay0yNm0gKFJFR0FSRExFU1Mgb2YgcmVmZXJlbmNlKQorICogd2hlbiB0aGV5IGRv bid0IGhhdmUgYSBsb2NrLCByZWdhcmRsZXNzIG9mIHJlYXNvbi4gVGhpcyBjYW4gYmUgdHJpZ2dl cmVkIGJ5IGRpc2FibGluZyB0aGUgUExMLAorICogc2V0dGluZyBhbiBvdXQtb2Ytc3BlYyBWQ08g ZnJlcXVlbmN5IG9yIGRpc2FibGluZyB0aGUgcGFyZW50LiBUaGlzIHNob3VsZG4ndCBtYXR0ZXIg aW4gcmVndWxhcgorICogb3BlcmF0aW9uLCBidXQgY2F1c2VkIG1lIHNvbWUgY29uZnVzaW9uIHdo ZW4gcmV2ZXJzZSBlbmdpbmVlcmluZyB0aGUgY2xvY2sgdHJlZS4gRS5nLiBjbG9jay0yNm0tPgor ICogdW5rbm93bnBsbChkaXNhYmxlZCkgLT4gZHBsbChlbmFibGVkKSBjb3VudGVyaW50dWl0aXZl bHkgcmVzdWx0cyBpbiBhIDI2IE1IeiBvdXRwdXQgY2xvY2suCisgKi8KKworI2RlZmluZSBaWDI5 X1BMTF9ESVNBQkxFCQkJQklUKDMxKQorI2RlZmluZSBaWDI5X1BMTF9MT0NLRUQJCQkJQklUKDMw KQorI2RlZmluZSBaWDI5X1BMTF9MT0NLX0ZJTFRFUgkJCUJJVCgyOSkKKyNkZWZpbmUgWlgyOV9Q TExfRFNNX0RJU0FCTEUJCQlCSVQoMjcpCisjZGVmaW5lIFpYMjlfUExMX1BBUkVOVF9NQVNLCQkJ R0VOTUFTSygyNiwgMjUpCisjZGVmaW5lIFpYMjlfUExMX1BBUkVOVF9TSElGVAkJCTI1CisjZGVm aW5lIFpYMjlfUExMX0JZUEFTUwkJCQlCSVQoMjQpCisjZGVmaW5lIFpYMjlfUExMX1JFRkRJVl9N QVNLCQkJR0VOTUFTSygyMywgMTgpCisjZGVmaW5lIFpYMjlfUExMX1JFRkRJVl9TSElGVAkJCTE4 CisjZGVmaW5lIFpYMjlfUExMX0ZCRElWX01BU0sJCQlHRU5NQVNLKDE3LCA2KQorI2RlZmluZSBa WDI5X1BMTF9GQkRJVl9TSElGVAkJCTYKKyNkZWZpbmUgWlgyOV9QTExfUE9TVERJVjFfTUFTSwkJ CUdFTk1BU0soNSwgMykKKyNkZWZpbmUgWlgyOV9QTExfUE9TVERJVjFfU0hJRlQJCQkzCisjZGVm aW5lIFpYMjlfUExMX1BPU1RESVYyX01BU0sJCQlHRU5NQVNLKDIsIDApCisjZGVmaW5lIFpYMjlf UExMX1BPU1RESVYyX1NISUZUCQkJMAorCisvKgorICogVGhlIHNlY29uZCByZWdpc3RlciBoYXMg YSAyNCBiaXQgZnJhY3Rpb25hbCB2YWx1ZSwgd2hpY2ggb25seSBtYXR0ZXJzIHdoZW4gWlgyOV9Q TExfRFNNX0RJU0FCTEUKKyAqIGlzIG5vdCBzZXQsIGFuZCBvbmx5IHNlZW1zIHRvIG1hdHRlciBm b3IgZHBsbC4gWlRFJ3MgZmlybXdhcmUgZG9lcyBub3QgbWFrZSB1c2Ugb2YgdGhlIGZyYWN0aW9u YWwKKyAqIGFuZCBpdCBpcyB1bmltcGxlbWVudGVkIGluIHRoaXMgZHJpdmVyLiBFeHBlcmltZW50 YWwgdGVzdGluZyBjb25maXJtcyB0aGF0IGl0IGhhcyBhbiBpbXBhY3Qgb24KKyAqIGRwbGwuCisg KgorICogQml0cyAyNzoyNCBjb250YWluIG1vcmUgZmxhZ3M6CisgKgorICogQml0IDI3OiBTZXR0 aW5nIFpYMjlfUExMX0RBQ0FQIHNsb3dzIGRvd24gdGhlIGxvY2sgdGltZSBhbmQgb2J2aWF0ZXMg dGhlIHNwZWVkIGdhaW5lZCBmcm9tCisgKiAgICAgICAgICFEU01fRElTQUJMRS4gTm8gb3RoZXIg ZWZmZWN0IG9ic2VydmVkLgorICoKKyAqIEJpdCAyNjogWlgyOV9QTExfNFBIQVNFX09VVF9ESVNB QkxFIGlzIHNldCBvbiBzb21lIFBMTHMgb24gYm9vdCBidXQgbm90IG9uIG90aGVycy4gSXQgaXMg c2V0IG9uCisgKiAgICAgICAgIGJvb3Qgb24gbXBsbCBhbmQgdXBsbCwgYnV0IG5vdCBncGxsLCBk cGxsIG9yIHVua25vd25wbGwuIEkgYW0gbm90IHN1cmUgd2hhdCBpdCBkb2VzCisgKiAgICAgICAg IGVpdGhlci4gVGhlIFNESU8gZGV2aWNlcyBicmVhayBpZiB0aGV5IGFyZSBmZWQgZnJvbSBncGxs IHdpdGggdGhpcyBmbGFnIHNldCwgYnV0IHRoZXkKKyAqICAgICAgICAgd29yayBPSyBpZiB0aGV5 IGFyZSBmZWQgZnJvbSBtcGxsIHdpdGhvdXQgdGhpcyBmbGFnIHNldC4KKyAqCisgKiBCaXQgMjU6 IFpYMjlfUExMX1BPU1RESVZfT1VUX0RJU0FCTEUgc2VlbXMgdG8gZGlzYWJsZSB0aGUgUExMIG91 dHB1dCBlbnRpcmVseS4gV2hldGhlciBpdCBpcworICogICAgICAgICBieXBhc3NlZCBieSBQTExf RElTQUJMRSBkaWZmZXJzIGJldHdlZW4gUExMcy4gZ3BsbCBzdGlsbCBwcm9kdWNlcyBhbiBvdXRw dXQgY2xvY2sgaWYKKyAqICAgICAgICAgUExMX0RJU0FCTEUgPSAxIGFuZCBQT1NURElWX0RJU0FC TEUgPSAxLCBidXQgcHJvZHVjZXMgbm8gb3V0cHV0IGlmIFBMTF9ESVNBQkxFID0gMCBhbmQKKyAq ICAgICAgICAgUE9TVERJVl9ESVNBQkxFID0gMS4gVGhlIGRwbGwgZmVlZGVyICgidW5rbm93bnBs bCIpIGF0IDB4MTAwIHByb2R1Y2VzIG5vIG91dHB1dCBjbG9jayBpZgorICogICAgICAgICBib3Ro IFBMTF9ESVNBQkxFIGFuZCBQT1NURElWX0RJU0FCTEUgYXJlIHNldCB0byAxLgorICoKKyAqIEJp dCAyNDogWlgyOV9QTExfVkNPX09VVF9ESVNBQkxFIHByb2JhYmx5IGRpc2FibGVzIHRoZSBvdXRw dXQgb2YgdGhlIFZDTyBjbG9jayB3aXRob3V0CisgKiAgICAgICAgIHBvc3QtVkNPLWRpdmlkZXJz LCBidXQgdGhlIHJhdyBWQ08gb3V0cHV0IGlzIG5vdCBhIHBvc3NpYmxlIHBhcmVudCBvZiBhbnkg Y29uc3VtZXIgY2xvY2ssCisgKiAgICAgICAgIHNvIEkgY291bGQgbm90IGNvbmZpcm0gdGhpcy4g SXQgZG9lcyBub3QgZGlzYWJsZSB0aGUgVkNPIGVudGlyZWx5IC0gdGhhdCdzIHdoYXQKKyAqICAg ICAgICAgUExMX0RJU0FCTEUgZG9lcy4KKyAqCisgKiBBIHNwaW5sb2NrIHNob3VsZCBub3QgYmUg bmVlZGVkLiBQTExzIGRvbid0IHNoYXJlIHRoZWlyIHJlZ2lzdGVycyB3aXRoIGFueXRoaW5nIGVs c2UgYW5kIHRoZQorICogZ2xvYmFsIHByZXBhcmUgbXV0ZXggYW5kIGVuYWJsZSBzcGlubG9jayBz aG91bGQgYmUgZW5vdWdoLiBCZXdhcmUgb2YgY29uZmxpY3RzIGluIHJlZzIgYmV0d2VlbgorICog UE9TVERJVl9PVVRfRElTQUJMRSBhbmQgdGhlIGZyYWN0aW9uYWwgdmFsdWUgaW4gY2FzZSB5b3Ug ZmluZCBvdXQgaG93IGZyYWN0aW9uYWwgZGl2aWRlcnMgd29yaworICogYW5kIGFkZCBzdXBwb3J0 IGZvciB0aGVtLgorICovCisjZGVmaW5lIFpYMjlfUExMX1JFRzJfT0ZGU0VUCQkJNAorI2RlZmlu ZSBaWDI5X1BMTF9EQUNBUAkJCQlCSVQoMjcpCisjZGVmaW5lIFpYMjlfUExMXzRQSEFTRV9PVVRf RElTQUJMRQkJQklUKDI2KQorI2RlZmluZSBaWDI5X1BMTF9QT1NURElWX09VVF9ESVNBQkxFCQlC SVQoMjUpCisjZGVmaW5lIFpYMjlfUExMX1ZDT19PVVRfRElTQUJMRQkJQklUKDI0KQorI2RlZmlu ZSBaWDI5X1BMTF9GUkFDVAkJCQlHRU5NQVNLKDIzLCAwKQorCisvKgorICogVGhlIFZDTydzIGZy ZXF1ZW5jeSByYW5nZSBpcyBsaW1pdGVkLiBUaGUgc3RvY2sgc2V0dGluZ3MgcnVuIHRoZSBWQ08g YmV0d2VlbiA5NjAgYW5kIDEyNDggTUh6LgorICogQWQtaG9jIHRlc3Rpbmcgd2l0aCBncGxsIHN1 Z2dlc3RzIHRoYXQgYXQgbGVhc3QgdGhpcyBQTEwgcmVtYWlucyBzdGFibGUgZG93biB0byBhYm91 dCA3IE1IeiBhbmQKKyAqIHVwIHRvIDIgR0h6IGFuZCBwcm9kdWNlcyBhIGNsb2NrIHRoYXQgY2Fu IGJlIHVzZWQgYnkgdGhlIFNESU8gY29udHJvbGxlci4gQXR0ZW1wdGluZyB0byBydW4gdGhlCisg KiBtcGxsIFZDTyBhdCA2MjQgTUh6IGFuZCBzZXR0aW5nIHBvc3RkaXYxID0gcG9zdGRpdjIgPSAx IC0gd2hpY2ggc2hvdWxkIHJlc3VsdCBpbiB0aGUgc2FtZSBvdXRwdXQKKyAqIGZyZXF1ZW5jeSAt IG9yIHJ1bm5pbmcgaXQgYXQgMTg3MiBNSHogd2l0aCBhbiBlZmZlY3RpdmUgcG9zdCBkaXZpZGVy IG9mIDMgY3Jhc2hlcyB0aGUgQ1BVLiBNb3N0CisgKiBsaWtlbHkgdGhlIFBMTHMgYmVjb21lIHVu c3RhYmxlIG91dHNpZGUgdGhlaXIgY29yZSByYW5nZSBhbmQgdGhlIFNESU8gY29udHJvbGxlciBp cyBtdWNoIG1vcmUKKyAqIGZvcmdpdmluZyB0aGFuIENQVSBhbmQgRFJBTSBhcmUuCisgKi8KKyNk ZWZpbmUgWlgyOV9QTExfVkNPX01BWF9GUkVRCQkJKDEzMDAgKiBIWl9QRVJfTUhaKQorI2RlZmlu ZSBaWDI5X1BMTF9WQ09fTUlOX0ZSRVEJCQkoOTAwICogSFpfUEVSX01IWikKKworc3RydWN0IHp4 MjlfY2xrX3BsbCB7CisJc3RydWN0IGNsa19odwlodzsKKwlzdHJ1Y3QgZGV2aWNlCSpkZXY7CisJ c3RydWN0IHJlZ21hcAkqbWFwOworCXUxNgkJcmVnOworfTsKKworc3RhdGljIGlubGluZSBzdHJ1 Y3QgengyOV9jbGtfcGxsICp0b196eDI5X2Nsa19wbGwoc3RydWN0IGNsa19odyAqaHcpCit7CisJ cmV0dXJuIGNvbnRhaW5lcl9vZihodywgc3RydWN0IHp4MjlfY2xrX3BsbCwgaHcpOworfQorCitz dGF0aWMgaW50IHp4MjlfcGxsX2lzX3ByZXBhcmVkKHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0 cnVjdCB6eDI5X2Nsa19wbGwgKnBsbCA9IHRvX3p4MjlfY2xrX3BsbChodyk7CisJaW50IHJlczsK KworCXJlcyA9IHJlZ21hcF90ZXN0X2JpdHMocGxsLT5tYXAsIHBsbC0+cmVnLCBaWDI5X1BMTF9E SVNBQkxFKTsKKwlpZiAocmVzIDwgMCkKKwkJcmV0dXJuIHJlczsKKworCXJldHVybiAhcmVzOwor fQorCitzdGF0aWMgaW50IHp4MjlfcGxsX3ByZXBhcmUoc3RydWN0IGNsa19odyAqaHcpCit7CisJ c3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsID0gdG9fengyOV9jbGtfcGxsKGh3KTsKKwl1MzIgdmFs ID0gMDsKKwlpbnQgcmVzOworCisJcmVzID0gcmVnbWFwX2NsZWFyX2JpdHMocGxsLT5tYXAsIHBs bC0+cmVnLCBaWDI5X1BMTF9ESVNBQkxFKTsKKwlpZiAocmVzIDwgMCkKKwkJcmV0dXJuIHJlczsK KworCS8qIExvY2sgZHVyYXRpb24gaXMgdXN1YWxseSBiZXR3ZWVuIDMwMCB1cyBhbmQgNTAwIHVz ICovCisJcmVzID0gcmVnbWFwX3JlYWRfcG9sbF90aW1lb3V0KHBsbC0+bWFwLCBwbGwtPnJlZywg dmFsLCB2YWwgJiBaWDI5X1BMTF9MT0NLRUQsIDUwLCAyMDAwKTsKKwlpZiAocmVzKSB7CisJCXJl Z21hcF9zZXRfYml0cyhwbGwtPm1hcCwgcGxsLT5yZWcsIFpYMjlfUExMX0RJU0FCTEUpOworCQlk ZXZfZXJyKHBsbC0+ZGV2LCAiJXM6IFBMTCBwcmVwYXJlIGZhaWxlZDogJWQuIENvbmZpZyB2YWx1 ZSAweCUwOHhcbiIsCisJCQljbGtfaHdfZ2V0X25hbWUoJnBsbC0+aHcpLCByZXMsIHZhbCk7CisJ fQorCXJldHVybiByZXM7Cit9CisKK3N0YXRpYyB2b2lkIHp4MjlfcGxsX3VucHJlcGFyZShzdHJ1 Y3QgY2xrX2h3ICpodykKK3sKKwlzdHJ1Y3QgengyOV9jbGtfcGxsICpwbGwgPSB0b196eDI5X2Ns a19wbGwoaHcpOworCisJcmVnbWFwX3NldF9iaXRzKHBsbC0+bWFwLCBwbGwtPnJlZywgWlgyOV9Q TExfRElTQUJMRSk7Cit9CisKK3N0YXRpYyBpbnQgengyOV9wbGxfaXNfZW5hYmxlZChzdHJ1Y3Qg Y2xrX2h3ICpodykKK3sKKwlzdHJ1Y3QgengyOV9jbGtfcGxsICpwbGwgPSB0b196eDI5X2Nsa19w bGwoaHcpOworCWludCByZXM7CisKKwlyZXMgPSByZWdtYXBfdGVzdF9iaXRzKHBsbC0+bWFwLCBw bGwtPnJlZyArIFpYMjlfUExMX1JFRzJfT0ZGU0VULAorCQkJICAgICAgIFpYMjlfUExMX1BPU1RE SVZfT1VUX0RJU0FCTEUpOworCWlmIChyZXMgPCAwKQorCQlyZXR1cm4gcmVzOworCisJcmV0dXJu ICFyZXM7Cit9CisKK3N0YXRpYyBpbnQgengyOV9wbGxfZW5hYmxlKHN0cnVjdCBjbGtfaHcgKmh3 KQoreworCXN0cnVjdCB6eDI5X2Nsa19wbGwgKnBsbCA9IHRvX3p4MjlfY2xrX3BsbChodyk7CisK KwlyZXR1cm4gcmVnbWFwX2NsZWFyX2JpdHMocGxsLT5tYXAsIHBsbC0+cmVnICsgWlgyOV9QTExf UkVHMl9PRkZTRVQsCisJCQkJIFpYMjlfUExMX1BPU1RESVZfT1VUX0RJU0FCTEUpOworfQorCitz dGF0aWMgdm9pZCB6eDI5X3BsbF9kaXNhYmxlKHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVj dCB6eDI5X2Nsa19wbGwgKnBsbCA9IHRvX3p4MjlfY2xrX3BsbChodyk7CisKKwlyZWdtYXBfc2V0 X2JpdHMocGxsLT5tYXAsIHBsbC0+cmVnICsgWlgyOV9QTExfUkVHMl9PRkZTRVQsCisJCQlaWDI5 X1BMTF9QT1NURElWX09VVF9ESVNBQkxFKTsKK30KKworc3RhdGljIHVuc2lnbmVkIGxvbmcgengy OV9wbGxfZ2V0X3JhdGUoY29uc3Qgc3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsLCB1bnNpZ25lZCBs b25nIHBhcmVudF9yYXRlLAorCQkJCSAgICAgICB1MzIgc2V0dGluZykKK3sKKwl1bnNpZ25lZCBs b25nIHJlZmRpdiwgZmJkaXYsIHBvc3RkaXYxLCBwb3N0ZGl2MiwgZnJlcTsKKwljb25zdCBjaGFy ICpuYW1lID0gY2xrX2h3X2dldF9uYW1lKCZwbGwtPmh3KTsKKwl1NjQgdmNvOworCisJcmVmZGl2 ID0gKHNldHRpbmcgJiBaWDI5X1BMTF9SRUZESVZfTUFTSykgPj4gWlgyOV9QTExfUkVGRElWX1NI SUZUOworCWZiZGl2ID0gKHNldHRpbmcgJiBaWDI5X1BMTF9GQkRJVl9NQVNLKSA+PiBaWDI5X1BM TF9GQkRJVl9TSElGVDsKKwlwb3N0ZGl2MSA9IChzZXR0aW5nICYgWlgyOV9QTExfUE9TVERJVjFf TUFTSykgPj4gWlgyOV9QTExfUE9TVERJVjFfU0hJRlQ7CisJcG9zdGRpdjIgPSAoc2V0dGluZyAm IFpYMjlfUExMX1BPU1RESVYyX01BU0spID4+IFpYMjlfUExMX1BPU1RESVYyX1NISUZUOworCWRl dl9kYmcocGxsLT5kZXYsICIlczogcmVmZXJlbmNlIGNsb2NrICVsdSBIeiwgUExMIHNldHRpbmcg MHglMDh4XG4iLAorCQluYW1lLCBwYXJlbnRfcmF0ZSwgc2V0dGluZyk7CisKKwlpZiAoIXJlZmRp diB8fCAhcG9zdGRpdjEgfHwgIXBvc3RkaXYyKSB7CisJCWRldl9lcnIocGxsLT5kZXYsICIlczog ZGl2aWRlIGJ5IHplcm8gKCVsdSwgJWx1LCAlbHUpXG4iLCBuYW1lLCByZWZkaXYsIHBvc3RkaXYx LAorCQkJcG9zdGRpdjIpOworCQlyZXR1cm4gMDsKKwl9CisKKwl2Y28gPSBkaXZfdTY0KCh1NjQp cGFyZW50X3JhdGUgKiBmYmRpdiwgcmVmZGl2KTsKKwlmcmVxID0gZGl2X3U2NChkaXZfdTY0KHZj bywgcG9zdGRpdjEpLCBwb3N0ZGl2Mik7CisJZGV2X2RiZyhwbGwtPmRldiwgIiVzOiByZWZkaXYg JWx1IGZiZGl2ICVsdVxuIiwgbmFtZSwgcmVmZGl2LCBmYmRpdik7CisJZGV2X2RiZyhwbGwtPmRl diwgIiVzOiBwb3N0ZGl2MSAlbHUgcG9zdGRpdjIgJWx1XG4iLCBuYW1lLCBwb3N0ZGl2MSwgcG9z dGRpdjIpOworCisJZGV2X2RiZyhwbGwtPmRldiwgIiVzOiAlbHUgTUh6XG4iLCBuYW1lLCBmcmVx IC8gSFpfUEVSX01IWik7CisKKwlyZXR1cm4gZnJlcTsKK30KKworc3RhdGljIHVuc2lnbmVkIGxv bmcgengyOV9wbGxfcmVjYWxjX3JhdGUoc3RydWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcg cGFyZW50X3JhdGUpCit7CisJc3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsID0gdG9fengyOV9jbGtf cGxsKGh3KTsKKwl1MzIgdmFsOworCWludCByZXM7CisKKwlyZXMgPSByZWdtYXBfcmVhZChwbGwt Pm1hcCwgcGxsLT5yZWcsICZ2YWwpOworCWlmIChyZXMgPCAwKSB7CisJCWRldl9lcnIocGxsLT5k ZXYsICIlczogRmFpbGVkIHRvIHJlYWQgUExMIHNldHRpbmdzXG4iLCBjbGtfaHdfZ2V0X25hbWUo JnBsbC0+aHcpKTsKKwkJcmV0dXJuIDA7CisJfQorCisJcmV0dXJuIHp4MjlfcGxsX2dldF9yYXRl KHBsbCwgcGFyZW50X3JhdGUsIHZhbCk7Cit9CisKK3N0YXRpYyB1MzIgengyOV9wbGxfY2FsY192 YWx1ZXMoY29uc3Qgc3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsLCB1bnNpZ25lZCBsb25nIHBhcmVu dF9yYXRlLAorCQkJCXVuc2lnbmVkIGxvbmcgcmF0ZSwgdW5zaWduZWQgbG9uZyBtaW5fcmF0ZSwg dW5zaWduZWQgbG9uZyBtYXhfcmF0ZSkKK3sKKwljb25zdCB1bnNpZ25lZCBpbnQgcG9zdGRpdjFf bWF4ID0gKDEgPDwgaHdlaWdodDMyKFpYMjlfUExMX1BPU1RESVYxX01BU0spKSAtIDE7CisJY29u c3QgdW5zaWduZWQgaW50IHBvc3RkaXYyX21heCA9ICgxIDw8IGh3ZWlnaHQzMihaWDI5X1BMTF9Q T1NURElWMl9NQVNLKSkgLSAxOworCXVuc2lnbmVkIGxvbmcgZmJkaXYsIHJlZmRpdiwgYmVzdF9m YmRpdiA9IDAsIGJlc3RfcmVmZGl2ID0gMDsKKwl1MzIgcG9zdGRpdjEgPSAwLCBwb3N0ZGl2MiA9 IDAsIGksIGosIHNldHRpbmc7CisJY29uc3QgY2hhciAqbmFtZSA9IGNsa19od19nZXRfbmFtZSgm cGxsLT5odyk7CisJbG9uZyBiZXN0ID0gTE9OR19NQVg7CisKKwkvKgorCSAqIFRoaXMgY29kZSBw cm9kdWNlcyB0aGUgc2FtZSBWQ08gc2V0dGluZ3MgdGhhdCB0aGUgYm9vdCBsb2FkZXIgYW5kIHN0 b2NrIGZpcm13YXJlIHVzZSBmb3IKKwkgKiB0aGUgc3RhbmRhcmQgZnJlcXVlbmNpZXMuIEl0IGhh cyBzZWVuIG9ubHkgdmVyeSBsaXR0bGUgbWFudWFsIHRlc3RpbmcgYmV5b25kIHRoYXQuCisJICoK KwkgKiBUaGUgZ29hbCBpcyB0byBmaW5kIGEgVkNPIHNldHRpbmcgdGhhdCBnZXRzIHVzIGFzIGNs b3NlIGFzIHBvc3NpYmxlIHRvIHRoZSBkZXNpcmVkIG91dHB1dAorCSAqIHJhdGUsIHdoaWxlIGJl aW5nIHdpdGhpbiB0aGUgVkNPJ3Mgb3BlcmF0aW5nIGxpbWl0cyBhbmQgYWNoaWV2YWJsZSB3aXRo IHRoZSBpbnB1dCB2YWx1ZQorCSAqIHJhbmdlLiBJdCBpcyBpdGVyYXRpbmcgb3ZlciBwb3NzaWJs ZSBwb3N0LVZDTyBkaXZpZGVyIHZhbHVlcyAoMS03KSooMS03KSB0byBsb29rIGZvcgorCSAqIHZh bGlkIFZDTyB0YXJnZXQgZnJlcXVlbmNpZXMgYW5kIHRoZW4gbG9va3MgZm9yIHJlZmRpdiBhbmQg ZmJkaXYgdmFsdWVzIHRvIGFjaGlldmUgdGhlCisJICogVkNPIGZyZXF1ZW5jeSBmcm9tIHRoZSBy ZWZlcmVuY2UgZnJlcXVlbmN5LgorCSAqLworCWZvciAoaiA9IDE7IGogPD0gcG9zdGRpdjJfbWF4 OyBqKyspIHsKKwkJZm9yIChpID0gMTsgaSA8PSBwb3N0ZGl2MV9tYXg7IGkrKykgeworCQkJdTY0 IHZjbyA9ICh1NjQpcmF0ZSAqIGkgKiBqOworCQkJdW5zaWduZWQgbG9uZyBvdXQ7CisKKwkJCWlm ICh2Y28gPiBaWDI5X1BMTF9WQ09fTUFYX0ZSRVEgfHwgdmNvIDwgWlgyOV9QTExfVkNPX01JTl9G UkVRKQorCQkJCWNvbnRpbnVlOworCisJCQlyYXRpb25hbF9iZXN0X2FwcHJveGltYXRpb24odmNv LCBwYXJlbnRfcmF0ZSwKKwkJCQkJCSAgICAoMSA8PCBod2VpZ2h0MzIoWlgyOV9QTExfRkJESVZf TUFTSykpIC0gMSwKKwkJCQkJCSAgICAoMSA8PCBod2VpZ2h0MzIoWlgyOV9QTExfUkVGRElWX01B U0spKSAtIDEsCisJCQkJCQkgICAgJmZiZGl2LCAmcmVmZGl2KTsKKwkJCXNldHRpbmcgPSBmYmRp diA8PCBaWDI5X1BMTF9GQkRJVl9TSElGVDsKKwkJCXNldHRpbmcgfD0gcmVmZGl2IDw8IFpYMjlf UExMX1JFRkRJVl9TSElGVDsKKwkJCXNldHRpbmcgfD0gaSA8PCBaWDI5X1BMTF9QT1NURElWMV9T SElGVDsKKwkJCXNldHRpbmcgfD0gaiA8PCBaWDI5X1BMTF9QT1NURElWMl9TSElGVDsKKwkJCW91 dCA9IHp4MjlfcGxsX2dldF9yYXRlKHBsbCwgcGFyZW50X3JhdGUsIHNldHRpbmcpOworCisJCQlp ZiAob3V0IDwgbWluX3JhdGUgfHwgb3V0ID4gbWF4X3JhdGUpCisJCQkJY29udGludWU7CisKKwkJ CWlmIChhYnNfZGlmZihvdXQsIHJhdGUpID4gYmVzdCkKKwkJCQljb250aW51ZTsKKworCQkJaWYg KGFic19kaWZmKG91dCwgcmF0ZSkgPCBiZXN0KSB7CisJCQkJcG9zdGRpdjEgPSBpOworCQkJCXBv c3RkaXYyID0gajsKKwkJCQliZXN0X2ZiZGl2ID0gZmJkaXY7CisJCQkJYmVzdF9yZWZkaXYgPSBy ZWZkaXY7CisJCQkJYmVzdCA9IGFic19kaWZmKG91dCwgcmF0ZSk7CisKKwkJCQlpZiAoIWJlc3Qp CisJCQkJCWdvdG8gc2VhcmNoX2RvbmU7CisJCQl9CisJCX0KKwl9CitzZWFyY2hfZG9uZToKKwor CWlmICghcG9zdGRpdjEpIHsKKwkJZGV2X2VycihwbGwtPmRldiwgIkRpZCBub3QgZmluZCBhIHNl dHRpbmcgZm9yICVsdSBIeiwgcGFyZW50ICVsdSBIelxuIiwKKwkJCXJhdGUsIHBhcmVudF9yYXRl KTsKKwkJcmV0dXJuIDA7CisJfQorCisJZGV2X2RiZyhwbGwtPmRldiwgIiVzOiBwYXJlbnQgcmF0 ZSAlbHVcbiIsIG5hbWUsIHBhcmVudF9yYXRlKTsKKwlkZXZfZGJnKHBsbC0+ZGV2LCAiJXM6IGZv dW5kIFZDTyBkaXZpZGVycyAldSBhbmQgJXVcbiIsIG5hbWUsIHBvc3RkaXYxLCBwb3N0ZGl2Mik7 CisJZGV2X2RiZyhwbGwtPmRldiwgIiVzOiBWQ08gdGFyZ2V0IHJhdGUgJWx1XG4iLCBuYW1lLCBy YXRlICogcG9zdGRpdjEgKiBwb3N0ZGl2Mik7CisKKwlkZXZfZGJnKHBsbC0+ZGV2LCAiJXM6IEdv dCBmYmRpdiA9ICVsdSByZWZkaXYgPSAlbHVcbiIsIG5hbWUsIGJlc3RfZmJkaXYsIGJlc3RfcmVm ZGl2KTsKKworCXNldHRpbmcgPSBiZXN0X2ZiZGl2IDw8IFpYMjlfUExMX0ZCRElWX1NISUZUOwor CXNldHRpbmcgfD0gYmVzdF9yZWZkaXYgPDwgWlgyOV9QTExfUkVGRElWX1NISUZUOworCXNldHRp bmcgfD0gcG9zdGRpdjEgPDwgWlgyOV9QTExfUE9TVERJVjFfU0hJRlQ7CisJc2V0dGluZyB8PSBw b3N0ZGl2MiA8PCBaWDI5X1BMTF9QT1NURElWMl9TSElGVDsKKwlkZXZfZGJnKHBsbC0+ZGV2LCAi JXM6IEZpbmFsIHNldHRpbmcgMHglMDh4XG4iLCBuYW1lLCBzZXR0aW5nKTsKKworCXJldHVybiBz ZXR0aW5nOworfQorCitzdGF0aWMgaW50IHp4MjlfcGxsX2RldGVybWluZV9yYXRlKHN0cnVjdCBj bGtfaHcgKmh3LCBzdHJ1Y3QgY2xrX3JhdGVfcmVxdWVzdCAqcmVxKQoreworCXN0cnVjdCB6eDI5 X2Nsa19wbGwgKnBsbCA9IHRvX3p4MjlfY2xrX3BsbChodyk7CisJdW5zaWduZWQgbG9uZyBuZXdf cmF0ZTsKKwl1MzIgc2V0dGluZzsKKworCS8qCisJICogVE9ETzogRFBMTCBjYW4gc3dpdGNoIGJl dHdlZW4gdHdvIHBhcmVudHMsIG9uZSBvZiB3aGljaCBpcyBhbm90aGVyIFBMTC4gVGFrZSB0aGlz IGludG8KKwkgKiBhY2NvdW50IHdoZW4gc2VhcmNoaW5nIHRoZSBjb25maWcgc3BhY2UgYW5kIHNl dCByZXEtPmJlc3RfcGFyZW50X3JhdGUuCisJICoKKwkgKiBJbiBwcmFjdGljZSBpdCBzaG91bGRu J3QgbWF0dGVyIHRob3VnaC4gRHBsbCBpcyBhbHdheXMgY29uZmlndXJlZCB0byBhIGZpeGVkIGZy ZXF1ZW5jeQorCSAqIGFuZCBpcyB0aGUgb25seSBjbG9jayB3aXRoIGEgc3dpdGNoYWJsZSBwYXJl bnQuCisJICovCisJaWYgKCFyZXEtPmJlc3RfcGFyZW50X3JhdGUpIHsKKwkJZGV2X2VycihwbGwt PmRldiwgIkRpZCBub3QgZXhwZWN0IGJlc3RfcGFyZW50X3JhdGU9MFxuIik7CisJCXJldHVybiAt RUlOVkFMOworCX0KKworCXNldHRpbmcgPSB6eDI5X3BsbF9jYWxjX3ZhbHVlcyhwbGwsIHJlcS0+ YmVzdF9wYXJlbnRfcmF0ZSwgcmVxLT5yYXRlLCByZXEtPm1pbl9yYXRlLAorCQkJCSAgICAgICBy ZXEtPm1heF9yYXRlKTsKKwlpZiAoIXNldHRpbmcpCisJCXJldHVybiAtRUlOVkFMOworCisJbmV3 X3JhdGUgPSB6eDI5X3BsbF9nZXRfcmF0ZShwbGwsIHJlcS0+YmVzdF9wYXJlbnRfcmF0ZSwgc2V0 dGluZyk7CisJaWYgKG5ld19yYXRlICE9IHJlcS0+cmF0ZSkgeworCQlkZXZfd2FybihwbGwtPmRl diwgIkRpZCBub3QgZmluZCBhbiBleGFjdCBtYXRjaC4gV2FudCAlbHUsIGdvdCAlbHVcbiIsCisJ CQkgcmVxLT5yYXRlLCBuZXdfcmF0ZSk7CisJCXJlcS0+cmF0ZSA9IG5ld19yYXRlOworCX0KKwor CXJldHVybiAwOworfQorCitzdGF0aWMgaW50IHp4MjlfcGxsX3NldF9yYXRlKHN0cnVjdCBjbGtf aHcgKmh3LCB1bnNpZ25lZCBsb25nIHJhdGUsCisJCQkgICAgIHVuc2lnbmVkIGxvbmcgcGFyZW50 X3JhdGUpCit7CisJc3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsID0gdG9fengyOV9jbGtfcGxsKGh3 KTsKKwl1MzIgc2V0dGluZzsKKworCS8qCisJICogVE9ETzogSW1wbGVtZW50IGdyYWR1YWwgUExM IHJhdGUgY2hhbmdlLiBQTExzIGNhbiBiZSBjaGFuZ2VkIHdoaWxlIHRoZXkgYXJlIHJ1bm5pbmcg YW5kCisJICogZG93bnN0cmVhbSBoYXJkd2FyZSBpcyBnZW5lcmFsbHkgZmluZSB3aXRoIHRoYXQu IFRoZSBleGNlcHRpb24gaXMgRFJBTSwgd2hpY2ggcmVhZHMKKwkgKiBpbmNvcnJlY3QgdmFsdWVz IGlmIGNoYW5nZWQgdG9vIGZhc3QuCisJICoKKwkgKiBDaGFuZ2luZyB0aGUgbXBsbCByYXRlIGlz IHBvdGVudGlhbGx5IHVzZWZ1bCBmb3Igb3Zlci91bmRlcmNsb2NraW5nLiBHYXRpbmcgbXBsbCBp cworCSAqIHVucmVhbGlzdGljIGJlY2F1c2UgdG9vIG1hbnkgZGV2aWNlcyBkZXBlbmQgb24gaXQu CisJICovCisJc2V0dGluZyA9IHp4MjlfcGxsX2NhbGNfdmFsdWVzKHBsbCwgcGFyZW50X3JhdGUs IHJhdGUsIHJhdGUsIHJhdGUpOworCWlmICghc2V0dGluZykKKwkJcmV0dXJuIC1FSU5WQUw7CisK KwlkZXZfaW5mbyhwbGwtPmRldiwgIiVzOiBTZXR0aW5nIG5ldyBjb25maWd1cmF0aW9uOiAweCUw OHhcbiIsIGNsa19od19nZXRfbmFtZShodyksIHNldHRpbmcpOworCisJcmV0dXJuIHJlZ21hcF91 cGRhdGVfYml0cyhwbGwtPm1hcCwgcGxsLT5yZWcsIDB4MDBmZmZmZmYsIHNldHRpbmcpOworfQor CitzdGF0aWMgdTggengyOV9wbGxfZ2V0X3BhcmVudChzdHJ1Y3QgY2xrX2h3ICpodykKK3sKKwlz dHJ1Y3QgengyOV9jbGtfcGxsICpwbGwgPSB0b196eDI5X2Nsa19wbGwoaHcpOworCXUzMiB2YWw7 CisJaW50IHJlczsKKworCXJlcyA9IHJlZ21hcF9yZWFkKHBsbC0+bWFwLCBwbGwtPnJlZywgJnZh bCk7CisJaWYgKHJlcyA8IDApCisJCXJldHVybiAweGZmOworCisJdmFsID0gKHZhbCAmIFpYMjlf UExMX1BBUkVOVF9NQVNLKSA+PiBaWDI5X1BMTF9QQVJFTlRfU0hJRlQ7CisJZGV2X2RiZyhwbGwt PmRldiwgIiVzOiBQYXJlbnQgMHgleFxuIiwgY2xrX2h3X2dldF9uYW1lKGh3KSwgdmFsKTsKKwor CXJldHVybiB2YWw7Cit9CisKK3N0YXRpYyBpbnQgengyOV9wbGxfc2V0X3BhcmVudChzdHJ1Y3Qg Y2xrX2h3ICpodywgdTggaW5kZXgpCit7CisJc3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsID0gdG9f engyOV9jbGtfcGxsKGh3KTsKKwl1MzIgaWR4X3NoaWZ0ID0gaW5kZXggPDwgWlgyOV9QTExfUEFS RU5UX1NISUZUOworCWludCByZXM7CisJdTMyIHZhbDsKKworCXJlcyA9IHJlZ21hcF91cGRhdGVf Yml0cyhwbGwtPm1hcCwgcGxsLT5yZWcsIFpYMjlfUExMX1BBUkVOVF9NQVNLLCBpZHhfc2hpZnQp OworCWlmIChyZXMgPCAwKQorCQlyZXR1cm4gcmVzOworCisJcmVzID0gcmVnbWFwX3JlYWQocGxs LT5tYXAsIHBsbC0+cmVnLCAmdmFsKTsKKwlpZiAocmVzIDwgMCkKKwkJcmV0dXJuIHJlczsKKwor CWlmICgodmFsICYgWlgyOV9QTExfUEFSRU5UX01BU0spICE9IGlkeF9zaGlmdCkgeworCQlkZXZf ZXJyKHBsbC0+ZGV2LCAiSGFyZHdhcmUgcmVqZWN0ZWQgUExMIHBhcmVudCAldVxuIiwgaW5kZXgp OworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCB6 eDI5X3BsbF9pbml0KHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCB6eDI5X2Nsa19wbGwg KnBsbCA9IHRvX3p4MjlfY2xrX3BsbChodyk7CisJY29uc3QgY2hhciAqbmFtZSA9IGNsa19od19n ZXRfbmFtZShodyk7CisJaW50IHJlczsKKwl1MzIgdmFsOworCisJZGV2X2RiZyhwbGwtPmRldiwg IiVzOiBpbml0aWFsaXppbmdcbiIsIG5hbWUpOworCisJLyoKKwkgKiBUaGUgZnJhY3Rpb25hbCB2 YWx1ZSBpcyBub3QgeWV0IGltcGxlbWVudGVkLiBJdCB3b3JrcyBhdCBsZWFzdCB3aXRoIGRwbGws IGJ1dCBJIGhhdmUKKwkgKiBuZXZlciBzZWVuIGl0IHVzZWQgb24gYWN0dWFsIGhhcmR3YXJlLgor CSAqLworCXJlcyA9IHJlZ21hcF9yZWFkKHBsbC0+bWFwLCBwbGwtPnJlZyArIFpYMjlfUExMX1JF RzJfT0ZGU0VULCAmdmFsKTsKKwlpZiAocmVzIDwgMCkKKwkJcmV0dXJuIHJlczsKKworCWlmICh2 YWwgJiBaWDI5X1BMTF9GUkFDVCkgeworCQlkZXZfd2FybihwbGwtPmRldiwgIiVzOiB1bnN1cHBv cnRlZCBub256ZXJvIGZyYWN0aW9uYWwgdmFsdWUgMHglMDhseFxuIiwKKwkJCSBuYW1lLCB2YWwg JiBaWDI5X1BMTF9GUkFDVCk7CisJfQorCisJLyoKKwkgKiBSZW1vdmUgdGhlIGJ5cGFzcyBmbGFn IHNvIHdlIGRvbid0IGhhdmUgdG8gYm90aGVyIHdpdGggaXQgaW4gZW5hYmxlL2Rpc2FibGUuIEkg aGF2ZSBuZXZlcgorCSAqIHNlZW4gaXQgc2V0IGJ5IHRoZSBlYXJsaWVyIGJvb3Qgc3RhZ2VzIGFu eWhvdy4KKwkgKi8KKwlyZXMgPSByZWdtYXBfY2xlYXJfYml0cyhwbGwtPm1hcCwgcGxsLT5yZWcs IFpYMjlfUExMX0JZUEFTUyk7CisJaWYgKHJlcyA8IDApCisJCXJldHVybiByZXM7CisKKwlyZXMg PSByZWdtYXBfdGVzdF9iaXRzKHBsbC0+bWFwLCBwbGwtPnJlZywgWlgyOV9QTExfRElTQUJMRSk7 CisJaWYgKHJlcyA+IDApIHsKKwkJLyoKKwkJICogU2V0IFpYMjlfUExMX1BPU1RESVZfT1VUX0RJ U0FCTEUgZm9yIFBMTHMgdGhhdCBoYXZlIFpYMjlfUExMX0RJU0FCTEUgZm9yCisJCSAqIGNvbnNp c3RlbmN5IHdpdGggLmVuYWJsZSBhbmQgLnByZXBhcmUuIFRoaXMgZW5zdXJlcyB0aGF0IC5wcmVw YXJlIGRvZXNuJ3QKKwkJICogaW5hZHZlcnRlbnRseSBlbmFibGUgUExMcyB3aXRob3V0IC5lbmFi bGUgYmVpbmcgY2FsbGVkLgorCQkgKi8KKwkJcmVzID0gcmVnbWFwX3NldF9iaXRzKHBsbC0+bWFw LCBwbGwtPnJlZyArIFpYMjlfUExMX1JFRzJfT0ZGU0VULAorCQkJCSAgICAgIFpYMjlfUExMX1BP U1RESVZfT1VUX0RJU0FCTEUpOworCX0KKworCXJldHVybiByZXM7Cit9CisKK3N0YXRpYyBjb25z dCBzdHJ1Y3QgY2xrX29wcyB6eDI5X3BsbF9vcHMgPSB7CisJLmluaXQJCT0gengyOV9wbGxfaW5p dCwKKwkuaXNfcHJlcGFyZWQJPSB6eDI5X3BsbF9pc19wcmVwYXJlZCwKKwkucHJlcGFyZQk9IHp4 MjlfcGxsX3ByZXBhcmUsCisJLnVucHJlcGFyZQk9IHp4MjlfcGxsX3VucHJlcGFyZSwKKwkuaXNf ZW5hYmxlZAk9IHp4MjlfcGxsX2lzX2VuYWJsZWQsCisJLmVuYWJsZQkJPSB6eDI5X3BsbF9lbmFi bGUsCisJLmRpc2FibGUJPSB6eDI5X3BsbF9kaXNhYmxlLAorCS5yZWNhbGNfcmF0ZQk9IHp4Mjlf cGxsX3JlY2FsY19yYXRlLAorCS5kZXRlcm1pbmVfcmF0ZSA9IHp4MjlfcGxsX2RldGVybWluZV9y YXRlLAorCS5nZXRfcGFyZW50CT0gengyOV9wbGxfZ2V0X3BhcmVudCwKKwkuc2V0X3BhcmVudAk9 IHp4MjlfcGxsX3NldF9wYXJlbnQsCisJLnNldF9yYXRlCT0gengyOV9wbGxfc2V0X3JhdGUsCit9 OworCisvKgorICogQSBQTEwgdGhhdCBjYW4gYmUgYSBwYXJlbnQgb2YgYW5vdGhlciBQTEwgbmVl ZHMgdG8gcHJvZHVjZSBhbiBvdXRwdXQgc2lnbmFsIHdoZW4gcHJlcGFyZWQsCisgKiBvdGhlcndp c2UgdGhlIGRvd25zdHJlYW0gUExMJ3MgcHJlcGFyZSgpIHdpbGwgZmFpbCB0byBhY3F1aXJlIGEg bG9jay4KKyAqLworc3RhdGljIGludCB6eDI5X3BsbF9ub2Rpc2FibGVfaW5pdChzdHJ1Y3QgY2xr X2h3ICpodykKK3sKKwlzdHJ1Y3QgengyOV9jbGtfcGxsICpwbGwgPSB0b196eDI5X2Nsa19wbGwo aHcpOworCWNvbnN0IGNoYXIgKm5hbWUgPSBjbGtfaHdfZ2V0X25hbWUoaHcpOworCWludCByZXM7 CisJdTMyIHZhbDsKKworCWRldl9kYmcocGxsLT5kZXYsICIlczogaW5pdGlhbGl6aW5nLCBwcmVw YXJlLWlzLWVuYWJsZWRcbiIsIG5hbWUpOworCisJcmVzID0gcmVnbWFwX3JlYWQocGxsLT5tYXAs IHBsbC0+cmVnICsgWlgyOV9QTExfUkVHMl9PRkZTRVQsICZ2YWwpOworCWlmIChyZXMgPCAwKQor CQlyZXR1cm4gcmVzOworCisJaWYgKHZhbCAmIFpYMjlfUExMX0ZSQUNUKSB7CisJCWRldl93YXJu KHBsbC0+ZGV2LCAiJXM6IHVuc3VwcG9ydGVkIG5vbnplcm8gZnJhY3Rpb25hbCB2YWx1ZSAweCUw OGx4XG4iLAorCQkJIG5hbWUsIHZhbCAmIFpYMjlfUExMX0ZSQUNUKTsKKwl9CisKKwlyZXMgPSBy ZWdtYXBfY2xlYXJfYml0cyhwbGwtPm1hcCwgcGxsLT5yZWcsIFpYMjlfUExMX0JZUEFTUyk7CisJ aWYgKHJlcyA8IDApCisJCXJldHVybiByZXM7CisKKwlyZXR1cm4gcmVnbWFwX2NsZWFyX2JpdHMo cGxsLT5tYXAsIHBsbC0+cmVnICsgWlgyOV9QTExfUkVHMl9PRkZTRVQsCisJCQkJIFpYMjlfUExM X1BPU1RESVZfT1VUX0RJU0FCTEUpOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IGNsa19vcHMg engyOV9wbGxfbm9kaXNhYmxlX29wcyA9IHsKKwkuaW5pdAkJPSB6eDI5X3BsbF9ub2Rpc2FibGVf aW5pdCwKKwkuaXNfcHJlcGFyZWQJPSB6eDI5X3BsbF9pc19wcmVwYXJlZCwKKwkucHJlcGFyZQk9 IHp4MjlfcGxsX3ByZXBhcmUsCisJLnVucHJlcGFyZQk9IHp4MjlfcGxsX3VucHJlcGFyZSwKKwku cmVjYWxjX3JhdGUJPSB6eDI5X3BsbF9yZWNhbGNfcmF0ZSwKKwkuZGV0ZXJtaW5lX3JhdGUgPSB6 eDI5X3BsbF9kZXRlcm1pbmVfcmF0ZSwKKwkuZ2V0X3BhcmVudAk9IHp4MjlfcGxsX2dldF9wYXJl bnQsCisJLnNldF9wYXJlbnQJPSB6eDI5X3BsbF9zZXRfcGFyZW50LAorCS5zZXRfcmF0ZQk9IHp4 MjlfcGxsX3NldF9yYXRlLAorfTsKKwogc3RydWN0IGNsa19odyAqenhfY2xrX3JlZ2lzdGVyX3Bs bChzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCByZWdtYXAgKnJlZ21hcCwKLQkJCQkgICBjb25z dCBzdHJ1Y3QgenhfcGxsX2Rlc2MgKmRlc2MsCi0JCQkJICAgc3RydWN0IGNsa19odyAqIGNvbnN0 ICpjbG9ja3MpCisJCQkJICAgY29uc3Qgc3RydWN0IHp4X3BsbF9kZXNjICpkZXNjLCBzdHJ1Y3Qg Y2xrX2h3ICogY29uc3QgKmNsb2NrcykKIHsKLQlyZXR1cm4gRVJSX1BUUigtRU5PREVWKTsKKwlz dHJ1Y3QgY2xrX3BhcmVudF9kYXRhIHBhcmVudHNbQ0xLX1pYX01BWF9QQVJFTlRTXTsKKwlzdHJ1 Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0ge307CisJc3RydWN0IHp4MjlfY2xrX3BsbCAqcGxsOwor CXVuc2lnbmVkIGludCBpOworCWludCByZXM7CisKKwlwbGwgPSBkZXZtX2t6YWxsb2MoZGV2LCBz aXplb2YoKnBsbCksIEdGUF9LRVJORUwpOworCWlmICghcGxsKQorCQlyZXR1cm4gRVJSX1BUUigt RU5PTUVNKTsKKworCWlmIChkZXNjLT5mbGFncyAmIENMS19aWF9QTExfUFJFUEFSRV9JU19FTkFC TEUpCisJCWluaXQub3BzID0gJnp4MjlfcGxsX25vZGlzYWJsZV9vcHM7CisJZWxzZQorCQlpbml0 Lm9wcyA9ICZ6eDI5X3BsbF9vcHM7CisKKwlpZiAoV0FSTl9PTihkZXNjLT5udW1fcGFyZW50cyA+ IEFSUkFZX1NJWkUocGFyZW50cykpKQorCQlyZXR1cm4gRVJSX1BUUigtRUlOVkFMKTsKKworCWZv ciAoaSA9IDA7IGkgPCBkZXNjLT5udW1fcGFyZW50czsgKytpKQorCQlwYXJlbnRzW2ldID0genhf Z2V0X3BhcmVudCgmZGVzYy0+cGFyZW50c1tpXSwgY2xvY2tzKTsKKworCWluaXQubmFtZSA9IGRl c2MtPm5hbWU7CisJaW5pdC5wYXJlbnRfZGF0YSA9IHBhcmVudHM7CisJaW5pdC5udW1fcGFyZW50 cyA9IGRlc2MtPm51bV9wYXJlbnRzOworCisJLyoKKwkgKiBEaXNhbGxvdyBsaXZlIHJlcGFyZW50 LCBidXQgYWxsb3cgcmF0ZSBjaGFuZ2VzLiBQTExzIGNhbiBoYW5kbGUgZ3JhZHVhbCBjaGFuZ2Vz IGZpbmUsIGJ1dAorCSAqIGxhcmdlIG9uZXMgY2F1c2UgYSB0ZW1wb3JhcnkgaW5jb3JyZWN0IG91 dHB1dCwgd2hpY2ggY2FuIGJyZWFrIGRvd25zdHJlYW0gZGV2aWNlcy4KKwkgKiBTZWUgengyOV9w bGxfc2V0X3JhdGUgZm9yIGNvbnNpZGVyYXRpb25zIG9uIHRoYXQuCisJICovCisJaW5pdC5mbGFn cyA9IENMS19TRVRfUEFSRU5UX0dBVEU7CisJcGxsLT5ody5pbml0ID0gJmluaXQ7CisJcGxsLT5k ZXYgPSBkZXY7CisJcGxsLT5tYXAgPSByZWdtYXA7CisJcGxsLT5yZWcgPSBkZXNjLT5yZWc7CisK KwlyZXMgPSBkZXZtX2Nsa19od19yZWdpc3RlcihkZXYsICZwbGwtPmh3KTsKKwlpZiAocmVzKQor CQlyZXR1cm4gRVJSX1BUUihyZXMpOworCisJLyoKKwkgKiBTZXQgdGhlIFBMTCByYXRlIG9ubHkg aWYgdGhlIGJvb3Rsb2FkZXIgbGVmdCBpdCBkaXNhYmxlZC4gS2VlcCB0aGUgYm9vdGxvYWRlciBz ZXR1cAorCSAqIG90aGVyd2lzZS4KKwkgKi8KKwlyZXMgPSByZWdtYXBfdGVzdF9iaXRzKHBsbC0+ bWFwLCBwbGwtPnJlZywgWlgyOV9QTExfRElTQUJMRSk7CisJaWYgKHJlcyA8IDApCisJCXJldHVy biBFUlJfUFRSKHJlcyk7CisKKwlpZiAocmVzID4gMCAmJiBkZXNjLT5yYXRlKSB7CisJCWRldl9k YmcocGxsLT5kZXYsICIlczogc2V0dGluZyB0byAlbHUgSHpcbiIsIGRlc2MtPm5hbWUsIGRlc2Mt PnJhdGUpOworCQlyZXMgPSBjbGtfc2V0X3JhdGUocGxsLT5ody5jbGssIGRlc2MtPnJhdGUpOwor CQlpZiAocmVzKQorCQkJcmV0dXJuIEVSUl9QVFIoZGV2X2Vycl9wcm9iZShkZXYsIHJlcywgIiVz OiBmYWlsZWQgdG8gc2V0IHJhdGVcbiIsCisJCQkJCQkgICAgIGRlc2MtPm5hbWUpKTsKKwl9CisK KwlyZXR1cm4gJnBsbC0+aHc7CiB9CgotLSAKMi41NC4wCgoKLS0gCmxpbnV4LXBoeSBtYWlsaW5n IGxpc3QKbGludXgtcGh5QGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cHM6Ly9saXN0cy5pbmZyYWRl YWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcGh5Cg==