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 54463C6FA8E for ; Sun, 5 Mar 2023 08:55:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229518AbjCEIz5 (ORCPT ); Sun, 5 Mar 2023 03:55:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45674 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229621AbjCEIzz (ORCPT ); Sun, 5 Mar 2023 03:55:55 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 07CE4CA2B; Sun, 5 Mar 2023 00:55:41 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 4C37C60AD6; Sun, 5 Mar 2023 08:55:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98A4EC433D2; Sun, 5 Mar 2023 08:55:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678006539; bh=WX0wYSxbdNdbxTJEbfDpGlef0cG1lLp6IyBHSxSWLaA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=XVejsf9ozZVet8UPVjOuA6VLFBrwH8RbFKXPQn3dXv1XM/dpri18UIFI1Hp3EU1It 8O8qqudnzTZqUKvIZ3LZ0QVJDp2VutJiTI2po6NrNL9aSY1lwizuDn9ifJGG+GcYr/ GfnZGCt96nXRzpkAgu8/Q05nR5zf06wNY6PrY8uTEEoZPD/qZ4qgUVcNYB0mbOVY2d Blj449+HHN2B3jVit900l5cv0tAIe09lV/ow3NAYJGYWQ998HFZCGuTrwWz/vMTI67 1YYS0Rj259A6cBJsRJ9jibVXeXZ6OmSkci07f0Jsta4gFblJLdXNwf1LWY6XlOKnQg /9F8qJZYhpqIQ== Date: Sun, 5 Mar 2023 08:55:33 +0000 From: Lee Jones To: ChiaEn Wu Cc: corbet@lwn.net, pavel@ucw.cz, matthias.bgg@gmail.com, andriy.shevchenko@linux.intel.com, jacek.anaszewski@gmail.com, angelogioacchino.delregno@collabora.com, linux-doc@vger.kernel.org, peterwu.pub@gmail.com, cy_huang@richtek.com, linux-leds@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, szunichen@gmail.com, Alice Chen Subject: Re: [PATCH v17 RESEND 1/3] leds: rgb: mt6370: Add MediaTek MT6370 current sink type LED Indicator support Message-ID: <20230305085533.GC2574592@google.com> References: <8f139c773de274311c8ca63a47d6b207c30913e2.1677150607.git.chiaen_wu@richtek.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <8f139c773de274311c8ca63a47d6b207c30913e2.1677150607.git.chiaen_wu@richtek.com> Precedence: bulk List-ID: X-Mailing-List: linux-doc@vger.kernel.org On Thu, 23 Feb 2023, ChiaEn Wu wrote: > From: ChiYuan Huang > > The MediaTek MT6370 is a highly-integrated smart power management IC, > which includes a single cell Li-Ion/Li-Polymer switching battery > charger, a USB Type-C & Power Delivery (PD) controller, dual > Flash LED current sources, a RGB LED driver, a backlight WLED driver, > a display bias driver and a general LDO for portable devices. > > Add support for the MediaTek MT6370 Current Sink Type LED Indicator > driver. It can control four channels current-sink RGB LEDs with 3 modes: > constant current, PWM, and breath mode. > > Acked-by: Jacek Anaszewski > Co-developed-by: Alice Chen > Signed-off-by: Alice Chen > Signed-off-by: ChiYuan Huang > Signed-off-by: ChiaEn Wu > --- > v17 > - Update the year of Copyright from 2022 to 2023 > > --- > drivers/leds/rgb/Kconfig | 13 + > drivers/leds/rgb/Makefile | 1 + > drivers/leds/rgb/leds-mt6370-rgb.c | 1009 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 1023 insertions(+) > create mode 100644 drivers/leds/rgb/leds-mt6370-rgb.c In generally, this is really nicely done. Great job. Just a few niggles, then you'll be good to go. > diff --git a/drivers/leds/rgb/Kconfig b/drivers/leds/rgb/Kconfig > index 204cf47..7d86bb2 100644 > --- a/drivers/leds/rgb/Kconfig > +++ b/drivers/leds/rgb/Kconfig > @@ -26,4 +26,17 @@ config LEDS_QCOM_LPG > > If compiled as a module, the module will be named leds-qcom-lpg. > > +config LEDS_MT6370_RGB > + tristate "LED Support for MediaTek MT6370 PMIC" > + depends on MFD_MT6370 > + select LINEAR_RANGE > + help > + Say Y here to enable support for MT6370_RGB LED device. > + In MT6370, there are four channel current-sink LED drivers that > + support hardware pattern for constant current, PWM, and breath mode. > + Isink4 channel can also be used as a CHG_VIN power good indicator. > + > + This driver can also be built as a module. If so, the module > + will be called "leds-mt6370-rgb". > + > endif # LEDS_CLASS_MULTICOLOR > diff --git a/drivers/leds/rgb/Makefile b/drivers/leds/rgb/Makefile > index 0675bc0..8c01daf 100644 > --- a/drivers/leds/rgb/Makefile > +++ b/drivers/leds/rgb/Makefile > @@ -2,3 +2,4 @@ > > obj-$(CONFIG_LEDS_PWM_MULTICOLOR) += leds-pwm-multicolor.o > obj-$(CONFIG_LEDS_QCOM_LPG) += leds-qcom-lpg.o > +obj-$(CONFIG_LEDS_MT6370_RGB) += leds-mt6370-rgb.o > diff --git a/drivers/leds/rgb/leds-mt6370-rgb.c b/drivers/leds/rgb/leds-mt6370-rgb.c > new file mode 100644 > index 00000000..185d5d7 > --- /dev/null > +++ b/drivers/leds/rgb/leds-mt6370-rgb.c > @@ -0,0 +1,1009 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Copyright (C) 2023 Richtek Technology Corp. > + * > + * Authors: > + * ChiYuan Huang > + * Alice Chen > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +enum { > + MT6370_LED_ISNK1 = 0, > + MT6370_LED_ISNK2, > + MT6370_LED_ISNK3, > + MT6370_LED_ISNK4, > + MT6370_MAX_LEDS > +}; > + > +enum mt6370_led_mode { > + MT6370_LED_PWM_MODE = 0, > + MT6370_LED_BREATH_MODE, > + MT6370_LED_REG_MODE, > + MT6370_LED_MAX_MODE > +}; > + > +enum mt6370_led_field { > + F_RGB_EN = 0, > + F_CHGIND_EN, > + F_LED1_CURR, > + F_LED2_CURR, > + F_LED3_CURR, > + F_LED4_CURR, > + F_LED1_MODE, > + F_LED2_MODE, > + F_LED3_MODE, > + F_LED4_MODE, > + F_LED1_DUTY, > + F_LED2_DUTY, > + F_LED3_DUTY, > + F_LED4_DUTY, > + F_LED1_FREQ, > + F_LED2_FREQ, > + F_LED3_FREQ, > + F_LED4_FREQ, > + F_MAX_FIELDS > +}; > + > +enum mt6370_led_ranges { > + R_LED123_CURR = 0, > + R_LED4_CURR, > + R_LED_TRFON, > + R_LED_TOFF, > + R_MAX_RANGES > +}; > + > +enum mt6370_pattern { > + P_LED_TR1 = 0, > + P_LED_TR2, > + P_LED_TF1, > + P_LED_TF2, > + P_LED_TON, > + P_LED_TOFF, > + P_MAX_PATTERNS > +}; > + > +#define MT6370_REG_DEV_INFO 0x100 > +#define MT6370_REG_RGB1_DIM 0x182 > +#define MT6370_REG_RGB2_DIM 0x183 > +#define MT6370_REG_RGB3_DIM 0x184 > +#define MT6370_REG_RGB_EN 0x185 > +#define MT6370_REG_RGB1_ISNK 0x186 > +#define MT6370_REG_RGB2_ISNK 0x187 > +#define MT6370_REG_RGB3_ISNK 0x188 > +#define MT6370_REG_RGB1_TR 0x189 > +#define MT6370_REG_RGB_CHRIND_DIM 0x192 > +#define MT6370_REG_RGB_CHRIND_CTRL 0x193 > +#define MT6370_REG_RGB_CHRIND_TR 0x194 > + > +#define MT6372_REG_RGB_EN 0x182 > +#define MT6372_REG_RGB1_ISNK 0x183 > +#define MT6372_REG_RGB2_ISNK 0x184 > +#define MT6372_REG_RGB3_ISNK 0x185 > +#define MT6372_REG_RGB4_ISNK 0x186 > +#define MT6372_REG_RGB1_DIM 0x187 > +#define MT6372_REG_RGB2_DIM 0x188 > +#define MT6372_REG_RGB3_DIM 0x189 > +#define MT6372_REG_RGB4_DIM 0x18A > +#define MT6372_REG_RGB12_FREQ 0x18B > +#define MT6372_REG_RGB34_FREQ 0x18C > +#define MT6372_REG_RGB1_TR 0x18D > + > +#define MT6370_VENID_MASK GENMASK(7, 4) Vendor? Defines should be self documenting. What does this save over "VENDOR_ID"? > +#define MT6370_CHEN_BIT(id) BIT(MT6370_LED_ISNK4 - id) > +#define MT6370_VIRTUAL_MULTICOLOR 5 > +#define MC_CHANNEL_NUM 3 > +#define MT6370_PWM_DUTY (BIT(5) - 1) > +#define MT6372_PWM_DUTY (BIT(8) - 1) > + > +struct mt6370_led { > + /* > + * If the color of the LED in DT is set to > + * - 'LED_COLOR_ID_RGB' > + * - 'LED_COLOR_ID_MULTI' > + * The member 'index' of this struct will be set to > + * 'MT6370_VIRTUAL_MULTICOLOR'. > + * If so, this LED will choose 'struct led_classdev_mc mc' to use. > + * Instead, if the member 'index' of this struct is set to > + * 'MT6370_LED_ISNK1' ~ 'MT6370_LED_ISNK4', then this LED will choose > + * 'struct led_classdev isink' to use. > + */ > + union { > + struct led_classdev isink; > + struct led_classdev_mc mc; > + }; > + struct mt6370_priv *priv; > + enum led_default_state default_state; > + u32 index; > +}; > + > +struct mt6370_pdata { > + const unsigned int *tfreq; > + unsigned int tfreq_len; > + u16 reg_rgb1_tr; > + s16 reg_rgb_chrind_tr; > + u8 pwm_duty; > +}; > + > +struct mt6370_priv { > + /* Per LED access lock */ > + struct mutex lock; > + struct regmap *regmap; > + struct regmap_field *fields[F_MAX_FIELDS]; > + const struct reg_field *reg_fields; > + const struct linear_range *ranges; > + struct reg_cfg *reg_cfgs; > + const struct mt6370_pdata *pdata; > + unsigned int leds_count; > + unsigned int leds_active; > + struct mt6370_led leds[]; > +}; > + > +static const struct reg_field common_reg_fields[F_MAX_FIELDS] = { > + [F_RGB_EN] = REG_FIELD(MT6370_REG_RGB_EN, 4, 7), > + [F_CHGIND_EN] = REG_FIELD(MT6370_REG_RGB_CHRIND_DIM, 7, 7), > + [F_LED1_CURR] = REG_FIELD(MT6370_REG_RGB1_ISNK, 0, 2), > + [F_LED2_CURR] = REG_FIELD(MT6370_REG_RGB2_ISNK, 0, 2), > + [F_LED3_CURR] = REG_FIELD(MT6370_REG_RGB3_ISNK, 0, 2), > + [F_LED4_CURR] = REG_FIELD(MT6370_REG_RGB_CHRIND_CTRL, 0, 1), > + [F_LED1_MODE] = REG_FIELD(MT6370_REG_RGB1_DIM, 5, 6), > + [F_LED2_MODE] = REG_FIELD(MT6370_REG_RGB2_DIM, 5, 6), > + [F_LED3_MODE] = REG_FIELD(MT6370_REG_RGB3_DIM, 5, 6), > + [F_LED4_MODE] = REG_FIELD(MT6370_REG_RGB_CHRIND_DIM, 5, 6), > + [F_LED1_DUTY] = REG_FIELD(MT6370_REG_RGB1_DIM, 0, 4), > + [F_LED2_DUTY] = REG_FIELD(MT6370_REG_RGB2_DIM, 0, 4), > + [F_LED3_DUTY] = REG_FIELD(MT6370_REG_RGB3_DIM, 0, 4), > + [F_LED4_DUTY] = REG_FIELD(MT6370_REG_RGB_CHRIND_DIM, 0, 4), > + [F_LED1_FREQ] = REG_FIELD(MT6370_REG_RGB1_ISNK, 3, 5), > + [F_LED2_FREQ] = REG_FIELD(MT6370_REG_RGB2_ISNK, 3, 5), > + [F_LED3_FREQ] = REG_FIELD(MT6370_REG_RGB3_ISNK, 3, 5), > + [F_LED4_FREQ] = REG_FIELD(MT6370_REG_RGB_CHRIND_CTRL, 2, 4), > +}; > + > +static const struct reg_field mt6372_reg_fields[F_MAX_FIELDS] = { > + [F_RGB_EN] = REG_FIELD(MT6372_REG_RGB_EN, 4, 7), > + [F_CHGIND_EN] = REG_FIELD(MT6372_REG_RGB_EN, 3, 3), > + [F_LED1_CURR] = REG_FIELD(MT6372_REG_RGB1_ISNK, 0, 3), > + [F_LED2_CURR] = REG_FIELD(MT6372_REG_RGB2_ISNK, 0, 3), > + [F_LED3_CURR] = REG_FIELD(MT6372_REG_RGB3_ISNK, 0, 3), > + [F_LED4_CURR] = REG_FIELD(MT6372_REG_RGB4_ISNK, 0, 3), > + [F_LED1_MODE] = REG_FIELD(MT6372_REG_RGB1_ISNK, 6, 7), > + [F_LED2_MODE] = REG_FIELD(MT6372_REG_RGB2_ISNK, 6, 7), > + [F_LED3_MODE] = REG_FIELD(MT6372_REG_RGB3_ISNK, 6, 7), > + [F_LED4_MODE] = REG_FIELD(MT6372_REG_RGB4_ISNK, 6, 7), > + [F_LED1_DUTY] = REG_FIELD(MT6372_REG_RGB1_DIM, 0, 7), > + [F_LED2_DUTY] = REG_FIELD(MT6372_REG_RGB2_DIM, 0, 7), > + [F_LED3_DUTY] = REG_FIELD(MT6372_REG_RGB3_DIM, 0, 7), > + [F_LED4_DUTY] = REG_FIELD(MT6372_REG_RGB4_DIM, 0, 7), > + [F_LED1_FREQ] = REG_FIELD(MT6372_REG_RGB12_FREQ, 5, 7), > + [F_LED2_FREQ] = REG_FIELD(MT6372_REG_RGB12_FREQ, 2, 4), > + [F_LED3_FREQ] = REG_FIELD(MT6372_REG_RGB34_FREQ, 5, 7), > + [F_LED4_FREQ] = REG_FIELD(MT6372_REG_RGB34_FREQ, 2, 4), > +}; > + > +/* Current unit: microamp, time unit: millisecond */ > +static const struct linear_range common_led_ranges[R_MAX_RANGES] = { > + [R_LED123_CURR] = { 4000, 1, 6, 4000 }, > + [R_LED4_CURR] = { 2000, 1, 3, 2000 }, > + [R_LED_TRFON] = { 125, 0, 15, 200 }, > + [R_LED_TOFF] = { 250, 0, 15, 400 }, > +}; > + > +static const struct linear_range mt6372_led_ranges[R_MAX_RANGES] = { > + [R_LED123_CURR] = { 2000, 1, 14, 2000 }, > + [R_LED4_CURR] = { 2000, 1, 14, 2000 }, > + [R_LED_TRFON] = { 125, 0, 15, 250 }, > + [R_LED_TOFF] = { 250, 0, 15, 500 }, > +}; > + > +static const unsigned int common_tfreqs[] = { > + 10000, 5000, 2000, 1000, 500, 200, 5, 1, > +}; > + > +static const unsigned int mt6372_tfreqs[] = { > + 8000, 4000, 2000, 1000, 500, 250, 8, 4, > +}; > + > +static const struct mt6370_pdata common_pdata = { > + .tfreq = common_tfreqs, > + .tfreq_len = ARRAY_SIZE(common_tfreqs), > + .pwm_duty = MT6370_PWM_DUTY, > + .reg_rgb1_tr = MT6370_REG_RGB1_TR, > + .reg_rgb_chrind_tr = MT6370_REG_RGB_CHRIND_TR, > +}; > + > +static const struct mt6370_pdata mt6372_pdata = { > + .tfreq = mt6372_tfreqs, > + .tfreq_len = ARRAY_SIZE(mt6372_tfreqs), > + .pwm_duty = MT6372_PWM_DUTY, > + .reg_rgb1_tr = MT6372_REG_RGB1_TR, > + .reg_rgb_chrind_tr = -1, > +}; > + > +static enum mt6370_led_field mt6370_get_led_current_field(unsigned int led_no) > +{ > + switch (led_no) { > + case MT6370_LED_ISNK1: > + return F_LED1_CURR; > + case MT6370_LED_ISNK2: > + return F_LED2_CURR; > + case MT6370_LED_ISNK3: > + return F_LED3_CURR; > + default: > + return F_LED4_CURR; > + } > +} > + > +static int mt6370_set_led_brightness(struct mt6370_priv *priv, > + unsigned int led_no, unsigned int level) > +{ > + enum mt6370_led_field sel_field; > + > + sel_field = mt6370_get_led_current_field(led_no); > + > + return regmap_field_write(priv->fields[sel_field], level); > +} > + > +static int mt6370_get_led_brightness(struct mt6370_priv *priv, > + unsigned int led_no, unsigned int *level) > +{ > + enum mt6370_led_field sel_field; > + > + sel_field = mt6370_get_led_current_field(led_no); > + > + return regmap_field_read(priv->fields[sel_field], level); > +} > + > +static int mt6370_set_led_duty(struct mt6370_priv *priv, unsigned int led_no, > + unsigned int ton, unsigned int toff) > +{ > + const struct mt6370_pdata *pdata = priv->pdata; > + enum mt6370_led_field sel_field; > + unsigned int divisor, ratio; > + > + divisor = pdata->pwm_duty; > + ratio = ton * divisor / (ton + toff); > + > + switch (led_no) { > + case MT6370_LED_ISNK1: > + sel_field = F_LED1_DUTY; > + break; > + case MT6370_LED_ISNK2: > + sel_field = F_LED2_DUTY; > + break; > + case MT6370_LED_ISNK3: > + sel_field = F_LED3_DUTY; > + break; > + default: > + sel_field = F_LED4_DUTY; > + break; > + } > + > + return regmap_field_write(priv->fields[sel_field], ratio); > +} > + > +static int mt6370_set_led_freq(struct mt6370_priv *priv, unsigned int led_no, > + unsigned int ton, unsigned int toff) > +{ > + const struct mt6370_pdata *pdata = priv->pdata; > + enum mt6370_led_field sel_field; > + unsigned int tfreq_len = pdata->tfreq_len; > + unsigned int tsum, sel; > + > + tsum = ton + toff; > + > + if (tsum > pdata->tfreq[0] || tsum < pdata->tfreq[tfreq_len - 1]) > + return -EOPNOTSUPP; > + > + sel = find_closest_descending(tsum, pdata->tfreq, tfreq_len); > + > + switch (led_no) { > + case MT6370_LED_ISNK1: > + sel_field = F_LED1_FREQ; > + break; > + case MT6370_LED_ISNK2: > + sel_field = F_LED2_FREQ; > + break; > + case MT6370_LED_ISNK3: > + sel_field = F_LED3_FREQ; > + break; > + default: > + sel_field = F_LED4_FREQ; > + break; > + } > + > + return regmap_field_write(priv->fields[sel_field], sel); > +} > + > +static void mt6370_get_breath_reg_base(struct mt6370_priv *priv, > + unsigned int led_no, unsigned int *base) > +{ > + const struct mt6370_pdata *pdata = priv->pdata; > + > + if (pdata->reg_rgb_chrind_tr < 0) { > + *base = pdata->reg_rgb1_tr + led_no * 3; > + return; > + } > + > + switch (led_no) { > + case MT6370_LED_ISNK1: > + case MT6370_LED_ISNK2: > + case MT6370_LED_ISNK3: > + *base = pdata->reg_rgb1_tr + led_no * 3; > + break; > + default: > + *base = pdata->reg_rgb_chrind_tr; > + break; > + } > +} > + > +static int mt6370_gen_breath_pattern(struct mt6370_priv *priv, > + struct led_pattern *pattern, u32 len, > + u8 *pattern_val, u32 val_len) > +{ > + enum mt6370_led_ranges sel_range; > + struct led_pattern *curr; > + unsigned int sel; > + u32 val = 0; > + int i; > + > + if (len < P_MAX_PATTERNS && val_len < P_MAX_PATTERNS / 2) > + return -EINVAL; > + > + /* > + * Pattern list > + * tr1: byte 0, b'[7: 4] Perhaps this is standard formatting and I'm just not aware of it, but the space is throwing me and making me think twice. Does this mean bits 7 through 4, so b'11110000? > + * tr2: byte 0, b'[3: 0] > + * tf1: byte 1, b'[7: 4] > + * tf2: byte 1, b'[3: 0] > + * ton: byte 2, b'[7: 4] > + * toff: byte 2, b'[3: 0] > + */ > + for (i = 0; i < P_MAX_PATTERNS; i++) { > + curr = pattern + i; > + > + sel_range = i == P_LED_TOFF ? R_LED_TOFF : R_LED_TRFON; > + > + linear_range_get_selector_within(priv->ranges + sel_range, > + curr->delta_t, &sel); > + > + if (i % 2) { > + val |= sel; > + } else { > + val <<= 8; > + val |= sel << 4; > + } > + } > + > + put_unaligned_be24(val, pattern_val); > + > + return 0; > +} > + > +static int mt6370_set_led_mode(struct mt6370_priv *priv, unsigned int led_no, > + enum mt6370_led_mode mode) > +{ > + enum mt6370_led_field sel_field; > + > + switch (led_no) { > + case MT6370_LED_ISNK1: > + sel_field = F_LED1_MODE; > + break; > + case MT6370_LED_ISNK2: > + sel_field = F_LED2_MODE; > + break; > + case MT6370_LED_ISNK3: > + sel_field = F_LED3_MODE; > + break; > + default: > + sel_field = F_LED4_MODE; > + break; > + } > + > + return regmap_field_write(priv->fields[sel_field], mode); > +} > + > +static int mt6370_mc_brightness_set(struct led_classdev *lcdev, > + enum led_brightness level) > +{ > + struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); > + struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); > + struct mt6370_priv *priv = led->priv; > + struct mc_subled *subled; > + unsigned int enable, disable; > + int i, ret; > + > + mutex_lock(&priv->lock); > + > + led_mc_calc_color_components(mccdev, level); > + > + ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); > + if (ret) > + goto out_unlock; > + > + disable = enable; > + > + for (i = 0; i < mccdev->num_colors; i++) { > + u32 brightness; > + > + subled = mccdev->subled_info + i; > + brightness = min(subled->brightness, lcdev->max_brightness); > + disable &= ~MT6370_CHEN_BIT(subled->channel); > + > + if (level == 0) { > + enable &= ~MT6370_CHEN_BIT(subled->channel); > + > + ret = mt6370_set_led_mode(priv, subled->channel, > + MT6370_LED_REG_MODE); Please unify your line-wrap strategy. In some places you are using the full 100-chars allowable and in many others, you line-wrap early. Please go through the entire file and unwrap to 100-chars where appropriate. You'll see what I mean as you re-read the file with this in mind. > + if (ret) > + goto out_unlock; > + > + continue; > + } > + > + if (brightness == 0) { > + enable &= ~MT6370_CHEN_BIT(subled->channel); > + continue; > + } > + > + enable |= MT6370_CHEN_BIT(subled->channel); > + > + ret = mt6370_set_led_brightness(priv, subled->channel, > + brightness); > + if (ret) > + goto out_unlock; > + } > + > + ret = regmap_field_write(priv->fields[F_RGB_EN], disable); > + if (ret) > + goto out_unlock; > + > + ret = regmap_field_write(priv->fields[F_RGB_EN], enable); > + > +out_unlock: > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static int mt6370_mc_blink_set(struct led_classdev *lcdev, > + unsigned long *delay_on, > + unsigned long *delay_off) > +{ > + struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); > + struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); > + struct mt6370_priv *priv = led->priv; > + struct mc_subled *subled; > + unsigned int enable, disable; > + int i, ret; > + > + mutex_lock(&priv->lock); > + > + if (!*delay_on && !*delay_off) > + *delay_on = *delay_off = 500; > + > + ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); > + if (ret) > + goto out_unlock; > + > + disable = enable; > + > + for (i = 0; i < mccdev->num_colors; i++) { > + subled = mccdev->subled_info + i; > + > + disable &= ~MT6370_CHEN_BIT(subled->channel); > + > + ret = mt6370_set_led_duty(priv, subled->channel, *delay_on, > + *delay_off); > + if (ret) > + goto out_unlock; > + > + ret = mt6370_set_led_freq(priv, subled->channel, *delay_on, > + *delay_off); > + if (ret) > + goto out_unlock; > + > + ret = mt6370_set_led_mode(priv, subled->channel, > + MT6370_LED_PWM_MODE); > + if (ret) > + goto out_unlock; > + } > + > + /* Toggle to make pattern timing the same */ > + ret = regmap_field_write(priv->fields[F_RGB_EN], disable); > + if (ret) > + goto out_unlock; > + > + ret = regmap_field_write(priv->fields[F_RGB_EN], enable); > + > +out_unlock: > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static int mt6370_mc_pattern_set(struct led_classdev *lcdev, > + struct led_pattern *pattern, u32 len, int repeat) > +{ > + struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); > + struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); > + struct mt6370_priv *priv = led->priv; > + struct mc_subled *subled; > + unsigned int reg_base, enable, disable; > + u8 params[P_MAX_PATTERNS / 2]; > + int i, ret; > + > + mutex_lock(&priv->lock); > + > + ret = mt6370_gen_breath_pattern(priv, pattern, len, params, > + sizeof(params)); > + if (ret) > + goto out_unlock; > + > + ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); > + if (ret) > + goto out_unlock; > + > + disable = enable; > + > + for (i = 0; i < mccdev->num_colors; i++) { > + subled = mccdev->subled_info + i; > + > + mt6370_get_breath_reg_base(priv, subled->channel, ®_base); > + disable &= ~MT6370_CHEN_BIT(subled->channel); > + > + ret = regmap_raw_write(priv->regmap, reg_base, params, > + sizeof(params)); > + if (ret) > + goto out_unlock; > + > + ret = mt6370_set_led_mode(priv, subled->channel, > + MT6370_LED_BREATH_MODE); > + if (ret) > + goto out_unlock; > + } > + > + /* Toggle to make pattern timing be the same */ > + ret = regmap_field_write(priv->fields[F_RGB_EN], disable); > + if (ret) > + goto out_unlock; > + > + ret = regmap_field_write(priv->fields[F_RGB_EN], enable); > + > +out_unlock: > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static inline int mt6370_mc_pattern_clear(struct led_classdev *lcdev) > +{ > + struct led_classdev_mc *mccdev = lcdev_to_mccdev(lcdev); > + struct mt6370_led *led = container_of(mccdev, struct mt6370_led, mc); > + struct mt6370_priv *priv = led->priv; > + struct mc_subled *subled; > + int i, ret; > + > + mutex_lock(&led->priv->lock); > + > + for (i = 0; i < mccdev->num_colors; i++) { > + subled = mccdev->subled_info + i; > + > + ret = mt6370_set_led_mode(priv, subled->channel, > + MT6370_LED_REG_MODE); > + if (ret) > + break; > + } > + > + mutex_unlock(&led->priv->lock); > + > + return ret; > +} > + > +static int mt6370_isnk_brightness_set(struct led_classdev *lcdev, > + enum led_brightness level) > +{ > + struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); > + struct mt6370_priv *priv = led->priv; > + unsigned int enable; > + int ret; > + > + mutex_lock(&priv->lock); > + > + ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); > + if (ret) > + goto out_unlock; > + > + if (level == 0) { > + enable &= ~MT6370_CHEN_BIT(led->index); > + > + ret = mt6370_set_led_mode(priv, led->index, > + MT6370_LED_REG_MODE); > + if (ret) > + goto out_unlock; > + } else { > + enable |= MT6370_CHEN_BIT(led->index); > + > + ret = mt6370_set_led_brightness(priv, led->index, level); > + if (ret) > + goto out_unlock; > + } > + > + ret = regmap_field_write(priv->fields[F_RGB_EN], enable); > + > +out_unlock: > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static int mt6370_isnk_blink_set(struct led_classdev *lcdev, > + unsigned long *delay_on, > + unsigned long *delay_off) > +{ > + struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); > + struct mt6370_priv *priv = led->priv; > + int ret; > + > + mutex_lock(&priv->lock); > + > + if (!*delay_on && !*delay_off) > + *delay_on = *delay_off = 500; > + > + ret = mt6370_set_led_duty(priv, led->index, *delay_on, *delay_off); > + if (ret) > + goto out_unlock; > + > + ret = mt6370_set_led_freq(priv, led->index, *delay_on, *delay_off); > + if (ret) > + goto out_unlock; > + > + ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_PWM_MODE); > + > +out_unlock: > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static int mt6370_isnk_pattern_set(struct led_classdev *lcdev, > + struct led_pattern *pattern, u32 len, > + int repeat) > +{ > + struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); > + struct mt6370_priv *priv = led->priv; > + unsigned int reg_base; > + u8 params[P_MAX_PATTERNS / 2]; > + int ret; > + > + mutex_lock(&priv->lock); > + > + ret = mt6370_gen_breath_pattern(priv, pattern, len, params, > + sizeof(params)); > + if (ret) > + goto out_unlock; > + > + mt6370_get_breath_reg_base(priv, led->index, ®_base); > + > + ret = regmap_raw_write(priv->regmap, reg_base, params, sizeof(params)); > + if (ret) > + goto out_unlock; > + > + ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_BREATH_MODE); > + > +out_unlock: > + mutex_unlock(&priv->lock); > + > + return ret; > +} > + > +static inline int mt6370_isnk_pattern_clear(struct led_classdev *lcdev) > +{ > + struct mt6370_led *led = container_of(lcdev, struct mt6370_led, isink); > + struct mt6370_priv *priv = led->priv; > + int ret; > + > + mutex_lock(&led->priv->lock); > + ret = mt6370_set_led_mode(priv, led->index, MT6370_LED_REG_MODE); > + mutex_unlock(&led->priv->lock); > + > + return ret; > +} > + > +static int mt6370_init_led_properties(struct device *dev, > + struct mt6370_led *led, > + struct led_init_data *init_data) > +{ > + struct mt6370_priv *priv = led->priv; > + struct led_classdev *lcdev; > + struct fwnode_handle *child; > + enum mt6370_led_ranges sel_range; > + u32 max_uA, max_level; > + int ret; > + > + if (led->index == MT6370_VIRTUAL_MULTICOLOR) { Rather than having these huge if-else statements, please consider using a sub-function. > + struct mc_subled *sub_led; > + u32 num_color = 0; > + > + sub_led = devm_kcalloc(dev, MC_CHANNEL_NUM, sizeof(*sub_led), > + GFP_KERNEL); > + if (!sub_led) > + return -ENOMEM; > + > + fwnode_for_each_child_node(init_data->fwnode, child) { > + u32 reg, color; > + > + ret = fwnode_property_read_u32(child, "reg", ®); > + if (ret || reg > MT6370_LED_ISNK3 || > + priv->leds_active & BIT(reg)) { > + fwnode_handle_put(child); > + return -EINVAL; > + } > + > + ret = fwnode_property_read_u32(child, "color", &color); > + if (ret) { > + fwnode_handle_put(child); > + return dev_err_probe(dev, ret, "LED %d, no color specified\n", > + led->index); > + } > + > + priv->leds_active |= BIT(reg); > + sub_led[num_color].color_index = color; > + sub_led[num_color].channel = reg; > + sub_led[num_color].intensity = 0; > + num_color++; > + } > + > + if (num_color < 2) > + return dev_err_probe(dev, -EINVAL, > + "Multicolor must include 2 or more LED channels\n"); > + > + led->mc.num_colors = num_color; > + led->mc.subled_info = sub_led; > + > + lcdev = &led->mc.led_cdev; > + lcdev->brightness_set_blocking = mt6370_mc_brightness_set; > + lcdev->blink_set = mt6370_mc_blink_set; > + lcdev->pattern_set = mt6370_mc_pattern_set; > + lcdev->pattern_clear = mt6370_mc_pattern_clear; > + } else { > + lcdev = &led->isink; > + lcdev->brightness_set_blocking = mt6370_isnk_brightness_set; > + lcdev->blink_set = mt6370_isnk_blink_set; > + lcdev->pattern_set = mt6370_isnk_pattern_set; > + lcdev->pattern_clear = mt6370_isnk_pattern_clear; > + } > + > + ret = fwnode_property_read_u32(init_data->fwnode, "led-max-microamp", > + &max_uA); > + if (ret) { > + dev_warn(dev, "Not specified led-max-microamp, config to the minimum\n"); > + max_uA = 0; > + } > + > + if (led->index == MT6370_LED_ISNK4) > + sel_range = R_LED4_CURR; > + else > + sel_range = R_LED123_CURR; > + > + linear_range_get_selector_within(priv->ranges + sel_range, max_uA, > + &max_level); > + > + lcdev->max_brightness = max_level; > + > + led->default_state = led_init_default_state_get(init_data->fwnode); > + > + return 0; > +} > + > +static int mt6370_isnk_init_default_state(struct mt6370_led *led) > +{ > + struct mt6370_priv *priv = led->priv; > + unsigned int enable, level; > + int ret; > + > + ret = mt6370_get_led_brightness(priv, led->index, &level); > + if (ret) > + return ret; > + > + ret = regmap_field_read(priv->fields[F_RGB_EN], &enable); > + if (ret) > + return ret; > + > + if (!(enable & MT6370_CHEN_BIT(led->index))) > + level = 0; > + > + switch (led->default_state) { > + case LEDS_DEFSTATE_ON: > + led->isink.brightness = led->isink.max_brightness; > + break; > + case LEDS_DEFSTATE_KEEP: > + led->isink.brightness = min(level, led->isink.max_brightness); > + break; > + default: > + led->isink.brightness = 0; > + break; > + } > + > + return mt6370_isnk_brightness_set(&led->isink, led->isink.brightness); > +} > + > +static int mt6370_led_register(struct device *dev, struct mt6370_led *led, > + struct led_init_data *init_data) > +{ > + struct mt6370_priv *priv = led->priv; > + int ret; > + > + if (led->index == MT6370_VIRTUAL_MULTICOLOR) { This too could be split into separate functions to tidy things up a little. > + ret = mt6370_mc_brightness_set(&led->mc.led_cdev, 0); > + if (ret) > + return dev_err_probe(dev, ret, "Couldn't set multicolor brightness\n"); > + > + ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc, > + init_data); > + if (ret) > + return dev_err_probe(dev, ret, "Couldn't register multicolor\n"); > + } else { > + if (led->index == MT6370_LED_ISNK4) { > + ret = regmap_field_write(priv->fields[F_CHGIND_EN], 1); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to set CHRIND to SW\n"); > + } > + > + ret = mt6370_isnk_init_default_state(led); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to init %d isnk state\n", > + led->index); > + > + ret = devm_led_classdev_register_ext(dev, &led->isink, > + init_data); > + if (ret) > + return dev_err_probe(dev, ret, "Couldn't register isink %d\n", led->index); > + } > + > + return 0; > +} > + > +static int mt6370_check_vendor_info(struct mt6370_priv *priv) > +{ > + unsigned int devinfo, vid; > + int ret; > + > + ret = regmap_read(priv->regmap, MT6370_REG_DEV_INFO, &devinfo); > + if (ret) > + return ret; > + > + vid = FIELD_GET(MT6370_VENID_MASK, devinfo); > + if (vid == 0x9 || vid == 0xb) { Are there nice human readable associates of these (vendor?) IDS? > + priv->reg_fields = mt6372_reg_fields; > + priv->ranges = mt6372_led_ranges; > + priv->pdata = &mt6372_pdata; > + } else { > + /* Common for MT6370/71 */ > + priv->reg_fields = common_reg_fields; > + priv->ranges = common_led_ranges; > + priv->pdata = &common_pdata; > + } > + > + return 0; > +} > + > +static int mt6370_leds_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct mt6370_priv *priv; > + struct fwnode_handle *child; > + size_t count; > + unsigned int i = 0; > + int ret; > + > + count = device_get_child_node_count(dev); > + if (!count || count > MT6370_MAX_LEDS) > + return dev_err_probe(dev, -EINVAL, > + "No child node or node count over max LED number %zu\n", > + count); > + > + priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + priv->leds_count = count; > + mutex_init(&priv->lock); > + > + priv->regmap = dev_get_regmap(dev->parent, NULL); > + if (!priv->regmap) > + return dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n"); > + > + ret = mt6370_check_vendor_info(priv); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to check vendor info\n"); > + > + ret = devm_regmap_field_bulk_alloc(dev, priv->regmap, priv->fields, > + priv->reg_fields, F_MAX_FIELDS); > + if (ret) > + return dev_err_probe(dev, ret, "Failed to allocate regmap field\n"); > + > + device_for_each_child_node(dev, child) { > + struct mt6370_led *led = priv->leds + i++; > + struct led_init_data init_data = { .fwnode = child }; > + u32 reg, color; > + > + ret = fwnode_property_read_u32(child, "reg", ®); > + if (ret) { > + fwnode_handle_put(child); > + return dev_err_probe(dev, ret, "Failed to parse reg property\n"); > + } > + > + if (reg >= MT6370_MAX_LEDS) { > + fwnode_handle_put(child); > + return dev_err_probe(dev, -EINVAL, "Error reg property number\n"); > + } > + > + ret = fwnode_property_read_u32(child, "color", &color); > + if (ret) { > + fwnode_handle_put(child); > + return dev_err_probe(dev, ret, "Failed to parse color property\n"); > + } > + > + if (color == LED_COLOR_ID_RGB || color == LED_COLOR_ID_MULTI) > + reg = MT6370_VIRTUAL_MULTICOLOR; > + > + if (priv->leds_active & BIT(reg)) { > + fwnode_handle_put(child); > + return dev_err_probe(dev, -EINVAL, "Duplicate reg property\n"); > + } > + > + priv->leds_active |= BIT(reg); > + > + led->index = reg; > + led->priv = priv; > + > + ret = mt6370_init_led_properties(dev, led, &init_data); > + if (ret) { > + fwnode_handle_put(child); I count 6 calls to fwnode_handle_put() here. Please use a goto to divert the error handling to the bottom of the function where you call fwnode_handle_put() just once. > + return ret; > + } > + > + ret = mt6370_led_register(dev, led, &init_data); > + if (ret) { > + fwnode_handle_put(child); > + return ret; > + } > + } > + > + return 0; > +} > + > +static const struct of_device_id mt6370_rgbled_device_table[] = { > + { .compatible = "mediatek,mt6370-indicator" }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, mt6370_rgbled_device_table); > + > +static struct platform_driver mt6370_rgbled_driver = { > + .driver = { > + .name = "mt6370-indicator", > + .of_match_table = mt6370_rgbled_device_table, > + }, > + .probe = mt6370_leds_probe, > +}; > +module_platform_driver(mt6370_rgbled_driver); > + > +MODULE_AUTHOR("Alice Chen "); > +MODULE_AUTHOR("ChiYuan Huang "); > +MODULE_DESCRIPTION("MediaTek MT6370 RGB LED Driver"); > +MODULE_LICENSE("GPL"); > -- > 2.7.4 > -- Lee Jones [李琼斯] 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 17F2DC6FA8E for ; Sun, 5 Mar 2023 08:57:23 +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=m2mi+Uh8wwe/1562pY5oR0LwzrSFmrTZWBSGTIYrcA4=; b=VufUg2Gsm2obFN VRCluQSIspwP2xhYLuVBTUdoJerOFLLONDMM13RJFAriK8b7hfP317UtOR7csyERBoNw3/hAb0mft fI5n9W43CiY+hOwUu25YzLc249d3HS/DDndwKxt+Q9A1noP7rxCJFhRYdfifscnqWMNZlWZsV/RoH szWNEJE3fSs1koSiHvRCoEgoYqw/6qwHv8wN3zH416Q1LEdRJ0tTG80m8Rm/C2OWuASRZHl74IpQf R8EYmfi1YYb0mlnQ0vX1wMkPwwJV0aM37imqI2aNGTjGRiDKQGGGcZ6QNZIST9LawEINtt5quglkN xMeOYQsNJhu0Gqb2PNgw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1pYk9l-009yoR-2o; Sun, 05 Mar 2023 08:55:49 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1pYk9d-009ynn-K7; Sun, 05 Mar 2023 08:55:45 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 354D660AB6; Sun, 5 Mar 2023 08:55:40 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98A4EC433D2; Sun, 5 Mar 2023 08:55:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678006539; bh=WX0wYSxbdNdbxTJEbfDpGlef0cG1lLp6IyBHSxSWLaA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=XVejsf9ozZVet8UPVjOuA6VLFBrwH8RbFKXPQn3dXv1XM/dpri18UIFI1Hp3EU1It 8O8qqudnzTZqUKvIZ3LZ0QVJDp2VutJiTI2po6NrNL9aSY1lwizuDn9ifJGG+GcYr/ GfnZGCt96nXRzpkAgu8/Q05nR5zf06wNY6PrY8uTEEoZPD/qZ4qgUVcNYB0mbOVY2d Blj449+HHN2B3jVit900l5cv0tAIe09lV/ow3NAYJGYWQ998HFZCGuTrwWz/vMTI67 1YYS0Rj259A6cBJsRJ9jibVXeXZ6OmSkci07f0Jsta4gFblJLdXNwf1LWY6XlOKnQg /9F8qJZYhpqIQ== Date: Sun, 5 Mar 2023 08:55:33 +0000 From: Lee Jones To: ChiaEn Wu Cc: corbet@lwn.net, pavel@ucw.cz, matthias.bgg@gmail.com, andriy.shevchenko@linux.intel.com, jacek.anaszewski@gmail.com, angelogioacchino.delregno@collabora.com, linux-doc@vger.kernel.org, peterwu.pub@gmail.com, cy_huang@richtek.com, linux-leds@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org, szunichen@gmail.com, Alice Chen Subject: Re: [PATCH v17 RESEND 1/3] leds: rgb: mt6370: Add MediaTek MT6370 current sink type LED Indicator support Message-ID: <20230305085533.GC2574592@google.com> References: <8f139c773de274311c8ca63a47d6b207c30913e2.1677150607.git.chiaen_wu@richtek.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <8f139c773de274311c8ca63a47d6b207c30913e2.1677150607.git.chiaen_wu@richtek.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230305_005541_814898_025B89F5 X-CRM114-Status: GOOD ( 34.20 ) 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 T24gVGh1LCAyMyBGZWIgMjAyMywgQ2hpYUVuIFd1IHdyb3RlOgoKPiBGcm9tOiBDaGlZdWFuIEh1 YW5nIDxjeV9odWFuZ0ByaWNodGVrLmNvbT4KPiAKPiBUaGUgTWVkaWFUZWsgTVQ2MzcwIGlzIGEg aGlnaGx5LWludGVncmF0ZWQgc21hcnQgcG93ZXIgbWFuYWdlbWVudCBJQywKPiB3aGljaCBpbmNs dWRlcyBhIHNpbmdsZSBjZWxsIExpLUlvbi9MaS1Qb2x5bWVyIHN3aXRjaGluZyBiYXR0ZXJ5Cj4g Y2hhcmdlciwgYSBVU0IgVHlwZS1DICYgUG93ZXIgRGVsaXZlcnkgKFBEKSBjb250cm9sbGVyLCBk dWFsCj4gRmxhc2ggTEVEIGN1cnJlbnQgc291cmNlcywgYSBSR0IgTEVEIGRyaXZlciwgYSBiYWNr bGlnaHQgV0xFRCBkcml2ZXIsCj4gYSBkaXNwbGF5IGJpYXMgZHJpdmVyIGFuZCBhIGdlbmVyYWwg TERPIGZvciBwb3J0YWJsZSBkZXZpY2VzLgo+IAo+IEFkZCBzdXBwb3J0IGZvciB0aGUgTWVkaWFU ZWsgTVQ2MzcwIEN1cnJlbnQgU2luayBUeXBlIExFRCBJbmRpY2F0b3IKPiBkcml2ZXIuIEl0IGNh biBjb250cm9sIGZvdXIgY2hhbm5lbHMgY3VycmVudC1zaW5rIFJHQiBMRURzIHdpdGggMyBtb2Rl czoKPiBjb25zdGFudCBjdXJyZW50LCBQV00sIGFuZCBicmVhdGggbW9kZS4KPiAKPiBBY2tlZC1i eTogSmFjZWsgQW5hc3pld3NraSA8amFjZWsuYW5hc3pld3NraUBnbWFpbC5jb20+Cj4gQ28tZGV2 ZWxvcGVkLWJ5OiBBbGljZSBDaGVuIDxhbGljZV9jaGVuQHJpY2h0ZWsuY29tPgo+IFNpZ25lZC1v ZmYtYnk6IEFsaWNlIENoZW4gPGFsaWNlX2NoZW5AcmljaHRlay5jb20+Cj4gU2lnbmVkLW9mZi1i eTogQ2hpWXVhbiBIdWFuZyA8Y3lfaHVhbmdAcmljaHRlay5jb20+Cj4gU2lnbmVkLW9mZi1ieTog Q2hpYUVuIFd1IDxjaGlhZW5fd3VAcmljaHRlay5jb20+Cj4gLS0tCj4gdjE3Cj4gLSBVcGRhdGUg dGhlIHllYXIgb2YgQ29weXJpZ2h0IGZyb20gMjAyMiB0byAyMDIzCj4gCj4gLS0tCj4gIGRyaXZl cnMvbGVkcy9yZ2IvS2NvbmZpZyAgICAgICAgICAgfCAgIDEzICsKPiAgZHJpdmVycy9sZWRzL3Jn Yi9NYWtlZmlsZSAgICAgICAgICB8ICAgIDEgKwo+ICBkcml2ZXJzL2xlZHMvcmdiL2xlZHMtbXQ2 MzcwLXJnYi5jIHwgMTAwOSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiAg MyBmaWxlcyBjaGFuZ2VkLCAxMDIzIGluc2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0 IGRyaXZlcnMvbGVkcy9yZ2IvbGVkcy1tdDYzNzAtcmdiLmMKCkluIGdlbmVyYWxseSwgdGhpcyBp cyByZWFsbHkgbmljZWx5IGRvbmUuICBHcmVhdCBqb2IuCgpKdXN0IGEgZmV3IG5pZ2dsZXMsIHRo ZW4geW91J2xsIGJlIGdvb2QgdG8gZ28uCiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9sZWRzL3Jn Yi9LY29uZmlnIGIvZHJpdmVycy9sZWRzL3JnYi9LY29uZmlnCj4gaW5kZXggMjA0Y2Y0Ny4uN2Q4 NmJiMiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2xlZHMvcmdiL0tjb25maWcKPiArKysgYi9kcml2 ZXJzL2xlZHMvcmdiL0tjb25maWcKPiBAQCAtMjYsNCArMjYsMTcgQEAgY29uZmlnIExFRFNfUUNP TV9MUEcKPiAgCj4gIAkgIElmIGNvbXBpbGVkIGFzIGEgbW9kdWxlLCB0aGUgbW9kdWxlIHdpbGwg YmUgbmFtZWQgbGVkcy1xY29tLWxwZy4KPiAgCj4gK2NvbmZpZyBMRURTX01UNjM3MF9SR0IKPiAr CXRyaXN0YXRlICJMRUQgU3VwcG9ydCBmb3IgTWVkaWFUZWsgTVQ2MzcwIFBNSUMiCj4gKwlkZXBl bmRzIG9uIE1GRF9NVDYzNzAKPiArCXNlbGVjdCBMSU5FQVJfUkFOR0UKPiArCWhlbHAKPiArCSAg U2F5IFkgaGVyZSB0byBlbmFibGUgc3VwcG9ydCBmb3IgTVQ2MzcwX1JHQiBMRUQgZGV2aWNlLgo+ ICsJICBJbiBNVDYzNzAsIHRoZXJlIGFyZSBmb3VyIGNoYW5uZWwgY3VycmVudC1zaW5rIExFRCBk cml2ZXJzIHRoYXQKPiArCSAgc3VwcG9ydCBoYXJkd2FyZSBwYXR0ZXJuIGZvciBjb25zdGFudCBj dXJyZW50LCBQV00sIGFuZCBicmVhdGggbW9kZS4KPiArCSAgSXNpbms0IGNoYW5uZWwgY2FuIGFs c28gYmUgdXNlZCBhcyBhIENIR19WSU4gcG93ZXIgZ29vZCBpbmRpY2F0b3IuCj4gKwo+ICsJICBU aGlzIGRyaXZlciBjYW4gYWxzbyBiZSBidWlsdCBhcyBhIG1vZHVsZS4gSWYgc28sIHRoZSBtb2R1 bGUKPiArCSAgd2lsbCBiZSBjYWxsZWQgImxlZHMtbXQ2MzcwLXJnYiIuCj4gKwo+ICBlbmRpZiAj IExFRFNfQ0xBU1NfTVVMVElDT0xPUgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2xlZHMvcmdiL01h a2VmaWxlIGIvZHJpdmVycy9sZWRzL3JnYi9NYWtlZmlsZQo+IGluZGV4IDA2NzViYzAuLjhjMDFk YWYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9sZWRzL3JnYi9NYWtlZmlsZQo+ICsrKyBiL2RyaXZl cnMvbGVkcy9yZ2IvTWFrZWZpbGUKPiBAQCAtMiwzICsyLDQgQEAKPiAgCj4gIG9iai0kKENPTkZJ R19MRURTX1BXTV9NVUxUSUNPTE9SKQkrPSBsZWRzLXB3bS1tdWx0aWNvbG9yLm8KPiAgb2JqLSQo Q09ORklHX0xFRFNfUUNPTV9MUEcpCQkrPSBsZWRzLXFjb20tbHBnLm8KPiArb2JqLSQoQ09ORklH X0xFRFNfTVQ2MzcwX1JHQikJCSs9IGxlZHMtbXQ2MzcwLXJnYi5vCj4gZGlmZiAtLWdpdCBhL2Ry aXZlcnMvbGVkcy9yZ2IvbGVkcy1tdDYzNzAtcmdiLmMgYi9kcml2ZXJzL2xlZHMvcmdiL2xlZHMt bXQ2MzcwLXJnYi5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMC4uMTg1 ZDVkNwo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2xlZHMvcmdiL2xlZHMtbXQ2Mzcw LXJnYi5jCj4gQEAgLTAsMCArMSwxMDA5IEBACj4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVy OiBHUEwtMi4wLW9ubHkKPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAyMDIzIFJpY2h0ZWsgVGVj aG5vbG9neSBDb3JwLgo+ICsgKgo+ICsgKiBBdXRob3JzOgo+ICsgKiAgIENoaVl1YW4gSHVhbmcg PGN5X2h1YW5nQHJpY2h0ZWsuY29tPgo+ICsgKiAgIEFsaWNlIENoZW4gPGFsaWNlX2NoZW5Acmlj aHRlay5jb20+Cj4gKyAqLwo+ICsKPiArI2luY2x1ZGUgPGxpbnV4L2JpdG9wcy5oPgo+ICsjaW5j bHVkZSA8bGludXgva2VybmVsLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9sZWRzLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9sZWQtY2xhc3MtbXVsdGljb2xvci5oPgo+ICsjaW5jbHVkZSA8bGludXgvbGlu ZWFyX3JhbmdlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2RfZGV2aWNldGFibGUuaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8bGludXgvcHJvcGVy dHkuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPgo+ICsjaW5jbHVkZSA8bGludXgvdXRp bF9tYWNyb3MuaD4KPiArCj4gKyNpbmNsdWRlIDxhc20vdW5hbGlnbmVkLmg+Cj4gKwo+ICtlbnVt IHsKPiArCU1UNjM3MF9MRURfSVNOSzEgPSAwLAo+ICsJTVQ2MzcwX0xFRF9JU05LMiwKPiArCU1U NjM3MF9MRURfSVNOSzMsCj4gKwlNVDYzNzBfTEVEX0lTTks0LAo+ICsJTVQ2MzcwX01BWF9MRURT Cj4gK307Cj4gKwo+ICtlbnVtIG10NjM3MF9sZWRfbW9kZSB7Cj4gKwlNVDYzNzBfTEVEX1BXTV9N T0RFID0gMCwKPiArCU1UNjM3MF9MRURfQlJFQVRIX01PREUsCj4gKwlNVDYzNzBfTEVEX1JFR19N T0RFLAo+ICsJTVQ2MzcwX0xFRF9NQVhfTU9ERQo+ICt9Owo+ICsKPiArZW51bSBtdDYzNzBfbGVk X2ZpZWxkIHsKPiArCUZfUkdCX0VOID0gMCwKPiArCUZfQ0hHSU5EX0VOLAo+ICsJRl9MRUQxX0NV UlIsCj4gKwlGX0xFRDJfQ1VSUiwKPiArCUZfTEVEM19DVVJSLAo+ICsJRl9MRUQ0X0NVUlIsCj4g KwlGX0xFRDFfTU9ERSwKPiArCUZfTEVEMl9NT0RFLAo+ICsJRl9MRUQzX01PREUsCj4gKwlGX0xF RDRfTU9ERSwKPiArCUZfTEVEMV9EVVRZLAo+ICsJRl9MRUQyX0RVVFksCj4gKwlGX0xFRDNfRFVU WSwKPiArCUZfTEVENF9EVVRZLAo+ICsJRl9MRUQxX0ZSRVEsCj4gKwlGX0xFRDJfRlJFUSwKPiAr CUZfTEVEM19GUkVRLAo+ICsJRl9MRUQ0X0ZSRVEsCj4gKwlGX01BWF9GSUVMRFMKPiArfTsKPiAr Cj4gK2VudW0gbXQ2MzcwX2xlZF9yYW5nZXMgewo+ICsJUl9MRUQxMjNfQ1VSUiA9IDAsCj4gKwlS X0xFRDRfQ1VSUiwKPiArCVJfTEVEX1RSRk9OLAo+ICsJUl9MRURfVE9GRiwKPiArCVJfTUFYX1JB TkdFUwo+ICt9Owo+ICsKPiArZW51bSBtdDYzNzBfcGF0dGVybiB7Cj4gKwlQX0xFRF9UUjEgPSAw LAo+ICsJUF9MRURfVFIyLAo+ICsJUF9MRURfVEYxLAo+ICsJUF9MRURfVEYyLAo+ICsJUF9MRURf VE9OLAo+ICsJUF9MRURfVE9GRiwKPiArCVBfTUFYX1BBVFRFUk5TCj4gK307Cj4gKwo+ICsjZGVm aW5lIE1UNjM3MF9SRUdfREVWX0lORk8JCQkweDEwMAo+ICsjZGVmaW5lIE1UNjM3MF9SRUdfUkdC MV9ESU0JCQkweDE4Mgo+ICsjZGVmaW5lIE1UNjM3MF9SRUdfUkdCMl9ESU0JCQkweDE4Mwo+ICsj ZGVmaW5lIE1UNjM3MF9SRUdfUkdCM19ESU0JCQkweDE4NAo+ICsjZGVmaW5lIE1UNjM3MF9SRUdf UkdCX0VOCQkJMHgxODUKPiArI2RlZmluZSBNVDYzNzBfUkVHX1JHQjFfSVNOSwkJCTB4MTg2Cj4g KyNkZWZpbmUgTVQ2MzcwX1JFR19SR0IyX0lTTksJCQkweDE4Nwo+ICsjZGVmaW5lIE1UNjM3MF9S RUdfUkdCM19JU05LCQkJMHgxODgKPiArI2RlZmluZSBNVDYzNzBfUkVHX1JHQjFfVFIJCQkweDE4 OQo+ICsjZGVmaW5lIE1UNjM3MF9SRUdfUkdCX0NIUklORF9ESU0JCTB4MTkyCj4gKyNkZWZpbmUg TVQ2MzcwX1JFR19SR0JfQ0hSSU5EX0NUUkwJCTB4MTkzCj4gKyNkZWZpbmUgTVQ2MzcwX1JFR19S R0JfQ0hSSU5EX1RSCQkweDE5NAo+ICsKPiArI2RlZmluZSBNVDYzNzJfUkVHX1JHQl9FTgkJCTB4 MTgyCj4gKyNkZWZpbmUgTVQ2MzcyX1JFR19SR0IxX0lTTksJCQkweDE4Mwo+ICsjZGVmaW5lIE1U NjM3Ml9SRUdfUkdCMl9JU05LCQkJMHgxODQKPiArI2RlZmluZSBNVDYzNzJfUkVHX1JHQjNfSVNO SwkJCTB4MTg1Cj4gKyNkZWZpbmUgTVQ2MzcyX1JFR19SR0I0X0lTTksJCQkweDE4Ngo+ICsjZGVm aW5lIE1UNjM3Ml9SRUdfUkdCMV9ESU0JCQkweDE4Nwo+ICsjZGVmaW5lIE1UNjM3Ml9SRUdfUkdC Ml9ESU0JCQkweDE4OAo+ICsjZGVmaW5lIE1UNjM3Ml9SRUdfUkdCM19ESU0JCQkweDE4OQo+ICsj ZGVmaW5lIE1UNjM3Ml9SRUdfUkdCNF9ESU0JCQkweDE4QQo+ICsjZGVmaW5lIE1UNjM3Ml9SRUdf UkdCMTJfRlJFUQkJCTB4MThCCj4gKyNkZWZpbmUgTVQ2MzcyX1JFR19SR0IzNF9GUkVRCQkJMHgx OEMKPiArI2RlZmluZSBNVDYzNzJfUkVHX1JHQjFfVFIJCQkweDE4RAo+ICsKPiArI2RlZmluZSBN VDYzNzBfVkVOSURfTUFTSwkJCUdFTk1BU0soNywgNCkKClZlbmRvcj8gIERlZmluZXMgc2hvdWxk IGJlIHNlbGYgZG9jdW1lbnRpbmcuCgpXaGF0IGRvZXMgdGhpcyBzYXZlIG92ZXIgIlZFTkRPUl9J RCI/Cgo+ICsjZGVmaW5lIE1UNjM3MF9DSEVOX0JJVChpZCkJCQlCSVQoTVQ2MzcwX0xFRF9JU05L NCAtIGlkKQo+ICsjZGVmaW5lIE1UNjM3MF9WSVJUVUFMX01VTFRJQ09MT1IJCTUKPiArI2RlZmlu ZSBNQ19DSEFOTkVMX05VTQkJCQkzCj4gKyNkZWZpbmUgTVQ2MzcwX1BXTV9EVVRZCQkJCShCSVQo NSkgLSAxKQo+ICsjZGVmaW5lIE1UNjM3Ml9QV01fRFVUWQkJCQkoQklUKDgpIC0gMSkKPiArCj4g K3N0cnVjdCBtdDYzNzBfbGVkIHsKPiArCS8qCj4gKwkgKiBJZiB0aGUgY29sb3Igb2YgdGhlIExF RCBpbiBEVCBpcyBzZXQgdG8KPiArCSAqICAgLSAnTEVEX0NPTE9SX0lEX1JHQicKPiArCSAqICAg LSAnTEVEX0NPTE9SX0lEX01VTFRJJwo+ICsJICogVGhlIG1lbWJlciAnaW5kZXgnIG9mIHRoaXMg c3RydWN0IHdpbGwgYmUgc2V0IHRvCj4gKwkgKiAnTVQ2MzcwX1ZJUlRVQUxfTVVMVElDT0xPUicu Cj4gKwkgKiBJZiBzbywgdGhpcyBMRUQgd2lsbCBjaG9vc2UgJ3N0cnVjdCBsZWRfY2xhc3NkZXZf bWMgbWMnIHRvIHVzZS4KPiArCSAqIEluc3RlYWQsIGlmIHRoZSBtZW1iZXIgJ2luZGV4JyBvZiB0 aGlzIHN0cnVjdCBpcyBzZXQgdG8KPiArCSAqICdNVDYzNzBfTEVEX0lTTksxJyB+ICdNVDYzNzBf TEVEX0lTTks0JywgdGhlbiB0aGlzIExFRCB3aWxsIGNob29zZQo+ICsJICogJ3N0cnVjdCBsZWRf Y2xhc3NkZXYgaXNpbmsnIHRvIHVzZS4KPiArCSAqLwo+ICsJdW5pb24gewo+ICsJCXN0cnVjdCBs ZWRfY2xhc3NkZXYgaXNpbms7Cj4gKwkJc3RydWN0IGxlZF9jbGFzc2Rldl9tYyBtYzsKPiArCX07 Cj4gKwlzdHJ1Y3QgbXQ2MzcwX3ByaXYgKnByaXY7Cj4gKwllbnVtIGxlZF9kZWZhdWx0X3N0YXRl IGRlZmF1bHRfc3RhdGU7Cj4gKwl1MzIgaW5kZXg7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgbXQ2Mzcw X3BkYXRhIHsKPiArCWNvbnN0IHVuc2lnbmVkIGludCAqdGZyZXE7Cj4gKwl1bnNpZ25lZCBpbnQg dGZyZXFfbGVuOwo+ICsJdTE2IHJlZ19yZ2IxX3RyOwo+ICsJczE2IHJlZ19yZ2JfY2hyaW5kX3Ry Owo+ICsJdTggcHdtX2R1dHk7Cj4gK307Cj4gKwo+ICtzdHJ1Y3QgbXQ2MzcwX3ByaXYgewo+ICsJ LyogUGVyIExFRCBhY2Nlc3MgbG9jayAqLwo+ICsJc3RydWN0IG11dGV4IGxvY2s7Cj4gKwlzdHJ1 Y3QgcmVnbWFwICpyZWdtYXA7Cj4gKwlzdHJ1Y3QgcmVnbWFwX2ZpZWxkICpmaWVsZHNbRl9NQVhf RklFTERTXTsKPiArCWNvbnN0IHN0cnVjdCByZWdfZmllbGQgKnJlZ19maWVsZHM7Cj4gKwljb25z dCBzdHJ1Y3QgbGluZWFyX3JhbmdlICpyYW5nZXM7Cj4gKwlzdHJ1Y3QgcmVnX2NmZyAqcmVnX2Nm Z3M7Cj4gKwljb25zdCBzdHJ1Y3QgbXQ2MzcwX3BkYXRhICpwZGF0YTsKPiArCXVuc2lnbmVkIGlu dCBsZWRzX2NvdW50Owo+ICsJdW5zaWduZWQgaW50IGxlZHNfYWN0aXZlOwo+ICsJc3RydWN0IG10 NjM3MF9sZWQgbGVkc1tdOwo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCByZWdfZmll bGQgY29tbW9uX3JlZ19maWVsZHNbRl9NQVhfRklFTERTXSA9IHsKPiArCVtGX1JHQl9FTl0JPSBS RUdfRklFTEQoTVQ2MzcwX1JFR19SR0JfRU4sIDQsIDcpLAo+ICsJW0ZfQ0hHSU5EX0VOXQk9IFJF R19GSUVMRChNVDYzNzBfUkVHX1JHQl9DSFJJTkRfRElNLCA3LCA3KSwKPiArCVtGX0xFRDFfQ1VS Ul0JPSBSRUdfRklFTEQoTVQ2MzcwX1JFR19SR0IxX0lTTkssIDAsIDIpLAo+ICsJW0ZfTEVEMl9D VVJSXQk9IFJFR19GSUVMRChNVDYzNzBfUkVHX1JHQjJfSVNOSywgMCwgMiksCj4gKwlbRl9MRUQz X0NVUlJdCT0gUkVHX0ZJRUxEKE1UNjM3MF9SRUdfUkdCM19JU05LLCAwLCAyKSwKPiArCVtGX0xF RDRfQ1VSUl0JPSBSRUdfRklFTEQoTVQ2MzcwX1JFR19SR0JfQ0hSSU5EX0NUUkwsIDAsIDEpLAo+ ICsJW0ZfTEVEMV9NT0RFXQk9IFJFR19GSUVMRChNVDYzNzBfUkVHX1JHQjFfRElNLCA1LCA2KSwK PiArCVtGX0xFRDJfTU9ERV0JPSBSRUdfRklFTEQoTVQ2MzcwX1JFR19SR0IyX0RJTSwgNSwgNiks Cj4gKwlbRl9MRUQzX01PREVdCT0gUkVHX0ZJRUxEKE1UNjM3MF9SRUdfUkdCM19ESU0sIDUsIDYp LAo+ICsJW0ZfTEVENF9NT0RFXQk9IFJFR19GSUVMRChNVDYzNzBfUkVHX1JHQl9DSFJJTkRfRElN LCA1LCA2KSwKPiArCVtGX0xFRDFfRFVUWV0JPSBSRUdfRklFTEQoTVQ2MzcwX1JFR19SR0IxX0RJ TSwgMCwgNCksCj4gKwlbRl9MRUQyX0RVVFldCT0gUkVHX0ZJRUxEKE1UNjM3MF9SRUdfUkdCMl9E SU0sIDAsIDQpLAo+ICsJW0ZfTEVEM19EVVRZXQk9IFJFR19GSUVMRChNVDYzNzBfUkVHX1JHQjNf RElNLCAwLCA0KSwKPiArCVtGX0xFRDRfRFVUWV0JPSBSRUdfRklFTEQoTVQ2MzcwX1JFR19SR0Jf Q0hSSU5EX0RJTSwgMCwgNCksCj4gKwlbRl9MRUQxX0ZSRVFdCT0gUkVHX0ZJRUxEKE1UNjM3MF9S RUdfUkdCMV9JU05LLCAzLCA1KSwKPiArCVtGX0xFRDJfRlJFUV0JPSBSRUdfRklFTEQoTVQ2Mzcw X1JFR19SR0IyX0lTTkssIDMsIDUpLAo+ICsJW0ZfTEVEM19GUkVRXQk9IFJFR19GSUVMRChNVDYz NzBfUkVHX1JHQjNfSVNOSywgMywgNSksCj4gKwlbRl9MRUQ0X0ZSRVFdCT0gUkVHX0ZJRUxEKE1U NjM3MF9SRUdfUkdCX0NIUklORF9DVFJMLCAyLCA0KSwKPiArfTsKPiArCj4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgcmVnX2ZpZWxkIG10NjM3Ml9yZWdfZmllbGRzW0ZfTUFYX0ZJRUxEU10gPSB7Cj4g KwlbRl9SR0JfRU5dCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdfUkdCX0VOLCA0LCA3KSwKPiArCVtG X0NIR0lORF9FTl0JPSBSRUdfRklFTEQoTVQ2MzcyX1JFR19SR0JfRU4sIDMsIDMpLAo+ICsJW0Zf TEVEMV9DVVJSXQk9IFJFR19GSUVMRChNVDYzNzJfUkVHX1JHQjFfSVNOSywgMCwgMyksCj4gKwlb Rl9MRUQyX0NVUlJdCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdfUkdCMl9JU05LLCAwLCAzKSwKPiAr CVtGX0xFRDNfQ1VSUl0JPSBSRUdfRklFTEQoTVQ2MzcyX1JFR19SR0IzX0lTTkssIDAsIDMpLAo+ ICsJW0ZfTEVENF9DVVJSXQk9IFJFR19GSUVMRChNVDYzNzJfUkVHX1JHQjRfSVNOSywgMCwgMyks Cj4gKwlbRl9MRUQxX01PREVdCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdfUkdCMV9JU05LLCA2LCA3 KSwKPiArCVtGX0xFRDJfTU9ERV0JPSBSRUdfRklFTEQoTVQ2MzcyX1JFR19SR0IyX0lTTkssIDYs IDcpLAo+ICsJW0ZfTEVEM19NT0RFXQk9IFJFR19GSUVMRChNVDYzNzJfUkVHX1JHQjNfSVNOSywg NiwgNyksCj4gKwlbRl9MRUQ0X01PREVdCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdfUkdCNF9JU05L LCA2LCA3KSwKPiArCVtGX0xFRDFfRFVUWV0JPSBSRUdfRklFTEQoTVQ2MzcyX1JFR19SR0IxX0RJ TSwgMCwgNyksCj4gKwlbRl9MRUQyX0RVVFldCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdfUkdCMl9E SU0sIDAsIDcpLAo+ICsJW0ZfTEVEM19EVVRZXQk9IFJFR19GSUVMRChNVDYzNzJfUkVHX1JHQjNf RElNLCAwLCA3KSwKPiArCVtGX0xFRDRfRFVUWV0JPSBSRUdfRklFTEQoTVQ2MzcyX1JFR19SR0I0 X0RJTSwgMCwgNyksCj4gKwlbRl9MRUQxX0ZSRVFdCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdfUkdC MTJfRlJFUSwgNSwgNyksCj4gKwlbRl9MRUQyX0ZSRVFdCT0gUkVHX0ZJRUxEKE1UNjM3Ml9SRUdf UkdCMTJfRlJFUSwgMiwgNCksCj4gKwlbRl9MRUQzX0ZSRVFdCT0gUkVHX0ZJRUxEKE1UNjM3Ml9S RUdfUkdCMzRfRlJFUSwgNSwgNyksCj4gKwlbRl9MRUQ0X0ZSRVFdCT0gUkVHX0ZJRUxEKE1UNjM3 Ml9SRUdfUkdCMzRfRlJFUSwgMiwgNCksCj4gK307Cj4gKwo+ICsvKiBDdXJyZW50IHVuaXQ6IG1p Y3JvYW1wLCB0aW1lIHVuaXQ6IG1pbGxpc2Vjb25kICovCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qg bGluZWFyX3JhbmdlIGNvbW1vbl9sZWRfcmFuZ2VzW1JfTUFYX1JBTkdFU10gPSB7Cj4gKwlbUl9M RUQxMjNfQ1VSUl0JPSB7IDQwMDAsIDEsIDYsIDQwMDAgfSwKPiArCVtSX0xFRDRfQ1VSUl0JPSB7 IDIwMDAsIDEsIDMsIDIwMDAgfSwKPiArCVtSX0xFRF9UUkZPTl0JPSB7IDEyNSwgMCwgMTUsIDIw MCB9LAo+ICsJW1JfTEVEX1RPRkZdCT0geyAyNTAsIDAsIDE1LCA0MDAgfSwKPiArfTsKPiArCj4g K3N0YXRpYyBjb25zdCBzdHJ1Y3QgbGluZWFyX3JhbmdlIG10NjM3Ml9sZWRfcmFuZ2VzW1JfTUFY X1JBTkdFU10gPSB7Cj4gKwlbUl9MRUQxMjNfQ1VSUl0JPSB7IDIwMDAsIDEsIDE0LCAyMDAwIH0s Cj4gKwlbUl9MRUQ0X0NVUlJdCT0geyAyMDAwLCAxLCAxNCwgMjAwMCB9LAo+ICsJW1JfTEVEX1RS Rk9OXQk9IHsgMTI1LCAwLCAxNSwgMjUwIH0sCj4gKwlbUl9MRURfVE9GRl0JPSB7IDI1MCwgMCwg MTUsIDUwMCB9LAo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHVuc2lnbmVkIGludCBjb21tb25f dGZyZXFzW10gPSB7Cj4gKwkxMDAwMCwgNTAwMCwgMjAwMCwgMTAwMCwgNTAwLCAyMDAsIDUsIDEs Cj4gK307Cj4gKwo+ICtzdGF0aWMgY29uc3QgdW5zaWduZWQgaW50IG10NjM3Ml90ZnJlcXNbXSA9 IHsKPiArCTgwMDAsIDQwMDAsIDIwMDAsIDEwMDAsIDUwMCwgMjUwLCA4LCA0LAo+ICt9Owo+ICsK PiArc3RhdGljIGNvbnN0IHN0cnVjdCBtdDYzNzBfcGRhdGEgY29tbW9uX3BkYXRhID0gewo+ICsJ LnRmcmVxID0gY29tbW9uX3RmcmVxcywKPiArCS50ZnJlcV9sZW4gPSBBUlJBWV9TSVpFKGNvbW1v bl90ZnJlcXMpLAo+ICsJLnB3bV9kdXR5ID0gTVQ2MzcwX1BXTV9EVVRZLAo+ICsJLnJlZ19yZ2Ix X3RyID0gTVQ2MzcwX1JFR19SR0IxX1RSLAo+ICsJLnJlZ19yZ2JfY2hyaW5kX3RyID0gTVQ2Mzcw X1JFR19SR0JfQ0hSSU5EX1RSLAo+ICt9Owo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBtdDYz NzBfcGRhdGEgbXQ2MzcyX3BkYXRhID0gewo+ICsJLnRmcmVxID0gbXQ2MzcyX3RmcmVxcywKPiAr CS50ZnJlcV9sZW4gPSBBUlJBWV9TSVpFKG10NjM3Ml90ZnJlcXMpLAo+ICsJLnB3bV9kdXR5ID0g TVQ2MzcyX1BXTV9EVVRZLAo+ICsJLnJlZ19yZ2IxX3RyID0gTVQ2MzcyX1JFR19SR0IxX1RSLAo+ ICsJLnJlZ19yZ2JfY2hyaW5kX3RyID0gLTEsCj4gK307Cj4gKwo+ICtzdGF0aWMgZW51bSBtdDYz NzBfbGVkX2ZpZWxkIG10NjM3MF9nZXRfbGVkX2N1cnJlbnRfZmllbGQodW5zaWduZWQgaW50IGxl ZF9ubykKPiArewo+ICsJc3dpdGNoIChsZWRfbm8pIHsKPiArCWNhc2UgTVQ2MzcwX0xFRF9JU05L MToKPiArCQlyZXR1cm4gRl9MRUQxX0NVUlI7Cj4gKwljYXNlIE1UNjM3MF9MRURfSVNOSzI6Cj4g KwkJcmV0dXJuIEZfTEVEMl9DVVJSOwo+ICsJY2FzZSBNVDYzNzBfTEVEX0lTTkszOgo+ICsJCXJl dHVybiBGX0xFRDNfQ1VSUjsKPiArCWRlZmF1bHQ6Cj4gKwkJcmV0dXJuIEZfTEVENF9DVVJSOwo+ ICsJfQo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG10NjM3MF9zZXRfbGVkX2JyaWdodG5lc3Moc3Ry dWN0IG10NjM3MF9wcml2ICpwcml2LAo+ICsJCQkJICAgICB1bnNpZ25lZCBpbnQgbGVkX25vLCB1 bnNpZ25lZCBpbnQgbGV2ZWwpCj4gK3sKPiArCWVudW0gbXQ2MzcwX2xlZF9maWVsZCBzZWxfZmll bGQ7Cj4gKwo+ICsJc2VsX2ZpZWxkID0gbXQ2MzcwX2dldF9sZWRfY3VycmVudF9maWVsZChsZWRf bm8pOwo+ICsKPiArCXJldHVybiByZWdtYXBfZmllbGRfd3JpdGUocHJpdi0+ZmllbGRzW3NlbF9m aWVsZF0sIGxldmVsKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBtdDYzNzBfZ2V0X2xlZF9icmln aHRuZXNzKHN0cnVjdCBtdDYzNzBfcHJpdiAqcHJpdiwKPiArCQkJCSAgICAgdW5zaWduZWQgaW50 IGxlZF9ubywgdW5zaWduZWQgaW50ICpsZXZlbCkKPiArewo+ICsJZW51bSBtdDYzNzBfbGVkX2Zp ZWxkIHNlbF9maWVsZDsKPiArCj4gKwlzZWxfZmllbGQgPSBtdDYzNzBfZ2V0X2xlZF9jdXJyZW50 X2ZpZWxkKGxlZF9ubyk7Cj4gKwo+ICsJcmV0dXJuIHJlZ21hcF9maWVsZF9yZWFkKHByaXYtPmZp ZWxkc1tzZWxfZmllbGRdLCBsZXZlbCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXQ2MzcwX3Nl dF9sZWRfZHV0eShzdHJ1Y3QgbXQ2MzcwX3ByaXYgKnByaXYsIHVuc2lnbmVkIGludCBsZWRfbm8s Cj4gKwkJCSAgICAgICB1bnNpZ25lZCBpbnQgdG9uLCB1bnNpZ25lZCBpbnQgdG9mZikKPiArewo+ ICsJY29uc3Qgc3RydWN0IG10NjM3MF9wZGF0YSAqcGRhdGEgPSBwcml2LT5wZGF0YTsKPiArCWVu dW0gbXQ2MzcwX2xlZF9maWVsZCBzZWxfZmllbGQ7Cj4gKwl1bnNpZ25lZCBpbnQgZGl2aXNvciwg cmF0aW87Cj4gKwo+ICsJZGl2aXNvciA9IHBkYXRhLT5wd21fZHV0eTsKPiArCXJhdGlvID0gdG9u ICogZGl2aXNvciAvICh0b24gKyB0b2ZmKTsKPiArCj4gKwlzd2l0Y2ggKGxlZF9ubykgewo+ICsJ Y2FzZSBNVDYzNzBfTEVEX0lTTksxOgo+ICsJCXNlbF9maWVsZCA9IEZfTEVEMV9EVVRZOwo+ICsJ CWJyZWFrOwo+ICsJY2FzZSBNVDYzNzBfTEVEX0lTTksyOgo+ICsJCXNlbF9maWVsZCA9IEZfTEVE Ml9EVVRZOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSBNVDYzNzBfTEVEX0lTTkszOgo+ICsJCXNlbF9m aWVsZCA9IEZfTEVEM19EVVRZOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlzZWxfZmll bGQgPSBGX0xFRDRfRFVUWTsKPiArCQlicmVhazsKPiArCX0KPiArCj4gKwlyZXR1cm4gcmVnbWFw X2ZpZWxkX3dyaXRlKHByaXYtPmZpZWxkc1tzZWxfZmllbGRdLCByYXRpbyk7Cj4gK30KPiArCj4g K3N0YXRpYyBpbnQgbXQ2MzcwX3NldF9sZWRfZnJlcShzdHJ1Y3QgbXQ2MzcwX3ByaXYgKnByaXYs IHVuc2lnbmVkIGludCBsZWRfbm8sCj4gKwkJCSAgICAgICB1bnNpZ25lZCBpbnQgdG9uLCB1bnNp Z25lZCBpbnQgdG9mZikKPiArewo+ICsJY29uc3Qgc3RydWN0IG10NjM3MF9wZGF0YSAqcGRhdGEg PSBwcml2LT5wZGF0YTsKPiArCWVudW0gbXQ2MzcwX2xlZF9maWVsZCBzZWxfZmllbGQ7Cj4gKwl1 bnNpZ25lZCBpbnQgdGZyZXFfbGVuID0gcGRhdGEtPnRmcmVxX2xlbjsKPiArCXVuc2lnbmVkIGlu dCB0c3VtLCBzZWw7Cj4gKwo+ICsJdHN1bSA9IHRvbiArIHRvZmY7Cj4gKwo+ICsJaWYgKHRzdW0g PiBwZGF0YS0+dGZyZXFbMF0gfHwgdHN1bSA8IHBkYXRhLT50ZnJlcVt0ZnJlcV9sZW4gLSAxXSkK PiArCQlyZXR1cm4gLUVPUE5PVFNVUFA7Cj4gKwo+ICsJc2VsID0gZmluZF9jbG9zZXN0X2Rlc2Nl bmRpbmcodHN1bSwgcGRhdGEtPnRmcmVxLCB0ZnJlcV9sZW4pOwo+ICsKPiArCXN3aXRjaCAobGVk X25vKSB7Cj4gKwljYXNlIE1UNjM3MF9MRURfSVNOSzE6Cj4gKwkJc2VsX2ZpZWxkID0gRl9MRUQx X0ZSRVE7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIE1UNjM3MF9MRURfSVNOSzI6Cj4gKwkJc2VsX2Zp ZWxkID0gRl9MRUQyX0ZSRVE7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIE1UNjM3MF9MRURfSVNOSzM6 Cj4gKwkJc2VsX2ZpZWxkID0gRl9MRUQzX0ZSRVE7Cj4gKwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ ICsJCXNlbF9maWVsZCA9IEZfTEVENF9GUkVROwo+ICsJCWJyZWFrOwo+ICsJfQo+ICsKPiArCXJl dHVybiByZWdtYXBfZmllbGRfd3JpdGUocHJpdi0+ZmllbGRzW3NlbF9maWVsZF0sIHNlbCk7Cj4g K30KPiArCj4gK3N0YXRpYyB2b2lkIG10NjM3MF9nZXRfYnJlYXRoX3JlZ19iYXNlKHN0cnVjdCBt dDYzNzBfcHJpdiAqcHJpdiwKPiArCQkJCSAgICAgICB1bnNpZ25lZCBpbnQgbGVkX25vLCB1bnNp Z25lZCBpbnQgKmJhc2UpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBtdDYzNzBfcGRhdGEgKnBkYXRh ID0gcHJpdi0+cGRhdGE7Cj4gKwo+ICsJaWYgKHBkYXRhLT5yZWdfcmdiX2NocmluZF90ciA8IDAp IHsKPiArCQkqYmFzZSA9IHBkYXRhLT5yZWdfcmdiMV90ciArIGxlZF9ubyAqIDM7Cj4gKwkJcmV0 dXJuOwo+ICsJfQo+ICsKPiArCXN3aXRjaCAobGVkX25vKSB7Cj4gKwljYXNlIE1UNjM3MF9MRURf SVNOSzE6Cj4gKwljYXNlIE1UNjM3MF9MRURfSVNOSzI6Cj4gKwljYXNlIE1UNjM3MF9MRURfSVNO SzM6Cj4gKwkJKmJhc2UgPSBwZGF0YS0+cmVnX3JnYjFfdHIgKyBsZWRfbm8gKiAzOwo+ICsJCWJy ZWFrOwo+ICsJZGVmYXVsdDoKPiArCQkqYmFzZSA9IHBkYXRhLT5yZWdfcmdiX2NocmluZF90cjsK PiArCQlicmVhazsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIGludCBtdDYzNzBfZ2VuX2JyZWF0 aF9wYXR0ZXJuKHN0cnVjdCBtdDYzNzBfcHJpdiAqcHJpdiwKPiArCQkJCSAgICAgc3RydWN0IGxl ZF9wYXR0ZXJuICpwYXR0ZXJuLCB1MzIgbGVuLAo+ICsJCQkJICAgICB1OCAqcGF0dGVybl92YWws IHUzMiB2YWxfbGVuKQo+ICt7Cj4gKwllbnVtIG10NjM3MF9sZWRfcmFuZ2VzIHNlbF9yYW5nZTsK PiArCXN0cnVjdCBsZWRfcGF0dGVybiAqY3VycjsKPiArCXVuc2lnbmVkIGludCBzZWw7Cj4gKwl1 MzIgdmFsID0gMDsKPiArCWludCBpOwo+ICsKPiArCWlmIChsZW4gPCBQX01BWF9QQVRURVJOUyAm JiB2YWxfbGVuIDwgUF9NQVhfUEFUVEVSTlMgLyAyKQo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsK PiArCS8qCj4gKwkgKiBQYXR0ZXJuIGxpc3QKPiArCSAqIHRyMToJIGJ5dGUgMCwgYidbNzogNF0K ClBlcmhhcHMgdGhpcyBpcyBzdGFuZGFyZCBmb3JtYXR0aW5nIGFuZCBJJ20ganVzdCBub3QgYXdh cmUgb2YgaXQsIGJ1dAp0aGUgc3BhY2UgaXMgdGhyb3dpbmcgbWUgYW5kIG1ha2luZyBtZSB0aGlu ayB0d2ljZS4gIERvZXMgdGhpcyBtZWFuIGJpdHMKNyB0aHJvdWdoIDQsIHNvIGInMTExMTAwMDA/ Cgo+ICsJICogdHIyOgkgYnl0ZSAwLCBiJ1szOiAwXQo+ICsJICogdGYxOgkgYnl0ZSAxLCBiJ1s3 OiA0XQo+ICsJICogdGYyOgkgYnl0ZSAxLCBiJ1szOiAwXQo+ICsJICogdG9uOgkgYnl0ZSAyLCBi J1s3OiA0XQo+ICsJICogdG9mZjogYnl0ZSAyLCBiJ1szOiAwXQo+ICsJICovCj4gKwlmb3IgKGkg PSAwOyBpIDwgUF9NQVhfUEFUVEVSTlM7IGkrKykgewo+ICsJCWN1cnIgPSBwYXR0ZXJuICsgaTsK PiArCj4gKwkJc2VsX3JhbmdlID0gaSA9PSBQX0xFRF9UT0ZGID8gUl9MRURfVE9GRiA6IFJfTEVE X1RSRk9OOwo+ICsKPiArCQlsaW5lYXJfcmFuZ2VfZ2V0X3NlbGVjdG9yX3dpdGhpbihwcml2LT5y YW5nZXMgKyBzZWxfcmFuZ2UsCj4gKwkJCQkJCSBjdXJyLT5kZWx0YV90LCAmc2VsKTsKPiArCj4g KwkJaWYgKGkgJSAyKSB7Cj4gKwkJCXZhbCB8PSBzZWw7Cj4gKwkJfSBlbHNlIHsKPiArCQkJdmFs IDw8PSA4Owo+ICsJCQl2YWwgfD0gc2VsIDw8IDQ7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCXB1dF91 bmFsaWduZWRfYmUyNCh2YWwsIHBhdHRlcm5fdmFsKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ ICsKPiArc3RhdGljIGludCBtdDYzNzBfc2V0X2xlZF9tb2RlKHN0cnVjdCBtdDYzNzBfcHJpdiAq cHJpdiwgdW5zaWduZWQgaW50IGxlZF9ubywKPiArCQkJICAgICAgIGVudW0gbXQ2MzcwX2xlZF9t b2RlIG1vZGUpCj4gK3sKPiArCWVudW0gbXQ2MzcwX2xlZF9maWVsZCBzZWxfZmllbGQ7Cj4gKwo+ ICsJc3dpdGNoIChsZWRfbm8pIHsKPiArCWNhc2UgTVQ2MzcwX0xFRF9JU05LMToKPiArCQlzZWxf ZmllbGQgPSBGX0xFRDFfTU9ERTsKPiArCQlicmVhazsKPiArCWNhc2UgTVQ2MzcwX0xFRF9JU05L MjoKPiArCQlzZWxfZmllbGQgPSBGX0xFRDJfTU9ERTsKPiArCQlicmVhazsKPiArCWNhc2UgTVQ2 MzcwX0xFRF9JU05LMzoKPiArCQlzZWxfZmllbGQgPSBGX0xFRDNfTU9ERTsKPiArCQlicmVhazsK PiArCWRlZmF1bHQ6Cj4gKwkJc2VsX2ZpZWxkID0gRl9MRUQ0X01PREU7Cj4gKwkJYnJlYWs7Cj4g Kwl9Cj4gKwo+ICsJcmV0dXJuIHJlZ21hcF9maWVsZF93cml0ZShwcml2LT5maWVsZHNbc2VsX2Zp ZWxkXSwgbW9kZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXQ2MzcwX21jX2JyaWdodG5lc3Nf c2V0KHN0cnVjdCBsZWRfY2xhc3NkZXYgKmxjZGV2LAo+ICsJCQkJICAgIGVudW0gbGVkX2JyaWdo dG5lc3MgbGV2ZWwpCj4gK3sKPiArCXN0cnVjdCBsZWRfY2xhc3NkZXZfbWMgKm1jY2RldiA9IGxj ZGV2X3RvX21jY2RldihsY2Rldik7Cj4gKwlzdHJ1Y3QgbXQ2MzcwX2xlZCAqbGVkID0gY29udGFp bmVyX29mKG1jY2Rldiwgc3RydWN0IG10NjM3MF9sZWQsIG1jKTsKPiArCXN0cnVjdCBtdDYzNzBf cHJpdiAqcHJpdiA9IGxlZC0+cHJpdjsKPiArCXN0cnVjdCBtY19zdWJsZWQgKnN1YmxlZDsKPiAr CXVuc2lnbmVkIGludCBlbmFibGUsIGRpc2FibGU7Cj4gKwlpbnQgaSwgcmV0Owo+ICsKPiArCW11 dGV4X2xvY2soJnByaXYtPmxvY2spOwo+ICsKPiArCWxlZF9tY19jYWxjX2NvbG9yX2NvbXBvbmVu dHMobWNjZGV2LCBsZXZlbCk7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX2ZpZWxkX3JlYWQocHJpdi0+ ZmllbGRzW0ZfUkdCX0VOXSwgJmVuYWJsZSk7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8gb3V0X3Vu bG9jazsKPiArCj4gKwlkaXNhYmxlID0gZW5hYmxlOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBt Y2NkZXYtPm51bV9jb2xvcnM7IGkrKykgewo+ICsJCXUzMiBicmlnaHRuZXNzOwo+ICsKPiArCQlz dWJsZWQgPSBtY2NkZXYtPnN1YmxlZF9pbmZvICsgaTsKPiArCQlicmlnaHRuZXNzID0gbWluKHN1 YmxlZC0+YnJpZ2h0bmVzcywgbGNkZXYtPm1heF9icmlnaHRuZXNzKTsKPiArCQlkaXNhYmxlICY9 IH5NVDYzNzBfQ0hFTl9CSVQoc3VibGVkLT5jaGFubmVsKTsKPiArCj4gKwkJaWYgKGxldmVsID09 IDApIHsKPiArCQkJZW5hYmxlICY9IH5NVDYzNzBfQ0hFTl9CSVQoc3VibGVkLT5jaGFubmVsKTsK PiArCj4gKwkJCXJldCA9IG10NjM3MF9zZXRfbGVkX21vZGUocHJpdiwgc3VibGVkLT5jaGFubmVs LAo+ICsJCQkJCQkgIE1UNjM3MF9MRURfUkVHX01PREUpOwoKUGxlYXNlIHVuaWZ5IHlvdXIgbGlu ZS13cmFwIHN0cmF0ZWd5LiAgSW4gc29tZSBwbGFjZXMgeW91IGFyZSB1c2luZyB0aGUKZnVsbCAx MDAtY2hhcnMgYWxsb3dhYmxlIGFuZCBpbiBtYW55IG90aGVycywgeW91IGxpbmUtd3JhcCBlYXJs eS4gIFBsZWFzZQpnbyB0aHJvdWdoIHRoZSBlbnRpcmUgZmlsZSBhbmQgdW53cmFwIHRvIDEwMC1j aGFycyB3aGVyZSBhcHByb3ByaWF0ZS4KCllvdSdsbCBzZWUgd2hhdCBJIG1lYW4gYXMgeW91IHJl LXJlYWQgdGhlIGZpbGUgd2l0aCB0aGlzIGluIG1pbmQuCgo+ICsJCQlpZiAocmV0KQo+ICsJCQkJ Z290byBvdXRfdW5sb2NrOwo+ICsKPiArCQkJY29udGludWU7Cj4gKwkJfQo+ICsKPiArCQlpZiAo YnJpZ2h0bmVzcyA9PSAwKSB7Cj4gKwkJCWVuYWJsZSAmPSB+TVQ2MzcwX0NIRU5fQklUKHN1Ymxl ZC0+Y2hhbm5lbCk7Cj4gKwkJCWNvbnRpbnVlOwo+ICsJCX0KPiArCj4gKwkJZW5hYmxlIHw9IE1U NjM3MF9DSEVOX0JJVChzdWJsZWQtPmNoYW5uZWwpOwo+ICsKPiArCQlyZXQgPSBtdDYzNzBfc2V0 X2xlZF9icmlnaHRuZXNzKHByaXYsIHN1YmxlZC0+Y2hhbm5lbCwKPiArCQkJCQkJYnJpZ2h0bmVz cyk7Cj4gKwkJaWYgKHJldCkKPiArCQkJZ290byBvdXRfdW5sb2NrOwo+ICsJfQo+ICsKPiArCXJl dCA9IHJlZ21hcF9maWVsZF93cml0ZShwcml2LT5maWVsZHNbRl9SR0JfRU5dLCBkaXNhYmxlKTsK PiArCWlmIChyZXQpCj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ICsKPiArCXJldCA9IHJlZ21hcF9m aWVsZF93cml0ZShwcml2LT5maWVsZHNbRl9SR0JfRU5dLCBlbmFibGUpOwo+ICsKPiArb3V0X3Vu bG9jazoKPiArCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cj4gKwo+ICsJcmV0dXJuIHJldDsK PiArfQo+ICsKPiArc3RhdGljIGludCBtdDYzNzBfbWNfYmxpbmtfc2V0KHN0cnVjdCBsZWRfY2xh c3NkZXYgKmxjZGV2LAo+ICsJCQkgICAgICAgdW5zaWduZWQgbG9uZyAqZGVsYXlfb24sCj4gKwkJ CSAgICAgICB1bnNpZ25lZCBsb25nICpkZWxheV9vZmYpCj4gK3sKPiArCXN0cnVjdCBsZWRfY2xh c3NkZXZfbWMgKm1jY2RldiA9IGxjZGV2X3RvX21jY2RldihsY2Rldik7Cj4gKwlzdHJ1Y3QgbXQ2 MzcwX2xlZCAqbGVkID0gY29udGFpbmVyX29mKG1jY2Rldiwgc3RydWN0IG10NjM3MF9sZWQsIG1j KTsKPiArCXN0cnVjdCBtdDYzNzBfcHJpdiAqcHJpdiA9IGxlZC0+cHJpdjsKPiArCXN0cnVjdCBt Y19zdWJsZWQgKnN1YmxlZDsKPiArCXVuc2lnbmVkIGludCBlbmFibGUsIGRpc2FibGU7Cj4gKwlp bnQgaSwgcmV0Owo+ICsKPiArCW11dGV4X2xvY2soJnByaXYtPmxvY2spOwo+ICsKPiArCWlmICgh KmRlbGF5X29uICYmICEqZGVsYXlfb2ZmKQo+ICsJCSpkZWxheV9vbiA9ICpkZWxheV9vZmYgPSA1 MDA7Cj4gKwo+ICsJcmV0ID0gcmVnbWFwX2ZpZWxkX3JlYWQocHJpdi0+ZmllbGRzW0ZfUkdCX0VO XSwgJmVuYWJsZSk7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8gb3V0X3VubG9jazsKPiArCj4gKwlk aXNhYmxlID0gZW5hYmxlOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBtY2NkZXYtPm51bV9jb2xv cnM7IGkrKykgewo+ICsJCXN1YmxlZCA9IG1jY2Rldi0+c3VibGVkX2luZm8gKyBpOwo+ICsKPiAr CQlkaXNhYmxlICY9IH5NVDYzNzBfQ0hFTl9CSVQoc3VibGVkLT5jaGFubmVsKTsKPiArCj4gKwkJ cmV0ID0gbXQ2MzcwX3NldF9sZWRfZHV0eShwcml2LCBzdWJsZWQtPmNoYW5uZWwsICpkZWxheV9v biwKPiArCQkJCQkgICpkZWxheV9vZmYpOwo+ICsJCWlmIChyZXQpCj4gKwkJCWdvdG8gb3V0X3Vu bG9jazsKPiArCj4gKwkJcmV0ID0gbXQ2MzcwX3NldF9sZWRfZnJlcShwcml2LCBzdWJsZWQtPmNo YW5uZWwsICpkZWxheV9vbiwKPiArCQkJCQkgICpkZWxheV9vZmYpOwo+ICsJCWlmIChyZXQpCj4g KwkJCWdvdG8gb3V0X3VubG9jazsKPiArCj4gKwkJcmV0ID0gbXQ2MzcwX3NldF9sZWRfbW9kZShw cml2LCBzdWJsZWQtPmNoYW5uZWwsCj4gKwkJCQkJICBNVDYzNzBfTEVEX1BXTV9NT0RFKTsKPiAr CQlpZiAocmV0KQo+ICsJCQlnb3RvIG91dF91bmxvY2s7Cj4gKwl9Cj4gKwo+ICsJLyogVG9nZ2xl IHRvIG1ha2UgcGF0dGVybiB0aW1pbmcgdGhlIHNhbWUgKi8KPiArCXJldCA9IHJlZ21hcF9maWVs ZF93cml0ZShwcml2LT5maWVsZHNbRl9SR0JfRU5dLCBkaXNhYmxlKTsKPiArCWlmIChyZXQpCj4g KwkJZ290byBvdXRfdW5sb2NrOwo+ICsKPiArCXJldCA9IHJlZ21hcF9maWVsZF93cml0ZShwcml2 LT5maWVsZHNbRl9SR0JfRU5dLCBlbmFibGUpOwo+ICsKPiArb3V0X3VubG9jazoKPiArCW11dGV4 X3VubG9jaygmcHJpdi0+bG9jayk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3Rh dGljIGludCBtdDYzNzBfbWNfcGF0dGVybl9zZXQoc3RydWN0IGxlZF9jbGFzc2RldiAqbGNkZXYs Cj4gKwkJCXN0cnVjdCBsZWRfcGF0dGVybiAqcGF0dGVybiwgdTMyIGxlbiwgaW50IHJlcGVhdCkK PiArewo+ICsJc3RydWN0IGxlZF9jbGFzc2Rldl9tYyAqbWNjZGV2ID0gbGNkZXZfdG9fbWNjZGV2 KGxjZGV2KTsKPiArCXN0cnVjdCBtdDYzNzBfbGVkICpsZWQgPSBjb250YWluZXJfb2YobWNjZGV2 LCBzdHJ1Y3QgbXQ2MzcwX2xlZCwgbWMpOwo+ICsJc3RydWN0IG10NjM3MF9wcml2ICpwcml2ID0g bGVkLT5wcml2Owo+ICsJc3RydWN0IG1jX3N1YmxlZCAqc3VibGVkOwo+ICsJdW5zaWduZWQgaW50 IHJlZ19iYXNlLCBlbmFibGUsIGRpc2FibGU7Cj4gKwl1OCBwYXJhbXNbUF9NQVhfUEFUVEVSTlMg LyAyXTsKPiArCWludCBpLCByZXQ7Cj4gKwo+ICsJbXV0ZXhfbG9jaygmcHJpdi0+bG9jayk7Cj4g Kwo+ICsJcmV0ID0gbXQ2MzcwX2dlbl9icmVhdGhfcGF0dGVybihwcml2LCBwYXR0ZXJuLCBsZW4s IHBhcmFtcywKPiArCQkJCQlzaXplb2YocGFyYW1zKSk7Cj4gKwlpZiAocmV0KQo+ICsJCWdvdG8g b3V0X3VubG9jazsKPiArCj4gKwlyZXQgPSByZWdtYXBfZmllbGRfcmVhZChwcml2LT5maWVsZHNb Rl9SR0JfRU5dLCAmZW5hYmxlKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ ICsKPiArCWRpc2FibGUgPSBlbmFibGU7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IG1jY2Rldi0+ bnVtX2NvbG9yczsgaSsrKSB7Cj4gKwkJc3VibGVkID0gbWNjZGV2LT5zdWJsZWRfaW5mbyArIGk7 Cj4gKwo+ICsJCW10NjM3MF9nZXRfYnJlYXRoX3JlZ19iYXNlKHByaXYsIHN1YmxlZC0+Y2hhbm5l bCwgJnJlZ19iYXNlKTsKPiArCQlkaXNhYmxlICY9IH5NVDYzNzBfQ0hFTl9CSVQoc3VibGVkLT5j aGFubmVsKTsKPiArCj4gKwkJcmV0ID0gcmVnbWFwX3Jhd193cml0ZShwcml2LT5yZWdtYXAsIHJl Z19iYXNlLCBwYXJhbXMsCj4gKwkJCQkgICAgICAgc2l6ZW9mKHBhcmFtcykpOwo+ICsJCWlmIChy ZXQpCj4gKwkJCWdvdG8gb3V0X3VubG9jazsKPiArCj4gKwkJcmV0ID0gbXQ2MzcwX3NldF9sZWRf bW9kZShwcml2LCBzdWJsZWQtPmNoYW5uZWwsCj4gKwkJCQkJICBNVDYzNzBfTEVEX0JSRUFUSF9N T0RFKTsKPiArCQlpZiAocmV0KQo+ICsJCQlnb3RvIG91dF91bmxvY2s7Cj4gKwl9Cj4gKwo+ICsJ LyogVG9nZ2xlIHRvIG1ha2UgcGF0dGVybiB0aW1pbmcgYmUgdGhlIHNhbWUgKi8KPiArCXJldCA9 IHJlZ21hcF9maWVsZF93cml0ZShwcml2LT5maWVsZHNbRl9SR0JfRU5dLCBkaXNhYmxlKTsKPiAr CWlmIChyZXQpCj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ICsKPiArCXJldCA9IHJlZ21hcF9maWVs ZF93cml0ZShwcml2LT5maWVsZHNbRl9SR0JfRU5dLCBlbmFibGUpOwo+ICsKPiArb3V0X3VubG9j azoKPiArCW11dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiAr fQo+ICsKPiArc3RhdGljIGlubGluZSBpbnQgbXQ2MzcwX21jX3BhdHRlcm5fY2xlYXIoc3RydWN0 IGxlZF9jbGFzc2RldiAqbGNkZXYpCj4gK3sKPiArCXN0cnVjdCBsZWRfY2xhc3NkZXZfbWMgKm1j Y2RldiA9IGxjZGV2X3RvX21jY2RldihsY2Rldik7Cj4gKwlzdHJ1Y3QgbXQ2MzcwX2xlZCAqbGVk ID0gY29udGFpbmVyX29mKG1jY2Rldiwgc3RydWN0IG10NjM3MF9sZWQsIG1jKTsKPiArCXN0cnVj dCBtdDYzNzBfcHJpdiAqcHJpdiA9IGxlZC0+cHJpdjsKPiArCXN0cnVjdCBtY19zdWJsZWQgKnN1 YmxlZDsKPiArCWludCBpLCByZXQ7Cj4gKwo+ICsJbXV0ZXhfbG9jaygmbGVkLT5wcml2LT5sb2Nr KTsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgbWNjZGV2LT5udW1fY29sb3JzOyBpKyspIHsKPiAr CQlzdWJsZWQgPSBtY2NkZXYtPnN1YmxlZF9pbmZvICsgaTsKPiArCj4gKwkJcmV0ID0gbXQ2Mzcw X3NldF9sZWRfbW9kZShwcml2LCBzdWJsZWQtPmNoYW5uZWwsCj4gKwkJCQkJICBNVDYzNzBfTEVE X1JFR19NT0RFKTsKPiArCQlpZiAocmV0KQo+ICsJCQlicmVhazsKPiArCX0KPiArCj4gKwltdXRl eF91bmxvY2soJmxlZC0+cHJpdi0+bG9jayk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsK PiArc3RhdGljIGludCBtdDYzNzBfaXNua19icmlnaHRuZXNzX3NldChzdHJ1Y3QgbGVkX2NsYXNz ZGV2ICpsY2RldiwKPiArCQkJCSAgICAgIGVudW0gbGVkX2JyaWdodG5lc3MgbGV2ZWwpCj4gK3sK PiArCXN0cnVjdCBtdDYzNzBfbGVkICpsZWQgPSBjb250YWluZXJfb2YobGNkZXYsIHN0cnVjdCBt dDYzNzBfbGVkLCBpc2luayk7Cj4gKwlzdHJ1Y3QgbXQ2MzcwX3ByaXYgKnByaXYgPSBsZWQtPnBy aXY7Cj4gKwl1bnNpZ25lZCBpbnQgZW5hYmxlOwo+ICsJaW50IHJldDsKPiArCj4gKwltdXRleF9s b2NrKCZwcml2LT5sb2NrKTsKPiArCj4gKwlyZXQgPSByZWdtYXBfZmllbGRfcmVhZChwcml2LT5m aWVsZHNbRl9SR0JfRU5dLCAmZW5hYmxlKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBvdXRfdW5s b2NrOwo+ICsKPiArCWlmIChsZXZlbCA9PSAwKSB7Cj4gKwkJZW5hYmxlICY9IH5NVDYzNzBfQ0hF Tl9CSVQobGVkLT5pbmRleCk7Cj4gKwo+ICsJCXJldCA9IG10NjM3MF9zZXRfbGVkX21vZGUocHJp diwgbGVkLT5pbmRleCwKPiArCQkJCQkgIE1UNjM3MF9MRURfUkVHX01PREUpOwo+ICsJCWlmIChy ZXQpCj4gKwkJCWdvdG8gb3V0X3VubG9jazsKPiArCX0gZWxzZSB7Cj4gKwkJZW5hYmxlIHw9IE1U NjM3MF9DSEVOX0JJVChsZWQtPmluZGV4KTsKPiArCj4gKwkJcmV0ID0gbXQ2MzcwX3NldF9sZWRf YnJpZ2h0bmVzcyhwcml2LCBsZWQtPmluZGV4LCBsZXZlbCk7Cj4gKwkJaWYgKHJldCkKPiArCQkJ Z290byBvdXRfdW5sb2NrOwo+ICsJfQo+ICsKPiArCXJldCA9IHJlZ21hcF9maWVsZF93cml0ZShw cml2LT5maWVsZHNbRl9SR0JfRU5dLCBlbmFibGUpOwo+ICsKPiArb3V0X3VubG9jazoKPiArCW11 dGV4X3VubG9jaygmcHJpdi0+bG9jayk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiAr c3RhdGljIGludCBtdDYzNzBfaXNua19ibGlua19zZXQoc3RydWN0IGxlZF9jbGFzc2RldiAqbGNk ZXYsCj4gKwkJCQkgdW5zaWduZWQgbG9uZyAqZGVsYXlfb24sCj4gKwkJCQkgdW5zaWduZWQgbG9u ZyAqZGVsYXlfb2ZmKQo+ICt7Cj4gKwlzdHJ1Y3QgbXQ2MzcwX2xlZCAqbGVkID0gY29udGFpbmVy X29mKGxjZGV2LCBzdHJ1Y3QgbXQ2MzcwX2xlZCwgaXNpbmspOwo+ICsJc3RydWN0IG10NjM3MF9w cml2ICpwcml2ID0gbGVkLT5wcml2Owo+ICsJaW50IHJldDsKPiArCj4gKwltdXRleF9sb2NrKCZw cml2LT5sb2NrKTsKPiArCj4gKwlpZiAoISpkZWxheV9vbiAmJiAhKmRlbGF5X29mZikKPiArCQkq ZGVsYXlfb24gPSAqZGVsYXlfb2ZmID0gNTAwOwo+ICsKPiArCXJldCA9IG10NjM3MF9zZXRfbGVk X2R1dHkocHJpdiwgbGVkLT5pbmRleCwgKmRlbGF5X29uLCAqZGVsYXlfb2ZmKTsKPiArCWlmIChy ZXQpCj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ICsKPiArCXJldCA9IG10NjM3MF9zZXRfbGVkX2Zy ZXEocHJpdiwgbGVkLT5pbmRleCwgKmRlbGF5X29uLCAqZGVsYXlfb2ZmKTsKPiArCWlmIChyZXQp Cj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ICsKPiArCXJldCA9IG10NjM3MF9zZXRfbGVkX21vZGUo cHJpdiwgbGVkLT5pbmRleCwgTVQ2MzcwX0xFRF9QV01fTU9ERSk7Cj4gKwo+ICtvdXRfdW5sb2Nr Ogo+ICsJbXV0ZXhfdW5sb2NrKCZwcml2LT5sb2NrKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9 Cj4gKwo+ICtzdGF0aWMgaW50IG10NjM3MF9pc25rX3BhdHRlcm5fc2V0KHN0cnVjdCBsZWRfY2xh c3NkZXYgKmxjZGV2LAo+ICsJCQkJICAgc3RydWN0IGxlZF9wYXR0ZXJuICpwYXR0ZXJuLCB1MzIg bGVuLAo+ICsJCQkJICAgaW50IHJlcGVhdCkKPiArewo+ICsJc3RydWN0IG10NjM3MF9sZWQgKmxl ZCA9IGNvbnRhaW5lcl9vZihsY2Rldiwgc3RydWN0IG10NjM3MF9sZWQsIGlzaW5rKTsKPiArCXN0 cnVjdCBtdDYzNzBfcHJpdiAqcHJpdiA9IGxlZC0+cHJpdjsKPiArCXVuc2lnbmVkIGludCByZWdf YmFzZTsKPiArCXU4IHBhcmFtc1tQX01BWF9QQVRURVJOUyAvIDJdOwo+ICsJaW50IHJldDsKPiAr Cj4gKwltdXRleF9sb2NrKCZwcml2LT5sb2NrKTsKPiArCj4gKwlyZXQgPSBtdDYzNzBfZ2VuX2Jy ZWF0aF9wYXR0ZXJuKHByaXYsIHBhdHRlcm4sIGxlbiwgcGFyYW1zLAo+ICsJCQkJCXNpemVvZihw YXJhbXMpKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ICsKPiArCW10NjM3 MF9nZXRfYnJlYXRoX3JlZ19iYXNlKHByaXYsIGxlZC0+aW5kZXgsICZyZWdfYmFzZSk7Cj4gKwo+ ICsJcmV0ID0gcmVnbWFwX3Jhd193cml0ZShwcml2LT5yZWdtYXAsIHJlZ19iYXNlLCBwYXJhbXMs IHNpemVvZihwYXJhbXMpKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBvdXRfdW5sb2NrOwo+ICsK PiArCXJldCA9IG10NjM3MF9zZXRfbGVkX21vZGUocHJpdiwgbGVkLT5pbmRleCwgTVQ2MzcwX0xF RF9CUkVBVEhfTU9ERSk7Cj4gKwo+ICtvdXRfdW5sb2NrOgo+ICsJbXV0ZXhfdW5sb2NrKCZwcml2 LT5sb2NrKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW5saW5lIGlu dCBtdDYzNzBfaXNua19wYXR0ZXJuX2NsZWFyKHN0cnVjdCBsZWRfY2xhc3NkZXYgKmxjZGV2KQo+ ICt7Cj4gKwlzdHJ1Y3QgbXQ2MzcwX2xlZCAqbGVkID0gY29udGFpbmVyX29mKGxjZGV2LCBzdHJ1 Y3QgbXQ2MzcwX2xlZCwgaXNpbmspOwo+ICsJc3RydWN0IG10NjM3MF9wcml2ICpwcml2ID0gbGVk LT5wcml2Owo+ICsJaW50IHJldDsKPiArCj4gKwltdXRleF9sb2NrKCZsZWQtPnByaXYtPmxvY2sp Owo+ICsJcmV0ID0gbXQ2MzcwX3NldF9sZWRfbW9kZShwcml2LCBsZWQtPmluZGV4LCBNVDYzNzBf TEVEX1JFR19NT0RFKTsKPiArCW11dGV4X3VubG9jaygmbGVkLT5wcml2LT5sb2NrKTsKPiArCj4g KwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG10NjM3MF9pbml0X2xlZF9wcm9w ZXJ0aWVzKHN0cnVjdCBkZXZpY2UgKmRldiwKPiArCQkJCSAgICAgIHN0cnVjdCBtdDYzNzBfbGVk ICpsZWQsCj4gKwkJCQkgICAgICBzdHJ1Y3QgbGVkX2luaXRfZGF0YSAqaW5pdF9kYXRhKQo+ICt7 Cj4gKwlzdHJ1Y3QgbXQ2MzcwX3ByaXYgKnByaXYgPSBsZWQtPnByaXY7Cj4gKwlzdHJ1Y3QgbGVk X2NsYXNzZGV2ICpsY2RldjsKPiArCXN0cnVjdCBmd25vZGVfaGFuZGxlICpjaGlsZDsKPiArCWVu dW0gbXQ2MzcwX2xlZF9yYW5nZXMgc2VsX3JhbmdlOwo+ICsJdTMyIG1heF91QSwgbWF4X2xldmVs Owo+ICsJaW50IHJldDsKPiArCj4gKwlpZiAobGVkLT5pbmRleCA9PSBNVDYzNzBfVklSVFVBTF9N VUxUSUNPTE9SKSB7CgpSYXRoZXIgdGhhbiBoYXZpbmcgdGhlc2UgaHVnZSBpZi1lbHNlIHN0YXRl bWVudHMsIHBsZWFzZSBjb25zaWRlciB1c2luZwphIHN1Yi1mdW5jdGlvbi4KCj4gKwkJc3RydWN0 IG1jX3N1YmxlZCAqc3ViX2xlZDsKPiArCQl1MzIgbnVtX2NvbG9yID0gMDsKPiArCj4gKwkJc3Vi X2xlZCA9IGRldm1fa2NhbGxvYyhkZXYsIE1DX0NIQU5ORUxfTlVNLCBzaXplb2YoKnN1Yl9sZWQp LAo+ICsJCQkJICAgICAgIEdGUF9LRVJORUwpOwo+ICsJCWlmICghc3ViX2xlZCkKPiArCQkJcmV0 dXJuIC1FTk9NRU07Cj4gKwo+ICsJCWZ3bm9kZV9mb3JfZWFjaF9jaGlsZF9ub2RlKGluaXRfZGF0 YS0+Zndub2RlLCBjaGlsZCkgewo+ICsJCQl1MzIgcmVnLCBjb2xvcjsKPiArCj4gKwkJCXJldCA9 IGZ3bm9kZV9wcm9wZXJ0eV9yZWFkX3UzMihjaGlsZCwgInJlZyIsICZyZWcpOwo+ICsJCQlpZiAo cmV0IHx8IHJlZyA+IE1UNjM3MF9MRURfSVNOSzMgfHwKPiArCQkJICAgIHByaXYtPmxlZHNfYWN0 aXZlICYgQklUKHJlZykpIHsKPiArCQkJCWZ3bm9kZV9oYW5kbGVfcHV0KGNoaWxkKTsKPiArCQkJ CXJldHVybiAtRUlOVkFMOwo+ICsJCQl9Cj4gKwo+ICsJCQlyZXQgPSBmd25vZGVfcHJvcGVydHlf cmVhZF91MzIoY2hpbGQsICJjb2xvciIsICZjb2xvcik7Cj4gKwkJCWlmIChyZXQpIHsKPiArCQkJ CWZ3bm9kZV9oYW5kbGVfcHV0KGNoaWxkKTsKPiArCQkJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRl diwgcmV0LCAiTEVEICVkLCBubyBjb2xvciBzcGVjaWZpZWRcbiIsCj4gKwkJCQkJCSAgICAgbGVk LT5pbmRleCk7Cj4gKwkJCX0KPiArCj4gKwkJCXByaXYtPmxlZHNfYWN0aXZlIHw9IEJJVChyZWcp Owo+ICsJCQlzdWJfbGVkW251bV9jb2xvcl0uY29sb3JfaW5kZXggPSBjb2xvcjsKPiArCQkJc3Vi X2xlZFtudW1fY29sb3JdLmNoYW5uZWwgPSByZWc7Cj4gKwkJCXN1Yl9sZWRbbnVtX2NvbG9yXS5p bnRlbnNpdHkgPSAwOwo+ICsJCQludW1fY29sb3IrKzsKPiArCQl9Cj4gKwo+ICsJCWlmIChudW1f Y29sb3IgPCAyKQo+ICsJCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIC1FSU5WQUwsCj4gKwkJ CQkJICAgICAiTXVsdGljb2xvciBtdXN0IGluY2x1ZGUgMiBvciBtb3JlIExFRCBjaGFubmVsc1xu Iik7Cj4gKwo+ICsJCWxlZC0+bWMubnVtX2NvbG9ycyA9IG51bV9jb2xvcjsKPiArCQlsZWQtPm1j LnN1YmxlZF9pbmZvID0gc3ViX2xlZDsKPiArCj4gKwkJbGNkZXYgPSAmbGVkLT5tYy5sZWRfY2Rl djsKPiArCQlsY2Rldi0+YnJpZ2h0bmVzc19zZXRfYmxvY2tpbmcgPSBtdDYzNzBfbWNfYnJpZ2h0 bmVzc19zZXQ7Cj4gKwkJbGNkZXYtPmJsaW5rX3NldCA9IG10NjM3MF9tY19ibGlua19zZXQ7Cj4g KwkJbGNkZXYtPnBhdHRlcm5fc2V0ID0gbXQ2MzcwX21jX3BhdHRlcm5fc2V0Owo+ICsJCWxjZGV2 LT5wYXR0ZXJuX2NsZWFyID0gbXQ2MzcwX21jX3BhdHRlcm5fY2xlYXI7Cj4gKwl9IGVsc2Ugewo+ ICsJCWxjZGV2ID0gJmxlZC0+aXNpbms7Cj4gKwkJbGNkZXYtPmJyaWdodG5lc3Nfc2V0X2Jsb2Nr aW5nID0gbXQ2MzcwX2lzbmtfYnJpZ2h0bmVzc19zZXQ7Cj4gKwkJbGNkZXYtPmJsaW5rX3NldCA9 IG10NjM3MF9pc25rX2JsaW5rX3NldDsKPiArCQlsY2Rldi0+cGF0dGVybl9zZXQgPSBtdDYzNzBf aXNua19wYXR0ZXJuX3NldDsKPiArCQlsY2Rldi0+cGF0dGVybl9jbGVhciA9IG10NjM3MF9pc25r X3BhdHRlcm5fY2xlYXI7Cj4gKwl9Cj4gKwo+ICsJcmV0ID0gZndub2RlX3Byb3BlcnR5X3JlYWRf dTMyKGluaXRfZGF0YS0+Zndub2RlLCAibGVkLW1heC1taWNyb2FtcCIsCj4gKwkJCQkgICAgICAg Jm1heF91QSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJZGV2X3dhcm4oZGV2LCAiTm90IHNwZWNpZmll ZCBsZWQtbWF4LW1pY3JvYW1wLCBjb25maWcgdG8gdGhlIG1pbmltdW1cbiIpOwo+ICsJCW1heF91 QSA9IDA7Cj4gKwl9Cj4gKwo+ICsJaWYgKGxlZC0+aW5kZXggPT0gTVQ2MzcwX0xFRF9JU05LNCkK PiArCQlzZWxfcmFuZ2UgPSBSX0xFRDRfQ1VSUjsKPiArCWVsc2UKPiArCQlzZWxfcmFuZ2UgPSBS X0xFRDEyM19DVVJSOwo+ICsKPiArCWxpbmVhcl9yYW5nZV9nZXRfc2VsZWN0b3Jfd2l0aGluKHBy aXYtPnJhbmdlcyArIHNlbF9yYW5nZSwgbWF4X3VBLAo+ICsJCQkJCSAmbWF4X2xldmVsKTsKPiAr Cj4gKwlsY2Rldi0+bWF4X2JyaWdodG5lc3MgPSBtYXhfbGV2ZWw7Cj4gKwo+ICsJbGVkLT5kZWZh dWx0X3N0YXRlID0gbGVkX2luaXRfZGVmYXVsdF9zdGF0ZV9nZXQoaW5pdF9kYXRhLT5md25vZGUp Owo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG10NjM3MF9pc25rX2lu aXRfZGVmYXVsdF9zdGF0ZShzdHJ1Y3QgbXQ2MzcwX2xlZCAqbGVkKQo+ICt7Cj4gKwlzdHJ1Y3Qg bXQ2MzcwX3ByaXYgKnByaXYgPSBsZWQtPnByaXY7Cj4gKwl1bnNpZ25lZCBpbnQgZW5hYmxlLCBs ZXZlbDsKPiArCWludCByZXQ7Cj4gKwo+ICsJcmV0ID0gbXQ2MzcwX2dldF9sZWRfYnJpZ2h0bmVz cyhwcml2LCBsZWQtPmluZGV4LCAmbGV2ZWwpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0 Owo+ICsKPiArCXJldCA9IHJlZ21hcF9maWVsZF9yZWFkKHByaXYtPmZpZWxkc1tGX1JHQl9FTl0s ICZlbmFibGUpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCWlmICghKGVu YWJsZSAmIE1UNjM3MF9DSEVOX0JJVChsZWQtPmluZGV4KSkpCj4gKwkJbGV2ZWwgPSAwOwo+ICsK PiArCXN3aXRjaCAobGVkLT5kZWZhdWx0X3N0YXRlKSB7Cj4gKwljYXNlIExFRFNfREVGU1RBVEVf T046Cj4gKwkJbGVkLT5pc2luay5icmlnaHRuZXNzID0gbGVkLT5pc2luay5tYXhfYnJpZ2h0bmVz czsKPiArCQlicmVhazsKPiArCWNhc2UgTEVEU19ERUZTVEFURV9LRUVQOgo+ICsJCWxlZC0+aXNp bmsuYnJpZ2h0bmVzcyA9IG1pbihsZXZlbCwgbGVkLT5pc2luay5tYXhfYnJpZ2h0bmVzcyk7Cj4g KwkJYnJlYWs7Cj4gKwlkZWZhdWx0Ogo+ICsJCWxlZC0+aXNpbmsuYnJpZ2h0bmVzcyA9IDA7Cj4g KwkJYnJlYWs7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIG10NjM3MF9pc25rX2JyaWdodG5lc3Nfc2V0 KCZsZWQtPmlzaW5rLCBsZWQtPmlzaW5rLmJyaWdodG5lc3MpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg aW50IG10NjM3MF9sZWRfcmVnaXN0ZXIoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgbXQ2Mzcw X2xlZCAqbGVkLAo+ICsJCQkgICAgICAgc3RydWN0IGxlZF9pbml0X2RhdGEgKmluaXRfZGF0YSkK PiArewo+ICsJc3RydWN0IG10NjM3MF9wcml2ICpwcml2ID0gbGVkLT5wcml2Owo+ICsJaW50IHJl dDsKPiArCj4gKwlpZiAobGVkLT5pbmRleCA9PSBNVDYzNzBfVklSVFVBTF9NVUxUSUNPTE9SKSB7 CgpUaGlzIHRvbyBjb3VsZCBiZSBzcGxpdCBpbnRvIHNlcGFyYXRlIGZ1bmN0aW9ucyB0byB0aWR5 IHRoaW5ncyB1cCBhCmxpdHRsZS4KCj4gKwkJcmV0ID0gbXQ2MzcwX21jX2JyaWdodG5lc3Nfc2V0 KCZsZWQtPm1jLmxlZF9jZGV2LCAwKTsKPiArCQlpZiAocmV0KQo+ICsJCQlyZXR1cm4gZGV2X2Vy cl9wcm9iZShkZXYsIHJldCwgIkNvdWxkbid0IHNldCBtdWx0aWNvbG9yIGJyaWdodG5lc3NcbiIp Owo+ICsKPiArCQlyZXQgPSBkZXZtX2xlZF9jbGFzc2Rldl9tdWx0aWNvbG9yX3JlZ2lzdGVyX2V4 dChkZXYsICZsZWQtPm1jLAo+ICsJCQkJCQkJCWluaXRfZGF0YSk7Cj4gKwkJaWYgKHJldCkKPiAr CQkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJDb3VsZG4ndCByZWdpc3RlciBtdWx0 aWNvbG9yXG4iKTsKPiArCX0gZWxzZSB7Cj4gKwkJaWYgKGxlZC0+aW5kZXggPT0gTVQ2MzcwX0xF RF9JU05LNCkgewo+ICsJCQlyZXQgPSByZWdtYXBfZmllbGRfd3JpdGUocHJpdi0+ZmllbGRzW0Zf Q0hHSU5EX0VOXSwgMSk7Cj4gKwkJCWlmIChyZXQpCj4gKwkJCQlyZXR1cm4gZGV2X2Vycl9wcm9i ZShkZXYsIHJldCwgIkZhaWxlZCB0byBzZXQgQ0hSSU5EIHRvIFNXXG4iKTsKPiArCQl9Cj4gKwo+ ICsJCXJldCA9IG10NjM3MF9pc25rX2luaXRfZGVmYXVsdF9zdGF0ZShsZWQpOwo+ICsJCWlmIChy ZXQpCj4gKwkJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgcmV0LCAiRmFpbGVkIHRvIGluaXQg JWQgaXNuayBzdGF0ZVxuIiwKPiArCQkJCQkgICAgIGxlZC0+aW5kZXgpOwo+ICsKPiArCQlyZXQg PSBkZXZtX2xlZF9jbGFzc2Rldl9yZWdpc3Rlcl9leHQoZGV2LCAmbGVkLT5pc2luaywKPiArCQkJ CQkJICAgICBpbml0X2RhdGEpOwo+ICsJCWlmIChyZXQpCj4gKwkJCXJldHVybiBkZXZfZXJyX3By b2JlKGRldiwgcmV0LCAiQ291bGRuJ3QgcmVnaXN0ZXIgaXNpbmsgJWRcbiIsIGxlZC0+aW5kZXgp Owo+ICsJfQo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG10NjM3MF9j aGVja192ZW5kb3JfaW5mbyhzdHJ1Y3QgbXQ2MzcwX3ByaXYgKnByaXYpCj4gK3sKPiArCXVuc2ln bmVkIGludCBkZXZpbmZvLCB2aWQ7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXJldCA9IHJlZ21hcF9y ZWFkKHByaXYtPnJlZ21hcCwgTVQ2MzcwX1JFR19ERVZfSU5GTywgJmRldmluZm8pOwo+ICsJaWYg KHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXZpZCA9IEZJRUxEX0dFVChNVDYzNzBfVkVO SURfTUFTSywgZGV2aW5mbyk7Cj4gKwlpZiAodmlkID09IDB4OSB8fCB2aWQgPT0gMHhiKSB7CgpB cmUgdGhlcmUgbmljZSBodW1hbiByZWFkYWJsZSBhc3NvY2lhdGVzIG9mIHRoZXNlICh2ZW5kb3I/ KSBJRFM/Cgo+ICsJCXByaXYtPnJlZ19maWVsZHMgPSBtdDYzNzJfcmVnX2ZpZWxkczsKPiArCQlw cml2LT5yYW5nZXMgPSBtdDYzNzJfbGVkX3JhbmdlczsKPiArCQlwcml2LT5wZGF0YSA9ICZtdDYz NzJfcGRhdGE7Cj4gKwl9IGVsc2Ugewo+ICsJCS8qIENvbW1vbiBmb3IgTVQ2MzcwLzcxICovCj4g KwkJcHJpdi0+cmVnX2ZpZWxkcyA9IGNvbW1vbl9yZWdfZmllbGRzOwo+ICsJCXByaXYtPnJhbmdl cyA9IGNvbW1vbl9sZWRfcmFuZ2VzOwo+ICsJCXByaXYtPnBkYXRhID0gJmNvbW1vbl9wZGF0YTsK PiArCX0KPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIGludCBtdDYzNzBfbGVk c19wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlzdHJ1Y3QgZGV2 aWNlICpkZXYgPSAmcGRldi0+ZGV2Owo+ICsJc3RydWN0IG10NjM3MF9wcml2ICpwcml2Owo+ICsJ c3RydWN0IGZ3bm9kZV9oYW5kbGUgKmNoaWxkOwo+ICsJc2l6ZV90IGNvdW50Owo+ICsJdW5zaWdu ZWQgaW50IGkgPSAwOwo+ICsJaW50IHJldDsKPiArCj4gKwljb3VudCA9IGRldmljZV9nZXRfY2hp bGRfbm9kZV9jb3VudChkZXYpOwo+ICsJaWYgKCFjb3VudCB8fCBjb3VudCA+IE1UNjM3MF9NQVhf TEVEUykKPiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIC1FSU5WQUwsCj4gKwkJCQkgICAg ICJObyBjaGlsZCBub2RlIG9yIG5vZGUgY291bnQgb3ZlciBtYXggTEVEIG51bWJlciAlenVcbiIs Cj4gKwkJCQkgICAgICBjb3VudCk7Cj4gKwo+ICsJcHJpdiA9IGRldm1fa3phbGxvYyhkZXYsIHN0 cnVjdF9zaXplKHByaXYsIGxlZHMsIGNvdW50KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXByaXYp Cj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJcHJpdi0+bGVkc19jb3VudCA9IGNvdW50Owo+ ICsJbXV0ZXhfaW5pdCgmcHJpdi0+bG9jayk7Cj4gKwo+ICsJcHJpdi0+cmVnbWFwID0gZGV2X2dl dF9yZWdtYXAoZGV2LT5wYXJlbnQsIE5VTEwpOwo+ICsJaWYgKCFwcml2LT5yZWdtYXApCj4gKwkJ cmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2LCAtRU5PREVWLCAiRmFpbGVkIHRvIGdldCBwYXJlbnQg cmVnbWFwXG4iKTsKPiArCj4gKwlyZXQgPSBtdDYzNzBfY2hlY2tfdmVuZG9yX2luZm8ocHJpdik7 Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgcmV0LCAiRmFpbGVk IHRvIGNoZWNrIHZlbmRvciBpbmZvXG4iKTsKPiArCj4gKwlyZXQgPSBkZXZtX3JlZ21hcF9maWVs ZF9idWxrX2FsbG9jKGRldiwgcHJpdi0+cmVnbWFwLCBwcml2LT5maWVsZHMsCj4gKwkJCQkJICAg cHJpdi0+cmVnX2ZpZWxkcywgRl9NQVhfRklFTERTKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJu IGRldl9lcnJfcHJvYmUoZGV2LCByZXQsICJGYWlsZWQgdG8gYWxsb2NhdGUgcmVnbWFwIGZpZWxk XG4iKTsKPiArCj4gKwlkZXZpY2VfZm9yX2VhY2hfY2hpbGRfbm9kZShkZXYsIGNoaWxkKSB7Cj4g KwkJc3RydWN0IG10NjM3MF9sZWQgKmxlZCA9IHByaXYtPmxlZHMgKyBpKys7Cj4gKwkJc3RydWN0 IGxlZF9pbml0X2RhdGEgaW5pdF9kYXRhID0geyAuZndub2RlID0gY2hpbGQgfTsKPiArCQl1MzIg cmVnLCBjb2xvcjsKPiArCj4gKwkJcmV0ID0gZndub2RlX3Byb3BlcnR5X3JlYWRfdTMyKGNoaWxk LCAicmVnIiwgJnJlZyk7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQlmd25vZGVfaGFuZGxlX3B1dChj aGlsZCk7Cj4gKwkJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRldiwgcmV0LCAiRmFpbGVkIHRvIHBh cnNlIHJlZyBwcm9wZXJ0eVxuIik7Cj4gKwkJfQo+ICsKPiArCQlpZiAocmVnID49IE1UNjM3MF9N QVhfTEVEUykgewo+ICsJCQlmd25vZGVfaGFuZGxlX3B1dChjaGlsZCk7Cj4gKwkJCXJldHVybiBk ZXZfZXJyX3Byb2JlKGRldiwgLUVJTlZBTCwgIkVycm9yIHJlZyBwcm9wZXJ0eSBudW1iZXJcbiIp Owo+ICsJCX0KPiArCj4gKwkJcmV0ID0gZndub2RlX3Byb3BlcnR5X3JlYWRfdTMyKGNoaWxkLCAi Y29sb3IiLCAmY29sb3IpOwo+ICsJCWlmIChyZXQpIHsKPiArCQkJZndub2RlX2hhbmRsZV9wdXQo Y2hpbGQpOwo+ICsJCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgIkZhaWxlZCB0byBw YXJzZSBjb2xvciBwcm9wZXJ0eVxuIik7Cj4gKwkJfQo+ICsKPiArCQlpZiAoY29sb3IgPT0gTEVE X0NPTE9SX0lEX1JHQiB8fCBjb2xvciA9PSBMRURfQ09MT1JfSURfTVVMVEkpCj4gKwkJCXJlZyA9 IE1UNjM3MF9WSVJUVUFMX01VTFRJQ09MT1I7Cj4gKwo+ICsJCWlmIChwcml2LT5sZWRzX2FjdGl2 ZSAmIEJJVChyZWcpKSB7Cj4gKwkJCWZ3bm9kZV9oYW5kbGVfcHV0KGNoaWxkKTsKPiArCQkJcmV0 dXJuIGRldl9lcnJfcHJvYmUoZGV2LCAtRUlOVkFMLCAiRHVwbGljYXRlIHJlZyBwcm9wZXJ0eVxu Iik7Cj4gKwkJfQo+ICsKPiArCQlwcml2LT5sZWRzX2FjdGl2ZSB8PSBCSVQocmVnKTsKPiArCj4g KwkJbGVkLT5pbmRleCA9IHJlZzsKPiArCQlsZWQtPnByaXYgPSBwcml2Owo+ICsKPiArCQlyZXQg PSBtdDYzNzBfaW5pdF9sZWRfcHJvcGVydGllcyhkZXYsIGxlZCwgJmluaXRfZGF0YSk7Cj4gKwkJ aWYgKHJldCkgewo+ICsJCQlmd25vZGVfaGFuZGxlX3B1dChjaGlsZCk7CgpJIGNvdW50IDYgY2Fs bHMgdG8gZndub2RlX2hhbmRsZV9wdXQoKSBoZXJlLgoKUGxlYXNlIHVzZSBhIGdvdG8gdG8gZGl2 ZXJ0IHRoZSBlcnJvciBoYW5kbGluZyB0byB0aGUgYm90dG9tIG9mIHRoZQpmdW5jdGlvbiB3aGVy ZSB5b3UgY2FsbCBmd25vZGVfaGFuZGxlX3B1dCgpIGp1c3Qgb25jZS4KCj4gKwkJCXJldHVybiBy ZXQ7Cj4gKwkJfQo+ICsKPiArCQlyZXQgPSBtdDYzNzBfbGVkX3JlZ2lzdGVyKGRldiwgbGVkLCAm aW5pdF9kYXRhKTsKPiArCQlpZiAocmV0KSB7Cj4gKwkJCWZ3bm9kZV9oYW5kbGVfcHV0KGNoaWxk KTsKPiArCQkJcmV0dXJuIHJldDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG10NjM3MF9yZ2JsZWRfZGV2 aWNlX3RhYmxlW10gPSB7Cj4gKwl7IC5jb21wYXRpYmxlID0gIm1lZGlhdGVrLG10NjM3MC1pbmRp Y2F0b3IiIH0sCj4gKwl7fQo+ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBtdDYzNzBf cmdibGVkX2RldmljZV90YWJsZSk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZl ciBtdDYzNzBfcmdibGVkX2RyaXZlciA9IHsKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUgPSAi bXQ2MzcwLWluZGljYXRvciIsCj4gKwkJLm9mX21hdGNoX3RhYmxlID0gbXQ2MzcwX3JnYmxlZF9k ZXZpY2VfdGFibGUsCj4gKwl9LAo+ICsJLnByb2JlID0gbXQ2MzcwX2xlZHNfcHJvYmUsCj4gK307 Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIobXQ2MzcwX3JnYmxlZF9kcml2ZXIpOwo+ICsKPiAr TU9EVUxFX0FVVEhPUigiQWxpY2UgQ2hlbiA8YWxpY2VfY2hlbkByaWNodGVrLmNvbT4iKTsKPiAr TU9EVUxFX0FVVEhPUigiQ2hpWXVhbiBIdWFuZyA8Y3lfaHVhbmdAcmljaHRlay5jb20+Iik7Cj4g K01PRFVMRV9ERVNDUklQVElPTigiTWVkaWFUZWsgTVQ2MzcwIFJHQiBMRUQgRHJpdmVyIik7Cj4g K01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKPiAtLSAKPiAyLjcuNAo+IAoKLS0gCkxlZSBKb25lcyBb 5p2O55C85pavXQoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5p bmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8v bGludXgtYXJtLWtlcm5lbAo=