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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B208C47089 for ; Wed, 23 Nov 2022 06:19:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235990AbiKWGTe (ORCPT ); Wed, 23 Nov 2022 01:19:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57616 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236023AbiKWGTT (ORCPT ); Wed, 23 Nov 2022 01:19:19 -0500 Received: from twspam01.aspeedtech.com (twspam01.aspeedtech.com [211.20.114.71]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9AC515B86C; Tue, 22 Nov 2022 22:19:16 -0800 (PST) Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 2AN5pU4L081940; Wed, 23 Nov 2022 13:51:32 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 23 Nov 2022 14:15:55 +0800 From: Billy Tsai To: , , , , , , , , , , , , , , , , , , CC: kernel test robot Subject: [v4 4/5] pwm: Add Aspeed ast2600 PWM support Date: Wed, 23 Nov 2022 14:16:34 +0800 Message-ID: <20221123061635.32025-5-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221123061635.32025-1-billy_tsai@aspeedtech.com> References: <20221123061635.32025-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 2AN5pU4L081940 Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org Add the support of PWM controller which can be found at aspeed ast2600 soc. The pwm supoorts up to 16 channels and it's part function of multi-function device "pwm-tach controller". Signed-off-by: Billy Tsai Reviewed-by: Uwe Kleine-König Reported-by: kernel test robot --- drivers/pwm/Kconfig | 10 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-aspeed-ast2600.c | 318 +++++++++++++++++++++++++++++++ 3 files changed, 329 insertions(+) create mode 100644 drivers/pwm/pwm-aspeed-ast2600.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 60d13a949bc5..54915185d918 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -51,6 +51,16 @@ config PWM_AB8500 To compile this driver as a module, choose M here: the module will be called pwm-ab8500. +config PWM_ASPEED_AST2600 + tristate "Aspeed ast2600 PWM support" + depends on ARCH_ASPEED || COMPILE_TEST + depends on HAVE_CLK && HAS_IOMEM + help + This driver provides support for Aspeed ast2600 PWM controllers. + + To compile this driver as a module, choose M here: the module + will be called pwm-aspeed-ast2600. + config PWM_ATMEL tristate "Atmel PWM support" depends on ARCH_AT91 || COMPILE_TEST diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 7bf1a29f02b8..5169c34056e6 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PWM) += core.o obj-$(CONFIG_PWM_SYSFS) += sysfs.o obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o +obj-$(CONFIG_PWM_ASPEED_AST2600) += pwm-aspeed-ast2600.o obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o obj-$(CONFIG_PWM_ATMEL_HLCDC_PWM) += pwm-atmel-hlcdc.o obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o diff --git a/drivers/pwm/pwm-aspeed-ast2600.c b/drivers/pwm/pwm-aspeed-ast2600.c new file mode 100644 index 000000000000..2c22aff18624 --- /dev/null +++ b/drivers/pwm/pwm-aspeed-ast2600.c @@ -0,0 +1,318 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2021 Aspeed Technology Inc. + * + * PWM controller driver for Aspeed ast2600 SoCs. + * This drivers doesn't support earlier version of the IP. + * + * The hardware operates in time quantities of length + * Q := (DIV_L + 1) << DIV_H / input-clk + * The length of a PWM period is (DUTY_CYCLE_PERIOD + 1) * Q. + * The maximal value for DUTY_CYCLE_PERIOD is used here to provide + * a fine grained selection for the duty cycle. + * + * This driver uses DUTY_CYCLE_RISING_POINT = 0, so from the start of a + * period the output is active until DUTY_CYCLE_FALLING_POINT * Q. Note + * that if DUTY_CYCLE_RISING_POINT = DUTY_CYCLE_FALLING_POINT the output is + * always active. + * + * Register usage: + * PIN_ENABLE: When it is unset the pwm controller will emit inactive level to the external. + * Use to determine whether the PWM channel is enabled or disabled + * CLK_ENABLE: When it is unset the pwm controller will assert the duty counter reset and + * emit inactive level to the PIN_ENABLE mux after that the driver can still change the pwm period + * and duty and the value will apply when CLK_ENABLE be set again. + * Use to determine whether duty_cycle bigger than 0. + * PWM_ASPEED_CTRL_INVERSE: When it is toggled the output value will inverse immediately. + * PWM_ASPEED_DUTY_CYCLE_FALLING_POINT/PWM_ASPEED_DUTY_CYCLE_RISING_POINT: When these two + * values are equal it means the duty cycle = 100%. + * + * The glitch may generate at: + * - Enabled changing when the duty_cycle bigger than 0% and less than 100%. + * - Polarity changing when the duty_cycle bigger than 0% and less than 100%. + * + * Limitations: + * - When changing both duty cycle and period, we cannot prevent in + * software that the output might produce a period with mixed + * settings. + * - Disabling the PWM doesn't complete the current period. + * + * Improvements: + * - When only changing one of duty cycle or period, our pwm controller will not + * generate the glitch, the configure will change at next cycle of pwm. + * This improvement can disable/enable through PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The channel number of Aspeed pwm controller */ +#define PWM_ASPEED_NR_PWMS 16 +/* PWM Control Register */ +#define PWM_ASPEED_CTRL(ch) ((ch) * 0x10 + 0x00) +#define PWM_ASPEED_CTRL_LOAD_SEL_RISING_AS_WDT BIT(19) +#define PWM_ASPEED_CTRL_DUTY_LOAD_AS_WDT_ENABLE BIT(18) +#define PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE BIT(17) +#define PWM_ASPEED_CTRL_CLK_ENABLE BIT(16) +#define PWM_ASPEED_CTRL_LEVEL_OUTPUT BIT(15) +#define PWM_ASPEED_CTRL_INVERSE BIT(14) +#define PWM_ASPEED_CTRL_OPEN_DRAIN_ENABLE BIT(13) +#define PWM_ASPEED_CTRL_PIN_ENABLE BIT(12) +#define PWM_ASPEED_CTRL_CLK_DIV_H GENMASK(11, 8) +#define PWM_ASPEED_CTRL_CLK_DIV_L GENMASK(7, 0) + +/* PWM Duty Cycle Register */ +#define PWM_ASPEED_DUTY_CYCLE(ch) ((ch) * 0x10 + 0x04) +#define PWM_ASPEED_DUTY_CYCLE_PERIOD GENMASK(31, 24) +#define PWM_ASPEED_DUTY_CYCLE_POINT_AS_WDT GENMASK(23, 16) +#define PWM_ASPEED_DUTY_CYCLE_FALLING_POINT GENMASK(15, 8) +#define PWM_ASPEED_DUTY_CYCLE_RISING_POINT GENMASK(7, 0) + +/* PWM fixed value */ +#define PWM_ASPEED_FIXED_PERIOD FIELD_MAX(PWM_ASPEED_DUTY_CYCLE_PERIOD) + +struct aspeed_pwm_data { + struct pwm_chip chip; + struct clk *clk; + struct regmap *regmap; + struct reset_control *reset; +}; + +static inline struct aspeed_pwm_data * +aspeed_pwm_chip_to_data(struct pwm_chip *chip) +{ + return container_of(chip, struct aspeed_pwm_data, chip); +} + +static void aspeed_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_state *state) +{ + struct device *dev = chip->dev; + struct aspeed_pwm_data *priv = aspeed_pwm_chip_to_data(chip); + u32 hwpwm = pwm->hwpwm; + bool polarity, pin_en, clk_en; + u32 duty_pt, val; + unsigned long rate; + u64 div_h, div_l, duty_cycle_period, dividend; + + regmap_read(priv->regmap, PWM_ASPEED_CTRL(hwpwm), &val); + polarity = FIELD_GET(PWM_ASPEED_CTRL_INVERSE, val); + pin_en = FIELD_GET(PWM_ASPEED_CTRL_PIN_ENABLE, val); + clk_en = FIELD_GET(PWM_ASPEED_CTRL_CLK_ENABLE, val); + div_h = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_H, val); + div_l = FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_L, val); + regmap_read(priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm), &val); + duty_pt = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, val); + duty_cycle_period = FIELD_GET(PWM_ASPEED_DUTY_CYCLE_PERIOD, val); + + rate = clk_get_rate(priv->clk); + + /* + * This multiplication doesn't overflow, the upper bound is + * 1000000000 * 256 * 256 << 15 = 0x1dcd650000000000 + */ + dividend = (u64)NSEC_PER_SEC * (div_l + 1) * (duty_cycle_period + 1) + << div_h; + state->period = DIV_ROUND_UP_ULL(dividend, rate); + + if (clk_en && duty_pt) { + dividend = (u64)NSEC_PER_SEC * (div_l + 1) * duty_pt + << div_h; + state->duty_cycle = DIV_ROUND_UP_ULL(dividend, rate); + } else { + state->duty_cycle = clk_en ? state->period : 0; + } + state->polarity = polarity ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; + state->enabled = pin_en; + dev_dbg(dev, "get period: %lldns, duty_cycle: %lldns", state->period, + state->duty_cycle); +} + +static int aspeed_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) +{ + struct device *dev = chip->dev; + struct aspeed_pwm_data *priv = aspeed_pwm_chip_to_data(chip); + u32 hwpwm = pwm->hwpwm, duty_pt; + unsigned long rate; + u64 div_h, div_l, divisor, expect_period; + bool clk_en; + + rate = clk_get_rate(priv->clk); + expect_period = min(div64_u64(ULLONG_MAX, (u64)rate), state->period); + dev_dbg(dev, "expect period: %lldns, duty_cycle: %lldns", expect_period, + state->duty_cycle); + /* + * Pick the smallest value for div_h so that div_l can be the biggest + * which results in a finer resolution near the target period value. + */ + divisor = (u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1) * + (FIELD_MAX(PWM_ASPEED_CTRL_CLK_DIV_L) + 1); + div_h = order_base_2(DIV64_U64_ROUND_UP(rate * expect_period, divisor)); + if (div_h > 0xf) + div_h = 0xf; + + divisor = ((u64)NSEC_PER_SEC * (PWM_ASPEED_FIXED_PERIOD + 1)) << div_h; + div_l = div64_u64(rate * expect_period, divisor); + + if (div_l == 0) + return -ERANGE; + + div_l -= 1; + + if (div_l > 255) + div_l = 255; + + dev_dbg(dev, "clk source: %ld div_h %lld, div_l : %lld\n", rate, div_h, + div_l); + /* duty_pt = duty_cycle * (PERIOD + 1) / period */ + duty_pt = div64_u64(state->duty_cycle * rate, + (u64)NSEC_PER_SEC * (div_l + 1) << div_h); + dev_dbg(dev, "duty_cycle = %lld, duty_pt = %d\n", state->duty_cycle, + duty_pt); + + /* + * Fixed DUTY_CYCLE_PERIOD to its max value to get a + * fine-grained resolution for duty_cycle at the expense of a + * coarser period resolution. + */ + regmap_update_bits(priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm), + PWM_ASPEED_DUTY_CYCLE_PERIOD, + FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_PERIOD, + PWM_ASPEED_FIXED_PERIOD)); + if (duty_pt == 0) { + /* emit inactive level and assert the duty counter reset */ + clk_en = 0; + } else { + clk_en = 1; + if (duty_pt >= (PWM_ASPEED_FIXED_PERIOD + 1)) + duty_pt = 0; + regmap_update_bits(priv->regmap, PWM_ASPEED_DUTY_CYCLE(hwpwm), + PWM_ASPEED_DUTY_CYCLE_RISING_POINT | + PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, + FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT, duty_pt)); + } + + regmap_update_bits(priv->regmap, PWM_ASPEED_CTRL(hwpwm), + PWM_ASPEED_CTRL_CLK_DIV_H | PWM_ASPEED_CTRL_CLK_DIV_L | + PWM_ASPEED_CTRL_PIN_ENABLE | PWM_ASPEED_CTRL_CLK_ENABLE | + PWM_ASPEED_CTRL_INVERSE, + FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_H, div_h) | + FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_L, div_l) | + FIELD_PREP(PWM_ASPEED_CTRL_PIN_ENABLE, state->enabled) | + FIELD_PREP(PWM_ASPEED_CTRL_CLK_ENABLE, clk_en) | + FIELD_PREP(PWM_ASPEED_CTRL_INVERSE, state->polarity)); + return 0; +} + +static const struct pwm_ops aspeed_pwm_ops = { + .apply = aspeed_pwm_apply, + .get_state = aspeed_pwm_get_state, + .owner = THIS_MODULE, +}; + +static void aspeed_pwm_reset_assert(void *data) +{ + struct reset_control *rst = data; + + reset_control_assert(rst); +} + +static void aspeed_pwm_chip_remove(void *data) +{ + struct pwm_chip *chip = data; + + pwmchip_remove(chip); +} + +static int aspeed_pwm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret; + struct aspeed_pwm_data *priv; + struct device_node *np; + struct platform_device *parent_dev; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + np = pdev->dev.parent->of_node; + if (!of_device_is_compatible(np, "aspeed,ast2600-pwm-tach")) + return dev_err_probe(dev, -ENODEV, + "Unsupported pwm device binding\n"); + + priv->regmap = syscon_node_to_regmap(np); + if (IS_ERR(priv->regmap)) + return dev_err_probe(dev, PTR_ERR(priv->regmap), + "Couldn't get regmap\n"); + + parent_dev = of_find_device_by_node(np); + priv->clk = devm_clk_get_enabled(&parent_dev->dev, NULL); + if (IS_ERR(priv->clk)) + return dev_err_probe(dev, PTR_ERR(priv->clk), + "Couldn't get clock\n"); + + priv->reset = devm_reset_control_get_shared(&parent_dev->dev, NULL); + if (IS_ERR(priv->reset)) + return dev_err_probe(dev, PTR_ERR(priv->reset), + "Couldn't get reset control\n"); + + ret = reset_control_deassert(priv->reset); + if (ret) + return dev_err_probe(dev, ret, + "Couldn't deassert reset control\n"); + + ret = devm_add_action_or_reset(dev, aspeed_pwm_reset_assert, + priv->reset); + if (ret) + return ret; + + priv->chip.dev = dev; + priv->chip.ops = &aspeed_pwm_ops; + priv->chip.npwm = PWM_ASPEED_NR_PWMS; + + ret = pwmchip_add(&priv->chip); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to add PWM chip\n"); + ret = devm_add_action_or_reset(dev, aspeed_pwm_chip_remove, + &priv->chip); + if (ret) + return ret; + return 0; +} + +static const struct of_device_id of_pwm_match_table[] = { + { + .compatible = "aspeed,ast2600-pwm", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_pwm_match_table); + +static struct platform_driver aspeed_pwm_driver = { + .probe = aspeed_pwm_probe, + .driver = { + .name = "aspeed-pwm", + .of_match_table = of_pwm_match_table, + }, +}; + +module_platform_driver(aspeed_pwm_driver); + +MODULE_AUTHOR("Billy Tsai "); +MODULE_DESCRIPTION("Aspeed ast2600 PWM device driver"); +MODULE_LICENSE("GPL"); -- 2.25.1 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 B4741C433FE for ; Wed, 23 Nov 2022 06:27:17 +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=241+KQn8dSYgseLOG9M6hqc6eyfOGtU9NYNpdbC4pBg=; b=IRK1ds70nuos7C Px1A1kPiLud2TNp2sSH8Pbu+ZqRPKbC3MCheOgI2g1M29f6cWjVO/hGGBK8Io0GnTa9vFJ9y1Bbwt loE6FgdLxLjTjr77yvH/UUcW8XWzrGJkQHnqhZ6hbaAZy+gskzG9KbZKu73aIycmpVa1xvL2/XdSQ zPBCUgXIqTjSPePy+vCAGMsd1Lhm5VGeZcuEwrLDdhMCqtA4g9dNZFa+8VfR57TimYP8l+hx1wyn7 h6477jgmeOoSG9kLuXfg/n0LyqjGzEignrMw2ZtT/xJTzYSCNy9AXjoxwNtR8QpAdTjQ8CHsPDRIV aLBFPyKIj0WS9tZoVSNA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oxjCq-00EfwD-Kv; Wed, 23 Nov 2022 06:26:01 +0000 Received: from twspam01.aspeedtech.com ([211.20.114.71]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oxj4W-00Ecce-Np for linux-arm-kernel@lists.infradead.org; Wed, 23 Nov 2022 06:17:31 +0000 Received: from mail.aspeedtech.com ([192.168.0.24]) by twspam01.aspeedtech.com with ESMTP id 2AN5pU4L081940; Wed, 23 Nov 2022 13:51:32 +0800 (GMT-8) (envelope-from billy_tsai@aspeedtech.com) Received: from BillyTsai-pc.aspeed.com (192.168.2.149) by TWMBX02.aspeed.com (192.168.0.24) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 23 Nov 2022 14:15:55 +0800 From: Billy Tsai To: , , , , , , , , , , , , , , , , , , CC: kernel test robot Subject: [v4 4/5] pwm: Add Aspeed ast2600 PWM support Date: Wed, 23 Nov 2022 14:16:34 +0800 Message-ID: <20221123061635.32025-5-billy_tsai@aspeedtech.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221123061635.32025-1-billy_tsai@aspeedtech.com> References: <20221123061635.32025-1-billy_tsai@aspeedtech.com> MIME-Version: 1.0 X-Originating-IP: [192.168.2.149] X-ClientProxiedBy: TWMBX02.aspeed.com (192.168.0.24) To TWMBX02.aspeed.com (192.168.0.24) X-DNSRBL: X-MAIL: twspam01.aspeedtech.com 2AN5pU4L081940 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221122_221725_271442_FFD4B8A6 X-CRM114-Status: GOOD ( 33.83 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org QWRkIHRoZSBzdXBwb3J0IG9mIFBXTSBjb250cm9sbGVyIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCBh c3BlZWQgYXN0MjYwMApzb2MuIFRoZSBwd20gc3Vwb29ydHMgdXAgdG8gMTYgY2hhbm5lbHMgYW5k IGl0J3MgcGFydCBmdW5jdGlvbiBvZgptdWx0aS1mdW5jdGlvbiBkZXZpY2UgInB3bS10YWNoIGNv bnRyb2xsZXIiLgoKU2lnbmVkLW9mZi1ieTogQmlsbHkgVHNhaSA8YmlsbHlfdHNhaUBhc3BlZWR0 ZWNoLmNvbT4KUmV2aWV3ZWQtYnk6IFV3ZSBLbGVpbmUtS8O2bmlnIDx1LmtsZWluZS1rb2VuaWdA cGVuZ3V0cm9uaXguZGU+ClJlcG9ydGVkLWJ5OiBrZXJuZWwgdGVzdCByb2JvdCA8bGtwQGludGVs LmNvbT4KLS0tCiBkcml2ZXJzL3B3bS9LY29uZmlnICAgICAgICAgICAgICB8ICAxMCArCiBkcml2 ZXJzL3B3bS9NYWtlZmlsZSAgICAgICAgICAgICB8ICAgMSArCiBkcml2ZXJzL3B3bS9wd20tYXNw ZWVkLWFzdDI2MDAuYyB8IDMxOCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiAzIGZp bGVzIGNoYW5nZWQsIDMyOSBpbnNlcnRpb25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVy cy9wd20vcHdtLWFzcGVlZC1hc3QyNjAwLmMKCmRpZmYgLS1naXQgYS9kcml2ZXJzL3B3bS9LY29u ZmlnIGIvZHJpdmVycy9wd20vS2NvbmZpZwppbmRleCA2MGQxM2E5NDliYzUuLjU0OTE1MTg1ZDkx OCAxMDA2NDQKLS0tIGEvZHJpdmVycy9wd20vS2NvbmZpZworKysgYi9kcml2ZXJzL3B3bS9LY29u ZmlnCkBAIC01MSw2ICs1MSwxNiBAQCBjb25maWcgUFdNX0FCODUwMAogCSAgVG8gY29tcGlsZSB0 aGlzIGRyaXZlciBhcyBhIG1vZHVsZSwgY2hvb3NlIE0gaGVyZTogdGhlIG1vZHVsZQogCSAgd2ls bCBiZSBjYWxsZWQgcHdtLWFiODUwMC4KIAorY29uZmlnIFBXTV9BU1BFRURfQVNUMjYwMAorCXRy aXN0YXRlICJBc3BlZWQgYXN0MjYwMCBQV00gc3VwcG9ydCIKKwlkZXBlbmRzIG9uIEFSQ0hfQVNQ RUVEIHx8IENPTVBJTEVfVEVTVAorCWRlcGVuZHMgb24gSEFWRV9DTEsgJiYgSEFTX0lPTUVNCisJ aGVscAorCSAgVGhpcyBkcml2ZXIgcHJvdmlkZXMgc3VwcG9ydCBmb3IgQXNwZWVkIGFzdDI2MDAg UFdNIGNvbnRyb2xsZXJzLgorCisJICBUbyBjb21waWxlIHRoaXMgZHJpdmVyIGFzIGEgbW9kdWxl LCBjaG9vc2UgTSBoZXJlOiB0aGUgbW9kdWxlCisJICB3aWxsIGJlIGNhbGxlZCBwd20tYXNwZWVk LWFzdDI2MDAuCisKIGNvbmZpZyBQV01fQVRNRUwKIAl0cmlzdGF0ZSAiQXRtZWwgUFdNIHN1cHBv cnQiCiAJZGVwZW5kcyBvbiBBUkNIX0FUOTEgfHwgQ09NUElMRV9URVNUCmRpZmYgLS1naXQgYS9k cml2ZXJzL3B3bS9NYWtlZmlsZSBiL2RyaXZlcnMvcHdtL01ha2VmaWxlCmluZGV4IDdiZjFhMjlm MDJiOC4uNTE2OWMzNDA1NmU2IDEwMDY0NAotLS0gYS9kcml2ZXJzL3B3bS9NYWtlZmlsZQorKysg Yi9kcml2ZXJzL3B3bS9NYWtlZmlsZQpAQCAtMiw2ICsyLDcgQEAKIG9iai0kKENPTkZJR19QV00p CQkrPSBjb3JlLm8KIG9iai0kKENPTkZJR19QV01fU1lTRlMpCQkrPSBzeXNmcy5vCiBvYmotJChD T05GSUdfUFdNX0FCODUwMCkJKz0gcHdtLWFiODUwMC5vCitvYmotJChDT05GSUdfUFdNX0FTUEVF RF9BU1QyNjAwKQkrPSBwd20tYXNwZWVkLWFzdDI2MDAubwogb2JqLSQoQ09ORklHX1BXTV9BVE1F TCkJCSs9IHB3bS1hdG1lbC5vCiBvYmotJChDT05GSUdfUFdNX0FUTUVMX0hMQ0RDX1BXTSkJKz0g cHdtLWF0bWVsLWhsY2RjLm8KIG9iai0kKENPTkZJR19QV01fQVRNRUxfVENCKQkrPSBwd20tYXRt ZWwtdGNiLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvcHdtL3B3bS1hc3BlZWQtYXN0MjYwMC5jIGIv ZHJpdmVycy9wd20vcHdtLWFzcGVlZC1hc3QyNjAwLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5k ZXggMDAwMDAwMDAwMDAwLi4yYzIyYWZmMTg2MjQKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJz L3B3bS9wd20tYXNwZWVkLWFzdDI2MDAuYwpAQCAtMCwwICsxLDMxOCBAQAorLy8gU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjAtb3ItbGF0ZXIKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIw MjEgQXNwZWVkIFRlY2hub2xvZ3kgSW5jLgorICoKKyAqIFBXTSBjb250cm9sbGVyIGRyaXZlciBm b3IgQXNwZWVkIGFzdDI2MDAgU29Dcy4KKyAqIFRoaXMgZHJpdmVycyBkb2Vzbid0IHN1cHBvcnQg ZWFybGllciB2ZXJzaW9uIG9mIHRoZSBJUC4KKyAqCisgKiBUaGUgaGFyZHdhcmUgb3BlcmF0ZXMg aW4gdGltZSBxdWFudGl0aWVzIG9mIGxlbmd0aAorICogUSA6PSAoRElWX0wgKyAxKSA8PCBESVZf SCAvIGlucHV0LWNsaworICogVGhlIGxlbmd0aCBvZiBhIFBXTSBwZXJpb2QgaXMgKERVVFlfQ1lD TEVfUEVSSU9EICsgMSkgKiBRLgorICogVGhlIG1heGltYWwgdmFsdWUgZm9yIERVVFlfQ1lDTEVf UEVSSU9EIGlzIHVzZWQgaGVyZSB0byBwcm92aWRlCisgKiBhIGZpbmUgZ3JhaW5lZCBzZWxlY3Rp b24gZm9yIHRoZSBkdXR5IGN5Y2xlLgorICoKKyAqIFRoaXMgZHJpdmVyIHVzZXMgRFVUWV9DWUNM RV9SSVNJTkdfUE9JTlQgPSAwLCBzbyBmcm9tIHRoZSBzdGFydCBvZiBhCisgKiBwZXJpb2QgdGhl IG91dHB1dCBpcyBhY3RpdmUgdW50aWwgRFVUWV9DWUNMRV9GQUxMSU5HX1BPSU5UICogUS4gTm90 ZQorICogdGhhdCBpZiBEVVRZX0NZQ0xFX1JJU0lOR19QT0lOVCA9IERVVFlfQ1lDTEVfRkFMTElO R19QT0lOVCB0aGUgb3V0cHV0IGlzCisgKiBhbHdheXMgYWN0aXZlLgorICoKKyAqIFJlZ2lzdGVy IHVzYWdlOgorICogUElOX0VOQUJMRTogV2hlbiBpdCBpcyB1bnNldCB0aGUgcHdtIGNvbnRyb2xs ZXIgd2lsbCBlbWl0IGluYWN0aXZlIGxldmVsIHRvIHRoZSBleHRlcm5hbC4KKyAqIFVzZSB0byBk ZXRlcm1pbmUgd2hldGhlciB0aGUgUFdNIGNoYW5uZWwgaXMgZW5hYmxlZCBvciBkaXNhYmxlZAor ICogQ0xLX0VOQUJMRTogV2hlbiBpdCBpcyB1bnNldCB0aGUgcHdtIGNvbnRyb2xsZXIgd2lsbCBh c3NlcnQgdGhlIGR1dHkgY291bnRlciByZXNldCBhbmQKKyAqIGVtaXQgaW5hY3RpdmUgbGV2ZWwg dG8gdGhlIFBJTl9FTkFCTEUgbXV4IGFmdGVyIHRoYXQgdGhlIGRyaXZlciBjYW4gc3RpbGwgY2hh bmdlIHRoZSBwd20gcGVyaW9kCisgKiBhbmQgZHV0eSBhbmQgdGhlIHZhbHVlIHdpbGwgYXBwbHkg d2hlbiBDTEtfRU5BQkxFIGJlIHNldCBhZ2Fpbi4KKyAqIFVzZSB0byBkZXRlcm1pbmUgd2hldGhl ciBkdXR5X2N5Y2xlIGJpZ2dlciB0aGFuIDAuCisgKiBQV01fQVNQRUVEX0NUUkxfSU5WRVJTRTog V2hlbiBpdCBpcyB0b2dnbGVkIHRoZSBvdXRwdXQgdmFsdWUgd2lsbCBpbnZlcnNlIGltbWVkaWF0 ZWx5LgorICogUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX0ZBTExJTkdfUE9JTlQvUFdNX0FTUEVFRF9E VVRZX0NZQ0xFX1JJU0lOR19QT0lOVDogV2hlbiB0aGVzZSB0d28KKyAqIHZhbHVlcyBhcmUgZXF1 YWwgaXQgbWVhbnMgdGhlIGR1dHkgY3ljbGUgPSAxMDAlLgorICoKKyAqIFRoZSBnbGl0Y2ggbWF5 IGdlbmVyYXRlIGF0OgorICogLSBFbmFibGVkIGNoYW5naW5nIHdoZW4gdGhlIGR1dHlfY3ljbGUg YmlnZ2VyIHRoYW4gMCUgYW5kIGxlc3MgdGhhbiAxMDAlLgorICogLSBQb2xhcml0eSBjaGFuZ2lu ZyB3aGVuIHRoZSBkdXR5X2N5Y2xlIGJpZ2dlciB0aGFuIDAlIGFuZCBsZXNzIHRoYW4gMTAwJS4K KyAqCisgKiBMaW1pdGF0aW9uczoKKyAqIC0gV2hlbiBjaGFuZ2luZyBib3RoIGR1dHkgY3ljbGUg YW5kIHBlcmlvZCwgd2UgY2Fubm90IHByZXZlbnQgaW4KKyAqICAgc29mdHdhcmUgdGhhdCB0aGUg b3V0cHV0IG1pZ2h0IHByb2R1Y2UgYSBwZXJpb2Qgd2l0aCBtaXhlZAorICogICBzZXR0aW5ncy4K KyAqIC0gRGlzYWJsaW5nIHRoZSBQV00gZG9lc24ndCBjb21wbGV0ZSB0aGUgY3VycmVudCBwZXJp b2QuCisgKgorICogSW1wcm92ZW1lbnRzOgorICogLSBXaGVuIG9ubHkgY2hhbmdpbmcgb25lIG9m IGR1dHkgY3ljbGUgb3IgcGVyaW9kLCBvdXIgcHdtIGNvbnRyb2xsZXIgd2lsbCBub3QKKyAqICAg Z2VuZXJhdGUgdGhlIGdsaXRjaCwgdGhlIGNvbmZpZ3VyZSB3aWxsIGNoYW5nZSBhdCBuZXh0IGN5 Y2xlIG9mIHB3bS4KKyAqICAgVGhpcyBpbXByb3ZlbWVudCBjYW4gZGlzYWJsZS9lbmFibGUgdGhy b3VnaCBQV01fQVNQRUVEX0NUUkxfRFVUWV9TWU5DX0RJU0FCTEUuCisgKi8KKworI2luY2x1ZGUg PGxpbnV4L2JpdGZpZWxkLmg+CisjaW5jbHVkZSA8bGludXgvY2xrLmg+CisjaW5jbHVkZSA8bGlu dXgvZXJybm8uaD4KKyNpbmNsdWRlIDxsaW51eC9pby5oPgorI2luY2x1ZGUgPGxpbnV4L2tlcm5l bC5oPgorI2luY2x1ZGUgPGxpbnV4L21hdGg2NC5oPgorI2luY2x1ZGUgPGxpbnV4L21mZC9zeXNj b24uaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9vZl9kZXZp Y2UuaD4KKyNpbmNsdWRlIDxsaW51eC9vZl9wbGF0Zm9ybS5oPgorI2luY2x1ZGUgPGxpbnV4L3Bs YXRmb3JtX2RldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L3B3bS5oPgorI2luY2x1ZGUgPGxpbnV4 L3JlZ21hcC5oPgorI2luY2x1ZGUgPGxpbnV4L3Jlc2V0Lmg+CisjaW5jbHVkZSA8bGludXgvc3lz ZnMuaD4KKworLyogVGhlIGNoYW5uZWwgbnVtYmVyIG9mIEFzcGVlZCBwd20gY29udHJvbGxlciAq LworI2RlZmluZSBQV01fQVNQRUVEX05SX1BXTVMJCQkxNgorLyogUFdNIENvbnRyb2wgUmVnaXN0 ZXIgKi8KKyNkZWZpbmUgUFdNX0FTUEVFRF9DVFJMKGNoKQkJCSgoY2gpICogMHgxMCArIDB4MDAp CisjZGVmaW5lIFBXTV9BU1BFRURfQ1RSTF9MT0FEX1NFTF9SSVNJTkdfQVNfV0RUCUJJVCgxOSkK KyNkZWZpbmUgUFdNX0FTUEVFRF9DVFJMX0RVVFlfTE9BRF9BU19XRFRfRU5BQkxFCUJJVCgxOCkK KyNkZWZpbmUgUFdNX0FTUEVFRF9DVFJMX0RVVFlfU1lOQ19ESVNBQkxFCUJJVCgxNykKKyNkZWZp bmUgUFdNX0FTUEVFRF9DVFJMX0NMS19FTkFCTEUJCUJJVCgxNikKKyNkZWZpbmUgUFdNX0FTUEVF RF9DVFJMX0xFVkVMX09VVFBVVAkJQklUKDE1KQorI2RlZmluZSBQV01fQVNQRUVEX0NUUkxfSU5W RVJTRQkJCUJJVCgxNCkKKyNkZWZpbmUgUFdNX0FTUEVFRF9DVFJMX09QRU5fRFJBSU5fRU5BQkxF CUJJVCgxMykKKyNkZWZpbmUgUFdNX0FTUEVFRF9DVFJMX1BJTl9FTkFCTEUJCUJJVCgxMikKKyNk ZWZpbmUgUFdNX0FTUEVFRF9DVFJMX0NMS19ESVZfSAkJR0VOTUFTSygxMSwgOCkKKyNkZWZpbmUg UFdNX0FTUEVFRF9DVFJMX0NMS19ESVZfTAkJR0VOTUFTSyg3LCAwKQorCisvKiBQV00gRHV0eSBD eWNsZSBSZWdpc3RlciAqLworI2RlZmluZSBQV01fQVNQRUVEX0RVVFlfQ1lDTEUoY2gpCQkoKGNo KSAqIDB4MTAgKyAweDA0KQorI2RlZmluZSBQV01fQVNQRUVEX0RVVFlfQ1lDTEVfUEVSSU9ECQlH RU5NQVNLKDMxLCAyNCkKKyNkZWZpbmUgUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX1BPSU5UX0FTX1dE VAlHRU5NQVNLKDIzLCAxNikKKyNkZWZpbmUgUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX0ZBTExJTkdf UE9JTlQJR0VOTUFTSygxNSwgOCkKKyNkZWZpbmUgUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX1JJU0lO R19QT0lOVAlHRU5NQVNLKDcsIDApCisKKy8qIFBXTSBmaXhlZCB2YWx1ZSAqLworI2RlZmluZSBQ V01fQVNQRUVEX0ZJWEVEX1BFUklPRAkJCUZJRUxEX01BWChQV01fQVNQRUVEX0RVVFlfQ1lDTEVf UEVSSU9EKQorCitzdHJ1Y3QgYXNwZWVkX3B3bV9kYXRhIHsKKwlzdHJ1Y3QgcHdtX2NoaXAgY2hp cDsKKwlzdHJ1Y3QgY2xrICpjbGs7CisJc3RydWN0IHJlZ21hcCAqcmVnbWFwOworCXN0cnVjdCBy ZXNldF9jb250cm9sICpyZXNldDsKK307CisKK3N0YXRpYyBpbmxpbmUgc3RydWN0IGFzcGVlZF9w d21fZGF0YSAqCithc3BlZWRfcHdtX2NoaXBfdG9fZGF0YShzdHJ1Y3QgcHdtX2NoaXAgKmNoaXAp Cit7CisJcmV0dXJuIGNvbnRhaW5lcl9vZihjaGlwLCBzdHJ1Y3QgYXNwZWVkX3B3bV9kYXRhLCBj aGlwKTsKK30KKworc3RhdGljIHZvaWQgYXNwZWVkX3B3bV9nZXRfc3RhdGUoc3RydWN0IHB3bV9j aGlwICpjaGlwLCBzdHJ1Y3QgcHdtX2RldmljZSAqcHdtLAorCQkJCSBzdHJ1Y3QgcHdtX3N0YXRl ICpzdGF0ZSkKK3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBjaGlwLT5kZXY7CisJc3RydWN0IGFz cGVlZF9wd21fZGF0YSAqcHJpdiA9IGFzcGVlZF9wd21fY2hpcF90b19kYXRhKGNoaXApOworCXUz MiBod3B3bSA9IHB3bS0+aHdwd207CisJYm9vbCBwb2xhcml0eSwJcGluX2VuLCBjbGtfZW47CisJ dTMyIGR1dHlfcHQsIHZhbDsKKwl1bnNpZ25lZCBsb25nIHJhdGU7CisJdTY0IGRpdl9oLCBkaXZf bCwgZHV0eV9jeWNsZV9wZXJpb2QsIGRpdmlkZW5kOworCisJcmVnbWFwX3JlYWQocHJpdi0+cmVn bWFwLCBQV01fQVNQRUVEX0NUUkwoaHdwd20pLCAmdmFsKTsKKwlwb2xhcml0eSA9IEZJRUxEX0dF VChQV01fQVNQRUVEX0NUUkxfSU5WRVJTRSwgdmFsKTsKKwlwaW5fZW4gPSBGSUVMRF9HRVQoUFdN X0FTUEVFRF9DVFJMX1BJTl9FTkFCTEUsIHZhbCk7CisJY2xrX2VuID0gRklFTERfR0VUKFBXTV9B U1BFRURfQ1RSTF9DTEtfRU5BQkxFLCB2YWwpOworCWRpdl9oID0gRklFTERfR0VUKFBXTV9BU1BF RURfQ1RSTF9DTEtfRElWX0gsIHZhbCk7CisJZGl2X2wgPSBGSUVMRF9HRVQoUFdNX0FTUEVFRF9D VFJMX0NMS19ESVZfTCwgdmFsKTsKKwlyZWdtYXBfcmVhZChwcml2LT5yZWdtYXAsIFBXTV9BU1BF RURfRFVUWV9DWUNMRShod3B3bSksICZ2YWwpOworCWR1dHlfcHQgPSBGSUVMRF9HRVQoUFdNX0FT UEVFRF9EVVRZX0NZQ0xFX0ZBTExJTkdfUE9JTlQsIHZhbCk7CisJZHV0eV9jeWNsZV9wZXJpb2Qg PSBGSUVMRF9HRVQoUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX1BFUklPRCwgdmFsKTsKKworCXJhdGUg PSBjbGtfZ2V0X3JhdGUocHJpdi0+Y2xrKTsKKworCS8qCisJICogVGhpcyBtdWx0aXBsaWNhdGlv biBkb2Vzbid0IG92ZXJmbG93LCB0aGUgdXBwZXIgYm91bmQgaXMKKwkgKiAxMDAwMDAwMDAwICog MjU2ICogMjU2IDw8IDE1ID0gMHgxZGNkNjUwMDAwMDAwMDAwCisJICovCisJZGl2aWRlbmQgPSAo dTY0KU5TRUNfUEVSX1NFQyAqIChkaXZfbCArIDEpICogKGR1dHlfY3ljbGVfcGVyaW9kICsgMSkK KwkJICAgICAgIDw8IGRpdl9oOworCXN0YXRlLT5wZXJpb2QgPSBESVZfUk9VTkRfVVBfVUxMKGRp dmlkZW5kLCByYXRlKTsKKworCWlmIChjbGtfZW4gJiYgZHV0eV9wdCkgeworCQlkaXZpZGVuZCA9 ICh1NjQpTlNFQ19QRVJfU0VDICogKGRpdl9sICsgMSkgKiBkdXR5X3B0CisJCQkJIDw8IGRpdl9o OworCQlzdGF0ZS0+ZHV0eV9jeWNsZSA9IERJVl9ST1VORF9VUF9VTEwoZGl2aWRlbmQsIHJhdGUp OworCX0gZWxzZSB7CisJCXN0YXRlLT5kdXR5X2N5Y2xlID0gY2xrX2VuID8gc3RhdGUtPnBlcmlv ZCA6IDA7CisJfQorCXN0YXRlLT5wb2xhcml0eSA9IHBvbGFyaXR5ID8gUFdNX1BPTEFSSVRZX0lO VkVSU0VEIDogUFdNX1BPTEFSSVRZX05PUk1BTDsKKwlzdGF0ZS0+ZW5hYmxlZCA9IHBpbl9lbjsK KwlkZXZfZGJnKGRldiwgImdldCBwZXJpb2Q6ICVsbGRucywgZHV0eV9jeWNsZTogJWxsZG5zIiwg c3RhdGUtPnBlcmlvZCwKKwkJc3RhdGUtPmR1dHlfY3ljbGUpOworfQorCitzdGF0aWMgaW50IGFz cGVlZF9wd21fYXBwbHkoc3RydWN0IHB3bV9jaGlwICpjaGlwLCBzdHJ1Y3QgcHdtX2RldmljZSAq cHdtLAorCQkJICAgIGNvbnN0IHN0cnVjdCBwd21fc3RhdGUgKnN0YXRlKQoreworCXN0cnVjdCBk ZXZpY2UgKmRldiA9IGNoaXAtPmRldjsKKwlzdHJ1Y3QgYXNwZWVkX3B3bV9kYXRhICpwcml2ID0g YXNwZWVkX3B3bV9jaGlwX3RvX2RhdGEoY2hpcCk7CisJdTMyIGh3cHdtID0gcHdtLT5od3B3bSwg ZHV0eV9wdDsKKwl1bnNpZ25lZCBsb25nIHJhdGU7CisJdTY0IGRpdl9oLCBkaXZfbCwgZGl2aXNv ciwgZXhwZWN0X3BlcmlvZDsKKwlib29sIGNsa19lbjsKKworCXJhdGUgPSBjbGtfZ2V0X3JhdGUo cHJpdi0+Y2xrKTsKKwlleHBlY3RfcGVyaW9kID0gbWluKGRpdjY0X3U2NChVTExPTkdfTUFYLCAo dTY0KXJhdGUpLCBzdGF0ZS0+cGVyaW9kKTsKKwlkZXZfZGJnKGRldiwgImV4cGVjdCBwZXJpb2Q6 ICVsbGRucywgZHV0eV9jeWNsZTogJWxsZG5zIiwgZXhwZWN0X3BlcmlvZCwKKwkJc3RhdGUtPmR1 dHlfY3ljbGUpOworCS8qCisJICogUGljayB0aGUgc21hbGxlc3QgdmFsdWUgZm9yIGRpdl9oIHNv IHRoYXQgZGl2X2wgY2FuIGJlIHRoZSBiaWdnZXN0CisJICogd2hpY2ggcmVzdWx0cyBpbiBhIGZp bmVyIHJlc29sdXRpb24gbmVhciB0aGUgdGFyZ2V0IHBlcmlvZCB2YWx1ZS4KKwkgKi8KKwlkaXZp c29yID0gKHU2NClOU0VDX1BFUl9TRUMgKiAoUFdNX0FTUEVFRF9GSVhFRF9QRVJJT0QgKyAxKSAq CisJCSAgKEZJRUxEX01BWChQV01fQVNQRUVEX0NUUkxfQ0xLX0RJVl9MKSArIDEpOworCWRpdl9o ID0gb3JkZXJfYmFzZV8yKERJVjY0X1U2NF9ST1VORF9VUChyYXRlICogZXhwZWN0X3BlcmlvZCwg ZGl2aXNvcikpOworCWlmIChkaXZfaCA+IDB4ZikKKwkJZGl2X2ggPSAweGY7CisKKwlkaXZpc29y ID0gKCh1NjQpTlNFQ19QRVJfU0VDICogKFBXTV9BU1BFRURfRklYRURfUEVSSU9EICsgMSkpIDw8 IGRpdl9oOworCWRpdl9sID0gZGl2NjRfdTY0KHJhdGUgKiBleHBlY3RfcGVyaW9kLCBkaXZpc29y KTsKKworCWlmIChkaXZfbCA9PSAwKQorCQlyZXR1cm4gLUVSQU5HRTsKKworCWRpdl9sIC09IDE7 CisKKwlpZiAoZGl2X2wgPiAyNTUpCisJCWRpdl9sID0gMjU1OworCisJZGV2X2RiZyhkZXYsICJj bGsgc291cmNlOiAlbGQgZGl2X2ggJWxsZCwgZGl2X2wgOiAlbGxkXG4iLCByYXRlLCBkaXZfaCwK KwkJZGl2X2wpOworCS8qIGR1dHlfcHQgPSBkdXR5X2N5Y2xlICogKFBFUklPRCArIDEpIC8gcGVy aW9kICovCisJZHV0eV9wdCA9IGRpdjY0X3U2NChzdGF0ZS0+ZHV0eV9jeWNsZSAqIHJhdGUsCisJ CQkgICAgKHU2NClOU0VDX1BFUl9TRUMgKiAoZGl2X2wgKyAxKSA8PCBkaXZfaCk7CisJZGV2X2Ri ZyhkZXYsICJkdXR5X2N5Y2xlID0gJWxsZCwgZHV0eV9wdCA9ICVkXG4iLCBzdGF0ZS0+ZHV0eV9j eWNsZSwKKwkJZHV0eV9wdCk7CisKKwkvKgorCSAqIEZpeGVkIERVVFlfQ1lDTEVfUEVSSU9EIHRv IGl0cyBtYXggdmFsdWUgdG8gZ2V0IGEKKwkgKiBmaW5lLWdyYWluZWQgcmVzb2x1dGlvbiBmb3Ig ZHV0eV9jeWNsZSBhdCB0aGUgZXhwZW5zZSBvZiBhCisJICogY29hcnNlciBwZXJpb2QgcmVzb2x1 dGlvbi4KKwkgKi8KKwlyZWdtYXBfdXBkYXRlX2JpdHMocHJpdi0+cmVnbWFwLCBQV01fQVNQRUVE X0RVVFlfQ1lDTEUoaHdwd20pLAorCQkJICAgUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX1BFUklPRCwK KwkJCSAgIEZJRUxEX1BSRVAoUFdNX0FTUEVFRF9EVVRZX0NZQ0xFX1BFUklPRCwKKwkJCQkgICAg ICBQV01fQVNQRUVEX0ZJWEVEX1BFUklPRCkpOworCWlmIChkdXR5X3B0ID09IDApIHsKKwkJLyog ZW1pdCBpbmFjdGl2ZSBsZXZlbCBhbmQgYXNzZXJ0IHRoZSBkdXR5IGNvdW50ZXIgcmVzZXQgKi8K KwkJY2xrX2VuID0gMDsKKwl9IGVsc2UgeworCQljbGtfZW4gPSAxOworCQlpZiAoZHV0eV9wdCA+ PSAoUFdNX0FTUEVFRF9GSVhFRF9QRVJJT0QgKyAxKSkKKwkJCWR1dHlfcHQgPSAwOworCQlyZWdt YXBfdXBkYXRlX2JpdHMocHJpdi0+cmVnbWFwLCBQV01fQVNQRUVEX0RVVFlfQ1lDTEUoaHdwd20p LAorCQkJCSAgIFBXTV9BU1BFRURfRFVUWV9DWUNMRV9SSVNJTkdfUE9JTlQgfAorCQkJCQkgICBQ V01fQVNQRUVEX0RVVFlfQ1lDTEVfRkFMTElOR19QT0lOVCwKKwkJCQkgICBGSUVMRF9QUkVQKFBX TV9BU1BFRURfRFVUWV9DWUNMRV9GQUxMSU5HX1BPSU5ULCBkdXR5X3B0KSk7CisJfQorCisJcmVn bWFwX3VwZGF0ZV9iaXRzKHByaXYtPnJlZ21hcCwgUFdNX0FTUEVFRF9DVFJMKGh3cHdtKSwKKwkJ CSAgIFBXTV9BU1BFRURfQ1RSTF9DTEtfRElWX0ggfCBQV01fQVNQRUVEX0NUUkxfQ0xLX0RJVl9M IHwKKwkJCQkgICBQV01fQVNQRUVEX0NUUkxfUElOX0VOQUJMRSB8IFBXTV9BU1BFRURfQ1RSTF9D TEtfRU5BQkxFIHwKKwkJCQkgICBQV01fQVNQRUVEX0NUUkxfSU5WRVJTRSwKKwkJCSAgIEZJRUxE X1BSRVAoUFdNX0FTUEVFRF9DVFJMX0NMS19ESVZfSCwgZGl2X2gpIHwKKwkJCQkgICBGSUVMRF9Q UkVQKFBXTV9BU1BFRURfQ1RSTF9DTEtfRElWX0wsIGRpdl9sKSB8CisJCQkJICAgRklFTERfUFJF UChQV01fQVNQRUVEX0NUUkxfUElOX0VOQUJMRSwgc3RhdGUtPmVuYWJsZWQpIHwKKwkJCQkgICBG SUVMRF9QUkVQKFBXTV9BU1BFRURfQ1RSTF9DTEtfRU5BQkxFLCBjbGtfZW4pIHwKKwkJCQkgICBG SUVMRF9QUkVQKFBXTV9BU1BFRURfQ1RSTF9JTlZFUlNFLCBzdGF0ZS0+cG9sYXJpdHkpKTsKKwly ZXR1cm4gMDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBwd21fb3BzIGFzcGVlZF9wd21fb3Bz ID0geworCS5hcHBseSA9IGFzcGVlZF9wd21fYXBwbHksCisJLmdldF9zdGF0ZSA9IGFzcGVlZF9w d21fZ2V0X3N0YXRlLAorCS5vd25lciA9IFRISVNfTU9EVUxFLAorfTsKKworc3RhdGljIHZvaWQg YXNwZWVkX3B3bV9yZXNldF9hc3NlcnQodm9pZCAqZGF0YSkKK3sKKwlzdHJ1Y3QgcmVzZXRfY29u dHJvbCAqcnN0ID0gZGF0YTsKKworCXJlc2V0X2NvbnRyb2xfYXNzZXJ0KHJzdCk7Cit9CisKK3N0 YXRpYyB2b2lkIGFzcGVlZF9wd21fY2hpcF9yZW1vdmUodm9pZCAqZGF0YSkKK3sKKwlzdHJ1Y3Qg cHdtX2NoaXAgKmNoaXAgPSBkYXRhOworCisJcHdtY2hpcF9yZW1vdmUoY2hpcCk7Cit9CisKK3N0 YXRpYyBpbnQgYXNwZWVkX3B3bV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQor eworCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7CisJaW50IHJldDsKKwlzdHJ1Y3Qg YXNwZWVkX3B3bV9kYXRhICpwcml2OworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbnA7CisJc3RydWN0 IHBsYXRmb3JtX2RldmljZSAqcGFyZW50X2RldjsKKworCXByaXYgPSBkZXZtX2t6YWxsb2MoZGV2 LCBzaXplb2YoKnByaXYpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXByaXYpCisJCXJldHVybiAtRU5P TUVNOworCisJbnAgPSBwZGV2LT5kZXYucGFyZW50LT5vZl9ub2RlOworCWlmICghb2ZfZGV2aWNl X2lzX2NvbXBhdGlibGUobnAsICJhc3BlZWQsYXN0MjYwMC1wd20tdGFjaCIpKQorCQlyZXR1cm4g ZGV2X2Vycl9wcm9iZShkZXYsIC1FTk9ERVYsCisJCQkJICAgICAiVW5zdXBwb3J0ZWQgcHdtIGRl dmljZSBiaW5kaW5nXG4iKTsKKworCXByaXYtPnJlZ21hcCA9IHN5c2Nvbl9ub2RlX3RvX3JlZ21h cChucCk7CisJaWYgKElTX0VSUihwcml2LT5yZWdtYXApKQorCQlyZXR1cm4gZGV2X2Vycl9wcm9i ZShkZXYsIFBUUl9FUlIocHJpdi0+cmVnbWFwKSwKKwkJCQkgICAgICJDb3VsZG4ndCBnZXQgcmVn bWFwXG4iKTsKKworCXBhcmVudF9kZXYgPSBvZl9maW5kX2RldmljZV9ieV9ub2RlKG5wKTsKKwlw cml2LT5jbGsgPSBkZXZtX2Nsa19nZXRfZW5hYmxlZCgmcGFyZW50X2Rldi0+ZGV2LCBOVUxMKTsK KwlpZiAoSVNfRVJSKHByaXYtPmNsaykpCisJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgUFRS X0VSUihwcml2LT5jbGspLAorCQkJCSAgICAgIkNvdWxkbid0IGdldCBjbG9ja1xuIik7CisKKwlw cml2LT5yZXNldCA9IGRldm1fcmVzZXRfY29udHJvbF9nZXRfc2hhcmVkKCZwYXJlbnRfZGV2LT5k ZXYsIE5VTEwpOworCWlmIChJU19FUlIocHJpdi0+cmVzZXQpKQorCQlyZXR1cm4gZGV2X2Vycl9w cm9iZShkZXYsIFBUUl9FUlIocHJpdi0+cmVzZXQpLAorCQkJCSAgICAgIkNvdWxkbid0IGdldCBy ZXNldCBjb250cm9sXG4iKTsKKworCXJldCA9IHJlc2V0X2NvbnRyb2xfZGVhc3NlcnQocHJpdi0+ cmVzZXQpOworCWlmIChyZXQpCisJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgcmV0LAorCQkJ CSAgICAgIkNvdWxkbid0IGRlYXNzZXJ0IHJlc2V0IGNvbnRyb2xcbiIpOworCisJcmV0ID0gZGV2 bV9hZGRfYWN0aW9uX29yX3Jlc2V0KGRldiwgYXNwZWVkX3B3bV9yZXNldF9hc3NlcnQsCisJCQkJ ICAgICAgIHByaXYtPnJlc2V0KTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJcHJpdi0+ Y2hpcC5kZXYgPSBkZXY7CisJcHJpdi0+Y2hpcC5vcHMgPSAmYXNwZWVkX3B3bV9vcHM7CisJcHJp di0+Y2hpcC5ucHdtID0gUFdNX0FTUEVFRF9OUl9QV01TOworCisJcmV0ID0gcHdtY2hpcF9hZGQo JnByaXYtPmNoaXApOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYs IHJldCwgIkZhaWxlZCB0byBhZGQgUFdNIGNoaXBcbiIpOworCXJldCA9IGRldm1fYWRkX2FjdGlv bl9vcl9yZXNldChkZXYsIGFzcGVlZF9wd21fY2hpcF9yZW1vdmUsCisJCQkJICAgICAgICZwcml2 LT5jaGlwKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCXJldHVybiAwOworfQorCitzdGF0 aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBvZl9wd21fbWF0Y2hfdGFibGVbXSA9IHsKKwl7 CisJCS5jb21wYXRpYmxlID0gImFzcGVlZCxhc3QyNjAwLXB3bSIsCisJfSwKKwl7fSwKK307CitN T0RVTEVfREVWSUNFX1RBQkxFKG9mLCBvZl9wd21fbWF0Y2hfdGFibGUpOworCitzdGF0aWMgc3Ry dWN0IHBsYXRmb3JtX2RyaXZlciBhc3BlZWRfcHdtX2RyaXZlciA9IHsKKwkucHJvYmUgPSBhc3Bl ZWRfcHdtX3Byb2JlLAorCS5kcml2ZXIJPSB7CisJCS5uYW1lID0gImFzcGVlZC1wd20iLAorCQku b2ZfbWF0Y2hfdGFibGUgPSBvZl9wd21fbWF0Y2hfdGFibGUsCisJfSwKK307CisKK21vZHVsZV9w bGF0Zm9ybV9kcml2ZXIoYXNwZWVkX3B3bV9kcml2ZXIpOworCitNT0RVTEVfQVVUSE9SKCJCaWxs eSBUc2FpIDxiaWxseV90c2FpQGFzcGVlZHRlY2guY29tPiIpOworTU9EVUxFX0RFU0NSSVBUSU9O KCJBc3BlZWQgYXN0MjYwMCBQV00gZGV2aWNlIGRyaXZlciIpOworTU9EVUxFX0xJQ0VOU0UoIkdQ TCIpOwotLSAKMi4yNS4xCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBs aXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlz dGluZm8vbGludXgtYXJtLWtlcm5lbAo=