From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Google-Smtp-Source: AG47ELvCiH+9jHbd1b44Fh1JAU4KmEJt0cYK1wH7FHIDA9Rfawx7xXfDFAa1RI9L+80UOxefnFkE ARC-Seal: i=1; a=rsa-sha256; t=1521550679; cv=none; d=google.com; s=arc-20160816; b=PL7poQ7NSC602v8lDDWlk5bnX8d7vs1oZMenotfZuIgUdpPiRAGDrbGwNDpFZSge8o qaWJmw2ULgok06k8fl++WGJ3y9Hr60N5J4a7ewX4Q0lNziOzMds08HGIzVVLeeBKOv/B C1dFLvXaYospwy/sYaByd/fdN4AJg+0eWjzxfjhpVJB+sZQGjUJO00u+L0vTFfvlxIqH g2c4W6B6zV7HPS9fo7UvcZN9lcq6BZggrr5zFXGuEsQZIaIIYrqPMC3693Me/l0usL8h E39y7ohavLowvVx7TQKvG6sPPNePWHyQGWlzV7E9z9AwoznoMu+2s1tMWhyGpGeRmoiU fHGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=Mq580pgbakI8XtfhRGVY+M/cBhyyxEuiR9LDhjagQU0=; b=xqlu9/P0cSauWJDQEbo3YQLJ7kJ0/7p1dfj++ExwZUdwtLXoZBo7ZBZFN/ZQ0RmRmZ 9ai8lfYi7vOi0GRCyzeMQ6XqDCnruHPe9VIL/J1OpQBBAbq26ustOupgRa8fCw3HU03C T8PUtx/3F0ef3KNBoATknS082shP1Jzu9e7lqh6VsnXH2an6WcxWDB1X+VFbRjQRtIl2 MOBeVirFcIiuI0v+d0fvP3g6uXJFBY7VYMwmrSxcV7unJQkEsPj5F/L02CWw4Uuv/3+E 4k+vODWkGBByub7EBC5jkfeUpVic97AT5VzRa/A/UwlAnGuNeSO3n5ZTIUf8njHsRpiR JDgA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of heikki.krogerus@linux.intel.com designates 134.134.136.31 as permitted sender) smtp.mailfrom=heikki.krogerus@linux.intel.com Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of heikki.krogerus@linux.intel.com designates 134.134.136.31 as permitted sender) smtp.mailfrom=heikki.krogerus@linux.intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,335,1517904000"; d="scan'208";a="39592644" 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 v9 12/12] extcon: axp288: Set USB role where necessary Date: Tue, 20 Mar 2018 15:57:13 +0300 Message-Id: <20180320125713.85465-13-heikki.krogerus@linux.intel.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180320125713.85465-1-heikki.krogerus@linux.intel.com> References: <20180320125713.85465-1-heikki.krogerus@linux.intel.com> X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: =?utf-8?q?1595461525847082609?= X-GMAIL-MSGID: =?utf-8?q?1595461525847082609?= 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: 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.2 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: [v9,12/12] extcon: axp288: Set USB role where necessary From: Heikki Krogerus Message-Id: <20180320125713.85465-13-heikki.krogerus@linux.intel.com> Date: Tue, 20 Mar 2018 15:57:13 +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 LmNvbT4KUmV2aWV3ZWQtYnk6IEFuZHkgU2hldmNoZW5rbyA8YW5keS5zaGV2Y2hlbmtvQGdtYWls LmNvbT4KU2lnbmVkLW9mZi1ieTogSGVpa2tpIEtyb2dlcnVzIDxoZWlra2kua3JvZ2VydXNAbGlu dXguaW50ZWwuY29tPgotLS0KQ2hhbmdlcyBpbiB2NDoKLUFkZCBBbmR5J3MgUmV2aWV3ZWQtYnkK CkNoYW5nZXMgaW4gdjI6Ci1BZGQgZGVwZW5kcyBvbiBYODYgdG8gS2NvbmZpZyAodGhlIEFYUDI4 OCBQTUlDIGlzIG9ubHkgdXNlZCBvbiBYODYpCi1Vc2UgbmV3IGFjcGlfZGV2X2dldF9maXJzdF9t YXRjaF9uYW1lKCkgaGVscGVyIHRvIGdldCB0aGUgSU5UMzQ5NiBkZXZpY2UtbmFtZQotQWRkIEhl aWtraSdzIFJldmlld2VkLWJ5Ci0tLQogZHJpdmVycy9leHRjb24vS2NvbmZpZyAgICAgICAgIHwg ICAzICstCiBkcml2ZXJzL2V4dGNvbi9leHRjb24tYXhwMjg4LmMgfCAxNzYgKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrLS0KIDIgZmlsZXMgY2hhbmdlZCwgMTcwIGluc2Vy dGlvbnMoKyksIDkgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy9leHRjb24vS2Nv bmZpZyBiL2RyaXZlcnMvZXh0Y29uL0tjb25maWcKaW5kZXggYTdiY2E0MjA3ZjQ0Li5kZTE1YmY1 NTg5NWIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZXh0Y29uL0tjb25maWcKKysrIGIvZHJpdmVycy9l eHRjb24vS2NvbmZpZwpAQCAtMzAsNyArMzAsOCBAQCBjb25maWcgRVhUQ09OX0FSSVpPTkEKIAog Y29uZmlnIEVYVENPTl9BWFAyODgKIAl0cmlzdGF0ZSAiWC1Qb3dlciBBWFAyODggRVhUQ09OIHN1 cHBvcnQiCi0JZGVwZW5kcyBvbiBNRkRfQVhQMjBYICYmIFVTQl9QSFkKKwlkZXBlbmRzIG9uIE1G RF9BWFAyMFggJiYgVVNCX1NVUFBPUlQgJiYgWDg2CisJc2VsZWN0IFVTQl9ST0xFX1NXSVRDSAog CWhlbHAKIAkgIFNheSBZIGhlcmUgdG8gZW5hYmxlIHN1cHBvcnQgZm9yIFVTQiBwZXJpcGhlcmFs IGRldGVjdGlvbgogCSAgYW5kIFVTQiBNVVggc3dpdGNoaW5nIGJ5IFgtUG93ZXIgQVhQMjg4IFBN SUMuCmRpZmYgLS1naXQgYS9kcml2ZXJzL2V4dGNvbi9leHRjb24tYXhwMjg4LmMgYi9kcml2ZXJz L2V4dGNvbi9leHRjb24tYXhwMjg4LmMKaW5kZXggM2VjNGM3MTVlMjQwLi5hOTgzNzA4Yjc3YTYg MTAwNjQ0Ci0tLSBhL2RyaXZlcnMvZXh0Y29uL2V4dGNvbi1heHAyODguYworKysgYi9kcml2ZXJz L2V4dGNvbi9leHRjb24tYXhwMjg4LmMKQEAgLTEsNiArMSw3IEBACiAvKgogICogZXh0Y29uLWF4 cDI4OC5jIC0gWC1Qb3dlciBBWFAyODggUE1JQyBleHRjb24gY2FibGUgZGV0ZWN0aW9uIGRyaXZl cgogICoKKyAqIENvcHlyaWdodCAoYykgMjAxNy0yMDE4IEhhbnMgZGUgR29lZGUgPGhkZWdvZWRl QHJlZGhhdC5jb20+CiAgKiBDb3B5cmlnaHQgKEMpIDIwMTUgSW50ZWwgQ29ycG9yYXRpb24KICAq IEF1dGhvcjogUmFtYWtyaXNobmEgUGFsbGFsYSA8cmFtYWtyaXNobmEucGFsbGFsYUBpbnRlbC5j b20+CiAgKgpAQCAtMTQsNiArMTUsNyBAQAogICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug Zm9yIG1vcmUgZGV0YWlscy4KICAqLwogCisjaW5jbHVkZSA8bGludXgvYWNwaS5oPgogI2luY2x1 ZGUgPGxpbnV4L21vZHVsZS5oPgogI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgogI2luY2x1ZGUg PGxpbnV4L2lvLmg+CkBAIC0yNSw2ICsyNywxMSBAQAogI2luY2x1ZGUgPGxpbnV4L2V4dGNvbi1w cm92aWRlci5oPgogI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPgogI2luY2x1ZGUgPGxpbnV4L21m ZC9heHAyMHguaD4KKyNpbmNsdWRlIDxsaW51eC91c2Ivcm9sZS5oPgorI2luY2x1ZGUgPGxpbnV4 L3dvcmtxdWV1ZS5oPgorCisjaW5jbHVkZSA8YXNtL2NwdV9kZXZpY2VfaWQuaD4KKyNpbmNsdWRl IDxhc20vaW50ZWwtZmFtaWx5Lmg+CiAKIC8qIFBvd2VyIHNvdXJjZSBzdGF0dXMgcmVnaXN0ZXIg Ki8KICNkZWZpbmUgUFNfU1RBVF9WQlVTX1RSSUdHRVIJCUJJVCgwKQpAQCAtOTcsOSArMTA0LDE5 IEBAIHN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gewogCXN0cnVjdCBkZXZpY2UgKmRldjsKIAlz dHJ1Y3QgcmVnbWFwICpyZWdtYXA7CiAJc3RydWN0IHJlZ21hcF9pcnFfY2hpcF9kYXRhICpyZWdt YXBfaXJxYzsKKwlzdHJ1Y3QgdXNiX3JvbGVfc3dpdGNoICpyb2xlX3N3OworCXN0cnVjdCB3b3Jr X3N0cnVjdCByb2xlX3dvcms7CiAJaW50IGlycVtFWFRDT05fSVJRX0VORF07CiAJc3RydWN0IGV4 dGNvbl9kZXYgKmVkZXY7CisJc3RydWN0IGV4dGNvbl9kZXYgKmlkX2V4dGNvbjsKKwlzdHJ1Y3Qg bm90aWZpZXJfYmxvY2sgaWRfbmI7CiAJdW5zaWduZWQgaW50IHByZXZpb3VzX2NhYmxlOworCWJv b2wgdmJ1c19hdHRhY2g7Cit9OworCitzdGF0aWMgY29uc3Qgc3RydWN0IHg4Nl9jcHVfaWQgY2hl cnJ5X3RyYWlsX2NwdV9pZHNbXSA9IHsKKwl7IFg4Nl9WRU5ET1JfSU5URUwsIDYsIElOVEVMX0ZB TTZfQVRPTV9BSVJNT05ULCBYODZfRkVBVFVSRV9BTlkgfSwKKwl7fQogfTsKIAogLyogUG93ZXIg dXAvZG93biByZWFzb24gc3RyaW5nIGFycmF5ICovCkBAIC0xMzcsMjAgKzE1NCw3NCBAQCBzdGF0 aWMgdm9pZCBheHAyODhfZXh0Y29uX2xvZ19yc2koc3RydWN0IGF4cDI4OF9leHRjb25faW5mbyAq aW5mbykKIAlyZWdtYXBfd3JpdGUoaW5mby0+cmVnbWFwLCBBWFAyODhfUFNfQk9PVF9SRUFTT05f UkVHLCBjbGVhcl9tYXNrKTsKIH0KIAotc3RhdGljIGludCBheHAyODhfaGFuZGxlX2NocmdfZGV0 X2V2ZW50KHN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8pCisvKgorICogVGhlIGJlbG93 IGNvZGUgdG8gY29udHJvbCB0aGUgVVNCIHJvbGUtc3dpdGNoIG9uIGRldmljZXMgd2l0aCBhbiBB WFAyODgKKyAqIG1heSBzZWVtIG91dCBvZiBwbGFjZSwgYnV0IHRoZXJlIGFyZSAyIHJlYXNvbnMg d2h5IHRoaXMgaXMgdGhlIGJlc3QgcGxhY2UKKyAqIHRvIGNvbnRyb2wgdGhlIFVTQiByb2xlLXN3 aXRjaCBvbiBzdWNoIGRldmljZXM6CisgKiAxKSBPbiBtYW55IGRldmljZXMgdGhlIFVTQiByb2xl IGlzIGNvbnRyb2xsZWQgYnkgQU1MIGNvZGUsIGJ1dCB0aGUgQU1MIGNvZGUKKyAqICAgIG9ubHkg c3dpdGNoZXMgYmV0d2VlbiB0aGUgaG9zdCBhbmQgbm9uZSByb2xlcywgYmVjYXVzZSBvZiBXaW5k b3dzIG5vdAorICogICAgcmVhbGx5IHVzaW5nIGRldmljZSBtb2RlLiBUbyBtYWtlIGRldmljZSBt b2RlIHdvcmsgd2UgbmVlZCB0byB0b2dnbGUKKyAqICAgIGJldHdlZW4gdGhlIG5vbmUvZGV2aWNl IHJvbGVzIGJhc2VkIG9uIFZidXMgcHJlc2VuY2UsIGFuZCB0aGlzIGRyaXZlcgorICogICAgZ2V0 cyBpbnRlcnJ1cHRzIG9uIFZidXMgaW5zZXJ0aW9uIC8gcmVtb3ZhbC4KKyAqIDIpIEluIG9yZGVy IGZvciBvdXIgQkMxLjIgY2hhcmdlciBkZXRlY3Rpb24gdG8gd29yayBwcm9wZXJseSB0aGUgcm9s ZQorICogICAgbXV4IG11c3QgYmUgcHJvcGVybHkgc2V0IHRvIGRldmljZSBtb2RlIGJlZm9yZSB3 ZSBkbyB0aGUgZGV0ZWN0aW9uLgorICovCisKKy8qIFJldHVybnMgdGhlIGlkLXBpbiB2YWx1ZSwg bm90ZSBwdWxsZWQgbG93IC8gZmFsc2UgPT0gaG9zdC1tb2RlICovCitzdGF0aWMgYm9vbCBheHAy ODhfZ2V0X2lkX3BpbihzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQogewotCWludCBy ZXQsIHN0YXQsIGNmZywgcHdyX3N0YXQ7Ci0JdTggY2hyZ190eXBlOwotCXVuc2lnbmVkIGludCBj YWJsZSA9IGluZm8tPnByZXZpb3VzX2NhYmxlOwotCWJvb2wgdmJ1c19hdHRhY2ggPSBmYWxzZTsK KwllbnVtIHVzYl9yb2xlIHJvbGU7CisKKwlpZiAoaW5mby0+aWRfZXh0Y29uKQorCQlyZXR1cm4g ZXh0Y29uX2dldF9zdGF0ZShpbmZvLT5pZF9leHRjb24sIEVYVENPTl9VU0JfSE9TVCkgPD0gMDsK KworCS8qIFdlIGNhbm5vdCBhY2Nlc3MgdGhlIGlkLXBpbiwgc2VlIHdoYXQgbW9kZSB0aGUgQU1M IGNvZGUgaGFzIHNldCAqLworCXJvbGUgPSB1c2Jfcm9sZV9zd2l0Y2hfZ2V0X3JvbGUoaW5mby0+ cm9sZV9zdyk7CisJcmV0dXJuIHJvbGUgIT0gVVNCX1JPTEVfSE9TVDsKK30KKworc3RhdGljIHZv aWQgYXhwMjg4X3VzYl9yb2xlX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQoreworCXN0 cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8gPQorCQljb250YWluZXJfb2Yod29yaywgc3Ry dWN0IGF4cDI4OF9leHRjb25faW5mbywgcm9sZV93b3JrKTsKKwllbnVtIHVzYl9yb2xlIHJvbGU7 CisJYm9vbCBpZF9waW47CisJaW50IHJldDsKKworCWlkX3BpbiA9IGF4cDI4OF9nZXRfaWRfcGlu KGluZm8pOworCWlmICghaWRfcGluKQorCQlyb2xlID0gVVNCX1JPTEVfSE9TVDsKKwllbHNlIGlm IChpbmZvLT52YnVzX2F0dGFjaCkKKwkJcm9sZSA9IFVTQl9ST0xFX0RFVklDRTsKKwllbHNlCisJ CXJvbGUgPSBVU0JfUk9MRV9OT05FOworCisJcmV0ID0gdXNiX3JvbGVfc3dpdGNoX3NldF9yb2xl KGluZm8tPnJvbGVfc3csIHJvbGUpOworCWlmIChyZXQpCisJCWRldl9lcnIoaW5mby0+ZGV2LCAi ZmFpbGVkIHRvIHNldCByb2xlOiAlZFxuIiwgcmV0KTsKK30KKworc3RhdGljIGJvb2wgYXhwMjg4 X2dldF92YnVzX2F0dGFjaChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQoreworCWlu dCByZXQsIHB3cl9zdGF0OwogCiAJcmV0ID0gcmVnbWFwX3JlYWQoaW5mby0+cmVnbWFwLCBBWFAy ODhfUFNfU1RBVF9SRUcsICZwd3Jfc3RhdCk7CiAJaWYgKHJldCA8IDApIHsKIAkJZGV2X2Vycihp bmZvLT5kZXYsICJmYWlsZWQgdG8gcmVhZCB2YnVzIHN0YXR1c1xuIik7Ci0JCXJldHVybiByZXQ7 CisJCXJldHVybiBmYWxzZTsKIAl9CiAKLQl2YnVzX2F0dGFjaCA9IChwd3Jfc3RhdCAmIFBTX1NU QVRfVkJVU19WQUxJRCk7CisJcmV0dXJuICEhKHB3cl9zdGF0ICYgUFNfU1RBVF9WQlVTX1ZBTElE KTsKK30KKworc3RhdGljIGludCBheHAyODhfaGFuZGxlX2NocmdfZGV0X2V2ZW50KHN0cnVjdCBh eHAyODhfZXh0Y29uX2luZm8gKmluZm8pCit7CisJaW50IHJldCwgc3RhdCwgY2ZnOworCXU4IGNo cmdfdHlwZTsKKwl1bnNpZ25lZCBpbnQgY2FibGUgPSBpbmZvLT5wcmV2aW91c19jYWJsZTsKKwli b29sIHZidXNfYXR0YWNoID0gZmFsc2U7CisKKwl2YnVzX2F0dGFjaCA9IGF4cDI4OF9nZXRfdmJ1 c19hdHRhY2goaW5mbyk7CiAJaWYgKCF2YnVzX2F0dGFjaCkKIAkJZ290byBub192YnVzOwogCkBA IC0yMDEsNiArMjcyLDEyIEBAIHN0YXRpYyBpbnQgYXhwMjg4X2hhbmRsZV9jaHJnX2RldF9ldmVu dChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQogCQlpbmZvLT5wcmV2aW91c19jYWJs ZSA9IGNhYmxlOwogCX0KIAorCWlmIChpbmZvLT5yb2xlX3N3ICYmIGluZm8tPnZidXNfYXR0YWNo ICE9IHZidXNfYXR0YWNoKSB7CisJCWluZm8tPnZidXNfYXR0YWNoID0gdmJ1c19hdHRhY2g7CisJ CS8qIFNldHRpbmcgdGhlIHJvbGUgY2FuIHRha2UgYSB3aGlsZSAqLworCQlxdWV1ZV93b3JrKHN5 c3RlbV9sb25nX3dxLCAmaW5mby0+cm9sZV93b3JrKTsKKwl9CisKIAlyZXR1cm4gMDsKIAogZGV2 X2RldF9yZXQ6CkBAIC0yMTAsNiArMjg3LDE4IEBAIHN0YXRpYyBpbnQgYXhwMjg4X2hhbmRsZV9j aHJnX2RldF9ldmVudChzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvKQogCXJldHVybiBy ZXQ7CiB9CiAKK3N0YXRpYyBpbnQgYXhwMjg4X2V4dGNvbl9pZF9ldnQoc3RydWN0IG5vdGlmaWVy X2Jsb2NrICpuYiwKKwkJCQl1bnNpZ25lZCBsb25nIGV2ZW50LCB2b2lkICpwYXJhbSkKK3sKKwlz dHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvID0KKwkJY29udGFpbmVyX29mKG5iLCBzdHJ1 Y3QgYXhwMjg4X2V4dGNvbl9pbmZvLCBpZF9uYik7CisKKwkvKiBXZSBtYXkgbm90IHNsZWVwIGFu ZCBzZXR0aW5nIHRoZSByb2xlIGNhbiB0YWtlIGEgd2hpbGUgKi8KKwlxdWV1ZV93b3JrKHN5c3Rl bV9sb25nX3dxLCAmaW5mby0+cm9sZV93b3JrKTsKKworCXJldHVybiBOT1RJRllfT0s7Cit9CisK IHN0YXRpYyBpcnFyZXR1cm5fdCBheHAyODhfZXh0Y29uX2lzcihpbnQgaXJxLCB2b2lkICpkYXRh KQogewogCXN0cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8gPSBkYXRhOwpAQCAtMjMxLDEw ICszMjAsMjAgQEAgc3RhdGljIHZvaWQgYXhwMjg4X2V4dGNvbl9lbmFibGUoc3RydWN0IGF4cDI4 OF9leHRjb25faW5mbyAqaW5mbykKIAkJCQkJQkNfR0xPQkFMX1JVTiwgQkNfR0xPQkFMX1JVTik7 CiB9CiAKK3N0YXRpYyB2b2lkIGF4cDI4OF9wdXRfcm9sZV9zdyh2b2lkICpkYXRhKQoreworCXN0 cnVjdCBheHAyODhfZXh0Y29uX2luZm8gKmluZm8gPSBkYXRhOworCisJY2FuY2VsX3dvcmtfc3lu YygmaW5mby0+cm9sZV93b3JrKTsKKwl1c2Jfcm9sZV9zd2l0Y2hfcHV0KGluZm8tPnJvbGVfc3cp OworfQorCiBzdGF0aWMgaW50IGF4cDI4OF9leHRjb25fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2Rl dmljZSAqcGRldikKIHsKIAlzdHJ1Y3QgYXhwMjg4X2V4dGNvbl9pbmZvICppbmZvOwogCXN0cnVj dCBheHAyMHhfZGV2ICpheHAyMHggPSBkZXZfZ2V0X2RydmRhdGEocGRldi0+ZGV2LnBhcmVudCk7 CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwljb25zdCBjaGFyICpuYW1lOwog CWludCByZXQsIGksIHBpcnE7CiAKIAlpbmZvID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsIHNp emVvZigqaW5mbyksIEdGUF9LRVJORUwpOwpAQCAtMjQ1LDkgKzM0NCwzMyBAQCBzdGF0aWMgaW50 IGF4cDI4OF9leHRjb25fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKIAlpbmZv LT5yZWdtYXAgPSBheHAyMHgtPnJlZ21hcDsKIAlpbmZvLT5yZWdtYXBfaXJxYyA9IGF4cDIweC0+ cmVnbWFwX2lycWM7CiAJaW5mby0+cHJldmlvdXNfY2FibGUgPSBFWFRDT05fTk9ORTsKKwlJTklU X1dPUksoJmluZm8tPnJvbGVfd29yaywgYXhwMjg4X3VzYl9yb2xlX3dvcmspOworCWluZm8tPmlk X25iLm5vdGlmaWVyX2NhbGwgPSBheHAyODhfZXh0Y29uX2lkX2V2dDsKIAogCXBsYXRmb3JtX3Nl dF9kcnZkYXRhKHBkZXYsIGluZm8pOwogCisJaW5mby0+cm9sZV9zdyA9IHVzYl9yb2xlX3N3aXRj aF9nZXQoZGV2KTsKKwlpZiAoSVNfRVJSKGluZm8tPnJvbGVfc3cpKQorCQlyZXR1cm4gUFRSX0VS UihpbmZvLT5yb2xlX3N3KTsKKwlpZiAoaW5mby0+cm9sZV9zdykgeworCQlyZXQgPSBkZXZtX2Fk ZF9hY3Rpb25fb3JfcmVzZXQoZGV2LCBheHAyODhfcHV0X3JvbGVfc3csIGluZm8pOworCQlpZiAo cmV0KQorCQkJcmV0dXJuIHJldDsKKworCQluYW1lID0gYWNwaV9kZXZfZ2V0X2ZpcnN0X21hdGNo X25hbWUoIklOVDM0OTYiLCBOVUxMLCAtMSk7CisJCWlmIChuYW1lKSB7CisJCQlpbmZvLT5pZF9l eHRjb24gPSBleHRjb25fZ2V0X2V4dGNvbl9kZXYobmFtZSk7CisJCQlpZiAoIWluZm8tPmlkX2V4 dGNvbikKKwkJCQlyZXR1cm4gLUVQUk9CRV9ERUZFUjsKKworCQkJZGV2X2luZm8oZGV2LCAiY29u dHJvbGxpbmcgVVNCIHJvbGVcbiIpOworCQl9IGVsc2UgeworCQkJZGV2X2luZm8oZGV2LCAiY29u dHJvbGxpbmcgVVNCIHJvbGUgYmFzZWQgb24gVmJ1cyBwcmVzZW5jZVxuIik7CisJCX0KKwl9CisK KwlpbmZvLT52YnVzX2F0dGFjaCA9IGF4cDI4OF9nZXRfdmJ1c19hdHRhY2goaW5mbyk7CisKIAlh eHAyODhfZXh0Y29uX2xvZ19yc2koaW5mbyk7CiAKIAkvKiBJbml0aWFsaXplIGV4dGNvbiBkZXZp Y2UgKi8KQEAgLTI4OSw2ICs0MTIsMTkgQEAgc3RhdGljIGludCBheHAyODhfZXh0Y29uX3Byb2Jl KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCiAJCX0KIAl9CiAKKwlpZiAoaW5mby0+aWRf ZXh0Y29uKSB7CisJCXJldCA9IGRldm1fZXh0Y29uX3JlZ2lzdGVyX25vdGlmaWVyX2FsbChkZXYs IGluZm8tPmlkX2V4dGNvbiwKKwkJCQkJCQkmaW5mby0+aWRfbmIpOworCQlpZiAocmV0KQorCQkJ cmV0dXJuIHJldDsKKwl9CisKKwkvKiBNYWtlIHN1cmUgdGhlIHJvbGUtc3cgaXMgc2V0IGNvcnJl Y3RseSBiZWZvcmUgZG9pbmcgQkMgZGV0ZWN0aW9uICovCisJaWYgKGluZm8tPnJvbGVfc3cpIHsK KwkJcXVldWVfd29yayhzeXN0ZW1fbG9uZ193cSwgJmluZm8tPnJvbGVfd29yayk7CisJCWZsdXNo X3dvcmsoJmluZm8tPnJvbGVfd29yayk7CisJfQorCiAJLyogU3RhcnQgY2hhcmdlciBjYWJsZSB0 eXBlIGRldGVjdGlvbiAqLwogCWF4cDI4OF9leHRjb25fZW5hYmxlKGluZm8pOwogCkBAIC0zMDgs OCArNDQ0LDMyIEBAIHN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGF4cDI4OF9leHRjb25f ZHJpdmVyID0gewogCQkubmFtZSA9ICJheHAyODhfZXh0Y29uIiwKIAl9LAogfTsKLW1vZHVsZV9w bGF0Zm9ybV9kcml2ZXIoYXhwMjg4X2V4dGNvbl9kcml2ZXIpOworCitzdGF0aWMgc3RydWN0IGRl dmljZV9jb25uZWN0aW9uIGF4cDI4OF9leHRjb25fcm9sZV9zd19jb25uID0geworCS5lbmRwb2lu dFswXSA9ICJheHAyODhfZXh0Y29uIiwKKwkuZW5kcG9pbnRbMV0gPSAiaW50ZWxfeGhjaV91c2Jf c3ctcm9sZS1zd2l0Y2giLAorCS5pZCA9ICJ1c2Itcm9sZS1zd2l0Y2giLAorfTsKKworc3RhdGlj IGludCBfX2luaXQgYXhwMjg4X2V4dGNvbl9pbml0KHZvaWQpCit7CisJaWYgKHg4Nl9tYXRjaF9j cHUoY2hlcnJ5X3RyYWlsX2NwdV9pZHMpKQorCQlkZXZpY2VfY29ubmVjdGlvbl9hZGQoJmF4cDI4 OF9leHRjb25fcm9sZV9zd19jb25uKTsKKworCXJldHVybiBwbGF0Zm9ybV9kcml2ZXJfcmVnaXN0 ZXIoJmF4cDI4OF9leHRjb25fZHJpdmVyKTsKK30KK21vZHVsZV9pbml0KGF4cDI4OF9leHRjb25f aW5pdCk7CisKK3N0YXRpYyB2b2lkIF9fZXhpdCBheHAyODhfZXh0Y29uX2V4aXQodm9pZCkKK3sK KwlpZiAoeDg2X21hdGNoX2NwdShjaGVycnlfdHJhaWxfY3B1X2lkcykpCisJCWRldmljZV9jb25u ZWN0aW9uX3JlbW92ZSgmYXhwMjg4X2V4dGNvbl9yb2xlX3N3X2Nvbm4pOworCisJcGxhdGZvcm1f ZHJpdmVyX3VucmVnaXN0ZXIoJmF4cDI4OF9leHRjb25fZHJpdmVyKTsKK30KK21vZHVsZV9leGl0 KGF4cDI4OF9leHRjb25fZXhpdCk7CiAKIE1PRFVMRV9BVVRIT1IoIlJhbWFrcmlzaG5hIFBhbGxh bGEgPHJhbWFrcmlzaG5hLnBhbGxhbGFAaW50ZWwuY29tPiIpOworTU9EVUxFX0FVVEhPUigiSGFu cyBkZSBHb2VkZSA8aGRlZ29lZGVAcmVkaGF0LmNvbT4iKTsKIE1PRFVMRV9ERVNDUklQVElPTigi WC1Qb3dlcnMgQVhQMjg4IGV4dGNvbiBkcml2ZXIiKTsKIE1PRFVMRV9MSUNFTlNFKCJHUEwgdjIi KTsK