From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-515744-1520865345-2-7381896758077431119 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, HEADER_FROM_DIFFERENT_DOMAINS 0.25, 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: 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=1520865344; b=HebuOPafFM74WlyRcXrgP/K/h6zvfzdMnq9sIXms6vE8kwK ObQD2ex9NXZhXLVfHzy+u9XgjEWKYGCJea3MSvbNXOJhFc+D4g/TlSpSH0WOG8Bt A9up9C/10GTcohJH1D3Y1uTB2j4tZS2Z5Rcm1bAO+ZbPB4DYtu4l/AwWZkBRhVm8 rM6OERrWIxXf0nhIWmw1YLvRmEaQ8dZXBBqDY/yUoMeeF2TIECDxuGRQnu8frgWP VB9ehbTbU6TNzYz5kivSW59j/8B8fyUbwhLmZI9K1/KIfHXtTGfwnWCjsayYdT2r WFlYdmzh4IqfWGAY122RJURie0YwXUEzjlUmNCA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:sender:list-id; s=arctest; t=1520865344; bh=Pk5GLNhGT0Aqd4m5LOxwSp8JlYLeWSn38xAd/VwuIgs=; b=wQL/Q0g+Whx3 7oxaqHLLfFgOHOHHhc36Xt1CW1TbCxlfhkZSVpMiAkdG9yOeb0Xcm8/HD+77bjj/ ZFTz6+i36xpwc1o4rjJyMdex1xMbG+jrUa8OMWtb5uP1lJneP3pNpxThuzHGv1N4 Ob3pw07dsE8szQOP+Y4l3YiZvpqbntCNwgSZJteLsmQ9Wo6i/qW+EpSbctSG/S1U BpTXCzyUVWb7OIiiDzKBJtCGwsjkfgvLZfK/AMPoknzQ2cNu8ayO2hhAGsphjaKD K3PO4wUqcvmlQuBfDIyofDXzkEMg2V7Miqsa3fz3KxuwzQtzgzAcL8qD9GzLIdjv goA1Jr42Eg== ARC-Authentication-Results: i=1; mx4.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=none (p=none,has-list-id=yes,d=none) header.from=linux.intel.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-category=clean score=-100 state=0; 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=linux.intel.com header.result=pass header_org.domain=intel.com header_org.result=pass header_is_org_domain=no Authentication-Results: mx4.messagingengine.com; arc=none (no signatures found); dkim=none (no signatures found); dmarc=none (p=none,has-list-id=yes,d=none) header.from=linux.intel.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-category=clean score=-100 state=0; 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=linux.intel.com header.result=pass header_org.domain=intel.com header_org.result=pass header_is_org_domain=no Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932433AbeCLOfb (ORCPT ); Mon, 12 Mar 2018 10:35:31 -0400 Received: from mga18.intel.com ([134.134.136.126]:22085 "EHLO mga18.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752250AbeCLOfR (ORCPT ); Mon, 12 Mar 2018 10:35:17 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.47,461,1515484800"; d="scan'208";a="37471122" From: Heikki Krogerus To: Greg Kroah-Hartman , Hans de Goede Cc: Darren Hart , Andy Shevchenko , MyungJoo Ham , Chanwoo Choi , Mathias Nyman , Guenter Roeck , Jun Li , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: [PATCH v7 12/12] extcon: axp288: Set USB role where necessary Date: Mon, 12 Mar 2018 17:34:31 +0300 Message-Id: <20180312143431.82396-13-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180312143431.82396-1-heikki.krogerus@linux.intel.com> References: <20180312143431.82396-1-heikki.krogerus@linux.intel.com> 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: From: Hans de Goede 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 Signed-off-by: Hans de Goede Reviewed-by: Heikki Krogerus Reviewed-by: Andy Shevchenko Signed-off-by: Heikki Krogerus --- 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 | 176 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 170 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..a983708b77a6 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,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -25,6 +27,11 @@ #include #include #include +#include +#include + +#include +#include /* Power source status register */ #define PS_STAT_VBUS_TRIGGER BIT(0) @@ -97,9 +104,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 +154,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 +272,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 +287,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 +320,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 +344,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 +412,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 +444,32 @@ static struct platform_driver axp288_extcon_driver = { .name = "axp288_extcon", }, }; -module_platform_driver(axp288_extcon_driver); + +static struct device_connection 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)) + device_connection_add(&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)) + device_connection_remove(&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"); -- 2.16.1 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: [v7,12/12] extcon: axp288: Set USB role where necessary From: Heikki Krogerus Message-Id: <20180312143431.82396-13-heikki.krogerus@linux.intel.com> Date: Mon, 12 Mar 2018 17:34:31 +0300 To: Greg Kroah-Hartman , Hans de Goede Cc: Darren Hart , Andy Shevchenko , MyungJoo Ham , Chanwoo Choi , Mathias Nyman , Guenter Roeck , Jun Li , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org List-ID: RnJvbTogSGFucyBkZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0LmNvbT4KClRoZSBBWFAyODggQkMx LjIgY2hhcmdlciBkZXRlY3Rpb24gLyBleHRjb24gY29kZSBtYXkgc2VlbSBsaWtlIGEgc3RyYW5n ZQpwbGFjZSB0byBhZGQgY29kZSB0byBjb250cm9sIHRoZSBVU0Igcm9sZS1zd2l0Y2ggb24gZGV2 aWNlcyB3aXRoIGFuIEFYUDI4OCwKYnV0IHRoZXJlIGFyZSAyIHJlYXNvbnMgdG8gZG8gdGhpcyBp bnNpZGUgdGhlIGF4cDI4OCBleHRjb24gY29kZToKCjEpIE9uIG1hbnkgZGV2aWNlcyB0aGUgVVNC IHJvbGUgaXMgY29udHJvbGxlZCBieSBBQ1BJIEFNTCBjb2RlLCBidXQgdGhlIEFNTAogICBjb2Rl IG9ubHkgc3dpdGNoZXMgYmV0d2VlbiB0aGUgaG9zdCBhbmQgbm9uZSByb2xlcywgYmVjYXVzZSBv ZiBXaW5kb3dzCiAgIG5vdCByZWFsbHkgdXNpbmcgZGV2aWNlIG1vZGUuIFRvIG1ha2UgZGV2aWNl IG1vZGUgd29yayB3ZSBuZWVkIHRvIHRvZ2dsZQogICBiZXR3ZWVuIHRoZSBub25lL2RldmljZSBy b2xlcyBiYXNlZCBvbiBWYnVzIHByZXNlbmNlLCBhbmQgdGhlIGF4cDI4OAogICBleHRjb24gZ2V0 cyBpbnRlcnJ1cHRzIG9uIFZidXMgaW5zZXJ0aW9uIC8gcmVtb3ZhbC4KCjIpIEluIG9yZGVyIGZv ciBvdXIgQkMxLjIgY2hhcmdlciBkZXRlY3Rpb24gdG8gd29yayBwcm9wZXJseSB0aGUgcm9sZQog ICBtdXggbXVzdCBiZSBwcm9wZXJseSBzZXQgdG8gZGV2aWNlIG1vZGUgYmVmb3JlIHdlIGRvIHRo ZSBkZXRlY3Rpb24uCgpBbHNvIG5vdGUgdGhlIEtjb25maWcgaGVscC10ZXh0IC8gb2Jzb2xldGUg ZGVwZW5kcyBvbiBVU0JfUEhZIHdoaWNoIGFyZQpyZW1uYW50cyBmcm9tIG9sZGVyIG5ldmVyIHVw c3RyZWFtZWQgY29kZSBhbHNvIGNvbnRyb2xsaW5nIHRoZSBtdXggZnJvbQp0aGUgYXhwMjg4IGV4 dGNvbiBjb2RlLgoKVGhpcyBjb21taXQgYWxzbyBhZGRzIGNvZGUgdG8gZ2V0IG5vdGlmaWNhdGlv bnMgZnJvbSB0aGUgSU5UMzQ5NiBleHRjb24KZGV2aWNlLCB3aGljaCBpcyB1c2VkIG9uIHNvbWUg ZGV2aWNlcyB0byBub3RpZnkgdGhlIGtlcm5lbCBhYm91dCBpZC1waW4KY2hhbmdlcyBpbnN0ZWFk IG9mIHRoZW0gYmVpbmcgaGFuZGxlZCB0aHJvdWdoIEFNTCBjb2RlLgoKVGhpcyBmaXhlczoKLURl dmljZSBtb2RlIG5vdCB3b3JraW5nIG9uIG1vc3QgQ0hUIGRldmljZXMgd2l0aCBhbiBBWFAyODgK LUhvc3QgbW9kZSBub3Qgd29ya2luZyBvbiBkZXZpY2VzIHdpdGggYW4gSU5UMzQ5NiBBQ1BJIGRl dmljZQotQ2hhcmdlci10eXBlIG1pc2RldGVjdGlvbiAoYWx3YXlzIFNEUCkgb24gZGV2aWNlcyB3 aXRoIGFuIElOVDM0OTYgd2hlbiB0aGUKIFVTQiByb2xlIChhbHdheXMpIGdldHMgaW5pdGlhbGl6 ZWQgYXMgaG9zdAoKU2lnbmVkLW9mZi1ieTogSGFucyBkZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0 LmNvbT4KUmV2aWV3ZWQtYnk6IEhlaWtraSBLcm9nZXJ1cyA8aGVpa2tpLmtyb2dlcnVzQGxpbnV4 LmludGVsLmNvbT4KUmV2aWV3ZWQtYnk6IEFuZHkgU2hldmNoZW5rbyA8YW5keS5zaGV2Y2hlbmtv QGdtYWlsLmNvbT4KU2lnbmVkLW9mZi1ieTogSGVpa2tpIEtyb2dlcnVzIDxoZWlra2kua3JvZ2Vy dXNAbGludXguaW50ZWwuY29tPgotLS0KQ2hhbmdlcyBpbiB2NDoKLUFkZCBBbmR5J3MgUmV2aWV3 ZWQtYnkKCkNoYW5nZXMgaW4gdjI6Ci1BZGQgZGVwZW5kcyBvbiBYODYgdG8gS2NvbmZpZyAodGhl IEFYUDI4OCBQTUlDIGlzIG9ubHkgdXNlZCBvbiBYODYpCi1Vc2UgbmV3IGFjcGlfZGV2X2dldF9m aXJzdF9tYXRjaF9uYW1lKCkgaGVscGVyIHRvIGdldCB0aGUgSU5UMzQ5NiBkZXZpY2UtbmFtZQot QWRkIEhlaWtraSdzIFJldmlld2VkLWJ5Ci0tLQogZHJpdmVycy9leHRjb24vS2NvbmZpZyAgICAg ICAgIHwgICAzICstCiBkcml2ZXJzL2V4dGNvbi9leHRjb24tYXhwMjg4LmMgfCAxNzYgKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLS0KIDIgZmlsZXMgY2hhbmdlZCwgMTcw IGluc2VydGlvbnMoKyksIDkgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9leHRj b24vS2NvbmZpZyBiL2RyaXZlcnMvZXh0Y29uL0tjb25maWcKaW5kZXggYTdiY2E0MjA3ZjQ0Li5k ZTE1YmY1NTg5NWIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZXh0Y29uL0tjb25maWcKKysrIGIvZHJp dmVycy9leHRjb24vS2NvbmZpZwpAQCAtMzAsNyArMzAsOCBAQCBjb25maWcgRVhUQ09OX0FSSVpP TkEKIAogY29uZmlnIEVYVENPTl9BWFAyODgKIAl0cmlzdGF0ZSAiWC1Qb3dlciBBWFAyODggRVhU Q09OIHN1cHBvcnQiCi0JZGVwZW5kcyBvbiBNRkRfQVhQMjBYICYmIFVTQl9QSFkKKwlkZXBlbmRz IG9uIE1GRF9BWFAyMFggJiYgVVNCX1NVUFBPUlQgJiYgWDg2CisJc2VsZWN0IFVTQl9ST0xFX1NX SVRDSAogCWhlbHAKIAkgIFNheSBZIGhlcmUgdG8gZW5hYmxlIHN1cHBvcnQgZm9yIFVTQiBwZXJp cGhlcmFsIGRldGVjdGlvbgogCSAgYW5kIFVTQiBNVVggc3dpdGNoaW5nIGJ5IFgtUG93ZXIgQVhQ Mjg4IFBNSUMuCmRpZmYgLS1naXQgYS9kcml2ZXJzL2V4dGNvbi9leHRjb24tYXhwMjg4LmMgYi9k cml2ZXJzL2V4dGNvbi9leHRjb24tYXhwMjg4LmMKaW5kZXggM2VjNGM3MTVlMjQwLi5hOTgzNzA4 Yjc3YTYgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZXh0Y29uL2V4dGNvbi1heHAyODguYworKysgYi9k cml2ZXJzL2V4dGNvbi9leHRjb24tYXhwMjg4LmMKQEAgLTEsNiArMSw3IEBACiAvKgogICogZXh0 Y29uLWF4cDI4OC5jIC0gWC1Qb3dlciBBWFAyODggUE1JQyBleHRjb24gY2FibGUgZGV0ZWN0aW9u IGRyaXZlcgogICoKKyAqIENvcHlyaWdodCAoYykgMjAxNy0yMDE4IEhhbnMgZGUgR29lZGUgPGhk ZWdvZWRlQHJlZGhhdC5jb20+CiAgKiBDb3B5cmlnaHQgKEMpIDIwMTUgSW50ZWwgQ29ycG9yYXRp b24KICAqIEF1dGhvcjogUmFtYWtyaXNobmEgUGFsbGFsYSA8cmFtYWtyaXNobmEucGFsbGFsYUBp bnRlbC5jb20+CiAgKgpAQCAtMTQsNiArMTUsNyBAQAogICogR05VIEdlbmVyYWwgUHVibGljIExp Y2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICAqLwogCisjaW5jbHVkZSA8bGludXgvYWNwaS5oPgog I2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgogI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgogI2lu Y2x1ZGUgPGxpbnV4L2lvLmg+CkBAIC0yNSw2ICsyNywxMSBAQAogI2luY2x1ZGUgPGxpbnV4L2V4 dGNvbi1wcm92aWRlci5oPgogI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPgogI2luY2x1ZGUgPGxp bnV4L21mZC9heHAyMHguaD4KKyNpbmNsdWRlIDxsaW51eC91c2Ivcm9sZS5oPgorI2luY2x1ZGUg PGxpbnV4L3dvcmtxdWV1ZS5oPgorCisjaW5jbHVkZSA8YXNtL2NwdV9kZXZpY2VfaWQuaD4KKyNp bmNsdWRlIDxhc20vaW50ZWwtZmFtaWx5Lmg+CiAKIC8qIFBvd2VyIHNvdXJjZSBzdGF0dXMgcmVn aXN0ZXIgKi8KICNkZWZpbmUgUFNfU1RBVF9WQlVTX1RSSUdHRVIJCUJJVCgwKQpAQCAtOTcsOSAr MTA0LDE5IEBAIHN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gewogCXN0cnVjdCBkZXZpY2UgKmRl djsKIAlzdHJ1Y3QgcmVnbWFwICpyZWdtYXA7CiAJc3RydWN0IHJlZ21hcF9pcnFfY2hpcF9kYXRh ICpyZWdtYXBfaXJxYzsKKwlzdHJ1Y3QgdXNiX3JvbGVfc3dpdGNoICpyb2xlX3N3OworCXN0cnVj dCB3b3JrX3N0cnVjdCByb2xlX3dvcms7CiAJaW50IGlycVtFWFRDT05fSVJRX0VORF07CiAJc3Ry dWN0IGV4dGNvbl9kZXYgKmVkZXY7CisJc3RydWN0IGV4dGNvbl9kZXYgKmlkX2V4dGNvbjsKKwlz dHJ1Y3Qgbm90aWZpZXJfYmxvY2sgaWRfbmI7CiAJdW5zaWduZWQgaW50IHByZXZpb3VzX2NhYmxl OworCWJvb2wgdmJ1c19hdHRhY2g7Cit9OworCitzdGF0aWMgY29uc3Qgc3RydWN0IHg4Nl9jcHVf aWQgY2hlcnJ5X3RyYWlsX2NwdV9pZHNbXSA9IHsKKwl7IFg4Nl9WRU5ET1JfSU5URUwsIDYsIElO VEVMX0ZBTTZfQVRPTV9BSVJNT05ULCBYODZfRkVBVFVSRV9BTlkgfSwKKwl7fQogfTsKIAogLyog UG93ZXIgdXAvZG93biByZWFzb24gc3RyaW5nIGFycmF5ICovCkBAIC0xMzcsMjAgKzE1NCw3NCBA QCBzdGF0aWMgdm9pZCBheHAyODhfZXh0Y29uX2xvZ19yc2koc3RydWN0IGF4cDI4OF9leHRjb25f aW5mbyAqaW5mbykKIAlyZWdtYXBfd3JpdGUoaW5mby0+cmVnbWFwLCBBWFAyODhfUFNfQk9PVF9S RUFTT05fUkVHLCBjbGVhcl9tYXNrKTsKIH0KIAotc3RhdGljIGludCBheHAyODhfaGFuZGxlX2No cmdfZGV0X2V2ZW50KHN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8pCisvKgorICogVGhl IGJlbG93IGNvZGUgdG8gY29udHJvbCB0aGUgVVNCIHJvbGUtc3dpdGNoIG9uIGRldmljZXMgd2l0 aCBhbiBBWFAyODgKKyAqIG1heSBzZWVtIG91dCBvZiBwbGFjZSwgYnV0IHRoZXJlIGFyZSAyIHJl YXNvbnMgd2h5IHRoaXMgaXMgdGhlIGJlc3QgcGxhY2UKKyAqIHRvIGNvbnRyb2wgdGhlIFVTQiBy b2xlLXN3aXRjaCBvbiBzdWNoIGRldmljZXM6CisgKiAxKSBPbiBtYW55IGRldmljZXMgdGhlIFVT QiByb2xlIGlzIGNvbnRyb2xsZWQgYnkgQU1MIGNvZGUsIGJ1dCB0aGUgQU1MIGNvZGUKKyAqICAg IG9ubHkgc3dpdGNoZXMgYmV0d2VlbiB0aGUgaG9zdCBhbmQgbm9uZSByb2xlcywgYmVjYXVzZSBv ZiBXaW5kb3dzIG5vdAorICogICAgcmVhbGx5IHVzaW5nIGRldmljZSBtb2RlLiBUbyBtYWtlIGRl dmljZSBtb2RlIHdvcmsgd2UgbmVlZCB0byB0b2dnbGUKKyAqICAgIGJldHdlZW4gdGhlIG5vbmUv ZGV2aWNlIHJvbGVzIGJhc2VkIG9uIFZidXMgcHJlc2VuY2UsIGFuZCB0aGlzIGRyaXZlcgorICog ICAgZ2V0cyBpbnRlcnJ1cHRzIG9uIFZidXMgaW5zZXJ0aW9uIC8gcmVtb3ZhbC4KKyAqIDIpIElu IG9yZGVyIGZvciBvdXIgQkMxLjIgY2hhcmdlciBkZXRlY3Rpb24gdG8gd29yayBwcm9wZXJseSB0 aGUgcm9sZQorICogICAgbXV4IG11c3QgYmUgcHJvcGVybHkgc2V0IHRvIGRldmljZSBtb2RlIGJl Zm9yZSB3ZSBkbyB0aGUgZGV0ZWN0aW9uLgorICovCisKKy8qIFJldHVybnMgdGhlIGlkLXBpbiB2 YWx1ZSwgbm90ZSBwdWxsZWQgbG93IC8gZmFsc2UgPT0gaG9zdC1tb2RlICovCitzdGF0aWMgYm9v bCBheHAyODhfZ2V0X2lkX3BpbihzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQogewot CWludCByZXQsIHN0YXQsIGNmZywgcHdyX3N0YXQ7Ci0JdTggY2hyZ190eXBlOwotCXVuc2lnbmVk IGludCBjYWJsZSA9IGluZm8tPnByZXZpb3VzX2NhYmxlOwotCWJvb2wgdmJ1c19hdHRhY2ggPSBm YWxzZTsKKwllbnVtIHVzYl9yb2xlIHJvbGU7CisKKwlpZiAoaW5mby0+aWRfZXh0Y29uKQorCQly ZXR1cm4gZXh0Y29uX2dldF9zdGF0ZShpbmZvLT5pZF9leHRjb24sIEVYVENPTl9VU0JfSE9TVCkg PD0gMDsKKworCS8qIFdlIGNhbm5vdCBhY2Nlc3MgdGhlIGlkLXBpbiwgc2VlIHdoYXQgbW9kZSB0 aGUgQU1MIGNvZGUgaGFzIHNldCAqLworCXJvbGUgPSB1c2Jfcm9sZV9zd2l0Y2hfZ2V0X3JvbGUo aW5mby0+cm9sZV9zdyk7CisJcmV0dXJuIHJvbGUgIT0gVVNCX1JPTEVfSE9TVDsKK30KKworc3Rh dGljIHZvaWQgYXhwMjg4X3VzYl9yb2xlX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQor eworCXN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8gPQorCQljb250YWluZXJfb2Yod29y aywgc3RydWN0IGF4cDI4OF9leHRjb25faW5mbywgcm9sZV93b3JrKTsKKwllbnVtIHVzYl9yb2xl IHJvbGU7CisJYm9vbCBpZF9waW47CisJaW50IHJldDsKKworCWlkX3BpbiA9IGF4cDI4OF9nZXRf aWRfcGluKGluZm8pOworCWlmICghaWRfcGluKQorCQlyb2xlID0gVVNCX1JPTEVfSE9TVDsKKwll bHNlIGlmIChpbmZvLT52YnVzX2F0dGFjaCkKKwkJcm9sZSA9IFVTQl9ST0xFX0RFVklDRTsKKwll bHNlCisJCXJvbGUgPSBVU0JfUk9MRV9OT05FOworCisJcmV0ID0gdXNiX3JvbGVfc3dpdGNoX3Nl dF9yb2xlKGluZm8tPnJvbGVfc3csIHJvbGUpOworCWlmIChyZXQpCisJCWRldl9lcnIoaW5mby0+ ZGV2LCAiZmFpbGVkIHRvIHNldCByb2xlOiAlZFxuIiwgcmV0KTsKK30KKworc3RhdGljIGJvb2wg YXhwMjg4X2dldF92YnVzX2F0dGFjaChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQor eworCWludCByZXQsIHB3cl9zdGF0OwogCiAJcmV0ID0gcmVnbWFwX3JlYWQoaW5mby0+cmVnbWFw LCBBWFAyODhfUFNfU1RBVF9SRUcsICZwd3Jfc3RhdCk7CiAJaWYgKHJldCA8IDApIHsKIAkJZGV2 X2VycihpbmZvLT5kZXYsICJmYWlsZWQgdG8gcmVhZCB2YnVzIHN0YXR1c1xuIik7Ci0JCXJldHVy biByZXQ7CisJCXJldHVybiBmYWxzZTsKIAl9CiAKLQl2YnVzX2F0dGFjaCA9IChwd3Jfc3RhdCAm IFBTX1NUQVRfVkJVU19WQUxJRCk7CisJcmV0dXJuICEhKHB3cl9zdGF0ICYgUFNfU1RBVF9WQlVT X1ZBTElEKTsKK30KKworc3RhdGljIGludCBheHAyODhfaGFuZGxlX2NocmdfZGV0X2V2ZW50KHN0 cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8pCit7CisJaW50IHJldCwgc3RhdCwgY2ZnOwor CXU4IGNocmdfdHlwZTsKKwl1bnNpZ25lZCBpbnQgY2FibGUgPSBpbmZvLT5wcmV2aW91c19jYWJs ZTsKKwlib29sIHZidXNfYXR0YWNoID0gZmFsc2U7CisKKwl2YnVzX2F0dGFjaCA9IGF4cDI4OF9n ZXRfdmJ1c19hdHRhY2goaW5mbyk7CiAJaWYgKCF2YnVzX2F0dGFjaCkKIAkJZ290byBub192YnVz OwogCkBAIC0yMDEsNiArMjcyLDEyIEBAIHN0YXRpYyBpbnQgYXhwMjg4X2hhbmRsZV9jaHJnX2Rl dF9ldmVudChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQogCQlpbmZvLT5wcmV2aW91 c19jYWJsZSA9IGNhYmxlOwogCX0KIAorCWlmIChpbmZvLT5yb2xlX3N3ICYmIGluZm8tPnZidXNf YXR0YWNoICE9IHZidXNfYXR0YWNoKSB7CisJCWluZm8tPnZidXNfYXR0YWNoID0gdmJ1c19hdHRh Y2g7CisJCS8qIFNldHRpbmcgdGhlIHJvbGUgY2FuIHRha2UgYSB3aGlsZSAqLworCQlxdWV1ZV93 b3JrKHN5c3RlbV9sb25nX3dxLCAmaW5mby0+cm9sZV93b3JrKTsKKwl9CisKIAlyZXR1cm4gMDsK IAogZGV2X2RldF9yZXQ6CkBAIC0yMTAsNiArMjg3LDE4IEBAIHN0YXRpYyBpbnQgYXhwMjg4X2hh bmRsZV9jaHJnX2RldF9ldmVudChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQogCXJl dHVybiByZXQ7CiB9CiAKK3N0YXRpYyBpbnQgYXhwMjg4X2V4dGNvbl9pZF9ldnQoc3RydWN0IG5v dGlmaWVyX2Jsb2NrICpuYiwKKwkJCQl1bnNpZ25lZCBsb25nIGV2ZW50LCB2b2lkICpwYXJhbSkK K3sKKwlzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvID0KKwkJY29udGFpbmVyX29mKG5i LCBzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvLCBpZF9uYik7CisKKwkvKiBXZSBtYXkgbm90IHNs ZWVwIGFuZCBzZXR0aW5nIHRoZSByb2xlIGNhbiB0YWtlIGEgd2hpbGUgKi8KKwlxdWV1ZV93b3Jr KHN5c3RlbV9sb25nX3dxLCAmaW5mby0+cm9sZV93b3JrKTsKKworCXJldHVybiBOT1RJRllfT0s7 Cit9CisKIHN0YXRpYyBpcnFyZXR1cm5fdCBheHAyODhfZXh0Y29uX2lzcihpbnQgaXJxLCB2b2lk ICpkYXRhKQogewogCXN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8gPSBkYXRhOwpAQCAt MjMxLDEwICszMjAsMjAgQEAgc3RhdGljIHZvaWQgYXhwMjg4X2V4dGNvbl9lbmFibGUoc3RydWN0 IGF4cDI4OF9leHRjb25faW5mbyAqaW5mbykKIAkJCQkJQkNfR0xPQkFMX1JVTiwgQkNfR0xPQkFM X1JVTik7CiB9CiAKK3N0YXRpYyB2b2lkIGF4cDI4OF9wdXRfcm9sZV9zdyh2b2lkICpkYXRhKQor eworCXN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8gPSBkYXRhOworCisJY2FuY2VsX3dv cmtfc3luYygmaW5mby0+cm9sZV93b3JrKTsKKwl1c2Jfcm9sZV9zd2l0Y2hfcHV0KGluZm8tPnJv bGVfc3cpOworfQorCiBzdGF0aWMgaW50IGF4cDI4OF9leHRjb25fcHJvYmUoc3RydWN0IHBsYXRm b3JtX2RldmljZSAqcGRldikKIHsKIAlzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvOwog CXN0cnVjdCBheHAyMHhfZGV2ICpheHAyMHggPSBkZXZfZ2V0X2RydmRhdGEocGRldi0+ZGV2LnBh cmVudCk7CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwljb25zdCBjaGFyICpu YW1lOwogCWludCByZXQsIGksIHBpcnE7CiAKIAlpbmZvID0gZGV2bV9remFsbG9jKCZwZGV2LT5k ZXYsIHNpemVvZigqaW5mbyksIEdGUF9LRVJORUwpOwpAQCAtMjQ1LDkgKzM0NCwzMyBAQCBzdGF0 aWMgaW50IGF4cDI4OF9leHRjb25fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikK IAlpbmZvLT5yZWdtYXAgPSBheHAyMHgtPnJlZ21hcDsKIAlpbmZvLT5yZWdtYXBfaXJxYyA9IGF4 cDIweC0+cmVnbWFwX2lycWM7CiAJaW5mby0+cHJldmlvdXNfY2FibGUgPSBFWFRDT05fTk9ORTsK KwlJTklUX1dPUksoJmluZm8tPnJvbGVfd29yaywgYXhwMjg4X3VzYl9yb2xlX3dvcmspOworCWlu Zm8tPmlkX25iLm5vdGlmaWVyX2NhbGwgPSBheHAyODhfZXh0Y29uX2lkX2V2dDsKIAogCXBsYXRm b3JtX3NldF9kcnZkYXRhKHBkZXYsIGluZm8pOwogCisJaW5mby0+cm9sZV9zdyA9IHVzYl9yb2xl X3N3aXRjaF9nZXQoZGV2KTsKKwlpZiAoSVNfRVJSKGluZm8tPnJvbGVfc3cpKQorCQlyZXR1cm4g UFRSX0VSUihpbmZvLT5yb2xlX3N3KTsKKwlpZiAoaW5mby0+cm9sZV9zdykgeworCQlyZXQgPSBk ZXZtX2FkZF9hY3Rpb25fb3JfcmVzZXQoZGV2LCBheHAyODhfcHV0X3JvbGVfc3csIGluZm8pOwor CQlpZiAocmV0KQorCQkJcmV0dXJuIHJldDsKKworCQluYW1lID0gYWNwaV9kZXZfZ2V0X2ZpcnN0 X21hdGNoX25hbWUoIklOVDM0OTYiLCBOVUxMLCAtMSk7CisJCWlmIChuYW1lKSB7CisJCQlpbmZv LT5pZF9leHRjb24gPSBleHRjb25fZ2V0X2V4dGNvbl9kZXYobmFtZSk7CisJCQlpZiAoIWluZm8t PmlkX2V4dGNvbikKKwkJCQlyZXR1cm4gLUVQUk9CRV9ERUZFUjsKKworCQkJZGV2X2luZm8oZGV2 LCAiY29udHJvbGxpbmcgVVNCIHJvbGVcbiIpOworCQl9IGVsc2UgeworCQkJZGV2X2luZm8oZGV2 LCAiY29udHJvbGxpbmcgVVNCIHJvbGUgYmFzZWQgb24gVmJ1cyBwcmVzZW5jZVxuIik7CisJCX0K Kwl9CisKKwlpbmZvLT52YnVzX2F0dGFjaCA9IGF4cDI4OF9nZXRfdmJ1c19hdHRhY2goaW5mbyk7 CisKIAlheHAyODhfZXh0Y29uX2xvZ19yc2koaW5mbyk7CiAKIAkvKiBJbml0aWFsaXplIGV4dGNv biBkZXZpY2UgKi8KQEAgLTI4OSw2ICs0MTIsMTkgQEAgc3RhdGljIGludCBheHAyODhfZXh0Y29u X3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCiAJCX0KIAl9CiAKKwlpZiAoaW5m by0+aWRfZXh0Y29uKSB7CisJCXJldCA9IGRldm1fZXh0Y29uX3JlZ2lzdGVyX25vdGlmaWVyX2Fs bChkZXYsIGluZm8tPmlkX2V4dGNvbiwKKwkJCQkJCQkmaW5mby0+aWRfbmIpOworCQlpZiAocmV0 KQorCQkJcmV0dXJuIHJldDsKKwl9CisKKwkvKiBNYWtlIHN1cmUgdGhlIHJvbGUtc3cgaXMgc2V0 IGNvcnJlY3RseSBiZWZvcmUgZG9pbmcgQkMgZGV0ZWN0aW9uICovCisJaWYgKGluZm8tPnJvbGVf c3cpIHsKKwkJcXVldWVfd29yayhzeXN0ZW1fbG9uZ193cSwgJmluZm8tPnJvbGVfd29yayk7CisJ CWZsdXNoX3dvcmsoJmluZm8tPnJvbGVfd29yayk7CisJfQorCiAJLyogU3RhcnQgY2hhcmdlciBj YWJsZSB0eXBlIGRldGVjdGlvbiAqLwogCWF4cDI4OF9leHRjb25fZW5hYmxlKGluZm8pOwogCkBA IC0zMDgsOCArNDQ0LDMyIEBAIHN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGF4cDI4OF9l eHRjb25fZHJpdmVyID0gewogCQkubmFtZSA9ICJheHAyODhfZXh0Y29uIiwKIAl9LAogfTsKLW1v ZHVsZV9wbGF0Zm9ybV9kcml2ZXIoYXhwMjg4X2V4dGNvbl9kcml2ZXIpOworCitzdGF0aWMgc3Ry dWN0IGRldmljZV9jb25uZWN0aW9uIGF4cDI4OF9leHRjb25fcm9sZV9zd19jb25uID0geworCS5l bmRwb2ludFswXSA9ICJheHAyODhfZXh0Y29uIiwKKwkuZW5kcG9pbnRbMV0gPSAiaW50ZWxfeGhj aV91c2Jfc3ctcm9sZS1zd2l0Y2giLAorCS5pZCA9ICJ1c2Itcm9sZS1zd2l0Y2giLAorfTsKKwor c3RhdGljIGludCBfX2luaXQgYXhwMjg4X2V4dGNvbl9pbml0KHZvaWQpCit7CisJaWYgKHg4Nl9t YXRjaF9jcHUoY2hlcnJ5X3RyYWlsX2NwdV9pZHMpKQorCQlkZXZpY2VfY29ubmVjdGlvbl9hZGQo JmF4cDI4OF9leHRjb25fcm9sZV9zd19jb25uKTsKKworCXJldHVybiBwbGF0Zm9ybV9kcml2ZXJf cmVnaXN0ZXIoJmF4cDI4OF9leHRjb25fZHJpdmVyKTsKK30KK21vZHVsZV9pbml0KGF4cDI4OF9l eHRjb25faW5pdCk7CisKK3N0YXRpYyB2b2lkIF9fZXhpdCBheHAyODhfZXh0Y29uX2V4aXQodm9p ZCkKK3sKKwlpZiAoeDg2X21hdGNoX2NwdShjaGVycnlfdHJhaWxfY3B1X2lkcykpCisJCWRldmlj ZV9jb25uZWN0aW9uX3JlbW92ZSgmYXhwMjg4X2V4dGNvbl9yb2xlX3N3X2Nvbm4pOworCisJcGxh dGZvcm1fZHJpdmVyX3VucmVnaXN0ZXIoJmF4cDI4OF9leHRjb25fZHJpdmVyKTsKK30KK21vZHVs ZV9leGl0KGF4cDI4OF9leHRjb25fZXhpdCk7CiAKIE1PRFVMRV9BVVRIT1IoIlJhbWFrcmlzaG5h IFBhbGxhbGEgPHJhbWFrcmlzaG5hLnBhbGxhbGFAaW50ZWwuY29tPiIpOworTU9EVUxFX0FVVEhP UigiSGFucyBkZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0LmNvbT4iKTsKIE1PRFVMRV9ERVNDUklQ VElPTigiWC1Qb3dlcnMgQVhQMjg4IGV4dGNvbiBkcml2ZXIiKTsKIE1PRFVMRV9MSUNFTlNFKCJH UEwgdjIiKTsK