From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5341FA373E for ; Mon, 24 Oct 2022 11:11:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230094AbiJXLLG (ORCPT ); Mon, 24 Oct 2022 07:11:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230115AbiJXLKu (ORCPT ); Mon, 24 Oct 2022 07:10:50 -0400 Received: from wout2-smtp.messagingengine.com (wout2-smtp.messagingengine.com [64.147.123.25]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73C4546DBB; Mon, 24 Oct 2022 04:10:48 -0700 (PDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id C80023200094; Mon, 24 Oct 2022 07:10:46 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Mon, 24 Oct 2022 07:10:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alistair23.me; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm3; t=1666609846; x= 1666696246; bh=RFLQ5GBjwTscdxLe26sPsHDoE6RCOQt/d0N6c/XvgEY=; b=A zqs3BikT13R+4YIdCL1jUm/h7StEaAKARum3EM5AO17A46+HX+ZRAyU4EpxbOgsy OF1qAuubGctDhRYv95ShTata/ro8JSAhB+svKTrlBdeLlQlPRUGxZoHRBk7leV/2 rOK1U4yjSxvT1UY2iPa+B+rpn1aPEHEbQ67/cD5sveyZHC7fiP/ol82AcO0CoW/L KszJBPFHhbvyIW5z2GMT493wu92IPR8nfzAJUReLLE0jWJlO33kmzi5T+e5XDrgS 3wwEPFCDlYuuczqq+qwmepiZO4fFyVFk3Y3DWGrrlPM+K6ZqpxP86UWx4puWIiuC E+v6mVfGIk/wOrpOIsgmQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1666609846; x= 1666696246; bh=RFLQ5GBjwTscdxLe26sPsHDoE6RCOQt/d0N6c/XvgEY=; b=K M9P/yxby5ZMeMBzGP2KwFEASbeC0B645sR+OjfqkVOlGfwhFqXBxWQL3BamMXPUb k4tTk1wWNyMcAgDPV8R358TvqfMy7Q59VhT3Xvpnsa7dXPC1KRh6zTVN9ahxQ0EC Yd1Ve8h/YB9rjYnVpv/K6ZoS2ACJedRVF7iVp2+M/MDLbArVSgypGtrqEE+mDLX0 sBiUwhOpnlAmsVzg7dAbDIP2LucY5RBhAvcb6f1lL7rlDrSCgSCbXkpL+OD3ct5u FbaIIXRZyk80FiQgB4oitbK/sY+WNdGlKnjhroWcPdIB1YpdR7t0R0zcClyE+MkR pXDZ+XsYi+ttV2DDOxsjw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrgedtgedgfeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeetlhhi shhtrghirhcuhfhrrghntghishcuoegrlhhishhtrghirhesrghlihhsthgrihhrvdefrd hmvgeqnecuggftrfgrthhtvghrnhepudefveevheeuffdttdfftddtgfekjedvvdetgeeh tdeugfehvdduudeiudeffeehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomheprghlihhsthgrihhrsegrlhhishhtrghirhdvfedrmhgv X-ME-Proxy: Feedback-ID: ifd214418:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 24 Oct 2022 07:10:34 -0400 (EDT) From: Alistair Francis To: linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: linus.walleij@linaro.org, s.hauer@pengutronix.de, robh+dt@kernel.org, andreas@kemnade.info, krzysztof.kozlowski+dt@linaro.org, alistair23@gmail.com, dmitry.torokhov@gmail.com, rydberg@bitmath.org, shawnguo@kernel.org, Alistair Francis , Maxime Ripard , =?UTF-8?q?Myl=C3=A8ne=20Josserand?= , Peter Geis Subject: [PATCH v9 1/4] Input: Add driver for Cypress Generation 5 touchscreen Date: Mon, 24 Oct 2022 21:10:14 +1000 Message-Id: <20221024111017.43859-2-alistair@alistair23.me> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221024111017.43859-1-alistair@alistair23.me> References: <20221024111017.43859-1-alistair@alistair23.me> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This is the basic driver for the Cypress TrueTouch Gen5 touchscreen controllers. This driver supports only the I2C bus but it uses regmap so SPI support could be added later. The touchscreen can retrieve some defined zone that are handled as buttons (according to the hardware). That is why it handles button and multitouch events. Reviewed-by: Maxime Ripard Signed-off-by: Mylène Josserand Signed-off-by: Alistair Francis Tested-by: Andreas Kemnade # Kobo Clara HD Tested-by: Peter Geis --- drivers/input/touchscreen/Kconfig | 16 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/cyttsp5.c | 902 ++++++++++++++++++++++++++++ 3 files changed, 919 insertions(+) create mode 100644 drivers/input/touchscreen/cyttsp5.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index dc90a3ea51ee..f332afcb2541 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -284,6 +284,22 @@ config TOUCHSCREEN_CYTTSP4_SPI To compile this driver as a module, choose M here: the module will be called cyttsp4_spi. +config TOUCHSCREEN_CYTTSP5 + tristate "Cypress TrueTouch Gen5 Touchscreen Driver" + depends on I2C + select REGMAP_I2C + select CRC_ITU_T + help + Driver for Parade TrueTouch Standard Product Generation 5 + touchscreen controllers. I2C bus interface support only. + + Say Y here if you have a Cypress Gen5 touchscreen. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called cyttsp5. + config TOUCHSCREEN_DA9034 tristate "Touchscreen support for Dialog Semiconductor DA9034" depends on PMIC_DA903X diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 557f84fd2075..044324c9dd13 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_CORE) += cyttsp4_core.o obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_I2C) += cyttsp4_i2c.o cyttsp_i2c_common.o obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_SPI) += cyttsp4_spi.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP5) += cyttsp5.o obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c new file mode 100644 index 000000000000..85f849f2e37d --- /dev/null +++ b/drivers/input/touchscreen/cyttsp5.c @@ -0,0 +1,902 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Parade TrueTouch(TM) Standard Product V5 Module. + * + * Copyright (C) 2015 Parade Technologies + * Copyright (C) 2012-2015 Cypress Semiconductor + * Copyright (C) 2018 Bootlin + * + * Authors: Mylène Josserand + * Alistair Francis + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CYTTSP5_NAME "cyttsp5" +#define CY_I2C_DATA_SIZE (2 * 256) +#define HID_VERSION 0x0100 +#define CY_MAX_INPUT 512 +#define CYTTSP5_PREALLOCATED_CMD_BUFFER 32 +#define CY_BITS_PER_BTN 1 +#define CY_NUM_BTN_EVENT_ID GENMASK(CY_BITS_PER_BTN, 0) + +#define MAX_AREA 255 +#define HID_OUTPUT_BL_SOP 0x1 +#define HID_OUTPUT_BL_EOP 0x17 +#define HID_OUTPUT_BL_LAUNCH_APP 0x3B +#define HID_OUTPUT_BL_LAUNCH_APP_SIZE 11 +#define HID_OUTPUT_GET_SYSINFO 0x2 +#define HID_OUTPUT_GET_SYSINFO_SIZE 5 +#define HID_OUTPUT_MAX_CMD_SIZE 12 + +#define HID_DESC_REG 0x1 +#define HID_INPUT_REG 0x3 +#define HID_OUTPUT_REG 0x4 + +#define REPORT_ID_TOUCH 0x1 +#define REPORT_ID_BTN 0x3 +#define REPORT_SIZE_5 5 +#define REPORT_SIZE_8 8 +#define REPORT_SIZE_16 16 + +/* Touch reports offsets */ +/* Header offsets */ +#define TOUCH_REPORT_DESC_HDR_CONTACTCOUNT 16 +/* Record offsets */ +#define TOUCH_REPORT_DESC_CONTACTID 8 +#define TOUCH_REPORT_DESC_X 16 +#define TOUCH_REPORT_DESC_Y 32 +#define TOUCH_REPORT_DESC_P 48 +#define TOUCH_REPORT_DESC_MAJ 56 +#define TOUCH_REPORT_DESC_MIN 64 + +/* HID */ +#define HID_TOUCH_REPORT_ID 0x1 +#define HID_BTN_REPORT_ID 0x3 +#define HID_APP_RESPONSE_REPORT_ID 0x1F +#define HID_APP_OUTPUT_REPORT_ID 0x2F +#define HID_BL_RESPONSE_REPORT_ID 0x30 +#define HID_BL_OUTPUT_REPORT_ID 0x40 + +#define HID_OUTPUT_RESPONSE_REPORT_OFFSET 2 +#define HID_OUTPUT_RESPONSE_CMD_OFFSET 4 +#define HID_OUTPUT_RESPONSE_CMD_MASK GENMASK(6, 0) + +#define HID_SYSINFO_SENSING_OFFSET 33 +#define HID_SYSINFO_BTN_OFFSET 48 +#define HID_SYSINFO_BTN_MASK GENMASK(7, 0) +#define HID_SYSINFO_MAX_BTN 8 + +#define CY_HID_OUTPUT_TIMEOUT_MS 200 +#define CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS 3000 +#define CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS 4000 + +/* maximum number of concurrent tracks */ +#define TOUCH_REPORT_SIZE 10 +#define TOUCH_INPUT_HEADER_SIZE 7 +#define BTN_REPORT_SIZE 9 +#define BTN_INPUT_HEADER_SIZE 5 + +#define MAX_CY_TCH_T_IDS 32 + +/* All usage pages for Touch Report */ +#define TOUCH_REPORT_USAGE_PG_X 0x00010030 +#define TOUCH_REPORT_USAGE_PG_Y 0x00010031 +#define TOUCH_REPORT_USAGE_PG_P 0x000D0030 +#define TOUCH_REPORT_USAGE_PG_CONTACTID 0x000D0051 +#define TOUCH_REPORT_USAGE_PG_CONTACTCOUNT 0x000D0054 +#define TOUCH_REPORT_USAGE_PG_MAJ 0xFF010062 +#define TOUCH_REPORT_USAGE_PG_MIN 0xFF010063 +#define TOUCH_COL_USAGE_PG 0x000D0022 + +/* System Information interface definitions */ +struct cyttsp5_sensing_conf_data_dev { + u8 electrodes_x; + u8 electrodes_y; + __le16 len_x; + __le16 len_y; + __le16 res_x; + __le16 res_y; + __le16 max_z; + u8 origin_x; + u8 origin_y; + u8 btn; + u8 scan_mode; + u8 max_num_of_tch_per_refresh_cycle; +} __packed; + +struct cyttsp5_sensing_conf_data { + u16 res_x; + u16 res_y; + u16 max_z; + u16 len_x; + u16 len_y; + u8 origin_x; + u8 origin_y; + u8 max_tch; +}; + +enum cyttsp5_tch_abs { /* for ordering within the extracted touch data array */ + CY_TCH_X, /* X */ + CY_TCH_Y, /* Y */ + CY_TCH_P, /* P (Z) */ + CY_TCH_T, /* TOUCH ID */ + CY_TCH_MAJ, /* TOUCH_MAJOR */ + CY_TCH_MIN, /* TOUCH_MINOR */ + CY_TCH_NUM_ABS +}; + +struct cyttsp5_tch_abs_params { + size_t ofs; /* abs byte offset */ + size_t size; /* size in bits */ + size_t min; /* min value */ + size_t max; /* max value */ + size_t bofs; /* bit offset */ +}; + +struct cyttsp5_touch { + int abs[CY_TCH_NUM_ABS]; +}; + +struct cyttsp5_sysinfo { + struct cyttsp5_sensing_conf_data sensing_conf_data; + int num_btns; + struct cyttsp5_tch_abs_params tch_hdr; + struct cyttsp5_tch_abs_params tch_abs[CY_TCH_NUM_ABS]; + u32 key_code[HID_SYSINFO_MAX_BTN]; +}; + +struct cyttsp5_hid_desc { + __le16 hid_desc_len; + u8 packet_id; + u8 reserved_byte; + __le16 bcd_version; + __le16 report_desc_len; + __le16 report_desc_register; + __le16 input_register; + __le16 max_input_len; + __le16 output_register; + __le16 max_output_len; + __le16 command_register; + __le16 data_register; + __le16 vendor_id; + __le16 product_id; + __le16 version_id; + u8 reserved[4]; +} __packed; + +struct cyttsp5 { + struct device *dev; + struct completion cmd_done; + struct cyttsp5_sysinfo sysinfo; + struct cyttsp5_hid_desc hid_desc; + u8 cmd_buf[CYTTSP5_PREALLOCATED_CMD_BUFFER]; + u8 input_buf[CY_MAX_INPUT]; + u8 response_buf[CY_MAX_INPUT]; + struct gpio_desc *reset_gpio; + struct input_dev *input; + char phys[NAME_MAX]; + int num_prv_rec; + struct regmap *regmap; + struct touchscreen_properties prop; + struct regulator *vdd; +}; + +/* + * For what is understood in the datasheet, the register does not + * matter. For consistency, use the Input Register address + * but it does mean anything to the device. The important data + * to send is the I2C address + */ +static int cyttsp5_read(struct cyttsp5 *ts, u8 *buf, u32 max) +{ + int error; + u32 size; + u8 temp[2]; + + /* Read the frame to retrieve the size */ + error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, temp, sizeof(temp)); + if (error) + return error; + + size = get_unaligned_le16(temp); + if (!size || size == 2) + return 0; + + if (size > max) + return -EINVAL; + + /* Get the real value */ + return regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, size); +} + +static int cyttsp5_write(struct cyttsp5 *ts, unsigned int reg, u8 *data, + size_t size) +{ + u8 cmd[HID_OUTPUT_MAX_CMD_SIZE]; + + if (size + 1 > HID_OUTPUT_MAX_CMD_SIZE) + return -E2BIG; + + /* High bytes of register address needed as first byte of cmd */ + cmd[0] = (reg >> 8) & 0xFF ; + + /* Copy the rest of the data */ + if (data) + memcpy(&cmd[1], data, size); + + /* + * The hardware wants to receive a frame with the address register + * contained in the first two bytes. As the regmap_write function + * add the register adresse in the frame, we use the low byte as + * first frame byte for the address register and the first + * data byte is the high register + left of the cmd to send + */ + return regmap_bulk_write(ts->regmap, reg & 0xFF, cmd, size + 1); +} + +static void cyttsp5_get_touch_axis(int *axis, int size, int max, u8 *xy_data, + int bofs) +{ + int nbyte; + + for (nbyte = 0, *axis = 0; nbyte < size; nbyte++) + *axis += ((xy_data[nbyte] >> bofs) << (nbyte * 8)); + + *axis &= max - 1; +} + +static void cyttsp5_get_touch_record(struct cyttsp5 *ts, + struct cyttsp5_touch *touch, u8 *xy_data) +{ + struct cyttsp5_sysinfo *si = &ts->sysinfo; + enum cyttsp5_tch_abs abs; + + for (abs = CY_TCH_X; abs < CY_TCH_NUM_ABS; abs++) + cyttsp5_get_touch_axis(&touch->abs[abs], + si->tch_abs[abs].size, + si->tch_abs[abs].max, + xy_data + si->tch_abs[abs].ofs, + si->tch_abs[abs].bofs); +} + +static void cyttsp5_get_mt_touches(struct cyttsp5 *ts, + struct cyttsp5_touch *tch, int num_cur_tch) +{ + struct cyttsp5_sysinfo *si = &ts->sysinfo; + int i, t = 0, offset = 0; + DECLARE_BITMAP(ids, MAX_CY_TCH_T_IDS); + u8 *tch_addr; + int tmp; + + bitmap_zero(ids, MAX_CY_TCH_T_IDS); + memset(tch->abs, 0, sizeof(tch->abs)); + + switch (ts->input_buf[2]) { + case HID_TOUCH_REPORT_ID: + offset = TOUCH_INPUT_HEADER_SIZE; + break; + case HID_BTN_REPORT_ID: + offset = BTN_INPUT_HEADER_SIZE; + break; + } + + for (i = 0; i < num_cur_tch; i++) { + tch_addr = ts->input_buf + offset + (i * TOUCH_REPORT_SIZE); + cyttsp5_get_touch_record(ts, tch, tch_addr); + + /* Convert MAJOR/MINOR from mm to resolution */ + tmp = tch->abs[CY_TCH_MAJ] * 100 * si->sensing_conf_data.res_x; + tch->abs[CY_TCH_MAJ] = tmp / si->sensing_conf_data.len_x; + tmp = tch->abs[CY_TCH_MIN] * 100 * si->sensing_conf_data.res_x; + tch->abs[CY_TCH_MIN] = tmp / si->sensing_conf_data.len_x; + + t = tch->abs[CY_TCH_T]; + input_mt_slot(ts->input, t); + input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); + __set_bit(t, ids); + + /* position and pressure fields */ + touchscreen_report_pos(ts->input, &ts->prop, + tch->abs[CY_TCH_X], tch->abs[CY_TCH_Y], + true); + input_report_abs(ts->input, ABS_MT_PRESSURE, + tch->abs[CY_TCH_P]); + + /* Get the extended touch fields */ + input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, + tch->abs[CY_TCH_MAJ]); + input_report_abs(ts->input, ABS_MT_TOUCH_MINOR, + tch->abs[CY_TCH_MIN]); + } + + ts->num_prv_rec = num_cur_tch; +} + +static int cyttsp5_mt_attention(struct device *dev) +{ + struct cyttsp5 *ts = dev_get_drvdata(dev); + struct cyttsp5_sysinfo *si = &ts->sysinfo; + int max_tch = si->sensing_conf_data.max_tch; + struct cyttsp5_touch tch; + int num_cur_tch; + + cyttsp5_get_touch_axis(&num_cur_tch, si->tch_hdr.size, + si->tch_hdr.max, + ts->input_buf + 3 + si->tch_hdr.ofs, + si->tch_hdr.bofs); + + if (num_cur_tch > max_tch) { + dev_err(dev, "Num touch err detected (n=%d)\n", num_cur_tch); + num_cur_tch = max_tch; + } + + if (num_cur_tch == 0 && ts->num_prv_rec == 0) + return 0; + + /* extract xy_data for all currently reported touches */ + if (num_cur_tch) + cyttsp5_get_mt_touches(ts, &tch, num_cur_tch); + + input_mt_sync_frame(ts->input); + input_sync(ts->input); + + return 0; +} + +static int cyttsp5_setup_input_device(struct device *dev) +{ + struct cyttsp5 *ts = dev_get_drvdata(dev); + struct cyttsp5_sysinfo *si = &ts->sysinfo; + int max_x, max_y, max_p; + int max_x_tmp, max_y_tmp; + int error; + + max_x_tmp = si->sensing_conf_data.res_x; + max_y_tmp = si->sensing_conf_data.res_y; + max_x = max_x_tmp - 1; + max_y = max_y_tmp - 1; + max_p = si->sensing_conf_data.max_z; + + input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, max_x, 0, 0); + input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0); + input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, max_p, 0, 0); + + input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0); + input_set_abs_params(ts->input, ABS_MT_TOUCH_MINOR, 0, MAX_AREA, 0, 0); + + error = input_mt_init_slots(ts->input, si->tch_abs[CY_TCH_T].max, + INPUT_MT_DROP_UNUSED | INPUT_MT_DIRECT); + if (error < 0) + return error; + + error = input_register_device(ts->input); + if (error < 0) + dev_err(dev, "Error, failed register input device r=%d\n", error); + + return error; +} + +static int cyttsp5_parse_dt_key_code(struct device *dev) +{ + struct cyttsp5 *ts = dev_get_drvdata(dev); + struct cyttsp5_sysinfo *si = &ts->sysinfo; + + if (!si->num_btns) + return 0; + + /* Initialize the button to RESERVED */ + memset32(si->key_code, KEY_RESERVED, si->num_btns); + + return device_property_read_u32_array(dev, "linux,keycodes", + si->key_code, si->num_btns); +} + +static int cyttsp5_btn_attention(struct device *dev) +{ + struct cyttsp5 *ts = dev_get_drvdata(dev); + struct cyttsp5_sysinfo *si = &ts->sysinfo; + int cur_btn, offset = 0; + int cur_btn_state; + + switch (ts->input_buf[2]) { + case HID_TOUCH_REPORT_ID: + offset = TOUCH_INPUT_HEADER_SIZE; + break; + case HID_BTN_REPORT_ID: + offset = BTN_INPUT_HEADER_SIZE; + break; + } + + if (ts->input_buf[2] != HID_BTN_REPORT_ID || !si->num_btns) + return 0; + + /* extract button press/release touch information */ + for (cur_btn = 0; cur_btn < si->num_btns; cur_btn++) { + /* Get current button state */ + cur_btn_state = (ts->input_buf[offset] >> (cur_btn * CY_BITS_PER_BTN)) + & CY_NUM_BTN_EVENT_ID; + + input_report_key(ts->input, si->key_code[cur_btn], + cur_btn_state); + input_sync(ts->input); + } + + return 0; +} + +static int cyttsp5_validate_cmd_response(struct cyttsp5 *ts, u8 code) +{ + u16 size, crc; + u8 status, report_id; + int command_code; + + size = get_unaligned_le16(&ts->response_buf[0]); + + if (!size) + return 0; + + report_id = ts->response_buf[HID_OUTPUT_RESPONSE_REPORT_OFFSET]; + + switch (report_id) { + case HID_BL_RESPONSE_REPORT_ID: { + if (ts->response_buf[4] != HID_OUTPUT_BL_SOP) { + dev_err(ts->dev, "HID output response, wrong SOP\n"); + return -EPROTO; + } + + if (ts->response_buf[size - 1] != HID_OUTPUT_BL_EOP) { + dev_err(ts->dev, "HID output response, wrong EOP\n"); + return -EPROTO; + } + + crc = crc_itu_t(0xFFFF, &ts->response_buf[4], size - 7); + if (get_unaligned_le16(&ts->response_buf[size - 3]) != crc) { + dev_err(ts->dev, "HID output response, wrong CRC 0x%X\n", + crc); + return -EPROTO; + } + + status = ts->response_buf[5]; + if (status) { + dev_err(ts->dev, "HID output response, ERROR:%d\n", + status); + return -EPROTO; + } + break; + } + case HID_APP_RESPONSE_REPORT_ID: { + command_code = ts->response_buf[HID_OUTPUT_RESPONSE_CMD_OFFSET] + & HID_OUTPUT_RESPONSE_CMD_MASK; + if (command_code != code) { + dev_err(ts->dev, + "HID output response, wrong command_code:%X\n", + command_code); + return -EPROTO; + } + break; + } + } + + return 0; +} + +static void cyttsp5_si_get_btn_data(struct cyttsp5 *ts) +{ + struct cyttsp5_sysinfo *si = &ts->sysinfo; + unsigned int btns = ts->response_buf[HID_SYSINFO_BTN_OFFSET] + & HID_SYSINFO_BTN_MASK; + + si->num_btns = hweight8(btns); +} + +static int cyttsp5_get_sysinfo_regs(struct cyttsp5 *ts) +{ + struct cyttsp5_sensing_conf_data *scd = &ts->sysinfo.sensing_conf_data; + struct cyttsp5_sensing_conf_data_dev *scd_dev = + (struct cyttsp5_sensing_conf_data_dev *) + &ts->response_buf[HID_SYSINFO_SENSING_OFFSET]; + + cyttsp5_si_get_btn_data(ts); + + scd->max_tch = scd_dev->max_num_of_tch_per_refresh_cycle; + scd->res_x = get_unaligned_le16(&scd_dev->res_x); + scd->res_y = get_unaligned_le16(&scd_dev->res_y); + scd->max_z = get_unaligned_le16(&scd_dev->max_z); + scd->len_x = get_unaligned_le16(&scd_dev->len_x); + scd->len_y = get_unaligned_le16(&scd_dev->len_y); + + return 0; +} + +static int cyttsp5_hid_output_get_sysinfo(struct cyttsp5 *ts) +{ + int rc; + u8 cmd[HID_OUTPUT_GET_SYSINFO_SIZE]; + + /* HI bytes of Output register address */ + put_unaligned_le16(HID_OUTPUT_GET_SYSINFO_SIZE, cmd); + cmd[2] = HID_APP_OUTPUT_REPORT_ID; + cmd[3] = 0x0; /* Reserved */ + cmd[4] = HID_OUTPUT_GET_SYSINFO; + + rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd, + HID_OUTPUT_GET_SYSINFO_SIZE); + if (rc) { + dev_err(ts->dev, "Failed to write command %d", rc); + return rc; + } + + rc = wait_for_completion_interruptible_timeout(&ts->cmd_done, + msecs_to_jiffies(CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS)); + if (rc <= 0) { + dev_err(ts->dev, "HID output cmd execution timed out\n"); + rc = -ETIMEDOUT; + return rc; + } + + rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_GET_SYSINFO); + if (rc) { + dev_err(ts->dev, "Validation of the response failed\n"); + return rc; + } + + return cyttsp5_get_sysinfo_regs(ts); +} + +static int cyttsp5_hid_output_bl_launch_app(struct cyttsp5 *ts) +{ + int rc; + u8 cmd[HID_OUTPUT_BL_LAUNCH_APP]; + u16 crc; + + put_unaligned_le16(HID_OUTPUT_BL_LAUNCH_APP_SIZE, cmd); + cmd[2] = HID_BL_OUTPUT_REPORT_ID; + cmd[3] = 0x0; /* Reserved */ + cmd[4] = HID_OUTPUT_BL_SOP; + cmd[5] = HID_OUTPUT_BL_LAUNCH_APP; + put_unaligned_le16(0x00, &cmd[6]); + crc = crc_itu_t(0xFFFF, &cmd[4], 4); + put_unaligned_le16(crc, &cmd[8]); + cmd[10] = HID_OUTPUT_BL_EOP; + + rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd, + HID_OUTPUT_BL_LAUNCH_APP_SIZE); + if (rc) { + dev_err(ts->dev, "Failed to write command %d", rc); + return rc; + } + + rc = wait_for_completion_interruptible_timeout(&ts->cmd_done, + msecs_to_jiffies(CY_HID_OUTPUT_TIMEOUT_MS)); + if (rc <= 0) { + dev_err(ts->dev, "HID output cmd execution timed out\n"); + rc = -ETIMEDOUT; + return rc; + } + + rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_BL_LAUNCH_APP); + if (rc) { + dev_err(ts->dev, "Validation of the response failed\n"); + return rc; + } + + return 0; +} + +static int cyttsp5_get_hid_descriptor(struct cyttsp5 *ts, + struct cyttsp5_hid_desc *desc) +{ + struct device *dev = ts->dev; + __le16 hid_desc_register = cpu_to_le16(HID_DESC_REG); + int rc; + u8 cmd[2]; + + /* Set HID descriptor register */ + memcpy(cmd, &hid_desc_register, sizeof(hid_desc_register)); + + rc = cyttsp5_write(ts, HID_DESC_REG, NULL, 0); + if (rc) { + dev_err(dev, "Failed to get HID descriptor, rc=%d\n", rc); + return rc; + } + + rc = wait_for_completion_interruptible_timeout(&ts->cmd_done, + msecs_to_jiffies(CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS)); + if (rc <= 0) { + dev_err(ts->dev, "HID get descriptor timed out\n"); + rc = -ETIMEDOUT; + return rc; + } + + memcpy(desc, ts->response_buf, sizeof(*desc)); + + /* Check HID descriptor length and version */ + if (le16_to_cpu(desc->hid_desc_len) != sizeof(*desc) || + le16_to_cpu(desc->bcd_version) != HID_VERSION) { + dev_err(dev, "Unsupported HID version\n"); + return -ENODEV; + } + + return 0; +} + +static int fill_tch_abs(struct cyttsp5_tch_abs_params *tch_abs, int report_size, + int offset) +{ + tch_abs->ofs = offset / 8; + tch_abs->size = report_size / 8; + if (report_size % 8) + tch_abs->size += 1; + tch_abs->min = 0; + tch_abs->max = 1 << report_size; + tch_abs->bofs = offset - (tch_abs->ofs << 3); + + return 0; +} + +static irqreturn_t cyttsp5_handle_irq(int irq, void *handle) +{ + struct cyttsp5 *ts = handle; + int report_id; + int size; + int error; + + error = cyttsp5_read(ts, ts->input_buf, CY_MAX_INPUT); + if (error) + return IRQ_HANDLED; + + size = get_unaligned_le16(&ts->input_buf[0]); + if (size == 0) { + /* reset */ + report_id = 0; + size = 2; + } else { + report_id = ts->input_buf[2]; + } + + switch (report_id) { + case HID_TOUCH_REPORT_ID: + cyttsp5_mt_attention(ts->dev); + break; + case HID_BTN_REPORT_ID: + cyttsp5_btn_attention(ts->dev); + break; + default: + /* It is not an input but a command response */ + memcpy(ts->response_buf, ts->input_buf, size); + complete(&ts->cmd_done); + } + + return IRQ_HANDLED; +} + +static int cyttsp5_deassert_int(struct cyttsp5 *ts) +{ + u16 size; + u8 buf[2]; + int error; + + error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, sizeof(buf)); + if (error < 0) + return error; + + size = get_unaligned_le16(&buf[0]); + if (size == 2 || size == 0) + return 0; + + return -EINVAL; +} + +static int cyttsp5_fill_all_touch(struct cyttsp5 *ts) +{ + struct cyttsp5_sysinfo *si = &ts->sysinfo; + + fill_tch_abs(&si->tch_abs[CY_TCH_X], REPORT_SIZE_16, + TOUCH_REPORT_DESC_X); + fill_tch_abs(&si->tch_abs[CY_TCH_Y], REPORT_SIZE_16, + TOUCH_REPORT_DESC_Y); + fill_tch_abs(&si->tch_abs[CY_TCH_P], REPORT_SIZE_8, + TOUCH_REPORT_DESC_P); + fill_tch_abs(&si->tch_abs[CY_TCH_T], REPORT_SIZE_5, + TOUCH_REPORT_DESC_CONTACTID); + fill_tch_abs(&si->tch_hdr, REPORT_SIZE_5, + TOUCH_REPORT_DESC_HDR_CONTACTCOUNT); + fill_tch_abs(&si->tch_abs[CY_TCH_MAJ], REPORT_SIZE_8, + TOUCH_REPORT_DESC_MAJ); + fill_tch_abs(&si->tch_abs[CY_TCH_MIN], REPORT_SIZE_8, + TOUCH_REPORT_DESC_MIN); + + return 0; +} + +static int cyttsp5_startup(struct cyttsp5 *ts) +{ + int error; + + error = cyttsp5_deassert_int(ts); + if (error) { + dev_err(ts->dev, "Error on deassert int r=%d\n", error); + return -ENODEV; + } + + /* + * Launch the application as the device starts in bootloader mode + * because of a power-on-reset + */ + error = cyttsp5_hid_output_bl_launch_app(ts); + if (error < 0) { + dev_err(ts->dev, "Error on launch app r=%d\n", error); + return error; + } + + error = cyttsp5_get_hid_descriptor(ts, &ts->hid_desc); + if (error < 0) { + dev_err(ts->dev, "Error on getting HID descriptor r=%d\n", error); + return error; + } + + error = cyttsp5_fill_all_touch(ts); + if (error < 0) { + dev_err(ts->dev, "Error on report descriptor r=%d\n", error); + return error; + } + + error = cyttsp5_hid_output_get_sysinfo(ts); + if (error) { + dev_err(ts->dev, "Error on getting sysinfo r=%d\n", error); + return error; + } + + return error; +} + +static void cyttsp5_cleanup(void *data) +{ + struct cyttsp5 *ts = data; + + regulator_disable(ts->vdd); +} + +static int cyttsp5_probe(struct device *dev, struct regmap *regmap, int irq, + const char *name) +{ + struct cyttsp5 *ts; + struct cyttsp5_sysinfo *si; + int error, i; + + ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL); + if (!ts) + return -ENOMEM; + + /* Initialize device info */ + ts->regmap = regmap; + ts->dev = dev; + si = &ts->sysinfo; + dev_set_drvdata(dev, ts); + + init_completion(&ts->cmd_done); + + /* Power up the device */ + ts->vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(ts->vdd)) { + error = PTR_ERR(ts->vdd); + return error; + } + + error = devm_add_action_or_reset(dev, cyttsp5_cleanup, ts); + if (error) { + return error; + } + + error = regulator_enable(ts->vdd); + if (error) { + return error; + } + + ts->input = devm_input_allocate_device(dev); + if (!ts->input) { + dev_err(dev, "Error, failed to allocate input device\n"); + return -ENODEV; + } + + ts->input->name = "cyttsp5"; + scnprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); + ts->input->phys = ts->phys; + input_set_drvdata(ts->input, ts); + + /* Reset the gpio to be in a reset state */ + ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(ts->reset_gpio)) { + error = PTR_ERR(ts->reset_gpio); + dev_err(dev, "Failed to request reset gpio, error %d\n", error); + return error; + } + gpiod_set_value(ts->reset_gpio, 0); + + /* Need a delay to have device up */ + msleep(20); + + error = devm_request_threaded_irq(dev, irq, NULL, cyttsp5_handle_irq, + IRQF_ONESHOT, name, ts); + if (error) { + dev_err(dev, "unable to request IRQ\n"); + return error; + } + + error = cyttsp5_startup(ts); + if (error) { + dev_err(ts->dev, "Fail initial startup r=%d\n", error); + return error; + } + + error = cyttsp5_parse_dt_key_code(dev); + if (error < 0) { + dev_err(ts->dev, "Error while parsing dts %d\n", error); + return error; + } + + touchscreen_parse_properties(ts->input, true, &ts->prop); + + __set_bit(EV_KEY, ts->input->evbit); + for (i = 0; i < si->num_btns; i++) + __set_bit(si->key_code[i], ts->input->keybit); + + return cyttsp5_setup_input_device(dev); +} + +static int cyttsp5_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct regmap *regmap; + static const struct regmap_config config = { + .reg_bits = 8, + .val_bits = 8, + }; + + regmap = devm_regmap_init_i2c(client, &config); + if (IS_ERR(regmap)) { + dev_err(&client->dev, "regmap allocation failed: %ld\n", + PTR_ERR(regmap)); + return PTR_ERR(regmap); + } + + return cyttsp5_probe(&client->dev, regmap, client->irq, client->name); +} + +static const struct of_device_id cyttsp5_of_match[] = { + { .compatible = "cypress,tt21000", }, + { } +}; +MODULE_DEVICE_TABLE(of, cyttsp5_of_match); + +static const struct i2c_device_id cyttsp5_i2c_id[] = { + { CYTTSP5_NAME, 0, }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id); + +static struct i2c_driver cyttsp5_i2c_driver = { + .driver = { + .name = CYTTSP5_NAME, + .of_match_table = cyttsp5_of_match, + }, + .probe = cyttsp5_i2c_probe, + .id_table = cyttsp5_i2c_id, +}; +module_i2c_driver(cyttsp5_i2c_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Touchscreen driver for Cypress TrueTouch Gen 5 Product"); +MODULE_AUTHOR("Mylène Josserand "); -- 2.37.3 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 41EDFC38A2D for ; Mon, 24 Oct 2022 11:12:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OpLN6M3XNRV7ob8LMqZo3KDm7Dt8cYUxQteXlAiOisQ=; b=kHVDf0TVcyGSHI SWPHiY05tGATuacERdI+pVPReUjloeXh+tnm2OjPgjIB1GRTN/+jUvLYskJkr7kNChbF8rT29Gki3 LAjF4T4OrRUpraJd2gZ285vXB4UVCt0BGlPm4Eaxtyi2sEB+7PV8l5GJcA5nA3VykBVSRZ38hXfSc f9XJ0YknfyS1IEMc400TW9doI1j4vYVAF5lhyt8MEHVfhQF9nOaCufgkJAcXRc+WJIzQV2OOhq7Vr y/oTAYhHO+7Ni3eDBBdvDN88MMwB3xdRBsHoDLZxegsXog5E1tqux4UuaO1C9ekB/r8VcRDt9uRc+ FzJDvngrre6ygnMuY0eQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1omvM5-000uaQ-MH; Mon, 24 Oct 2022 11:10:53 +0000 Received: from wout2-smtp.messagingengine.com ([64.147.123.25]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1omvM0-000uZE-LX for linux-arm-kernel@lists.infradead.org; Mon, 24 Oct 2022 11:10:51 +0000 Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailout.west.internal (Postfix) with ESMTP id C80023200094; Mon, 24 Oct 2022 07:10:46 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Mon, 24 Oct 2022 07:10:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alistair23.me; h=cc:cc:content-transfer-encoding:content-type:date:date:from :from:in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm3; t=1666609846; x= 1666696246; bh=RFLQ5GBjwTscdxLe26sPsHDoE6RCOQt/d0N6c/XvgEY=; b=A zqs3BikT13R+4YIdCL1jUm/h7StEaAKARum3EM5AO17A46+HX+ZRAyU4EpxbOgsy OF1qAuubGctDhRYv95ShTata/ro8JSAhB+svKTrlBdeLlQlPRUGxZoHRBk7leV/2 rOK1U4yjSxvT1UY2iPa+B+rpn1aPEHEbQ67/cD5sveyZHC7fiP/ol82AcO0CoW/L KszJBPFHhbvyIW5z2GMT493wu92IPR8nfzAJUReLLE0jWJlO33kmzi5T+e5XDrgS 3wwEPFCDlYuuczqq+qwmepiZO4fFyVFk3Y3DWGrrlPM+K6ZqpxP86UWx4puWIiuC E+v6mVfGIk/wOrpOIsgmQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t=1666609846; x= 1666696246; bh=RFLQ5GBjwTscdxLe26sPsHDoE6RCOQt/d0N6c/XvgEY=; b=K M9P/yxby5ZMeMBzGP2KwFEASbeC0B645sR+OjfqkVOlGfwhFqXBxWQL3BamMXPUb k4tTk1wWNyMcAgDPV8R358TvqfMy7Q59VhT3Xvpnsa7dXPC1KRh6zTVN9ahxQ0EC Yd1Ve8h/YB9rjYnVpv/K6ZoS2ACJedRVF7iVp2+M/MDLbArVSgypGtrqEE+mDLX0 sBiUwhOpnlAmsVzg7dAbDIP2LucY5RBhAvcb6f1lL7rlDrSCgSCbXkpL+OD3ct5u FbaIIXRZyk80FiQgB4oitbK/sY+WNdGlKnjhroWcPdIB1YpdR7t0R0zcClyE+MkR pXDZ+XsYi+ttV2DDOxsjw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrgedtgedgfeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeetlhhi shhtrghirhcuhfhrrghntghishcuoegrlhhishhtrghirhesrghlihhsthgrihhrvdefrd hmvgeqnecuggftrfgrthhtvghrnhepudefveevheeuffdttdfftddtgfekjedvvdetgeeh tdeugfehvdduudeiudeffeehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpe hmrghilhhfrhhomheprghlihhsthgrihhrsegrlhhishhtrghirhdvfedrmhgv X-ME-Proxy: Feedback-ID: ifd214418:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 24 Oct 2022 07:10:34 -0400 (EDT) From: Alistair Francis To: linux-input@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: linus.walleij@linaro.org, s.hauer@pengutronix.de, robh+dt@kernel.org, andreas@kemnade.info, krzysztof.kozlowski+dt@linaro.org, alistair23@gmail.com, dmitry.torokhov@gmail.com, rydberg@bitmath.org, shawnguo@kernel.org, Alistair Francis , Maxime Ripard , =?UTF-8?q?Myl=C3=A8ne=20Josserand?= , Peter Geis Subject: [PATCH v9 1/4] Input: Add driver for Cypress Generation 5 touchscreen Date: Mon, 24 Oct 2022 21:10:14 +1000 Message-Id: <20221024111017.43859-2-alistair@alistair23.me> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221024111017.43859-1-alistair@alistair23.me> References: <20221024111017.43859-1-alistair@alistair23.me> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221024_041048_802028_BDE322D1 X-CRM114-Status: GOOD ( 26.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org VGhpcyBpcyB0aGUgYmFzaWMgZHJpdmVyIGZvciB0aGUgQ3lwcmVzcyBUcnVlVG91Y2ggR2VuNSB0 b3VjaHNjcmVlbgpjb250cm9sbGVycy4gVGhpcyBkcml2ZXIgc3VwcG9ydHMgb25seSB0aGUgSTJD IGJ1cyBidXQgaXQgdXNlcyByZWdtYXAKc28gU1BJIHN1cHBvcnQgY291bGQgYmUgYWRkZWQgbGF0 ZXIuClRoZSB0b3VjaHNjcmVlbiBjYW4gcmV0cmlldmUgc29tZSBkZWZpbmVkIHpvbmUgdGhhdCBh cmUgaGFuZGxlZCBhcwpidXR0b25zIChhY2NvcmRpbmcgdG8gdGhlIGhhcmR3YXJlKS4gVGhhdCBp cyB3aHkgaXQgaGFuZGxlcwpidXR0b24gYW5kIG11bHRpdG91Y2ggZXZlbnRzLgoKUmV2aWV3ZWQt Ynk6IE1heGltZSBSaXBhcmQgPG1heGltZS5yaXBhcmRAYm9vdGxpbi5jb20+ClNpZ25lZC1vZmYt Ynk6IE15bMOobmUgSm9zc2VyYW5kIDxteWxlbmUuam9zc2VyYW5kQGJvb3RsaW4uY29tPgpTaWdu ZWQtb2ZmLWJ5OiBBbGlzdGFpciBGcmFuY2lzIDxhbGlzdGFpckBhbGlzdGFpcjIzLm1lPgpUZXN0 ZWQtYnk6IEFuZHJlYXMgS2VtbmFkZSA8YW5kcmVhc0BrZW1uYWRlLmluZm8+ICMgS29ibyBDbGFy YSBIRApUZXN0ZWQtYnk6IFBldGVyIEdlaXMgPHBnd2lwZW91dEBnbWFpbC5jb20+Ci0tLQogZHJp dmVycy9pbnB1dC90b3VjaHNjcmVlbi9LY29uZmlnICAgfCAgMTYgKwogZHJpdmVycy9pbnB1dC90 b3VjaHNjcmVlbi9NYWtlZmlsZSAgfCAgIDEgKwogZHJpdmVycy9pbnB1dC90b3VjaHNjcmVlbi9j eXR0c3A1LmMgfCA5MDIgKysrKysrKysrKysrKysrKysrKysrKysrKysrKwogMyBmaWxlcyBjaGFu Z2VkLCA5MTkgaW5zZXJ0aW9ucygrKQogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaW5wdXQv dG91Y2hzY3JlZW4vY3l0dHNwNS5jCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9pbnB1dC90b3VjaHNj cmVlbi9LY29uZmlnIGIvZHJpdmVycy9pbnB1dC90b3VjaHNjcmVlbi9LY29uZmlnCmluZGV4IGRj OTBhM2VhNTFlZS4uZjMzMmFmY2IyNTQxIDEwMDY0NAotLS0gYS9kcml2ZXJzL2lucHV0L3RvdWNo c2NyZWVuL0tjb25maWcKKysrIGIvZHJpdmVycy9pbnB1dC90b3VjaHNjcmVlbi9LY29uZmlnCkBA IC0yODQsNiArMjg0LDIyIEBAIGNvbmZpZyBUT1VDSFNDUkVFTl9DWVRUU1A0X1NQSQogCSAgVG8g Y29tcGlsZSB0aGlzIGRyaXZlciBhcyBhIG1vZHVsZSwgY2hvb3NlIE0gaGVyZTogdGhlCiAJICBt b2R1bGUgd2lsbCBiZSBjYWxsZWQgY3l0dHNwNF9zcGkuCiAKK2NvbmZpZyBUT1VDSFNDUkVFTl9D WVRUU1A1CisJdHJpc3RhdGUgIkN5cHJlc3MgVHJ1ZVRvdWNoIEdlbjUgVG91Y2hzY3JlZW4gRHJp dmVyIgorCWRlcGVuZHMgb24gSTJDCisJc2VsZWN0IFJFR01BUF9JMkMKKwlzZWxlY3QgQ1JDX0lU VV9UCisJaGVscAorCSAgRHJpdmVyIGZvciBQYXJhZGUgVHJ1ZVRvdWNoIFN0YW5kYXJkIFByb2R1 Y3QgR2VuZXJhdGlvbiA1CisJICB0b3VjaHNjcmVlbiBjb250cm9sbGVycy4gSTJDIGJ1cyBpbnRl cmZhY2Ugc3VwcG9ydCBvbmx5LgorCisJICBTYXkgWSBoZXJlIGlmIHlvdSBoYXZlIGEgQ3lwcmVz cyBHZW41IHRvdWNoc2NyZWVuLgorCisJICBJZiB1bnN1cmUsIHNheSBOLgorCisJICBUbyBjb21w aWxlIHRoaXMgZHJpdmVyIGFzIGEgbW9kdWxlLCBjaG9vc2UgTSBoZXJlOiB0aGUKKwkgIG1vZHVs ZSB3aWxsIGJlIGNhbGxlZCBjeXR0c3A1LgorCiBjb25maWcgVE9VQ0hTQ1JFRU5fREE5MDM0CiAJ dHJpc3RhdGUgIlRvdWNoc2NyZWVuIHN1cHBvcnQgZm9yIERpYWxvZyBTZW1pY29uZHVjdG9yIERB OTAzNCIKIAlkZXBlbmRzIG9uIFBNSUNfREE5MDNYCmRpZmYgLS1naXQgYS9kcml2ZXJzL2lucHV0 L3RvdWNoc2NyZWVuL01ha2VmaWxlIGIvZHJpdmVycy9pbnB1dC90b3VjaHNjcmVlbi9NYWtlZmls ZQppbmRleCA1NTdmODRmZDIwNzUuLjA0NDMyNGM5ZGQxMyAxMDA2NDQKLS0tIGEvZHJpdmVycy9p bnB1dC90b3VjaHNjcmVlbi9NYWtlZmlsZQorKysgYi9kcml2ZXJzL2lucHV0L3RvdWNoc2NyZWVu L01ha2VmaWxlCkBAIC0zMCw2ICszMCw3IEBAIG9iai0kKENPTkZJR19UT1VDSFNDUkVFTl9DWVRU U1BfU1BJKQkrPSBjeXR0c3Bfc3BpLm8KIG9iai0kKENPTkZJR19UT1VDSFNDUkVFTl9DWVRUU1A0 X0NPUkUpCSs9IGN5dHRzcDRfY29yZS5vCiBvYmotJChDT05GSUdfVE9VQ0hTQ1JFRU5fQ1lUVFNQ NF9JMkMpCSs9IGN5dHRzcDRfaTJjLm8gY3l0dHNwX2kyY19jb21tb24ubwogb2JqLSQoQ09ORklH X1RPVUNIU0NSRUVOX0NZVFRTUDRfU1BJKQkrPSBjeXR0c3A0X3NwaS5vCitvYmotJChDT05GSUdf VE9VQ0hTQ1JFRU5fQ1lUVFNQNSkJKz0gY3l0dHNwNS5vCiBvYmotJChDT05GSUdfVE9VQ0hTQ1JF RU5fREE5MDM0KQkrPSBkYTkwMzQtdHMubwogb2JqLSQoQ09ORklHX1RPVUNIU0NSRUVOX0RBOTA1 MikJKz0gZGE5MDUyX3RzaS5vCiBvYmotJChDT05GSUdfVE9VQ0hTQ1JFRU5fRFlOQVBSTykJKz0g ZHluYXByby5vCmRpZmYgLS1naXQgYS9kcml2ZXJzL2lucHV0L3RvdWNoc2NyZWVuL2N5dHRzcDUu YyBiL2RyaXZlcnMvaW5wdXQvdG91Y2hzY3JlZW4vY3l0dHNwNS5jCm5ldyBmaWxlIG1vZGUgMTAw NjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uODVmODQ5ZjJlMzdkCi0tLSAvZGV2L251bGwKKysrIGIv ZHJpdmVycy9pbnB1dC90b3VjaHNjcmVlbi9jeXR0c3A1LmMKQEAgLTAsMCArMSw5MDIgQEAKKy8v IFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wCisvKgorICogUGFyYWRlIFRydWVUb3Vj aChUTSkgU3RhbmRhcmQgUHJvZHVjdCBWNSBNb2R1bGUuCisgKgorICogQ29weXJpZ2h0IChDKSAy MDE1IFBhcmFkZSBUZWNobm9sb2dpZXMKKyAqIENvcHlyaWdodCAoQykgMjAxMi0yMDE1IEN5cHJl c3MgU2VtaWNvbmR1Y3RvcgorICogQ29weXJpZ2h0IChDKSAyMDE4IEJvb3RsaW4KKyAqCisgKiBB dXRob3JzOiBNeWzDqG5lIEpvc3NlcmFuZCA8bXlsZW5lLmpvc3NlcmFuZEBib290bGluLmNvbT4K KyAqICAgICAgICAgICAgICAgIEFsaXN0YWlyIEZyYW5jaXMgPGFsaXN0YWlyQGFsaXN0YWlyMjMu bWU+CisgKi8KKworI2luY2x1ZGUgPGxpbnV4L2NyYy1pdHUtdC5oPgorI2luY2x1ZGUgPGxpbnV4 L2RlbGF5Lmg+CisjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CisjaW5jbHVkZSA8bGludXgvZ3Bp by9jb25zdW1lci5oPgorI2luY2x1ZGUgPGxpbnV4L2lucHV0L210Lmg+CisjaW5jbHVkZSA8bGlu dXgvaW5wdXQvdG91Y2hzY3JlZW4uaD4KKyNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KKyNp bmNsdWRlIDxsaW51eC9pMmMuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRl IDxsaW51eC9vZl9kZXZpY2UuaD4KKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4KKyNpbmNsdWRl IDxhc20vdW5hbGlnbmVkLmg+CisKKyNkZWZpbmUgQ1lUVFNQNV9OQU1FCQkJCSJjeXR0c3A1Igor I2RlZmluZSBDWV9JMkNfREFUQV9TSVpFCQkJKDIgKiAyNTYpCisjZGVmaW5lIEhJRF9WRVJTSU9O CQkJCTB4MDEwMAorI2RlZmluZSBDWV9NQVhfSU5QVVQJCQkJNTEyCisjZGVmaW5lIENZVFRTUDVf UFJFQUxMT0NBVEVEX0NNRF9CVUZGRVIJMzIKKyNkZWZpbmUgQ1lfQklUU19QRVJfQlROCQkJMQor I2RlZmluZSBDWV9OVU1fQlROX0VWRU5UX0lECQkJR0VOTUFTSyhDWV9CSVRTX1BFUl9CVE4sIDAp CisKKyNkZWZpbmUgTUFYX0FSRUEJCQkJMjU1CisjZGVmaW5lIEhJRF9PVVRQVVRfQkxfU09QCQkJ MHgxCisjZGVmaW5lIEhJRF9PVVRQVVRfQkxfRU9QCQkJMHgxNworI2RlZmluZSBISURfT1VUUFVU X0JMX0xBVU5DSF9BUFAJCTB4M0IKKyNkZWZpbmUgSElEX09VVFBVVF9CTF9MQVVOQ0hfQVBQX1NJ WkUJCTExCisjZGVmaW5lIEhJRF9PVVRQVVRfR0VUX1NZU0lORk8JCQkweDIKKyNkZWZpbmUgSElE X09VVFBVVF9HRVRfU1lTSU5GT19TSVpFCQk1CisjZGVmaW5lIEhJRF9PVVRQVVRfTUFYX0NNRF9T SVpFCQkxMgorCisjZGVmaW5lIEhJRF9ERVNDX1JFRwkJCQkweDEKKyNkZWZpbmUgSElEX0lOUFVU X1JFRwkJCQkweDMKKyNkZWZpbmUgSElEX09VVFBVVF9SRUcJCQkJMHg0CisKKyNkZWZpbmUgUkVQ T1JUX0lEX1RPVUNICQkJMHgxCisjZGVmaW5lIFJFUE9SVF9JRF9CVE4JCQkJMHgzCisjZGVmaW5l IFJFUE9SVF9TSVpFXzUJCQkJNQorI2RlZmluZSBSRVBPUlRfU0laRV84CQkJCTgKKyNkZWZpbmUg UkVQT1JUX1NJWkVfMTYJCQkJMTYKKworLyogVG91Y2ggcmVwb3J0cyBvZmZzZXRzICovCisvKiBI ZWFkZXIgb2Zmc2V0cyAqLworI2RlZmluZSBUT1VDSF9SRVBPUlRfREVTQ19IRFJfQ09OVEFDVENP VU5UCTE2CisvKiBSZWNvcmQgb2Zmc2V0cyAqLworI2RlZmluZSBUT1VDSF9SRVBPUlRfREVTQ19D T05UQUNUSUQJCTgKKyNkZWZpbmUgVE9VQ0hfUkVQT1JUX0RFU0NfWAkJCTE2CisjZGVmaW5lIFRP VUNIX1JFUE9SVF9ERVNDX1kJCQkzMgorI2RlZmluZSBUT1VDSF9SRVBPUlRfREVTQ19QCQkJNDgK KyNkZWZpbmUgVE9VQ0hfUkVQT1JUX0RFU0NfTUFKCQkJNTYKKyNkZWZpbmUgVE9VQ0hfUkVQT1JU X0RFU0NfTUlOCQkJNjQKKworLyogSElEICovCisjZGVmaW5lIEhJRF9UT1VDSF9SRVBPUlRfSUQJ CQkweDEKKyNkZWZpbmUgSElEX0JUTl9SRVBPUlRfSUQJCQkweDMKKyNkZWZpbmUgSElEX0FQUF9S RVNQT05TRV9SRVBPUlRfSUQJCTB4MUYKKyNkZWZpbmUgSElEX0FQUF9PVVRQVVRfUkVQT1JUX0lE CQkweDJGCisjZGVmaW5lIEhJRF9CTF9SRVNQT05TRV9SRVBPUlRfSUQJCTB4MzAKKyNkZWZpbmUg SElEX0JMX09VVFBVVF9SRVBPUlRfSUQJCTB4NDAKKworI2RlZmluZSBISURfT1VUUFVUX1JFU1BP TlNFX1JFUE9SVF9PRkZTRVQJMgorI2RlZmluZSBISURfT1VUUFVUX1JFU1BPTlNFX0NNRF9PRkZT RVQJCTQKKyNkZWZpbmUgSElEX09VVFBVVF9SRVNQT05TRV9DTURfTUFTSwkJR0VOTUFTSyg2LCAw KQorCisjZGVmaW5lIEhJRF9TWVNJTkZPX1NFTlNJTkdfT0ZGU0VUCQkzMworI2RlZmluZSBISURf U1lTSU5GT19CVE5fT0ZGU0VUCQkJNDgKKyNkZWZpbmUgSElEX1NZU0lORk9fQlROX01BU0sJCQlH RU5NQVNLKDcsIDApCisjZGVmaW5lIEhJRF9TWVNJTkZPX01BWF9CVE4JCQk4CisKKyNkZWZpbmUg Q1lfSElEX09VVFBVVF9USU1FT1VUX01TCQkJMjAwCisjZGVmaW5lIENZX0hJRF9PVVRQVVRfR0VU X1NZU0lORk9fVElNRU9VVF9NUwkzMDAwCisjZGVmaW5lIENZX0hJRF9HRVRfSElEX0RFU0NSSVBU T1JfVElNRU9VVF9NUwk0MDAwCisKKy8qIG1heGltdW0gbnVtYmVyIG9mIGNvbmN1cnJlbnQgdHJh Y2tzICovCisjZGVmaW5lIFRPVUNIX1JFUE9SVF9TSVpFCQkJMTAKKyNkZWZpbmUgVE9VQ0hfSU5Q VVRfSEVBREVSX1NJWkUJCTcKKyNkZWZpbmUgQlROX1JFUE9SVF9TSVpFCQkJOQorI2RlZmluZSBC VE5fSU5QVVRfSEVBREVSX1NJWkUJCQk1CisKKyNkZWZpbmUgTUFYX0NZX1RDSF9UX0lEUwkzMgor CisvKiBBbGwgdXNhZ2UgcGFnZXMgZm9yIFRvdWNoIFJlcG9ydCAqLworI2RlZmluZSBUT1VDSF9S RVBPUlRfVVNBR0VfUEdfWAkJMHgwMDAxMDAzMAorI2RlZmluZSBUT1VDSF9SRVBPUlRfVVNBR0Vf UEdfWQkJMHgwMDAxMDAzMQorI2RlZmluZSBUT1VDSF9SRVBPUlRfVVNBR0VfUEdfUAkJMHgwMDBE MDAzMAorI2RlZmluZSBUT1VDSF9SRVBPUlRfVVNBR0VfUEdfQ09OVEFDVElECTB4MDAwRDAwNTEK KyNkZWZpbmUgVE9VQ0hfUkVQT1JUX1VTQUdFX1BHX0NPTlRBQ1RDT1VOVAkweDAwMEQwMDU0Cisj ZGVmaW5lIFRPVUNIX1JFUE9SVF9VU0FHRV9QR19NQUoJCTB4RkYwMTAwNjIKKyNkZWZpbmUgVE9V Q0hfUkVQT1JUX1VTQUdFX1BHX01JTgkJMHhGRjAxMDA2MworI2RlZmluZSBUT1VDSF9DT0xfVVNB R0VfUEcJCQkweDAwMEQwMDIyCisKKy8qIFN5c3RlbSBJbmZvcm1hdGlvbiBpbnRlcmZhY2UgZGVm aW5pdGlvbnMgKi8KK3N0cnVjdCBjeXR0c3A1X3NlbnNpbmdfY29uZl9kYXRhX2RldiB7CisJdTgg ZWxlY3Ryb2Rlc194OworCXU4IGVsZWN0cm9kZXNfeTsKKwlfX2xlMTYgbGVuX3g7CisJX19sZTE2 IGxlbl95OworCV9fbGUxNiByZXNfeDsKKwlfX2xlMTYgcmVzX3k7CisJX19sZTE2IG1heF96Owor CXU4IG9yaWdpbl94OworCXU4IG9yaWdpbl95OworCXU4IGJ0bjsKKwl1OCBzY2FuX21vZGU7CisJ dTggbWF4X251bV9vZl90Y2hfcGVyX3JlZnJlc2hfY3ljbGU7Cit9IF9fcGFja2VkOworCitzdHJ1 Y3QgY3l0dHNwNV9zZW5zaW5nX2NvbmZfZGF0YSB7CisJdTE2IHJlc194OworCXUxNiByZXNfeTsK Kwl1MTYgbWF4X3o7CisJdTE2IGxlbl94OworCXUxNiBsZW5feTsKKwl1OCBvcmlnaW5feDsKKwl1 OCBvcmlnaW5feTsKKwl1OCBtYXhfdGNoOworfTsKKworZW51bSBjeXR0c3A1X3RjaF9hYnMgewkv KiBmb3Igb3JkZXJpbmcgd2l0aGluIHRoZSBleHRyYWN0ZWQgdG91Y2ggZGF0YSBhcnJheSAqLwor CUNZX1RDSF9YLAkvKiBYICovCisJQ1lfVENIX1ksCS8qIFkgKi8KKwlDWV9UQ0hfUCwJLyogUCAo WikgKi8KKwlDWV9UQ0hfVCwJLyogVE9VQ0ggSUQgKi8KKwlDWV9UQ0hfTUFKLAkvKiBUT1VDSF9N QUpPUiAqLworCUNZX1RDSF9NSU4sCS8qIFRPVUNIX01JTk9SICovCisJQ1lfVENIX05VTV9BQlMK K307CisKK3N0cnVjdCBjeXR0c3A1X3RjaF9hYnNfcGFyYW1zIHsKKwlzaXplX3Qgb2ZzOwkvKiBh YnMgYnl0ZSBvZmZzZXQgKi8KKwlzaXplX3Qgc2l6ZTsJLyogc2l6ZSBpbiBiaXRzICovCisJc2l6 ZV90IG1pbjsJLyogbWluIHZhbHVlICovCisJc2l6ZV90IG1heDsJLyogbWF4IHZhbHVlICovCisJ c2l6ZV90IGJvZnM7CS8qIGJpdCBvZmZzZXQgKi8KK307CisKK3N0cnVjdCBjeXR0c3A1X3RvdWNo IHsKKwlpbnQgYWJzW0NZX1RDSF9OVU1fQUJTXTsKK307CisKK3N0cnVjdCBjeXR0c3A1X3N5c2lu Zm8geworCXN0cnVjdCBjeXR0c3A1X3NlbnNpbmdfY29uZl9kYXRhIHNlbnNpbmdfY29uZl9kYXRh OworCWludCBudW1fYnRuczsKKwlzdHJ1Y3QgY3l0dHNwNV90Y2hfYWJzX3BhcmFtcyB0Y2hfaGRy OworCXN0cnVjdCBjeXR0c3A1X3RjaF9hYnNfcGFyYW1zIHRjaF9hYnNbQ1lfVENIX05VTV9BQlNd OworCXUzMiBrZXlfY29kZVtISURfU1lTSU5GT19NQVhfQlROXTsKK307CisKK3N0cnVjdCBjeXR0 c3A1X2hpZF9kZXNjIHsKKwlfX2xlMTYgaGlkX2Rlc2NfbGVuOworCXU4IHBhY2tldF9pZDsKKwl1 OCByZXNlcnZlZF9ieXRlOworCV9fbGUxNiBiY2RfdmVyc2lvbjsKKwlfX2xlMTYgcmVwb3J0X2Rl c2NfbGVuOworCV9fbGUxNiByZXBvcnRfZGVzY19yZWdpc3RlcjsKKwlfX2xlMTYgaW5wdXRfcmVn aXN0ZXI7CisJX19sZTE2IG1heF9pbnB1dF9sZW47CisJX19sZTE2IG91dHB1dF9yZWdpc3RlcjsK KwlfX2xlMTYgbWF4X291dHB1dF9sZW47CisJX19sZTE2IGNvbW1hbmRfcmVnaXN0ZXI7CisJX19s ZTE2IGRhdGFfcmVnaXN0ZXI7CisJX19sZTE2IHZlbmRvcl9pZDsKKwlfX2xlMTYgcHJvZHVjdF9p ZDsKKwlfX2xlMTYgdmVyc2lvbl9pZDsKKwl1OCByZXNlcnZlZFs0XTsKK30gX19wYWNrZWQ7CisK K3N0cnVjdCBjeXR0c3A1IHsKKwlzdHJ1Y3QgZGV2aWNlICpkZXY7CisJc3RydWN0IGNvbXBsZXRp b24gY21kX2RvbmU7CisJc3RydWN0IGN5dHRzcDVfc3lzaW5mbyBzeXNpbmZvOworCXN0cnVjdCBj eXR0c3A1X2hpZF9kZXNjIGhpZF9kZXNjOworCXU4IGNtZF9idWZbQ1lUVFNQNV9QUkVBTExPQ0FU RURfQ01EX0JVRkZFUl07CisJdTggaW5wdXRfYnVmW0NZX01BWF9JTlBVVF07CisJdTggcmVzcG9u c2VfYnVmW0NZX01BWF9JTlBVVF07CisJc3RydWN0IGdwaW9fZGVzYyAqcmVzZXRfZ3BpbzsKKwlz dHJ1Y3QgaW5wdXRfZGV2ICppbnB1dDsKKwljaGFyIHBoeXNbTkFNRV9NQVhdOworCWludCBudW1f cHJ2X3JlYzsKKwlzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7CisJc3RydWN0IHRvdWNoc2NyZWVuX3By b3BlcnRpZXMgcHJvcDsKKwlzdHJ1Y3QgcmVndWxhdG9yICp2ZGQ7Cit9OworCisvKgorICogRm9y IHdoYXQgaXMgdW5kZXJzdG9vZCBpbiB0aGUgZGF0YXNoZWV0LCB0aGUgcmVnaXN0ZXIgZG9lcyBu b3QKKyAqIG1hdHRlci4gRm9yIGNvbnNpc3RlbmN5LCB1c2UgdGhlIElucHV0IFJlZ2lzdGVyIGFk ZHJlc3MKKyAqIGJ1dCBpdCBkb2VzIG1lYW4gYW55dGhpbmcgdG8gdGhlIGRldmljZS4gVGhlIGlt cG9ydGFudCBkYXRhCisgKiB0byBzZW5kIGlzIHRoZSBJMkMgYWRkcmVzcworICovCitzdGF0aWMg aW50IGN5dHRzcDVfcmVhZChzdHJ1Y3QgY3l0dHNwNSAqdHMsIHU4ICpidWYsIHUzMiBtYXgpCit7 CisJaW50IGVycm9yOworCXUzMiBzaXplOworCXU4IHRlbXBbMl07CisKKwkvKiBSZWFkIHRoZSBm cmFtZSB0byByZXRyaWV2ZSB0aGUgc2l6ZSAqLworCWVycm9yID0gcmVnbWFwX2J1bGtfcmVhZCh0 cy0+cmVnbWFwLCBISURfSU5QVVRfUkVHLCB0ZW1wLCBzaXplb2YodGVtcCkpOworCWlmIChlcnJv cikKKwkJcmV0dXJuIGVycm9yOworCisJc2l6ZSA9IGdldF91bmFsaWduZWRfbGUxNih0ZW1wKTsK KwlpZiAoIXNpemUgfHwgc2l6ZSA9PSAyKQorCQlyZXR1cm4gMDsKKworCWlmIChzaXplID4gbWF4 KQorCQlyZXR1cm4gLUVJTlZBTDsKKworCS8qIEdldCB0aGUgcmVhbCB2YWx1ZSAqLworCXJldHVy biByZWdtYXBfYnVsa19yZWFkKHRzLT5yZWdtYXAsIEhJRF9JTlBVVF9SRUcsIGJ1Ziwgc2l6ZSk7 Cit9CisKK3N0YXRpYyBpbnQgY3l0dHNwNV93cml0ZShzdHJ1Y3QgY3l0dHNwNSAqdHMsIHVuc2ln bmVkIGludCByZWcsIHU4ICpkYXRhLAorCQkJIHNpemVfdCBzaXplKQoreworCXU4IGNtZFtISURf T1VUUFVUX01BWF9DTURfU0laRV07CisKKwlpZiAoc2l6ZSArIDEgPiBISURfT1VUUFVUX01BWF9D TURfU0laRSkKKwkJcmV0dXJuIC1FMkJJRzsKKworCS8qIEhpZ2ggYnl0ZXMgb2YgcmVnaXN0ZXIg YWRkcmVzcyBuZWVkZWQgYXMgZmlyc3QgYnl0ZSBvZiBjbWQgKi8KKwljbWRbMF0gPSAocmVnID4+ IDgpICYgMHhGRiA7CisKKwkvKiBDb3B5IHRoZSByZXN0IG9mIHRoZSBkYXRhICovCisJaWYgKGRh dGEpCisJCW1lbWNweSgmY21kWzFdLCBkYXRhLCBzaXplKTsKKworCS8qCisJICogVGhlIGhhcmR3 YXJlIHdhbnRzIHRvIHJlY2VpdmUgYSBmcmFtZSB3aXRoIHRoZSBhZGRyZXNzIHJlZ2lzdGVyCisJ ICogY29udGFpbmVkIGluIHRoZSBmaXJzdCB0d28gYnl0ZXMuIEFzIHRoZSByZWdtYXBfd3JpdGUg ZnVuY3Rpb24KKwkgKiBhZGQgdGhlIHJlZ2lzdGVyIGFkcmVzc2UgaW4gdGhlIGZyYW1lLCB3ZSB1 c2UgdGhlIGxvdyBieXRlIGFzCisJICogZmlyc3QgZnJhbWUgYnl0ZSBmb3IgdGhlIGFkZHJlc3Mg cmVnaXN0ZXIgYW5kIHRoZSBmaXJzdAorCSAqIGRhdGEgYnl0ZSBpcyB0aGUgaGlnaCByZWdpc3Rl ciArIGxlZnQgb2YgdGhlIGNtZCB0byBzZW5kCisJICovCisJcmV0dXJuIHJlZ21hcF9idWxrX3dy aXRlKHRzLT5yZWdtYXAsIHJlZyAmIDB4RkYsIGNtZCwgc2l6ZSArIDEpOworfQorCitzdGF0aWMg dm9pZCBjeXR0c3A1X2dldF90b3VjaF9heGlzKGludCAqYXhpcywgaW50IHNpemUsIGludCBtYXgs IHU4ICp4eV9kYXRhLAorCQkJCSAgIGludCBib2ZzKQoreworCWludCBuYnl0ZTsKKworCWZvciAo bmJ5dGUgPSAwLCAqYXhpcyA9IDA7IG5ieXRlIDwgc2l6ZTsgbmJ5dGUrKykKKwkJKmF4aXMgKz0g KCh4eV9kYXRhW25ieXRlXSA+PiBib2ZzKSA8PCAobmJ5dGUgKiA4KSk7CisKKwkqYXhpcyAmPSBt YXggLSAxOworfQorCitzdGF0aWMgdm9pZCBjeXR0c3A1X2dldF90b3VjaF9yZWNvcmQoc3RydWN0 IGN5dHRzcDUgKnRzLAorCQkJCSAgICAgc3RydWN0IGN5dHRzcDVfdG91Y2ggKnRvdWNoLCB1OCAq eHlfZGF0YSkKK3sKKwlzdHJ1Y3QgY3l0dHNwNV9zeXNpbmZvICpzaSA9ICZ0cy0+c3lzaW5mbzsK KwllbnVtIGN5dHRzcDVfdGNoX2FicyBhYnM7CisKKwlmb3IgKGFicyA9IENZX1RDSF9YOyBhYnMg PCBDWV9UQ0hfTlVNX0FCUzsgYWJzKyspCisJCWN5dHRzcDVfZ2V0X3RvdWNoX2F4aXMoJnRvdWNo LT5hYnNbYWJzXSwKKwkJCQkgICAgICAgc2ktPnRjaF9hYnNbYWJzXS5zaXplLAorCQkJCSAgICAg ICBzaS0+dGNoX2Fic1thYnNdLm1heCwKKwkJCQkgICAgICAgeHlfZGF0YSArIHNpLT50Y2hfYWJz W2Fic10ub2ZzLAorCQkJCSAgICAgICBzaS0+dGNoX2Fic1thYnNdLmJvZnMpOworfQorCitzdGF0 aWMgdm9pZCBjeXR0c3A1X2dldF9tdF90b3VjaGVzKHN0cnVjdCBjeXR0c3A1ICp0cywKKwkJCQkg ICBzdHJ1Y3QgY3l0dHNwNV90b3VjaCAqdGNoLCBpbnQgbnVtX2N1cl90Y2gpCit7CisJc3RydWN0 IGN5dHRzcDVfc3lzaW5mbyAqc2kgPSAmdHMtPnN5c2luZm87CisJaW50IGksIHQgPSAwLCBvZmZz ZXQgPSAwOworCURFQ0xBUkVfQklUTUFQKGlkcywgTUFYX0NZX1RDSF9UX0lEUyk7CisJdTggKnRj aF9hZGRyOworCWludCB0bXA7CisKKwliaXRtYXBfemVybyhpZHMsIE1BWF9DWV9UQ0hfVF9JRFMp OworCW1lbXNldCh0Y2gtPmFicywgMCwgc2l6ZW9mKHRjaC0+YWJzKSk7CisKKwlzd2l0Y2ggKHRz LT5pbnB1dF9idWZbMl0pIHsKKwljYXNlIEhJRF9UT1VDSF9SRVBPUlRfSUQ6CisJCW9mZnNldCA9 IFRPVUNIX0lOUFVUX0hFQURFUl9TSVpFOworCQlicmVhazsKKwljYXNlIEhJRF9CVE5fUkVQT1JU X0lEOgorCQlvZmZzZXQgPSBCVE5fSU5QVVRfSEVBREVSX1NJWkU7CisJCWJyZWFrOworCX0KKwor CWZvciAoaSA9IDA7IGkgPCBudW1fY3VyX3RjaDsgaSsrKSB7CisJCXRjaF9hZGRyID0gdHMtPmlu cHV0X2J1ZiArIG9mZnNldCArIChpICogVE9VQ0hfUkVQT1JUX1NJWkUpOworCQljeXR0c3A1X2dl dF90b3VjaF9yZWNvcmQodHMsIHRjaCwgdGNoX2FkZHIpOworCisJCS8qIENvbnZlcnQgTUFKT1Iv TUlOT1IgZnJvbSBtbSB0byByZXNvbHV0aW9uICovCisJCXRtcCA9IHRjaC0+YWJzW0NZX1RDSF9N QUpdICogMTAwICogc2ktPnNlbnNpbmdfY29uZl9kYXRhLnJlc194OworCQl0Y2gtPmFic1tDWV9U Q0hfTUFKXSA9IHRtcCAvIHNpLT5zZW5zaW5nX2NvbmZfZGF0YS5sZW5feDsKKwkJdG1wID0gdGNo LT5hYnNbQ1lfVENIX01JTl0gKiAxMDAgKiBzaS0+c2Vuc2luZ19jb25mX2RhdGEucmVzX3g7CisJ CXRjaC0+YWJzW0NZX1RDSF9NSU5dID0gdG1wIC8gc2ktPnNlbnNpbmdfY29uZl9kYXRhLmxlbl94 OworCisJCXQgPSB0Y2gtPmFic1tDWV9UQ0hfVF07CisJCWlucHV0X210X3Nsb3QodHMtPmlucHV0 LCB0KTsKKwkJaW5wdXRfbXRfcmVwb3J0X3Nsb3Rfc3RhdGUodHMtPmlucHV0LCBNVF9UT09MX0ZJ TkdFUiwgdHJ1ZSk7CisJCV9fc2V0X2JpdCh0LCBpZHMpOworCisJCS8qIHBvc2l0aW9uIGFuZCBw cmVzc3VyZSBmaWVsZHMgKi8KKwkJdG91Y2hzY3JlZW5fcmVwb3J0X3Bvcyh0cy0+aW5wdXQsICZ0 cy0+cHJvcCwKKwkJCQkgICAgICAgdGNoLT5hYnNbQ1lfVENIX1hdLCB0Y2gtPmFic1tDWV9UQ0hf WV0sCisJCQkJICAgICAgIHRydWUpOworCQlpbnB1dF9yZXBvcnRfYWJzKHRzLT5pbnB1dCwgQUJT X01UX1BSRVNTVVJFLAorCQkJCSB0Y2gtPmFic1tDWV9UQ0hfUF0pOworCisJCS8qIEdldCB0aGUg ZXh0ZW5kZWQgdG91Y2ggZmllbGRzICovCisJCWlucHV0X3JlcG9ydF9hYnModHMtPmlucHV0LCBB QlNfTVRfVE9VQ0hfTUFKT1IsCisJCQkJIHRjaC0+YWJzW0NZX1RDSF9NQUpdKTsKKwkJaW5wdXRf cmVwb3J0X2Ficyh0cy0+aW5wdXQsIEFCU19NVF9UT1VDSF9NSU5PUiwKKwkJCQkgdGNoLT5hYnNb Q1lfVENIX01JTl0pOworCX0KKworCXRzLT5udW1fcHJ2X3JlYyA9IG51bV9jdXJfdGNoOworfQor CitzdGF0aWMgaW50IGN5dHRzcDVfbXRfYXR0ZW50aW9uKHN0cnVjdCBkZXZpY2UgKmRldikKK3sK KwlzdHJ1Y3QgY3l0dHNwNSAqdHMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKwlzdHJ1Y3QgY3l0 dHNwNV9zeXNpbmZvICpzaSA9ICZ0cy0+c3lzaW5mbzsKKwlpbnQgbWF4X3RjaCA9IHNpLT5zZW5z aW5nX2NvbmZfZGF0YS5tYXhfdGNoOworCXN0cnVjdCBjeXR0c3A1X3RvdWNoIHRjaDsKKwlpbnQg bnVtX2N1cl90Y2g7CisKKwljeXR0c3A1X2dldF90b3VjaF9heGlzKCZudW1fY3VyX3RjaCwgc2kt PnRjaF9oZHIuc2l6ZSwKKwkJCSAgICAgICBzaS0+dGNoX2hkci5tYXgsCisJCQkgICAgICAgdHMt PmlucHV0X2J1ZiArIDMgKyBzaS0+dGNoX2hkci5vZnMsCisJCQkgICAgICAgc2ktPnRjaF9oZHIu Ym9mcyk7CisKKwlpZiAobnVtX2N1cl90Y2ggPiBtYXhfdGNoKSB7CisJCWRldl9lcnIoZGV2LCAi TnVtIHRvdWNoIGVyciBkZXRlY3RlZCAobj0lZClcbiIsIG51bV9jdXJfdGNoKTsKKwkJbnVtX2N1 cl90Y2ggPSBtYXhfdGNoOworCX0KKworCWlmIChudW1fY3VyX3RjaCA9PSAwICYmIHRzLT5udW1f cHJ2X3JlYyA9PSAwKQorCQlyZXR1cm4gMDsKKworCS8qIGV4dHJhY3QgeHlfZGF0YSBmb3IgYWxs IGN1cnJlbnRseSByZXBvcnRlZCB0b3VjaGVzICovCisJaWYgKG51bV9jdXJfdGNoKQorCQljeXR0 c3A1X2dldF9tdF90b3VjaGVzKHRzLCAmdGNoLCBudW1fY3VyX3RjaCk7CisKKwlpbnB1dF9tdF9z eW5jX2ZyYW1lKHRzLT5pbnB1dCk7CisJaW5wdXRfc3luYyh0cy0+aW5wdXQpOworCisJcmV0dXJu IDA7Cit9CisKK3N0YXRpYyBpbnQgY3l0dHNwNV9zZXR1cF9pbnB1dF9kZXZpY2Uoc3RydWN0IGRl dmljZSAqZGV2KQoreworCXN0cnVjdCBjeXR0c3A1ICp0cyA9IGRldl9nZXRfZHJ2ZGF0YShkZXYp OworCXN0cnVjdCBjeXR0c3A1X3N5c2luZm8gKnNpID0gJnRzLT5zeXNpbmZvOworCWludCBtYXhf eCwgbWF4X3ksIG1heF9wOworCWludCBtYXhfeF90bXAsIG1heF95X3RtcDsKKwlpbnQgZXJyb3I7 CisKKwltYXhfeF90bXAgPSBzaS0+c2Vuc2luZ19jb25mX2RhdGEucmVzX3g7CisJbWF4X3lfdG1w ID0gc2ktPnNlbnNpbmdfY29uZl9kYXRhLnJlc195OworCW1heF94ID0gbWF4X3hfdG1wIC0gMTsK KwltYXhfeSA9IG1heF95X3RtcCAtIDE7CisJbWF4X3AgPSBzaS0+c2Vuc2luZ19jb25mX2RhdGEu bWF4X3o7CisKKwlpbnB1dF9zZXRfYWJzX3BhcmFtcyh0cy0+aW5wdXQsIEFCU19NVF9QT1NJVElP Tl9YLCAwLCBtYXhfeCwgMCwgMCk7CisJaW5wdXRfc2V0X2Fic19wYXJhbXModHMtPmlucHV0LCBB QlNfTVRfUE9TSVRJT05fWSwgMCwgbWF4X3ksIDAsIDApOworCWlucHV0X3NldF9hYnNfcGFyYW1z KHRzLT5pbnB1dCwgQUJTX01UX1BSRVNTVVJFLCAwLCBtYXhfcCwgMCwgMCk7CisKKwlpbnB1dF9z ZXRfYWJzX3BhcmFtcyh0cy0+aW5wdXQsIEFCU19NVF9UT1VDSF9NQUpPUiwgMCwgTUFYX0FSRUEs IDAsIDApOworCWlucHV0X3NldF9hYnNfcGFyYW1zKHRzLT5pbnB1dCwgQUJTX01UX1RPVUNIX01J Tk9SLCAwLCBNQVhfQVJFQSwgMCwgMCk7CisKKwllcnJvciA9IGlucHV0X210X2luaXRfc2xvdHMo dHMtPmlucHV0LCBzaS0+dGNoX2Fic1tDWV9UQ0hfVF0ubWF4LAorCQlJTlBVVF9NVF9EUk9QX1VO VVNFRCB8IElOUFVUX01UX0RJUkVDVCk7CisJaWYgKGVycm9yIDwgMCkKKwkJcmV0dXJuIGVycm9y OworCisJZXJyb3IgPSBpbnB1dF9yZWdpc3Rlcl9kZXZpY2UodHMtPmlucHV0KTsKKwlpZiAoZXJy b3IgPCAwKQorCQlkZXZfZXJyKGRldiwgIkVycm9yLCBmYWlsZWQgcmVnaXN0ZXIgaW5wdXQgZGV2 aWNlIHI9JWRcbiIsIGVycm9yKTsKKworCXJldHVybiBlcnJvcjsKK30KKworc3RhdGljIGludCBj eXR0c3A1X3BhcnNlX2R0X2tleV9jb2RlKHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3Qg Y3l0dHNwNSAqdHMgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKwlzdHJ1Y3QgY3l0dHNwNV9zeXNp bmZvICpzaSA9ICZ0cy0+c3lzaW5mbzsKKworCWlmICghc2ktPm51bV9idG5zKQorCQlyZXR1cm4g MDsKKworCS8qIEluaXRpYWxpemUgdGhlIGJ1dHRvbiB0byBSRVNFUlZFRCAqLworCW1lbXNldDMy KHNpLT5rZXlfY29kZSwgS0VZX1JFU0VSVkVELCAgc2ktPm51bV9idG5zKTsKKworCXJldHVybiBk ZXZpY2VfcHJvcGVydHlfcmVhZF91MzJfYXJyYXkoZGV2LCAibGludXgsa2V5Y29kZXMiLAorCQkJ CSAgIHNpLT5rZXlfY29kZSwgc2ktPm51bV9idG5zKTsKK30KKworc3RhdGljIGludCBjeXR0c3A1 X2J0bl9hdHRlbnRpb24oc3RydWN0IGRldmljZSAqZGV2KQoreworCXN0cnVjdCBjeXR0c3A1ICp0 cyA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOworCXN0cnVjdCBjeXR0c3A1X3N5c2luZm8gKnNpID0g JnRzLT5zeXNpbmZvOworCWludCBjdXJfYnRuLCBvZmZzZXQgPSAwOworCWludCBjdXJfYnRuX3N0 YXRlOworCisJc3dpdGNoICh0cy0+aW5wdXRfYnVmWzJdKSB7CisJY2FzZSBISURfVE9VQ0hfUkVQ T1JUX0lEOgorCQlvZmZzZXQgPSBUT1VDSF9JTlBVVF9IRUFERVJfU0laRTsKKwkJYnJlYWs7CisJ Y2FzZSBISURfQlROX1JFUE9SVF9JRDoKKwkJb2Zmc2V0ID0gQlROX0lOUFVUX0hFQURFUl9TSVpF OworCQlicmVhazsKKwl9CisKKwlpZiAodHMtPmlucHV0X2J1ZlsyXSAhPSBISURfQlROX1JFUE9S VF9JRCB8fCAhc2ktPm51bV9idG5zKQorCQlyZXR1cm4gMDsKKworCS8qIGV4dHJhY3QgYnV0dG9u IHByZXNzL3JlbGVhc2UgdG91Y2ggaW5mb3JtYXRpb24gKi8KKwlmb3IgKGN1cl9idG4gPSAwOyBj dXJfYnRuIDwgc2ktPm51bV9idG5zOyBjdXJfYnRuKyspIHsKKwkJLyogR2V0IGN1cnJlbnQgYnV0 dG9uIHN0YXRlICovCisJCWN1cl9idG5fc3RhdGUgPSAodHMtPmlucHV0X2J1ZltvZmZzZXRdID4+ IChjdXJfYnRuICogQ1lfQklUU19QRVJfQlROKSkKKwkJCSYgQ1lfTlVNX0JUTl9FVkVOVF9JRDsK KworCQlpbnB1dF9yZXBvcnRfa2V5KHRzLT5pbnB1dCwgc2ktPmtleV9jb2RlW2N1cl9idG5dLAor CQkJCSBjdXJfYnRuX3N0YXRlKTsKKwkJaW5wdXRfc3luYyh0cy0+aW5wdXQpOworCX0KKworCXJl dHVybiAwOworfQorCitzdGF0aWMgaW50IGN5dHRzcDVfdmFsaWRhdGVfY21kX3Jlc3BvbnNlKHN0 cnVjdCBjeXR0c3A1ICp0cywgdTggY29kZSkKK3sKKwl1MTYgc2l6ZSwgY3JjOworCXU4IHN0YXR1 cywgcmVwb3J0X2lkOworCWludCBjb21tYW5kX2NvZGU7CisKKwlzaXplID0gZ2V0X3VuYWxpZ25l ZF9sZTE2KCZ0cy0+cmVzcG9uc2VfYnVmWzBdKTsKKworCWlmICghc2l6ZSkKKwkJcmV0dXJuIDA7 CisKKwlyZXBvcnRfaWQgPSB0cy0+cmVzcG9uc2VfYnVmW0hJRF9PVVRQVVRfUkVTUE9OU0VfUkVQ T1JUX09GRlNFVF07CisKKwlzd2l0Y2ggKHJlcG9ydF9pZCkgeworCWNhc2UgSElEX0JMX1JFU1BP TlNFX1JFUE9SVF9JRDogeworCQlpZiAodHMtPnJlc3BvbnNlX2J1Zls0XSAhPSBISURfT1VUUFVU X0JMX1NPUCkgeworCQkJZGV2X2Vycih0cy0+ZGV2LCAiSElEIG91dHB1dCByZXNwb25zZSwgd3Jv bmcgU09QXG4iKTsKKwkJCXJldHVybiAtRVBST1RPOworCQl9CisKKwkJaWYgKHRzLT5yZXNwb25z ZV9idWZbc2l6ZSAtIDFdICE9IEhJRF9PVVRQVVRfQkxfRU9QKSB7CisJCQlkZXZfZXJyKHRzLT5k ZXYsICJISUQgb3V0cHV0IHJlc3BvbnNlLCB3cm9uZyBFT1BcbiIpOworCQkJcmV0dXJuIC1FUFJP VE87CisJCX0KKworCQljcmMgPSBjcmNfaXR1X3QoMHhGRkZGLCAmdHMtPnJlc3BvbnNlX2J1Zls0 XSwgc2l6ZSAtIDcpOworCQlpZiAoZ2V0X3VuYWxpZ25lZF9sZTE2KCZ0cy0+cmVzcG9uc2VfYnVm W3NpemUgLSAzXSkgIT0gY3JjKSB7CisJCQlkZXZfZXJyKHRzLT5kZXYsICJISUQgb3V0cHV0IHJl c3BvbnNlLCB3cm9uZyBDUkMgMHglWFxuIiwKKwkJCQljcmMpOworCQkJcmV0dXJuIC1FUFJPVE87 CisJCX0KKworCQlzdGF0dXMgPSB0cy0+cmVzcG9uc2VfYnVmWzVdOworCQlpZiAoc3RhdHVzKSB7 CisJCQlkZXZfZXJyKHRzLT5kZXYsICJISUQgb3V0cHV0IHJlc3BvbnNlLCBFUlJPUjolZFxuIiwK KwkJCQlzdGF0dXMpOworCQkJcmV0dXJuIC1FUFJPVE87CisJCX0KKwkJYnJlYWs7CisJfQorCWNh c2UgSElEX0FQUF9SRVNQT05TRV9SRVBPUlRfSUQ6IHsKKwkJY29tbWFuZF9jb2RlID0gdHMtPnJl c3BvbnNlX2J1ZltISURfT1VUUFVUX1JFU1BPTlNFX0NNRF9PRkZTRVRdCisJCQkmIEhJRF9PVVRQ VVRfUkVTUE9OU0VfQ01EX01BU0s7CisJCWlmIChjb21tYW5kX2NvZGUgIT0gY29kZSkgeworCQkJ ZGV2X2Vycih0cy0+ZGV2LAorCQkJCSJISUQgb3V0cHV0IHJlc3BvbnNlLCB3cm9uZyBjb21tYW5k X2NvZGU6JVhcbiIsCisJCQkJY29tbWFuZF9jb2RlKTsKKwkJCXJldHVybiAtRVBST1RPOworCQl9 CisJCWJyZWFrOworCX0KKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgY3l0dHNw NV9zaV9nZXRfYnRuX2RhdGEoc3RydWN0IGN5dHRzcDUgKnRzKQoreworCXN0cnVjdCBjeXR0c3A1 X3N5c2luZm8gKnNpID0gJnRzLT5zeXNpbmZvOworCXVuc2lnbmVkIGludCBidG5zID0gdHMtPnJl c3BvbnNlX2J1ZltISURfU1lTSU5GT19CVE5fT0ZGU0VUXQorCQkmIEhJRF9TWVNJTkZPX0JUTl9N QVNLOworCisJc2ktPm51bV9idG5zID0gaHdlaWdodDgoYnRucyk7Cit9CisKK3N0YXRpYyBpbnQg Y3l0dHNwNV9nZXRfc3lzaW5mb19yZWdzKHN0cnVjdCBjeXR0c3A1ICp0cykKK3sKKwlzdHJ1Y3Qg Y3l0dHNwNV9zZW5zaW5nX2NvbmZfZGF0YSAqc2NkID0gJnRzLT5zeXNpbmZvLnNlbnNpbmdfY29u Zl9kYXRhOworCXN0cnVjdCBjeXR0c3A1X3NlbnNpbmdfY29uZl9kYXRhX2RldiAqc2NkX2RldiA9 CisJCShzdHJ1Y3QgY3l0dHNwNV9zZW5zaW5nX2NvbmZfZGF0YV9kZXYgKikKKwkJJnRzLT5yZXNw b25zZV9idWZbSElEX1NZU0lORk9fU0VOU0lOR19PRkZTRVRdOworCisJY3l0dHNwNV9zaV9nZXRf YnRuX2RhdGEodHMpOworCisJc2NkLT5tYXhfdGNoID0gc2NkX2Rldi0+bWF4X251bV9vZl90Y2hf cGVyX3JlZnJlc2hfY3ljbGU7CisJc2NkLT5yZXNfeCA9IGdldF91bmFsaWduZWRfbGUxNigmc2Nk X2Rldi0+cmVzX3gpOworCXNjZC0+cmVzX3kgPSBnZXRfdW5hbGlnbmVkX2xlMTYoJnNjZF9kZXYt PnJlc195KTsKKwlzY2QtPm1heF96ID0gZ2V0X3VuYWxpZ25lZF9sZTE2KCZzY2RfZGV2LT5tYXhf eik7CisJc2NkLT5sZW5feCA9IGdldF91bmFsaWduZWRfbGUxNigmc2NkX2Rldi0+bGVuX3gpOwor CXNjZC0+bGVuX3kgPSBnZXRfdW5hbGlnbmVkX2xlMTYoJnNjZF9kZXYtPmxlbl95KTsKKworCXJl dHVybiAwOworfQorCitzdGF0aWMgaW50IGN5dHRzcDVfaGlkX291dHB1dF9nZXRfc3lzaW5mbyhz dHJ1Y3QgY3l0dHNwNSAqdHMpCit7CisJaW50IHJjOworCXU4IGNtZFtISURfT1VUUFVUX0dFVF9T WVNJTkZPX1NJWkVdOworCisJLyogSEkgYnl0ZXMgb2YgT3V0cHV0IHJlZ2lzdGVyIGFkZHJlc3Mg Ki8KKwlwdXRfdW5hbGlnbmVkX2xlMTYoSElEX09VVFBVVF9HRVRfU1lTSU5GT19TSVpFLCBjbWQp OworCWNtZFsyXSA9IEhJRF9BUFBfT1VUUFVUX1JFUE9SVF9JRDsKKwljbWRbM10gPSAweDA7IC8q IFJlc2VydmVkICovCisJY21kWzRdID0gSElEX09VVFBVVF9HRVRfU1lTSU5GTzsKKworCXJjID0g Y3l0dHNwNV93cml0ZSh0cywgSElEX09VVFBVVF9SRUcsIGNtZCwKKwkJCSAgIEhJRF9PVVRQVVRf R0VUX1NZU0lORk9fU0laRSk7CisJaWYgKHJjKSB7CisJCWRldl9lcnIodHMtPmRldiwgIkZhaWxl ZCB0byB3cml0ZSBjb21tYW5kICVkIiwgcmMpOworCQlyZXR1cm4gcmM7CisJfQorCisJcmMgPSB3 YWl0X2Zvcl9jb21wbGV0aW9uX2ludGVycnVwdGlibGVfdGltZW91dCgmdHMtPmNtZF9kb25lLAor CQkJCQkJbXNlY3NfdG9famlmZmllcyhDWV9ISURfT1VUUFVUX0dFVF9TWVNJTkZPX1RJTUVPVVRf TVMpKTsKKwlpZiAocmMgPD0gMCkgeworCQlkZXZfZXJyKHRzLT5kZXYsICJISUQgb3V0cHV0IGNt ZCBleGVjdXRpb24gdGltZWQgb3V0XG4iKTsKKwkJcmMgPSAtRVRJTUVET1VUOworCQlyZXR1cm4g cmM7CisJfQorCisJcmMgPSBjeXR0c3A1X3ZhbGlkYXRlX2NtZF9yZXNwb25zZSh0cywgSElEX09V VFBVVF9HRVRfU1lTSU5GTyk7CisJaWYgKHJjKSB7CisJCWRldl9lcnIodHMtPmRldiwgIlZhbGlk YXRpb24gb2YgdGhlIHJlc3BvbnNlIGZhaWxlZFxuIik7CisJCXJldHVybiByYzsKKwl9CisKKwly ZXR1cm4gY3l0dHNwNV9nZXRfc3lzaW5mb19yZWdzKHRzKTsKK30KKworc3RhdGljIGludCBjeXR0 c3A1X2hpZF9vdXRwdXRfYmxfbGF1bmNoX2FwcChzdHJ1Y3QgY3l0dHNwNSAqdHMpCit7CisJaW50 IHJjOworCXU4IGNtZFtISURfT1VUUFVUX0JMX0xBVU5DSF9BUFBdOworCXUxNiBjcmM7CisKKwlw dXRfdW5hbGlnbmVkX2xlMTYoSElEX09VVFBVVF9CTF9MQVVOQ0hfQVBQX1NJWkUsIGNtZCk7CisJ Y21kWzJdID0gSElEX0JMX09VVFBVVF9SRVBPUlRfSUQ7CisJY21kWzNdID0gMHgwOyAvKiBSZXNl cnZlZCAqLworCWNtZFs0XSA9IEhJRF9PVVRQVVRfQkxfU09QOworCWNtZFs1XSA9IEhJRF9PVVRQ VVRfQkxfTEFVTkNIX0FQUDsKKwlwdXRfdW5hbGlnbmVkX2xlMTYoMHgwMCwgJmNtZFs2XSk7CisJ Y3JjID0gY3JjX2l0dV90KDB4RkZGRiwgJmNtZFs0XSwgNCk7CisJcHV0X3VuYWxpZ25lZF9sZTE2 KGNyYywgJmNtZFs4XSk7CisJY21kWzEwXSA9IEhJRF9PVVRQVVRfQkxfRU9QOworCisJcmMgPSBj eXR0c3A1X3dyaXRlKHRzLCBISURfT1VUUFVUX1JFRywgY21kLAorCQkJICAgSElEX09VVFBVVF9C TF9MQVVOQ0hfQVBQX1NJWkUpOworCWlmIChyYykgeworCQlkZXZfZXJyKHRzLT5kZXYsICJGYWls ZWQgdG8gd3JpdGUgY29tbWFuZCAlZCIsIHJjKTsKKwkJcmV0dXJuIHJjOworCX0KKworCXJjID0g d2FpdF9mb3JfY29tcGxldGlvbl9pbnRlcnJ1cHRpYmxlX3RpbWVvdXQoJnRzLT5jbWRfZG9uZSwK KwkJCQkJCW1zZWNzX3RvX2ppZmZpZXMoQ1lfSElEX09VVFBVVF9USU1FT1VUX01TKSk7CisJaWYg KHJjIDw9IDApIHsKKwkJZGV2X2Vycih0cy0+ZGV2LCAiSElEIG91dHB1dCBjbWQgZXhlY3V0aW9u IHRpbWVkIG91dFxuIik7CisJCXJjID0gLUVUSU1FRE9VVDsKKwkJcmV0dXJuIHJjOworCX0KKwor CXJjID0gY3l0dHNwNV92YWxpZGF0ZV9jbWRfcmVzcG9uc2UodHMsIEhJRF9PVVRQVVRfQkxfTEFV TkNIX0FQUCk7CisJaWYgKHJjKSB7CisJCWRldl9lcnIodHMtPmRldiwgIlZhbGlkYXRpb24gb2Yg dGhlIHJlc3BvbnNlIGZhaWxlZFxuIik7CisJCXJldHVybiByYzsKKwl9CisKKwlyZXR1cm4gMDsK K30KKworc3RhdGljIGludCBjeXR0c3A1X2dldF9oaWRfZGVzY3JpcHRvcihzdHJ1Y3QgY3l0dHNw NSAqdHMsCisJCQkJICAgICAgc3RydWN0IGN5dHRzcDVfaGlkX2Rlc2MgKmRlc2MpCit7CisJc3Ry dWN0IGRldmljZSAqZGV2ID0gdHMtPmRldjsKKwlfX2xlMTYgaGlkX2Rlc2NfcmVnaXN0ZXIgPSBj cHVfdG9fbGUxNihISURfREVTQ19SRUcpOworCWludCByYzsKKwl1OCBjbWRbMl07CisKKwkvKiBT ZXQgSElEIGRlc2NyaXB0b3IgcmVnaXN0ZXIgKi8KKwltZW1jcHkoY21kLCAmaGlkX2Rlc2NfcmVn aXN0ZXIsIHNpemVvZihoaWRfZGVzY19yZWdpc3RlcikpOworCisJcmMgPSBjeXR0c3A1X3dyaXRl KHRzLCBISURfREVTQ19SRUcsIE5VTEwsIDApOworCWlmIChyYykgeworCQlkZXZfZXJyKGRldiwg IkZhaWxlZCB0byBnZXQgSElEIGRlc2NyaXB0b3IsIHJjPSVkXG4iLCByYyk7CisJCXJldHVybiBy YzsKKwl9CisKKwlyYyA9IHdhaXRfZm9yX2NvbXBsZXRpb25faW50ZXJydXB0aWJsZV90aW1lb3V0 KCZ0cy0+Y21kX2RvbmUsCisJCQkJCQltc2Vjc190b19qaWZmaWVzKENZX0hJRF9HRVRfSElEX0RF U0NSSVBUT1JfVElNRU9VVF9NUykpOworCWlmIChyYyA8PSAwKSB7CisJCWRldl9lcnIodHMtPmRl diwgIkhJRCBnZXQgZGVzY3JpcHRvciB0aW1lZCBvdXRcbiIpOworCQlyYyA9IC1FVElNRURPVVQ7 CisJCXJldHVybiByYzsKKwl9CisKKwltZW1jcHkoZGVzYywgdHMtPnJlc3BvbnNlX2J1Ziwgc2l6 ZW9mKCpkZXNjKSk7CisKKwkvKiBDaGVjayBISUQgZGVzY3JpcHRvciBsZW5ndGggYW5kIHZlcnNp b24gKi8KKwlpZiAobGUxNl90b19jcHUoZGVzYy0+aGlkX2Rlc2NfbGVuKSAhPSBzaXplb2YoKmRl c2MpIHx8CisJICAgIGxlMTZfdG9fY3B1KGRlc2MtPmJjZF92ZXJzaW9uKSAhPSBISURfVkVSU0lP TikgeworCQlkZXZfZXJyKGRldiwgIlVuc3VwcG9ydGVkIEhJRCB2ZXJzaW9uXG4iKTsKKwkJcmV0 dXJuIC1FTk9ERVY7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgZmlsbF90Y2hf YWJzKHN0cnVjdCBjeXR0c3A1X3RjaF9hYnNfcGFyYW1zICp0Y2hfYWJzLCBpbnQgcmVwb3J0X3Np emUsCisJCQlpbnQgb2Zmc2V0KQoreworCXRjaF9hYnMtPm9mcyA9IG9mZnNldCAvIDg7CisJdGNo X2Ficy0+c2l6ZSA9IHJlcG9ydF9zaXplIC8gODsKKwlpZiAocmVwb3J0X3NpemUgJSA4KQorCQl0 Y2hfYWJzLT5zaXplICs9IDE7CisJdGNoX2Ficy0+bWluID0gMDsKKwl0Y2hfYWJzLT5tYXggPSAx IDw8IHJlcG9ydF9zaXplOworCXRjaF9hYnMtPmJvZnMgPSBvZmZzZXQgLSAodGNoX2Ficy0+b2Zz IDw8IDMpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpcnFyZXR1cm5fdCBjeXR0c3A1X2hh bmRsZV9pcnEoaW50IGlycSwgdm9pZCAqaGFuZGxlKQoreworCXN0cnVjdCBjeXR0c3A1ICp0cyA9 IGhhbmRsZTsKKwlpbnQgcmVwb3J0X2lkOworCWludCBzaXplOworCWludCBlcnJvcjsKKworCWVy cm9yID0gY3l0dHNwNV9yZWFkKHRzLCB0cy0+aW5wdXRfYnVmLCBDWV9NQVhfSU5QVVQpOworCWlm IChlcnJvcikKKwkJcmV0dXJuIElSUV9IQU5ETEVEOworCisJc2l6ZSA9IGdldF91bmFsaWduZWRf bGUxNigmdHMtPmlucHV0X2J1ZlswXSk7CisJaWYgKHNpemUgPT0gMCkgeworCQkvKiByZXNldCAq LworCQlyZXBvcnRfaWQgPSAwOworCQlzaXplID0gMjsKKwl9IGVsc2UgeworCQlyZXBvcnRfaWQg PSB0cy0+aW5wdXRfYnVmWzJdOworCX0KKworCXN3aXRjaCAocmVwb3J0X2lkKSB7CisJY2FzZSBI SURfVE9VQ0hfUkVQT1JUX0lEOgorCQljeXR0c3A1X210X2F0dGVudGlvbih0cy0+ZGV2KTsKKwkJ YnJlYWs7CisJY2FzZSBISURfQlROX1JFUE9SVF9JRDoKKwkJY3l0dHNwNV9idG5fYXR0ZW50aW9u KHRzLT5kZXYpOworCQlicmVhazsKKwlkZWZhdWx0OgorCQkvKiBJdCBpcyBub3QgYW4gaW5wdXQg YnV0IGEgY29tbWFuZCByZXNwb25zZSAqLworCQltZW1jcHkodHMtPnJlc3BvbnNlX2J1ZiwgdHMt PmlucHV0X2J1Ziwgc2l6ZSk7CisJCWNvbXBsZXRlKCZ0cy0+Y21kX2RvbmUpOworCX0KKworCXJl dHVybiBJUlFfSEFORExFRDsKK30KKworc3RhdGljIGludCBjeXR0c3A1X2RlYXNzZXJ0X2ludChz dHJ1Y3QgY3l0dHNwNSAqdHMpCit7CisJdTE2IHNpemU7CisJdTggYnVmWzJdOworCWludCBlcnJv cjsKKworCWVycm9yID0gcmVnbWFwX2J1bGtfcmVhZCh0cy0+cmVnbWFwLCBISURfSU5QVVRfUkVH LCBidWYsIHNpemVvZihidWYpKTsKKwlpZiAoZXJyb3IgPCAwKQorCQlyZXR1cm4gZXJyb3I7CisK KwlzaXplID0gZ2V0X3VuYWxpZ25lZF9sZTE2KCZidWZbMF0pOworCWlmIChzaXplID09IDIgfHwg c2l6ZSA9PSAwKQorCQlyZXR1cm4gMDsKKworCXJldHVybiAtRUlOVkFMOworfQorCitzdGF0aWMg aW50IGN5dHRzcDVfZmlsbF9hbGxfdG91Y2goc3RydWN0IGN5dHRzcDUgKnRzKQoreworCXN0cnVj dCBjeXR0c3A1X3N5c2luZm8gKnNpID0gJnRzLT5zeXNpbmZvOworCisJZmlsbF90Y2hfYWJzKCZz aS0+dGNoX2Fic1tDWV9UQ0hfWF0sIFJFUE9SVF9TSVpFXzE2LAorCQkgICAgIFRPVUNIX1JFUE9S VF9ERVNDX1gpOworCWZpbGxfdGNoX2Ficygmc2ktPnRjaF9hYnNbQ1lfVENIX1ldLCBSRVBPUlRf U0laRV8xNiwKKwkJICAgICBUT1VDSF9SRVBPUlRfREVTQ19ZKTsKKwlmaWxsX3RjaF9hYnMoJnNp LT50Y2hfYWJzW0NZX1RDSF9QXSwgUkVQT1JUX1NJWkVfOCwKKwkJICAgICBUT1VDSF9SRVBPUlRf REVTQ19QKTsKKwlmaWxsX3RjaF9hYnMoJnNpLT50Y2hfYWJzW0NZX1RDSF9UXSwgUkVQT1JUX1NJ WkVfNSwKKwkJICAgICBUT1VDSF9SRVBPUlRfREVTQ19DT05UQUNUSUQpOworCWZpbGxfdGNoX2Fi cygmc2ktPnRjaF9oZHIsIFJFUE9SVF9TSVpFXzUsCisJCSAgICAgVE9VQ0hfUkVQT1JUX0RFU0Nf SERSX0NPTlRBQ1RDT1VOVCk7CisJZmlsbF90Y2hfYWJzKCZzaS0+dGNoX2Fic1tDWV9UQ0hfTUFK XSwgUkVQT1JUX1NJWkVfOCwKKwkJICAgICBUT1VDSF9SRVBPUlRfREVTQ19NQUopOworCWZpbGxf dGNoX2Ficygmc2ktPnRjaF9hYnNbQ1lfVENIX01JTl0sIFJFUE9SVF9TSVpFXzgsCisJCSAgICAg VE9VQ0hfUkVQT1JUX0RFU0NfTUlOKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGN5 dHRzcDVfc3RhcnR1cChzdHJ1Y3QgY3l0dHNwNSAqdHMpCit7CisJaW50IGVycm9yOworCisJZXJy b3IgPSBjeXR0c3A1X2RlYXNzZXJ0X2ludCh0cyk7CisJaWYgKGVycm9yKSB7CisJCWRldl9lcnIo dHMtPmRldiwgIkVycm9yIG9uIGRlYXNzZXJ0IGludCByPSVkXG4iLCBlcnJvcik7CisJCXJldHVy biAtRU5PREVWOworCX0KKworCS8qCisJICogTGF1bmNoIHRoZSBhcHBsaWNhdGlvbiBhcyB0aGUg ZGV2aWNlIHN0YXJ0cyBpbiBib290bG9hZGVyIG1vZGUKKwkgKiBiZWNhdXNlIG9mIGEgcG93ZXIt b24tcmVzZXQKKwkgKi8KKwllcnJvciA9IGN5dHRzcDVfaGlkX291dHB1dF9ibF9sYXVuY2hfYXBw KHRzKTsKKwlpZiAoZXJyb3IgPCAwKSB7CisJCWRldl9lcnIodHMtPmRldiwgIkVycm9yIG9uIGxh dW5jaCBhcHAgcj0lZFxuIiwgZXJyb3IpOworCQlyZXR1cm4gZXJyb3I7CisJfQorCisJZXJyb3Ig PSBjeXR0c3A1X2dldF9oaWRfZGVzY3JpcHRvcih0cywgJnRzLT5oaWRfZGVzYyk7CisJaWYgKGVy cm9yIDwgMCkgeworCQlkZXZfZXJyKHRzLT5kZXYsICJFcnJvciBvbiBnZXR0aW5nIEhJRCBkZXNj cmlwdG9yIHI9JWRcbiIsIGVycm9yKTsKKwkJcmV0dXJuIGVycm9yOworCX0KKworCWVycm9yID0g Y3l0dHNwNV9maWxsX2FsbF90b3VjaCh0cyk7CisJaWYgKGVycm9yIDwgMCkgeworCQlkZXZfZXJy KHRzLT5kZXYsICJFcnJvciBvbiByZXBvcnQgZGVzY3JpcHRvciByPSVkXG4iLCBlcnJvcik7CisJ CXJldHVybiBlcnJvcjsKKwl9CisKKwllcnJvciA9IGN5dHRzcDVfaGlkX291dHB1dF9nZXRfc3lz aW5mbyh0cyk7CisJaWYgKGVycm9yKSB7CisJCWRldl9lcnIodHMtPmRldiwgIkVycm9yIG9uIGdl dHRpbmcgc3lzaW5mbyByPSVkXG4iLCBlcnJvcik7CisJCXJldHVybiBlcnJvcjsKKwl9CisKKwly ZXR1cm4gZXJyb3I7Cit9CisKK3N0YXRpYyB2b2lkIGN5dHRzcDVfY2xlYW51cCh2b2lkICpkYXRh KQoreworCXN0cnVjdCBjeXR0c3A1ICp0cyA9IGRhdGE7CisKKwlyZWd1bGF0b3JfZGlzYWJsZSh0 cy0+dmRkKTsKK30KKworc3RhdGljIGludCBjeXR0c3A1X3Byb2JlKHN0cnVjdCBkZXZpY2UgKmRl diwgc3RydWN0IHJlZ21hcCAqcmVnbWFwLCBpbnQgaXJxLAorCQkJIGNvbnN0IGNoYXIgKm5hbWUp Cit7CisJc3RydWN0IGN5dHRzcDUgKnRzOworCXN0cnVjdCBjeXR0c3A1X3N5c2luZm8gKnNpOwor CWludCBlcnJvciwgaTsKKworCXRzID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCp0cyksIEdG UF9LRVJORUwpOworCWlmICghdHMpCisJCXJldHVybiAtRU5PTUVNOworCisJLyogSW5pdGlhbGl6 ZSBkZXZpY2UgaW5mbyAqLworCXRzLT5yZWdtYXAgPSByZWdtYXA7CisJdHMtPmRldiA9IGRldjsK KwlzaSA9ICZ0cy0+c3lzaW5mbzsKKwlkZXZfc2V0X2RydmRhdGEoZGV2LCB0cyk7CisKKwlpbml0 X2NvbXBsZXRpb24oJnRzLT5jbWRfZG9uZSk7CisKKwkvKiBQb3dlciB1cCB0aGUgZGV2aWNlICov CisJdHMtPnZkZCA9IGRldm1fcmVndWxhdG9yX2dldChkZXYsICJ2ZGQiKTsKKwlpZiAoSVNfRVJS KHRzLT52ZGQpKSB7CisJCWVycm9yID0gUFRSX0VSUih0cy0+dmRkKTsKKwkJcmV0dXJuIGVycm9y OworCX0KKworCWVycm9yID0gZGV2bV9hZGRfYWN0aW9uX29yX3Jlc2V0KGRldiwgY3l0dHNwNV9j bGVhbnVwLCB0cyk7CisJaWYgKGVycm9yKSB7CisJCXJldHVybiBlcnJvcjsKKwl9CisKKwllcnJv ciA9IHJlZ3VsYXRvcl9lbmFibGUodHMtPnZkZCk7CisJaWYgKGVycm9yKSB7CisJCXJldHVybiBl cnJvcjsKKwl9CisKKwl0cy0+aW5wdXQgPSBkZXZtX2lucHV0X2FsbG9jYXRlX2RldmljZShkZXYp OworCWlmICghdHMtPmlucHV0KSB7CisJCWRldl9lcnIoZGV2LCAiRXJyb3IsIGZhaWxlZCB0byBh bGxvY2F0ZSBpbnB1dCBkZXZpY2VcbiIpOworCQlyZXR1cm4gLUVOT0RFVjsKKwl9CisKKwl0cy0+ aW5wdXQtPm5hbWUgPSAiY3l0dHNwNSI7CisJc2NucHJpbnRmKHRzLT5waHlzLCBzaXplb2YodHMt PnBoeXMpLCAiJXMvaW5wdXQwIiwgZGV2X25hbWUoZGV2KSk7CisJdHMtPmlucHV0LT5waHlzID0g dHMtPnBoeXM7CisJaW5wdXRfc2V0X2RydmRhdGEodHMtPmlucHV0LCB0cyk7CisKKwkvKiBSZXNl dCB0aGUgZ3BpbyB0byBiZSBpbiBhIHJlc2V0IHN0YXRlICovCisJdHMtPnJlc2V0X2dwaW8gPSBk ZXZtX2dwaW9kX2dldF9vcHRpb25hbChkZXYsICJyZXNldCIsIEdQSU9EX09VVF9ISUdIKTsKKwlp ZiAoSVNfRVJSKHRzLT5yZXNldF9ncGlvKSkgeworCQllcnJvciA9IFBUUl9FUlIodHMtPnJlc2V0 X2dwaW8pOworCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byByZXF1ZXN0IHJlc2V0IGdwaW8sIGVy cm9yICVkXG4iLCBlcnJvcik7CisJCXJldHVybiBlcnJvcjsKKwl9CisJZ3Bpb2Rfc2V0X3ZhbHVl KHRzLT5yZXNldF9ncGlvLCAwKTsKKworCS8qIE5lZWQgYSBkZWxheSB0byBoYXZlIGRldmljZSB1 cCAqLworCW1zbGVlcCgyMCk7CisKKwllcnJvciA9IGRldm1fcmVxdWVzdF90aHJlYWRlZF9pcnEo ZGV2LCBpcnEsIE5VTEwsIGN5dHRzcDVfaGFuZGxlX2lycSwKKwkJCQkgICAgICAgSVJRRl9PTkVT SE9ULCBuYW1lLCB0cyk7CisJaWYgKGVycm9yKSB7CisJCWRldl9lcnIoZGV2LCAidW5hYmxlIHRv IHJlcXVlc3QgSVJRXG4iKTsKKwkJcmV0dXJuIGVycm9yOworCX0KKworCWVycm9yID0gY3l0dHNw NV9zdGFydHVwKHRzKTsKKwlpZiAoZXJyb3IpIHsKKwkJZGV2X2Vycih0cy0+ZGV2LCAiRmFpbCBp bml0aWFsIHN0YXJ0dXAgcj0lZFxuIiwgZXJyb3IpOworCQlyZXR1cm4gZXJyb3I7CisJfQorCisJ ZXJyb3IgPSBjeXR0c3A1X3BhcnNlX2R0X2tleV9jb2RlKGRldik7CisJaWYgKGVycm9yIDwgMCkg eworCQlkZXZfZXJyKHRzLT5kZXYsICJFcnJvciB3aGlsZSBwYXJzaW5nIGR0cyAlZFxuIiwgZXJy b3IpOworCQlyZXR1cm4gZXJyb3I7CisJfQorCisJdG91Y2hzY3JlZW5fcGFyc2VfcHJvcGVydGll cyh0cy0+aW5wdXQsIHRydWUsICZ0cy0+cHJvcCk7CisKKwlfX3NldF9iaXQoRVZfS0VZLCB0cy0+ aW5wdXQtPmV2Yml0KTsKKwlmb3IgKGkgPSAwOyBpIDwgc2ktPm51bV9idG5zOyBpKyspCisJCV9f c2V0X2JpdChzaS0+a2V5X2NvZGVbaV0sIHRzLT5pbnB1dC0+a2V5Yml0KTsKKworCXJldHVybiBj eXR0c3A1X3NldHVwX2lucHV0X2RldmljZShkZXYpOworfQorCitzdGF0aWMgaW50IGN5dHRzcDVf aTJjX3Byb2JlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQsCisJCQkgICAgIGNvbnN0IHN0cnVj dCBpMmNfZGV2aWNlX2lkICppZCkKK3sKKwlzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7CisJc3RhdGlj IGNvbnN0IHN0cnVjdCByZWdtYXBfY29uZmlnIGNvbmZpZyA9IHsKKwkJLnJlZ19iaXRzID0gOCwK KwkJLnZhbF9iaXRzID0gOCwKKwl9OworCisJcmVnbWFwID0gZGV2bV9yZWdtYXBfaW5pdF9pMmMo Y2xpZW50LCAmY29uZmlnKTsKKwlpZiAoSVNfRVJSKHJlZ21hcCkpIHsKKwkJZGV2X2VycigmY2xp ZW50LT5kZXYsICJyZWdtYXAgYWxsb2NhdGlvbiBmYWlsZWQ6ICVsZFxuIiwKKwkJCVBUUl9FUlIo cmVnbWFwKSk7CisJCXJldHVybiBQVFJfRVJSKHJlZ21hcCk7CisJfQorCisJcmV0dXJuIGN5dHRz cDVfcHJvYmUoJmNsaWVudC0+ZGV2LCByZWdtYXAsIGNsaWVudC0+aXJxLCBjbGllbnQtPm5hbWUp OworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBjeXR0c3A1X29mX21hdGNo W10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJjeXByZXNzLHR0MjEwMDAiLCB9LAorCXsgfQorfTsK K01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGN5dHRzcDVfb2ZfbWF0Y2gpOworCitzdGF0aWMgY29u c3Qgc3RydWN0IGkyY19kZXZpY2VfaWQgY3l0dHNwNV9pMmNfaWRbXSA9IHsKKwl7IENZVFRTUDVf TkFNRSwgMCwgfSwKKwl7IH0KK307CitNT0RVTEVfREVWSUNFX1RBQkxFKGkyYywgY3l0dHNwNV9p MmNfaWQpOworCitzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIgY3l0dHNwNV9pMmNfZHJpdmVyID0g eworCS5kcml2ZXIgPSB7CisJCS5uYW1lID0gQ1lUVFNQNV9OQU1FLAorCQkub2ZfbWF0Y2hfdGFi bGUgPSBjeXR0c3A1X29mX21hdGNoLAorCX0sCisJLnByb2JlID0gY3l0dHNwNV9pMmNfcHJvYmUs CisJLmlkX3RhYmxlID0gY3l0dHNwNV9pMmNfaWQsCit9OworbW9kdWxlX2kyY19kcml2ZXIoY3l0 dHNwNV9pMmNfZHJpdmVyKTsKKworTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOworTU9EVUxFX0RFU0NS SVBUSU9OKCJUb3VjaHNjcmVlbiBkcml2ZXIgZm9yIEN5cHJlc3MgVHJ1ZVRvdWNoIEdlbiA1IFBy b2R1Y3QiKTsKK01PRFVMRV9BVVRIT1IoIk15bMOobmUgSm9zc2VyYW5kIDxteWxlbmUuam9zc2Vy YW5kQGJvb3RsaW4uY29tPiIpOwotLSAKMi4zNy4zCgoKX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGlu dXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQu b3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=