From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-1164852-1519981722-2-7043151130662691251 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no ("Email failed DMARC policy for domain") X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, HEADER_FROM_DIFFERENT_DOMAINS 0.249, ME_NOAUTH 0.01, RCVD_IN_DNSWL_HI -5, T_RP_MATCHES_RCVD -0.01, LANGUAGES en, BAYES_USED global, SA_VERSION 3.4.0 X-Spam-source: IP='209.132.180.67', Host='vger.kernel.org', Country='CN', FromHeader='com', MailFrom='org' X-Spam-charsets: plain='utf-8' X-IgnoreVacation: yes ("Email failed DMARC policy for domain") X-Resolved-to: greg@kroah.com X-Delivered-to: greg@kroah.com X-Mail-from: linux-usb-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=arctest; t=1519981721; b=pHHKEVon8Ed9+JReXA2vSInhX1Bx2mRwRWSeRtHqoOxO/bP 9TS0RJ0QgJTEvHzlW68amgZTuFQ3wwduXo76Ts8uJciQgE/08t82Rv+baR9ujvVd N07PLriReCXCyVlyP3hDvNBi3FfU0oYhaw6sM1w8vyoP5+CrKnKGF48OEi0oG/rj llp4DbAvUo9S3VgrN1au/LRp+7n3YLWja9BQ4kgb7jGcYqlAE9R7lOGl/qoBFBnR ZxtnHu5i0s6fAZsR565zFof9alm9ewZ2jefisbb4Ax4usa6u9bDZjBGAeDD0AGda wKGb2hpKnE2V2fVKFLApfRrM/6meP5tRr4PNnWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=subject:to:cc:references:from:message-id :date:mime-version:in-reply-to:content-type :content-transfer-encoding:sender:list-id; s=arctest; t= 1519981721; bh=BcCrJSF8Wl3bNIW73c6/sicGIcsxoHjgUv8vko72/1U=; b=W rgvqhymOwO0K9lyYcODf8k2OQ+vyDjwHNFbiANj927ue6EeLqofHeqklJve4icPT rVxRCbQzz8oFsZ+4NC00OUlPiXIXmbRuhryBDx4y6n3Hszn+hqA5DRoVd7mrqtPr h4oC4DZnDVEVTAUnv/1ezoEzIktNbqvxEKgt/yv9a8oJ+4XVyO5+HKGo9JXaAER/ PaXwHmLcnud4cXdXAHSK7wHZ4YyNGigCJAIQ8EPOFrNTC4i/Km5537VCp/4x/4AM LULmrcf0F0z8l0VekpvbD2IOZGF0idL9ExqOlheW7BLP0H/k7v8TrPO3xLeD4xoK 4woAdoOtM/qv8FxKgwDbw== ARC-Authentication-Results: i=1; mx2.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=fail (p=none,has-list-id=yes,d=none) header.from=redhat.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-google-dkim=fail (body has been altered; 2048-bit rsa key) header.d=1e100.net header.i=@1e100.net header.b=CItoYnFn; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=redhat.com header.result=pass header_is_org_domain=yes Authentication-Results: mx2.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=fail (p=none,has-list-id=yes,d=none) header.from=redhat.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=linux-usb-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-google-dkim=fail (body has been altered; 2048-bit rsa key) header.d=1e100.net header.i=@1e100.net header.b=CItoYnFn; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=redhat.com header.result=pass header_is_org_domain=yes Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1425185AbeCBJGp (ORCPT ); Fri, 2 Mar 2018 04:06:45 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:50277 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1425305AbeCBJGb (ORCPT ); Fri, 2 Mar 2018 04:06:31 -0500 X-Google-Smtp-Source: AG47ELuW8+gnhLwRBlblVXeXsOnFv5y9W4h9/GZnHhOVFiR2MC3wWvLKGkPGZ6YUeVBh0GPPCYJgLQ== Subject: Re: [PATCH v5 12/12] extcon: axp288: Set USB role where necessary To: Chanwoo Choi , Darren Hart , Andy Shevchenko , MyungJoo Ham , Mathias Nyman , Heikki Krogerus , Greg Kroah-Hartman , Guenter Roeck Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org References: <20180228150749.26831-1-hdegoede@redhat.com> <20180228150749.26831-13-hdegoede@redhat.com> <5A989D2B.8090903@samsung.com> From: Hans de Goede Message-ID: <01235ed2-59e1-93c1-7bc1-03d5dd1b4f3e@redhat.com> Date: Fri, 2 Mar 2018 10:06:28 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <5A989D2B.8090903@samsung.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-usb-owner@vger.kernel.org X-Mailing-List: linux-usb@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-Mailing-List: linux-kernel@vger.kernel.org List-ID: Hi, On 02-03-18 01:39, Chanwoo Choi wrote: > Hi, > > Basically, I have no objection. But I'll reply the my ack tag > after finishing the review of 'devcon and usb_role_switch' from USB maintainer. > > And I have a question. > Before this patch, extcon-axp288 is used to detect charger connector > and extcon-intel-int3496 is used to detect the USB_HOST connector > on one h/w device? Yes the ACPI tables of some devices with an AXP288 PMIC have an INT3496 ACPI device which gives access to the id-pin on the micro-AB connector which the extcon-intel-int3496 exports as a USB_HOST connector, on these devices we fully control the USB role. On other devices the switching of the USB data lines is controlled by AML code which switches the data lines, but never sets the VBus valid bit in the USB PHY control registers, so it is effectively switching between between the host and none roles, since the device role only works when the VBus valid bit is set. This patch addresses both types of devices / ACPI tables and makes host *and* device mode work. This patch also makes switching between them by plugging in a different cable after boot work. Regards, Hans > > Best Regards, > Chanwoo Choi > Samsung Electronics > > On 2018년 03월 01일 00:07, Hans de Goede wrote: >> The AXP288 BC1.2 charger detection / extcon code may seem like a strange >> place to add code to control the USB role-switch on devices with an AXP288, >> but there are 2 reasons to do this inside the axp288 extcon code: >> >> 1) On many devices the USB role is controlled by ACPI AML code, but the AML >> code only switches between the host and none roles, because of Windows >> not really using device mode. To make device mode work we need to toggle >> between the none/device roles based on Vbus presence, and the axp288 >> extcon gets interrupts on Vbus insertion / removal. >> >> 2) In order for our BC1.2 charger detection to work properly the role >> mux must be properly set to device mode before we do the detection. >> >> Also note the Kconfig help-text / obsolete depends on USB_PHY which are >> remnants from older never upstreamed code also controlling the mux from >> the axp288 extcon code. >> >> This commit also adds code to get notifications from the INT3496 extcon >> device, which is used on some devices to notify the kernel about id-pin >> changes instead of them being handled through AML code. >> >> This fixes: >> -Device mode not working on most CHT devices with an AXP288 >> -Host mode not working on devices with an INT3496 ACPI device >> -Charger-type misdetection (always SDP) on devices with an INT3496 when the >> USB role (always) gets initialized as host >> >> Reviewed-by: Heikki Krogerus >> Reviewed-by: Andy Shevchenko >> Signed-off-by: Hans de Goede >> --- >> Changes in v4: >> -Add Andy's Reviewed-by >> >> Changes in v2: >> -Add depends on X86 to Kconfig (the AXP288 PMIC is only used on X86) >> -Use new acpi_dev_get_first_match_name() helper to get the INT3496 device-name >> -Add Heikki's Reviewed-by >> --- >> drivers/extcon/Kconfig | 3 +- >> drivers/extcon/extcon-axp288.c | 177 +++++++++++++++++++++++++++++++++++++++-- >> 2 files changed, 171 insertions(+), 9 deletions(-) >> >> diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig >> index a7bca4207f44..de15bf55895b 100644 >> --- a/drivers/extcon/Kconfig >> +++ b/drivers/extcon/Kconfig >> @@ -30,7 +30,8 @@ config EXTCON_ARIZONA >> >> config EXTCON_AXP288 >> tristate "X-Power AXP288 EXTCON support" >> - depends on MFD_AXP20X && USB_PHY >> + depends on MFD_AXP20X && USB_SUPPORT && X86 >> + select USB_ROLE_SWITCH >> help >> Say Y here to enable support for USB peripheral detection >> and USB MUX switching by X-Power AXP288 PMIC. >> diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c >> index 3ec4c715e240..51e77c7a32c2 100644 >> --- a/drivers/extcon/extcon-axp288.c >> +++ b/drivers/extcon/extcon-axp288.c >> @@ -1,6 +1,7 @@ >> /* >> * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver >> * >> + * Copyright (c) 2017-2018 Hans de Goede >> * Copyright (C) 2015 Intel Corporation >> * Author: Ramakrishna Pallala >> * >> @@ -14,6 +15,8 @@ >> * GNU General Public License for more details. >> */ >> >> +#include >> +#include >> #include >> #include >> #include >> @@ -25,6 +28,11 @@ >> #include >> #include >> #include >> +#include >> +#include >> + >> +#include >> +#include >> >> /* Power source status register */ >> #define PS_STAT_VBUS_TRIGGER BIT(0) >> @@ -97,9 +105,19 @@ struct axp288_extcon_info { >> struct device *dev; >> struct regmap *regmap; >> struct regmap_irq_chip_data *regmap_irqc; >> + struct usb_role_switch *role_sw; >> + struct work_struct role_work; >> int irq[EXTCON_IRQ_END]; >> struct extcon_dev *edev; >> + struct extcon_dev *id_extcon; >> + struct notifier_block id_nb; >> unsigned int previous_cable; >> + bool vbus_attach; >> +}; >> + >> +static const struct x86_cpu_id cherry_trail_cpu_ids[] = { >> + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT, X86_FEATURE_ANY }, >> + {} >> }; >> >> /* Power up/down reason string array */ >> @@ -137,20 +155,74 @@ static void axp288_extcon_log_rsi(struct axp288_extcon_info *info) >> regmap_write(info->regmap, AXP288_PS_BOOT_REASON_REG, clear_mask); >> } >> >> -static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) >> +/* >> + * The below code to control the USB role-switch on devices with an AXP288 >> + * may seem out of place, but there are 2 reasons why this is the best place >> + * to control the USB role-switch on such devices: >> + * 1) On many devices the USB role is controlled by AML code, but the AML code >> + * only switches between the host and none roles, because of Windows not >> + * really using device mode. To make device mode work we need to toggle >> + * between the none/device roles based on Vbus presence, and this driver >> + * gets interrupts on Vbus insertion / removal. >> + * 2) In order for our BC1.2 charger detection to work properly the role >> + * mux must be properly set to device mode before we do the detection. >> + */ >> + >> +/* Returns the id-pin value, note pulled low / false == host-mode */ >> +static bool axp288_get_id_pin(struct axp288_extcon_info *info) >> { >> - int ret, stat, cfg, pwr_stat; >> - u8 chrg_type; >> - unsigned int cable = info->previous_cable; >> - bool vbus_attach = false; >> + enum usb_role role; >> + >> + if (info->id_extcon) >> + return extcon_get_state(info->id_extcon, EXTCON_USB_HOST) <= 0; >> + >> + /* We cannot access the id-pin, see what mode the AML code has set */ >> + role = usb_role_switch_get_role(info->role_sw); >> + return role != USB_ROLE_HOST; >> +} >> + >> +static void axp288_usb_role_work(struct work_struct *work) >> +{ >> + struct axp288_extcon_info *info = >> + container_of(work, struct axp288_extcon_info, role_work); >> + enum usb_role role; >> + bool id_pin; >> + int ret; >> + >> + id_pin = axp288_get_id_pin(info); >> + if (!id_pin) >> + role = USB_ROLE_HOST; >> + else if (info->vbus_attach) >> + role = USB_ROLE_DEVICE; >> + else >> + role = USB_ROLE_NONE; >> + >> + ret = usb_role_switch_set_role(info->role_sw, role); >> + if (ret) >> + dev_err(info->dev, "failed to set role: %d\n", ret); >> +} >> + >> +static bool axp288_get_vbus_attach(struct axp288_extcon_info *info) >> +{ >> + int ret, pwr_stat; >> >> ret = regmap_read(info->regmap, AXP288_PS_STAT_REG, &pwr_stat); >> if (ret < 0) { >> dev_err(info->dev, "failed to read vbus status\n"); >> - return ret; >> + return false; >> } >> >> - vbus_attach = (pwr_stat & PS_STAT_VBUS_VALID); >> + return !!(pwr_stat & PS_STAT_VBUS_VALID); >> +} >> + >> +static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) >> +{ >> + int ret, stat, cfg; >> + u8 chrg_type; >> + unsigned int cable = info->previous_cable; >> + bool vbus_attach = false; >> + >> + vbus_attach = axp288_get_vbus_attach(info); >> if (!vbus_attach) >> goto no_vbus; >> >> @@ -201,6 +273,12 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) >> info->previous_cable = cable; >> } >> >> + if (info->role_sw && info->vbus_attach != vbus_attach) { >> + info->vbus_attach = vbus_attach; >> + /* Setting the role can take a while */ >> + queue_work(system_long_wq, &info->role_work); >> + } >> + >> return 0; >> >> dev_det_ret: >> @@ -210,6 +288,18 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) >> return ret; >> } >> >> +static int axp288_extcon_id_evt(struct notifier_block *nb, >> + unsigned long event, void *param) >> +{ >> + struct axp288_extcon_info *info = >> + container_of(nb, struct axp288_extcon_info, id_nb); >> + >> + /* We may not sleep and setting the role can take a while */ >> + queue_work(system_long_wq, &info->role_work); >> + >> + return NOTIFY_OK; >> +} >> + >> static irqreturn_t axp288_extcon_isr(int irq, void *data) >> { >> struct axp288_extcon_info *info = data; >> @@ -231,10 +321,20 @@ static void axp288_extcon_enable(struct axp288_extcon_info *info) >> BC_GLOBAL_RUN, BC_GLOBAL_RUN); >> } >> >> +static void axp288_put_role_sw(void *data) >> +{ >> + struct axp288_extcon_info *info = data; >> + >> + cancel_work_sync(&info->role_work); >> + usb_role_switch_put(info->role_sw); >> +} >> + >> static int axp288_extcon_probe(struct platform_device *pdev) >> { >> struct axp288_extcon_info *info; >> struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); >> + struct device *dev = &pdev->dev; >> + const char *name; >> int ret, i, pirq; >> >> info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); >> @@ -245,9 +345,33 @@ static int axp288_extcon_probe(struct platform_device *pdev) >> info->regmap = axp20x->regmap; >> info->regmap_irqc = axp20x->regmap_irqc; >> info->previous_cable = EXTCON_NONE; >> + INIT_WORK(&info->role_work, axp288_usb_role_work); >> + info->id_nb.notifier_call = axp288_extcon_id_evt; >> >> platform_set_drvdata(pdev, info); >> >> + info->role_sw = usb_role_switch_get(dev); >> + if (IS_ERR(info->role_sw)) >> + return PTR_ERR(info->role_sw); >> + if (info->role_sw) { >> + ret = devm_add_action_or_reset(dev, axp288_put_role_sw, info); >> + if (ret) >> + return ret; >> + >> + name = acpi_dev_get_first_match_name("INT3496", NULL, -1); >> + if (name) { >> + info->id_extcon = extcon_get_extcon_dev(name); >> + if (!info->id_extcon) >> + return -EPROBE_DEFER; >> + >> + dev_info(dev, "controlling USB role\n"); >> + } else { >> + dev_info(dev, "controlling USB role based on Vbus presence\n"); >> + } >> + } >> + >> + info->vbus_attach = axp288_get_vbus_attach(info); >> + >> axp288_extcon_log_rsi(info); >> >> /* Initialize extcon device */ >> @@ -289,6 +413,19 @@ static int axp288_extcon_probe(struct platform_device *pdev) >> } >> } >> >> + if (info->id_extcon) { >> + ret = devm_extcon_register_notifier_all(dev, info->id_extcon, >> + &info->id_nb); >> + if (ret) >> + return ret; >> + } >> + >> + /* Make sure the role-sw is set correctly before doing BC detection */ >> + if (info->role_sw) { >> + queue_work(system_long_wq, &info->role_work); >> + flush_work(&info->role_work); >> + } >> + >> /* Start charger cable type detection */ >> axp288_extcon_enable(info); >> >> @@ -308,8 +445,32 @@ static struct platform_driver axp288_extcon_driver = { >> .name = "axp288_extcon", >> }, >> }; >> -module_platform_driver(axp288_extcon_driver); >> + >> +static struct devcon axp288_extcon_role_sw_conn = { >> + .endpoint[0] = "axp288_extcon", >> + .endpoint[1] = "intel_xhci_usb_sw-role-switch", >> + .id = "usb-role-switch", >> +}; >> + >> +static int __init axp288_extcon_init(void) >> +{ >> + if (x86_match_cpu(cherry_trail_cpu_ids)) >> + add_device_connection(&axp288_extcon_role_sw_conn); >> + >> + return platform_driver_register(&axp288_extcon_driver); >> +} >> +module_init(axp288_extcon_init); >> + >> +static void __exit axp288_extcon_exit(void) >> +{ >> + if (x86_match_cpu(cherry_trail_cpu_ids)) >> + remove_device_connection(&axp288_extcon_role_sw_conn); >> + >> + platform_driver_unregister(&axp288_extcon_driver); >> +} >> +module_exit(axp288_extcon_exit); >> >> MODULE_AUTHOR("Ramakrishna Pallala "); >> +MODULE_AUTHOR("Hans de Goede "); >> MODULE_DESCRIPTION("X-Powers AXP288 extcon driver"); >> MODULE_LICENSE("GPL v2"); >> > From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [v5,12/12] extcon: axp288: Set USB role where necessary From: Hans de Goede Message-Id: <01235ed2-59e1-93c1-7bc1-03d5dd1b4f3e@redhat.com> Date: Fri, 2 Mar 2018 10:06:28 +0100 To: Chanwoo Choi , Darren Hart , Andy Shevchenko , MyungJoo Ham , Mathias Nyman , Heikki Krogerus , Greg Kroah-Hartman , Guenter Roeck Cc: platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org List-ID: SGksCgpPbiAwMi0wMy0xOCAwMTozOSwgQ2hhbndvbyBDaG9pIHdyb3RlOgo+IEhpLAo+IAo+IEJh c2ljYWxseSwgSSBoYXZlIG5vIG9iamVjdGlvbi4gQnV0IEknbGwgcmVwbHkgdGhlIG15IGFjayB0 YWcKPiBhZnRlciBmaW5pc2hpbmcgdGhlIHJldmlldyBvZiAnZGV2Y29uIGFuZCB1c2Jfcm9sZV9z d2l0Y2gnIGZyb20gVVNCIG1haW50YWluZXIuCj4gCj4gQW5kIEkgaGF2ZSBhIHF1ZXN0aW9uLgo+ IEJlZm9yZSB0aGlzIHBhdGNoLCBleHRjb24tYXhwMjg4IGlzIHVzZWQgdG8gZGV0ZWN0IGNoYXJn ZXIgY29ubmVjdG9yCj4gYW5kIGV4dGNvbi1pbnRlbC1pbnQzNDk2IGlzIHVzZWQgdG8gZGV0ZWN0 IHRoZSBVU0JfSE9TVCBjb25uZWN0b3IKPiBvbiBvbmUgaC93IGRldmljZT8KClllcyB0aGUgQUNQ SSB0YWJsZXMgb2Ygc29tZSBkZXZpY2VzIHdpdGggYW4gQVhQMjg4IFBNSUMgaGF2ZSBhbiBJTlQz NDk2CkFDUEkgZGV2aWNlIHdoaWNoIGdpdmVzIGFjY2VzcyB0byB0aGUgaWQtcGluIG9uIHRoZSBt aWNyby1BQiBjb25uZWN0b3IKd2hpY2ggdGhlIGV4dGNvbi1pbnRlbC1pbnQzNDk2IGV4cG9ydHMg YXMgYSBVU0JfSE9TVCBjb25uZWN0b3IsIG9uIHRoZXNlCmRldmljZXMgd2UgZnVsbHkgY29udHJv bCB0aGUgVVNCIHJvbGUuCgpPbiBvdGhlciBkZXZpY2VzIHRoZSBzd2l0Y2hpbmcgb2YgdGhlIFVT QiBkYXRhIGxpbmVzIGlzIGNvbnRyb2xsZWQgYnkgQU1MCmNvZGUgd2hpY2ggc3dpdGNoZXMgdGhl IGRhdGEgbGluZXMsIGJ1dCBuZXZlciBzZXRzIHRoZSBWQnVzIHZhbGlkIGJpdAppbiB0aGUgVVNC IFBIWSBjb250cm9sIHJlZ2lzdGVycywgc28gaXQgaXMgZWZmZWN0aXZlbHkgc3dpdGNoaW5nIGJl dHdlZW4KYmV0d2VlbiB0aGUgaG9zdCBhbmQgbm9uZSByb2xlcywgc2luY2UgdGhlIGRldmljZSBy b2xlIG9ubHkgd29ya3Mgd2hlbgp0aGUgVkJ1cyB2YWxpZCBiaXQgaXMgc2V0LgoKVGhpcyBwYXRj aCBhZGRyZXNzZXMgYm90aCB0eXBlcyBvZiBkZXZpY2VzIC8gQUNQSSB0YWJsZXMgYW5kIG1ha2Vz Cmhvc3QgKmFuZCogZGV2aWNlIG1vZGUgd29yay4gVGhpcyBwYXRjaCBhbHNvIG1ha2VzIHN3aXRj aGluZyBiZXR3ZWVuIHRoZW0KYnkgcGx1Z2dpbmcgaW4gYSBkaWZmZXJlbnQgY2FibGUgYWZ0ZXIg Ym9vdCB3b3JrLgoKUmVnYXJkcywKCkhhbnMKCgoKPiAKPiBCZXN0IFJlZ2FyZHMsCj4gQ2hhbndv byBDaG9pCj4gU2Ftc3VuZyBFbGVjdHJvbmljcwo+IAo+IE9uIDIwMTjrhYQgMDPsm5QgMDHsnbwg MDA6MDcsIEhhbnMgZGUgR29lZGUgd3JvdGU6Cj4+IFRoZSBBWFAyODggQkMxLjIgY2hhcmdlciBk ZXRlY3Rpb24gLyBleHRjb24gY29kZSBtYXkgc2VlbSBsaWtlIGEgc3RyYW5nZQo+PiBwbGFjZSB0 byBhZGQgY29kZSB0byBjb250cm9sIHRoZSBVU0Igcm9sZS1zd2l0Y2ggb24gZGV2aWNlcyB3aXRo IGFuIEFYUDI4OCwKPj4gYnV0IHRoZXJlIGFyZSAyIHJlYXNvbnMgdG8gZG8gdGhpcyBpbnNpZGUg dGhlIGF4cDI4OCBleHRjb24gY29kZToKPj4KPj4gMSkgT24gbWFueSBkZXZpY2VzIHRoZSBVU0Ig cm9sZSBpcyBjb250cm9sbGVkIGJ5IEFDUEkgQU1MIGNvZGUsIGJ1dCB0aGUgQU1MCj4+ICAgICBj b2RlIG9ubHkgc3dpdGNoZXMgYmV0d2VlbiB0aGUgaG9zdCBhbmQgbm9uZSByb2xlcywgYmVjYXVz ZSBvZiBXaW5kb3dzCj4+ICAgICBub3QgcmVhbGx5IHVzaW5nIGRldmljZSBtb2RlLiBUbyBtYWtl IGRldmljZSBtb2RlIHdvcmsgd2UgbmVlZCB0byB0b2dnbGUKPj4gICAgIGJldHdlZW4gdGhlIG5v bmUvZGV2aWNlIHJvbGVzIGJhc2VkIG9uIFZidXMgcHJlc2VuY2UsIGFuZCB0aGUgYXhwMjg4Cj4+ ICAgICBleHRjb24gZ2V0cyBpbnRlcnJ1cHRzIG9uIFZidXMgaW5zZXJ0aW9uIC8gcmVtb3ZhbC4K Pj4KPj4gMikgSW4gb3JkZXIgZm9yIG91ciBCQzEuMiBjaGFyZ2VyIGRldGVjdGlvbiB0byB3b3Jr IHByb3Blcmx5IHRoZSByb2xlCj4+ICAgICBtdXggbXVzdCBiZSBwcm9wZXJseSBzZXQgdG8gZGV2 aWNlIG1vZGUgYmVmb3JlIHdlIGRvIHRoZSBkZXRlY3Rpb24uCj4+Cj4+IEFsc28gbm90ZSB0aGUg S2NvbmZpZyBoZWxwLXRleHQgLyBvYnNvbGV0ZSBkZXBlbmRzIG9uIFVTQl9QSFkgd2hpY2ggYXJl Cj4+IHJlbW5hbnRzIGZyb20gb2xkZXIgbmV2ZXIgdXBzdHJlYW1lZCBjb2RlIGFsc28gY29udHJv bGxpbmcgdGhlIG11eCBmcm9tCj4+IHRoZSBheHAyODggZXh0Y29uIGNvZGUuCj4+Cj4+IFRoaXMg Y29tbWl0IGFsc28gYWRkcyBjb2RlIHRvIGdldCBub3RpZmljYXRpb25zIGZyb20gdGhlIElOVDM0 OTYgZXh0Y29uCj4+IGRldmljZSwgd2hpY2ggaXMgdXNlZCBvbiBzb21lIGRldmljZXMgdG8gbm90 aWZ5IHRoZSBrZXJuZWwgYWJvdXQgaWQtcGluCj4+IGNoYW5nZXMgaW5zdGVhZCBvZiB0aGVtIGJl aW5nIGhhbmRsZWQgdGhyb3VnaCBBTUwgY29kZS4KPj4KPj4gVGhpcyBmaXhlczoKPj4gLURldmlj ZSBtb2RlIG5vdCB3b3JraW5nIG9uIG1vc3QgQ0hUIGRldmljZXMgd2l0aCBhbiBBWFAyODgKPj4g LUhvc3QgbW9kZSBub3Qgd29ya2luZyBvbiBkZXZpY2VzIHdpdGggYW4gSU5UMzQ5NiBBQ1BJIGRl dmljZQo+PiAtQ2hhcmdlci10eXBlIG1pc2RldGVjdGlvbiAoYWx3YXlzIFNEUCkgb24gZGV2aWNl cyB3aXRoIGFuIElOVDM0OTYgd2hlbiB0aGUKPj4gICBVU0Igcm9sZSAoYWx3YXlzKSBnZXRzIGlu aXRpYWxpemVkIGFzIGhvc3QKPj4KPj4gUmV2aWV3ZWQtYnk6IEhlaWtraSBLcm9nZXJ1cyA8aGVp a2tpLmtyb2dlcnVzQGxpbnV4LmludGVsLmNvbT4KPj4gUmV2aWV3ZWQtYnk6IEFuZHkgU2hldmNo ZW5rbyA8YW5keS5zaGV2Y2hlbmtvQGdtYWlsLmNvbT4KPj4gU2lnbmVkLW9mZi1ieTogSGFucyBk ZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0LmNvbT4KPj4gLS0tCj4+IENoYW5nZXMgaW4gdjQ6Cj4+ IC1BZGQgQW5keSdzIFJldmlld2VkLWJ5Cj4+Cj4+IENoYW5nZXMgaW4gdjI6Cj4+IC1BZGQgZGVw ZW5kcyBvbiBYODYgdG8gS2NvbmZpZyAodGhlIEFYUDI4OCBQTUlDIGlzIG9ubHkgdXNlZCBvbiBY ODYpCj4+IC1Vc2UgbmV3IGFjcGlfZGV2X2dldF9maXJzdF9tYXRjaF9uYW1lKCkgaGVscGVyIHRv IGdldCB0aGUgSU5UMzQ5NiBkZXZpY2UtbmFtZQo+PiAtQWRkIEhlaWtraSdzIFJldmlld2VkLWJ5 Cj4+IC0tLQo+PiAgIGRyaXZlcnMvZXh0Y29uL0tjb25maWcgICAgICAgICB8ICAgMyArLQo+PiAg IGRyaXZlcnMvZXh0Y29uL2V4dGNvbi1heHAyODguYyB8IDE3NyArKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKystLQo+PiAgIDIgZmlsZXMgY2hhbmdlZCwgMTcxIGluc2VydGlv bnMoKyksIDkgZGVsZXRpb25zKC0pCj4+Cj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2V4dGNvbi9L Y29uZmlnIGIvZHJpdmVycy9leHRjb24vS2NvbmZpZwo+PiBpbmRleCBhN2JjYTQyMDdmNDQuLmRl MTViZjU1ODk1YiAxMDA2NDQKPj4gLS0tIGEvZHJpdmVycy9leHRjb24vS2NvbmZpZwo+PiArKysg Yi9kcml2ZXJzL2V4dGNvbi9LY29uZmlnCj4+IEBAIC0zMCw3ICszMCw4IEBAIGNvbmZpZyBFWFRD T05fQVJJWk9OQQo+PiAgIAo+PiAgIGNvbmZpZyBFWFRDT05fQVhQMjg4Cj4+ICAgCXRyaXN0YXRl ICJYLVBvd2VyIEFYUDI4OCBFWFRDT04gc3VwcG9ydCIKPj4gLQlkZXBlbmRzIG9uIE1GRF9BWFAy MFggJiYgVVNCX1BIWQo+PiArCWRlcGVuZHMgb24gTUZEX0FYUDIwWCAmJiBVU0JfU1VQUE9SVCAm JiBYODYKPj4gKwlzZWxlY3QgVVNCX1JPTEVfU1dJVENICj4+ICAgCWhlbHAKPj4gICAJICBTYXkg WSBoZXJlIHRvIGVuYWJsZSBzdXBwb3J0IGZvciBVU0IgcGVyaXBoZXJhbCBkZXRlY3Rpb24KPj4g ICAJICBhbmQgVVNCIE1VWCBzd2l0Y2hpbmcgYnkgWC1Qb3dlciBBWFAyODggUE1JQy4KPj4gZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZXh0Y29uL2V4dGNvbi1heHAyODguYyBiL2RyaXZlcnMvZXh0Y29u L2V4dGNvbi1heHAyODguYwo+PiBpbmRleCAzZWM0YzcxNWUyNDAuLjUxZTc3YzdhMzJjMiAxMDA2 NDQKPj4gLS0tIGEvZHJpdmVycy9leHRjb24vZXh0Y29uLWF4cDI4OC5jCj4+ICsrKyBiL2RyaXZl cnMvZXh0Y29uL2V4dGNvbi1heHAyODguYwo+PiBAQCAtMSw2ICsxLDcgQEAKPj4gICAvKgo+PiAg ICAqIGV4dGNvbi1heHAyODguYyAtIFgtUG93ZXIgQVhQMjg4IFBNSUMgZXh0Y29uIGNhYmxlIGRl dGVjdGlvbiBkcml2ZXIKPj4gICAgKgo+PiArICogQ29weXJpZ2h0IChjKSAyMDE3LTIwMTggSGFu cyBkZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0LmNvbT4KPj4gICAgKiBDb3B5cmlnaHQgKEMpIDIw MTUgSW50ZWwgQ29ycG9yYXRpb24KPj4gICAgKiBBdXRob3I6IFJhbWFrcmlzaG5hIFBhbGxhbGEg PHJhbWFrcmlzaG5hLnBhbGxhbGFAaW50ZWwuY29tPgo+PiAgICAqCj4+IEBAIC0xNCw2ICsxNSw4 IEBACj4+ICAgICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4K Pj4gICAgKi8KPj4gICAKPj4gKyNpbmNsdWRlIDxsaW51eC9hY3BpLmg+Cj4+ICsjaW5jbHVkZSA8 bGludXgvY29ubmVjdGlvbi5oPgo+PiAgICNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4gICAj aW5jbHVkZSA8bGludXgva2VybmVsLmg+Cj4+ICAgI2luY2x1ZGUgPGxpbnV4L2lvLmg+Cj4+IEBA IC0yNSw2ICsyOCwxMSBAQAo+PiAgICNpbmNsdWRlIDxsaW51eC9leHRjb24tcHJvdmlkZXIuaD4K Pj4gICAjaW5jbHVkZSA8bGludXgvcmVnbWFwLmg+Cj4+ICAgI2luY2x1ZGUgPGxpbnV4L21mZC9h eHAyMHguaD4KPj4gKyNpbmNsdWRlIDxsaW51eC91c2Ivcm9sZS5oPgo+PiArI2luY2x1ZGUgPGxp bnV4L3dvcmtxdWV1ZS5oPgo+PiArCj4+ICsjaW5jbHVkZSA8YXNtL2NwdV9kZXZpY2VfaWQuaD4K Pj4gKyNpbmNsdWRlIDxhc20vaW50ZWwtZmFtaWx5Lmg+Cj4+ICAgCj4+ICAgLyogUG93ZXIgc291 cmNlIHN0YXR1cyByZWdpc3RlciAqLwo+PiAgICNkZWZpbmUgUFNfU1RBVF9WQlVTX1RSSUdHRVIJ CUJJVCgwKQo+PiBAQCAtOTcsOSArMTA1LDE5IEBAIHN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8g ewo+PiAgIAlzdHJ1Y3QgZGV2aWNlICpkZXY7Cj4+ICAgCXN0cnVjdCByZWdtYXAgKnJlZ21hcDsK Pj4gICAJc3RydWN0IHJlZ21hcF9pcnFfY2hpcF9kYXRhICpyZWdtYXBfaXJxYzsKPj4gKwlzdHJ1 Y3QgdXNiX3JvbGVfc3dpdGNoICpyb2xlX3N3Owo+PiArCXN0cnVjdCB3b3JrX3N0cnVjdCByb2xl X3dvcms7Cj4+ICAgCWludCBpcnFbRVhUQ09OX0lSUV9FTkRdOwo+PiAgIAlzdHJ1Y3QgZXh0Y29u X2RldiAqZWRldjsKPj4gKwlzdHJ1Y3QgZXh0Y29uX2RldiAqaWRfZXh0Y29uOwo+PiArCXN0cnVj dCBub3RpZmllcl9ibG9jayBpZF9uYjsKPj4gICAJdW5zaWduZWQgaW50IHByZXZpb3VzX2NhYmxl Owo+PiArCWJvb2wgdmJ1c19hdHRhY2g7Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3Ry dWN0IHg4Nl9jcHVfaWQgY2hlcnJ5X3RyYWlsX2NwdV9pZHNbXSA9IHsKPj4gKwl7IFg4Nl9WRU5E T1JfSU5URUwsIDYsIElOVEVMX0ZBTTZfQVRPTV9BSVJNT05ULCBYODZfRkVBVFVSRV9BTlkgfSwK Pj4gKwl7fQo+PiAgIH07Cj4+ICAgCj4+ICAgLyogUG93ZXIgdXAvZG93biByZWFzb24gc3RyaW5n IGFycmF5ICovCj4+IEBAIC0xMzcsMjAgKzE1NSw3NCBAQCBzdGF0aWMgdm9pZCBheHAyODhfZXh0 Y29uX2xvZ19yc2koc3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbykKPj4gICAJcmVnbWFw X3dyaXRlKGluZm8tPnJlZ21hcCwgQVhQMjg4X1BTX0JPT1RfUkVBU09OX1JFRywgY2xlYXJfbWFz ayk7Cj4+ICAgfQo+PiAgIAo+PiAtc3RhdGljIGludCBheHAyODhfaGFuZGxlX2NocmdfZGV0X2V2 ZW50KHN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8pCj4+ICsvKgo+PiArICogVGhlIGJl bG93IGNvZGUgdG8gY29udHJvbCB0aGUgVVNCIHJvbGUtc3dpdGNoIG9uIGRldmljZXMgd2l0aCBh biBBWFAyODgKPj4gKyAqIG1heSBzZWVtIG91dCBvZiBwbGFjZSwgYnV0IHRoZXJlIGFyZSAyIHJl YXNvbnMgd2h5IHRoaXMgaXMgdGhlIGJlc3QgcGxhY2UKPj4gKyAqIHRvIGNvbnRyb2wgdGhlIFVT QiByb2xlLXN3aXRjaCBvbiBzdWNoIGRldmljZXM6Cj4+ICsgKiAxKSBPbiBtYW55IGRldmljZXMg dGhlIFVTQiByb2xlIGlzIGNvbnRyb2xsZWQgYnkgQU1MIGNvZGUsIGJ1dCB0aGUgQU1MIGNvZGUK Pj4gKyAqICAgIG9ubHkgc3dpdGNoZXMgYmV0d2VlbiB0aGUgaG9zdCBhbmQgbm9uZSByb2xlcywg YmVjYXVzZSBvZiBXaW5kb3dzIG5vdAo+PiArICogICAgcmVhbGx5IHVzaW5nIGRldmljZSBtb2Rl LiBUbyBtYWtlIGRldmljZSBtb2RlIHdvcmsgd2UgbmVlZCB0byB0b2dnbGUKPj4gKyAqICAgIGJl dHdlZW4gdGhlIG5vbmUvZGV2aWNlIHJvbGVzIGJhc2VkIG9uIFZidXMgcHJlc2VuY2UsIGFuZCB0 aGlzIGRyaXZlcgo+PiArICogICAgZ2V0cyBpbnRlcnJ1cHRzIG9uIFZidXMgaW5zZXJ0aW9uIC8g cmVtb3ZhbC4KPj4gKyAqIDIpIEluIG9yZGVyIGZvciBvdXIgQkMxLjIgY2hhcmdlciBkZXRlY3Rp b24gdG8gd29yayBwcm9wZXJseSB0aGUgcm9sZQo+PiArICogICAgbXV4IG11c3QgYmUgcHJvcGVy bHkgc2V0IHRvIGRldmljZSBtb2RlIGJlZm9yZSB3ZSBkbyB0aGUgZGV0ZWN0aW9uLgo+PiArICov Cj4+ICsKPj4gKy8qIFJldHVybnMgdGhlIGlkLXBpbiB2YWx1ZSwgbm90ZSBwdWxsZWQgbG93IC8g ZmFsc2UgPT0gaG9zdC1tb2RlICovCj4+ICtzdGF0aWMgYm9vbCBheHAyODhfZ2V0X2lkX3Bpbihz dHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQo+PiAgIHsKPj4gLQlpbnQgcmV0LCBzdGF0 LCBjZmcsIHB3cl9zdGF0Owo+PiAtCXU4IGNocmdfdHlwZTsKPj4gLQl1bnNpZ25lZCBpbnQgY2Fi bGUgPSBpbmZvLT5wcmV2aW91c19jYWJsZTsKPj4gLQlib29sIHZidXNfYXR0YWNoID0gZmFsc2U7 Cj4+ICsJZW51bSB1c2Jfcm9sZSByb2xlOwo+PiArCj4+ICsJaWYgKGluZm8tPmlkX2V4dGNvbikK Pj4gKwkJcmV0dXJuIGV4dGNvbl9nZXRfc3RhdGUoaW5mby0+aWRfZXh0Y29uLCBFWFRDT05fVVNC X0hPU1QpIDw9IDA7Cj4+ICsKPj4gKwkvKiBXZSBjYW5ub3QgYWNjZXNzIHRoZSBpZC1waW4sIHNl ZSB3aGF0IG1vZGUgdGhlIEFNTCBjb2RlIGhhcyBzZXQgKi8KPj4gKwlyb2xlID0gdXNiX3JvbGVf c3dpdGNoX2dldF9yb2xlKGluZm8tPnJvbGVfc3cpOwo+PiArCXJldHVybiByb2xlICE9IFVTQl9S T0xFX0hPU1Q7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGF4cDI4OF91c2Jfcm9sZV93b3Jr KHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKPj4gK3sKPj4gKwlzdHJ1Y3QgYXhwMjg4X2V4dGNv bl9pbmZvICppbmZvID0KPj4gKwkJY29udGFpbmVyX29mKHdvcmssIHN0cnVjdCBheHAyODhfZXh0 Y29uX2luZm8sIHJvbGVfd29yayk7Cj4+ICsJZW51bSB1c2Jfcm9sZSByb2xlOwo+PiArCWJvb2wg aWRfcGluOwo+PiArCWludCByZXQ7Cj4+ICsKPj4gKwlpZF9waW4gPSBheHAyODhfZ2V0X2lkX3Bp bihpbmZvKTsKPj4gKwlpZiAoIWlkX3BpbikKPj4gKwkJcm9sZSA9IFVTQl9ST0xFX0hPU1Q7Cj4+ ICsJZWxzZSBpZiAoaW5mby0+dmJ1c19hdHRhY2gpCj4+ICsJCXJvbGUgPSBVU0JfUk9MRV9ERVZJ Q0U7Cj4+ICsJZWxzZQo+PiArCQlyb2xlID0gVVNCX1JPTEVfTk9ORTsKPj4gKwo+PiArCXJldCA9 IHVzYl9yb2xlX3N3aXRjaF9zZXRfcm9sZShpbmZvLT5yb2xlX3N3LCByb2xlKTsKPj4gKwlpZiAo cmV0KQo+PiArCQlkZXZfZXJyKGluZm8tPmRldiwgImZhaWxlZCB0byBzZXQgcm9sZTogJWRcbiIs IHJldCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBib29sIGF4cDI4OF9nZXRfdmJ1c19hdHRhY2go c3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbykKPj4gK3sKPj4gKwlpbnQgcmV0LCBwd3Jf c3RhdDsKPj4gICAKPj4gICAJcmV0ID0gcmVnbWFwX3JlYWQoaW5mby0+cmVnbWFwLCBBWFAyODhf UFNfU1RBVF9SRUcsICZwd3Jfc3RhdCk7Cj4+ICAgCWlmIChyZXQgPCAwKSB7Cj4+ICAgCQlkZXZf ZXJyKGluZm8tPmRldiwgImZhaWxlZCB0byByZWFkIHZidXMgc3RhdHVzXG4iKTsKPj4gLQkJcmV0 dXJuIHJldDsKPj4gKwkJcmV0dXJuIGZhbHNlOwo+PiAgIAl9Cj4+ICAgCj4+IC0JdmJ1c19hdHRh Y2ggPSAocHdyX3N0YXQgJiBQU19TVEFUX1ZCVVNfVkFMSUQpOwo+PiArCXJldHVybiAhIShwd3Jf c3RhdCAmIFBTX1NUQVRfVkJVU19WQUxJRCk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBpbnQgYXhw Mjg4X2hhbmRsZV9jaHJnX2RldF9ldmVudChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZv KQo+PiArewo+PiArCWludCByZXQsIHN0YXQsIGNmZzsKPj4gKwl1OCBjaHJnX3R5cGU7Cj4+ICsJ dW5zaWduZWQgaW50IGNhYmxlID0gaW5mby0+cHJldmlvdXNfY2FibGU7Cj4+ICsJYm9vbCB2YnVz X2F0dGFjaCA9IGZhbHNlOwo+PiArCj4+ICsJdmJ1c19hdHRhY2ggPSBheHAyODhfZ2V0X3ZidXNf YXR0YWNoKGluZm8pOwo+PiAgIAlpZiAoIXZidXNfYXR0YWNoKQo+PiAgIAkJZ290byBub192YnVz Owo+PiAgIAo+PiBAQCAtMjAxLDYgKzI3MywxMiBAQCBzdGF0aWMgaW50IGF4cDI4OF9oYW5kbGVf Y2hyZ19kZXRfZXZlbnQoc3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbykKPj4gICAJCWlu Zm8tPnByZXZpb3VzX2NhYmxlID0gY2FibGU7Cj4+ICAgCX0KPj4gICAKPj4gKwlpZiAoaW5mby0+ cm9sZV9zdyAmJiBpbmZvLT52YnVzX2F0dGFjaCAhPSB2YnVzX2F0dGFjaCkgewo+PiArCQlpbmZv LT52YnVzX2F0dGFjaCA9IHZidXNfYXR0YWNoOwo+PiArCQkvKiBTZXR0aW5nIHRoZSByb2xlIGNh biB0YWtlIGEgd2hpbGUgKi8KPj4gKwkJcXVldWVfd29yayhzeXN0ZW1fbG9uZ193cSwgJmluZm8t PnJvbGVfd29yayk7Cj4+ICsJfQo+PiArCj4+ICAgCXJldHVybiAwOwo+PiAgIAo+PiAgIGRldl9k ZXRfcmV0Ogo+PiBAQCAtMjEwLDYgKzI4OCwxOCBAQCBzdGF0aWMgaW50IGF4cDI4OF9oYW5kbGVf Y2hyZ19kZXRfZXZlbnQoc3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbykKPj4gICAJcmV0 dXJuIHJldDsKPj4gICB9Cj4+ICAgCj4+ICtzdGF0aWMgaW50IGF4cDI4OF9leHRjb25faWRfZXZ0 KHN0cnVjdCBub3RpZmllcl9ibG9jayAqbmIsCj4+ICsJCQkJdW5zaWduZWQgbG9uZyBldmVudCwg dm9pZCAqcGFyYW0pCj4+ICt7Cj4+ICsJc3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbyA9 Cj4+ICsJCWNvbnRhaW5lcl9vZihuYiwgc3RydWN0IGF4cDI4OF9leHRjb25faW5mbywgaWRfbmIp Owo+PiArCj4+ICsJLyogV2UgbWF5IG5vdCBzbGVlcCBhbmQgc2V0dGluZyB0aGUgcm9sZSBjYW4g dGFrZSBhIHdoaWxlICovCj4+ICsJcXVldWVfd29yayhzeXN0ZW1fbG9uZ193cSwgJmluZm8tPnJv bGVfd29yayk7Cj4+ICsKPj4gKwlyZXR1cm4gTk9USUZZX09LOwo+PiArfQo+PiArCj4+ICAgc3Rh dGljIGlycXJldHVybl90IGF4cDI4OF9leHRjb25faXNyKGludCBpcnEsIHZvaWQgKmRhdGEpCj4+ ICAgewo+PiAgIAlzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvID0gZGF0YTsKPj4gQEAg LTIzMSwxMCArMzIxLDIwIEBAIHN0YXRpYyB2b2lkIGF4cDI4OF9leHRjb25fZW5hYmxlKHN0cnVj dCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8pCj4+ICAgCQkJCQlCQ19HTE9CQUxfUlVOLCBCQ19H TE9CQUxfUlVOKTsKPj4gICB9Cj4+ICAgCj4+ICtzdGF0aWMgdm9pZCBheHAyODhfcHV0X3JvbGVf c3codm9pZCAqZGF0YSkKPj4gK3sKPj4gKwlzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZv ID0gZGF0YTsKPj4gKwo+PiArCWNhbmNlbF93b3JrX3N5bmMoJmluZm8tPnJvbGVfd29yayk7Cj4+ ICsJdXNiX3JvbGVfc3dpdGNoX3B1dChpbmZvLT5yb2xlX3N3KTsKPj4gK30KPj4gKwo+PiAgIHN0 YXRpYyBpbnQgYXhwMjg4X2V4dGNvbl9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2 KQo+PiAgIHsKPj4gICAJc3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbzsKPj4gICAJc3Ry dWN0IGF4cDIweF9kZXYgKmF4cDIweCA9IGRldl9nZXRfZHJ2ZGF0YShwZGV2LT5kZXYucGFyZW50 KTsKPj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2Owo+PiArCWNvbnN0IGNoYXIg Km5hbWU7Cj4+ICAgCWludCByZXQsIGksIHBpcnE7Cj4+ICAgCj4+ICAgCWluZm8gPSBkZXZtX2t6 YWxsb2MoJnBkZXYtPmRldiwgc2l6ZW9mKCppbmZvKSwgR0ZQX0tFUk5FTCk7Cj4+IEBAIC0yNDUs OSArMzQ1LDMzIEBAIHN0YXRpYyBpbnQgYXhwMjg4X2V4dGNvbl9wcm9iZShzdHJ1Y3QgcGxhdGZv cm1fZGV2aWNlICpwZGV2KQo+PiAgIAlpbmZvLT5yZWdtYXAgPSBheHAyMHgtPnJlZ21hcDsKPj4g ICAJaW5mby0+cmVnbWFwX2lycWMgPSBheHAyMHgtPnJlZ21hcF9pcnFjOwo+PiAgIAlpbmZvLT5w cmV2aW91c19jYWJsZSA9IEVYVENPTl9OT05FOwo+PiArCUlOSVRfV09SSygmaW5mby0+cm9sZV93 b3JrLCBheHAyODhfdXNiX3JvbGVfd29yayk7Cj4+ICsJaW5mby0+aWRfbmIubm90aWZpZXJfY2Fs bCA9IGF4cDI4OF9leHRjb25faWRfZXZ0Owo+PiAgIAo+PiAgIAlwbGF0Zm9ybV9zZXRfZHJ2ZGF0 YShwZGV2LCBpbmZvKTsKPj4gICAKPj4gKwlpbmZvLT5yb2xlX3N3ID0gdXNiX3JvbGVfc3dpdGNo X2dldChkZXYpOwo+PiArCWlmIChJU19FUlIoaW5mby0+cm9sZV9zdykpCj4+ICsJCXJldHVybiBQ VFJfRVJSKGluZm8tPnJvbGVfc3cpOwo+PiArCWlmIChpbmZvLT5yb2xlX3N3KSB7Cj4+ICsJCXJl dCA9IGRldm1fYWRkX2FjdGlvbl9vcl9yZXNldChkZXYsIGF4cDI4OF9wdXRfcm9sZV9zdywgaW5m byk7Cj4+ICsJCWlmIChyZXQpCj4+ICsJCQlyZXR1cm4gcmV0Owo+PiArCj4+ICsJCW5hbWUgPSBh Y3BpX2Rldl9nZXRfZmlyc3RfbWF0Y2hfbmFtZSgiSU5UMzQ5NiIsIE5VTEwsIC0xKTsKPj4gKwkJ aWYgKG5hbWUpIHsKPj4gKwkJCWluZm8tPmlkX2V4dGNvbiA9IGV4dGNvbl9nZXRfZXh0Y29uX2Rl dihuYW1lKTsKPj4gKwkJCWlmICghaW5mby0+aWRfZXh0Y29uKQo+PiArCQkJCXJldHVybiAtRVBS T0JFX0RFRkVSOwo+PiArCj4+ICsJCQlkZXZfaW5mbyhkZXYsICJjb250cm9sbGluZyBVU0Igcm9s ZVxuIik7Cj4+ICsJCX0gZWxzZSB7Cj4+ICsJCQlkZXZfaW5mbyhkZXYsICJjb250cm9sbGluZyBV U0Igcm9sZSBiYXNlZCBvbiBWYnVzIHByZXNlbmNlXG4iKTsKPj4gKwkJfQo+PiArCX0KPj4gKwo+ PiArCWluZm8tPnZidXNfYXR0YWNoID0gYXhwMjg4X2dldF92YnVzX2F0dGFjaChpbmZvKTsKPj4g Kwo+PiAgIAlheHAyODhfZXh0Y29uX2xvZ19yc2koaW5mbyk7Cj4+ICAgCj4+ICAgCS8qIEluaXRp YWxpemUgZXh0Y29uIGRldmljZSAqLwo+PiBAQCAtMjg5LDYgKzQxMywxOSBAQCBzdGF0aWMgaW50 IGF4cDI4OF9leHRjb25fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPj4gICAJ CX0KPj4gICAJfQo+PiAgIAo+PiArCWlmIChpbmZvLT5pZF9leHRjb24pIHsKPj4gKwkJcmV0ID0g ZGV2bV9leHRjb25fcmVnaXN0ZXJfbm90aWZpZXJfYWxsKGRldiwgaW5mby0+aWRfZXh0Y29uLAo+ PiArCQkJCQkJCSZpbmZvLT5pZF9uYik7Cj4+ICsJCWlmIChyZXQpCj4+ICsJCQlyZXR1cm4gcmV0 Owo+PiArCX0KPj4gKwo+PiArCS8qIE1ha2Ugc3VyZSB0aGUgcm9sZS1zdyBpcyBzZXQgY29ycmVj dGx5IGJlZm9yZSBkb2luZyBCQyBkZXRlY3Rpb24gKi8KPj4gKwlpZiAoaW5mby0+cm9sZV9zdykg ewo+PiArCQlxdWV1ZV93b3JrKHN5c3RlbV9sb25nX3dxLCAmaW5mby0+cm9sZV93b3JrKTsKPj4g KwkJZmx1c2hfd29yaygmaW5mby0+cm9sZV93b3JrKTsKPj4gKwl9Cj4+ICsKPj4gICAJLyogU3Rh cnQgY2hhcmdlciBjYWJsZSB0eXBlIGRldGVjdGlvbiAqLwo+PiAgIAlheHAyODhfZXh0Y29uX2Vu YWJsZShpbmZvKTsKPj4gICAKPj4gQEAgLTMwOCw4ICs0NDUsMzIgQEAgc3RhdGljIHN0cnVjdCBw bGF0Zm9ybV9kcml2ZXIgYXhwMjg4X2V4dGNvbl9kcml2ZXIgPSB7Cj4+ICAgCQkubmFtZSA9ICJh eHAyODhfZXh0Y29uIiwKPj4gICAJfSwKPj4gICB9Owo+PiAtbW9kdWxlX3BsYXRmb3JtX2RyaXZl cihheHAyODhfZXh0Y29uX2RyaXZlcik7Cj4+ICsKPj4gK3N0YXRpYyBzdHJ1Y3QgZGV2Y29uIGF4 cDI4OF9leHRjb25fcm9sZV9zd19jb25uID0gewo+PiArCS5lbmRwb2ludFswXSA9ICJheHAyODhf ZXh0Y29uIiwKPj4gKwkuZW5kcG9pbnRbMV0gPSAiaW50ZWxfeGhjaV91c2Jfc3ctcm9sZS1zd2l0 Y2giLAo+PiArCS5pZCA9ICJ1c2Itcm9sZS1zd2l0Y2giLAo+PiArfTsKPj4gKwo+PiArc3RhdGlj IGludCBfX2luaXQgYXhwMjg4X2V4dGNvbl9pbml0KHZvaWQpCj4+ICt7Cj4+ICsJaWYgKHg4Nl9t YXRjaF9jcHUoY2hlcnJ5X3RyYWlsX2NwdV9pZHMpKQo+PiArCQlhZGRfZGV2aWNlX2Nvbm5lY3Rp b24oJmF4cDI4OF9leHRjb25fcm9sZV9zd19jb25uKTsKPj4gKwo+PiArCXJldHVybiBwbGF0Zm9y bV9kcml2ZXJfcmVnaXN0ZXIoJmF4cDI4OF9leHRjb25fZHJpdmVyKTsKPj4gK30KPj4gK21vZHVs ZV9pbml0KGF4cDI4OF9leHRjb25faW5pdCk7Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIF9fZXhpdCBh eHAyODhfZXh0Y29uX2V4aXQodm9pZCkKPj4gK3sKPj4gKwlpZiAoeDg2X21hdGNoX2NwdShjaGVy cnlfdHJhaWxfY3B1X2lkcykpCj4+ICsJCXJlbW92ZV9kZXZpY2VfY29ubmVjdGlvbigmYXhwMjg4 X2V4dGNvbl9yb2xlX3N3X2Nvbm4pOwo+PiArCj4+ICsJcGxhdGZvcm1fZHJpdmVyX3VucmVnaXN0 ZXIoJmF4cDI4OF9leHRjb25fZHJpdmVyKTsKPj4gK30KPj4gK21vZHVsZV9leGl0KGF4cDI4OF9l eHRjb25fZXhpdCk7Cj4+ICAgCj4+ICAgTU9EVUxFX0FVVEhPUigiUmFtYWtyaXNobmEgUGFsbGFs YSA8cmFtYWtyaXNobmEucGFsbGFsYUBpbnRlbC5jb20+Iik7Cj4+ICtNT0RVTEVfQVVUSE9SKCJI YW5zIGRlIEdvZWRlIDxoZGVnb2VkZUByZWRoYXQuY29tPiIpOwo+PiAgIE1PRFVMRV9ERVNDUklQ VElPTigiWC1Qb3dlcnMgQVhQMjg4IGV4dGNvbiBkcml2ZXIiKTsKPj4gICBNT0RVTEVfTElDRU5T RSgiR1BMIHYyIik7Cj4+Cj4KLS0tClRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5k IHRoZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC11c2IiIGluCnRoZSBib2R5IG9mIGEgbWVzc2Fn ZSB0byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnCk1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0 dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbAo=