From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD3281C230C; Fri, 16 Aug 2024 17:13:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723828422; cv=none; b=ispZGGjs/Hb+EZoUj8XNoXn/WxqL4uxnQtRVN/FaIaJ40YI27enBZANcipncn7HQRLucrsicwfTPqH0S7nULVs/JDAZsztsrKrWxdL5e+B6b+4IKvCA8TGdjR1C4VUCifbtplLsHSUThhBvuBGavoSgG5Rp5RDKIlHYgYU8LBqE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723828422; c=relaxed/simple; bh=VuO0lhV6v1fhCig+xAS2g1N9ON3e+KySvA10Zp/DwMw=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=nx0O7vQmvGeXmAG+Y/gZk04miLaGyIdXOPQyxLmQbm2/enmmWrWykF7O5hQ2Rjz4qYvl+DE0SO+oWlCEQxYeFWm53eCg2S3taLuuIOCWe8aUM2YZay+g8SrbRiH+EKWdkfYPmNS3hVtYD7jRUu1xQISZXPPD7tOPT5jepCjvCxM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rj4qRNPJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rj4qRNPJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF4BDC32782; Fri, 16 Aug 2024 17:13:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723828422; bh=VuO0lhV6v1fhCig+xAS2g1N9ON3e+KySvA10Zp/DwMw=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=rj4qRNPJr+Krim3X1SYt9Oel1PAau46i7EGUSsB+OnWDim/lksrcq9QGm4rPZabLU 4u+w7kcAfdKMqFsFwrChhRggKfkBrdnxHpg2JqtqWZ3QI2WwmaTZBVrmN/zYBsJlpH rXJSQXJ0vi17SAq6ZTVzjPXRMkcGjSS4/q0f8cubSQkY4yi6IIorqTsAsxOHnn7+qS CuhgV+jsuA89CuZyB8S/bHfrGStX9rY7LiSN8vuPiDSourpIzwmREBpXUg8yyM/p2Z P53yvYHDYlwHZDEulL5vZEYfTdDkcGcrqgxYl2Ce0OQpDw1OodLbFHnb+SD7MfD6Q5 3SE2DpgK/CM8w== Date: Fri, 16 Aug 2024 18:13:36 +0100 From: Lee Jones To: Heiko Stuebner Cc: jdelvare@suse.com, linux@roeck-us.net, dmitry.torokhov@gmail.com, pavel@ucw.cz, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, ukleinek@debian.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-hwmon@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org Subject: Re: [PATCH v4 2/7] mfd: add base driver for qnap-mcu devices Message-ID: <20240816171336.GF5853@google.com> References: <20240810184743.277248-1-heiko@sntech.de> <20240810184743.277248-3-heiko@sntech.de> Precedence: bulk X-Mailing-List: linux-hwmon@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20240810184743.277248-3-heiko@sntech.de> On Sat, 10 Aug 2024, Heiko Stuebner wrote: > These MCUs are used in network-attached-storage devices made by QNAP > and provide additional functionality to the system. > > This adds the base driver that implements the serial protocol via > serdev and additionally hooks into the poweroff handlers to turn > off the parts of the system not supplied by the general PMIC. > > Turning off (at least the TSx33 devices using Rockchip SoCs) is twofold. This sentence doesn't make sense. "twofold" means "times (multiply by) two". > Turning off the MCU does not turn off the SoC and turning off the SoC > does not turn off the hard-drives. And if the MCU is not turned off, > the system also won't start again until it is unplugged from power. > > So on shutdown the MCU needs to be turned off before the general PMIC. > > The protocol spoken by the MCU is sadly not documented, but was > obtained by listening to the chatter on the serial port, as thankfully > the "hal_app" program from QNAPs firmware allows triggering all/most > MCU actions from the command line. > > The implementation of how to talk to the serial device got some > inspiration from the rave-sp servdev mfd. "MFD" or better yet "driver". > Signed-off-by: Heiko Stuebner > --- > MAINTAINERS | 6 + > drivers/mfd/Kconfig | 10 + > drivers/mfd/Makefile | 2 + > drivers/mfd/qnap-mcu.c | 358 +++++++++++++++++++++++++++++++++++ > include/linux/mfd/qnap-mcu.h | 28 +++ > 5 files changed, 404 insertions(+) > create mode 100644 drivers/mfd/qnap-mcu.c > create mode 100644 include/linux/mfd/qnap-mcu.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index 8766f3e5e87e0..f9f605a3c12a4 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -18652,6 +18652,12 @@ L: linux-media@vger.kernel.org > S: Odd Fixes > F: drivers/media/tuners/qm1d1c0042* > > +QNAP MCU DRIVER > +M: Heiko Stuebner > +S: Maintained > +F: drivers/mfd/qnap-mcu.c > +F: include/linux/qnap-mcu.h > + > QNX4 FILESYSTEM > M: Anders Larsen > S: Maintained > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index bc8be2e593b6b..ca7289e906a7b 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -2362,6 +2362,16 @@ config MFD_INTEL_M10_BMC_PMCI > additional drivers must be enabled in order to use the functionality > of the device. > > +config MFD_QNAP_MCU > + tristate "QNAP MCU core driver" Now's the time to expand "MCU" > + depends on SERIAL_DEV_BUS You need to depend on the MFD Core too. > + help > + Select this to get support for the QNAP MCU device found in > + several devices of QNAP network attached storages. s/storages/storage devices/ > + > + It implements the base serial protocol to talk to the device > + and provides functions for the other parts to hook into. > + > config MFD_RSMU_I2C > tristate "Renesas Synchronization Management Unit with I2C" > depends on I2C && OF > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index 02b651cd75352..fc8b825725ff2 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -286,5 +286,7 @@ obj-$(CONFIG_MFD_INTEL_M10_BMC_PMCI) += intel-m10-bmc-pmci.o > obj-$(CONFIG_MFD_ATC260X) += atc260x-core.o > obj-$(CONFIG_MFD_ATC260X_I2C) += atc260x-i2c.o > > +obj-$(CONFIG_MFD_QNAP_MCU) += qnap-mcu.o > + > obj-$(CONFIG_MFD_RSMU_I2C) += rsmu_i2c.o rsmu_core.o > obj-$(CONFIG_MFD_RSMU_SPI) += rsmu_spi.o rsmu_core.o > diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c > new file mode 100644 > index 0000000000000..be73bd88d7608 > --- /dev/null > +++ b/drivers/mfd/qnap-mcu.c > @@ -0,0 +1,358 @@ > +// SPDX-License-Identifier: GPL-2.0-only > + Superfluous newline. > +/* > + * MFD core driver for the MCU in Qnap NAS devices that is connected No such thing as an "MFD". Please describe the device. Is it QNAP or Qnap? Please be consistent. > + * via a dedicated UART port > + * > + * Copyright (C) 2024 Heiko Stuebner > + */ > + > +#include What is this used for? > +#include > +#include > +#include > +#include > +#include > +#include > +#include Alphabetical. > +/* The longest command found so far is 5 bytes long */ > +#define QNAP_MCU_MAX_CMD_SIZE 5 > +#define QNAP_MCU_MAX_DATA_SIZE 36 > +#define QNAP_MCU_CHECKSUM_SIZE 1 > + > +#define QNAP_MCU_RX_BUFFER_SIZE \ > + (QNAP_MCU_MAX_DATA_SIZE + QNAP_MCU_CHECKSUM_SIZE) > + > +#define QNAP_MCU_TX_BUFFER_SIZE \ > + (QNAP_MCU_MAX_CMD_SIZE + QNAP_MCU_CHECKSUM_SIZE) > + > +/** > + * struct qnap_mcu_reply - Reply to a command > + * > + * @data: Buffer to store reply payload in > + * @length: Expected reply length, including the checksum > + * @received: So far received number of bytes "Received number of Bytes, so far" > + * @done: Reply received completely "Triggered when the entire reply has been received" > + */ > +struct qnap_mcu_reply { > + u8 *data; > + size_t length; > + size_t received; > + struct completion done; > +}; > + > +/** > + * struct qnap_mcu - QNAP NAS embedded controller > + * > + * @serdev: Pointer to underlying serdev > + * @bus_lock: Lock to serialize access to the device > + * @reply_lock: Lock protecting @reply > + * @reply: Pointer to memory to store reply payload > + * @variant: Device variant specific information > + * @version: MCU firmware version > + */ > +struct qnap_mcu { > + struct serdev_device *serdev; > + /* Serialize access to the device */ Comments and K-doc is OOT. > + struct mutex bus_lock; > + /* Protect access to the reply pointer */ > + struct mutex reply_lock; > + struct qnap_mcu_reply *reply; > + const struct qnap_mcu_variant *variant; > + u8 version[4]; Please define all magic numbers. > +}; > + > +/* > + * The QNAP-MCU uses a basic XOR checksum. > + * It is always the last byte and XORs the whole previous message. > + */ > +static u8 qnap_mcu_csum(const u8 *buf, size_t size) > +{ > + u8 csum = 0; > + > + while (size--) > + csum ^= *buf++; > + > + return csum; > +} > + > +static int qnap_mcu_write(struct qnap_mcu *sp, const u8 *data, u8 data_size) > +{ > + unsigned char tx[QNAP_MCU_TX_BUFFER_SIZE]; > + size_t length = data_size + QNAP_MCU_CHECKSUM_SIZE; > + > + if (WARN_ON(length > sizeof(tx))) Are you sure you want to warn like this here? A dev_err() seems more appropriate. > + return -ENOMEM; Why does this condition signify OOM? Maybe consider -EINVAL? > + memcpy(tx, data, data_size); > + tx[data_size] = qnap_mcu_csum(data, data_size); > + > + print_hex_dump_debug("qnap-mcu tx: ", DUMP_PREFIX_NONE, > + 16, 1, tx, length, false); You can remove this now development is complete. > + return serdev_device_write(sp->serdev, tx, length, HZ); > +} > + > +static size_t qnap_mcu_receive_buf(struct serdev_device *serdev, > + const u8 *buf, size_t size) Use up to 100-chars to prevent early line-wrap. > +{ > + struct device *dev = &serdev->dev; > + struct qnap_mcu *mcu = dev_get_drvdata(dev); > + struct qnap_mcu_reply *reply = mcu->reply; > + const u8 *src = buf; > + const u8 *end = buf + size; > + > + mutex_lock(&mcu->reply_lock); > + if (!reply) { > + dev_warn(dev, "received %zu bytes, we were not waiting for\n", > + size); > + mutex_unlock(&mcu->reply_lock); guard(mutex)? > + return size; > + } > + > + while (src < end) { > + reply->data[reply->received] = *src++; > + reply->received++; > + > + if (reply->received == reply->length) { > + complete(&reply->done); > + mutex_unlock(&mcu->reply_lock); > + > + /* > + * We report the consumed number of bytes. If there > + * are still bytes remaining (though there shouldn't) > + * the serdev layer will re-execute this handler with > + * the remainder of the Rx bytes. > + */ > + return src - buf; > + } > + } > + > + /* > + * The only way to get out of the above loop and end up here > + * is through consuming all of the supplied data, so here we > + * report that we processed it all. > + */ > + mutex_unlock(&mcu->reply_lock); > + return size; > +} > + > +static const struct serdev_device_ops qnap_mcu_serdev_device_ops = { > + .receive_buf = qnap_mcu_receive_buf, > + .write_wakeup = serdev_device_write_wakeup, > +}; > + > +int qnap_mcu_exec(struct qnap_mcu *mcu, > + const u8 *cmd_data, size_t cmd_data_size, > + u8 *reply_data, size_t reply_data_size) > +{ > + unsigned char rx[QNAP_MCU_RX_BUFFER_SIZE]; > + size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE; > + struct qnap_mcu_reply reply = { > + .data = rx, > + .length = length, > + .received = 0, > + .done = COMPLETION_INITIALIZER_ONSTACK(reply.done), > + }; > + int ret; > + > + if (WARN_ON(length > sizeof(rx))) > + return -ENOMEM; > + > + mutex_lock(&mcu->bus_lock); > + > + mutex_lock(&mcu->reply_lock); > + mcu->reply = &reply; > + mutex_unlock(&mcu->reply_lock); > + > + qnap_mcu_write(mcu, cmd_data, cmd_data_size); > + > + if (!wait_for_completion_timeout(&reply.done, > + msecs_to_jiffies(500))) { > + dev_err(&mcu->serdev->dev, "Command timeout\n"); > + ret = -ETIMEDOUT; > + } else { > + u8 crc = qnap_mcu_csum(rx, reply_data_size); > + > + print_hex_dump_debug("qnap-mcu rx: ", DUMP_PREFIX_NONE, > + 16, 1, rx, length, false); > + > + if (crc != rx[reply_data_size]) { > + dev_err(&mcu->serdev->dev, > + "Checksum 0x%02x wrong for data\n", crc); > + ret = -EIO; > + } else { > + memcpy(reply_data, rx, reply_data_size); > + ret = 0; > + } > + } > + > + mutex_lock(&mcu->reply_lock); > + mcu->reply = NULL; > + mutex_unlock(&mcu->reply_lock); > + > + mutex_unlock(&mcu->bus_lock); > + return ret; > +} > +EXPORT_SYMBOL_GPL(qnap_mcu_exec); > + > +int qnap_mcu_exec_with_ack(struct qnap_mcu *mcu, > + const u8 *cmd_data, size_t cmd_data_size) > +{ > + u8 ack[2]; > + int ret; > + > + ret = qnap_mcu_exec(mcu, cmd_data, cmd_data_size, ack, sizeof(ack)); > + if (ret) > + return ret; > + > + /* Should return @0 */ > + if (ack[0] != 0x40 || ack[1] != 0x30) { Why not use the char variants? > + dev_err(&mcu->serdev->dev, "Did not receive ack\n"); > + return -EIO; > + } > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(qnap_mcu_exec_with_ack); > + > +const struct qnap_mcu_variant *qnap_mcu_get_variant_data(struct qnap_mcu *mcu) > +{ > + return mcu->variant; > +} > +EXPORT_SYMBOL_GPL(qnap_mcu_get_variant_data); > + > +static int qnap_mcu_get_version(struct qnap_mcu *mcu) > +{ > + u8 cmd[] = { > + [0] = 0x25, /* % */ > + [1] = 0x56 /* V */ > + }; > + u8 rx[14]; > + int ret; > + > + ret = qnap_mcu_exec(mcu, cmd, sizeof(cmd), rx, 6); > + if (ret) > + return ret; > + > + memcpy(mcu->version, &rx[2], 4); > + > + return 0; > +} > + > +/* > + * The MCU controls power to the peripherals but not the CPU. > + * > + * So using the pmic to power off the system keeps the MCU and hard-drives > + * running. This also then prevents the system from turning back on until > + * the MCU is turned off by unplugging the power-cable. > + * Turning off the MCU alone on the other hand turns off the hard-drives, > + * LEDs, etc while the main SoC stays running - including its network ports. > + */ > +static int qnap_mcu_power_off(struct sys_off_data *data) > +{ > + struct qnap_mcu *mcu = data->cb_data; > + int ret; > + u8 cmd[] = { > + [0] = 0x40, /* @ */ > + [1] = 0x43, /* C */ > + [2] = 0x30 /* 0 */ > + }; u8 cmd [] = { '@', 'C', '0' }; ? > + dev_dbg(&mcu->serdev->dev, "running MCU poweroff\n"); This is unlikely to be useful post-development. > + ret = qnap_mcu_exec_with_ack(mcu, cmd, sizeof(cmd)); > + if (ret) { > + dev_err(&mcu->serdev->dev, "MCU poweroff failed %d\n", ret); > + return NOTIFY_STOP; > + } > + > + return NOTIFY_DONE; > +} > + > +static const struct qnap_mcu_variant qnap_ts433_mcu = { > + .baud_rate = 115200, > + .num_drives = 4, > + .fan_pwm_min = 51, /* specified in original model.conf */ Please start sentences with upper-case chars. > + .fan_pwm_max = 255, > + .usb_led = true, > +}; > + > +static const struct of_device_id qnap_mcu_dt_ids[] = { > + { .compatible = "qnap,ts433-mcu", .data = &qnap_ts433_mcu }, > + { /* sentinel */ } > +}; > +MODULE_DEVICE_TABLE(of, qnap_mcu_dt_ids); > + > +static const struct mfd_cell qnap_mcu_subdevs[] = { > + { .name = "qnap-mcu-input", }, > + { .name = "qnap-mcu-leds", }, > + { .name = "qnap-mcu-hwmon", } > +}; > + > +static int qnap_mcu_probe(struct serdev_device *serdev) > +{ > + struct device *dev = &serdev->dev; > + struct qnap_mcu *mcu; > + int ret; > + > + mcu = devm_kzalloc(dev, sizeof(*mcu), GFP_KERNEL); > + if (!mcu) > + return -ENOMEM; > + > + mcu->serdev = serdev; > + dev_set_drvdata(dev, mcu); > + > + mcu->variant = of_device_get_match_data(dev); > + if (!mcu->variant) > + return -ENODEV; > + > + mutex_init(&mcu->bus_lock); > + mutex_init(&mcu->reply_lock); Can you not get away with a single lock? > + serdev_device_set_client_ops(serdev, &qnap_mcu_serdev_device_ops); > + ret = devm_serdev_device_open(dev, serdev); > + if (ret) > + return ret; > + > + serdev_device_set_baudrate(serdev, mcu->variant->baud_rate); > + serdev_device_set_flow_control(serdev, false); > + > + ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE); > + if (ret) { > + dev_err(dev, "Failed to set parity\n"); > + return ret; > + } > + > + ret = qnap_mcu_get_version(mcu); > + if (ret) > + return ret; > + > + ret = devm_register_sys_off_handler(dev, > + SYS_OFF_MODE_POWER_OFF_PREPARE, > + SYS_OFF_PRIO_DEFAULT, > + &qnap_mcu_power_off, mcu); > + if (ret) > + return dev_err_probe(dev, ret, > + "failed to register poweroff handler\n"); > + > + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, qnap_mcu_subdevs, > + ARRAY_SIZE(qnap_mcu_subdevs), NULL, 0, NULL); > + if (ret) > + return dev_err_probe(dev, ret, "adding qnap mfd devices failed\n"); "Failed to add child devices" > + > + return 0; > +} > + > +static struct serdev_device_driver qnap_mcu_drv = { > + .probe = qnap_mcu_probe, > + .driver = { > + .name = "qnap-mcu", > + .of_match_table = qnap_mcu_dt_ids, > + }, > +}; This tabbing is odd. > +module_serdev_device_driver(qnap_mcu_drv); > + > +MODULE_LICENSE("GPL"); Suggest this goes at the bottom. > +MODULE_AUTHOR("Heiko Stuebner "); > +MODULE_DESCRIPTION("QNAP MCU core driver"); > diff --git a/include/linux/mfd/qnap-mcu.h b/include/linux/mfd/qnap-mcu.h > new file mode 100644 > index 0000000000000..f954815d3025b > --- /dev/null > +++ b/include/linux/mfd/qnap-mcu.h > @@ -0,0 +1,28 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > + As above. > +/* > + * Core definitions for QNAP MCU MFD driver. > + * Copyright (C) 2024 Heiko Stuebner > + */ > + > +#ifndef _LINUX_QNAP_MCU_H_ > +#define _LINUX_QNAP_MCU_H_ > + > +struct qnap_mcu; > + > +struct qnap_mcu_variant { > + u32 baud_rate; > + int num_drives; > + int fan_pwm_min; > + int fan_pwm_max; > + bool usb_led; > +}; > + > +int qnap_mcu_exec(struct qnap_mcu *mcu, > + const u8 *cmd_data, size_t cmd_data_size, > + u8 *reply_data, size_t reply_data_size); > +int qnap_mcu_exec_with_ack(struct qnap_mcu *mcu, > + const u8 *cmd_data, size_t cmd_data_size); > +const struct qnap_mcu_variant *qnap_mcu_get_variant_data(struct qnap_mcu *mcu); > + > +#endif /* _LINUX_QNAP_MCU_H_ */ > -- > 2.39.2 > -- 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 27502C3DA4A for ; Fri, 16 Aug 2024 17:14:39 +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=08Fg/7ZfTziZmAw4g8226JyGgUY2XrGWso41ZvxAoSA=; b=f+nqe9EdGCHErB XeeQ/e7G8CxZDNLyBlZiIgwKNUKAlSHrplg8CgxGCTptOJchpXpNcrhD3nkpL2QAYOvzCLdYB0SY/ evy/beUSUZckBk0WSKwnY73C91WoE1Umht8Yjq6rCSXQlFWIkAAQ+QqX/iQNvc/zOxGHsEmwYANfM pa1AamV1T3GetPIHxsfz3iFjz1+E9FHmajfkpsnPc+em0sHHX8+43OE+8L7blLHY6gOC95pj9rT5s SmQd3T+3N8z1O1t6d3k13s+/r4P3JfBngBKelqCBBcAOzTyzedgf7b+M+LVRSbVRZtrFojRxNTzcW fFAxnzEJgy40rqOzEOPA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sf0X2-0000000DgbI-3QSd; Fri, 16 Aug 2024 17:14:32 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sf0WF-0000000DgNb-1Mur; Fri, 16 Aug 2024 17:13:45 +0000 Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by dfw.source.kernel.org (Postfix) with ESMTP id 8486561DBB; Fri, 16 Aug 2024 17:13:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF4BDC32782; Fri, 16 Aug 2024 17:13:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723828422; bh=VuO0lhV6v1fhCig+xAS2g1N9ON3e+KySvA10Zp/DwMw=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=rj4qRNPJr+Krim3X1SYt9Oel1PAau46i7EGUSsB+OnWDim/lksrcq9QGm4rPZabLU 4u+w7kcAfdKMqFsFwrChhRggKfkBrdnxHpg2JqtqWZ3QI2WwmaTZBVrmN/zYBsJlpH rXJSQXJ0vi17SAq6ZTVzjPXRMkcGjSS4/q0f8cubSQkY4yi6IIorqTsAsxOHnn7+qS CuhgV+jsuA89CuZyB8S/bHfrGStX9rY7LiSN8vuPiDSourpIzwmREBpXUg8yyM/p2Z P53yvYHDYlwHZDEulL5vZEYfTdDkcGcrqgxYl2Ce0OQpDw1OodLbFHnb+SD7MfD6Q5 3SE2DpgK/CM8w== Date: Fri, 16 Aug 2024 18:13:36 +0100 From: Lee Jones To: Heiko Stuebner Cc: jdelvare@suse.com, linux@roeck-us.net, dmitry.torokhov@gmail.com, pavel@ucw.cz, robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, ukleinek@debian.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-hwmon@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org Subject: Re: [PATCH v4 2/7] mfd: add base driver for qnap-mcu devices Message-ID: <20240816171336.GF5853@google.com> References: <20240810184743.277248-1-heiko@sntech.de> <20240810184743.277248-3-heiko@sntech.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20240810184743.277248-3-heiko@sntech.de> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240816_101343_552869_E27C5EB0 X-CRM114-Status: GOOD ( 50.36 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org T24gU2F0LCAxMCBBdWcgMjAyNCwgSGVpa28gU3R1ZWJuZXIgd3JvdGU6Cgo+IFRoZXNlIE1DVXMg YXJlIHVzZWQgaW4gbmV0d29yay1hdHRhY2hlZC1zdG9yYWdlIGRldmljZXMgbWFkZSBieSBRTkFQ Cj4gYW5kIHByb3ZpZGUgYWRkaXRpb25hbCBmdW5jdGlvbmFsaXR5IHRvIHRoZSBzeXN0ZW0uCj4g Cj4gVGhpcyBhZGRzIHRoZSBiYXNlIGRyaXZlciB0aGF0IGltcGxlbWVudHMgdGhlIHNlcmlhbCBw cm90b2NvbCB2aWEKPiBzZXJkZXYgYW5kIGFkZGl0aW9uYWxseSBob29rcyBpbnRvIHRoZSBwb3dl cm9mZiBoYW5kbGVycyB0byB0dXJuCj4gb2ZmIHRoZSBwYXJ0cyBvZiB0aGUgc3lzdGVtIG5vdCBz dXBwbGllZCBieSB0aGUgZ2VuZXJhbCBQTUlDLgo+IAo+IFR1cm5pbmcgb2ZmIChhdCBsZWFzdCB0 aGUgVFN4MzMgZGV2aWNlcyB1c2luZyBSb2NrY2hpcCBTb0NzKSBpcyB0d29mb2xkLgoKVGhpcyBz ZW50ZW5jZSBkb2Vzbid0IG1ha2Ugc2Vuc2UuCgoidHdvZm9sZCIgbWVhbnMgInRpbWVzIChtdWx0 aXBseSBieSkgdHdvIi4KCj4gVHVybmluZyBvZmYgdGhlIE1DVSBkb2VzIG5vdCB0dXJuIG9mZiB0 aGUgU29DIGFuZCB0dXJuaW5nIG9mZiB0aGUgU29DCj4gZG9lcyBub3QgdHVybiBvZmYgdGhlIGhh cmQtZHJpdmVzLiBBbmQgaWYgdGhlIE1DVSBpcyBub3QgdHVybmVkIG9mZiwKPiB0aGUgc3lzdGVt IGFsc28gd29uJ3Qgc3RhcnQgYWdhaW4gdW50aWwgaXQgaXMgdW5wbHVnZ2VkIGZyb20gcG93ZXIu Cj4gCj4gU28gb24gc2h1dGRvd24gdGhlIE1DVSBuZWVkcyB0byBiZSB0dXJuZWQgb2ZmIGJlZm9y ZSB0aGUgZ2VuZXJhbCBQTUlDLgo+IAo+IFRoZSBwcm90b2NvbCBzcG9rZW4gYnkgdGhlIE1DVSBp cyBzYWRseSBub3QgZG9jdW1lbnRlZCwgYnV0IHdhcwo+IG9idGFpbmVkIGJ5IGxpc3RlbmluZyB0 byB0aGUgY2hhdHRlciBvbiB0aGUgc2VyaWFsIHBvcnQsIGFzIHRoYW5rZnVsbHkKPiB0aGUgImhh bF9hcHAiIHByb2dyYW0gZnJvbSBRTkFQcyBmaXJtd2FyZSBhbGxvd3MgdHJpZ2dlcmluZyBhbGwv bW9zdAo+IE1DVSBhY3Rpb25zIGZyb20gdGhlIGNvbW1hbmQgbGluZS4KPiAKPiBUaGUgaW1wbGVt ZW50YXRpb24gb2YgaG93IHRvIHRhbGsgdG8gdGhlIHNlcmlhbCBkZXZpY2UgZ290IHNvbWUKPiBp bnNwaXJhdGlvbiBmcm9tIHRoZSByYXZlLXNwIHNlcnZkZXYgbWZkLgoKIk1GRCIgb3IgYmV0dGVy IHlldCAiZHJpdmVyIi4KCj4gU2lnbmVkLW9mZi1ieTogSGVpa28gU3R1ZWJuZXIgPGhlaWtvQHNu dGVjaC5kZT4KPiAtLS0KPiAgTUFJTlRBSU5FUlMgICAgICAgICAgICAgICAgICB8ICAgNiArCj4g IGRyaXZlcnMvbWZkL0tjb25maWcgICAgICAgICAgfCAgMTAgKwo+ICBkcml2ZXJzL21mZC9NYWtl ZmlsZSAgICAgICAgIHwgICAyICsKPiAgZHJpdmVycy9tZmQvcW5hcC1tY3UuYyAgICAgICB8IDM1 OCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ICBpbmNsdWRlL2xpbnV4L21m ZC9xbmFwLW1jdS5oIHwgIDI4ICsrKwo+ICA1IGZpbGVzIGNoYW5nZWQsIDQwNCBpbnNlcnRpb25z KCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21mZC9xbmFwLW1jdS5jCj4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBpbmNsdWRlL2xpbnV4L21mZC9xbmFwLW1jdS5oCj4gCj4gZGlmZiAtLWdp dCBhL01BSU5UQUlORVJTIGIvTUFJTlRBSU5FUlMKPiBpbmRleCA4NzY2ZjNlNWU4N2UwLi5mOWY2 MDVhM2MxMmE0IDEwMDY0NAo+IC0tLSBhL01BSU5UQUlORVJTCj4gKysrIGIvTUFJTlRBSU5FUlMK PiBAQCAtMTg2NTIsNiArMTg2NTIsMTIgQEAgTDoJbGludXgtbWVkaWFAdmdlci5rZXJuZWwub3Jn Cj4gIFM6CU9kZCBGaXhlcwo+ICBGOglkcml2ZXJzL21lZGlhL3R1bmVycy9xbTFkMWMwMDQyKgo+ ICAKPiArUU5BUCBNQ1UgRFJJVkVSCj4gK006CUhlaWtvIFN0dWVibmVyIDxoZWlrb0BzbnRlY2gu ZGU+Cj4gK1M6CU1haW50YWluZWQKPiArRjoJZHJpdmVycy9tZmQvcW5hcC1tY3UuYwo+ICtGOglp bmNsdWRlL2xpbnV4L3FuYXAtbWN1LmgKPiArCj4gIFFOWDQgRklMRVNZU1RFTQo+ICBNOglBbmRl cnMgTGFyc2VuIDxhbEBhbGFyc2VuLm5ldD4KPiAgUzoJTWFpbnRhaW5lZAo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL21mZC9LY29uZmlnIGIvZHJpdmVycy9tZmQvS2NvbmZpZwo+IGluZGV4IGJjOGJl MmU1OTNiNmIuLmNhNzI4OWU5MDZhN2IgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9tZmQvS2NvbmZp Zwo+ICsrKyBiL2RyaXZlcnMvbWZkL0tjb25maWcKPiBAQCAtMjM2Miw2ICsyMzYyLDE2IEBAIGNv bmZpZyBNRkRfSU5URUxfTTEwX0JNQ19QTUNJCj4gIAkgIGFkZGl0aW9uYWwgZHJpdmVycyBtdXN0 IGJlIGVuYWJsZWQgaW4gb3JkZXIgdG8gdXNlIHRoZSBmdW5jdGlvbmFsaXR5Cj4gIAkgIG9mIHRo ZSBkZXZpY2UuCj4gIAo+ICtjb25maWcgTUZEX1FOQVBfTUNVCj4gKwl0cmlzdGF0ZSAiUU5BUCBN Q1UgY29yZSBkcml2ZXIiCgpOb3cncyB0aGUgdGltZSB0byBleHBhbmQgIk1DVSIKCj4gKwlkZXBl bmRzIG9uIFNFUklBTF9ERVZfQlVTCgpZb3UgbmVlZCB0byBkZXBlbmQgb24gdGhlIE1GRCBDb3Jl IHRvby4KCj4gKwloZWxwCj4gKwkgIFNlbGVjdCB0aGlzIHRvIGdldCBzdXBwb3J0IGZvciB0aGUg UU5BUCBNQ1UgZGV2aWNlIGZvdW5kIGluCj4gKwkgIHNldmVyYWwgZGV2aWNlcyBvZiBRTkFQIG5l dHdvcmsgYXR0YWNoZWQgc3RvcmFnZXMuCgpzL3N0b3JhZ2VzL3N0b3JhZ2UgZGV2aWNlcy8KCj4g Kwo+ICsJICBJdCBpbXBsZW1lbnRzIHRoZSBiYXNlIHNlcmlhbCBwcm90b2NvbCB0byB0YWxrIHRv IHRoZSBkZXZpY2UKPiArCSAgYW5kIHByb3ZpZGVzIGZ1bmN0aW9ucyBmb3IgdGhlIG90aGVyIHBh cnRzIHRvIGhvb2sgaW50by4KPiArCj4gIGNvbmZpZyBNRkRfUlNNVV9JMkMKPiAgCXRyaXN0YXRl ICJSZW5lc2FzIFN5bmNocm9uaXphdGlvbiBNYW5hZ2VtZW50IFVuaXQgd2l0aCBJMkMiCj4gIAlk ZXBlbmRzIG9uIEkyQyAmJiBPRgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21mZC9NYWtlZmlsZSBi L2RyaXZlcnMvbWZkL01ha2VmaWxlCj4gaW5kZXggMDJiNjUxY2Q3NTM1Mi4uZmM4YjgyNTcyNWZm MiAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL21mZC9NYWtlZmlsZQo+ICsrKyBiL2RyaXZlcnMvbWZk L01ha2VmaWxlCj4gQEAgLTI4Niw1ICsyODYsNyBAQCBvYmotJChDT05GSUdfTUZEX0lOVEVMX00x MF9CTUNfUE1DSSkgICArPSBpbnRlbC1tMTAtYm1jLXBtY2kubwo+ICBvYmotJChDT05GSUdfTUZE X0FUQzI2MFgpCSs9IGF0YzI2MHgtY29yZS5vCj4gIG9iai0kKENPTkZJR19NRkRfQVRDMjYwWF9J MkMpCSs9IGF0YzI2MHgtaTJjLm8KPiAgCj4gK29iai0kKENPTkZJR19NRkRfUU5BUF9NQ1UpCSs9 IHFuYXAtbWN1Lm8KPiArCj4gIG9iai0kKENPTkZJR19NRkRfUlNNVV9JMkMpCSs9IHJzbXVfaTJj Lm8gcnNtdV9jb3JlLm8KPiAgb2JqLSQoQ09ORklHX01GRF9SU01VX1NQSSkJKz0gcnNtdV9zcGku byByc211X2NvcmUubwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21mZC9xbmFwLW1jdS5jIGIvZHJp dmVycy9tZmQvcW5hcC1tY3UuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAw MDAwMDAwMC4uYmU3M2JkODhkNzYwOAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL21m ZC9xbmFwLW1jdS5jCj4gQEAgLTAsMCArMSwzNTggQEAKPiArLy8gU1BEWC1MaWNlbnNlLUlkZW50 aWZpZXI6IEdQTC0yLjAtb25seQo+ICsKClN1cGVyZmx1b3VzIG5ld2xpbmUuCgo+ICsvKgo+ICsg KiBNRkQgY29yZSBkcml2ZXIgZm9yIHRoZSBNQ1UgaW4gUW5hcCBOQVMgZGV2aWNlcyB0aGF0IGlz IGNvbm5lY3RlZAoKTm8gc3VjaCB0aGluZyBhcyBhbiAiTUZEIi4gIFBsZWFzZSBkZXNjcmliZSB0 aGUgZGV2aWNlLgoKSXMgaXQgUU5BUCBvciBRbmFwPyAgUGxlYXNlIGJlIGNvbnNpc3RlbnQuCgo+ ICsgKiB2aWEgYSBkZWRpY2F0ZWQgVUFSVCBwb3J0Cj4gKyAqCj4gKyAqIENvcHlyaWdodCAoQykg MjAyNCBIZWlrbyBTdHVlYm5lciA8aGVpa29Ac250ZWNoLmRlPgo+ICsgKi8KPiArCj4gKyNpbmNs dWRlIDxsaW51eC9leHBvcnQuaD4KCldoYXQgaXMgdGhpcyB1c2VkIGZvcj8KCj4gKyNpbmNsdWRl IDxsaW51eC9zbGFiLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tZmQvY29yZS5oPgo+ICsjaW5jbHVk ZSA8bGludXgvbWZkL3FuYXAtbWN1Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPiAr I2luY2x1ZGUgPGxpbnV4L29mLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWJvb3QuaD4KPiArI2lu Y2x1ZGUgPGxpbnV4L3NlcmRldi5oPgoKQWxwaGFiZXRpY2FsLgoKPiArLyogVGhlIGxvbmdlc3Qg Y29tbWFuZCBmb3VuZCBzbyBmYXIgaXMgNSBieXRlcyBsb25nICovCj4gKyNkZWZpbmUgUU5BUF9N Q1VfTUFYX0NNRF9TSVpFCQk1Cj4gKyNkZWZpbmUgUU5BUF9NQ1VfTUFYX0RBVEFfU0laRQkJMzYK PiArI2RlZmluZSBRTkFQX01DVV9DSEVDS1NVTV9TSVpFCQkxCj4gKwo+ICsjZGVmaW5lIFFOQVBf TUNVX1JYX0JVRkZFUl9TSVpFCQlcCj4gKwkJKFFOQVBfTUNVX01BWF9EQVRBX1NJWkUgKyBRTkFQ X01DVV9DSEVDS1NVTV9TSVpFKQo+ICsKPiArI2RlZmluZSBRTkFQX01DVV9UWF9CVUZGRVJfU0la RQkJXAo+ICsJCShRTkFQX01DVV9NQVhfQ01EX1NJWkUgKyBRTkFQX01DVV9DSEVDS1NVTV9TSVpF KQo+ICsKPiArLyoqCj4gKyAqIHN0cnVjdCBxbmFwX21jdV9yZXBseSAtIFJlcGx5IHRvIGEgY29t bWFuZAo+ICsgKgo+ICsgKiBAZGF0YToJQnVmZmVyIHRvIHN0b3JlIHJlcGx5IHBheWxvYWQgaW4K PiArICogQGxlbmd0aDoJRXhwZWN0ZWQgcmVwbHkgbGVuZ3RoLCBpbmNsdWRpbmcgdGhlIGNoZWNr c3VtCj4gKyAqIEByZWNlaXZlZDoJU28gZmFyIHJlY2VpdmVkIG51bWJlciBvZiBieXRlcwoKIlJl Y2VpdmVkIG51bWJlciBvZiBCeXRlcywgc28gZmFyIgoKPiArICogQGRvbmU6CVJlcGx5IHJlY2Vp dmVkIGNvbXBsZXRlbHkKCiJUcmlnZ2VyZWQgd2hlbiB0aGUgZW50aXJlIHJlcGx5IGhhcyBiZWVu IHJlY2VpdmVkIgoKPiArICovCj4gK3N0cnVjdCBxbmFwX21jdV9yZXBseSB7Cj4gKwl1OCAqZGF0 YTsKPiArCXNpemVfdCBsZW5ndGg7Cj4gKwlzaXplX3QgcmVjZWl2ZWQ7Cj4gKwlzdHJ1Y3QgY29t cGxldGlvbiBkb25lOwo+ICt9Owo+ICsKPiArLyoqCj4gKyAqIHN0cnVjdCBxbmFwX21jdSAtIFFO QVAgTkFTIGVtYmVkZGVkIGNvbnRyb2xsZXIKPiArICoKPiArICogQHNlcmRldjoJUG9pbnRlciB0 byB1bmRlcmx5aW5nIHNlcmRldgo+ICsgKiBAYnVzX2xvY2s6CUxvY2sgdG8gc2VyaWFsaXplIGFj Y2VzcyB0byB0aGUgZGV2aWNlCj4gKyAqIEByZXBseV9sb2NrOglMb2NrIHByb3RlY3RpbmcgQHJl cGx5Cj4gKyAqIEByZXBseToJUG9pbnRlciB0byBtZW1vcnkgdG8gc3RvcmUgcmVwbHkgcGF5bG9h ZAo+ICsgKiBAdmFyaWFudDoJRGV2aWNlIHZhcmlhbnQgc3BlY2lmaWMgaW5mb3JtYXRpb24KPiAr ICogQHZlcnNpb246CU1DVSBmaXJtd2FyZSB2ZXJzaW9uCj4gKyAqLwo+ICtzdHJ1Y3QgcW5hcF9t Y3Ugewo+ICsJc3RydWN0IHNlcmRldl9kZXZpY2UgKnNlcmRldjsKPiArCS8qIFNlcmlhbGl6ZSBh Y2Nlc3MgdG8gdGhlIGRldmljZSAqLwoKQ29tbWVudHMgYW5kIEstZG9jIGlzIE9PVC4KCj4gKwlz dHJ1Y3QgbXV0ZXggYnVzX2xvY2s7Cj4gKwkvKiBQcm90ZWN0IGFjY2VzcyB0byB0aGUgcmVwbHkg cG9pbnRlciAqLwo+ICsJc3RydWN0IG11dGV4IHJlcGx5X2xvY2s7Cj4gKwlzdHJ1Y3QgcW5hcF9t Y3VfcmVwbHkgKnJlcGx5Owo+ICsJY29uc3Qgc3RydWN0IHFuYXBfbWN1X3ZhcmlhbnQgKnZhcmlh bnQ7Cj4gKwl1OCB2ZXJzaW9uWzRdOwoKUGxlYXNlIGRlZmluZSBhbGwgbWFnaWMgbnVtYmVycy4K Cj4gK307Cj4gKwo+ICsvKgo+ICsgKiBUaGUgUU5BUC1NQ1UgdXNlcyBhIGJhc2ljIFhPUiBjaGVj a3N1bS4KPiArICogSXQgaXMgYWx3YXlzIHRoZSBsYXN0IGJ5dGUgYW5kIFhPUnMgdGhlIHdob2xl IHByZXZpb3VzIG1lc3NhZ2UuCj4gKyAqLwo+ICtzdGF0aWMgdTggcW5hcF9tY3VfY3N1bShjb25z dCB1OCAqYnVmLCBzaXplX3Qgc2l6ZSkKPiArewo+ICsJdTggY3N1bSA9IDA7Cj4gKwo+ICsJd2hp bGUgKHNpemUtLSkKPiArCQljc3VtIF49ICpidWYrKzsKPiArCj4gKwlyZXR1cm4gY3N1bTsKPiAr fQo+ICsKPiArc3RhdGljIGludCBxbmFwX21jdV93cml0ZShzdHJ1Y3QgcW5hcF9tY3UgKnNwLCBj b25zdCB1OCAqZGF0YSwgdTggZGF0YV9zaXplKQo+ICt7Cj4gKwl1bnNpZ25lZCBjaGFyIHR4W1FO QVBfTUNVX1RYX0JVRkZFUl9TSVpFXTsKPiArCXNpemVfdCBsZW5ndGggPSBkYXRhX3NpemUgKyBR TkFQX01DVV9DSEVDS1NVTV9TSVpFOwo+ICsKPiArCWlmIChXQVJOX09OKGxlbmd0aCA+IHNpemVv Zih0eCkpKQoKQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIHdhcm4gbGlrZSB0aGlzIGhlcmU/CgpB IGRldl9lcnIoKSBzZWVtcyBtb3JlIGFwcHJvcHJpYXRlLgoKPiArCQlyZXR1cm4gLUVOT01FTTsK CldoeSBkb2VzIHRoaXMgY29uZGl0aW9uIHNpZ25pZnkgT09NPwoKTWF5YmUgY29uc2lkZXIgLUVJ TlZBTD8KCj4gKwltZW1jcHkodHgsIGRhdGEsIGRhdGFfc2l6ZSk7Cj4gKwl0eFtkYXRhX3NpemVd ID0gcW5hcF9tY3VfY3N1bShkYXRhLCBkYXRhX3NpemUpOwo+ICsKPiArCXByaW50X2hleF9kdW1w X2RlYnVnKCJxbmFwLW1jdSB0eDogIiwgRFVNUF9QUkVGSVhfTk9ORSwKPiArCQkJICAgICAxNiwg MSwgdHgsIGxlbmd0aCwgZmFsc2UpOwoKWW91IGNhbiByZW1vdmUgdGhpcyBub3cgZGV2ZWxvcG1l bnQgaXMgY29tcGxldGUuCgo+ICsJcmV0dXJuIHNlcmRldl9kZXZpY2Vfd3JpdGUoc3AtPnNlcmRl diwgdHgsIGxlbmd0aCwgSFopOwo+ICt9Cj4gKwo+ICtzdGF0aWMgc2l6ZV90IHFuYXBfbWN1X3Jl Y2VpdmVfYnVmKHN0cnVjdCBzZXJkZXZfZGV2aWNlICpzZXJkZXYsCj4gKwkJCQkgICBjb25zdCB1 OCAqYnVmLCBzaXplX3Qgc2l6ZSkKClVzZSB1cCB0byAxMDAtY2hhcnMgdG8gcHJldmVudCBlYXJs eSBsaW5lLXdyYXAuCgo+ICt7Cj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmc2VyZGV2LT5kZXY7 Cj4gKwlzdHJ1Y3QgcW5hcF9tY3UgKm1jdSA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+ICsJc3Ry dWN0IHFuYXBfbWN1X3JlcGx5ICpyZXBseSA9IG1jdS0+cmVwbHk7Cj4gKwljb25zdCB1OCAqc3Jj ID0gYnVmOwo+ICsJY29uc3QgdTggKmVuZCA9IGJ1ZiArIHNpemU7Cj4gKwo+ICsJbXV0ZXhfbG9j aygmbWN1LT5yZXBseV9sb2NrKTsKPiArCWlmICghcmVwbHkpIHsKPiArCQlkZXZfd2FybihkZXYs ICJyZWNlaXZlZCAlenUgYnl0ZXMsIHdlIHdlcmUgbm90IHdhaXRpbmcgZm9yXG4iLAo+ICsJCQkg c2l6ZSk7Cj4gKwkJbXV0ZXhfdW5sb2NrKCZtY3UtPnJlcGx5X2xvY2spOwoKZ3VhcmQobXV0ZXgp PwoKPiArCQlyZXR1cm4gc2l6ZTsKPiArCX0KPiArCj4gKwl3aGlsZSAoc3JjIDwgZW5kKSB7Cj4g KwkJcmVwbHktPmRhdGFbcmVwbHktPnJlY2VpdmVkXSA9ICpzcmMrKzsKPiArCQlyZXBseS0+cmVj ZWl2ZWQrKzsKPiArCj4gKwkJaWYgKHJlcGx5LT5yZWNlaXZlZCA9PSByZXBseS0+bGVuZ3RoKSB7 Cj4gKwkJCWNvbXBsZXRlKCZyZXBseS0+ZG9uZSk7Cj4gKwkJCW11dGV4X3VubG9jaygmbWN1LT5y ZXBseV9sb2NrKTsKPiArCj4gKwkJCS8qCj4gKwkJCSAqIFdlIHJlcG9ydCB0aGUgY29uc3VtZWQg bnVtYmVyIG9mIGJ5dGVzLiBJZiB0aGVyZQo+ICsJCQkgKiBhcmUgc3RpbGwgYnl0ZXMgcmVtYWlu aW5nICh0aG91Z2ggdGhlcmUgc2hvdWxkbid0KQo+ICsJCQkgKiB0aGUgc2VyZGV2IGxheWVyIHdp bGwgcmUtZXhlY3V0ZSB0aGlzIGhhbmRsZXIgd2l0aAo+ICsJCQkgKiB0aGUgcmVtYWluZGVyIG9m IHRoZSBSeCBieXRlcy4KPiArCQkJICovCj4gKwkJCXJldHVybiBzcmMgLSBidWY7Cj4gKwkJfQo+ ICsJfQo+ICsKPiArCS8qCj4gKwkgKiBUaGUgb25seSB3YXkgdG8gZ2V0IG91dCBvZiB0aGUgYWJv dmUgbG9vcCBhbmQgZW5kIHVwIGhlcmUKPiArCSAqIGlzIHRocm91Z2ggY29uc3VtaW5nIGFsbCBv ZiB0aGUgc3VwcGxpZWQgZGF0YSwgc28gaGVyZSB3ZQo+ICsJICogcmVwb3J0IHRoYXQgd2UgcHJv Y2Vzc2VkIGl0IGFsbC4KPiArCSAqLwo+ICsJbXV0ZXhfdW5sb2NrKCZtY3UtPnJlcGx5X2xvY2sp Owo+ICsJcmV0dXJuIHNpemU7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgc2VyZGV2 X2RldmljZV9vcHMgcW5hcF9tY3Vfc2VyZGV2X2RldmljZV9vcHMgPSB7Cj4gKwkucmVjZWl2ZV9i dWYgID0gcW5hcF9tY3VfcmVjZWl2ZV9idWYsCj4gKwkud3JpdGVfd2FrZXVwID0gc2VyZGV2X2Rl dmljZV93cml0ZV93YWtldXAsCj4gK307Cj4gKwo+ICtpbnQgcW5hcF9tY3VfZXhlYyhzdHJ1Y3Qg cW5hcF9tY3UgKm1jdSwKPiArCQkgIGNvbnN0IHU4ICpjbWRfZGF0YSwgc2l6ZV90IGNtZF9kYXRh X3NpemUsCj4gKwkJICB1OCAqcmVwbHlfZGF0YSwgc2l6ZV90IHJlcGx5X2RhdGFfc2l6ZSkKPiAr ewo+ICsJdW5zaWduZWQgY2hhciByeFtRTkFQX01DVV9SWF9CVUZGRVJfU0laRV07Cj4gKwlzaXpl X3QgbGVuZ3RoID0gcmVwbHlfZGF0YV9zaXplICsgUU5BUF9NQ1VfQ0hFQ0tTVU1fU0laRTsKPiAr CXN0cnVjdCBxbmFwX21jdV9yZXBseSByZXBseSA9IHsKPiArCQkuZGF0YSAgICAgPSByeCwKPiAr CQkubGVuZ3RoICAgPSBsZW5ndGgsCj4gKwkJLnJlY2VpdmVkID0gMCwKPiArCQkuZG9uZSAgICAg PSBDT01QTEVUSU9OX0lOSVRJQUxJWkVSX09OU1RBQ0socmVwbHkuZG9uZSksCj4gKwl9Owo+ICsJ aW50IHJldDsKPiArCj4gKwlpZiAoV0FSTl9PTihsZW5ndGggPiBzaXplb2YocngpKSkKPiArCQly ZXR1cm4gLUVOT01FTTsKPiArCj4gKwltdXRleF9sb2NrKCZtY3UtPmJ1c19sb2NrKTsKPiArCj4g KwltdXRleF9sb2NrKCZtY3UtPnJlcGx5X2xvY2spOwo+ICsJbWN1LT5yZXBseSA9ICZyZXBseTsK PiArCW11dGV4X3VubG9jaygmbWN1LT5yZXBseV9sb2NrKTsKPiArCj4gKwlxbmFwX21jdV93cml0 ZShtY3UsIGNtZF9kYXRhLCBjbWRfZGF0YV9zaXplKTsKPiArCj4gKwlpZiAoIXdhaXRfZm9yX2Nv bXBsZXRpb25fdGltZW91dCgmcmVwbHkuZG9uZSwKPiArCQkJCQkgbXNlY3NfdG9famlmZmllcyg1 MDApKSkgewo+ICsJCWRldl9lcnIoJm1jdS0+c2VyZGV2LT5kZXYsICJDb21tYW5kIHRpbWVvdXRc biIpOwo+ICsJCXJldCA9IC1FVElNRURPVVQ7Cj4gKwl9IGVsc2Ugewo+ICsJCXU4IGNyYyA9IHFu YXBfbWN1X2NzdW0ocngsIHJlcGx5X2RhdGFfc2l6ZSk7Cj4gKwo+ICsJCXByaW50X2hleF9kdW1w X2RlYnVnKCJxbmFwLW1jdSByeDogIiwgRFVNUF9QUkVGSVhfTk9ORSwKPiArCQkJCSAgICAgMTYs IDEsIHJ4LCBsZW5ndGgsIGZhbHNlKTsKPiArCj4gKwkJaWYgKGNyYyAhPSByeFtyZXBseV9kYXRh X3NpemVdKSB7Cj4gKwkJCWRldl9lcnIoJm1jdS0+c2VyZGV2LT5kZXYsCj4gKwkJCQkiQ2hlY2tz dW0gMHglMDJ4IHdyb25nIGZvciBkYXRhXG4iLCBjcmMpOwo+ICsJCQlyZXQgPSAtRUlPOwo+ICsJ CX0gZWxzZSB7Cj4gKwkJCW1lbWNweShyZXBseV9kYXRhLCByeCwgcmVwbHlfZGF0YV9zaXplKTsK PiArCQkJcmV0ID0gMDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJbXV0ZXhfbG9jaygmbWN1LT5yZXBs eV9sb2NrKTsKPiArCW1jdS0+cmVwbHkgPSBOVUxMOwo+ICsJbXV0ZXhfdW5sb2NrKCZtY3UtPnJl cGx5X2xvY2spOwo+ICsKPiArCW11dGV4X3VubG9jaygmbWN1LT5idXNfbG9jayk7Cj4gKwlyZXR1 cm4gcmV0Owo+ICt9Cj4gK0VYUE9SVF9TWU1CT0xfR1BMKHFuYXBfbWN1X2V4ZWMpOwo+ICsKPiAr aW50IHFuYXBfbWN1X2V4ZWNfd2l0aF9hY2soc3RydWN0IHFuYXBfbWN1ICptY3UsCj4gKwkJCSAg IGNvbnN0IHU4ICpjbWRfZGF0YSwgc2l6ZV90IGNtZF9kYXRhX3NpemUpCj4gK3sKPiArCXU4IGFj a1syXTsKPiArCWludCByZXQ7Cj4gKwo+ICsJcmV0ID0gcW5hcF9tY3VfZXhlYyhtY3UsIGNtZF9k YXRhLCBjbWRfZGF0YV9zaXplLCBhY2ssIHNpemVvZihhY2spKTsKPiArCWlmIChyZXQpCj4gKwkJ cmV0dXJuIHJldDsKPiArCj4gKwkvKiBTaG91bGQgcmV0dXJuIEAwICovCj4gKwlpZiAoYWNrWzBd ICE9IDB4NDAgfHwgYWNrWzFdICE9IDB4MzApIHsKCldoeSBub3QgdXNlIHRoZSBjaGFyIHZhcmlh bnRzPwoKPiArCQlkZXZfZXJyKCZtY3UtPnNlcmRldi0+ZGV2LCAiRGlkIG5vdCByZWNlaXZlIGFj a1xuIik7Cj4gKwkJcmV0dXJuIC1FSU87Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiAr RVhQT1JUX1NZTUJPTF9HUEwocW5hcF9tY3VfZXhlY193aXRoX2Fjayk7Cj4gKwo+ICtjb25zdCBz dHJ1Y3QgcW5hcF9tY3VfdmFyaWFudCAqcW5hcF9tY3VfZ2V0X3ZhcmlhbnRfZGF0YShzdHJ1Y3Qg cW5hcF9tY3UgKm1jdSkKPiArewo+ICsJcmV0dXJuIG1jdS0+dmFyaWFudDsKPiArfQo+ICtFWFBP UlRfU1lNQk9MX0dQTChxbmFwX21jdV9nZXRfdmFyaWFudF9kYXRhKTsKPiArCj4gK3N0YXRpYyBp bnQgcW5hcF9tY3VfZ2V0X3ZlcnNpb24oc3RydWN0IHFuYXBfbWN1ICptY3UpCj4gK3sKPiArCXU4 IGNtZFtdID0gewo+ICsJCVswXSA9IDB4MjUsIC8qICUgKi8KPiArCQlbMV0gPSAweDU2ICAvKiBW ICovCj4gKwl9Owo+ICsJdTggcnhbMTRdOwo+ICsJaW50IHJldDsKPiArCj4gKwlyZXQgPSBxbmFw X21jdV9leGVjKG1jdSwgY21kLCBzaXplb2YoY21kKSwgcngsIDYpOwo+ICsJaWYgKHJldCkKPiAr CQlyZXR1cm4gcmV0Owo+ICsKPiArCW1lbWNweShtY3UtPnZlcnNpb24sICZyeFsyXSwgNCk7Cj4g Kwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gKy8qCj4gKyAqIFRoZSBNQ1UgY29udHJvbHMgcG93 ZXIgdG8gdGhlIHBlcmlwaGVyYWxzIGJ1dCBub3QgdGhlIENQVS4KPiArICoKPiArICogU28gdXNp bmcgdGhlIHBtaWMgdG8gcG93ZXIgb2ZmIHRoZSBzeXN0ZW0ga2VlcHMgdGhlIE1DVSBhbmQgaGFy ZC1kcml2ZXMKPiArICogcnVubmluZy4gVGhpcyBhbHNvIHRoZW4gcHJldmVudHMgdGhlIHN5c3Rl bSBmcm9tIHR1cm5pbmcgYmFjayBvbiB1bnRpbAo+ICsgKiB0aGUgTUNVIGlzIHR1cm5lZCBvZmYg YnkgdW5wbHVnZ2luZyB0aGUgcG93ZXItY2FibGUuCj4gKyAqIFR1cm5pbmcgb2ZmIHRoZSBNQ1Ug YWxvbmUgb24gdGhlIG90aGVyIGhhbmQgdHVybnMgb2ZmIHRoZSBoYXJkLWRyaXZlcywKPiArICog TEVEcywgZXRjIHdoaWxlIHRoZSBtYWluIFNvQyBzdGF5cyBydW5uaW5nIC0gaW5jbHVkaW5nIGl0 cyBuZXR3b3JrIHBvcnRzLgo+ICsgKi8KPiArc3RhdGljIGludCBxbmFwX21jdV9wb3dlcl9vZmYo c3RydWN0IHN5c19vZmZfZGF0YSAqZGF0YSkKPiArewo+ICsJc3RydWN0IHFuYXBfbWN1ICptY3Ug PSBkYXRhLT5jYl9kYXRhOwo+ICsJaW50IHJldDsKPiArCXU4IGNtZFtdID0gewo+ICsJCVswXSA9 IDB4NDAsIC8qIEAgKi8KPiArCQlbMV0gPSAweDQzLCAvKiBDICovCj4gKwkJWzJdID0gMHgzMCAg LyogMCAqLwo+ICsJfTsKCnU4IGNtZCBbXSA9IHsgJ0AnLCAnQycsICcwJyB9OyAgPwoKCj4gKwlk ZXZfZGJnKCZtY3UtPnNlcmRldi0+ZGV2LCAicnVubmluZyBNQ1UgcG93ZXJvZmZcbiIpOwoKVGhp cyBpcyB1bmxpa2VseSB0byBiZSB1c2VmdWwgcG9zdC1kZXZlbG9wbWVudC4KCj4gKwlyZXQgPSBx bmFwX21jdV9leGVjX3dpdGhfYWNrKG1jdSwgY21kLCBzaXplb2YoY21kKSk7Cj4gKwlpZiAocmV0 KSB7Cj4gKwkJZGV2X2VycigmbWN1LT5zZXJkZXYtPmRldiwgIk1DVSBwb3dlcm9mZiBmYWlsZWQg JWRcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIE5PVElGWV9TVE9QOwo+ICsJfQo+ICsKPiArCXJldHVy biBOT1RJRllfRE9ORTsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBxbmFwX21jdV92 YXJpYW50IHFuYXBfdHM0MzNfbWN1ID0gewo+ICsJLmJhdWRfcmF0ZSA9IDExNTIwMCwKPiArCS5u dW1fZHJpdmVzID0gNCwKPiArCS5mYW5fcHdtX21pbiA9IDUxLCAgLyogc3BlY2lmaWVkIGluIG9y aWdpbmFsIG1vZGVsLmNvbmYgKi8KClBsZWFzZSBzdGFydCBzZW50ZW5jZXMgd2l0aCB1cHBlci1j YXNlIGNoYXJzLgoKPiArCS5mYW5fcHdtX21heCA9IDI1NSwKPiArCS51c2JfbGVkID0gdHJ1ZSwK PiArfTsKPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIHFuYXBfbWN1X2R0 X2lkc1tdID0gewo+ICsJeyAuY29tcGF0aWJsZSA9ICJxbmFwLHRzNDMzLW1jdSIsIC5kYXRhID0g JnFuYXBfdHM0MzNfbWN1IH0sCj4gKwl7IC8qIHNlbnRpbmVsICovIH0KPiArfTsKPiArTU9EVUxF X0RFVklDRV9UQUJMRShvZiwgcW5hcF9tY3VfZHRfaWRzKTsKPiArCj4gK3N0YXRpYyBjb25zdCBz dHJ1Y3QgbWZkX2NlbGwgcW5hcF9tY3Vfc3ViZGV2c1tdID0gewo+ICsJeyAubmFtZSA9ICJxbmFw LW1jdS1pbnB1dCIsIH0sCj4gKwl7IC5uYW1lID0gInFuYXAtbWN1LWxlZHMiLCB9LAo+ICsJeyAu bmFtZSA9ICJxbmFwLW1jdS1od21vbiIsIH0KPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgcW5hcF9t Y3VfcHJvYmUoc3RydWN0IHNlcmRldl9kZXZpY2UgKnNlcmRldikKPiArewo+ICsJc3RydWN0IGRl dmljZSAqZGV2ID0gJnNlcmRldi0+ZGV2Owo+ICsJc3RydWN0IHFuYXBfbWN1ICptY3U7Cj4gKwlp bnQgcmV0Owo+ICsKPiArCW1jdSA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqbWN1KSwgR0ZQ X0tFUk5FTCk7Cj4gKwlpZiAoIW1jdSkKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwltY3Ut PnNlcmRldiA9IHNlcmRldjsKPiArCWRldl9zZXRfZHJ2ZGF0YShkZXYsIG1jdSk7Cj4gKwo+ICsJ bWN1LT52YXJpYW50ID0gb2ZfZGV2aWNlX2dldF9tYXRjaF9kYXRhKGRldik7Cj4gKwlpZiAoIW1j dS0+dmFyaWFudCkKPiArCQlyZXR1cm4gLUVOT0RFVjsKPiArCj4gKwltdXRleF9pbml0KCZtY3Ut PmJ1c19sb2NrKTsKPiArCW11dGV4X2luaXQoJm1jdS0+cmVwbHlfbG9jayk7CgpDYW4geW91IG5v dCBnZXQgYXdheSB3aXRoIGEgc2luZ2xlIGxvY2s/Cgo+ICsJc2VyZGV2X2RldmljZV9zZXRfY2xp ZW50X29wcyhzZXJkZXYsICZxbmFwX21jdV9zZXJkZXZfZGV2aWNlX29wcyk7Cj4gKwlyZXQgPSBk ZXZtX3NlcmRldl9kZXZpY2Vfb3BlbihkZXYsIHNlcmRldik7Cj4gKwlpZiAocmV0KQo+ICsJCXJl dHVybiByZXQ7Cj4gKwo+ICsJc2VyZGV2X2RldmljZV9zZXRfYmF1ZHJhdGUoc2VyZGV2LCBtY3Ut PnZhcmlhbnQtPmJhdWRfcmF0ZSk7Cj4gKwlzZXJkZXZfZGV2aWNlX3NldF9mbG93X2NvbnRyb2wo c2VyZGV2LCBmYWxzZSk7Cj4gKwo+ICsJcmV0ID0gc2VyZGV2X2RldmljZV9zZXRfcGFyaXR5KHNl cmRldiwgU0VSREVWX1BBUklUWV9OT05FKTsKPiArCWlmIChyZXQpIHsKPiArCQlkZXZfZXJyKGRl diwgIkZhaWxlZCB0byBzZXQgcGFyaXR5XG4iKTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ICsK PiArCXJldCA9IHFuYXBfbWN1X2dldF92ZXJzaW9uKG1jdSk7Cj4gKwlpZiAocmV0KQo+ICsJCXJl dHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gZGV2bV9yZWdpc3Rlcl9zeXNfb2ZmX2hhbmRsZXIoZGV2 LAo+ICsJCQkJCSAgICBTWVNfT0ZGX01PREVfUE9XRVJfT0ZGX1BSRVBBUkUsCj4gKwkJCQkJICAg IFNZU19PRkZfUFJJT19ERUZBVUxULAo+ICsJCQkJCSAgICAmcW5hcF9tY3VfcG93ZXJfb2ZmLCBt Y3UpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwKPiAr CQkJCSAgICAgImZhaWxlZCB0byByZWdpc3RlciBwb3dlcm9mZiBoYW5kbGVyXG4iKTsKPiArCj4g KwlyZXQgPSBkZXZtX21mZF9hZGRfZGV2aWNlcyhkZXYsIFBMQVRGT1JNX0RFVklEX0FVVE8sIHFu YXBfbWN1X3N1YmRldnMsCj4gKwkJCQkgICBBUlJBWV9TSVpFKHFuYXBfbWN1X3N1YmRldnMpLCBO VUxMLCAwLCBOVUxMKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZGV2 LCByZXQsICJhZGRpbmcgcW5hcCBtZmQgZGV2aWNlcyBmYWlsZWRcbiIpOwoKIkZhaWxlZCB0byBh ZGQgY2hpbGQgZGV2aWNlcyIKCj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBz dHJ1Y3Qgc2VyZGV2X2RldmljZV9kcml2ZXIgcW5hcF9tY3VfZHJ2ID0gewo+ICsJLnByb2JlCQkJ PSBxbmFwX21jdV9wcm9iZSwKPiArCS5kcml2ZXIgPSB7Cj4gKwkJLm5hbWUJCT0gInFuYXAtbWN1 IiwKPiArCQkub2ZfbWF0Y2hfdGFibGUJPSBxbmFwX21jdV9kdF9pZHMsCj4gKwl9LAo+ICt9OwoK VGhpcyB0YWJiaW5nIGlzIG9kZC4KCj4gK21vZHVsZV9zZXJkZXZfZGV2aWNlX2RyaXZlcihxbmFw X21jdV9kcnYpOwo+ICsKPiArTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKU3VnZ2VzdCB0aGlzIGdv ZXMgYXQgdGhlIGJvdHRvbS4KCj4gK01PRFVMRV9BVVRIT1IoIkhlaWtvIFN0dWVibmVyIDxoZWlr b0BzbnRlY2guZGU+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiUU5BUCBNQ1UgY29yZSBkcml2 ZXIiKTsKPiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9tZmQvcW5hcC1tY3UuaCBiL2luY2x1 ZGUvbGludXgvbWZkL3FuYXAtbWN1LmgKPiBuZXcgZmlsZSBtb2RlIDEwMDY0NAo+IGluZGV4IDAw MDAwMDAwMDAwMDAuLmY5NTQ4MTVkMzAyNWIKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvaW5jbHVk ZS9saW51eC9tZmQvcW5hcC1tY3UuaAo+IEBAIC0wLDAgKzEsMjggQEAKPiArLyogU1BEWC1MaWNl bnNlLUlkZW50aWZpZXI6IEdQTC0yLjArICovCj4gKwoKQXMgYWJvdmUuCgo+ICsvKgo+ICsgKiBD b3JlIGRlZmluaXRpb25zIGZvciBRTkFQIE1DVSBNRkQgZHJpdmVyLgo+ICsgKiBDb3B5cmlnaHQg KEMpIDIwMjQgSGVpa28gU3R1ZWJuZXIgPGhlaWtvQHNudGVjaC5kZT4KPiArICovCj4gKwo+ICsj aWZuZGVmIF9MSU5VWF9RTkFQX01DVV9IXwo+ICsjZGVmaW5lIF9MSU5VWF9RTkFQX01DVV9IXwo+ ICsKPiArc3RydWN0IHFuYXBfbWN1Owo+ICsKPiArc3RydWN0IHFuYXBfbWN1X3ZhcmlhbnQgewo+ ICsJdTMyIGJhdWRfcmF0ZTsKPiArCWludCBudW1fZHJpdmVzOwo+ICsJaW50IGZhbl9wd21fbWlu Owo+ICsJaW50IGZhbl9wd21fbWF4Owo+ICsJYm9vbCB1c2JfbGVkOwo+ICt9Owo+ICsKPiAraW50 IHFuYXBfbWN1X2V4ZWMoc3RydWN0IHFuYXBfbWN1ICptY3UsCj4gKwkJICBjb25zdCB1OCAqY21k X2RhdGEsIHNpemVfdCBjbWRfZGF0YV9zaXplLAo+ICsJCSAgdTggKnJlcGx5X2RhdGEsIHNpemVf dCByZXBseV9kYXRhX3NpemUpOwo+ICtpbnQgcW5hcF9tY3VfZXhlY193aXRoX2FjayhzdHJ1Y3Qg cW5hcF9tY3UgKm1jdSwKPiArCQkJICAgY29uc3QgdTggKmNtZF9kYXRhLCBzaXplX3QgY21kX2Rh dGFfc2l6ZSk7Cj4gK2NvbnN0IHN0cnVjdCBxbmFwX21jdV92YXJpYW50ICpxbmFwX21jdV9nZXRf dmFyaWFudF9kYXRhKHN0cnVjdCBxbmFwX21jdSAqbWN1KTsKPiArCj4gKyNlbmRpZiAvKiBfTElO VVhfUU5BUF9NQ1VfSF8gKi8KPiAtLSAKPiAyLjM5LjIKPiAKCi0tIApMZWUgSm9uZXMgW+adjueQ vOaWr10KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCkxp bnV4LXJvY2tjaGlwIG1haWxpbmcgbGlzdApMaW51eC1yb2NrY2hpcEBsaXN0cy5pbmZyYWRlYWQu b3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtcm9j a2NoaXAK