From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from layka.disroot.org (layka.disroot.org [178.21.23.139]) (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 A04261D61BB; Tue, 9 Sep 2025 02:51:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=178.21.23.139 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757386322; cv=none; b=OcFMRarY11BX29K5Gc00iS4tQCn7HiTbWxU9RjBT2KycOFhDa7NbCNnoBXsuLAHMnH06gCzR/DKOus/jzG26qAbft9ildZCnJ5nppWpdYPPkaJ9P2bXUOpeEwWy9E13apdSNKJLDD+a6XAviy9Cp/BhZfyuRaUn91x669HZ9fl0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757386322; c=relaxed/simple; bh=rJ6zql9GvPc0S5blprEyBy/gNctD4hMQy6wVOb34PiQ=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=QbukWs2xbOyBHt4pFm6YkXiplto6n5f1X3dJEONmV5APUx52fCF/EUdmTcIpY2fi3bCb45ef4/5KOdXVXm9ydfllBw4hsoMZc2nYVpmjfYOc7bo32AVI8g5i9Hma8OZ1yuQGBFRkSn4iK587cBZtwPpQBCJ0uiXi4IsuD+d3MAc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=disroot.org; spf=pass smtp.mailfrom=disroot.org; dkim=pass (2048-bit key) header.d=disroot.org header.i=@disroot.org header.b=BZ+79DwK; arc=none smtp.client-ip=178.21.23.139 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=disroot.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=disroot.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=disroot.org header.i=@disroot.org header.b="BZ+79DwK" Received: from mail01.disroot.lan (localhost [127.0.0.1]) by disroot.org (Postfix) with ESMTP id 44B7722EC1; Tue, 9 Sep 2025 04:51:51 +0200 (CEST) X-Virus-Scanned: SPAM Filter at disroot.org Received: from layka.disroot.org ([127.0.0.1]) by localhost (disroot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id cUb3k8BRjNKs; Tue, 9 Sep 2025 04:51:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1757386310; bh=rJ6zql9GvPc0S5blprEyBy/gNctD4hMQy6wVOb34PiQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=BZ+79DwKXgux9NaOekFldf3z1TrMwFEm5nfKU+qzQSyY830UhXQ6opPaz84xdu9hg mCT1KAYwdlE0GlY2OnqzLe0Cp+zMPGP0HVeQ2YexIEOPRMtDuphvlYB8CW+SjNxoCc YVfDV/DRbwJlXp/sRajBkp+sqPXEOdGylGJpGanCf33sLWnbeG7+pqNR2pKuBz/DVq fYVyJ5G9BQXfyyEbq2haMwMtOX7y7HV47Efaf04IaFlncZFiMrHEy5JuxNU9J+rFhJ 0UrIZOI/gmhffSGm78Sb2rZyElO0GsdDww5TuQVe+cW56KHd3WRBaPbA9Wd6fvpraR vhDWRujn73Hjg== Date: Tue, 9 Sep 2025 02:51:29 +0000 From: Yao Zi To: Xukai Wang , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Conor Dooley Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, Samuel Holland , Troy Mitchell Subject: Re: [PATCH v8 2/3] clk: canaan: Add clock driver for Canaan K230 Message-ID: References: <20250905-b4-k230-clk-v8-0-96caa02d5428@zohomail.com> <20250905-b4-k230-clk-v8-2-96caa02d5428@zohomail.com> <0947d9cc-86ba-46e0-92aa-04f4714e7a20@zohomail.com> Precedence: bulk X-Mailing-List: linux-clk@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <0947d9cc-86ba-46e0-92aa-04f4714e7a20@zohomail.com> On Mon, Sep 08, 2025 at 10:13:15PM +0800, Xukai Wang wrote: > > On 2025/9/7 11:13, Yao Zi wrote: > >> On Fri, Sep 05, 2025 at 11:10:23AM +0800, Xukai Wang wrote: > >> This patch provides basic support for the K230 clock, which covers > >> all clocks in K230 SoC. > >> > >> The clock tree of the K230 SoC consists of a 24MHZ external crystal > >> oscillator, PLLs and an external pulse input for timerX, and their > >> derived clocks. > >> > >> Co-developed-by: Troy Mitchell > >> Signed-off-by: Troy Mitchell > >> Signed-off-by: Xukai Wang > >> --- > >> drivers/clk/Kconfig | 6 + > >> drivers/clk/Makefile | 1 + > >> drivers/clk/clk-k230.c | 2456 ++++++++++++++++++++++++++++++++++++++++++++++++ > >> 3 files changed, 2463 insertions(+) ... > >> new file mode 100644 > >> index 0000000000000000000000000000000000000000..2ba74c008b30ae3400acbd8c08550e8315dfe205 > >> --- /dev/null > >> +++ b/drivers/clk/clk-k230.c > >> @@ -0,0 +1,2456 @@ ... > > > >> +static int k230_clk_set_rate_mul(struct clk_hw *hw, unsigned long rate, > >> + unsigned long parent_rate) > >> +{ > >> + struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw); > >> + struct k230_clk_rate_self *rate_self = &clk->clk; > >> + u32 div, mul, mul_reg; > >> + > >> + if (rate > parent_rate) > >> + return -EINVAL; > >> + > >> + if (rate_self->read_only) > >> + return 0; > >> + > >> + if (k230_clk_find_approximate_mul(rate_self->mul_min, rate_self->mul_max, > >> + rate_self->div_min, rate_self->div_max, > >> + rate, parent_rate, &div, &mul)) > >> + return -EINVAL; > >> + > >> + guard(spinlock)(rate_self->lock); > >> + > >> + mul_reg = readl(rate_self->reg + clk->mul_reg_off); > >> + mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift); > >> + mul_reg |= BIT(rate_self->write_enable_bit); > >> + writel(mul_reg, rate_self->reg + clk->mul_reg_off); > >> + > >> + return 0; > >> +} > >> + > >> +static int k230_clk_set_rate_div(struct clk_hw *hw, unsigned long rate, > >> + unsigned long parent_rate) > >> +{ > >> + struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw); > >> + struct k230_clk_rate_self *rate_self = &clk->clk; > >> + u32 div, mul, div_reg; > >> + > >> + if (rate > parent_rate) > >> + return -EINVAL; > >> + > >> + if (rate_self->read_only) > >> + return 0; > >> + > >> + if (k230_clk_find_approximate_div(rate_self->mul_min, rate_self->mul_max, > >> + rate_self->div_min, rate_self->div_max, > >> + rate, parent_rate, &div, &mul)) > >> + return -EINVAL; > >> + > >> + guard(spinlock)(rate_self->lock); > >> + > >> + div_reg = readl(rate_self->reg + clk->div_reg_off); > >> + div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift); > >> + div_reg |= BIT(rate_self->write_enable_bit); > >> + writel(div_reg, rate_self->reg + clk->div_reg_off); > >> + > >> + return 0; > >> +} > >> + > >> +static int k230_clk_set_rate_mul_div(struct clk_hw *hw, unsigned long rate, > >> + unsigned long parent_rate) > >> +{ > >> + struct k230_clk_rate *clk = hw_to_k230_clk_rate(hw); > >> + struct k230_clk_rate_self *rate_self = &clk->clk; > >> + u32 div, mul, div_reg, mul_reg; > >> + > >> + if (rate > parent_rate) > >> + return -EINVAL; > >> + > >> + if (rate_self->read_only) > >> + return 0; > >> + > >> + if (k230_clk_find_approximate_mul_div(rate_self->mul_min, rate_self->mul_max, > >> + rate_self->div_min, rate_self->div_max, > >> + rate, parent_rate, &div, &mul)) > >> + return -EINVAL; > >> + > >> + guard(spinlock)(rate_self->lock); > >> + > >> + div_reg = readl(rate_self->reg + clk->div_reg_off); > >> + div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift); > >> + div_reg |= BIT(rate_self->write_enable_bit); > >> + writel(div_reg, rate_self->reg + clk->div_reg_off); > >> + > >> + mul_reg = readl(rate_self->reg + clk->mul_reg_off); > >> + mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift); > >> + mul_reg |= BIT(rate_self->write_enable_bit); > >> + writel(mul_reg, rate_self->reg + clk->mul_reg_off); > >> + > >> + return 0; > >> +} > > There are three variants of rate clocks, mul-only, div-only and mul-div > > ones, which are similar to clk-multiplier, clk-divider, > > clk-fractional-divider. > > > > The only difference is to setup new parameters for K230's rate clocks, > > a register bit, described as k230_clk_rate_self.write_enable_bit, must > > be set first. > Actually, I think the differences are not limited to just the > write_enable_bit. There are also distinct mul_min, mul_max, div_min, and > div_max values, which are not typically just 1 and (1 << bit_width) as > in standard clock divider or multiplier structures. Oops, I missed these members, so there're more differences, but... > For example, the div_min for hs_sd_card_src_rate is 2, not 1. This > affects the calculation of the approximate divider, and cannot be fully > represented if we only use the clk_divider structure. Reading through the TRM[1], I cannot find why using one as divisor isn't valid for hs_sd_card_src_rate. The clock corresponds to field hs_SDCLK_CFG.sd_cclk_div, and is described as "Sd card clock divider. N: (N+1) divider. Sd0、sd1 cclk is divided from this clock". Do you have any extra information about the limitation? > Another example is ls_codec_adc_rate, where mul_min is 0x10, mul_max is > 0x1B9, div_min is 0xC35, and div_max is 0x3D09. These specific ranges > cannot be described using the normal clk_fractional_divider structure. According to the TRM, the two fields in control of the fractional clock are described as > codec clock stup. For example, audio_clk: 25644.1K, source clock: > 400M, 400M/(25644.1K) can be simplied to : 15625/441. sum is set to : > 15625, step is set to 441 and > codec clock sum still I cannot find any information about the range you described with mul_min and div_min. Could you confirm whether they're really necessary? > > > > What do you think of introducing support for such "write enable bit" to > > the generic implementation of multipler/divider/fractional? Then you > > could reuse the generic implementation in K230's driver, avoiding code > > duplication. > Therefore, in addition to the requirement of setting the > write_enable_bit, the customizable ranges for these parameters are also > important differences that should be considered. Best regards, Yao Zi [1]: https://github.com/revyos/external-docs/blob/master/K230/en-us/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf 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 31B08CAC589 for ; Tue, 9 Sep 2025 06:56:51 +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:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=iwPiiJU6lscUUge5ZOBX1d46HUmR9H/cHRcMd2gbc4I=; b=YgVVKucClE+aLM zumR+Yg3d5E7IKllZA5FlOHvJPYMK+OddDA0LxR22dxi5sNtNhXymY1Bu9UGbIwGyU7649HizOSbK d4+PflWrzZmi1ywPLJr98Wzaevt6kR82vSV5jyArO6QgdytVgRGj3gXmJoVQssHWse2PTVXvLq6vV Ll2mfrwE4rluPJ0vzDkq994iHS+2qky1uFrxbibsH5R0K6urHVJKwlNtUxNTAKgcEi7nAc5o67Lwz vPUR9fyhoGM2FDnm3OhJdsnZXRF+jByaQods8nELI4GC++ie/RDoJVkRN/5cI5o0aSUU66Yj4v0uZ /d2vf84YLseqiVtLA1kg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uvsHS-00000004wYd-1UKj; Tue, 09 Sep 2025 06:56:42 +0000 Received: from layka.disroot.org ([178.21.23.139]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uvoSZ-00000003oWX-27La for linux-riscv@lists.infradead.org; Tue, 09 Sep 2025 02:51:57 +0000 Received: from mail01.disroot.lan (localhost [127.0.0.1]) by disroot.org (Postfix) with ESMTP id 44B7722EC1; Tue, 9 Sep 2025 04:51:51 +0200 (CEST) X-Virus-Scanned: SPAM Filter at disroot.org Received: from layka.disroot.org ([127.0.0.1]) by localhost (disroot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id cUb3k8BRjNKs; Tue, 9 Sep 2025 04:51:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=disroot.org; s=mail; t=1757386310; bh=rJ6zql9GvPc0S5blprEyBy/gNctD4hMQy6wVOb34PiQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=BZ+79DwKXgux9NaOekFldf3z1TrMwFEm5nfKU+qzQSyY830UhXQ6opPaz84xdu9hg mCT1KAYwdlE0GlY2OnqzLe0Cp+zMPGP0HVeQ2YexIEOPRMtDuphvlYB8CW+SjNxoCc YVfDV/DRbwJlXp/sRajBkp+sqPXEOdGylGJpGanCf33sLWnbeG7+pqNR2pKuBz/DVq fYVyJ5G9BQXfyyEbq2haMwMtOX7y7HV47Efaf04IaFlncZFiMrHEy5JuxNU9J+rFhJ 0UrIZOI/gmhffSGm78Sb2rZyElO0GsdDww5TuQVe+cW56KHd3WRBaPbA9Wd6fvpraR vhDWRujn73Hjg== Date: Tue, 9 Sep 2025 02:51:29 +0000 From: Yao Zi To: Xukai Wang , Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Albert Ou , Conor Dooley Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, Samuel Holland , Troy Mitchell Subject: Re: [PATCH v8 2/3] clk: canaan: Add clock driver for Canaan K230 Message-ID: References: <20250905-b4-k230-clk-v8-0-96caa02d5428@zohomail.com> <20250905-b4-k230-clk-v8-2-96caa02d5428@zohomail.com> <0947d9cc-86ba-46e0-92aa-04f4714e7a20@zohomail.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <0947d9cc-86ba-46e0-92aa-04f4714e7a20@zohomail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250908_195156_087679_DB9B0167 X-CRM114-Status: GOOD ( 32.20 ) 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 T24gTW9uLCBTZXAgMDgsIDIwMjUgYXQgMTA6MTM6MTVQTSArMDgwMCwgWHVrYWkgV2FuZyB3cm90 ZToKPiAKPiBPbiAyMDI1LzkvNyAxMToxMywgWWFvIFppIHdyb3RlOgo+ID4+IE9uIEZyaSwgU2Vw IDA1LCAyMDI1IGF0IDExOjEwOjIzQU0gKzA4MDAsIFh1a2FpIFdhbmcgd3JvdGU6Cj4gPj4gVGhp cyBwYXRjaCBwcm92aWRlcyBiYXNpYyBzdXBwb3J0IGZvciB0aGUgSzIzMCBjbG9jaywgd2hpY2gg Y292ZXJzCj4gPj4gYWxsIGNsb2NrcyBpbiBLMjMwIFNvQy4KPiA+Pgo+ID4+IFRoZSBjbG9jayB0 cmVlIG9mIHRoZSBLMjMwIFNvQyBjb25zaXN0cyBvZiBhIDI0TUhaIGV4dGVybmFsIGNyeXN0YWwK PiA+PiBvc2NpbGxhdG9yLCBQTExzIGFuZCBhbiBleHRlcm5hbCBwdWxzZSBpbnB1dCBmb3IgdGlt ZXJYLCBhbmQgdGhlaXIKPiA+PiBkZXJpdmVkIGNsb2Nrcy4KPiA+Pgo+ID4+IENvLWRldmVsb3Bl ZC1ieTogVHJveSBNaXRjaGVsbCA8VHJveU1pdGNoZWxsOTg4QGdtYWlsLmNvbT4KPiA+PiBTaWdu ZWQtb2ZmLWJ5OiBUcm95IE1pdGNoZWxsIDxUcm95TWl0Y2hlbGw5ODhAZ21haWwuY29tPgo+ID4+ IFNpZ25lZC1vZmYtYnk6IFh1a2FpIFdhbmcgPGtpbmd4dWthaUB6b2hvbWFpbC5jb20+Cj4gPj4g LS0tCj4gPj4gIGRyaXZlcnMvY2xrL0tjb25maWcgICAgfCAgICA2ICsKPiA+PiAgZHJpdmVycy9j bGsvTWFrZWZpbGUgICB8ICAgIDEgKwo+ID4+ICBkcml2ZXJzL2Nsay9jbGstazIzMC5jIHwgMjQ1 NiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiA+PiAg MyBmaWxlcyBjaGFuZ2VkLCAyNDYzIGluc2VydGlvbnMoKykKCi4uLgoKPiA+PiBuZXcgZmlsZSBt b2RlIDEwMDY0NAo+ID4+IGluZGV4IDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAuLjJiYTc0YzAwOGIzMGFlMzQwMGFjYmQ4YzA4NTUwZTgzMTVkZmUyMDUKPiA+PiAtLS0g L2Rldi9udWxsCj4gPj4gKysrIGIvZHJpdmVycy9jbGsvY2xrLWsyMzAuYwo+ID4+IEBAIC0wLDAg KzEsMjQ1NiBAQAoKLi4uCgo+ID4KPiA+PiArc3RhdGljIGludCBrMjMwX2Nsa19zZXRfcmF0ZV9t dWwoc3RydWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwKPiA+PiArCQkJCSB1bnNp Z25lZCBsb25nIHBhcmVudF9yYXRlKQo+ID4+ICt7Cj4gPj4gKwlzdHJ1Y3QgazIzMF9jbGtfcmF0 ZSAqY2xrID0gaHdfdG9fazIzMF9jbGtfcmF0ZShodyk7Cj4gPj4gKwlzdHJ1Y3QgazIzMF9jbGtf cmF0ZV9zZWxmICpyYXRlX3NlbGYgPSAmY2xrLT5jbGs7Cj4gPj4gKwl1MzIgZGl2LCBtdWwsIG11 bF9yZWc7Cj4gPj4gKwo+ID4+ICsJaWYgKHJhdGUgPiBwYXJlbnRfcmF0ZSkKPiA+PiArCQlyZXR1 cm4gLUVJTlZBTDsKPiA+PiArCj4gPj4gKwlpZiAocmF0ZV9zZWxmLT5yZWFkX29ubHkpCj4gPj4g KwkJcmV0dXJuIDA7Cj4gPj4gKwo+ID4+ICsJaWYgKGsyMzBfY2xrX2ZpbmRfYXBwcm94aW1hdGVf bXVsKHJhdGVfc2VsZi0+bXVsX21pbiwgcmF0ZV9zZWxmLT5tdWxfbWF4LAo+ID4+ICsJCQkJCSAg cmF0ZV9zZWxmLT5kaXZfbWluLCByYXRlX3NlbGYtPmRpdl9tYXgsCj4gPj4gKwkJCQkJICByYXRl LCBwYXJlbnRfcmF0ZSwgJmRpdiwgJm11bCkpCj4gPj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gPj4g Kwo+ID4+ICsJZ3VhcmQoc3BpbmxvY2spKHJhdGVfc2VsZi0+bG9jayk7Cj4gPj4gKwo+ID4+ICsJ bXVsX3JlZyA9IHJlYWRsKHJhdGVfc2VsZi0+cmVnICsgY2xrLT5tdWxfcmVnX29mZik7Cj4gPj4g KwltdWxfcmVnIHw9ICgobXVsIC0gMSkgJiByYXRlX3NlbGYtPm11bF9tYXNrKSA8PCAocmF0ZV9z ZWxmLT5tdWxfc2hpZnQpOwo+ID4+ICsJbXVsX3JlZyB8PSBCSVQocmF0ZV9zZWxmLT53cml0ZV9l bmFibGVfYml0KTsKPiA+PiArCXdyaXRlbChtdWxfcmVnLCByYXRlX3NlbGYtPnJlZyArIGNsay0+ bXVsX3JlZ19vZmYpOwo+ID4+ICsKPiA+PiArCXJldHVybiAwOwo+ID4+ICt9Cj4gPj4gKwo+ID4+ ICtzdGF0aWMgaW50IGsyMzBfY2xrX3NldF9yYXRlX2RpdihzdHJ1Y3QgY2xrX2h3ICpodywgdW5z aWduZWQgbG9uZyByYXRlLAo+ID4+ICsJCQkJIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpCj4g Pj4gK3sKPiA+PiArCXN0cnVjdCBrMjMwX2Nsa19yYXRlICpjbGsgPSBod190b19rMjMwX2Nsa19y YXRlKGh3KTsKPiA+PiArCXN0cnVjdCBrMjMwX2Nsa19yYXRlX3NlbGYgKnJhdGVfc2VsZiA9ICZj bGstPmNsazsKPiA+PiArCXUzMiBkaXYsIG11bCwgZGl2X3JlZzsKPiA+PiArCj4gPj4gKwlpZiAo cmF0ZSA+IHBhcmVudF9yYXRlKQo+ID4+ICsJCXJldHVybiAtRUlOVkFMOwo+ID4+ICsKPiA+PiAr CWlmIChyYXRlX3NlbGYtPnJlYWRfb25seSkKPiA+PiArCQlyZXR1cm4gMDsKPiA+PiArCj4gPj4g KwlpZiAoazIzMF9jbGtfZmluZF9hcHByb3hpbWF0ZV9kaXYocmF0ZV9zZWxmLT5tdWxfbWluLCBy YXRlX3NlbGYtPm11bF9tYXgsCj4gPj4gKwkJCQkJICByYXRlX3NlbGYtPmRpdl9taW4sIHJhdGVf c2VsZi0+ZGl2X21heCwKPiA+PiArCQkJCQkgIHJhdGUsIHBhcmVudF9yYXRlLCAmZGl2LCAmbXVs KSkKPiA+PiArCQlyZXR1cm4gLUVJTlZBTDsKPiA+PiArCj4gPj4gKwlndWFyZChzcGlubG9jayko cmF0ZV9zZWxmLT5sb2NrKTsKPiA+PiArCj4gPj4gKwlkaXZfcmVnID0gcmVhZGwocmF0ZV9zZWxm LT5yZWcgKyBjbGstPmRpdl9yZWdfb2ZmKTsKPiA+PiArCWRpdl9yZWcgfD0gKChkaXYgLSAxKSAm IHJhdGVfc2VsZi0+ZGl2X21hc2spIDw8IChyYXRlX3NlbGYtPmRpdl9zaGlmdCk7Cj4gPj4gKwlk aXZfcmVnIHw9IEJJVChyYXRlX3NlbGYtPndyaXRlX2VuYWJsZV9iaXQpOwo+ID4+ICsJd3JpdGVs KGRpdl9yZWcsIHJhdGVfc2VsZi0+cmVnICsgY2xrLT5kaXZfcmVnX29mZik7Cj4gPj4gKwo+ID4+ ICsJcmV0dXJuIDA7Cj4gPj4gK30KPiA+PiArCj4gPj4gK3N0YXRpYyBpbnQgazIzMF9jbGtfc2V0 X3JhdGVfbXVsX2RpdihzdHJ1Y3QgY2xrX2h3ICpodywgdW5zaWduZWQgbG9uZyByYXRlLAo+ID4+ ICsJCQkJICAgICB1bnNpZ25lZCBsb25nIHBhcmVudF9yYXRlKQo+ID4+ICt7Cj4gPj4gKwlzdHJ1 Y3QgazIzMF9jbGtfcmF0ZSAqY2xrID0gaHdfdG9fazIzMF9jbGtfcmF0ZShodyk7Cj4gPj4gKwlz dHJ1Y3QgazIzMF9jbGtfcmF0ZV9zZWxmICpyYXRlX3NlbGYgPSAmY2xrLT5jbGs7Cj4gPj4gKwl1 MzIgZGl2LCBtdWwsIGRpdl9yZWcsIG11bF9yZWc7Cj4gPj4gKwo+ID4+ICsJaWYgKHJhdGUgPiBw YXJlbnRfcmF0ZSkKPiA+PiArCQlyZXR1cm4gLUVJTlZBTDsKPiA+PiArCj4gPj4gKwlpZiAocmF0 ZV9zZWxmLT5yZWFkX29ubHkpCj4gPj4gKwkJcmV0dXJuIDA7Cj4gPj4gKwo+ID4+ICsJaWYgKGsy MzBfY2xrX2ZpbmRfYXBwcm94aW1hdGVfbXVsX2RpdihyYXRlX3NlbGYtPm11bF9taW4sIHJhdGVf c2VsZi0+bXVsX21heCwKPiA+PiArCQkJCQkgICAgICByYXRlX3NlbGYtPmRpdl9taW4sIHJhdGVf c2VsZi0+ZGl2X21heCwKPiA+PiArCQkJCQkgICAgICByYXRlLCBwYXJlbnRfcmF0ZSwgJmRpdiwg Jm11bCkpCj4gPj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gPj4gKwo+ID4+ICsJZ3VhcmQoc3Bpbmxv Y2spKHJhdGVfc2VsZi0+bG9jayk7Cj4gPj4gKwo+ID4+ICsJZGl2X3JlZyA9IHJlYWRsKHJhdGVf c2VsZi0+cmVnICsgY2xrLT5kaXZfcmVnX29mZik7Cj4gPj4gKwlkaXZfcmVnIHw9ICgoZGl2IC0g MSkgJiByYXRlX3NlbGYtPmRpdl9tYXNrKSA8PCAocmF0ZV9zZWxmLT5kaXZfc2hpZnQpOwo+ID4+ ICsJZGl2X3JlZyB8PSBCSVQocmF0ZV9zZWxmLT53cml0ZV9lbmFibGVfYml0KTsKPiA+PiArCXdy aXRlbChkaXZfcmVnLCByYXRlX3NlbGYtPnJlZyArIGNsay0+ZGl2X3JlZ19vZmYpOwo+ID4+ICsK PiA+PiArCW11bF9yZWcgPSByZWFkbChyYXRlX3NlbGYtPnJlZyArIGNsay0+bXVsX3JlZ19vZmYp Owo+ID4+ICsJbXVsX3JlZyB8PSAoKG11bCAtIDEpICYgcmF0ZV9zZWxmLT5tdWxfbWFzaykgPDwg KHJhdGVfc2VsZi0+bXVsX3NoaWZ0KTsKPiA+PiArCW11bF9yZWcgfD0gQklUKHJhdGVfc2VsZi0+ d3JpdGVfZW5hYmxlX2JpdCk7Cj4gPj4gKwl3cml0ZWwobXVsX3JlZywgcmF0ZV9zZWxmLT5yZWcg KyBjbGstPm11bF9yZWdfb2ZmKTsKPiA+PiArCj4gPj4gKwlyZXR1cm4gMDsKPiA+PiArfQo+ID4g VGhlcmUgYXJlIHRocmVlIHZhcmlhbnRzIG9mIHJhdGUgY2xvY2tzLCBtdWwtb25seSwgZGl2LW9u bHkgYW5kIG11bC1kaXYKPiA+IG9uZXMsIHdoaWNoIGFyZSBzaW1pbGFyIHRvIGNsay1tdWx0aXBs aWVyLCBjbGstZGl2aWRlciwKPiA+IGNsay1mcmFjdGlvbmFsLWRpdmlkZXIuCj4gPgo+ID4gVGhl IG9ubHkgZGlmZmVyZW5jZSBpcyB0byBzZXR1cCBuZXcgcGFyYW1ldGVycyBmb3IgSzIzMCdzIHJh dGUgY2xvY2tzLAo+ID4gYSByZWdpc3RlciBiaXQsIGRlc2NyaWJlZCBhcyBrMjMwX2Nsa19yYXRl X3NlbGYud3JpdGVfZW5hYmxlX2JpdCwgbXVzdAo+ID4gYmUgc2V0IGZpcnN0Lgo+IEFjdHVhbGx5 LCBJIHRoaW5rIHRoZSBkaWZmZXJlbmNlcyBhcmUgbm90IGxpbWl0ZWQgdG8ganVzdCB0aGUKPiB3 cml0ZV9lbmFibGVfYml0LiBUaGVyZSBhcmUgYWxzbyBkaXN0aW5jdCBtdWxfbWluLCBtdWxfbWF4 LCBkaXZfbWluLCBhbmQKPiBkaXZfbWF4IHZhbHVlcywgd2hpY2ggYXJlIG5vdCB0eXBpY2FsbHkg anVzdCAxIGFuZCAoMSA8PCBiaXRfd2lkdGgpIGFzCj4gaW4gc3RhbmRhcmQgY2xvY2sgZGl2aWRl ciBvciBtdWx0aXBsaWVyIHN0cnVjdHVyZXMuCgpPb3BzLCBJIG1pc3NlZCB0aGVzZSBtZW1iZXJz LCBzbyB0aGVyZSdyZSBtb3JlIGRpZmZlcmVuY2VzLCBidXQuLi4KCj4gRm9yIGV4YW1wbGUsIHRo ZSBkaXZfbWluIGZvciBoc19zZF9jYXJkX3NyY19yYXRlIGlzIDIsIG5vdCAxLiBUaGlzCj4gYWZm ZWN0cyB0aGUgY2FsY3VsYXRpb24gb2YgdGhlIGFwcHJveGltYXRlIGRpdmlkZXIsIGFuZCBjYW5u b3QgYmUgZnVsbHkKPiByZXByZXNlbnRlZCBpZiB3ZSBvbmx5IHVzZSB0aGUgY2xrX2RpdmlkZXIg c3RydWN0dXJlLgoKUmVhZGluZyB0aHJvdWdoIHRoZSBUUk1bMV0sIEkgY2Fubm90IGZpbmQgd2h5 IHVzaW5nIG9uZSBhcyBkaXZpc29yIGlzbid0CnZhbGlkIGZvciBoc19zZF9jYXJkX3NyY19yYXRl LiBUaGUgY2xvY2sgY29ycmVzcG9uZHMgdG8gZmllbGQKaHNfU0RDTEtfQ0ZHLnNkX2NjbGtfZGl2 LCBhbmQgaXMgZGVzY3JpYmVkIGFzICJTZCBjYXJkIGNsb2NrIGRpdmlkZXIuCk46IChOKzEpIGRp dmlkZXIuIFNkMOOAgXNkMSBjY2xrIGlzIGRpdmlkZWQgZnJvbSB0aGlzIGNsb2NrIi4KCkRvIHlv dSBoYXZlIGFueSBleHRyYSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbGltaXRhdGlvbj8KCj4gQW5v dGhlciBleGFtcGxlIGlzIGxzX2NvZGVjX2FkY19yYXRlLCB3aGVyZSBtdWxfbWluIGlzIDB4MTAs IG11bF9tYXggaXMKPiAweDFCOSwgZGl2X21pbiBpcyAweEMzNSwgYW5kIGRpdl9tYXggaXMgMHgz RDA5LiBUaGVzZSBzcGVjaWZpYyByYW5nZXMKPiBjYW5ub3QgYmUgZGVzY3JpYmVkIHVzaW5nIHRo ZSBub3JtYWwgY2xrX2ZyYWN0aW9uYWxfZGl2aWRlciBzdHJ1Y3R1cmUuCgpBY2NvcmRpbmcgdG8g dGhlIFRSTSwgdGhlIHR3byBmaWVsZHMgaW4gY29udHJvbCBvZiB0aGUgZnJhY3Rpb25hbCBjbG9j awphcmUgZGVzY3JpYmVkIGFzCgo+IGNvZGVjIGNsb2NrIHN0dXAuIEZvciBleGFtcGxlLCBhdWRp b19jbGs6IDI1NjQ0LjFLLCBzb3VyY2UgY2xvY2s6Cj4gNDAwTSwgNDAwTS8oMjU2NDQuMUspIGNh biBiZSBzaW1wbGllZAp0byA6IDE1NjI1LzQ0MS4gc3VtIGlzIHNldCB0byA6Cj4gMTU2MjUsIHN0 ZXAgaXMgc2V0IHRvIDQ0MQoKYW5kCgo+IGNvZGVjIGNsb2NrIHN1bQoKc3RpbGwgSSBjYW5ub3Qg ZmluZCBhbnkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJhbmdlIHlvdSBkZXNjcmliZWQgd2l0aApt dWxfbWluIGFuZCBkaXZfbWluLiBDb3VsZCB5b3UgY29uZmlybSB3aGV0aGVyIHRoZXkncmUgcmVh bGx5Cm5lY2Vzc2FyeT8KCj4gPgo+ID4gV2hhdCBkbyB5b3UgdGhpbmsgb2YgaW50cm9kdWNpbmcg c3VwcG9ydCBmb3Igc3VjaCAid3JpdGUgZW5hYmxlIGJpdCIgdG8KPiA+IHRoZSBnZW5lcmljIGlt cGxlbWVudGF0aW9uIG9mIG11bHRpcGxlci9kaXZpZGVyL2ZyYWN0aW9uYWw/IFRoZW4geW91Cj4g PiBjb3VsZCByZXVzZSB0aGUgZ2VuZXJpYyBpbXBsZW1lbnRhdGlvbiBpbiBLMjMwJ3MgZHJpdmVy LCBhdm9pZGluZyBjb2RlCj4gPiBkdXBsaWNhdGlvbi4KPiBUaGVyZWZvcmUsIGluIGFkZGl0aW9u IHRvIHRoZSByZXF1aXJlbWVudCBvZiBzZXR0aW5nIHRoZQo+IHdyaXRlX2VuYWJsZV9iaXQsIHRo ZSBjdXN0b21pemFibGUgcmFuZ2VzIGZvciB0aGVzZSBwYXJhbWV0ZXJzIGFyZSBhbHNvCj4gaW1w b3J0YW50IGRpZmZlcmVuY2VzIHRoYXQgc2hvdWxkIGJlIGNvbnNpZGVyZWQuCgpCZXN0IHJlZ2Fy ZHMsCllhbyBaaQoKWzFdOiBodHRwczovL2dpdGh1Yi5jb20vcmV2eW9zL2V4dGVybmFsLWRvY3Mv YmxvYi9tYXN0ZXIvSzIzMC9lbi11cy9LMjMwX1RlY2huaWNhbF9SZWZlcmVuY2VfTWFudWFsX1Yw LjMuMV8yMDI0MTExOC5wZGYKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fCmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51eC1yaXNjdkBsaXN0cy5pbmZy YWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGlu dXgtcmlzY3YK