From mboxrd@z Thu Jan 1 00:00:00 1970 From: Prakruthi Deepak Heragu Subject: [PATCH v1 2/2] Embedded USB Debugger (EUD) driver Date: Thu, 16 Aug 2018 17:05:48 -0700 Message-ID: <1534464348-8227-3-git-send-email-pheragu@codeaurora.org> References: <1534464348-8227-1-git-send-email-pheragu@codeaurora.org> Return-path: In-Reply-To: <1534464348-8227-1-git-send-email-pheragu@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org To: linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-usb@vger.kernel.org Cc: linux-kernel@vger.kernel.org, tsoni@codeaurora.org, ckadabi@codeaurora.org, bryanh@codeaurora.org, psodagud@codeaurora.org, rnayak@codeaurora.org, Satya Durga Srinivasu Prabhala , Prakruthi Deepak Heragu List-Id: linux-arm-msm@vger.kernel.org Add support for control peripheral of EUD (Embedded USB Debugger) to listen to events such as USB attach/detach, charger enable/disable, pet EUD to indicate software is functional. Signed-off-by: Satya Durga Srinivasu Prabhala Signed-off-by: Prakruthi Deepak Heragu --- drivers/soc/qcom/Kconfig | 12 ++ drivers/soc/qcom/Makefile | 1 + drivers/soc/qcom/eud.c | 340 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 353 insertions(+) create mode 100644 drivers/soc/qcom/eud.c diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 5856e79..12669ec 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -136,4 +136,16 @@ config QCOM_APR application processor and QDSP6. APR is used by audio driver to configure QDSP6 ASM, ADM and AFE modules. + +config QCOM_EUD + tristate "QTI Embedded USB Debugger (EUD)" + depends on ARCH_QCOM + help + The Embedded USB Debugger (EUD) driver is a driver for the + control peripheral which waits on events like USB attach/detach + and charger enable/disable. The control peripheral further helps + support the USB-based debug and trace capabilities. + This module enables support for Qualcomm Technologies, Inc. + Embedded USB Debugger (EUD). + If unsure, say N. endmenu diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 19dcf95..dd4701b 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_QCOM_SMP2P) += smp2p.o obj-$(CONFIG_QCOM_SMSM) += smsm.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_QCOM_APR) += apr.o +obj-$(CONFIG_QCOM_EUD) += eud.o diff --git a/drivers/soc/qcom/eud.c b/drivers/soc/qcom/eud.c new file mode 100644 index 0000000..b4c4235 --- /dev/null +++ b/drivers/soc/qcom/eud.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EUD_ENABLE_CMD 1 +#define EUD_DISABLE_CMD 0 + +#define EUD_REG_INT1_EN_MASK 0x0024 +#define EUD_REG_INT_STATUS_1 0x0044 +#define EUD_REG_CTL_OUT_1 0x0074 +#define EUD_REG_VBUS_INT_CLR 0x0080 +#define EUD_REG_CHGR_INT_CLR 0x0084 +#define EUD_REG_CSR_EUD_EN 0x1014 +#define EUD_REG_SW_ATTACH_DET 0x1018 + +#define EUD_INT_VBUS BIT(2) +#define EUD_INT_CHGR BIT(3) +#define EUD_INT_SAFE_MODE BIT(4) + +#define EUD_NR 1 + +struct eud_chip { + struct device *dev; + int eud_irq; + unsigned int extcon_id; + unsigned int int_status; + bool usb_attach; + bool chgr_enable; + void __iomem *eud_reg_base; + struct extcon_dev *extcon; + struct work_struct eud_work; +}; + +static const unsigned int eud_extcon_cable[] = { + EXTCON_USB, + EXTCON_CHG_USB_SDP, + EXTCON_NONE, +}; + +/* + * On the kernel command line specify eud.enable=1 to enable EUD. + * EUD is disabled by default. + */ +static int enable; +static bool eud_ready; +static struct eud_chip *eud_private; + +static void enable_eud(struct eud_chip *priv) +{ + struct power_supply *usb_psy = NULL; + union power_supply_propval pval = {0}; + union power_supply_propval tval = {0}; + int ret; + + usb_psy = power_supply_get_by_name("usb"); + if (!usb_psy) + return; + + ret = power_supply_get_property(usb_psy, + POWER_SUPPLY_PROP_PRESENT, &pval); + if (ret) + return; + + ret = power_supply_get_property(usb_psy, + POWER_SUPPLY_PROP_REAL_TYPE, &tval); + if (ret) + return; + + if (pval.intval && (tval.intval == POWER_SUPPLY_TYPE_USB || + tval.intval == POWER_SUPPLY_TYPE_USB_CDP)) { + /* write into CSR to enable EUD */ + writel_relaxed(BIT(0), priv->eud_reg_base + EUD_REG_CSR_EUD_EN); + /* Enable vbus, chgr & safe mode warning interrupts */ + writel_relaxed(EUD_INT_VBUS | EUD_INT_CHGR | EUD_INT_SAFE_MODE, + priv->eud_reg_base + EUD_REG_INT1_EN_MASK); + + /* Ensure Register Writes Complete */ + wmb(); + + /* + * Set the default cable state to usb connect and charger + * enable + */ + ret = extcon_set_state_sync(priv->extcon, EXTCON_USB, true); + if (ret) + return; + ret = extcon_set_state_sync(priv->extcon, + EXTCON_CHG_USB_SDP, true); + if (ret) + return; + } else { + return; + } + +} + +static void disable_eud(struct eud_chip *priv) +{ + /* write into CSR to disable EUD */ + writel_relaxed(0, priv->eud_reg_base + EUD_REG_CSR_EUD_EN); +} + +static int param_eud_set(const char *val, const struct kernel_param *kp) +{ + int enable = 0; + + if (sscanf(val, "%du", &enable) != 1) + return -EINVAL; + + if (enable != EUD_ENABLE_CMD && enable != EUD_DISABLE_CMD) + return -EINVAL; + + *((uint *)kp->arg) = enable; + if (!eud_ready) + return 0; + + if (enable == EUD_ENABLE_CMD) + enable_eud(eud_private); + else if (enable == EUD_DISABLE_CMD) + disable_eud(eud_private); + + return 0; +} + +static const struct kernel_param_ops eud_param_ops = { + .set = param_eud_set, + .get = param_get_int, +}; + +module_param_cb(enable, &eud_param_ops, &enable, 0644); + +static void eud_event_notifier(struct work_struct *eud_work) +{ + struct eud_chip *chip = container_of(eud_work, struct eud_chip, + eud_work); + int ret; + + if (chip->int_status == EUD_INT_VBUS) { + ret = extcon_set_state_sync(chip->extcon, chip->extcon_id, + chip->usb_attach); + if (ret) + return; + } else if (chip->int_status == EUD_INT_CHGR) { + ret = extcon_set_state_sync(chip->extcon, chip->extcon_id, + chip->chgr_enable); + if (ret) + return; + } +} + +static void usb_attach_detach(struct eud_chip *chip) +{ + u32 reg; + + chip->extcon_id = EXTCON_USB; + /* read ctl_out_1[4] to find USB attach or detach event */ + reg = readl_relaxed(chip->eud_reg_base + EUD_REG_CTL_OUT_1); + if (reg & BIT(4)) + chip->usb_attach = true; + else + chip->usb_attach = false; + + schedule_work(&chip->eud_work); + + /* set and clear vbus_int_clr[0] to clear interrupt */ + writel_relaxed(BIT(0), chip->eud_reg_base + EUD_REG_VBUS_INT_CLR); + /* Ensure Register Writes Complete */ + wmb(); + writel_relaxed(0, chip->eud_reg_base + EUD_REG_VBUS_INT_CLR); +} + +static void chgr_enable_disable(struct eud_chip *chip) +{ + u32 reg; + + chip->extcon_id = EXTCON_CHG_USB_SDP; + /* read ctl_out_1[6] to find charger enable or disable event */ + reg = readl_relaxed(chip->eud_reg_base + EUD_REG_CTL_OUT_1); + if (reg & BIT(6)) + chip->chgr_enable = true; + else + chip->chgr_enable = false; + + schedule_work(&chip->eud_work); + + /* set and clear chgr_int_clr[0] to clear interrupt */ + writel_relaxed(BIT(0), chip->eud_reg_base + EUD_REG_CHGR_INT_CLR); + /* Ensure Register Writes Complete */ + wmb(); + writel_relaxed(0, chip->eud_reg_base + EUD_REG_CHGR_INT_CLR); +} + +static void pet_eud(struct eud_chip *chip) +{ + u32 reg; + + /* read sw_attach_det[0] to find attach/detach event */ + reg = readl_relaxed(chip->eud_reg_base + EUD_REG_SW_ATTACH_DET); + if (reg & BIT(0)) { + /* Detach & Attach pet for EUD */ + writel_relaxed(0, chip->eud_reg_base + EUD_REG_SW_ATTACH_DET); + /* Ensure Register Writes Complete */ + wmb(); + /* Delay to make sure detach pet is done before attach pet */ + udelay(100); + writel_relaxed(BIT(0), chip->eud_reg_base + + EUD_REG_SW_ATTACH_DET); + /* Ensure Register Writes Complete */ + wmb(); + } else { + /* Attach pet for EUD */ + writel_relaxed(BIT(0), chip->eud_reg_base + + EUD_REG_SW_ATTACH_DET); + /* Ensure Register Writes Complete */ + wmb(); + } +} + +static irqreturn_t handle_eud_irq(int irq, void *data) +{ + struct eud_chip *chip = data; + u32 reg; + + /* read status register and find out which interrupt triggered */ + reg = readl_relaxed(chip->eud_reg_base + EUD_REG_INT_STATUS_1); + if (reg & EUD_INT_VBUS) { + chip->int_status = EUD_INT_VBUS; + usb_attach_detach(chip); + } else if (reg & EUD_INT_CHGR) { + chip->int_status = EUD_INT_CHGR; + chgr_enable_disable(chip); + } else if (reg & EUD_INT_SAFE_MODE) { + pet_eud(chip); + } else { + return IRQ_NONE; + } + + return IRQ_HANDLED; +} + +static int msm_eud_probe(struct platform_device *pdev) +{ + struct eud_chip *chip; + struct resource *res; + int ret; + + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) { + ret = -ENOMEM; + return ret; + } + + platform_set_drvdata(pdev, chip); + + chip->extcon = devm_extcon_dev_allocate(&pdev->dev, eud_extcon_cable); + if (IS_ERR(chip->extcon)) + return PTR_ERR(chip->extcon); + + ret = devm_extcon_dev_register(&pdev->dev, chip->extcon); + if (ret) + return ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENOMEM; + return ret; + } + + chip->eud_reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(chip->eud_reg_base)) + return PTR_ERR(chip->eud_reg_base); + + chip->eud_irq = platform_get_irq(pdev, 0); + + ret = devm_request_irq(&pdev->dev, chip->eud_irq, handle_eud_irq, + IRQF_TRIGGER_HIGH, NULL, chip); + if (ret) + return ret; + + device_init_wakeup(&pdev->dev, true); + enable_irq_wake(chip->eud_irq); + + INIT_WORK(&chip->eud_work, eud_event_notifier); + + eud_private = chip; + eud_ready = true; + + /* Enable EUD */ + if (enable) + enable_eud(eud_private); + + return 0; +} + +static int msm_eud_remove(struct platform_device *pdev) +{ + struct eud_chip *chip = platform_get_drvdata(pdev); + + if (enable) + disable_eud(eud_private); + device_init_wakeup(&pdev->dev, false); + disable_irq_wake(chip->eud_irq); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id msm_eud_dt_match[] = { + {.compatible = "qcom,msm-eud"}, + {}, +}; +MODULE_DEVICE_TABLE(of, msm_eud_dt_match); + +static struct platform_driver msm_eud_driver = { + .probe = msm_eud_probe, + .remove = msm_eud_remove, + .driver = { + .name = "msm-eud", + .of_match_table = msm_eud_dt_match, + }, +}; +module_platform_driver(msm_eud_driver); + +MODULE_DESCRIPTION("QTI EUD driver"); +MODULE_LICENSE("GPL v2"); -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project 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: [v1,2/2] Embedded USB Debugger (EUD) driver From: Prakruthi Deepak Heragu Message-Id: <1534464348-8227-3-git-send-email-pheragu@codeaurora.org> Date: Thu, 16 Aug 2018 17:05:48 -0700 To: linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-usb@vger.kernel.org Cc: linux-kernel@vger.kernel.org, tsoni@codeaurora.org, ckadabi@codeaurora.org, bryanh@codeaurora.org, psodagud@codeaurora.org, rnayak@codeaurora.org, Satya Durga Srinivasu Prabhala , Prakruthi Deepak Heragu List-ID: QWRkIHN1cHBvcnQgZm9yIGNvbnRyb2wgcGVyaXBoZXJhbCBvZiBFVUQgKEVtYmVkZGVkIFVTQiBE ZWJ1Z2dlcikgdG8KbGlzdGVuIHRvIGV2ZW50cyBzdWNoIGFzIFVTQiBhdHRhY2gvZGV0YWNoLCBj aGFyZ2VyIGVuYWJsZS9kaXNhYmxlLCBwZXQKRVVEIHRvIGluZGljYXRlIHNvZnR3YXJlIGlzIGZ1 bmN0aW9uYWwuCgpTaWduZWQtb2ZmLWJ5OiBTYXR5YSBEdXJnYSBTcmluaXZhc3UgUHJhYmhhbGEg PHNhdHlhcEBjb2RlYXVyb3JhLm9yZz4KU2lnbmVkLW9mZi1ieTogUHJha3J1dGhpIERlZXBhayBI ZXJhZ3UgPHBoZXJhZ3VAY29kZWF1cm9yYS5vcmc+Ci0tLQogZHJpdmVycy9zb2MvcWNvbS9LY29u ZmlnICB8ICAxMiArKwogZHJpdmVycy9zb2MvcWNvbS9NYWtlZmlsZSB8ICAgMSArCiBkcml2ZXJz L3NvYy9xY29tL2V1ZC5jICAgIHwgMzQwICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysKIDMgZmlsZXMgY2hhbmdlZCwgMzUzIGluc2VydGlvbnMoKykKIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3NvYy9xY29tL2V1ZC5jCgpkaWZmIC0tZ2l0IGEvZHJpdmVy cy9zb2MvcWNvbS9LY29uZmlnIGIvZHJpdmVycy9zb2MvcWNvbS9LY29uZmlnCmluZGV4IDU4NTZl NzkuLjEyNjY5ZWMgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvc29jL3Fjb20vS2NvbmZpZworKysgYi9k cml2ZXJzL3NvYy9xY29tL0tjb25maWcKQEAgLTEzNiw0ICsxMzYsMTYgQEAgY29uZmlnIFFDT01f QVBSCiAgICAgICAgICAgYXBwbGljYXRpb24gcHJvY2Vzc29yIGFuZCBRRFNQNi4gQVBSIGlzCiAg ICAgICAgICAgdXNlZCBieSBhdWRpbyBkcml2ZXIgdG8gY29uZmlndXJlIFFEU1A2CiAgICAgICAg ICAgQVNNLCBBRE0gYW5kIEFGRSBtb2R1bGVzLgorCitjb25maWcgUUNPTV9FVUQKKwl0cmlzdGF0 ZSAiUVRJIEVtYmVkZGVkIFVTQiBEZWJ1Z2dlciAoRVVEKSIKKwlkZXBlbmRzIG9uIEFSQ0hfUUNP TQorCWhlbHAKKwkgIFRoZSBFbWJlZGRlZCBVU0IgRGVidWdnZXIgKEVVRCkgZHJpdmVyIGlzIGEg ZHJpdmVyIGZvciB0aGUKKwkgIGNvbnRyb2wgcGVyaXBoZXJhbCB3aGljaCB3YWl0cyBvbiBldmVu dHMgbGlrZSBVU0IgYXR0YWNoL2RldGFjaAorCSAgYW5kIGNoYXJnZXIgZW5hYmxlL2Rpc2FibGUu IFRoZSBjb250cm9sIHBlcmlwaGVyYWwgZnVydGhlciBoZWxwcworCSAgc3VwcG9ydCB0aGUgVVNC LWJhc2VkIGRlYnVnIGFuZCB0cmFjZSBjYXBhYmlsaXRpZXMuCisJICBUaGlzIG1vZHVsZSBlbmFi bGVzIHN1cHBvcnQgZm9yIFF1YWxjb21tIFRlY2hub2xvZ2llcywgSW5jLgorCSAgRW1iZWRkZWQg VVNCIERlYnVnZ2VyIChFVUQpLgorCSAgSWYgdW5zdXJlLCBzYXkgTi4KIGVuZG1lbnUKZGlmZiAt LWdpdCBhL2RyaXZlcnMvc29jL3Fjb20vTWFrZWZpbGUgYi9kcml2ZXJzL3NvYy9xY29tL01ha2Vm aWxlCmluZGV4IDE5ZGNmOTUuLmRkNDcwMWIgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvc29jL3Fjb20v TWFrZWZpbGUKKysrIGIvZHJpdmVycy9zb2MvcWNvbS9NYWtlZmlsZQpAQCAtMTUsMyArMTUsNCBA QCBvYmotJChDT05GSUdfUUNPTV9TTVAyUCkJKz0gc21wMnAubwogb2JqLSQoQ09ORklHX1FDT01f U01TTSkJKz0gc21zbS5vCiBvYmotJChDT05GSUdfUUNPTV9XQ05TU19DVFJMKSArPSB3Y25zc19j dHJsLm8KIG9iai0kKENPTkZJR19RQ09NX0FQUikgKz0gYXByLm8KK29iai0kKENPTkZJR19RQ09N X0VVRCkgKz0gZXVkLm8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvc29jL3Fjb20vZXVkLmMgYi9kcml2 ZXJzL3NvYy9xY29tL2V1ZC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI0 YzQyMzUKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL3NvYy9xY29tL2V1ZC5jCkBAIC0wLDAg KzEsMzQwIEBACisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAorLyoKKyAqIENv cHlyaWdodCAoYykgMjAxNi0yMDE4LCBUaGUgTGludXggRm91bmRhdGlvbi4gQWxsIHJpZ2h0cyBy ZXNlcnZlZC4KKyAqLworCisjaW5jbHVkZSA8bGludXgva2VybmVsLmg+CisjaW5jbHVkZSA8bGlu dXgvbW9kdWxlLmg+CisjaW5jbHVkZSA8bGludXgvc2xhYi5oPgorI2luY2x1ZGUgPGxpbnV4L2lu dGVycnVwdC5oPgorI2luY2x1ZGUgPGxpbnV4L2Vyci5oPgorI2luY2x1ZGUgPGxpbnV4L3BsYXRm b3JtX2RldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L2V4dGNvbi5oPgorI2luY2x1ZGUgPGxpbnV4 L2RlbGF5Lmg+CisjaW5jbHVkZSA8bGludXgvc3lzZnMuaD4KKyNpbmNsdWRlIDxsaW51eC9pby5o PgorI2luY2x1ZGUgPGxpbnV4L2JpdG9wcy5oPgorI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5o PgorI2luY2x1ZGUgPGxpbnV4L3Bvd2VyX3N1cHBseS5oPgorCisjZGVmaW5lIEVVRF9FTkFCTEVf Q01EIDEKKyNkZWZpbmUgRVVEX0RJU0FCTEVfQ01EIDAKKworI2RlZmluZSBFVURfUkVHX0lOVDFf RU5fTUFTSwkweDAwMjQKKyNkZWZpbmUgRVVEX1JFR19JTlRfU1RBVFVTXzEJMHgwMDQ0CisjZGVm aW5lIEVVRF9SRUdfQ1RMX09VVF8xCTB4MDA3NAorI2RlZmluZSBFVURfUkVHX1ZCVVNfSU5UX0NM UgkweDAwODAKKyNkZWZpbmUgRVVEX1JFR19DSEdSX0lOVF9DTFIJMHgwMDg0CisjZGVmaW5lIEVV RF9SRUdfQ1NSX0VVRF9FTgkweDEwMTQKKyNkZWZpbmUgRVVEX1JFR19TV19BVFRBQ0hfREVUCTB4 MTAxOAorCisjZGVmaW5lIEVVRF9JTlRfVkJVUwkJQklUKDIpCisjZGVmaW5lIEVVRF9JTlRfQ0hH UgkJQklUKDMpCisjZGVmaW5lIEVVRF9JTlRfU0FGRV9NT0RFCUJJVCg0KQorCisjZGVmaW5lIEVV RF9OUgkJCTEKKworc3RydWN0IGV1ZF9jaGlwIHsKKwlzdHJ1Y3QgZGV2aWNlCQkJKmRldjsKKwlp bnQJCQkJZXVkX2lycTsKKwl1bnNpZ25lZCBpbnQJCQlleHRjb25faWQ7CisJdW5zaWduZWQgaW50 CQkJaW50X3N0YXR1czsKKwlib29sCQkJCXVzYl9hdHRhY2g7CisJYm9vbAkJCQljaGdyX2VuYWJs ZTsKKwl2b2lkIF9faW9tZW0JCQkqZXVkX3JlZ19iYXNlOworCXN0cnVjdCBleHRjb25fZGV2CQkq ZXh0Y29uOworCXN0cnVjdCB3b3JrX3N0cnVjdAkJZXVkX3dvcms7Cit9OworCitzdGF0aWMgY29u c3QgdW5zaWduZWQgaW50IGV1ZF9leHRjb25fY2FibGVbXSA9IHsKKwlFWFRDT05fVVNCLAorCUVY VENPTl9DSEdfVVNCX1NEUCwKKwlFWFRDT05fTk9ORSwKK307CisKKy8qCisgKiBPbiB0aGUga2Vy bmVsIGNvbW1hbmQgbGluZSBzcGVjaWZ5IGV1ZC5lbmFibGU9MSB0byBlbmFibGUgRVVELgorICog RVVEIGlzIGRpc2FibGVkIGJ5IGRlZmF1bHQuCisgKi8KK3N0YXRpYyBpbnQgZW5hYmxlOworc3Rh dGljIGJvb2wgZXVkX3JlYWR5Oworc3RhdGljIHN0cnVjdCBldWRfY2hpcCAqZXVkX3ByaXZhdGU7 CisKK3N0YXRpYyB2b2lkIGVuYWJsZV9ldWQoc3RydWN0IGV1ZF9jaGlwICpwcml2KQoreworCXN0 cnVjdCBwb3dlcl9zdXBwbHkgKnVzYl9wc3kgPSBOVUxMOworCXVuaW9uIHBvd2VyX3N1cHBseV9w cm9wdmFsIHB2YWwgPSB7MH07CisJdW5pb24gcG93ZXJfc3VwcGx5X3Byb3B2YWwgdHZhbCA9IHsw fTsKKwlpbnQgcmV0OworCisJdXNiX3BzeSA9IHBvd2VyX3N1cHBseV9nZXRfYnlfbmFtZSgidXNi Iik7CisJaWYgKCF1c2JfcHN5KQorCQlyZXR1cm47CisKKwlyZXQgPSBwb3dlcl9zdXBwbHlfZ2V0 X3Byb3BlcnR5KHVzYl9wc3ksCisJCQlQT1dFUl9TVVBQTFlfUFJPUF9QUkVTRU5ULCAmcHZhbCk7 CisJaWYgKHJldCkKKwkJcmV0dXJuOworCisJcmV0ID0gcG93ZXJfc3VwcGx5X2dldF9wcm9wZXJ0 eSh1c2JfcHN5LAorCQkJUE9XRVJfU1VQUExZX1BST1BfUkVBTF9UWVBFLCAmdHZhbCk7CisJaWYg KHJldCkKKwkJcmV0dXJuOworCisJaWYgKHB2YWwuaW50dmFsICYmICh0dmFsLmludHZhbCA9PSBQ T1dFUl9TVVBQTFlfVFlQRV9VU0IgfHwKKwkgICAgdHZhbC5pbnR2YWwgPT0gUE9XRVJfU1VQUExZ X1RZUEVfVVNCX0NEUCkpIHsKKwkJLyogd3JpdGUgaW50byBDU1IgdG8gZW5hYmxlIEVVRCAqLwor CQl3cml0ZWxfcmVsYXhlZChCSVQoMCksIHByaXYtPmV1ZF9yZWdfYmFzZSArIEVVRF9SRUdfQ1NS X0VVRF9FTik7CisJCS8qIEVuYWJsZSB2YnVzLCBjaGdyICYgc2FmZSBtb2RlIHdhcm5pbmcgaW50 ZXJydXB0cyAqLworCQl3cml0ZWxfcmVsYXhlZChFVURfSU5UX1ZCVVMgfCBFVURfSU5UX0NIR1Ig fCBFVURfSU5UX1NBRkVfTU9ERSwKKwkJCQlwcml2LT5ldWRfcmVnX2Jhc2UgKyBFVURfUkVHX0lO VDFfRU5fTUFTSyk7CisKKwkJLyogRW5zdXJlIFJlZ2lzdGVyIFdyaXRlcyBDb21wbGV0ZSAqLwor CQl3bWIoKTsKKworCQkvKgorCQkgKiBTZXQgdGhlIGRlZmF1bHQgY2FibGUgc3RhdGUgdG8gdXNi IGNvbm5lY3QgYW5kIGNoYXJnZXIKKwkJICogZW5hYmxlCisJCSAqLworCQlyZXQgPSBleHRjb25f c2V0X3N0YXRlX3N5bmMocHJpdi0+ZXh0Y29uLCBFWFRDT05fVVNCLCB0cnVlKTsKKwkJaWYgKHJl dCkKKwkJCXJldHVybjsKKwkJcmV0ID0gZXh0Y29uX3NldF9zdGF0ZV9zeW5jKHByaXYtPmV4dGNv biwKKwkJCQlFWFRDT05fQ0hHX1VTQl9TRFAsIHRydWUpOworCQlpZiAocmV0KQorCQkJcmV0dXJu OworCX0gZWxzZSB7CisJCXJldHVybjsKKwl9CisKK30KKworc3RhdGljIHZvaWQgZGlzYWJsZV9l dWQoc3RydWN0IGV1ZF9jaGlwICpwcml2KQoreworCS8qIHdyaXRlIGludG8gQ1NSIHRvIGRpc2Fi bGUgRVVEICovCisJd3JpdGVsX3JlbGF4ZWQoMCwgcHJpdi0+ZXVkX3JlZ19iYXNlICsgRVVEX1JF R19DU1JfRVVEX0VOKTsKK30KKworc3RhdGljIGludCBwYXJhbV9ldWRfc2V0KGNvbnN0IGNoYXIg KnZhbCwgY29uc3Qgc3RydWN0IGtlcm5lbF9wYXJhbSAqa3ApCit7CisJaW50IGVuYWJsZSA9IDA7 CisKKwlpZiAoc3NjYW5mKHZhbCwgIiVkdSIsICZlbmFibGUpICE9IDEpCisJCXJldHVybiAtRUlO VkFMOworCisJaWYgKGVuYWJsZSAhPSBFVURfRU5BQkxFX0NNRCAmJiBlbmFibGUgIT0gRVVEX0RJ U0FCTEVfQ01EKQorCQlyZXR1cm4gLUVJTlZBTDsKKworCSooKHVpbnQgKilrcC0+YXJnKSA9IGVu YWJsZTsKKwlpZiAoIWV1ZF9yZWFkeSkKKwkJcmV0dXJuIDA7CisKKwlpZiAoZW5hYmxlID09IEVV RF9FTkFCTEVfQ01EKQorCQllbmFibGVfZXVkKGV1ZF9wcml2YXRlKTsKKwllbHNlIGlmIChlbmFi bGUgPT0gRVVEX0RJU0FCTEVfQ01EKQorCQlkaXNhYmxlX2V1ZChldWRfcHJpdmF0ZSk7CisKKwly ZXR1cm4gMDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBrZXJuZWxfcGFyYW1fb3BzIGV1ZF9w YXJhbV9vcHMgPSB7CisJLnNldCA9IHBhcmFtX2V1ZF9zZXQsCisJLmdldCA9IHBhcmFtX2dldF9p bnQsCit9OworCittb2R1bGVfcGFyYW1fY2IoZW5hYmxlLCAmZXVkX3BhcmFtX29wcywgJmVuYWJs ZSwgMDY0NCk7CisKK3N0YXRpYyB2b2lkIGV1ZF9ldmVudF9ub3RpZmllcihzdHJ1Y3Qgd29ya19z dHJ1Y3QgKmV1ZF93b3JrKQoreworCXN0cnVjdCBldWRfY2hpcCAqY2hpcCA9IGNvbnRhaW5lcl9v ZihldWRfd29yaywgc3RydWN0IGV1ZF9jaGlwLAorCQkJCQlldWRfd29yayk7CisJaW50IHJldDsK KworCWlmIChjaGlwLT5pbnRfc3RhdHVzID09IEVVRF9JTlRfVkJVUykgeworCQlyZXQgPSBleHRj b25fc2V0X3N0YXRlX3N5bmMoY2hpcC0+ZXh0Y29uLCBjaGlwLT5leHRjb25faWQsCisJCQkJCWNo aXAtPnVzYl9hdHRhY2gpOworCQlpZiAocmV0KQorCQkJcmV0dXJuOworCX0gZWxzZSBpZiAoY2hp cC0+aW50X3N0YXR1cyA9PSBFVURfSU5UX0NIR1IpIHsKKwkJcmV0ID0gZXh0Y29uX3NldF9zdGF0 ZV9zeW5jKGNoaXAtPmV4dGNvbiwgY2hpcC0+ZXh0Y29uX2lkLAorCQkJCQljaGlwLT5jaGdyX2Vu YWJsZSk7CisJCWlmIChyZXQpCisJCQlyZXR1cm47CisJfQorfQorCitzdGF0aWMgdm9pZCB1c2Jf YXR0YWNoX2RldGFjaChzdHJ1Y3QgZXVkX2NoaXAgKmNoaXApCit7CisJdTMyIHJlZzsKKworCWNo aXAtPmV4dGNvbl9pZCA9IEVYVENPTl9VU0I7CisJLyogcmVhZCBjdGxfb3V0XzFbNF0gdG8gZmlu ZCBVU0IgYXR0YWNoIG9yIGRldGFjaCBldmVudCAqLworCXJlZyA9IHJlYWRsX3JlbGF4ZWQoY2hp cC0+ZXVkX3JlZ19iYXNlICsgRVVEX1JFR19DVExfT1VUXzEpOworCWlmIChyZWcgJiBCSVQoNCkp CisJCWNoaXAtPnVzYl9hdHRhY2ggPSB0cnVlOworCWVsc2UKKwkJY2hpcC0+dXNiX2F0dGFjaCA9 IGZhbHNlOworCisJc2NoZWR1bGVfd29yaygmY2hpcC0+ZXVkX3dvcmspOworCisJLyogc2V0IGFu ZCBjbGVhciB2YnVzX2ludF9jbHJbMF0gdG8gY2xlYXIgaW50ZXJydXB0ICovCisJd3JpdGVsX3Jl bGF4ZWQoQklUKDApLCBjaGlwLT5ldWRfcmVnX2Jhc2UgKyBFVURfUkVHX1ZCVVNfSU5UX0NMUik7 CisJLyogRW5zdXJlIFJlZ2lzdGVyIFdyaXRlcyBDb21wbGV0ZSAqLworCXdtYigpOworCXdyaXRl bF9yZWxheGVkKDAsIGNoaXAtPmV1ZF9yZWdfYmFzZSArIEVVRF9SRUdfVkJVU19JTlRfQ0xSKTsK K30KKworc3RhdGljIHZvaWQgY2hncl9lbmFibGVfZGlzYWJsZShzdHJ1Y3QgZXVkX2NoaXAgKmNo aXApCit7CisJdTMyIHJlZzsKKworCWNoaXAtPmV4dGNvbl9pZCA9IEVYVENPTl9DSEdfVVNCX1NE UDsKKwkvKiByZWFkIGN0bF9vdXRfMVs2XSB0byBmaW5kIGNoYXJnZXIgZW5hYmxlIG9yIGRpc2Fi bGUgZXZlbnQgKi8KKwlyZWcgPSByZWFkbF9yZWxheGVkKGNoaXAtPmV1ZF9yZWdfYmFzZSArIEVV RF9SRUdfQ1RMX09VVF8xKTsKKwlpZiAocmVnICYgQklUKDYpKQorCQljaGlwLT5jaGdyX2VuYWJs ZSA9IHRydWU7CisJZWxzZQorCQljaGlwLT5jaGdyX2VuYWJsZSA9IGZhbHNlOworCisJc2NoZWR1 bGVfd29yaygmY2hpcC0+ZXVkX3dvcmspOworCisJLyogc2V0IGFuZCBjbGVhciBjaGdyX2ludF9j bHJbMF0gdG8gY2xlYXIgaW50ZXJydXB0ICovCisJd3JpdGVsX3JlbGF4ZWQoQklUKDApLCBjaGlw LT5ldWRfcmVnX2Jhc2UgKyBFVURfUkVHX0NIR1JfSU5UX0NMUik7CisJLyogRW5zdXJlIFJlZ2lz dGVyIFdyaXRlcyBDb21wbGV0ZSAqLworCXdtYigpOworCXdyaXRlbF9yZWxheGVkKDAsIGNoaXAt PmV1ZF9yZWdfYmFzZSArIEVVRF9SRUdfQ0hHUl9JTlRfQ0xSKTsKK30KKworc3RhdGljIHZvaWQg cGV0X2V1ZChzdHJ1Y3QgZXVkX2NoaXAgKmNoaXApCit7CisJdTMyIHJlZzsKKworCS8qIHJlYWQg c3dfYXR0YWNoX2RldFswXSB0byBmaW5kIGF0dGFjaC9kZXRhY2ggZXZlbnQgKi8KKwlyZWcgPSBy ZWFkbF9yZWxheGVkKGNoaXAtPmV1ZF9yZWdfYmFzZSArIEVVRF9SRUdfU1dfQVRUQUNIX0RFVCk7 CisJaWYgKHJlZyAmIEJJVCgwKSkgeworCQkvKiBEZXRhY2ggJiBBdHRhY2ggcGV0IGZvciBFVUQg Ki8KKwkJd3JpdGVsX3JlbGF4ZWQoMCwgY2hpcC0+ZXVkX3JlZ19iYXNlICsgRVVEX1JFR19TV19B VFRBQ0hfREVUKTsKKwkJLyogRW5zdXJlIFJlZ2lzdGVyIFdyaXRlcyBDb21wbGV0ZSAqLworCQl3 bWIoKTsKKwkJLyogRGVsYXkgdG8gbWFrZSBzdXJlIGRldGFjaCBwZXQgaXMgZG9uZSBiZWZvcmUg YXR0YWNoIHBldCAqLworCQl1ZGVsYXkoMTAwKTsKKwkJd3JpdGVsX3JlbGF4ZWQoQklUKDApLCBj aGlwLT5ldWRfcmVnX2Jhc2UgKworCQkJCQlFVURfUkVHX1NXX0FUVEFDSF9ERVQpOworCQkvKiBF bnN1cmUgUmVnaXN0ZXIgV3JpdGVzIENvbXBsZXRlICovCisJCXdtYigpOworCX0gZWxzZSB7CisJ CS8qIEF0dGFjaCBwZXQgZm9yIEVVRCAqLworCQl3cml0ZWxfcmVsYXhlZChCSVQoMCksIGNoaXAt PmV1ZF9yZWdfYmFzZSArCisJCQkJCUVVRF9SRUdfU1dfQVRUQUNIX0RFVCk7CisJCS8qIEVuc3Vy ZSBSZWdpc3RlciBXcml0ZXMgQ29tcGxldGUgKi8KKwkJd21iKCk7CisJfQorfQorCitzdGF0aWMg aXJxcmV0dXJuX3QgaGFuZGxlX2V1ZF9pcnEoaW50IGlycSwgdm9pZCAqZGF0YSkKK3sKKwlzdHJ1 Y3QgZXVkX2NoaXAgKmNoaXAgPSBkYXRhOworCXUzMiByZWc7CisKKwkvKiByZWFkIHN0YXR1cyBy ZWdpc3RlciBhbmQgZmluZCBvdXQgd2hpY2ggaW50ZXJydXB0IHRyaWdnZXJlZCAqLworCXJlZyA9 IHJlYWRsX3JlbGF4ZWQoY2hpcC0+ZXVkX3JlZ19iYXNlICsgRVVEX1JFR19JTlRfU1RBVFVTXzEp OworCWlmIChyZWcgJiBFVURfSU5UX1ZCVVMpIHsKKwkJY2hpcC0+aW50X3N0YXR1cyA9IEVVRF9J TlRfVkJVUzsKKwkJdXNiX2F0dGFjaF9kZXRhY2goY2hpcCk7CisJfSBlbHNlIGlmIChyZWcgJiBF VURfSU5UX0NIR1IpIHsKKwkJY2hpcC0+aW50X3N0YXR1cyA9IEVVRF9JTlRfQ0hHUjsKKwkJY2hn cl9lbmFibGVfZGlzYWJsZShjaGlwKTsKKwl9IGVsc2UgaWYgKHJlZyAmIEVVRF9JTlRfU0FGRV9N T0RFKSB7CisJCXBldF9ldWQoY2hpcCk7CisJfSBlbHNlIHsKKwkJcmV0dXJuIElSUV9OT05FOwor CX0KKworCXJldHVybiBJUlFfSEFORExFRDsKK30KKworc3RhdGljIGludCBtc21fZXVkX3Byb2Jl KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3RydWN0IGV1ZF9jaGlwICpjaGlw OworCXN0cnVjdCByZXNvdXJjZSAqcmVzOworCWludCByZXQ7CisKKwljaGlwID0gZGV2bV9remFs bG9jKCZwZGV2LT5kZXYsIHNpemVvZigqY2hpcCksIEdGUF9LRVJORUwpOworCWlmICghY2hpcCkg eworCQlyZXQgPSAtRU5PTUVNOworCQlyZXR1cm4gcmV0OworCX0KKworCXBsYXRmb3JtX3NldF9k cnZkYXRhKHBkZXYsIGNoaXApOworCisJY2hpcC0+ZXh0Y29uID0gZGV2bV9leHRjb25fZGV2X2Fs bG9jYXRlKCZwZGV2LT5kZXYsIGV1ZF9leHRjb25fY2FibGUpOworCWlmIChJU19FUlIoY2hpcC0+ ZXh0Y29uKSkKKwkJcmV0dXJuIFBUUl9FUlIoY2hpcC0+ZXh0Y29uKTsKKworCXJldCA9IGRldm1f ZXh0Y29uX2Rldl9yZWdpc3RlcigmcGRldi0+ZGV2LCBjaGlwLT5leHRjb24pOworCWlmIChyZXQp CisJCXJldHVybiByZXQ7CisKKwlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9S RVNPVVJDRV9NRU0sIDApOworCWlmICghcmVzKSB7CisJCXJldCA9IC1FTk9NRU07CisJCXJldHVy biByZXQ7CisJfQorCisJY2hpcC0+ZXVkX3JlZ19iYXNlID0gZGV2bV9pb3JlbWFwX3Jlc291cmNl KCZwZGV2LT5kZXYsIHJlcyk7CisJaWYgKElTX0VSUihjaGlwLT5ldWRfcmVnX2Jhc2UpKQorCQly ZXR1cm4gUFRSX0VSUihjaGlwLT5ldWRfcmVnX2Jhc2UpOworCisJY2hpcC0+ZXVkX2lycSA9IHBs YXRmb3JtX2dldF9pcnEocGRldiwgMCk7CisKKwlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKCZwZGV2 LT5kZXYsIGNoaXAtPmV1ZF9pcnEsIGhhbmRsZV9ldWRfaXJxLAorCQkJCUlSUUZfVFJJR0dFUl9I SUdILCBOVUxMLCBjaGlwKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJZGV2aWNlX2lu aXRfd2FrZXVwKCZwZGV2LT5kZXYsIHRydWUpOworCWVuYWJsZV9pcnFfd2FrZShjaGlwLT5ldWRf aXJxKTsKKworCUlOSVRfV09SSygmY2hpcC0+ZXVkX3dvcmssIGV1ZF9ldmVudF9ub3RpZmllcik7 CisKKwlldWRfcHJpdmF0ZSA9IGNoaXA7CisJZXVkX3JlYWR5ID0gdHJ1ZTsKKworCS8qIEVuYWJs ZSBFVUQgKi8KKwlpZiAoZW5hYmxlKQorCQllbmFibGVfZXVkKGV1ZF9wcml2YXRlKTsKKworCXJl dHVybiAwOworfQorCitzdGF0aWMgaW50IG1zbV9ldWRfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpCit7CisJc3RydWN0IGV1ZF9jaGlwICpjaGlwID0gcGxhdGZvcm1fZ2V0X2Ry dmRhdGEocGRldik7CisKKwlpZiAoZW5hYmxlKQorCQlkaXNhYmxlX2V1ZChldWRfcHJpdmF0ZSk7 CisJZGV2aWNlX2luaXRfd2FrZXVwKCZwZGV2LT5kZXYsIGZhbHNlKTsKKwlkaXNhYmxlX2lycV93 YWtlKGNoaXAtPmV1ZF9pcnEpOworCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIE5VTEwpOwor CisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG1zbV9l dWRfZHRfbWF0Y2hbXSA9IHsKKwl7LmNvbXBhdGlibGUgPSAicWNvbSxtc20tZXVkIn0sCisJe30s Cit9OworTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgbXNtX2V1ZF9kdF9tYXRjaCk7CisKK3N0YXRp YyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG1zbV9ldWRfZHJpdmVyID0geworCS5wcm9iZQkJPSBt c21fZXVkX3Byb2JlLAorCS5yZW1vdmUJCT0gbXNtX2V1ZF9yZW1vdmUsCisJLmRyaXZlcgkJPSB7 CisJCS5uYW1lCQk9ICJtc20tZXVkIiwKKwkJLm9mX21hdGNoX3RhYmxlID0gbXNtX2V1ZF9kdF9t YXRjaCwKKwl9LAorfTsKK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIobXNtX2V1ZF9kcml2ZXIpOwor CitNT0RVTEVfREVTQ1JJUFRJT04oIlFUSSBFVUQgZHJpdmVyIik7CitNT0RVTEVfTElDRU5TRSgi R1BMIHYyIik7Cg==