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 X-Spam-Level: X-Spam-Status: No, score=-11.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F012AC432C3 for ; Mon, 2 Dec 2019 01:58:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C6E8A24653 for ; Mon, 2 Dec 2019 01:58:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=megous.com header.i=@megous.com header.b="iH7TvVm/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727345AbfLBB6X (ORCPT ); Sun, 1 Dec 2019 20:58:23 -0500 Received: from vps.xff.cz ([195.181.215.36]:60536 "EHLO vps.xff.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727279AbfLBB6X (ORCPT ); Sun, 1 Dec 2019 20:58:23 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megous.com; s=mail; t=1575251896; bh=CaIhZzyVTFlNqKtL+qRE2ORuyG4z/Wb+57yrtwb/Ewg=; h=Date:From:To:Cc:Subject:References:X-My-GPG-KeyId:From; b=iH7TvVm/cFjFgZW8tcPgiJGkvoMKoVjI3XWsBKwE8MeYC0ly+ZCC35BzYhY+hN6rL oJ+8PVFUDgwcd13SFqAx+OxQa9cDcjKp5LZxLW4pp0qdiaLOHr7lT8Wag5/p2UIMky odaxTp7YL+O5V2SkJ8MKOWqq4zIVF+9+WpKMqdEk= Date: Mon, 2 Dec 2019 02:58:16 +0100 From: =?utf-8?Q?Ond=C5=99ej?= Jirman To: Frank Lee Cc: Vasily Khoruzhick , Zhang Rui , Eduardo Valentin , Daniel Lezcano , Amit Kucheria , Rob Herring , Mark Rutland , Maxime Ripard , Chen-Yu Tsai , Mauro Carvalho Chehab , "David S. Miller" , Greg Kroah-Hartman , Linux PM , devicetree , Linux ARM , Linux Kernel Mailing List Subject: Re: [PATCH v6 1/7] thermal: sun8i: add thermal driver for H6/H5/H3/A64/A83T/R40 Message-ID: <20191202015816.amtz45fyd6h6pcqk@core.my.home> Mail-Followup-To: Frank Lee , Vasily Khoruzhick , Zhang Rui , Eduardo Valentin , Daniel Lezcano , Amit Kucheria , Rob Herring , Mark Rutland , Maxime Ripard , Chen-Yu Tsai , Mauro Carvalho Chehab , "David S. Miller" , Greg Kroah-Hartman , Linux PM , devicetree , Linux ARM , Linux Kernel Mailing List References: <20191127052935.1719897-1-anarsoul@gmail.com> <20191127052935.1719897-2-anarsoul@gmail.com> <20191128170626.xsm7xmizmbenqval@core.my.home> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-My-GPG-KeyId: EBFBDDE11FB918D44D1F56C1F9F0A873BE9777ED Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Nov 29, 2019 at 07:46:58PM +0800, Frank Lee wrote: > On Fri, Nov 29, 2019 at 1:06 AM Ondřej Jirman wrote: > > > > On Fri, Nov 29, 2019 at 12:43:02AM +0800, Frank Lee wrote: > > > HI, > > > > > > I took a closer look at it, and I had some questions about these places. > > > > > > On Wed, Nov 27, 2019 at 1:30 PM Vasily Khoruzhick wrote: > > > > > > > > From: Yangtao Li > > > > > > > > This patch adds the support for allwinner thermal sensor, within > > > > allwinner SoC. It will register sensors for thermal framework > > > > and use device tree to bind cooling device. > > > > > > > > Signed-off-by: Yangtao Li > > > > Signed-off-by: Ondrej Jirman > > > > Signed-off-by: Vasily Khoruzhick > > > > --- > > > > MAINTAINERS | 7 + > > > > drivers/thermal/Kconfig | 14 + > > > > drivers/thermal/Makefile | 1 + > > > > drivers/thermal/sun8i_thermal.c | 643 ++++++++++++++++++++++++++++++++ > > > > 4 files changed, 665 insertions(+) > > > > create mode 100644 drivers/thermal/sun8i_thermal.c > > > > > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > > > index 66cc549ac327..da34f3f2e80b 100644 > > > > --- a/MAINTAINERS > > > > +++ b/MAINTAINERS > > > > @@ -688,6 +688,13 @@ L: linux-crypto@vger.kernel.org > > > > S: Maintained > > > > F: drivers/crypto/allwinner/ > > > > > > > > +ALLWINNER THERMAL DRIVER > > > > +M: Yangtao Li > > > > +L: linux-pm@vger.kernel.org > > > > +S: Maintained > > > > +F: Documentation/devicetree/bindings/thermal/allwinner,sun8i-a83t-ths.yaml > > > > +F: drivers/thermal/sun8i_thermal.c > > > > + > > > > ALLWINNER VPU DRIVER > > > > M: Maxime Ripard > > > > M: Paul Kocialkowski > > > > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig > > > > index 001a21abcc28..0b0422e89adb 100644 > > > > --- a/drivers/thermal/Kconfig > > > > +++ b/drivers/thermal/Kconfig > > > > @@ -262,6 +262,20 @@ config SPEAR_THERMAL > > > > Enable this to plug the SPEAr thermal sensor driver into the Linux > > > > thermal framework. > > > > > > > > +config SUN8I_THERMAL > > > > + tristate "Allwinner sun8i thermal driver" > > > > + depends on ARCH_SUNXI || COMPILE_TEST > > > > + depends on HAS_IOMEM > > > > + depends on NVMEM > > > > + depends on OF > > > > + depends on RESET_CONTROLLER > > > > + help > > > > + Support for the sun8i thermal sensor driver into the Linux thermal > > > > + framework. > > > > + > > > > + To compile this driver as a module, choose M here: the > > > > + module will be called sun8i-thermal. > > > > + > > > > config ROCKCHIP_THERMAL > > > > tristate "Rockchip thermal driver" > > > > depends on ARCH_ROCKCHIP || COMPILE_TEST > > > > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile > > > > index 74a37c7f847a..fa6f8b206281 100644 > > > > --- a/drivers/thermal/Makefile > > > > +++ b/drivers/thermal/Makefile > > > > @@ -31,6 +31,7 @@ thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o > > > > obj-y += broadcom/ > > > > obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o > > > > obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o > > > > +obj-$(CONFIG_SUN8I_THERMAL) += sun8i_thermal.o > > > > obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o > > > > obj-$(CONFIG_RCAR_THERMAL) += rcar_thermal.o > > > > obj-$(CONFIG_RCAR_GEN3_THERMAL) += rcar_gen3_thermal.o > > > > diff --git a/drivers/thermal/sun8i_thermal.c b/drivers/thermal/sun8i_thermal.c > > > > new file mode 100644 > > > > index 000000000000..e86b64f51196 > > > > --- /dev/null > > > > +++ b/drivers/thermal/sun8i_thermal.c > > > > @@ -0,0 +1,643 @@ > > > > +// SPDX-License-Identifier: GPL-2.0 > > > > +/* > > > > + * Thermal sensor driver for Allwinner SOC > > > > + * Copyright (C) 2019 Yangtao Li > > > > + * > > > > + * Based on the work of Icenowy Zheng > > > > + * Based on the work of Ondrej Jirman > > > > + * Based on the work of Josef Gajdusek > > > > + */ > > > > + > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > +#include > > > > + > > > > +#define MAX_SENSOR_NUM 4 > > > > + > > > > +#define FT_TEMP_MASK GENMASK(11, 0) > > > > +#define TEMP_CALIB_MASK GENMASK(11, 0) > > > > +#define CALIBRATE_DEFAULT 0x800 > > > > + > > > > +#define SUN8I_THS_CTRL0 0x00 > > > > +#define SUN8I_THS_CTRL2 0x40 > > > > +#define SUN8I_THS_IC 0x44 > > > > +#define SUN8I_THS_IS 0x48 > > > > +#define SUN8I_THS_MFC 0x70 > > > > +#define SUN8I_THS_TEMP_CALIB 0x74 > > > > +#define SUN8I_THS_TEMP_DATA 0x80 > > > > + > > > > +#define SUN50I_THS_CTRL0 0x00 > > > > +#define SUN50I_H6_THS_ENABLE 0x04 > > > > +#define SUN50I_H6_THS_PC 0x08 > > > > +#define SUN50I_H6_THS_DIC 0x10 > > > > +#define SUN50I_H6_THS_DIS 0x20 > > > > +#define SUN50I_H6_THS_MFC 0x30 > > > > +#define SUN50I_H6_THS_TEMP_CALIB 0xa0 > > > > +#define SUN50I_H6_THS_TEMP_DATA 0xc0 > > > > + > > > > +#define SUN8I_THS_CTRL0_T_ACQ0(x) (GENMASK(15, 0) & (x)) > > > > +#define SUN8I_THS_CTRL2_T_ACQ1(x) ((GENMASK(15, 0) & (x)) << 16) > > > > +#define SUN8I_THS_DATA_IRQ_STS(x) BIT(x + 8) > > > > + > > > > +#define SUN50I_THS_CTRL0_T_ACQ(x) ((GENMASK(15, 0) & (x)) << 16) > > > > +#define SUN50I_THS_FILTER_EN BIT(2) > > > > +#define SUN50I_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x)) > > > > +#define SUN50I_H6_THS_PC_TEMP_PERIOD(x) ((GENMASK(19, 0) & (x)) << 12) > > > > +#define SUN50I_H6_THS_DATA_IRQ_STS(x) BIT(x) > > > > + > > > > +/* millidegree celsius */ > > > > +#define THS_EFUSE_CP_FT_MASK 0x3000 > > > > +#define THS_EFUSE_CP_FT_BIT 12 > > > > +#define THS_CALIBRATION_IN_FT 1 > > > > + > > > > +struct ths_device; > > > > + > > > > +struct tsensor { > > > > + struct ths_device *tmdev; > > > > + struct thermal_zone_device *tzd; > > > > + int id; > > > > +}; > > > > + > > > > +struct ths_thermal_chip { > > > > + bool has_mod_clk; > > > > + bool has_bus_clk_reset; > > > > + int sensor_num; > > > > + int offset; > > > > + int scale; > > > > + int ft_deviation; > > > > + int temp_data_base; > > > > + int (*calibrate)(struct ths_device *tmdev, > > > > + u16 *caldata, int callen); > > > > + int (*init)(struct ths_device *tmdev); > > > > + int (*irq_ack)(struct ths_device *tmdev); > > > > + int (*calc_temp)(struct ths_device *tmdev, > > > > + int id, int reg); > > > > +}; > > > > + > > > > +struct ths_device { > > > > + const struct ths_thermal_chip *chip; > > > > + struct device *dev; > > > > + struct regmap *regmap; > > > > + struct reset_control *reset; > > > > + struct clk *bus_clk; > > > > + struct clk *mod_clk; > > > > + struct tsensor sensor[MAX_SENSOR_NUM]; > > > > + u32 cp_ft_flag; > > > > +}; > > > > + > > > > +/* Temp Unit: millidegree Celsius */ > > > > +static int sun8i_ths_calc_temp(struct ths_device *tmdev, > > > > + int id, int reg) > > > > +{ > > > > + return tmdev->chip->offset - (reg * tmdev->chip->scale / 10); > > > > +} > > > > + > > > > +static int sun50i_h5_calc_temp(struct ths_device *tmdev, > > > > + int id, int reg) > > > > +{ > > > > + if (reg >= 0x500) > > > > + return -1191 * reg / 10 + 223000; > > > > + else if (!id) > > > > + return -1452 * reg / 10 + 259000; > > > > + else > > > > + return -1590 * reg / 10 + 276000; > > > > +} > > > > + > > > > +static int sun8i_ths_get_temp(void *data, int *temp) > > > > +{ > > > > + struct tsensor *s = data; > > > > + struct ths_device *tmdev = s->tmdev; > > > > + int val = 0; > > > > + > > > > + regmap_read(tmdev->regmap, tmdev->chip->temp_data_base + > > > > + 0x4 * s->id, &val); > > > > + > > > > + /* ths have no data yet */ > > > > + if (!val) > > > > + return -EAGAIN; > > > > + > > > > + *temp = tmdev->chip->calc_temp(tmdev, s->id, val); > > > > + /* > > > > + * According to the original sdk, there are some platforms(rarely) > > > > + * that add a fixed offset value after calculating the temperature > > > > + * value. We can't simply put it on the formula for calculating the > > > > + * temperature above, because the formula for calculating the > > > > + * temperature above is also used when the sensor is calibrated. If > > > > + * do this, the correct calibration formula is hard to know. > > > > + */ > > > > + *temp += tmdev->chip->ft_deviation; > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static const struct thermal_zone_of_device_ops ths_ops = { > > > > + .get_temp = sun8i_ths_get_temp, > > > > +}; > > > > + > > > > +static const struct regmap_config config = { > > > > + .reg_bits = 32, > > > > + .val_bits = 32, > > > > + .reg_stride = 4, > > > > + .fast_io = true, > > > > + .max_register = 0xfc, > > > > +}; > > > > + > > > > +static int sun8i_h3_irq_ack(struct ths_device *tmdev) > > > > +{ > > > > + int i, state, ret = 0; > > > > + > > > > + regmap_read(tmdev->regmap, SUN8I_THS_IS, &state); > > > > + > > > > + for (i = 0; i < tmdev->chip->sensor_num; i++) { > > > > + if (state & SUN8I_THS_DATA_IRQ_STS(i)) { > > > > + regmap_write(tmdev->regmap, SUN8I_THS_IS, > > > > + SUN8I_THS_DATA_IRQ_STS(i)); > > > > + ret |= BIT(i); > > > > + } > > > > + } > > > > + > > > > + return ret; > > > > +} > > > > + > > > > +static int sun50i_h6_irq_ack(struct ths_device *tmdev) > > > > +{ > > > > + int i, state, ret = 0; > > > > + > > > > + regmap_read(tmdev->regmap, SUN50I_H6_THS_DIS, &state); > > > > + > > > > + for (i = 0; i < tmdev->chip->sensor_num; i++) { > > > > + if (state & SUN50I_H6_THS_DATA_IRQ_STS(i)) { > > > > + regmap_write(tmdev->regmap, SUN50I_H6_THS_DIS, > > > > + SUN50I_H6_THS_DATA_IRQ_STS(i)); > > > > + ret |= BIT(i); > > > > + } > > > > + } > > > > + > > > > + return ret; > > > > +} > > > > + > > > > +static irqreturn_t sun8i_irq_thread(int irq, void *data) > > > > +{ > > > > + struct ths_device *tmdev = data; > > > > + int i, state; > > > > + > > > > + state = tmdev->chip->irq_ack(tmdev); > > > > + > > > > + for (i = 0; i < tmdev->chip->sensor_num; i++) { > > > > + if (state & BIT(i)) > > > > + thermal_zone_device_update(tmdev->sensor[i].tzd, > > > > + THERMAL_EVENT_UNSPECIFIED); > > > > + } > > > > + > > > > + return IRQ_HANDLED; > > > > +} > > > > + > > > > +static int sun8i_h3_ths_calibrate(struct ths_device *tmdev, > > > > + u16 *caldata, int callen) > > > > +{ > > > > + int i; > > > > + > > > > + if (!caldata[0] || callen < 2 * tmdev->chip->sensor_num) > > > > + return -EINVAL; > > > > + > > > > + for (i = 0; i < tmdev->chip->sensor_num; i++) { > > > > + int offset = (i % 2) << 4; > > > > + > > > > + regmap_update_bits(tmdev->regmap, > > > > + SUN8I_THS_TEMP_CALIB + (4 * (i >> 1)), > > > > + 0xfff << offset, > > > > + caldata[i] << offset); > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int sun50i_h6_ths_calibrate(struct ths_device *tmdev, > > > > + u16 *caldata, int callen) > > > > +{ > > > > + struct device *dev = tmdev->dev; > > > > + int i, ft_temp; > > > > + > > > > + if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num) > > > > + return -EINVAL; > > > > + > > > > + /* > > > > + * efuse layout: > > > > + * > > > > + * 0 11 16 32 > > > > + * +-------+-------+-------+ > > > > + * |temp| |sensor0|sensor1| > > > > + * +-------+-------+-------+ > > > > + * > > > > + * The calibration data on the H6 is the ambient temperature and > > > > + * sensor values that are filled during the factory test stage. > > > > + * > > > > + * The unit of stored FT temperature is 0.1 degreee celusis. > > > > + * > > > > + * We need to calculate a delta between measured and caluclated > > > > + * register values and this will become a calibration offset. > > > > + */ > > > > + ft_temp = (caldata[0] & FT_TEMP_MASK) * 100; > > > > + tmdev->cp_ft_flag = (caldata[0] & THS_EFUSE_CP_FT_MASK) > > > > + >> THS_EFUSE_CP_FT_BIT; > > > > > > Here got an unused data "cp_ft_flag", > > > which is used in the calculation of the temperature function according > > > to the source code. > > > > > > https://github.com/orangepi-xunlong/OrangePiH6_kernel/blob/master/drivers/thermal/sunxi_thermal/sunxi_ths_core.c#L392 > > > > It should be used to enable the addition of ft_deviation in > > sun8i_ths_get_temp(), I guess. Probably an ommission. I guess most of H6 > > chips will have this set anyway. > > > > > > + > > > > + for (i = 0; i < tmdev->chip->sensor_num; i++) { > > > > + int sensor_reg = caldata[i + 1]; > > > > + int cdata, offset; > > > > + int sensor_temp = tmdev->chip->calc_temp(tmdev, i, sensor_reg); > > > > + > > > > + /* > > > > + * Calibration data is CALIBRATE_DEFAULT - (calculated > > > > + * temperature from sensor reading at factory temperature > > > > + * minus actual factory temperature) * 14.88 (scale from > > > > + * temperature to register values) > > > > + */ > > > > + cdata = CALIBRATE_DEFAULT - > > > > + ((sensor_temp - ft_temp) * 10 / tmdev->chip->scale); > > > > > > Why change the formula here. > > > > > > https://github.com/orangepi-xunlong/OrangePiH6_kernel/blob/master/drivers/thermal/sunxi_thermal/sunxi_ths_core.c#L339 > > > > HI, > > I suggest keeping you as it was before this patch, just change this > place to this. > > cdata = CALIBRATE_DEFAULT - ((ft_temp * 100 - sensor_temp) / > tmdev->chip->scale); Hi, any reason for your suggestion? I also changed scale to be 10* specifically to allow it to be more precise when doing integer math, so that it more easily supports A83T's value. H6's scale value is also needlessly rounded too much without this change. With your suggestion, I'd have to round A83T's scale from 70.5 to either 70 or 71, but why? regards, o. > Yangtao > > > It looks the same to me as before. Here's the original patch: > > > > https://megous.com/git/linux/commit/?h=ths-5.4&id=cae28a7dfa6fc79ba37e31d4dff281947247e822 > > > > It's basicaly to avoid magic values TEMP_TO_REG and use what's defined > > in the chip struct. > > > > regards, > > o. > > > > > > + if (cdata & ~TEMP_CALIB_MASK) { > > > > + /* > > > > + * Calibration value more than 12-bit, but calibration > > > > + * register is 12-bit. In this case, ths hardware can > > > > + * still work without calibration, although the data > > > > + * won't be so accurate. > > > > + */ > > > > + dev_warn(dev, "sensor%d is not calibrated.\n", i); > > > > + continue; > > > > + } > > > > + > > > > + offset = (i % 2) * 16; > > > > + regmap_update_bits(tmdev->regmap, > > > > + SUN50I_H6_THS_TEMP_CALIB + (i / 2 * 4), > > > > + 0xfff << offset, > > > > + cdata << offset); > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int sun8i_ths_calibrate(struct ths_device *tmdev) > > > > +{ > > > > + struct nvmem_cell *calcell; > > > > + struct device *dev = tmdev->dev; > > > > + u16 *caldata; > > > > + size_t callen; > > > > + int ret = 0; > > > > + > > > > + calcell = devm_nvmem_cell_get(dev, "calibration"); > > > > + if (IS_ERR(calcell)) { > > > > + if (PTR_ERR(calcell) == -EPROBE_DEFER) > > > > + return -EPROBE_DEFER; > > > > + /* > > > > + * Even if the external calibration data stored in sid is > > > > + * not accessible, the THS hardware can still work, although > > > > + * the data won't be so accurate. > > > > + * > > > > + * The default value of calibration register is 0x800 for > > > > + * every sensor, and the calibration value is usually 0x7xx > > > > + * or 0x8xx, so they won't be away from the default value > > > > + * for a lot. > > > > + * > > > > + * So here we do not return error if the calibartion data is > > > > + * not available, except the probe needs deferring. > > > > + */ > > > > + goto out; > > > > + } > > > > + > > > > + caldata = nvmem_cell_read(calcell, &callen); > > > > + if (IS_ERR(caldata)) { > > > > + ret = PTR_ERR(caldata); > > > > + goto out; > > > > + } > > > > + > > > > + tmdev->chip->calibrate(tmdev, caldata, callen); > > > > + > > > > + kfree(caldata); > > > > +out: > > > > + return ret; > > > > +} > > > > + > > > > +static int sun8i_ths_resource_init(struct ths_device *tmdev) > > > > +{ > > > > + struct device *dev = tmdev->dev; > > > > + struct platform_device *pdev = to_platform_device(dev); > > > > + struct resource *mem; > > > > + void __iomem *base; > > > > + int ret; > > > > + > > > > + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > > > + base = devm_ioremap_resource(dev, mem); > > > > + if (IS_ERR(base)) > > > > + return PTR_ERR(base); > > > > + > > > > + tmdev->regmap = devm_regmap_init_mmio(dev, base, &config); > > > > + if (IS_ERR(tmdev->regmap)) > > > > + return PTR_ERR(tmdev->regmap); > > > > + > > > > + if (tmdev->chip->has_bus_clk_reset) { > > > > + tmdev->reset = devm_reset_control_get(dev, 0); > > > > + if (IS_ERR(tmdev->reset)) > > > > + return PTR_ERR(tmdev->reset); > > > > + > > > > + tmdev->bus_clk = devm_clk_get(&pdev->dev, "bus"); > > > > + if (IS_ERR(tmdev->bus_clk)) > > > > + return PTR_ERR(tmdev->bus_clk); > > > > + } > > > > + > > > > + if (tmdev->chip->has_mod_clk) { > > > > + tmdev->mod_clk = devm_clk_get(&pdev->dev, "mod"); > > > > + if (IS_ERR(tmdev->mod_clk)) > > > > + return PTR_ERR(tmdev->mod_clk); > > > > + } > > > > + > > > > + ret = reset_control_deassert(tmdev->reset); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + ret = clk_prepare_enable(tmdev->bus_clk); > > > > + if (ret) > > > > + goto assert_reset; > > > > + > > > > + ret = clk_set_rate(tmdev->mod_clk, 24000000); > > > > + if (ret) > > > > + goto bus_disable; > > > > + > > > > + ret = clk_prepare_enable(tmdev->mod_clk); > > > > + if (ret) > > > > + goto bus_disable; > > > > + > > > > + ret = sun8i_ths_calibrate(tmdev); > > > > + if (ret) > > > > + goto mod_disable; > > > > + > > > > + return 0; > > > > + > > > > +mod_disable: > > > > + clk_disable_unprepare(tmdev->mod_clk); > > > > +bus_disable: > > > > + clk_disable_unprepare(tmdev->bus_clk); > > > > +assert_reset: > > > > + reset_control_assert(tmdev->reset); > > > > + > > > > + return ret; > > > > +} > > > > + > > > > +static int sun8i_h3_thermal_init(struct ths_device *tmdev) > > > > +{ > > > > + int val; > > > > + > > > > + /* average over 4 samples */ > > > > + regmap_write(tmdev->regmap, SUN8I_THS_MFC, > > > > + SUN50I_THS_FILTER_EN | > > > > + SUN50I_THS_FILTER_TYPE(1)); > > > > + /* > > > > + * clkin = 24MHz > > > > + * filter_samples = 4 > > > > + * period = 0.25s > > > > + * > > > > + * x = period * clkin / 4096 / filter_samples - 1 > > > > + * = 365 > > > > + */ > > > > + val = GENMASK(7 + tmdev->chip->sensor_num, 8); > > > > + regmap_write(tmdev->regmap, SUN8I_THS_IC, > > > > + SUN50I_H6_THS_PC_TEMP_PERIOD(365) | val); > > > > + /* > > > > + * T_acq = 20us > > > > + * clkin = 24MHz > > > > + * > > > > + * x = T_acq * clkin - 1 > > > > + * = 479 > > > > + */ > > > > + regmap_write(tmdev->regmap, SUN8I_THS_CTRL0, > > > > + SUN8I_THS_CTRL0_T_ACQ0(479)); > > > > + val = GENMASK(tmdev->chip->sensor_num - 1, 0); > > > > + regmap_write(tmdev->regmap, SUN8I_THS_CTRL2, > > > > + SUN8I_THS_CTRL2_T_ACQ1(479) | val); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +/* > > > > + * Without this undocummented value, the returned temperatures would > > > > + * be higher than real ones by about 20C. > > > > + */ > > > > +#define SUN50I_H6_CTRL0_UNK 0x0000002f > > > > + > > > > +static int sun50i_h6_thermal_init(struct ths_device *tmdev) > > > > +{ > > > > + int val; > > > > + > > > > + /* > > > > + * T_acq = 20us > > > > + * clkin = 24MHz > > > > + * > > > > + * x = T_acq * clkin - 1 > > > > + * = 479 > > > > + */ > > > > + regmap_write(tmdev->regmap, SUN50I_THS_CTRL0, > > > > + SUN50I_H6_CTRL0_UNK | SUN50I_THS_CTRL0_T_ACQ(479)); > > > > + /* average over 4 samples */ > > > > + regmap_write(tmdev->regmap, SUN50I_H6_THS_MFC, > > > > + SUN50I_THS_FILTER_EN | > > > > + SUN50I_THS_FILTER_TYPE(1)); > > > > + /* > > > > + * clkin = 24MHz > > > > + * filter_samples = 4 > > > > + * period = 0.25s > > > > + * > > > > + * x = period * clkin / 4096 / filter_samples - 1 > > > > + * = 365 > > > > + */ > > > > + regmap_write(tmdev->regmap, SUN50I_H6_THS_PC, > > > > + SUN50I_H6_THS_PC_TEMP_PERIOD(365)); > > > > + /* enable sensor */ > > > > + val = GENMASK(tmdev->chip->sensor_num - 1, 0); > > > > + regmap_write(tmdev->regmap, SUN50I_H6_THS_ENABLE, val); > > > > + /* thermal data interrupt enable */ > > > > + val = GENMASK(tmdev->chip->sensor_num - 1, 0); > > > > + regmap_write(tmdev->regmap, SUN50I_H6_THS_DIC, val); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int sun8i_ths_register(struct ths_device *tmdev) > > > > +{ > > > > + int i; > > > > + > > > > + for (i = 0; i < tmdev->chip->sensor_num; i++) { > > > > + tmdev->sensor[i].tmdev = tmdev; > > > > + tmdev->sensor[i].id = i; > > > > + tmdev->sensor[i].tzd = > > > > + devm_thermal_zone_of_sensor_register(tmdev->dev, > > > > + i, > > > > + &tmdev->sensor[i], > > > > + &ths_ops); > > > > + if (IS_ERR(tmdev->sensor[i].tzd)) > > > > + return PTR_ERR(tmdev->sensor[i].tzd); > > > > + } > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static int sun8i_ths_probe(struct platform_device *pdev) > > > > +{ > > > > + struct ths_device *tmdev; > > > > + struct device *dev = &pdev->dev; > > > > + int ret, irq; > > > > + > > > > + tmdev = devm_kzalloc(dev, sizeof(*tmdev), GFP_KERNEL); > > > > + if (!tmdev) > > > > + return -ENOMEM; > > > > + > > > > + tmdev->dev = dev; > > > > + tmdev->chip = of_device_get_match_data(&pdev->dev); > > > > + if (!tmdev->chip) > > > > + return -EINVAL; > > > > + > > > > + platform_set_drvdata(pdev, tmdev); > > > > + > > > > + ret = sun8i_ths_resource_init(tmdev); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + irq = platform_get_irq(pdev, 0); > > > > + if (irq < 0) > > > > + return irq; > > > > + > > > > + ret = tmdev->chip->init(tmdev); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + ret = sun8i_ths_register(tmdev); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + /* > > > > + * Avoid entering the interrupt handler, the thermal device is not > > > > + * registered yet, we deffer the registration of the interrupt to > > > > + * the end. > > > > + */ > > > > + ret = devm_request_threaded_irq(dev, irq, NULL, > > > > + sun8i_irq_thread, > > > > + IRQF_ONESHOT, "ths", tmdev); > > > > + if (ret) > > > > + return ret; > > > > + > > > > + return ret; > > > > +} > > > > + > > > > +static int sun8i_ths_remove(struct platform_device *pdev) > > > > +{ > > > > + struct ths_device *tmdev = platform_get_drvdata(pdev); > > > > + > > > > + clk_disable_unprepare(tmdev->mod_clk); > > > > + clk_disable_unprepare(tmdev->bus_clk); > > > > + reset_control_assert(tmdev->reset); > > > > + > > > > + return 0; > > > > +} > > > > + > > > > +static const struct ths_thermal_chip sun8i_a83t_ths = { > > > > + .sensor_num = 3, > > > > + .scale = 705, > > > > + .offset = 191668, > > > > + .temp_data_base = SUN8I_THS_TEMP_DATA, > > > > + .calibrate = sun8i_h3_ths_calibrate, > > > > + .init = sun8i_h3_thermal_init, > > > > + .irq_ack = sun8i_h3_irq_ack, > > > > + .calc_temp = sun8i_ths_calc_temp, > > > > +}; > > > > + > > > > +static const struct ths_thermal_chip sun8i_h3_ths = { > > > > + .sensor_num = 1, > > > > + .scale = 1211, > > > > + .offset = 217000, > > > > + .has_mod_clk = true, > > > > + .has_bus_clk_reset = true, > > > > + .temp_data_base = SUN8I_THS_TEMP_DATA, > > > > + .calibrate = sun8i_h3_ths_calibrate, > > > > + .init = sun8i_h3_thermal_init, > > > > + .irq_ack = sun8i_h3_irq_ack, > > > > + .calc_temp = sun8i_ths_calc_temp, > > > > +}; > > > > + > > > > +static const struct ths_thermal_chip sun8i_r40_ths = { > > > > + .sensor_num = 3, > > > > + .offset = 251086, > > > > + .scale = 1130, > > > > + .has_mod_clk = true, > > > > + .has_bus_clk_reset = true, > > > > + .temp_data_base = SUN8I_THS_TEMP_DATA, > > > > + .calibrate = sun8i_h3_ths_calibrate, > > > > + .init = sun8i_h3_thermal_init, > > > > + .irq_ack = sun8i_h3_irq_ack, > > > > + .calc_temp = sun8i_ths_calc_temp, > > > > +}; > > > > + > > > > +static const struct ths_thermal_chip sun50i_a64_ths = { > > > > + .sensor_num = 3, > > > > + .offset = 253890, > > > > + .scale = 1170, > > > > + .has_mod_clk = true, > > > > + .has_bus_clk_reset = true, > > > > + .temp_data_base = SUN8I_THS_TEMP_DATA, > > > > + .calibrate = sun8i_h3_ths_calibrate, > > > > + .init = sun8i_h3_thermal_init, > > > > + .irq_ack = sun8i_h3_irq_ack, > > > > + .calc_temp = sun8i_ths_calc_temp, > > > > +}; > > > > + > > > > +static const struct ths_thermal_chip sun50i_h5_ths = { > > > > + .sensor_num = 2, > > > > + .has_mod_clk = true, > > > > + .has_bus_clk_reset = true, > > > > + .temp_data_base = SUN8I_THS_TEMP_DATA, > > > > + .calibrate = sun8i_h3_ths_calibrate, > > > > + .init = sun8i_h3_thermal_init, > > > > + .irq_ack = sun8i_h3_irq_ack, > > > > + .calc_temp = sun50i_h5_calc_temp, > > > > +}; > > > > + > > > > +static const struct ths_thermal_chip sun50i_h6_ths = { > > > > + .sensor_num = 2, > > > > + .has_bus_clk_reset = true, > > > > + .ft_deviation = 7000, > > > > + .offset = 187744, > > > > + .scale = 672, > > > > + .temp_data_base = SUN50I_H6_THS_TEMP_DATA, > > > > + .calibrate = sun50i_h6_ths_calibrate, > > > > + .init = sun50i_h6_thermal_init, > > > > + .irq_ack = sun50i_h6_irq_ack, > > > > + .calc_temp = sun8i_ths_calc_temp, > > > > +}; > > > > + > > > > +static const struct of_device_id of_ths_match[] = { > > > > + { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_a83t_ths }, > > > > + { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_ths }, > > > > + { .compatible = "allwinner,sun8i-r40-ths", .data = &sun8i_r40_ths }, > > > > + { .compatible = "allwinner,sun50i-a64-ths", .data = &sun50i_a64_ths }, > > > > + { .compatible = "allwinner,sun50i-h5-ths", .data = &sun50i_h5_ths }, > > > > + { .compatible = "allwinner,sun50i-h6-ths", .data = &sun50i_h6_ths }, > > > > + { /* sentinel */ }, > > > > +}; > > > > +MODULE_DEVICE_TABLE(of, of_ths_match); > > > > + > > > > +static struct platform_driver ths_driver = { > > > > + .probe = sun8i_ths_probe, > > > > + .remove = sun8i_ths_remove, > > > > + .driver = { > > > > + .name = "sun8i-thermal", > > > > + .of_match_table = of_ths_match, > > > > + }, > > > > +}; > > > > +module_platform_driver(ths_driver); > > > > + > > > > +MODULE_DESCRIPTION("Thermal sensor driver for Allwinner SOC"); > > > > +MODULE_LICENSE("GPL v2"); > > > > -- > > > > 2.24.0 > > > > > > > > > > Thx, > > > Yangtao > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel 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 X-Spam-Level: X-Spam-Status: No, score=-10.7 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_ADSP_ALL, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9B9DC432C0 for ; Mon, 2 Dec 2019 01:58:30 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id A4E102146E for ; Mon, 2 Dec 2019 01:58:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Di+CE67W"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=megous.com header.i=@megous.com header.b="iH7TvVm/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A4E102146E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=megous.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject: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=cmeix5nw9audteBAV9jo4J/lFwxDGDeowoGWrqjsr04=; b=Di+CE67WGRsu+a 8P4ae9l+pm4vcvRc2JzgVev0ediaOT4xxf0mqaDthhc8ejqIbSUbwK/F85BQRFeBKxiVWdkwzi1pB DX5u3slB20heN1gMh3kXQPPaNXn5k5GNwZ2+afdK16Ii/muaJw4r9k50yY4X4yglOR76ovfvlzkP5 ZYtuTLSlhL30WBu7tRyJVLYQ4xp2KwpFn5QbbJSdoYqduyHdRV54DnzHcIp29JOQjB+i9WalYp/Il DmXyYfjfbBiKEsgHetu17/ajSKykHM2yKY+gd7CUI4vx05vkqkon2HmXgCQwNxN48b81ev01kBMAu DOIAkA0uDzsITGXeuZqQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1ibayo-0001Xx-VF; Mon, 02 Dec 2019 01:58:26 +0000 Received: from vps.xff.cz ([195.181.215.36]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ibayj-0001Wv-Lh for linux-arm-kernel@lists.infradead.org; Mon, 02 Dec 2019 01:58:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=megous.com; s=mail; t=1575251896; bh=CaIhZzyVTFlNqKtL+qRE2ORuyG4z/Wb+57yrtwb/Ewg=; h=Date:From:To:Cc:Subject:References:X-My-GPG-KeyId:From; b=iH7TvVm/cFjFgZW8tcPgiJGkvoMKoVjI3XWsBKwE8MeYC0ly+ZCC35BzYhY+hN6rL oJ+8PVFUDgwcd13SFqAx+OxQa9cDcjKp5LZxLW4pp0qdiaLOHr7lT8Wag5/p2UIMky odaxTp7YL+O5V2SkJ8MKOWqq4zIVF+9+WpKMqdEk= Date: Mon, 2 Dec 2019 02:58:16 +0100 From: =?utf-8?Q?Ond=C5=99ej?= Jirman To: Frank Lee Subject: Re: [PATCH v6 1/7] thermal: sun8i: add thermal driver for H6/H5/H3/A64/A83T/R40 Message-ID: <20191202015816.amtz45fyd6h6pcqk@core.my.home> Mail-Followup-To: Frank Lee , Vasily Khoruzhick , Zhang Rui , Eduardo Valentin , Daniel Lezcano , Amit Kucheria , Rob Herring , Mark Rutland , Maxime Ripard , Chen-Yu Tsai , Mauro Carvalho Chehab , "David S. Miller" , Greg Kroah-Hartman , Linux PM , devicetree , Linux ARM , Linux Kernel Mailing List References: <20191127052935.1719897-1-anarsoul@gmail.com> <20191127052935.1719897-2-anarsoul@gmail.com> <20191128170626.xsm7xmizmbenqval@core.my.home> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-My-GPG-KeyId: EBFBDDE11FB918D44D1F56C1F9F0A873BE9777ED X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191201_175822_228865_10080610 X-CRM114-Status: GOOD ( 30.31 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Eduardo Valentin , Amit Kucheria , Linux PM , Greg Kroah-Hartman , Daniel Lezcano , Linux Kernel Mailing List , Maxime Ripard , Chen-Yu Tsai , Rob Herring , Linux ARM , Mauro Carvalho Chehab , Zhang Rui , "David S. Miller" , devicetree Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gRnJpLCBOb3YgMjksIDIwMTkgYXQgMDc6NDY6NThQTSArMDgwMCwgRnJhbmsgTGVlIHdyb3Rl Ogo+IE9uIEZyaSwgTm92IDI5LCAyMDE5IGF0IDE6MDYgQU0gT25kxZllaiBKaXJtYW4gPG1lZ291 c0BtZWdvdXMuY29tPiB3cm90ZToKPiA+Cj4gPiBPbiBGcmksIE5vdiAyOSwgMjAxOSBhdCAxMjo0 MzowMkFNICswODAwLCBGcmFuayBMZWUgd3JvdGU6Cj4gPiA+IEhJLAo+ID4gPgo+ID4gPiBJIHRv b2sgYSBjbG9zZXIgbG9vayBhdCBpdCwgYW5kIEkgaGFkIHNvbWUgcXVlc3Rpb25zIGFib3V0IHRo ZXNlIHBsYWNlcy4KPiA+ID4KPiA+ID4gT24gV2VkLCBOb3YgMjcsIDIwMTkgYXQgMTozMCBQTSBW YXNpbHkgS2hvcnV6aGljayA8YW5hcnNvdWxAZ21haWwuY29tPiB3cm90ZToKPiA+ID4gPgo+ID4g PiA+IEZyb206IFlhbmd0YW8gTGkgPHRpbnkud2luZHp6QGdtYWlsLmNvbT4KPiA+ID4gPgo+ID4g PiA+IFRoaXMgcGF0Y2ggYWRkcyB0aGUgc3VwcG9ydCBmb3IgYWxsd2lubmVyIHRoZXJtYWwgc2Vu c29yLCB3aXRoaW4KPiA+ID4gPiBhbGx3aW5uZXIgU29DLiBJdCB3aWxsIHJlZ2lzdGVyIHNlbnNv cnMgZm9yIHRoZXJtYWwgZnJhbWV3b3JrCj4gPiA+ID4gYW5kIHVzZSBkZXZpY2UgdHJlZSB0byBi aW5kIGNvb2xpbmcgZGV2aWNlLgo+ID4gPiA+Cj4gPiA+ID4gU2lnbmVkLW9mZi1ieTogWWFuZ3Rh byBMaSA8dGlueS53aW5kenpAZ21haWwuY29tPgo+ID4gPiA+IFNpZ25lZC1vZmYtYnk6IE9uZHJl aiBKaXJtYW4gPG1lZ291c0BtZWdvdXMuY29tPgo+ID4gPiA+IFNpZ25lZC1vZmYtYnk6IFZhc2ls eSBLaG9ydXpoaWNrIDxhbmFyc291bEBnbWFpbC5jb20+Cj4gPiA+ID4gLS0tCj4gPiA+ID4gIE1B SU5UQUlORVJTICAgICAgICAgICAgICAgICAgICAgfCAgIDcgKwo+ID4gPiA+ICBkcml2ZXJzL3Ro ZXJtYWwvS2NvbmZpZyAgICAgICAgIHwgIDE0ICsKPiA+ID4gPiAgZHJpdmVycy90aGVybWFsL01h a2VmaWxlICAgICAgICB8ICAgMSArCj4gPiA+ID4gIGRyaXZlcnMvdGhlcm1hbC9zdW44aV90aGVy bWFsLmMgfCA2NDMgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKPiA+ID4gPiAgNCBm aWxlcyBjaGFuZ2VkLCA2NjUgaW5zZXJ0aW9ucygrKQo+ID4gPiA+ICBjcmVhdGUgbW9kZSAxMDA2 NDQgZHJpdmVycy90aGVybWFsL3N1bjhpX3RoZXJtYWwuYwo+ID4gPiA+Cj4gPiA+ID4gZGlmZiAt LWdpdCBhL01BSU5UQUlORVJTIGIvTUFJTlRBSU5FUlMKPiA+ID4gPiBpbmRleCA2NmNjNTQ5YWMz MjcuLmRhMzRmM2YyZTgwYiAxMDA2NDQKPiA+ID4gPiAtLS0gYS9NQUlOVEFJTkVSUwo+ID4gPiA+ ICsrKyBiL01BSU5UQUlORVJTCj4gPiA+ID4gQEAgLTY4OCw2ICs2ODgsMTMgQEAgTDogbGludXgt Y3J5cHRvQHZnZXIua2VybmVsLm9yZwo+ID4gPiA+ICBTOiAgICAgTWFpbnRhaW5lZAo+ID4gPiA+ ICBGOiAgICAgZHJpdmVycy9jcnlwdG8vYWxsd2lubmVyLwo+ID4gPiA+Cj4gPiA+ID4gK0FMTFdJ Tk5FUiBUSEVSTUFMIERSSVZFUgo+ID4gPiA+ICtNOiAgICAgWWFuZ3RhbyBMaSA8dGlueS53aW5k enpAZ21haWwuY29tPgo+ID4gPiA+ICtMOiAgICAgbGludXgtcG1Admdlci5rZXJuZWwub3JnCj4g PiA+ID4gK1M6ICAgICBNYWludGFpbmVkCj4gPiA+ID4gK0Y6ICAgICBEb2N1bWVudGF0aW9uL2Rl dmljZXRyZWUvYmluZGluZ3MvdGhlcm1hbC9hbGx3aW5uZXIsc3VuOGktYTgzdC10aHMueWFtbAo+ ID4gPiA+ICtGOiAgICAgZHJpdmVycy90aGVybWFsL3N1bjhpX3RoZXJtYWwuYwo+ID4gPiA+ICsK PiA+ID4gPiAgQUxMV0lOTkVSIFZQVSBEUklWRVIKPiA+ID4gPiAgTTogICAgIE1heGltZSBSaXBh cmQgPG1yaXBhcmRAa2VybmVsLm9yZz4KPiA+ID4gPiAgTTogICAgIFBhdWwgS29jaWFsa293c2tp IDxwYXVsLmtvY2lhbGtvd3NraUBib290bGluLmNvbT4KPiA+ID4gPiBkaWZmIC0tZ2l0IGEvZHJp dmVycy90aGVybWFsL0tjb25maWcgYi9kcml2ZXJzL3RoZXJtYWwvS2NvbmZpZwo+ID4gPiA+IGlu ZGV4IDAwMWEyMWFiY2MyOC4uMGIwNDIyZTg5YWRiIDEwMDY0NAo+ID4gPiA+IC0tLSBhL2RyaXZl cnMvdGhlcm1hbC9LY29uZmlnCj4gPiA+ID4gKysrIGIvZHJpdmVycy90aGVybWFsL0tjb25maWcK PiA+ID4gPiBAQCAtMjYyLDYgKzI2MiwyMCBAQCBjb25maWcgU1BFQVJfVEhFUk1BTAo+ID4gPiA+ ICAgICAgICAgICBFbmFibGUgdGhpcyB0byBwbHVnIHRoZSBTUEVBciB0aGVybWFsIHNlbnNvciBk cml2ZXIgaW50byB0aGUgTGludXgKPiA+ID4gPiAgICAgICAgICAgdGhlcm1hbCBmcmFtZXdvcmsu Cj4gPiA+ID4KPiA+ID4gPiArY29uZmlnIFNVTjhJX1RIRVJNQUwKPiA+ID4gPiArICAgICAgIHRy aXN0YXRlICJBbGx3aW5uZXIgc3VuOGkgdGhlcm1hbCBkcml2ZXIiCj4gPiA+ID4gKyAgICAgICBk ZXBlbmRzIG9uIEFSQ0hfU1VOWEkgfHwgQ09NUElMRV9URVNUCj4gPiA+ID4gKyAgICAgICBkZXBl bmRzIG9uIEhBU19JT01FTQo+ID4gPiA+ICsgICAgICAgZGVwZW5kcyBvbiBOVk1FTQo+ID4gPiA+ ICsgICAgICAgZGVwZW5kcyBvbiBPRgo+ID4gPiA+ICsgICAgICAgZGVwZW5kcyBvbiBSRVNFVF9D T05UUk9MTEVSCj4gPiA+ID4gKyAgICAgICBoZWxwCj4gPiA+ID4gKyAgICAgICAgIFN1cHBvcnQg Zm9yIHRoZSBzdW44aSB0aGVybWFsIHNlbnNvciBkcml2ZXIgaW50byB0aGUgTGludXggdGhlcm1h bAo+ID4gPiA+ICsgICAgICAgICBmcmFtZXdvcmsuCj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAg ICBUbyBjb21waWxlIHRoaXMgZHJpdmVyIGFzIGEgbW9kdWxlLCBjaG9vc2UgTSBoZXJlOiB0aGUK PiA+ID4gPiArICAgICAgICAgbW9kdWxlIHdpbGwgYmUgY2FsbGVkIHN1bjhpLXRoZXJtYWwuCj4g PiA+ID4gKwo+ID4gPiA+ICBjb25maWcgUk9DS0NISVBfVEhFUk1BTAo+ID4gPiA+ICAgICAgICAg dHJpc3RhdGUgIlJvY2tjaGlwIHRoZXJtYWwgZHJpdmVyIgo+ID4gPiA+ICAgICAgICAgZGVwZW5k cyBvbiBBUkNIX1JPQ0tDSElQIHx8IENPTVBJTEVfVEVTVAo+ID4gPiA+IGRpZmYgLS1naXQgYS9k cml2ZXJzL3RoZXJtYWwvTWFrZWZpbGUgYi9kcml2ZXJzL3RoZXJtYWwvTWFrZWZpbGUKPiA+ID4g PiBpbmRleCA3NGEzN2M3Zjg0N2EuLmZhNmY4YjIwNjI4MSAxMDA2NDQKPiA+ID4gPiAtLS0gYS9k cml2ZXJzL3RoZXJtYWwvTWFrZWZpbGUKPiA+ID4gPiArKysgYi9kcml2ZXJzL3RoZXJtYWwvTWFr ZWZpbGUKPiA+ID4gPiBAQCAtMzEsNiArMzEsNyBAQCB0aGVybWFsX3N5cy0kKENPTkZJR19ERVZG UkVRX1RIRVJNQUwpICs9IGRldmZyZXFfY29vbGluZy5vCj4gPiA+ID4gIG9iai15ICAgICAgICAg ICAgICAgICAgICAgICAgICArPSBicm9hZGNvbS8KPiA+ID4gPiAgb2JqLSQoQ09ORklHX1RIRVJN QUxfTU1JTykgICAgICAgICAgICAgKz0gdGhlcm1hbF9tbWlvLm8KPiA+ID4gPiAgb2JqLSQoQ09O RklHX1NQRUFSX1RIRVJNQUwpICAgICs9IHNwZWFyX3RoZXJtYWwubwo+ID4gPiA+ICtvYmotJChD T05GSUdfU1VOOElfVEhFUk1BTCkgICAgICs9IHN1bjhpX3RoZXJtYWwubwo+ID4gPiA+ICBvYmot JChDT05GSUdfUk9DS0NISVBfVEhFUk1BTCkgKz0gcm9ja2NoaXBfdGhlcm1hbC5vCj4gPiA+ID4g IG9iai0kKENPTkZJR19SQ0FSX1RIRVJNQUwpICAgICArPSByY2FyX3RoZXJtYWwubwo+ID4gPiA+ ICBvYmotJChDT05GSUdfUkNBUl9HRU4zX1RIRVJNQUwpICAgICAgICArPSByY2FyX2dlbjNfdGhl cm1hbC5vCj4gPiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdGhlcm1hbC9zdW44aV90aGVybWFs LmMgYi9kcml2ZXJzL3RoZXJtYWwvc3VuOGlfdGhlcm1hbC5jCj4gPiA+ID4gbmV3IGZpbGUgbW9k ZSAxMDA2NDQKPiA+ID4gPiBpbmRleCAwMDAwMDAwMDAwMDAuLmU4NmI2NGY1MTE5Ngo+ID4gPiA+ IC0tLSAvZGV2L251bGwKPiA+ID4gPiArKysgYi9kcml2ZXJzL3RoZXJtYWwvc3VuOGlfdGhlcm1h bC5jCj4gPiA+ID4gQEAgLTAsMCArMSw2NDMgQEAKPiA+ID4gPiArLy8gU1BEWC1MaWNlbnNlLUlk ZW50aWZpZXI6IEdQTC0yLjAKPiA+ID4gPiArLyoKPiA+ID4gPiArICogVGhlcm1hbCBzZW5zb3Ig ZHJpdmVyIGZvciBBbGx3aW5uZXIgU09DCj4gPiA+ID4gKyAqIENvcHlyaWdodCAoQykgMjAxOSBZ YW5ndGFvIExpCj4gPiA+ID4gKyAqCj4gPiA+ID4gKyAqIEJhc2VkIG9uIHRoZSB3b3JrIG9mIElj ZW5vd3kgWmhlbmcgPGljZW5vd3lAYW9zYy5pbz4KPiA+ID4gPiArICogQmFzZWQgb24gdGhlIHdv cmsgb2YgT25kcmVqIEppcm1hbiA8bWVnb3VzQG1lZ291cy5jb20+Cj4gPiA+ID4gKyAqIEJhc2Vk IG9uIHRoZSB3b3JrIG9mIEpvc2VmIEdhamR1c2VrIDxhdHhAYXR4Lm5hbWU+Cj4gPiA+ID4gKyAq Lwo+ID4gPiA+ICsKPiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+ID4gPiA+ICsjaW5j bHVkZSA8bGludXgvZGV2aWNlLmg+Cj4gPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQu aD4KPiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8 bGludXgvbnZtZW0tY29uc3VtZXIuaD4KPiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L29mX2Rldmlj ZS5oPgo+ID4gPiA+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gPiA+ID4g KyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4KPiA+ID4gPiArI2luY2x1ZGUgPGxpbnV4L3Jlc2V0 Lmg+Cj4gPiA+ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+Cj4gPiA+ID4gKyNpbmNsdWRlIDxs aW51eC90aGVybWFsLmg+Cj4gPiA+ID4gKwo+ID4gPiA+ICsjZGVmaW5lIE1BWF9TRU5TT1JfTlVN IDQKPiA+ID4gPiArCj4gPiA+ID4gKyNkZWZpbmUgRlRfVEVNUF9NQVNLICAgICAgICAgICAgICAg ICAgICAgICAgICAgR0VOTUFTSygxMSwgMCkKPiA+ID4gPiArI2RlZmluZSBURU1QX0NBTElCX01B U0sgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdFTk1BU0soMTEsIDApCj4gPiA+ID4g KyNkZWZpbmUgQ0FMSUJSQVRFX0RFRkFVTFQgICAgICAgICAgICAgICAgICAgICAgMHg4MDAKPiA+ ID4gPiArCj4gPiA+ID4gKyNkZWZpbmUgU1VOOElfVEhTX0NUUkwwICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAweDAwCj4gPiA+ID4gKyNkZWZpbmUgU1VOOElfVEhTX0NUUkwyICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAweDQwCj4gPiA+ID4gKyNkZWZpbmUgU1VOOElfVEhT X0lDICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0NAo+ID4gPiA+ICsjZGVmaW5lIFNVTjhJ X1RIU19JUyAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDgKPiA+ID4gPiArI2RlZmluZSBT VU44SV9USFNfTUZDICAgICAgICAgICAgICAgICAgICAgICAgICAweDcwCj4gPiA+ID4gKyNkZWZp bmUgU1VOOElfVEhTX1RFTVBfQ0FMSUIgICAgICAgICAgICAgICAgICAgMHg3NAo+ID4gPiA+ICsj ZGVmaW5lIFNVTjhJX1RIU19URU1QX0RBVEEgICAgICAgICAgICAgICAgICAgIDB4ODAKPiA+ID4g PiArCj4gPiA+ID4gKyNkZWZpbmUgU1VONTBJX1RIU19DVFJMMCAgICAgICAgICAgICAgICAgICAg ICAgMHgwMAo+ID4gPiA+ICsjZGVmaW5lIFNVTjUwSV9INl9USFNfRU5BQkxFICAgICAgICAgICAg ICAgICAgIDB4MDQKPiA+ID4gPiArI2RlZmluZSBTVU41MElfSDZfVEhTX1BDICAgICAgICAgICAg ICAgICAgICAgICAweDA4Cj4gPiA+ID4gKyNkZWZpbmUgU1VONTBJX0g2X1RIU19ESUMgICAgICAg ICAgICAgICAgICAgICAgMHgxMAo+ID4gPiA+ICsjZGVmaW5lIFNVTjUwSV9INl9USFNfRElTICAg ICAgICAgICAgICAgICAgICAgIDB4MjAKPiA+ID4gPiArI2RlZmluZSBTVU41MElfSDZfVEhTX01G QyAgICAgICAgICAgICAgICAgICAgICAweDMwCj4gPiA+ID4gKyNkZWZpbmUgU1VONTBJX0g2X1RI U19URU1QX0NBTElCICAgICAgICAgICAgICAgMHhhMAo+ID4gPiA+ICsjZGVmaW5lIFNVTjUwSV9I Nl9USFNfVEVNUF9EQVRBICAgICAgICAgICAgICAgICAgICAgICAgMHhjMAo+ID4gPiA+ICsKPiA+ ID4gPiArI2RlZmluZSBTVU44SV9USFNfQ1RSTDBfVF9BQ1EwKHgpICAgICAgICAgICAgICAoR0VO TUFTSygxNSwgMCkgJiAoeCkpCj4gPiA+ID4gKyNkZWZpbmUgU1VOOElfVEhTX0NUUkwyX1RfQUNR MSh4KSAgICAgICAgICAgICAgKChHRU5NQVNLKDE1LCAwKSAmICh4KSkgPDwgMTYpCj4gPiA+ID4g KyNkZWZpbmUgU1VOOElfVEhTX0RBVEFfSVJRX1NUUyh4KSAgICAgICAgICAgICAgQklUKHggKyA4 KQo+ID4gPiA+ICsKPiA+ID4gPiArI2RlZmluZSBTVU41MElfVEhTX0NUUkwwX1RfQUNRKHgpICAg ICAgICAgICAgICAoKEdFTk1BU0soMTUsIDApICYgKHgpKSA8PCAxNikKPiA+ID4gPiArI2RlZmlu ZSBTVU41MElfVEhTX0ZJTFRFUl9FTiAgICAgICAgICAgICAgICAgICBCSVQoMikKPiA+ID4gPiAr I2RlZmluZSBTVU41MElfVEhTX0ZJTFRFUl9UWVBFKHgpICAgICAgICAgICAgICAoR0VOTUFTSygx LCAwKSAmICh4KSkKPiA+ID4gPiArI2RlZmluZSBTVU41MElfSDZfVEhTX1BDX1RFTVBfUEVSSU9E KHgpICAgICAgICAgICAgICAgICgoR0VOTUFTSygxOSwgMCkgJiAoeCkpIDw8IDEyKQo+ID4gPiA+ ICsjZGVmaW5lIFNVTjUwSV9INl9USFNfREFUQV9JUlFfU1RTKHgpICAgICAgICAgIEJJVCh4KQo+ ID4gPiA+ICsKPiA+ID4gPiArLyogbWlsbGlkZWdyZWUgY2Vsc2l1cyAqLwo+ID4gPiA+ICsjZGVm aW5lIFRIU19FRlVTRV9DUF9GVF9NQVNLICAgICAgICAgICAgICAgICAgIDB4MzAwMAo+ID4gPiA+ ICsjZGVmaW5lIFRIU19FRlVTRV9DUF9GVF9CSVQgICAgICAgICAgICAgICAgICAgIDEyCj4gPiA+ ID4gKyNkZWZpbmUgVEhTX0NBTElCUkFUSU9OX0lOX0ZUICAgICAgICAgICAgICAgICAgMQo+ID4g PiA+ICsKPiA+ID4gPiArc3RydWN0IHRoc19kZXZpY2U7Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdHJ1 Y3QgdHNlbnNvciB7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgdGhzX2RldmljZSAgICAgICAgICAg ICAgICp0bWRldjsKPiA+ID4gPiArICAgICAgIHN0cnVjdCB0aGVybWFsX3pvbmVfZGV2aWNlICAg ICAgKnR6ZDsKPiA+ID4gPiArICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAg aWQ7Cj4gPiA+ID4gK307Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdHJ1Y3QgdGhzX3RoZXJtYWxfY2hp cCB7Cj4gPiA+ID4gKyAgICAgICBib29sICAgICAgICAgICAgaGFzX21vZF9jbGs7Cj4gPiA+ID4g KyAgICAgICBib29sICAgICAgICAgICAgaGFzX2J1c19jbGtfcmVzZXQ7Cj4gPiA+ID4gKyAgICAg ICBpbnQgICAgICAgICAgICAgc2Vuc29yX251bTsKPiA+ID4gPiArICAgICAgIGludCAgICAgICAg ICAgICBvZmZzZXQ7Cj4gPiA+ID4gKyAgICAgICBpbnQgICAgICAgICAgICAgc2NhbGU7Cj4gPiA+ ID4gKyAgICAgICBpbnQgICAgICAgICAgICAgZnRfZGV2aWF0aW9uOwo+ID4gPiA+ICsgICAgICAg aW50ICAgICAgICAgICAgIHRlbXBfZGF0YV9iYXNlOwo+ID4gPiA+ICsgICAgICAgaW50ICAgICAg ICAgICAgICgqY2FsaWJyYXRlKShzdHJ1Y3QgdGhzX2RldmljZSAqdG1kZXYsCj4gPiA+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHUxNiAqY2FsZGF0YSwgaW50IGNhbGxl bik7Cj4gPiA+ID4gKyAgICAgICBpbnQgICAgICAgICAgICAgKCppbml0KShzdHJ1Y3QgdGhzX2Rl dmljZSAqdG1kZXYpOwo+ID4gPiA+ICsgICAgICAgaW50ICAgICAgICAgICAgICgqaXJxX2Fjayko c3RydWN0IHRoc19kZXZpY2UgKnRtZGV2KTsKPiA+ID4gPiArICAgICAgIGludCAgICAgICAgICAg ICAoKmNhbGNfdGVtcCkoc3RydWN0IHRoc19kZXZpY2UgKnRtZGV2LAo+ID4gPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaWQsIGludCByZWcpOwo+ID4gPiA+ICt9 Owo+ID4gPiA+ICsKPiA+ID4gPiArc3RydWN0IHRoc19kZXZpY2Ugewo+ID4gPiA+ICsgICAgICAg Y29uc3Qgc3RydWN0IHRoc190aGVybWFsX2NoaXAgICAgICAgICAgICpjaGlwOwo+ID4gPiA+ICsg ICAgICAgc3RydWN0IGRldmljZSAgICAgICAgICAgICAgICAgICAgICAgICAgICpkZXY7Cj4gPiA+ ID4gKyAgICAgICBzdHJ1Y3QgcmVnbWFwICAgICAgICAgICAgICAgICAgICAgICAgICAgKnJlZ21h cDsKPiA+ID4gPiArICAgICAgIHN0cnVjdCByZXNldF9jb250cm9sICAgICAgICAgICAgICAgICAg ICAqcmVzZXQ7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgY2xrICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgKmJ1c19jbGs7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgY2xrICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgKm1vZF9jbGs7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgdHNlbnNv ciAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vuc29yW01BWF9TRU5TT1JfTlVNXTsKPiA+ID4g PiArICAgICAgIHUzMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcF9mdF9m bGFnOwo+ID4gPiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArLyogVGVtcCBVbml0OiBtaWxsaWRl Z3JlZSBDZWxzaXVzICovCj4gPiA+ID4gK3N0YXRpYyBpbnQgc3VuOGlfdGhzX2NhbGNfdGVtcChz dHJ1Y3QgdGhzX2RldmljZSAqdG1kZXYsCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIGludCBpZCwgaW50IHJlZykKPiA+ID4gPiArewo+ID4gPiA+ICsgICAgICAgcmV0dXJu IHRtZGV2LT5jaGlwLT5vZmZzZXQgLSAocmVnICogdG1kZXYtPmNoaXAtPnNjYWxlIC8gMTApOwo+ ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50IHN1bjUwaV9oNV9jYWxjX3Rl bXAoc3RydWN0IHRoc19kZXZpY2UgKnRtZGV2LAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBpbnQgaWQsIGludCByZWcpCj4gPiA+ID4gK3sKPiA+ID4gPiArICAgICAgIGlm IChyZWcgPj0gMHg1MDApCj4gPiA+ID4gKyAgICAgICAgICAgICAgIHJldHVybiAtMTE5MSAqIHJl ZyAvIDEwICsgMjIzMDAwOwo+ID4gPiA+ICsgICAgICAgZWxzZSBpZiAoIWlkKQo+ID4gPiA+ICsg ICAgICAgICAgICAgICByZXR1cm4gLTE0NTIgKiByZWcgLyAxMCArIDI1OTAwMDsKPiA+ID4gPiAr ICAgICAgIGVsc2UKPiA+ID4gPiArICAgICAgICAgICAgICAgcmV0dXJuIC0xNTkwICogcmVnIC8g MTAgKyAyNzYwMDA7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgc3Vu OGlfdGhzX2dldF90ZW1wKHZvaWQgKmRhdGEsIGludCAqdGVtcCkKPiA+ID4gPiArewo+ID4gPiA+ ICsgICAgICAgc3RydWN0IHRzZW5zb3IgKnMgPSBkYXRhOwo+ID4gPiA+ICsgICAgICAgc3RydWN0 IHRoc19kZXZpY2UgKnRtZGV2ID0gcy0+dG1kZXY7Cj4gPiA+ID4gKyAgICAgICBpbnQgdmFsID0g MDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICByZWdtYXBfcmVhZCh0bWRldi0+cmVnbWFwLCB0 bWRldi0+Y2hpcC0+dGVtcF9kYXRhX2Jhc2UgKwo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAg MHg0ICogcy0+aWQsICZ2YWwpOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIC8qIHRocyBoYXZl IG5vIGRhdGEgeWV0ICovCj4gPiA+ID4gKyAgICAgICBpZiAoIXZhbCkKPiA+ID4gPiArICAgICAg ICAgICAgICAgcmV0dXJuIC1FQUdBSU47Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAgKnRlbXAg PSB0bWRldi0+Y2hpcC0+Y2FsY190ZW1wKHRtZGV2LCBzLT5pZCwgdmFsKTsKPiA+ID4gPiArICAg ICAgIC8qCj4gPiA+ID4gKyAgICAgICAgKiBBY2NvcmRpbmcgdG8gdGhlIG9yaWdpbmFsIHNkaywg dGhlcmUgYXJlIHNvbWUgcGxhdGZvcm1zKHJhcmVseSkKPiA+ID4gPiArICAgICAgICAqIHRoYXQg YWRkIGEgZml4ZWQgb2Zmc2V0IHZhbHVlIGFmdGVyIGNhbGN1bGF0aW5nIHRoZSB0ZW1wZXJhdHVy ZQo+ID4gPiA+ICsgICAgICAgICogdmFsdWUuIFdlIGNhbid0IHNpbXBseSBwdXQgaXQgb24gdGhl IGZvcm11bGEgZm9yIGNhbGN1bGF0aW5nIHRoZQo+ID4gPiA+ICsgICAgICAgICogdGVtcGVyYXR1 cmUgYWJvdmUsIGJlY2F1c2UgdGhlIGZvcm11bGEgZm9yIGNhbGN1bGF0aW5nIHRoZQo+ID4gPiA+ ICsgICAgICAgICogdGVtcGVyYXR1cmUgYWJvdmUgaXMgYWxzbyB1c2VkIHdoZW4gdGhlIHNlbnNv ciBpcyBjYWxpYnJhdGVkLiBJZgo+ID4gPiA+ICsgICAgICAgICogZG8gdGhpcywgdGhlIGNvcnJl Y3QgY2FsaWJyYXRpb24gZm9ybXVsYSBpcyBoYXJkIHRvIGtub3cuCj4gPiA+ID4gKyAgICAgICAg Ki8KPiA+ID4gPiArICAgICAgICp0ZW1wICs9IHRtZGV2LT5jaGlwLT5mdF9kZXZpYXRpb247Cj4g PiA+ID4gKwo+ID4gPiA+ICsgICAgICAgcmV0dXJuIDA7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4g PiA+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdGhlcm1hbF96b25lX29mX2RldmljZV9vcHMgdGhz X29wcyA9IHsKPiA+ID4gPiArICAgICAgIC5nZXRfdGVtcCA9IHN1bjhpX3Roc19nZXRfdGVtcCwK PiA+ID4gPiArfTsKPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgcmVnbWFw X2NvbmZpZyBjb25maWcgPSB7Cj4gPiA+ID4gKyAgICAgICAucmVnX2JpdHMgPSAzMiwKPiA+ID4g PiArICAgICAgIC52YWxfYml0cyA9IDMyLAo+ID4gPiA+ICsgICAgICAgLnJlZ19zdHJpZGUgPSA0 LAo+ID4gPiA+ICsgICAgICAgLmZhc3RfaW8gPSB0cnVlLAo+ID4gPiA+ICsgICAgICAgLm1heF9y ZWdpc3RlciA9IDB4ZmMsCj4gPiA+ID4gK307Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50 IHN1bjhpX2gzX2lycV9hY2soc3RydWN0IHRoc19kZXZpY2UgKnRtZGV2KQo+ID4gPiA+ICt7Cj4g PiA+ID4gKyAgICAgICBpbnQgaSwgc3RhdGUsIHJldCA9IDA7Cj4gPiA+ID4gKwo+ID4gPiA+ICsg ICAgICAgcmVnbWFwX3JlYWQodG1kZXYtPnJlZ21hcCwgU1VOOElfVEhTX0lTLCAmc3RhdGUpOwo+ ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIGZvciAoaSA9IDA7IGkgPCB0bWRldi0+Y2hpcC0+c2Vu c29yX251bTsgaSsrKSB7Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIGlmIChzdGF0ZSAmIFNVTjhJ X1RIU19EQVRBX0lSUV9TVFMoaSkpIHsKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICBy ZWdtYXBfd3JpdGUodG1kZXYtPnJlZ21hcCwgU1VOOElfVEhTX0lTLAo+ID4gPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVU44SV9USFNfREFUQV9JUlFfU1RTKGkpKTsK PiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICByZXQgfD0gQklUKGkpOwo+ID4gPiA+ICsg ICAgICAgICAgICAgICB9Cj4gPiA+ID4gKyAgICAgICB9Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAg ICAgcmV0dXJuIHJldDsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGludCBz dW41MGlfaDZfaXJxX2FjayhzdHJ1Y3QgdGhzX2RldmljZSAqdG1kZXYpCj4gPiA+ID4gK3sKPiA+ ID4gPiArICAgICAgIGludCBpLCBzdGF0ZSwgcmV0ID0gMDsKPiA+ID4gPiArCj4gPiA+ID4gKyAg ICAgICByZWdtYXBfcmVhZCh0bWRldi0+cmVnbWFwLCBTVU41MElfSDZfVEhTX0RJUywgJnN0YXRl KTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgdG1kZXYtPmNoaXAt PnNlbnNvcl9udW07IGkrKykgewo+ID4gPiA+ICsgICAgICAgICAgICAgICBpZiAoc3RhdGUgJiBT VU41MElfSDZfVEhTX0RBVEFfSVJRX1NUUyhpKSkgewo+ID4gPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgIHJlZ21hcF93cml0ZSh0bWRldi0+cmVnbWFwLCBTVU41MElfSDZfVEhTX0RJUywKPiA+ ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1VONTBJX0g2X1RIU19E QVRBX0lSUV9TVFMoaSkpOwo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldCB8PSBC SVQoaSk7Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIH0KPiA+ID4gPiArICAgICAgIH0KPiA+ID4g PiArCj4gPiA+ID4gKyAgICAgICByZXR1cm4gcmV0Owo+ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4g PiA+ICtzdGF0aWMgaXJxcmV0dXJuX3Qgc3VuOGlfaXJxX3RocmVhZChpbnQgaXJxLCB2b2lkICpk YXRhKQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgdGhzX2RldmljZSAqdG1kZXYg PSBkYXRhOwo+ID4gPiA+ICsgICAgICAgaW50IGksIHN0YXRlOwo+ID4gPiA+ICsKPiA+ID4gPiAr ICAgICAgIHN0YXRlID0gdG1kZXYtPmNoaXAtPmlycV9hY2sodG1kZXYpOwo+ID4gPiA+ICsKPiA+ ID4gPiArICAgICAgIGZvciAoaSA9IDA7IGkgPCB0bWRldi0+Y2hpcC0+c2Vuc29yX251bTsgaSsr KSB7Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIGlmIChzdGF0ZSAmIEJJVChpKSkKPiA+ID4gPiAr ICAgICAgICAgICAgICAgICAgICAgICB0aGVybWFsX3pvbmVfZGV2aWNlX3VwZGF0ZSh0bWRldi0+ c2Vuc29yW2ldLnR6ZCwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBUSEVSTUFMX0VWRU5UX1VOU1BFQ0lGSUVEKTsKPiA+ID4gPiArICAg ICAgIH0KPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICByZXR1cm4gSVJRX0hBTkRMRUQ7Cj4gPiA+ ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgc3VuOGlfaDNfdGhzX2NhbGlicmF0 ZShzdHJ1Y3QgdGhzX2RldmljZSAqdG1kZXYsCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHUxNiAqY2FsZGF0YSwgaW50IGNhbGxlbikKPiA+ID4gPiArewo+ID4gPiA+ ICsgICAgICAgaW50IGk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAgaWYgKCFjYWxkYXRhWzBd IHx8IGNhbGxlbiA8IDIgKiB0bWRldi0+Y2hpcC0+c2Vuc29yX251bSkKPiA+ID4gPiArICAgICAg ICAgICAgICAgcmV0dXJuIC1FSU5WQUw7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAgZm9yIChp ID0gMDsgaSA8IHRtZGV2LT5jaGlwLT5zZW5zb3JfbnVtOyBpKyspIHsKPiA+ID4gPiArICAgICAg ICAgICAgICAgaW50IG9mZnNldCA9IChpICUgMikgPDwgNDsKPiA+ID4gPiArCj4gPiA+ID4gKyAg ICAgICAgICAgICAgIHJlZ21hcF91cGRhdGVfYml0cyh0bWRldi0+cmVnbWFwLAo+ID4gPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1VOOElfVEhTX1RFTVBfQ0FMSUIgKyAo NCAqIChpID4+IDEpKSwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IDB4ZmZmIDw8IG9mZnNldCwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIGNhbGRhdGFbaV0gPDwgb2Zmc2V0KTsKPiA+ID4gPiArICAgICAgIH0KPiA+ID4gPiArCj4g PiA+ID4gKyAgICAgICByZXR1cm4gMDsKPiA+ID4gPiArfQo+ID4gPiA+ICsKPiA+ID4gPiArc3Rh dGljIGludCBzdW41MGlfaDZfdGhzX2NhbGlicmF0ZShzdHJ1Y3QgdGhzX2RldmljZSAqdG1kZXYs Cj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1MTYgKmNhbGRhdGEs IGludCBjYWxsZW4pCj4gPiA+ID4gK3sKPiA+ID4gPiArICAgICAgIHN0cnVjdCBkZXZpY2UgKmRl diA9IHRtZGV2LT5kZXY7Cj4gPiA+ID4gKyAgICAgICBpbnQgaSwgZnRfdGVtcDsKPiA+ID4gPiAr Cj4gPiA+ID4gKyAgICAgICBpZiAoIWNhbGRhdGFbMF0gfHwgY2FsbGVuIDwgMiArIDIgKiB0bWRl di0+Y2hpcC0+c2Vuc29yX251bSkKPiA+ID4gPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5W QUw7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAgLyoKPiA+ID4gPiArICAgICAgICAqIGVmdXNl IGxheW91dDoKPiA+ID4gPiArICAgICAgICAqCj4gPiA+ID4gKyAgICAgICAgKiAgICAgIDAgICAx MSAgMTYgICAgICAgMzIKPiA+ID4gPiArICAgICAgICAqICAgICAgKy0tLS0tLS0rLS0tLS0tLSst LS0tLS0tKwo+ID4gPiA+ICsgICAgICAgICogICAgICB8dGVtcHwgIHxzZW5zb3IwfHNlbnNvcjF8 Cj4gPiA+ID4gKyAgICAgICAgKiAgICAgICstLS0tLS0tKy0tLS0tLS0rLS0tLS0tLSsKPiA+ID4g PiArICAgICAgICAqCj4gPiA+ID4gKyAgICAgICAgKiBUaGUgY2FsaWJyYXRpb24gZGF0YSBvbiB0 aGUgSDYgaXMgdGhlIGFtYmllbnQgdGVtcGVyYXR1cmUgYW5kCj4gPiA+ID4gKyAgICAgICAgKiBz ZW5zb3IgdmFsdWVzIHRoYXQgYXJlIGZpbGxlZCBkdXJpbmcgdGhlIGZhY3RvcnkgdGVzdCBzdGFn ZS4KPiA+ID4gPiArICAgICAgICAqCj4gPiA+ID4gKyAgICAgICAgKiBUaGUgdW5pdCBvZiBzdG9y ZWQgRlQgdGVtcGVyYXR1cmUgaXMgMC4xIGRlZ3JlZWUgY2VsdXNpcy4KPiA+ID4gPiArICAgICAg ICAqCj4gPiA+ID4gKyAgICAgICAgKiBXZSBuZWVkIHRvIGNhbGN1bGF0ZSBhIGRlbHRhIGJldHdl ZW4gbWVhc3VyZWQgYW5kIGNhbHVjbGF0ZWQKPiA+ID4gPiArICAgICAgICAqIHJlZ2lzdGVyIHZh bHVlcyBhbmQgdGhpcyB3aWxsIGJlY29tZSBhIGNhbGlicmF0aW9uIG9mZnNldC4KPiA+ID4gPiAr ICAgICAgICAqLwo+ID4gPiA+ICsgICAgICAgZnRfdGVtcCA9IChjYWxkYXRhWzBdICYgRlRfVEVN UF9NQVNLKSAqIDEwMDsKPiA+ID4gPiArICAgICAgIHRtZGV2LT5jcF9mdF9mbGFnID0gKGNhbGRh dGFbMF0gJiBUSFNfRUZVU0VfQ1BfRlRfTUFTSykKPiA+ID4gPiArICAgICAgICAgICAgICAgPj4g VEhTX0VGVVNFX0NQX0ZUX0JJVDsKPiA+ID4KPiA+ID4gSGVyZSBnb3QgYW4gdW51c2VkIGRhdGEg ImNwX2Z0X2ZsYWciLAo+ID4gPiB3aGljaCBpcyB1c2VkIGluIHRoZSBjYWxjdWxhdGlvbiBvZiB0 aGUgdGVtcGVyYXR1cmUgZnVuY3Rpb24gYWNjb3JkaW5nCj4gPiA+IHRvIHRoZSBzb3VyY2UgY29k ZS4KPiA+ID4KPiA+ID4gaHR0cHM6Ly9naXRodWIuY29tL29yYW5nZXBpLXh1bmxvbmcvT3Jhbmdl UGlINl9rZXJuZWwvYmxvYi9tYXN0ZXIvZHJpdmVycy90aGVybWFsL3N1bnhpX3RoZXJtYWwvc3Vu eGlfdGhzX2NvcmUuYyNMMzkyCj4gPgo+ID4gSXQgc2hvdWxkIGJlIHVzZWQgdG8gZW5hYmxlIHRo ZSBhZGRpdGlvbiBvZiBmdF9kZXZpYXRpb24gaW4KPiA+IHN1bjhpX3Roc19nZXRfdGVtcCgpLCBJ IGd1ZXNzLiBQcm9iYWJseSBhbiBvbW1pc3Npb24uIEkgZ3Vlc3MgbW9zdCBvZiBINgo+ID4gY2hp cHMgd2lsbCBoYXZlIHRoaXMgc2V0IGFueXdheS4KPiA+Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAg ICAgZm9yIChpID0gMDsgaSA8IHRtZGV2LT5jaGlwLT5zZW5zb3JfbnVtOyBpKyspIHsKPiA+ID4g PiArICAgICAgICAgICAgICAgaW50IHNlbnNvcl9yZWcgPSBjYWxkYXRhW2kgKyAxXTsKPiA+ID4g PiArICAgICAgICAgICAgICAgaW50IGNkYXRhLCBvZmZzZXQ7Cj4gPiA+ID4gKyAgICAgICAgICAg ICAgIGludCBzZW5zb3JfdGVtcCA9IHRtZGV2LT5jaGlwLT5jYWxjX3RlbXAodG1kZXYsIGksIHNl bnNvcl9yZWcpOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgICAgICAgICAgLyoKPiA+ID4gPiAr ICAgICAgICAgICAgICAgICogQ2FsaWJyYXRpb24gZGF0YSBpcyBDQUxJQlJBVEVfREVGQVVMVCAt IChjYWxjdWxhdGVkCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAqIHRlbXBlcmF0dXJlIGZyb20g c2Vuc29yIHJlYWRpbmcgYXQgZmFjdG9yeSB0ZW1wZXJhdHVyZQo+ID4gPiA+ICsgICAgICAgICAg ICAgICAgKiBtaW51cyBhY3R1YWwgZmFjdG9yeSB0ZW1wZXJhdHVyZSkgKiAxNC44OCAoc2NhbGUg ZnJvbQo+ID4gPiA+ICsgICAgICAgICAgICAgICAgKiB0ZW1wZXJhdHVyZSB0byByZWdpc3RlciB2 YWx1ZXMpCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAqLwo+ID4gPiA+ICsgICAgICAgICAgICAg ICBjZGF0YSA9IENBTElCUkFURV9ERUZBVUxUIC0KPiA+ID4gPiArICAgICAgICAgICAgICAgICAg ICAgICAoKHNlbnNvcl90ZW1wIC0gZnRfdGVtcCkgKiAxMCAvIHRtZGV2LT5jaGlwLT5zY2FsZSk7 Cj4gPiA+Cj4gPiA+IFdoeSBjaGFuZ2UgdGhlIGZvcm11bGEgaGVyZS4KPiA+ID4KPiA+ID4gaHR0 cHM6Ly9naXRodWIuY29tL29yYW5nZXBpLXh1bmxvbmcvT3JhbmdlUGlINl9rZXJuZWwvYmxvYi9t YXN0ZXIvZHJpdmVycy90aGVybWFsL3N1bnhpX3RoZXJtYWwvc3VueGlfdGhzX2NvcmUuYyNMMzM5 Cj4gPgo+IAo+IEhJLAo+IAo+IEkgc3VnZ2VzdCBrZWVwaW5nIHlvdSBhcyBpdCB3YXMgYmVmb3Jl IHRoaXMgcGF0Y2gsIGp1c3QgY2hhbmdlIHRoaXMKPiBwbGFjZSB0byB0aGlzLgo+IAo+IGNkYXRh ID0gQ0FMSUJSQVRFX0RFRkFVTFQgLSAoKGZ0X3RlbXAgKiAxMDAgLSBzZW5zb3JfdGVtcCkgLwo+ IHRtZGV2LT5jaGlwLT5zY2FsZSk7CgpIaSwKCmFueSByZWFzb24gZm9yIHlvdXIgc3VnZ2VzdGlv bj8gSSBhbHNvIGNoYW5nZWQgc2NhbGUgdG8gYmUgMTAqIHNwZWNpZmljYWxseSB0bwphbGxvdyBp dCB0byBiZSBtb3JlIHByZWNpc2Ugd2hlbiBkb2luZyBpbnRlZ2VyIG1hdGgsIHNvIHRoYXQgaXQg bW9yZSBlYXNpbHkKc3VwcG9ydHMgQTgzVCdzIHZhbHVlLiBINidzIHNjYWxlIHZhbHVlIGlzIGFs c28gbmVlZGxlc3NseSByb3VuZGVkIHRvbyBtdWNoCndpdGhvdXQgdGhpcyBjaGFuZ2UuIFdpdGgg eW91ciBzdWdnZXN0aW9uLCBJJ2QgaGF2ZSB0byByb3VuZCBBODNUJ3Mgc2NhbGUgZnJvbQo3MC41 IHRvIGVpdGhlciA3MCBvciA3MSwgYnV0IHdoeT8KCnJlZ2FyZHMsCglvLgoKPiBZYW5ndGFvCj4g Cj4gPiBJdCBsb29rcyB0aGUgc2FtZSB0byBtZSBhcyBiZWZvcmUuIEhlcmUncyB0aGUgb3JpZ2lu YWwgcGF0Y2g6Cj4gPgo+ID4gaHR0cHM6Ly9tZWdvdXMuY29tL2dpdC9saW51eC9jb21taXQvP2g9 dGhzLTUuNCZpZD1jYWUyOGE3ZGZhNmZjNzliYTM3ZTMxZDRkZmYyODE5NDcyNDdlODIyCj4gPgo+ ID4gSXQncyBiYXNpY2FseSB0byBhdm9pZCBtYWdpYyB2YWx1ZXMgVEVNUF9UT19SRUcgYW5kIHVz ZSB3aGF0J3MgZGVmaW5lZAo+ID4gaW4gdGhlIGNoaXAgc3RydWN0Lgo+ID4KPiA+IHJlZ2FyZHMs Cj4gPiAgICAgICAgIG8uCj4gPgo+ID4gPiA+ICsgICAgICAgICAgICAgICBpZiAoY2RhdGEgJiB+ VEVNUF9DQUxJQl9NQVNLKSB7Cj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgLyoKPiA+ ID4gPiArICAgICAgICAgICAgICAgICAgICAgICAgKiBDYWxpYnJhdGlvbiB2YWx1ZSBtb3JlIHRo YW4gMTItYml0LCBidXQgY2FsaWJyYXRpb24KPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgKiByZWdpc3RlciBpcyAxMi1iaXQuIEluIHRoaXMgY2FzZSwgdGhzIGhhcmR3YXJlIGNhbgo+ ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAqIHN0aWxsIHdvcmsgd2l0aG91dCBjYWxp YnJhdGlvbiwgYWx0aG91Z2ggdGhlIGRhdGEKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgKiB3b24ndCBiZSBzbyBhY2N1cmF0ZS4KPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgKi8KPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICBkZXZfd2FybihkZXYsICJzZW5z b3IlZCBpcyBub3QgY2FsaWJyYXRlZC5cbiIsIGkpOwo+ID4gPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgIGNvbnRpbnVlOwo+ID4gPiA+ICsgICAgICAgICAgICAgICB9Cj4gPiA+ID4gKwo+ID4g PiA+ICsgICAgICAgICAgICAgICBvZmZzZXQgPSAoaSAlIDIpICogMTY7Cj4gPiA+ID4gKyAgICAg ICAgICAgICAgIHJlZ21hcF91cGRhdGVfYml0cyh0bWRldi0+cmVnbWFwLAo+ID4gPiA+ICsgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1VONTBJX0g2X1RIU19URU1QX0NBTElCICsg KGkgLyAyICogNCksCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAw eGZmZiA8PCBvZmZzZXQsCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBjZGF0YSA8PCBvZmZzZXQpOwo+ID4gPiA+ICsgICAgICAgfQo+ID4gPiA+ICsKPiA+ID4gPiAr ICAgICAgIHJldHVybiAwOwo+ID4gPiA+ICt9Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgaW50 IHN1bjhpX3Roc19jYWxpYnJhdGUoc3RydWN0IHRoc19kZXZpY2UgKnRtZGV2KQo+ID4gPiA+ICt7 Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgbnZtZW1fY2VsbCAqY2FsY2VsbDsKPiA+ID4gPiArICAg ICAgIHN0cnVjdCBkZXZpY2UgKmRldiA9IHRtZGV2LT5kZXY7Cj4gPiA+ID4gKyAgICAgICB1MTYg KmNhbGRhdGE7Cj4gPiA+ID4gKyAgICAgICBzaXplX3QgY2FsbGVuOwo+ID4gPiA+ICsgICAgICAg aW50IHJldCA9IDA7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAgY2FsY2VsbCA9IGRldm1fbnZt ZW1fY2VsbF9nZXQoZGV2LCAiY2FsaWJyYXRpb24iKTsKPiA+ID4gPiArICAgICAgIGlmIChJU19F UlIoY2FsY2VsbCkpIHsKPiA+ID4gPiArICAgICAgICAgICAgICAgaWYgKFBUUl9FUlIoY2FsY2Vs bCkgPT0gLUVQUk9CRV9ERUZFUikKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICByZXR1 cm4gLUVQUk9CRV9ERUZFUjsKPiA+ID4gPiArICAgICAgICAgICAgICAgLyoKPiA+ID4gPiArICAg ICAgICAgICAgICAgICogRXZlbiBpZiB0aGUgZXh0ZXJuYWwgY2FsaWJyYXRpb24gZGF0YSBzdG9y ZWQgaW4gc2lkIGlzCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAqIG5vdCBhY2Nlc3NpYmxlLCB0 aGUgVEhTIGhhcmR3YXJlIGNhbiBzdGlsbCB3b3JrLCBhbHRob3VnaAo+ID4gPiA+ICsgICAgICAg ICAgICAgICAgKiB0aGUgZGF0YSB3b24ndCBiZSBzbyBhY2N1cmF0ZS4KPiA+ID4gPiArICAgICAg ICAgICAgICAgICoKPiA+ID4gPiArICAgICAgICAgICAgICAgICogVGhlIGRlZmF1bHQgdmFsdWUg b2YgY2FsaWJyYXRpb24gcmVnaXN0ZXIgaXMgMHg4MDAgZm9yCj4gPiA+ID4gKyAgICAgICAgICAg ICAgICAqIGV2ZXJ5IHNlbnNvciwgYW5kIHRoZSBjYWxpYnJhdGlvbiB2YWx1ZSBpcyB1c3VhbGx5 IDB4N3h4Cj4gPiA+ID4gKyAgICAgICAgICAgICAgICAqIG9yIDB4OHh4LCBzbyB0aGV5IHdvbid0 IGJlIGF3YXkgZnJvbSB0aGUgZGVmYXVsdCB2YWx1ZQo+ID4gPiA+ICsgICAgICAgICAgICAgICAg KiBmb3IgYSBsb3QuCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAqCj4gPiA+ID4gKyAgICAgICAg ICAgICAgICAqIFNvIGhlcmUgd2UgZG8gbm90IHJldHVybiBlcnJvciBpZiB0aGUgY2FsaWJhcnRp b24gZGF0YSBpcwo+ID4gPiA+ICsgICAgICAgICAgICAgICAgKiBub3QgYXZhaWxhYmxlLCBleGNl cHQgdGhlIHByb2JlIG5lZWRzIGRlZmVycmluZy4KPiA+ID4gPiArICAgICAgICAgICAgICAgICov Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIGdvdG8gb3V0Owo+ID4gPiA+ICsgICAgICAgfQo+ID4g PiA+ICsKPiA+ID4gPiArICAgICAgIGNhbGRhdGEgPSBudm1lbV9jZWxsX3JlYWQoY2FsY2VsbCwg JmNhbGxlbik7Cj4gPiA+ID4gKyAgICAgICBpZiAoSVNfRVJSKGNhbGRhdGEpKSB7Cj4gPiA+ID4g KyAgICAgICAgICAgICAgIHJldCA9IFBUUl9FUlIoY2FsZGF0YSk7Cj4gPiA+ID4gKyAgICAgICAg ICAgICAgIGdvdG8gb3V0Owo+ID4gPiA+ICsgICAgICAgfQo+ID4gPiA+ICsKPiA+ID4gPiArICAg ICAgIHRtZGV2LT5jaGlwLT5jYWxpYnJhdGUodG1kZXYsIGNhbGRhdGEsIGNhbGxlbik7Cj4gPiA+ ID4gKwo+ID4gPiA+ICsgICAgICAga2ZyZWUoY2FsZGF0YSk7Cj4gPiA+ID4gK291dDoKPiA+ID4g PiArICAgICAgIHJldHVybiByZXQ7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRp YyBpbnQgc3VuOGlfdGhzX3Jlc291cmNlX2luaXQoc3RydWN0IHRoc19kZXZpY2UgKnRtZGV2KQo+ ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgZGV2aWNlICpkZXYgPSB0bWRldi0+ZGV2 Owo+ID4gPiA+ICsgICAgICAgc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRm b3JtX2RldmljZShkZXYpOwo+ID4gPiA+ICsgICAgICAgc3RydWN0IHJlc291cmNlICptZW07Cj4g PiA+ID4gKyAgICAgICB2b2lkIF9faW9tZW0gKmJhc2U7Cj4gPiA+ID4gKyAgICAgICBpbnQgcmV0 Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIG1lbSA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShw ZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7Cj4gPiA+ID4gKyAgICAgICBiYXNlID0gZGV2bV9pb3Jl bWFwX3Jlc291cmNlKGRldiwgbWVtKTsKPiA+ID4gPiArICAgICAgIGlmIChJU19FUlIoYmFzZSkp Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIHJldHVybiBQVFJfRVJSKGJhc2UpOwo+ID4gPiA+ICsK PiA+ID4gPiArICAgICAgIHRtZGV2LT5yZWdtYXAgPSBkZXZtX3JlZ21hcF9pbml0X21taW8oZGV2 LCBiYXNlLCAmY29uZmlnKTsKPiA+ID4gPiArICAgICAgIGlmIChJU19FUlIodG1kZXYtPnJlZ21h cCkpCj4gPiA+ID4gKyAgICAgICAgICAgICAgIHJldHVybiBQVFJfRVJSKHRtZGV2LT5yZWdtYXAp Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIGlmICh0bWRldi0+Y2hpcC0+aGFzX2J1c19jbGtf cmVzZXQpIHsKPiA+ID4gPiArICAgICAgICAgICAgICAgdG1kZXYtPnJlc2V0ID0gZGV2bV9yZXNl dF9jb250cm9sX2dldChkZXYsIDApOwo+ID4gPiA+ICsgICAgICAgICAgICAgICBpZiAoSVNfRVJS KHRtZGV2LT5yZXNldCkpCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFBU Ul9FUlIodG1kZXYtPnJlc2V0KTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICAgICAgICAgIHRt ZGV2LT5idXNfY2xrID0gZGV2bV9jbGtfZ2V0KCZwZGV2LT5kZXYsICJidXMiKTsKPiA+ID4gPiAr ICAgICAgICAgICAgICAgaWYgKElTX0VSUih0bWRldi0+YnVzX2NsaykpCj4gPiA+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgcmV0dXJuIFBUUl9FUlIodG1kZXYtPmJ1c19jbGspOwo+ID4gPiA+ ICsgICAgICAgfQo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIGlmICh0bWRldi0+Y2hpcC0+aGFz X21vZF9jbGspIHsKPiA+ID4gPiArICAgICAgICAgICAgICAgdG1kZXYtPm1vZF9jbGsgPSBkZXZt X2Nsa19nZXQoJnBkZXYtPmRldiwgIm1vZCIpOwo+ID4gPiA+ICsgICAgICAgICAgICAgICBpZiAo SVNfRVJSKHRtZGV2LT5tb2RfY2xrKSkKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICAgICBy ZXR1cm4gUFRSX0VSUih0bWRldi0+bW9kX2Nsayk7Cj4gPiA+ID4gKyAgICAgICB9Cj4gPiA+ID4g Kwo+ID4gPiA+ICsgICAgICAgcmV0ID0gcmVzZXRfY29udHJvbF9kZWFzc2VydCh0bWRldi0+cmVz ZXQpOwo+ID4gPiA+ICsgICAgICAgaWYgKHJldCkKPiA+ID4gPiArICAgICAgICAgICAgICAgcmV0 dXJuIHJldDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICByZXQgPSBjbGtfcHJlcGFyZV9lbmFi bGUodG1kZXYtPmJ1c19jbGspOwo+ID4gPiA+ICsgICAgICAgaWYgKHJldCkKPiA+ID4gPiArICAg ICAgICAgICAgICAgZ290byBhc3NlcnRfcmVzZXQ7Cj4gPiA+ID4gKwo+ID4gPiA+ICsgICAgICAg cmV0ID0gY2xrX3NldF9yYXRlKHRtZGV2LT5tb2RfY2xrLCAyNDAwMDAwMCk7Cj4gPiA+ID4gKyAg ICAgICBpZiAocmV0KQo+ID4gPiA+ICsgICAgICAgICAgICAgICBnb3RvIGJ1c19kaXNhYmxlOwo+ ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIHJldCA9IGNsa19wcmVwYXJlX2VuYWJsZSh0bWRldi0+ bW9kX2Nsayk7Cj4gPiA+ID4gKyAgICAgICBpZiAocmV0KQo+ID4gPiA+ICsgICAgICAgICAgICAg ICBnb3RvIGJ1c19kaXNhYmxlOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIHJldCA9IHN1bjhp X3Roc19jYWxpYnJhdGUodG1kZXYpOwo+ID4gPiA+ICsgICAgICAgaWYgKHJldCkKPiA+ID4gPiAr ICAgICAgICAgICAgICAgZ290byBtb2RfZGlzYWJsZTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAg ICByZXR1cm4gMDsKPiA+ID4gPiArCj4gPiA+ID4gK21vZF9kaXNhYmxlOgo+ID4gPiA+ICsgICAg ICAgY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHRtZGV2LT5tb2RfY2xrKTsKPiA+ID4gPiArYnVzX2Rp c2FibGU6Cj4gPiA+ID4gKyAgICAgICBjbGtfZGlzYWJsZV91bnByZXBhcmUodG1kZXYtPmJ1c19j bGspOwo+ID4gPiA+ICthc3NlcnRfcmVzZXQ6Cj4gPiA+ID4gKyAgICAgICByZXNldF9jb250cm9s X2Fzc2VydCh0bWRldi0+cmVzZXQpOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIHJldHVybiBy ZXQ7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBpbnQgc3VuOGlfaDNfdGhl cm1hbF9pbml0KHN0cnVjdCB0aHNfZGV2aWNlICp0bWRldikKPiA+ID4gPiArewo+ID4gPiA+ICsg ICAgICAgaW50IHZhbDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICAvKiBhdmVyYWdlIG92ZXIg NCBzYW1wbGVzICovCj4gPiA+ID4gKyAgICAgICByZWdtYXBfd3JpdGUodG1kZXYtPnJlZ21hcCwg U1VOOElfVEhTX01GQywKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICBTVU41MElfVEhTX0ZJ TFRFUl9FTiB8Cj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgU1VONTBJX1RIU19GSUxURVJf VFlQRSgxKSk7Cj4gPiA+ID4gKyAgICAgICAvKgo+ID4gPiA+ICsgICAgICAgICogY2xraW4gPSAy NE1Iego+ID4gPiA+ICsgICAgICAgICogZmlsdGVyX3NhbXBsZXMgPSA0Cj4gPiA+ID4gKyAgICAg ICAgKiBwZXJpb2QgPSAwLjI1cwo+ID4gPiA+ICsgICAgICAgICoKPiA+ID4gPiArICAgICAgICAq IHggPSBwZXJpb2QgKiBjbGtpbiAvIDQwOTYgLyBmaWx0ZXJfc2FtcGxlcyAtIDEKPiA+ID4gPiAr ICAgICAgICAqICAgPSAzNjUKPiA+ID4gPiArICAgICAgICAqLwo+ID4gPiA+ICsgICAgICAgdmFs ID0gR0VOTUFTSyg3ICsgdG1kZXYtPmNoaXAtPnNlbnNvcl9udW0sIDgpOwo+ID4gPiA+ICsgICAg ICAgcmVnbWFwX3dyaXRlKHRtZGV2LT5yZWdtYXAsIFNVTjhJX1RIU19JQywKPiA+ID4gPiArICAg ICAgICAgICAgICAgICAgICBTVU41MElfSDZfVEhTX1BDX1RFTVBfUEVSSU9EKDM2NSkgfCB2YWwp Owo+ID4gPiA+ICsgICAgICAgLyoKPiA+ID4gPiArICAgICAgICAqIFRfYWNxID0gMjB1cwo+ID4g PiA+ICsgICAgICAgICogY2xraW4gPSAyNE1Iego+ID4gPiA+ICsgICAgICAgICoKPiA+ID4gPiAr ICAgICAgICAqIHggPSBUX2FjcSAqIGNsa2luIC0gMQo+ID4gPiA+ICsgICAgICAgICogICA9IDQ3 OQo+ID4gPiA+ICsgICAgICAgICovCj4gPiA+ID4gKyAgICAgICByZWdtYXBfd3JpdGUodG1kZXYt PnJlZ21hcCwgU1VOOElfVEhTX0NUUkwwLAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgIFNV TjhJX1RIU19DVFJMMF9UX0FDUTAoNDc5KSk7Cj4gPiA+ID4gKyAgICAgICB2YWwgPSBHRU5NQVNL KHRtZGV2LT5jaGlwLT5zZW5zb3JfbnVtIC0gMSwgMCk7Cj4gPiA+ID4gKyAgICAgICByZWdtYXBf d3JpdGUodG1kZXYtPnJlZ21hcCwgU1VOOElfVEhTX0NUUkwyLAo+ID4gPiA+ICsgICAgICAgICAg ICAgICAgICAgIFNVTjhJX1RIU19DVFJMMl9UX0FDUTEoNDc5KSB8IHZhbCk7Cj4gPiA+ID4gKwo+ ID4gPiA+ICsgICAgICAgcmV0dXJuIDA7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gKy8q Cj4gPiA+ID4gKyAqIFdpdGhvdXQgdGhpcyB1bmRvY3VtbWVudGVkIHZhbHVlLCB0aGUgcmV0dXJu ZWQgdGVtcGVyYXR1cmVzIHdvdWxkCj4gPiA+ID4gKyAqIGJlIGhpZ2hlciB0aGFuIHJlYWwgb25l cyBieSBhYm91dCAyMEMuCj4gPiA+ID4gKyAqLwo+ID4gPiA+ICsjZGVmaW5lIFNVTjUwSV9INl9D VFJMMF9VTksgMHgwMDAwMDAyZgo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGludCBzdW41MGlf aDZfdGhlcm1hbF9pbml0KHN0cnVjdCB0aHNfZGV2aWNlICp0bWRldikKPiA+ID4gPiArewo+ID4g PiA+ICsgICAgICAgaW50IHZhbDsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICAvKgo+ID4gPiA+ ICsgICAgICAgICogVF9hY3EgPSAyMHVzCj4gPiA+ID4gKyAgICAgICAgKiBjbGtpbiA9IDI0TUh6 Cj4gPiA+ID4gKyAgICAgICAgKgo+ID4gPiA+ICsgICAgICAgICogeCA9IFRfYWNxICogY2xraW4g LSAxCj4gPiA+ID4gKyAgICAgICAgKiAgID0gNDc5Cj4gPiA+ID4gKyAgICAgICAgKi8KPiA+ID4g PiArICAgICAgIHJlZ21hcF93cml0ZSh0bWRldi0+cmVnbWFwLCBTVU41MElfVEhTX0NUUkwwLAo+ ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgIFNVTjUwSV9INl9DVFJMMF9VTksgfCBTVU41MElf VEhTX0NUUkwwX1RfQUNRKDQ3OSkpOwo+ID4gPiA+ICsgICAgICAgLyogYXZlcmFnZSBvdmVyIDQg c2FtcGxlcyAqLwo+ID4gPiA+ICsgICAgICAgcmVnbWFwX3dyaXRlKHRtZGV2LT5yZWdtYXAsIFNV TjUwSV9INl9USFNfTUZDLAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgIFNVTjUwSV9USFNf RklMVEVSX0VOIHwKPiA+ID4gPiArICAgICAgICAgICAgICAgICAgICBTVU41MElfVEhTX0ZJTFRF Ul9UWVBFKDEpKTsKPiA+ID4gPiArICAgICAgIC8qCj4gPiA+ID4gKyAgICAgICAgKiBjbGtpbiA9 IDI0TUh6Cj4gPiA+ID4gKyAgICAgICAgKiBmaWx0ZXJfc2FtcGxlcyA9IDQKPiA+ID4gPiArICAg ICAgICAqIHBlcmlvZCA9IDAuMjVzCj4gPiA+ID4gKyAgICAgICAgKgo+ID4gPiA+ICsgICAgICAg ICogeCA9IHBlcmlvZCAqIGNsa2luIC8gNDA5NiAvIGZpbHRlcl9zYW1wbGVzIC0gMQo+ID4gPiA+ ICsgICAgICAgICogICA9IDM2NQo+ID4gPiA+ICsgICAgICAgICovCj4gPiA+ID4gKyAgICAgICBy ZWdtYXBfd3JpdGUodG1kZXYtPnJlZ21hcCwgU1VONTBJX0g2X1RIU19QQywKPiA+ID4gPiArICAg ICAgICAgICAgICAgICAgICBTVU41MElfSDZfVEhTX1BDX1RFTVBfUEVSSU9EKDM2NSkpOwo+ID4g PiA+ICsgICAgICAgLyogZW5hYmxlIHNlbnNvciAqLwo+ID4gPiA+ICsgICAgICAgdmFsID0gR0VO TUFTSyh0bWRldi0+Y2hpcC0+c2Vuc29yX251bSAtIDEsIDApOwo+ID4gPiA+ICsgICAgICAgcmVn bWFwX3dyaXRlKHRtZGV2LT5yZWdtYXAsIFNVTjUwSV9INl9USFNfRU5BQkxFLCB2YWwpOwo+ID4g PiA+ICsgICAgICAgLyogdGhlcm1hbCBkYXRhIGludGVycnVwdCBlbmFibGUgKi8KPiA+ID4gPiAr ICAgICAgIHZhbCA9IEdFTk1BU0sodG1kZXYtPmNoaXAtPnNlbnNvcl9udW0gLSAxLCAwKTsKPiA+ ID4gPiArICAgICAgIHJlZ21hcF93cml0ZSh0bWRldi0+cmVnbWFwLCBTVU41MElfSDZfVEhTX0RJ QywgdmFsKTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICByZXR1cm4gMDsKPiA+ID4gPiArfQo+ ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGludCBzdW44aV90aHNfcmVnaXN0ZXIoc3RydWN0IHRo c19kZXZpY2UgKnRtZGV2KQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgICBpbnQgaTsKPiA+ID4g PiArCj4gPiA+ID4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgdG1kZXYtPmNoaXAtPnNlbnNvcl9u dW07IGkrKykgewo+ID4gPiA+ICsgICAgICAgICAgICAgICB0bWRldi0+c2Vuc29yW2ldLnRtZGV2 ID0gdG1kZXY7Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIHRtZGV2LT5zZW5zb3JbaV0uaWQgPSBp Owo+ID4gPiA+ICsgICAgICAgICAgICAgICB0bWRldi0+c2Vuc29yW2ldLnR6ZCA9Cj4gPiA+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgZGV2bV90aGVybWFsX3pvbmVfb2Zfc2Vuc29yX3JlZ2lz dGVyKHRtZGV2LT5kZXYsCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGksCj4gPiA+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0bWRldi0+c2Vuc29y W2ldLAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAmdGhzX29wcyk7Cj4gPiA+ID4gKyAgICAgICAgICAgICAgIGlmIChJ U19FUlIodG1kZXYtPnNlbnNvcltpXS50emQpKQo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgIHJldHVybiBQVFJfRVJSKHRtZGV2LT5zZW5zb3JbaV0udHpkKTsKPiA+ID4gPiArICAgICAg IH0KPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICByZXR1cm4gMDsKPiA+ID4gPiArfQo+ID4gPiA+ ICsKPiA+ID4gPiArc3RhdGljIGludCBzdW44aV90aHNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2Rl dmljZSAqcGRldikKPiA+ID4gPiArewo+ID4gPiA+ICsgICAgICAgc3RydWN0IHRoc19kZXZpY2Ug KnRtZGV2Owo+ID4gPiA+ICsgICAgICAgc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsK PiA+ID4gPiArICAgICAgIGludCByZXQsIGlycTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICB0 bWRldiA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqdG1kZXYpLCBHRlBfS0VSTkVMKTsKPiA+ ID4gPiArICAgICAgIGlmICghdG1kZXYpCj4gPiA+ID4gKyAgICAgICAgICAgICAgIHJldHVybiAt RU5PTUVNOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIHRtZGV2LT5kZXYgPSBkZXY7Cj4gPiA+ ID4gKyAgICAgICB0bWRldi0+Y2hpcCA9IG9mX2RldmljZV9nZXRfbWF0Y2hfZGF0YSgmcGRldi0+ ZGV2KTsKPiA+ID4gPiArICAgICAgIGlmICghdG1kZXYtPmNoaXApCj4gPiA+ID4gKyAgICAgICAg ICAgICAgIHJldHVybiAtRUlOVkFMOwo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIHBsYXRmb3Jt X3NldF9kcnZkYXRhKHBkZXYsIHRtZGV2KTsKPiA+ID4gPiArCj4gPiA+ID4gKyAgICAgICByZXQg PSBzdW44aV90aHNfcmVzb3VyY2VfaW5pdCh0bWRldik7Cj4gPiA+ID4gKyAgICAgICBpZiAocmV0 KQo+ID4gPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ID4gPiA+ICsKPiA+ID4gPiAr ICAgICAgIGlycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7Cj4gPiA+ID4gKyAgICAgICBp ZiAoaXJxIDwgMCkKPiA+ID4gPiArICAgICAgICAgICAgICAgcmV0dXJuIGlycTsKPiA+ID4gPiAr Cj4gPiA+ID4gKyAgICAgICByZXQgPSB0bWRldi0+Y2hpcC0+aW5pdCh0bWRldik7Cj4gPiA+ID4g KyAgICAgICBpZiAocmV0KQo+ID4gPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ID4g PiA+ICsKPiA+ID4gPiArICAgICAgIHJldCA9IHN1bjhpX3Roc19yZWdpc3Rlcih0bWRldik7Cj4g PiA+ID4gKyAgICAgICBpZiAocmV0KQo+ID4gPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0 Owo+ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIC8qCj4gPiA+ID4gKyAgICAgICAgKiBBdm9pZCBl bnRlcmluZyB0aGUgaW50ZXJydXB0IGhhbmRsZXIsIHRoZSB0aGVybWFsIGRldmljZSBpcyBub3QK PiA+ID4gPiArICAgICAgICAqIHJlZ2lzdGVyZWQgeWV0LCB3ZSBkZWZmZXIgdGhlIHJlZ2lzdHJh dGlvbiBvZiB0aGUgaW50ZXJydXB0IHRvCj4gPiA+ID4gKyAgICAgICAgKiB0aGUgZW5kLgo+ID4g PiA+ICsgICAgICAgICovCj4gPiA+ID4gKyAgICAgICByZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFk ZWRfaXJxKGRldiwgaXJxLCBOVUxMLAo+ID4gPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBzdW44aV9pcnFfdGhyZWFkLAo+ID4gPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBJUlFGX09ORVNIT1QsICJ0aHMiLCB0bWRldik7Cj4gPiA+ ID4gKyAgICAgICBpZiAocmV0KQo+ID4gPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Owo+ ID4gPiA+ICsKPiA+ID4gPiArICAgICAgIHJldHVybiByZXQ7Cj4gPiA+ID4gK30KPiA+ID4gPiAr Cj4gPiA+ID4gK3N0YXRpYyBpbnQgc3VuOGlfdGhzX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2KQo+ID4gPiA+ICt7Cj4gPiA+ID4gKyAgICAgICBzdHJ1Y3QgdGhzX2RldmljZSAq dG1kZXYgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKPiA+ID4gPiArCj4gPiA+ID4gKyAg ICAgICBjbGtfZGlzYWJsZV91bnByZXBhcmUodG1kZXYtPm1vZF9jbGspOwo+ID4gPiA+ICsgICAg ICAgY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHRtZGV2LT5idXNfY2xrKTsKPiA+ID4gPiArICAgICAg IHJlc2V0X2NvbnRyb2xfYXNzZXJ0KHRtZGV2LT5yZXNldCk7Cj4gPiA+ID4gKwo+ID4gPiA+ICsg ICAgICAgcmV0dXJuIDA7Cj4gPiA+ID4gK30KPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBjb25z dCBzdHJ1Y3QgdGhzX3RoZXJtYWxfY2hpcCBzdW44aV9hODN0X3RocyA9IHsKPiA+ID4gPiArICAg ICAgIC5zZW5zb3JfbnVtID0gMywKPiA+ID4gPiArICAgICAgIC5zY2FsZSA9IDcwNSwKPiA+ID4g PiArICAgICAgIC5vZmZzZXQgPSAxOTE2NjgsCj4gPiA+ID4gKyAgICAgICAudGVtcF9kYXRhX2Jh c2UgPSBTVU44SV9USFNfVEVNUF9EQVRBLAo+ID4gPiA+ICsgICAgICAgLmNhbGlicmF0ZSA9IHN1 bjhpX2gzX3Roc19jYWxpYnJhdGUsCj4gPiA+ID4gKyAgICAgICAuaW5pdCA9IHN1bjhpX2gzX3Ro ZXJtYWxfaW5pdCwKPiA+ID4gPiArICAgICAgIC5pcnFfYWNrID0gc3VuOGlfaDNfaXJxX2FjaywK PiA+ID4gPiArICAgICAgIC5jYWxjX3RlbXAgPSBzdW44aV90aHNfY2FsY190ZW1wLAo+ID4gPiA+ ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB0aHNfdGhlcm1hbF9j aGlwIHN1bjhpX2gzX3RocyA9IHsKPiA+ID4gPiArICAgICAgIC5zZW5zb3JfbnVtID0gMSwKPiA+ ID4gPiArICAgICAgIC5zY2FsZSA9IDEyMTEsCj4gPiA+ID4gKyAgICAgICAub2Zmc2V0ID0gMjE3 MDAwLAo+ID4gPiA+ICsgICAgICAgLmhhc19tb2RfY2xrID0gdHJ1ZSwKPiA+ID4gPiArICAgICAg IC5oYXNfYnVzX2Nsa19yZXNldCA9IHRydWUsCj4gPiA+ID4gKyAgICAgICAudGVtcF9kYXRhX2Jh c2UgPSBTVU44SV9USFNfVEVNUF9EQVRBLAo+ID4gPiA+ICsgICAgICAgLmNhbGlicmF0ZSA9IHN1 bjhpX2gzX3Roc19jYWxpYnJhdGUsCj4gPiA+ID4gKyAgICAgICAuaW5pdCA9IHN1bjhpX2gzX3Ro ZXJtYWxfaW5pdCwKPiA+ID4gPiArICAgICAgIC5pcnFfYWNrID0gc3VuOGlfaDNfaXJxX2FjaywK PiA+ID4gPiArICAgICAgIC5jYWxjX3RlbXAgPSBzdW44aV90aHNfY2FsY190ZW1wLAo+ID4gPiA+ ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB0aHNfdGhlcm1hbF9j aGlwIHN1bjhpX3I0MF90aHMgPSB7Cj4gPiA+ID4gKyAgICAgICAuc2Vuc29yX251bSA9IDMsCj4g PiA+ID4gKyAgICAgICAub2Zmc2V0ID0gMjUxMDg2LAo+ID4gPiA+ICsgICAgICAgLnNjYWxlID0g MTEzMCwKPiA+ID4gPiArICAgICAgIC5oYXNfbW9kX2NsayA9IHRydWUsCj4gPiA+ID4gKyAgICAg ICAuaGFzX2J1c19jbGtfcmVzZXQgPSB0cnVlLAo+ID4gPiA+ICsgICAgICAgLnRlbXBfZGF0YV9i YXNlID0gU1VOOElfVEhTX1RFTVBfREFUQSwKPiA+ID4gPiArICAgICAgIC5jYWxpYnJhdGUgPSBz dW44aV9oM190aHNfY2FsaWJyYXRlLAo+ID4gPiA+ICsgICAgICAgLmluaXQgPSBzdW44aV9oM190 aGVybWFsX2luaXQsCj4gPiA+ID4gKyAgICAgICAuaXJxX2FjayA9IHN1bjhpX2gzX2lycV9hY2ss Cj4gPiA+ID4gKyAgICAgICAuY2FsY190ZW1wID0gc3VuOGlfdGhzX2NhbGNfdGVtcCwKPiA+ID4g PiArfTsKPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgdGhzX3RoZXJtYWxf Y2hpcCBzdW41MGlfYTY0X3RocyA9IHsKPiA+ID4gPiArICAgICAgIC5zZW5zb3JfbnVtID0gMywK PiA+ID4gPiArICAgICAgIC5vZmZzZXQgPSAyNTM4OTAsCj4gPiA+ID4gKyAgICAgICAuc2NhbGUg PSAxMTcwLAo+ID4gPiA+ICsgICAgICAgLmhhc19tb2RfY2xrID0gdHJ1ZSwKPiA+ID4gPiArICAg ICAgIC5oYXNfYnVzX2Nsa19yZXNldCA9IHRydWUsCj4gPiA+ID4gKyAgICAgICAudGVtcF9kYXRh X2Jhc2UgPSBTVU44SV9USFNfVEVNUF9EQVRBLAo+ID4gPiA+ICsgICAgICAgLmNhbGlicmF0ZSA9 IHN1bjhpX2gzX3Roc19jYWxpYnJhdGUsCj4gPiA+ID4gKyAgICAgICAuaW5pdCA9IHN1bjhpX2gz X3RoZXJtYWxfaW5pdCwKPiA+ID4gPiArICAgICAgIC5pcnFfYWNrID0gc3VuOGlfaDNfaXJxX2Fj aywKPiA+ID4gPiArICAgICAgIC5jYWxjX3RlbXAgPSBzdW44aV90aHNfY2FsY190ZW1wLAo+ID4g PiA+ICt9Owo+ID4gPiA+ICsKPiA+ID4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB0aHNfdGhlcm1h bF9jaGlwIHN1bjUwaV9oNV90aHMgPSB7Cj4gPiA+ID4gKyAgICAgICAuc2Vuc29yX251bSA9IDIs Cj4gPiA+ID4gKyAgICAgICAuaGFzX21vZF9jbGsgPSB0cnVlLAo+ID4gPiA+ICsgICAgICAgLmhh c19idXNfY2xrX3Jlc2V0ID0gdHJ1ZSwKPiA+ID4gPiArICAgICAgIC50ZW1wX2RhdGFfYmFzZSA9 IFNVTjhJX1RIU19URU1QX0RBVEEsCj4gPiA+ID4gKyAgICAgICAuY2FsaWJyYXRlID0gc3VuOGlf aDNfdGhzX2NhbGlicmF0ZSwKPiA+ID4gPiArICAgICAgIC5pbml0ID0gc3VuOGlfaDNfdGhlcm1h bF9pbml0LAo+ID4gPiA+ICsgICAgICAgLmlycV9hY2sgPSBzdW44aV9oM19pcnFfYWNrLAo+ID4g PiA+ICsgICAgICAgLmNhbGNfdGVtcCA9IHN1bjUwaV9oNV9jYWxjX3RlbXAsCj4gPiA+ID4gK307 Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHRoc190aGVybWFsX2NoaXAg c3VuNTBpX2g2X3RocyA9IHsKPiA+ID4gPiArICAgICAgIC5zZW5zb3JfbnVtID0gMiwKPiA+ID4g PiArICAgICAgIC5oYXNfYnVzX2Nsa19yZXNldCA9IHRydWUsCj4gPiA+ID4gKyAgICAgICAuZnRf ZGV2aWF0aW9uID0gNzAwMCwKPiA+ID4gPiArICAgICAgIC5vZmZzZXQgPSAxODc3NDQsCj4gPiA+ ID4gKyAgICAgICAuc2NhbGUgPSA2NzIsCj4gPiA+ID4gKyAgICAgICAudGVtcF9kYXRhX2Jhc2Ug PSBTVU41MElfSDZfVEhTX1RFTVBfREFUQSwKPiA+ID4gPiArICAgICAgIC5jYWxpYnJhdGUgPSBz dW41MGlfaDZfdGhzX2NhbGlicmF0ZSwKPiA+ID4gPiArICAgICAgIC5pbml0ID0gc3VuNTBpX2g2 X3RoZXJtYWxfaW5pdCwKPiA+ID4gPiArICAgICAgIC5pcnFfYWNrID0gc3VuNTBpX2g2X2lycV9h Y2ssCj4gPiA+ID4gKyAgICAgICAuY2FsY190ZW1wID0gc3VuOGlfdGhzX2NhbGNfdGVtcCwKPiA+ ID4gPiArfTsKPiA+ID4gPiArCj4gPiA+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNl X2lkIG9mX3Roc19tYXRjaFtdID0gewo+ID4gPiA+ICsgICAgICAgeyAuY29tcGF0aWJsZSA9ICJh bGx3aW5uZXIsc3VuOGktYTgzdC10aHMiLCAuZGF0YSA9ICZzdW44aV9hODN0X3RocyB9LAo+ID4g PiA+ICsgICAgICAgeyAuY29tcGF0aWJsZSA9ICJhbGx3aW5uZXIsc3VuOGktaDMtdGhzIiwgLmRh dGEgPSAmc3VuOGlfaDNfdGhzIH0sCj4gPiA+ID4gKyAgICAgICB7IC5jb21wYXRpYmxlID0gImFs bHdpbm5lcixzdW44aS1yNDAtdGhzIiwgLmRhdGEgPSAmc3VuOGlfcjQwX3RocyB9LAo+ID4gPiA+ ICsgICAgICAgeyAuY29tcGF0aWJsZSA9ICJhbGx3aW5uZXIsc3VuNTBpLWE2NC10aHMiLCAuZGF0 YSA9ICZzdW41MGlfYTY0X3RocyB9LAo+ID4gPiA+ICsgICAgICAgeyAuY29tcGF0aWJsZSA9ICJh bGx3aW5uZXIsc3VuNTBpLWg1LXRocyIsIC5kYXRhID0gJnN1bjUwaV9oNV90aHMgfSwKPiA+ID4g PiArICAgICAgIHsgLmNvbXBhdGlibGUgPSAiYWxsd2lubmVyLHN1bjUwaS1oNi10aHMiLCAuZGF0 YSA9ICZzdW41MGlfaDZfdGhzIH0sCj4gPiA+ID4gKyAgICAgICB7IC8qIHNlbnRpbmVsICovIH0s Cj4gPiA+ID4gK307Cj4gPiA+ID4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIG9mX3Roc19tYXRj aCk7Cj4gPiA+ID4gKwo+ID4gPiA+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciB0aHNf ZHJpdmVyID0gewo+ID4gPiA+ICsgICAgICAgLnByb2JlID0gc3VuOGlfdGhzX3Byb2JlLAo+ID4g PiA+ICsgICAgICAgLnJlbW92ZSA9IHN1bjhpX3Roc19yZW1vdmUsCj4gPiA+ID4gKyAgICAgICAu ZHJpdmVyID0gewo+ID4gPiA+ICsgICAgICAgICAgICAgICAubmFtZSA9ICJzdW44aS10aGVybWFs IiwKPiA+ID4gPiArICAgICAgICAgICAgICAgLm9mX21hdGNoX3RhYmxlID0gb2ZfdGhzX21hdGNo LAo+ID4gPiA+ICsgICAgICAgfSwKPiA+ID4gPiArfTsKPiA+ID4gPiArbW9kdWxlX3BsYXRmb3Jt X2RyaXZlcih0aHNfZHJpdmVyKTsKPiA+ID4gPiArCj4gPiA+ID4gK01PRFVMRV9ERVNDUklQVElP TigiVGhlcm1hbCBzZW5zb3IgZHJpdmVyIGZvciBBbGx3aW5uZXIgU09DIik7Cj4gPiA+ID4gK01P RFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsKPiA+ID4gPiAtLQo+ID4gPiA+IDIuMjQuMAo+ID4gPiA+ Cj4gPiA+Cj4gPiA+IFRoeCwKPiA+ID4gWWFuZ3Rhbwo+IAo+IF9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCj4gbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxp c3QKPiBsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKPiBodHRwOi8vbGlzdHMu aW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwKCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwg bWFpbGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8v bGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK