From mboxrd@z Thu Jan 1 00:00:00 1970 From: Manu Gautam Subject: [PATCH v2 2/3] usb: dwc3: Add Qualcomm DWC3 glue driver Date: Fri, 13 Apr 2018 22:21:23 +0530 Message-ID: <1523638285-5742-3-git-send-email-mgautam@codeaurora.org> References: <1523638285-5742-1-git-send-email-mgautam@codeaurora.org> Return-path: In-Reply-To: <1523638285-5742-1-git-send-email-mgautam@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org To: balbi@kernel.org, robh@kernel.org, andy.gross@linaro.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, robh+dt@kernel.org, linux-arm-msm@vger.kernel.org, Manu Gautam , Greg Kroah-Hartman List-Id: linux-arm-msm@vger.kernel.org DWC3 controller on Qualcomm SOCs has a Qscratch wrapper. Some of its uses are described below resulting in need to have a separate glue driver instead of using dwc3-of-simple: - It exposes register interface to override vbus-override and lane0-pwr-present signals going to hardware. These must be updated in peripheral mode for DWC3 if vbus lines are not connected to hardware block. Otherwise RX termination in SS mode or DP pull-up is not applied by device controller. - pwr_events_irq_stat support to check if USB2 PHY is in L2 state before glue driver proceeds with suspend. - Support for wakeup interrupts lines that are asserted whenever there is any wakeup event on USB3 or USB2 bus. - Support to replace pip3 clock going to DWC3 with utmi clock for hardware configuration where SSPHY is not used with DWC3. Signed-off-by: Manu Gautam --- drivers/usb/dwc3/Kconfig | 12 + drivers/usb/dwc3/Makefile | 1 + drivers/usb/dwc3/dwc3-of-simple.c | 1 - drivers/usb/dwc3/dwc3-qcom.c | 618 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 631 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/dwc3/dwc3-qcom.c diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index ab8c0e0..451012e 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -106,4 +106,16 @@ config USB_DWC3_ST inside (i.e. STiH407). Say 'Y' or 'M' if you have one such device. +config USB_DWC3_QCOM + tristate "Qualcomm Platform" + depends on ARCH_QCOM || COMPILE_TEST + depends on OF + default USB_DWC3 + help + Some Qualcomm SoCs use DesignWare Core IP for USB2/3 + functionality. + This driver also handles Qscratch wrapper which is needed + for peripheral mode support. + Say 'Y' or 'M' if you have one such device. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 025bc68..5c07d8f 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -48,3 +48,4 @@ obj-$(CONFIG_USB_DWC3_PCI) += dwc3-pci.o obj-$(CONFIG_USB_DWC3_KEYSTONE) += dwc3-keystone.o obj-$(CONFIG_USB_DWC3_OF_SIMPLE) += dwc3-of-simple.o obj-$(CONFIG_USB_DWC3_ST) += dwc3-st.o +obj-$(CONFIG_USB_DWC3_QCOM) += dwc3-qcom.o diff --git a/drivers/usb/dwc3/dwc3-of-simple.c b/drivers/usb/dwc3/dwc3-of-simple.c index cb2ee96..0fd0e8e 100644 --- a/drivers/usb/dwc3/dwc3-of-simple.c +++ b/drivers/usb/dwc3/dwc3-of-simple.c @@ -208,7 +208,6 @@ static int dwc3_of_simple_runtime_resume(struct device *dev) }; static const struct of_device_id of_dwc3_simple_match[] = { - { .compatible = "qcom,dwc3" }, { .compatible = "rockchip,rk3399-dwc3" }, { .compatible = "xlnx,zynqmp-dwc3" }, { .compatible = "cavium,octeon-7130-usb-uctl" }, diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c new file mode 100644 index 0000000..ecb2218 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -0,0 +1,618 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * Inspired by dwc3-of-simple.c + */ +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "core.h" + +/* USB QSCRATCH Hardware registers */ +#define QSCRATCH_HS_PHY_CTRL 0x10 +#define UTMI_OTG_VBUS_VALID BIT(20) +#define SW_SESSVLD_SEL BIT(28) + +#define QSCRATCH_SS_PHY_CTRL 0x30 +#define LANE0_PWR_PRESENT BIT(24) + +#define QSCRATCH_GENERAL_CFG 0x08 +#define PIPE_UTMI_CLK_SEL BIT(0) +#define PIPE3_PHYSTATUS_SW BIT(3) +#define PIPE_UTMI_CLK_DIS BIT(8) + +#define PWR_EVNT_IRQ_STAT_REG 0x58 +#define PWR_EVNT_LPM_IN_L2_MASK BIT(4) +#define PWR_EVNT_LPM_OUT_L2_MASK BIT(5) + +struct dwc3_qcom { + struct device *dev; + void __iomem *qscratch_base; + struct platform_device *dwc3; + struct clk **clks; + int num_clocks; + struct reset_control *resets; + + int hs_phy_irq; + int dp_hs_phy_irq; + int dm_hs_phy_irq; + int ss_phy_irq; + + struct extcon_dev *edev; + struct extcon_dev *host_edev; + struct notifier_block vbus_nb; + struct notifier_block host_nb; + + enum usb_dr_mode mode; + bool is_suspended; + bool pm_suspended; +}; + +static inline void dwc3_qcom_setbits(void __iomem *base, u32 offset, u32 val) +{ + u32 reg; + + reg = readl(base + offset); + reg |= val; + writel(reg, base + offset); + + /* ensure that above write is through */ + readl(base + offset); +} + +static inline void dwc3_qcom_clrbits(void __iomem *base, u32 offset, u32 val) +{ + u32 reg; + + reg = readl(base + offset); + reg &= ~val; + writel(reg, base + offset); + + /* ensure that above write is through */ + readl(base + offset); +} + +static void dwc3_qcom_vbus_overrride_enable(struct dwc3_qcom *qcom, bool enable) +{ + if (enable) { + dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, + LANE0_PWR_PRESENT); + dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL); + } else { + dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, + LANE0_PWR_PRESENT); + dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL); + } +} + +static int dwc3_qcom_vbus_notifier(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, vbus_nb); + + /* enable vbus override for device mode */ + dwc3_qcom_vbus_overrride_enable(qcom, event); + qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST; + + return NOTIFY_DONE; +} + +static int dwc3_qcom_host_notifier(struct notifier_block *nb, + unsigned long event, void *ptr) +{ + struct dwc3_qcom *qcom = container_of(nb, struct dwc3_qcom, host_nb); + + /* disable vbus override in host mode */ + dwc3_qcom_vbus_overrride_enable(qcom, !event); + qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL; + + return NOTIFY_DONE; +} + +static int dwc3_qcom_register_extcon(struct dwc3_qcom *qcom) +{ + struct device *dev = qcom->dev; + struct extcon_dev *host_edev; + int ret; + + if (!of_property_read_bool(dev->of_node, "extcon")) + return 0; + + qcom->edev = extcon_get_edev_by_phandle(dev, 0); + if (IS_ERR(qcom->edev)) + return PTR_ERR(qcom->edev); + + qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier; + + qcom->host_edev = extcon_get_edev_by_phandle(dev, 1); + if (IS_ERR(qcom->host_edev)) + qcom->host_edev = NULL; + + ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB, + &qcom->vbus_nb); + if (ret < 0) { + dev_err(dev, "VBUS notifier register failed\n"); + return ret; + } + + if (qcom->host_edev) + host_edev = qcom->host_edev; + else + host_edev = qcom->edev; + + qcom->host_nb.notifier_call = dwc3_qcom_host_notifier; + ret = devm_extcon_register_notifier(dev, host_edev, EXTCON_USB_HOST, + &qcom->host_nb); + if (ret < 0) { + dev_err(dev, "Host notifier register failed\n"); + return ret; + } + + /* Update initial VBUS override based on extcon state */ + if (extcon_get_state(qcom->edev, EXTCON_USB) || + !extcon_get_state(host_edev, EXTCON_USB_HOST)) + dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev); + else + dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev); + + return 0; +} + +static void dwc3_qcom_disable_interrupts(struct dwc3_qcom *qcom) +{ + if (qcom->hs_phy_irq) { + disable_irq_wake(qcom->hs_phy_irq); + disable_irq_nosync(qcom->hs_phy_irq); + } + + if (qcom->dp_hs_phy_irq) { + disable_irq_wake(qcom->dp_hs_phy_irq); + disable_irq_nosync(qcom->dp_hs_phy_irq); + } + + if (qcom->dm_hs_phy_irq) { + disable_irq_wake(qcom->dm_hs_phy_irq); + disable_irq_nosync(qcom->dm_hs_phy_irq); + } + + if (qcom->ss_phy_irq) { + disable_irq_wake(qcom->ss_phy_irq); + disable_irq_nosync(qcom->ss_phy_irq); + } +} + +static void dwc3_qcom_enable_interrupts(struct dwc3_qcom *qcom) +{ + if (qcom->hs_phy_irq) { + enable_irq(qcom->hs_phy_irq); + enable_irq_wake(qcom->hs_phy_irq); + } + + if (qcom->dp_hs_phy_irq) { + enable_irq(qcom->dp_hs_phy_irq); + enable_irq_wake(qcom->dp_hs_phy_irq); + } + + if (qcom->dm_hs_phy_irq) { + enable_irq(qcom->dm_hs_phy_irq); + enable_irq_wake(qcom->dm_hs_phy_irq); + } + + if (qcom->ss_phy_irq) { + enable_irq(qcom->ss_phy_irq); + enable_irq_wake(qcom->ss_phy_irq); + } +} + +static int dwc3_qcom_suspend(struct dwc3_qcom *qcom) +{ + u32 val; + int i; + + if (qcom->is_suspended) + return 0; + + val = readl(qcom->qscratch_base + PWR_EVNT_IRQ_STAT_REG); + if (!(val & PWR_EVNT_LPM_IN_L2_MASK)) + dev_err(qcom->dev, "HS-PHY not in L2\n"); + + for (i = qcom->num_clocks - 1; i >= 0; i--) + clk_disable_unprepare(qcom->clks[i]); + + qcom->is_suspended = true; + dwc3_qcom_enable_interrupts(qcom); + + return 0; +} + +static int dwc3_qcom_resume(struct dwc3_qcom *qcom) +{ + int ret; + int i; + + if (!qcom->is_suspended) + return 0; + + dwc3_qcom_disable_interrupts(qcom); + + for (i = 0; i < qcom->num_clocks; i++) { + ret = clk_prepare_enable(qcom->clks[i]); + if (ret < 0) { + while (--i >= 0) + clk_disable_unprepare(qcom->clks[i]); + return ret; + } + } + + /* Clear existing events from PHY related to L2 in/out */ + dwc3_qcom_setbits(qcom->qscratch_base, PWR_EVNT_IRQ_STAT_REG, + PWR_EVNT_LPM_IN_L2_MASK | PWR_EVNT_LPM_OUT_L2_MASK); + + qcom->is_suspended = false; + + return 0; +} + +static irqreturn_t qcom_dwc3_resume_irq(int irq, void *data) +{ + struct dwc3_qcom *qcom = data; + struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); + + /* If pm_suspended then let pm_resume take care of resuming h/w */ + if (qcom->pm_suspended) + return IRQ_HANDLED; + + if (dwc->xhci) + pm_runtime_resume(&dwc->xhci->dev); + + return IRQ_HANDLED; +} + +static void dwc3_qcom_select_utmi_clk(struct dwc3_qcom *qcom) +{ + /* Configure dwc3 to use UTMI clock as PIPE clock not present */ + dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, + PIPE_UTMI_CLK_DIS); + + usleep_range(100, 1000); + + dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, + PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW); + + usleep_range(100, 1000); + + dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, + PIPE_UTMI_CLK_DIS); +} + +static int dwc3_qcom_setup_irq(struct platform_device *pdev) +{ + struct dwc3_qcom *qcom = platform_get_drvdata(pdev); + int irq, ret; + + irq = platform_get_irq_byname(pdev, "hs_phy_irq"); + if (irq > 0) { + /* Keep wakeup interrupts disabled until suspend */ + irq_set_status_flags(irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(qcom->dev, irq, NULL, + qcom_dwc3_resume_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "qcom_dwc3 HS", qcom); + if (ret) { + dev_err(qcom->dev, "hs_phy_irq failed: %d\n", ret); + return ret; + } + qcom->hs_phy_irq = irq; + } + + irq = platform_get_irq_byname(pdev, "dp_hs_phy_irq"); + if (irq > 0) { + irq_set_status_flags(irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(qcom->dev, irq, NULL, + qcom_dwc3_resume_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "qcom_dwc3 DP_HS", qcom); + if (ret) { + dev_err(qcom->dev, "dp_hs_phy_irq failed: %d\n", ret); + return ret; + } + qcom->dp_hs_phy_irq = irq; + } + + irq = platform_get_irq_byname(pdev, "dm_hs_phy_irq"); + if (irq > 0) { + irq_set_status_flags(irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(qcom->dev, irq, NULL, + qcom_dwc3_resume_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "qcom_dwc3 DM_HS", qcom); + if (ret) { + dev_err(qcom->dev, "dm_hs_phy_irq failed: %d\n", ret); + return ret; + } + qcom->dm_hs_phy_irq = irq; + } + + irq = platform_get_irq_byname(pdev, "ss_phy_irq"); + if (irq > 0) { + irq_set_status_flags(irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(qcom->dev, irq, NULL, + qcom_dwc3_resume_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + "qcom_dwc3 SS", qcom); + if (ret) { + dev_err(qcom->dev, "ss_phy_irq failed: %d\n", ret); + return ret; + } + qcom->ss_phy_irq = irq; + } + + return 0; +} + +static int dwc3_qcom_clk_init(struct dwc3_qcom *qcom, int count) +{ + struct device *dev = qcom->dev; + struct device_node *np = dev->of_node; + int i; + + qcom->num_clocks = count; + + if (!count) + return 0; + + qcom->clks = devm_kcalloc(dev, qcom->num_clocks, + sizeof(struct clk *), GFP_KERNEL); + if (!qcom->clks) + return -ENOMEM; + + for (i = 0; i < qcom->num_clocks; i++) { + struct clk *clk; + int ret; + + clk = of_clk_get(np, i); + if (IS_ERR(clk)) { + while (--i >= 0) + clk_put(qcom->clks[i]); + return PTR_ERR(clk); + } + + ret = clk_prepare_enable(clk); + if (ret < 0) { + while (--i >= 0) { + clk_disable_unprepare(qcom->clks[i]); + clk_put(qcom->clks[i]); + } + clk_put(clk); + + return ret; + } + + qcom->clks[i] = clk; + } + + return 0; +} + +static int dwc3_qcom_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node, *dwc3_np; + struct device *dev = &pdev->dev; + struct dwc3_qcom *qcom; + struct resource *res; + int ret, i; + bool ignore_pipe_clk; + + qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL); + if (!qcom) + return -ENOMEM; + + platform_set_drvdata(pdev, qcom); + qcom->dev = &pdev->dev; + + qcom->resets = devm_reset_control_array_get_optional_exclusive(dev); + if (IS_ERR(qcom->resets)) { + ret = PTR_ERR(qcom->resets); + dev_err(&pdev->dev, "failed to get resets, err=%d\n", ret); + return ret; + } + + ret = reset_control_assert(qcom->resets); + if (ret) { + dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret); + return ret; + } + + usleep_range(10, 1000); + + ret = reset_control_deassert(qcom->resets); + if (ret) { + dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret); + goto reset_assert; + } + + ret = dwc3_qcom_clk_init(qcom, of_count_phandle_with_args(np, + "clocks", "#clock-cells")); + if (ret) { + dev_err(dev, "failed to get clocks\n"); + goto reset_assert; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + qcom->qscratch_base = devm_ioremap_resource(dev, res); + if (IS_ERR(qcom->qscratch_base)) { + dev_err(dev, "failed to map qscratch, err=%d\n", ret); + ret = PTR_ERR(qcom->qscratch_base); + goto clk_disable; + } + + ret = dwc3_qcom_setup_irq(pdev); + if (ret) + goto clk_disable; + + dwc3_np = of_get_child_by_name(np, "dwc3"); + if (!dwc3_np) { + dev_err(dev, "failed to find dwc3 core child\n"); + ret = -ENODEV; + goto clk_disable; + } + + /* + * Disable pipe_clk requirement if specified. Used when dwc3 + * operates without SSPHY and only HS/FS/LS modes are supported. + */ + ignore_pipe_clk = device_property_read_bool(dev, + "qcom,select-utmi-as-pipe-clk"); + if (ignore_pipe_clk) + dwc3_qcom_select_utmi_clk(qcom); + + ret = of_platform_populate(np, NULL, NULL, dev); + if (ret) { + dev_err(dev, "failed to register dwc3 core - %d\n", ret); + goto clk_disable; + } + + qcom->dwc3 = of_find_device_by_node(dwc3_np); + if (!qcom->dwc3) { + dev_err(&pdev->dev, "failed to get dwc3 platform device\n"); + goto depopulate; + } + + qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev); + + /* enable vbus override for device mode */ + if (qcom->mode == USB_DR_MODE_PERIPHERAL) + dwc3_qcom_vbus_overrride_enable(qcom, true); + + /* register extcon to override sw_vbus on Vbus change later */ + ret = dwc3_qcom_register_extcon(qcom); + if (ret) + goto depopulate; + + device_init_wakeup(&pdev->dev, 1); + qcom->is_suspended = false; + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_forbid(dev); + + return 0; + +depopulate: + of_platform_depopulate(&pdev->dev); +clk_disable: + for (i = qcom->num_clocks - 1; i >= 0; i--) { + clk_disable_unprepare(qcom->clks[i]); + clk_put(qcom->clks[i]); + } +reset_assert: + reset_control_assert(qcom->resets); + + return ret; +} + +static int dwc3_qcom_remove(struct platform_device *pdev) +{ + struct dwc3_qcom *qcom = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + int i; + + of_platform_depopulate(dev); + + for (i = qcom->num_clocks - 1; i >= 0; i--) { + clk_disable_unprepare(qcom->clks[i]); + clk_put(qcom->clks[i]); + } + qcom->num_clocks = 0; + + reset_control_assert(qcom->resets); + + pm_runtime_allow(dev); + pm_runtime_disable(dev); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int dwc3_qcom_pm_suspend(struct device *dev) +{ + struct dwc3_qcom *qcom = dev_get_drvdata(dev); + int ret = 0; + + ret = dwc3_qcom_suspend(qcom); + if (!ret) + qcom->pm_suspended = true; + + return ret; +} + +static int dwc3_qcom_pm_resume(struct device *dev) +{ + struct dwc3_qcom *qcom = dev_get_drvdata(dev); + int ret; + + ret = dwc3_qcom_resume(qcom); + if (!ret) + qcom->pm_suspended = false; + + return ret; +} +#endif + +#ifdef CONFIG_PM +static int dwc3_qcom_runtime_suspend(struct device *dev) +{ + struct dwc3_qcom *qcom = dev_get_drvdata(dev); + + return dwc3_qcom_suspend(qcom); +} + +static int dwc3_qcom_runtime_resume(struct device *dev) +{ + struct dwc3_qcom *qcom = dev_get_drvdata(dev); + + return dwc3_qcom_resume(qcom); +} +#endif + +static const struct dev_pm_ops dwc3_qcom_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(dwc3_qcom_pm_suspend, dwc3_qcom_pm_resume) + SET_RUNTIME_PM_OPS(dwc3_qcom_runtime_suspend, dwc3_qcom_runtime_resume, + NULL) +}; + +static const struct of_device_id dwc3_qcom_of_match[] = { + { .compatible = "qcom,dwc3" }, + { } +}; +MODULE_DEVICE_TABLE(of, dwc3_qcom_of_match); + +static struct platform_driver dwc3_qcom_driver = { + .probe = dwc3_qcom_probe, + .remove = dwc3_qcom_remove, + .driver = { + .name = "dwc3-qcom", + .pm = &dwc3_qcom_dev_pm_ops, + .of_match_table = dwc3_qcom_of_match, + }, +}; + +module_platform_driver(dwc3_qcom_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("DesignWare DWC3 QCOM Glue Driver"); -- 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: [v2,2/3] usb: dwc3: Add Qualcomm DWC3 glue driver From: Manu Gautam Message-Id: <1523638285-5742-3-git-send-email-mgautam@codeaurora.org> Date: Fri, 13 Apr 2018 22:21:23 +0530 To: balbi@kernel.org, robh@kernel.org, andy.gross@linaro.org Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, robh+dt@kernel.org, linux-arm-msm@vger.kernel.org, Manu Gautam , Greg Kroah-Hartman List-ID: RFdDMyBjb250cm9sbGVyIG9uIFF1YWxjb21tIFNPQ3MgaGFzIGEgUXNjcmF0Y2ggd3JhcHBlci4K U29tZSBvZiBpdHMgdXNlcyBhcmUgZGVzY3JpYmVkIGJlbG93IHJlc3VsdGluZyBpbiBuZWVkIHRv CmhhdmUgYSBzZXBhcmF0ZSBnbHVlIGRyaXZlciBpbnN0ZWFkIG9mIHVzaW5nIGR3YzMtb2Ytc2lt cGxlOgogLSBJdCBleHBvc2VzIHJlZ2lzdGVyIGludGVyZmFjZSB0byBvdmVycmlkZSB2YnVzLW92 ZXJyaWRlCiAgIGFuZCBsYW5lMC1wd3ItcHJlc2VudCBzaWduYWxzIGdvaW5nIHRvIGhhcmR3YXJl LiBUaGVzZQogICBtdXN0IGJlIHVwZGF0ZWQgaW4gcGVyaXBoZXJhbCBtb2RlIGZvciBEV0MzIGlm IHZidXMgbGluZXMKICAgYXJlIG5vdCBjb25uZWN0ZWQgdG8gaGFyZHdhcmUgYmxvY2suIE90aGVy d2lzZSBSWCB0ZXJtaW5hdGlvbgogICBpbiBTUyBtb2RlIG9yIERQIHB1bGwtdXAgaXMgbm90IGFw cGxpZWQgYnkgZGV2aWNlIGNvbnRyb2xsZXIuCiAtIHB3cl9ldmVudHNfaXJxX3N0YXQgc3VwcG9y dCB0byBjaGVjayBpZiBVU0IyIFBIWSBpcyBpbiBMMiBzdGF0ZQogICBiZWZvcmUgZ2x1ZSBkcml2 ZXIgcHJvY2VlZHMgd2l0aCBzdXNwZW5kLgogLSBTdXBwb3J0IGZvciB3YWtldXAgaW50ZXJydXB0 cyBsaW5lcyB0aGF0IGFyZSBhc3NlcnRlZCB3aGVuZXZlcgogICB0aGVyZSBpcyBhbnkgd2FrZXVw IGV2ZW50IG9uIFVTQjMgb3IgVVNCMiBidXMuCiAtIFN1cHBvcnQgdG8gcmVwbGFjZSBwaXAzIGNs b2NrIGdvaW5nIHRvIERXQzMgd2l0aCB1dG1pIGNsb2NrCiAgIGZvciBoYXJkd2FyZSBjb25maWd1 cmF0aW9uIHdoZXJlIFNTUEhZIGlzIG5vdCB1c2VkIHdpdGggRFdDMy4KClNpZ25lZC1vZmYtYnk6 IE1hbnUgR2F1dGFtIDxtZ2F1dGFtQGNvZGVhdXJvcmEub3JnPgotLS0KIGRyaXZlcnMvdXNiL2R3 YzMvS2NvbmZpZyAgICAgICAgICB8ICAxMiArCiBkcml2ZXJzL3VzYi9kd2MzL01ha2VmaWxlICAg ICAgICAgfCAgIDEgKwogZHJpdmVycy91c2IvZHdjMy9kd2MzLW9mLXNpbXBsZS5jIHwgICAxIC0K IGRyaXZlcnMvdXNiL2R3YzMvZHdjMy1xY29tLmMgICAgICB8IDYxOCArKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKwogNCBmaWxlcyBjaGFuZ2VkLCA2MzEgaW5zZXJ0aW9ucygr KSwgMSBkZWxldGlvbigtKQogY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL2R3YzMvZHdj My1xY29tLmMKCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9kd2MzL0tjb25maWcgYi9kcml2ZXJz L3VzYi9kd2MzL0tjb25maWcKaW5kZXggYWI4YzBlMC4uNDUxMDEyZSAxMDA2NDQKLS0tIGEvZHJp dmVycy91c2IvZHdjMy9LY29uZmlnCisrKyBiL2RyaXZlcnMvdXNiL2R3YzMvS2NvbmZpZwpAQCAt MTA2LDQgKzEwNiwxNiBAQCBjb25maWcgVVNCX0RXQzNfU1QKIAkgIGluc2lkZSAoaS5lLiBTVGlI NDA3KS4KIAkgIFNheSAnWScgb3IgJ00nIGlmIHlvdSBoYXZlIG9uZSBzdWNoIGRldmljZS4KIAor Y29uZmlnIFVTQl9EV0MzX1FDT00KKwl0cmlzdGF0ZSAiUXVhbGNvbW0gUGxhdGZvcm0iCisJZGVw ZW5kcyBvbiBBUkNIX1FDT00gfHwgQ09NUElMRV9URVNUCisJZGVwZW5kcyBvbiBPRgorCWRlZmF1 bHQgVVNCX0RXQzMKKwloZWxwCisJICBTb21lIFF1YWxjb21tIFNvQ3MgdXNlIERlc2lnbldhcmUg Q29yZSBJUCBmb3IgVVNCMi8zCisJICBmdW5jdGlvbmFsaXR5LgorCSAgVGhpcyBkcml2ZXIgYWxz byBoYW5kbGVzIFFzY3JhdGNoIHdyYXBwZXIgd2hpY2ggaXMgbmVlZGVkCisJICBmb3IgcGVyaXBo ZXJhbCBtb2RlIHN1cHBvcnQuCisJICBTYXkgJ1knIG9yICdNJyBpZiB5b3UgaGF2ZSBvbmUgc3Vj aCBkZXZpY2UuCisKIGVuZGlmCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9kd2MzL01ha2VmaWxl IGIvZHJpdmVycy91c2IvZHdjMy9NYWtlZmlsZQppbmRleCAwMjViYzY4Li41YzA3ZDhmIDEwMDY0 NAotLS0gYS9kcml2ZXJzL3VzYi9kd2MzL01ha2VmaWxlCisrKyBiL2RyaXZlcnMvdXNiL2R3YzMv TWFrZWZpbGUKQEAgLTQ4LDMgKzQ4LDQgQEAgb2JqLSQoQ09ORklHX1VTQl9EV0MzX1BDSSkJCSs9 IGR3YzMtcGNpLm8KIG9iai0kKENPTkZJR19VU0JfRFdDM19LRVlTVE9ORSkJCSs9IGR3YzMta2V5 c3RvbmUubwogb2JqLSQoQ09ORklHX1VTQl9EV0MzX09GX1NJTVBMRSkJKz0gZHdjMy1vZi1zaW1w bGUubwogb2JqLSQoQ09ORklHX1VTQl9EV0MzX1NUKQkJKz0gZHdjMy1zdC5vCitvYmotJChDT05G SUdfVVNCX0RXQzNfUUNPTSkJCSs9IGR3YzMtcWNvbS5vCmRpZmYgLS1naXQgYS9kcml2ZXJzL3Vz Yi9kd2MzL2R3YzMtb2Ytc2ltcGxlLmMgYi9kcml2ZXJzL3VzYi9kd2MzL2R3YzMtb2Ytc2ltcGxl LmMKaW5kZXggY2IyZWU5Ni4uMGZkMGU4ZSAxMDA2NDQKLS0tIGEvZHJpdmVycy91c2IvZHdjMy9k d2MzLW9mLXNpbXBsZS5jCisrKyBiL2RyaXZlcnMvdXNiL2R3YzMvZHdjMy1vZi1zaW1wbGUuYwpA QCAtMjA4LDcgKzIwOCw2IEBAIHN0YXRpYyBpbnQgZHdjM19vZl9zaW1wbGVfcnVudGltZV9yZXN1 bWUoc3RydWN0IGRldmljZSAqZGV2KQogfTsKIAogc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZp Y2VfaWQgb2ZfZHdjM19zaW1wbGVfbWF0Y2hbXSA9IHsKLQl7IC5jb21wYXRpYmxlID0gInFjb20s ZHdjMyIgfSwKIAl7IC5jb21wYXRpYmxlID0gInJvY2tjaGlwLHJrMzM5OS1kd2MzIiB9LAogCXsg LmNvbXBhdGlibGUgPSAieGxueCx6eW5xbXAtZHdjMyIgfSwKIAl7IC5jb21wYXRpYmxlID0gImNh dml1bSxvY3Rlb24tNzEzMC11c2ItdWN0bCIgfSwKZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2R3 YzMvZHdjMy1xY29tLmMgYi9kcml2ZXJzL3VzYi9kd2MzL2R3YzMtcWNvbS5jCm5ldyBmaWxlIG1v ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjYjIyMTgKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2 ZXJzL3VzYi9kd2MzL2R3YzMtcWNvbS5jCkBAIC0wLDAgKzEsNjE4IEBACisvLyBTUERYLUxpY2Vu c2UtSWRlbnRpZmllcjogR1BMLTIuMAorLyogQ29weXJpZ2h0IChjKSAyMDE4LCBUaGUgTGludXgg Rm91bmRhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBJbnNwaXJlZCBieSBkd2Mz LW9mLXNpbXBsZS5jCisgKi8KKyNkZWZpbmUgREVCVUcKKworI2luY2x1ZGUgPGxpbnV4L2lvLmg+ CisjaW5jbHVkZSA8bGludXgvb2YuaD4KKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KKyNpbmNsdWRl IDxsaW51eC9pcnEuaD4KKyNpbmNsdWRlIDxsaW51eC9jbGstcHJvdmlkZXIuaD4KKyNpbmNsdWRl IDxsaW51eC9tb2R1bGUuaD4KKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KKyNpbmNsdWRlIDxs aW51eC9leHRjb24uaD4KKyNpbmNsdWRlIDxsaW51eC9vZl9wbGF0Zm9ybS5oPgorI2luY2x1ZGUg PGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgorI2luY2x1ZGUgPGxpbnV4L3BoeS9waHkuaD4KKyNp bmNsdWRlIDxsaW51eC91c2Ivb2YuaD4KKyNpbmNsdWRlIDxsaW51eC9yZXNldC5oPgorI2luY2x1 ZGUgPGxpbnV4L2lvcG9sbC5oPgorCisjaW5jbHVkZSAiY29yZS5oIgorCisvKiBVU0IgUVNDUkFU Q0ggSGFyZHdhcmUgcmVnaXN0ZXJzICovCisjZGVmaW5lIFFTQ1JBVENIX0hTX1BIWV9DVFJMCQkJ MHgxMAorI2RlZmluZSBVVE1JX09UR19WQlVTX1ZBTElECQkJQklUKDIwKQorI2RlZmluZSBTV19T RVNTVkxEX1NFTAkJCQlCSVQoMjgpCisKKyNkZWZpbmUgUVNDUkFUQ0hfU1NfUEhZX0NUUkwJCQkw eDMwCisjZGVmaW5lIExBTkUwX1BXUl9QUkVTRU5UCQkJQklUKDI0KQorCisjZGVmaW5lIFFTQ1JB VENIX0dFTkVSQUxfQ0ZHCQkJMHgwOAorI2RlZmluZSBQSVBFX1VUTUlfQ0xLX1NFTAkJCUJJVCgw KQorI2RlZmluZSBQSVBFM19QSFlTVEFUVVNfU1cJCQlCSVQoMykKKyNkZWZpbmUgUElQRV9VVE1J X0NMS19ESVMJCQlCSVQoOCkKKworI2RlZmluZSBQV1JfRVZOVF9JUlFfU1RBVF9SRUcJCQkweDU4 CisjZGVmaW5lIFBXUl9FVk5UX0xQTV9JTl9MMl9NQVNLCQkJQklUKDQpCisjZGVmaW5lIFBXUl9F Vk5UX0xQTV9PVVRfTDJfTUFTSwkJQklUKDUpCisKK3N0cnVjdCBkd2MzX3Fjb20geworCXN0cnVj dCBkZXZpY2UJCSpkZXY7CisJdm9pZCBfX2lvbWVtCQkqcXNjcmF0Y2hfYmFzZTsKKwlzdHJ1Y3Qg cGxhdGZvcm1fZGV2aWNlCSpkd2MzOworCXN0cnVjdCBjbGsJCSoqY2xrczsKKwlpbnQJCQludW1f Y2xvY2tzOworCXN0cnVjdCByZXNldF9jb250cm9sCSpyZXNldHM7CisKKwlpbnQJCQloc19waHlf aXJxOworCWludAkJCWRwX2hzX3BoeV9pcnE7CisJaW50CQkJZG1faHNfcGh5X2lycTsKKwlpbnQJ CQlzc19waHlfaXJxOworCisJc3RydWN0IGV4dGNvbl9kZXYJKmVkZXY7CisJc3RydWN0IGV4dGNv bl9kZXYJKmhvc3RfZWRldjsKKwlzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sJdmJ1c19uYjsKKwlzdHJ1 Y3Qgbm90aWZpZXJfYmxvY2sJaG9zdF9uYjsKKworCWVudW0gdXNiX2RyX21vZGUJbW9kZTsKKwli b29sCQkJaXNfc3VzcGVuZGVkOworCWJvb2wJCQlwbV9zdXNwZW5kZWQ7Cit9OworCitzdGF0aWMg aW5saW5lIHZvaWQgZHdjM19xY29tX3NldGJpdHModm9pZCBfX2lvbWVtICpiYXNlLCB1MzIgb2Zm c2V0LCB1MzIgdmFsKQoreworCXUzMiByZWc7CisKKwlyZWcgPSByZWFkbChiYXNlICsgb2Zmc2V0 KTsKKwlyZWcgfD0gdmFsOworCXdyaXRlbChyZWcsIGJhc2UgKyBvZmZzZXQpOworCisJLyogZW5z dXJlIHRoYXQgYWJvdmUgd3JpdGUgaXMgdGhyb3VnaCAqLworCXJlYWRsKGJhc2UgKyBvZmZzZXQp OworfQorCitzdGF0aWMgaW5saW5lIHZvaWQgZHdjM19xY29tX2NscmJpdHModm9pZCBfX2lvbWVt ICpiYXNlLCB1MzIgb2Zmc2V0LCB1MzIgdmFsKQoreworCXUzMiByZWc7CisKKwlyZWcgPSByZWFk bChiYXNlICsgb2Zmc2V0KTsKKwlyZWcgJj0gfnZhbDsKKwl3cml0ZWwocmVnLCBiYXNlICsgb2Zm c2V0KTsKKworCS8qIGVuc3VyZSB0aGF0IGFib3ZlIHdyaXRlIGlzIHRocm91Z2ggKi8KKwlyZWFk bChiYXNlICsgb2Zmc2V0KTsKK30KKworc3RhdGljIHZvaWQgZHdjM19xY29tX3ZidXNfb3ZlcnJy aWRlX2VuYWJsZShzdHJ1Y3QgZHdjM19xY29tICpxY29tLCBib29sIGVuYWJsZSkKK3sKKwlpZiAo ZW5hYmxlKSB7CisJCWR3YzNfcWNvbV9zZXRiaXRzKHFjb20tPnFzY3JhdGNoX2Jhc2UsIFFTQ1JB VENIX1NTX1BIWV9DVFJMLAorCQkJCSAgTEFORTBfUFdSX1BSRVNFTlQpOworCQlkd2MzX3Fjb21f c2V0Yml0cyhxY29tLT5xc2NyYXRjaF9iYXNlLCBRU0NSQVRDSF9IU19QSFlfQ1RSTCwKKwkJCQkg IFVUTUlfT1RHX1ZCVVNfVkFMSUQgfCBTV19TRVNTVkxEX1NFTCk7CisJfSBlbHNlIHsKKwkJZHdj M19xY29tX2NscmJpdHMocWNvbS0+cXNjcmF0Y2hfYmFzZSwgUVNDUkFUQ0hfU1NfUEhZX0NUUkws CisJCQkJICBMQU5FMF9QV1JfUFJFU0VOVCk7CisJCWR3YzNfcWNvbV9jbHJiaXRzKHFjb20tPnFz Y3JhdGNoX2Jhc2UsIFFTQ1JBVENIX0hTX1BIWV9DVFJMLAorCQkJCSAgVVRNSV9PVEdfVkJVU19W QUxJRCB8IFNXX1NFU1NWTERfU0VMKTsKKwl9Cit9CisKK3N0YXRpYyBpbnQgZHdjM19xY29tX3Zi dXNfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuYiwKKwkJCQkgICB1bnNpZ25lZCBs b25nIGV2ZW50LCB2b2lkICpwdHIpCit7CisJc3RydWN0IGR3YzNfcWNvbSAqcWNvbSA9IGNvbnRh aW5lcl9vZihuYiwgc3RydWN0IGR3YzNfcWNvbSwgdmJ1c19uYik7CisKKwkvKiBlbmFibGUgdmJ1 cyBvdmVycmlkZSBmb3IgZGV2aWNlIG1vZGUgKi8KKwlkd2MzX3Fjb21fdmJ1c19vdmVycnJpZGVf ZW5hYmxlKHFjb20sIGV2ZW50KTsKKwlxY29tLT5tb2RlID0gZXZlbnQgPyBVU0JfRFJfTU9ERV9Q RVJJUEhFUkFMIDogVVNCX0RSX01PREVfSE9TVDsKKworCXJldHVybiBOT1RJRllfRE9ORTsKK30K Kworc3RhdGljIGludCBkd2MzX3Fjb21faG9zdF9ub3RpZmllcihzdHJ1Y3Qgbm90aWZpZXJfYmxv Y2sgKm5iLAorCQkJCSAgIHVuc2lnbmVkIGxvbmcgZXZlbnQsIHZvaWQgKnB0cikKK3sKKwlzdHJ1 Y3QgZHdjM19xY29tICpxY29tID0gY29udGFpbmVyX29mKG5iLCBzdHJ1Y3QgZHdjM19xY29tLCBo b3N0X25iKTsKKworCS8qIGRpc2FibGUgdmJ1cyBvdmVycmlkZSBpbiBob3N0IG1vZGUgKi8KKwlk d2MzX3Fjb21fdmJ1c19vdmVycnJpZGVfZW5hYmxlKHFjb20sICFldmVudCk7CisJcWNvbS0+bW9k ZSA9IGV2ZW50ID8gVVNCX0RSX01PREVfSE9TVCA6IFVTQl9EUl9NT0RFX1BFUklQSEVSQUw7CisK KwlyZXR1cm4gTk9USUZZX0RPTkU7Cit9CisKK3N0YXRpYyBpbnQgZHdjM19xY29tX3JlZ2lzdGVy X2V4dGNvbihzdHJ1Y3QgZHdjM19xY29tICpxY29tKQoreworCXN0cnVjdCBkZXZpY2UJCSpkZXYg PSBxY29tLT5kZXY7CisJc3RydWN0IGV4dGNvbl9kZXYJKmhvc3RfZWRldjsKKwlpbnQJCQlyZXQ7 CisKKwlpZiAoIW9mX3Byb3BlcnR5X3JlYWRfYm9vbChkZXYtPm9mX25vZGUsICJleHRjb24iKSkK KwkJcmV0dXJuIDA7CisKKwlxY29tLT5lZGV2ID0gZXh0Y29uX2dldF9lZGV2X2J5X3BoYW5kbGUo ZGV2LCAwKTsKKwlpZiAoSVNfRVJSKHFjb20tPmVkZXYpKQorCQlyZXR1cm4gUFRSX0VSUihxY29t LT5lZGV2KTsKKworCXFjb20tPnZidXNfbmIubm90aWZpZXJfY2FsbCA9IGR3YzNfcWNvbV92YnVz X25vdGlmaWVyOworCisJcWNvbS0+aG9zdF9lZGV2ID0gZXh0Y29uX2dldF9lZGV2X2J5X3BoYW5k bGUoZGV2LCAxKTsKKwlpZiAoSVNfRVJSKHFjb20tPmhvc3RfZWRldikpCisJCXFjb20tPmhvc3Rf ZWRldiA9IE5VTEw7CisKKwlyZXQgPSBkZXZtX2V4dGNvbl9yZWdpc3Rlcl9ub3RpZmllcihkZXYs IHFjb20tPmVkZXYsIEVYVENPTl9VU0IsCisJCQkJCSAgICAmcWNvbS0+dmJ1c19uYik7CisJaWYg KHJldCA8IDApIHsKKwkJZGV2X2VycihkZXYsICJWQlVTIG5vdGlmaWVyIHJlZ2lzdGVyIGZhaWxl ZFxuIik7CisJCXJldHVybiByZXQ7CisJfQorCisJaWYgKHFjb20tPmhvc3RfZWRldikKKwkJaG9z dF9lZGV2ID0gcWNvbS0+aG9zdF9lZGV2OworCWVsc2UKKwkJaG9zdF9lZGV2ID0gcWNvbS0+ZWRl djsKKworCXFjb20tPmhvc3RfbmIubm90aWZpZXJfY2FsbCA9IGR3YzNfcWNvbV9ob3N0X25vdGlm aWVyOworCXJldCA9IGRldm1fZXh0Y29uX3JlZ2lzdGVyX25vdGlmaWVyKGRldiwgaG9zdF9lZGV2 LCBFWFRDT05fVVNCX0hPU1QsCisJCQkJCSAgICAmcWNvbS0+aG9zdF9uYik7CisJaWYgKHJldCA8 IDApIHsKKwkJZGV2X2VycihkZXYsICJIb3N0IG5vdGlmaWVyIHJlZ2lzdGVyIGZhaWxlZFxuIik7 CisJCXJldHVybiByZXQ7CisJfQorCisJLyogVXBkYXRlIGluaXRpYWwgVkJVUyBvdmVycmlkZSBi YXNlZCBvbiBleHRjb24gc3RhdGUgKi8KKwlpZiAoZXh0Y29uX2dldF9zdGF0ZShxY29tLT5lZGV2 LCBFWFRDT05fVVNCKSB8fAorCSAgICAhZXh0Y29uX2dldF9zdGF0ZShob3N0X2VkZXYsIEVYVENP Tl9VU0JfSE9TVCkpCisJCWR3YzNfcWNvbV92YnVzX25vdGlmaWVyKCZxY29tLT52YnVzX25iLCB0 cnVlLCBxY29tLT5lZGV2KTsKKwllbHNlCisJCWR3YzNfcWNvbV92YnVzX25vdGlmaWVyKCZxY29t LT52YnVzX25iLCBmYWxzZSwgcWNvbS0+ZWRldik7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGlj IHZvaWQgZHdjM19xY29tX2Rpc2FibGVfaW50ZXJydXB0cyhzdHJ1Y3QgZHdjM19xY29tICpxY29t KQoreworCWlmIChxY29tLT5oc19waHlfaXJxKSB7CisJCWRpc2FibGVfaXJxX3dha2UocWNvbS0+ aHNfcGh5X2lycSk7CisJCWRpc2FibGVfaXJxX25vc3luYyhxY29tLT5oc19waHlfaXJxKTsKKwl9 CisKKwlpZiAocWNvbS0+ZHBfaHNfcGh5X2lycSkgeworCQlkaXNhYmxlX2lycV93YWtlKHFjb20t PmRwX2hzX3BoeV9pcnEpOworCQlkaXNhYmxlX2lycV9ub3N5bmMocWNvbS0+ZHBfaHNfcGh5X2ly cSk7CisJfQorCisJaWYgKHFjb20tPmRtX2hzX3BoeV9pcnEpIHsKKwkJZGlzYWJsZV9pcnFfd2Fr ZShxY29tLT5kbV9oc19waHlfaXJxKTsKKwkJZGlzYWJsZV9pcnFfbm9zeW5jKHFjb20tPmRtX2hz X3BoeV9pcnEpOworCX0KKworCWlmIChxY29tLT5zc19waHlfaXJxKSB7CisJCWRpc2FibGVfaXJx X3dha2UocWNvbS0+c3NfcGh5X2lycSk7CisJCWRpc2FibGVfaXJxX25vc3luYyhxY29tLT5zc19w aHlfaXJxKTsKKwl9Cit9CisKK3N0YXRpYyB2b2lkIGR3YzNfcWNvbV9lbmFibGVfaW50ZXJydXB0 cyhzdHJ1Y3QgZHdjM19xY29tICpxY29tKQoreworCWlmIChxY29tLT5oc19waHlfaXJxKSB7CisJ CWVuYWJsZV9pcnEocWNvbS0+aHNfcGh5X2lycSk7CisJCWVuYWJsZV9pcnFfd2FrZShxY29tLT5o c19waHlfaXJxKTsKKwl9CisKKwlpZiAocWNvbS0+ZHBfaHNfcGh5X2lycSkgeworCQllbmFibGVf aXJxKHFjb20tPmRwX2hzX3BoeV9pcnEpOworCQllbmFibGVfaXJxX3dha2UocWNvbS0+ZHBfaHNf cGh5X2lycSk7CisJfQorCisJaWYgKHFjb20tPmRtX2hzX3BoeV9pcnEpIHsKKwkJZW5hYmxlX2ly cShxY29tLT5kbV9oc19waHlfaXJxKTsKKwkJZW5hYmxlX2lycV93YWtlKHFjb20tPmRtX2hzX3Bo eV9pcnEpOworCX0KKworCWlmIChxY29tLT5zc19waHlfaXJxKSB7CisJCWVuYWJsZV9pcnEocWNv bS0+c3NfcGh5X2lycSk7CisJCWVuYWJsZV9pcnFfd2FrZShxY29tLT5zc19waHlfaXJxKTsKKwl9 Cit9CisKK3N0YXRpYyBpbnQgZHdjM19xY29tX3N1c3BlbmQoc3RydWN0IGR3YzNfcWNvbSAqcWNv bSkKK3sKKwl1MzIgdmFsOworCWludCBpOworCisJaWYgKHFjb20tPmlzX3N1c3BlbmRlZCkKKwkJ cmV0dXJuIDA7CisKKwl2YWwgPSByZWFkbChxY29tLT5xc2NyYXRjaF9iYXNlICsgUFdSX0VWTlRf SVJRX1NUQVRfUkVHKTsKKwlpZiAoISh2YWwgJiBQV1JfRVZOVF9MUE1fSU5fTDJfTUFTSykpCisJ CWRldl9lcnIocWNvbS0+ZGV2LCAiSFMtUEhZIG5vdCBpbiBMMlxuIik7CisKKwlmb3IgKGkgPSBx Y29tLT5udW1fY2xvY2tzIC0gMTsgaSA+PSAwOyBpLS0pCisJCWNsa19kaXNhYmxlX3VucHJlcGFy ZShxY29tLT5jbGtzW2ldKTsKKworCXFjb20tPmlzX3N1c3BlbmRlZCA9IHRydWU7CisJZHdjM19x Y29tX2VuYWJsZV9pbnRlcnJ1cHRzKHFjb20pOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBp bnQgZHdjM19xY29tX3Jlc3VtZShzdHJ1Y3QgZHdjM19xY29tICpxY29tKQoreworCWludCByZXQ7 CisJaW50IGk7CisKKwlpZiAoIXFjb20tPmlzX3N1c3BlbmRlZCkKKwkJcmV0dXJuIDA7CisKKwlk d2MzX3Fjb21fZGlzYWJsZV9pbnRlcnJ1cHRzKHFjb20pOworCisJZm9yIChpID0gMDsgaSA8IHFj b20tPm51bV9jbG9ja3M7IGkrKykgeworCQlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUocWNvbS0+ Y2xrc1tpXSk7CisJCWlmIChyZXQgPCAwKSB7CisJCQl3aGlsZSAoLS1pID49IDApCisJCQkJY2xr X2Rpc2FibGVfdW5wcmVwYXJlKHFjb20tPmNsa3NbaV0pOworCQkJcmV0dXJuIHJldDsKKwkJfQor CX0KKworCS8qIENsZWFyIGV4aXN0aW5nIGV2ZW50cyBmcm9tIFBIWSByZWxhdGVkIHRvIEwyIGlu L291dCAqLworCWR3YzNfcWNvbV9zZXRiaXRzKHFjb20tPnFzY3JhdGNoX2Jhc2UsIFBXUl9FVk5U X0lSUV9TVEFUX1JFRywKKwkJCSAgUFdSX0VWTlRfTFBNX0lOX0wyX01BU0sgfCBQV1JfRVZOVF9M UE1fT1VUX0wyX01BU0spOworCisJcWNvbS0+aXNfc3VzcGVuZGVkID0gZmFsc2U7CisKKwlyZXR1 cm4gMDsKK30KKworc3RhdGljIGlycXJldHVybl90IHFjb21fZHdjM19yZXN1bWVfaXJxKGludCBp cnEsIHZvaWQgKmRhdGEpCit7CisJc3RydWN0IGR3YzNfcWNvbSAqcWNvbSA9IGRhdGE7CisJc3Ry dWN0IGR3YzMJKmR3YyA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHFjb20tPmR3YzMpOworCisJLyog SWYgcG1fc3VzcGVuZGVkIHRoZW4gbGV0IHBtX3Jlc3VtZSB0YWtlIGNhcmUgb2YgcmVzdW1pbmcg aC93ICovCisJaWYgKHFjb20tPnBtX3N1c3BlbmRlZCkKKwkJcmV0dXJuIElSUV9IQU5ETEVEOwor CisJaWYgKGR3Yy0+eGhjaSkKKwkJcG1fcnVudGltZV9yZXN1bWUoJmR3Yy0+eGhjaS0+ZGV2KTsK KworCXJldHVybiBJUlFfSEFORExFRDsKK30KKworc3RhdGljIHZvaWQgZHdjM19xY29tX3NlbGVj dF91dG1pX2NsayhzdHJ1Y3QgZHdjM19xY29tICpxY29tKQoreworCS8qIENvbmZpZ3VyZSBkd2Mz IHRvIHVzZSBVVE1JIGNsb2NrIGFzIFBJUEUgY2xvY2sgbm90IHByZXNlbnQgKi8KKwlkd2MzX3Fj b21fc2V0Yml0cyhxY29tLT5xc2NyYXRjaF9iYXNlLCBRU0NSQVRDSF9HRU5FUkFMX0NGRywKKwkJ CSAgUElQRV9VVE1JX0NMS19ESVMpOworCisJdXNsZWVwX3JhbmdlKDEwMCwgMTAwMCk7CisKKwlk d2MzX3Fjb21fc2V0Yml0cyhxY29tLT5xc2NyYXRjaF9iYXNlLCBRU0NSQVRDSF9HRU5FUkFMX0NG RywKKwkJCSAgUElQRV9VVE1JX0NMS19TRUwgfCBQSVBFM19QSFlTVEFUVVNfU1cpOworCisJdXNs ZWVwX3JhbmdlKDEwMCwgMTAwMCk7CisKKwlkd2MzX3Fjb21fY2xyYml0cyhxY29tLT5xc2NyYXRj aF9iYXNlLCBRU0NSQVRDSF9HRU5FUkFMX0NGRywKKwkJCSAgUElQRV9VVE1JX0NMS19ESVMpOwor fQorCitzdGF0aWMgaW50IGR3YzNfcWNvbV9zZXR1cF9pcnEoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldikKK3sKKwlzdHJ1Y3QgZHdjM19xY29tICpxY29tID0gcGxhdGZvcm1fZ2V0X2RydmRh dGEocGRldik7CisJaW50IGlycSwgcmV0OworCisJaXJxID0gcGxhdGZvcm1fZ2V0X2lycV9ieW5h bWUocGRldiwgImhzX3BoeV9pcnEiKTsKKwlpZiAoaXJxID4gMCkgeworCQkvKiBLZWVwIHdha2V1 cCBpbnRlcnJ1cHRzIGRpc2FibGVkIHVudGlsIHN1c3BlbmQgKi8KKwkJaXJxX3NldF9zdGF0dXNf ZmxhZ3MoaXJxLCBJUlFfTk9BVVRPRU4pOworCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFkZWRf aXJxKHFjb20tPmRldiwgaXJxLCBOVUxMLAorCQkJCQlxY29tX2R3YzNfcmVzdW1lX2lycSwKKwkJ CQkJSVJRRl9UUklHR0VSX0hJR0ggfCBJUlFGX09ORVNIT1QsCisJCQkJCSJxY29tX2R3YzMgSFMi LCBxY29tKTsKKwkJaWYgKHJldCkgeworCQkJZGV2X2VycihxY29tLT5kZXYsICJoc19waHlfaXJx IGZhaWxlZDogJWRcbiIsIHJldCk7CisJCQlyZXR1cm4gcmV0OworCQl9CisJCXFjb20tPmhzX3Bo eV9pcnEgPSBpcnE7CisJfQorCisJaXJxID0gcGxhdGZvcm1fZ2V0X2lycV9ieW5hbWUocGRldiwg ImRwX2hzX3BoeV9pcnEiKTsKKwlpZiAoaXJxID4gMCkgeworCQlpcnFfc2V0X3N0YXR1c19mbGFn cyhpcnEsIElSUV9OT0FVVE9FTik7CisJCXJldCA9IGRldm1fcmVxdWVzdF90aHJlYWRlZF9pcnEo cWNvbS0+ZGV2LCBpcnEsIE5VTEwsCisJCQkJCXFjb21fZHdjM19yZXN1bWVfaXJxLAorCQkJCQlJ UlFGX1RSSUdHRVJfSElHSCB8IElSUUZfT05FU0hPVCwKKwkJCQkJInFjb21fZHdjMyBEUF9IUyIs IHFjb20pOworCQlpZiAocmV0KSB7CisJCQlkZXZfZXJyKHFjb20tPmRldiwgImRwX2hzX3BoeV9p cnEgZmFpbGVkOiAlZFxuIiwgcmV0KTsKKwkJCXJldHVybiByZXQ7CisJCX0KKwkJcWNvbS0+ZHBf aHNfcGh5X2lycSA9IGlycTsKKwl9CisKKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxX2J5bmFtZShw ZGV2LCAiZG1faHNfcGh5X2lycSIpOworCWlmIChpcnEgPiAwKSB7CisJCWlycV9zZXRfc3RhdHVz X2ZsYWdzKGlycSwgSVJRX05PQVVUT0VOKTsKKwkJcmV0ID0gZGV2bV9yZXF1ZXN0X3RocmVhZGVk X2lycShxY29tLT5kZXYsIGlycSwgTlVMTCwKKwkJCQkJcWNvbV9kd2MzX3Jlc3VtZV9pcnEsCisJ CQkJCUlSUUZfVFJJR0dFUl9ISUdIIHwgSVJRRl9PTkVTSE9ULAorCQkJCQkicWNvbV9kd2MzIERN X0hTIiwgcWNvbSk7CisJCWlmIChyZXQpIHsKKwkJCWRldl9lcnIocWNvbS0+ZGV2LCAiZG1faHNf cGh5X2lycSBmYWlsZWQ6ICVkXG4iLCByZXQpOworCQkJcmV0dXJuIHJldDsKKwkJfQorCQlxY29t LT5kbV9oc19waHlfaXJxID0gaXJxOworCX0KKworCWlycSA9IHBsYXRmb3JtX2dldF9pcnFfYnlu YW1lKHBkZXYsICJzc19waHlfaXJxIik7CisJaWYgKGlycSA+IDApIHsKKwkJaXJxX3NldF9zdGF0 dXNfZmxhZ3MoaXJxLCBJUlFfTk9BVVRPRU4pOworCQlyZXQgPSBkZXZtX3JlcXVlc3RfdGhyZWFk ZWRfaXJxKHFjb20tPmRldiwgaXJxLCBOVUxMLAorCQkJCQlxY29tX2R3YzNfcmVzdW1lX2lycSwK KwkJCQkJSVJRRl9UUklHR0VSX0hJR0ggfCBJUlFGX09ORVNIT1QsCisJCQkJCSJxY29tX2R3YzMg U1MiLCBxY29tKTsKKwkJaWYgKHJldCkgeworCQkJZGV2X2VycihxY29tLT5kZXYsICJzc19waHlf aXJxIGZhaWxlZDogJWRcbiIsIHJldCk7CisJCQlyZXR1cm4gcmV0OworCQl9CisJCXFjb20tPnNz X3BoeV9pcnEgPSBpcnE7CisJfQorCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgZHdjM19x Y29tX2Nsa19pbml0KHN0cnVjdCBkd2MzX3Fjb20gKnFjb20sIGludCBjb3VudCkKK3sKKwlzdHJ1 Y3QgZGV2aWNlCQkqZGV2ID0gcWNvbS0+ZGV2OworCXN0cnVjdCBkZXZpY2Vfbm9kZQkqbnAgPSBk ZXYtPm9mX25vZGU7CisJaW50CQkJaTsKKworCXFjb20tPm51bV9jbG9ja3MgPSBjb3VudDsKKwor CWlmICghY291bnQpCisJCXJldHVybiAwOworCisJcWNvbS0+Y2xrcyA9IGRldm1fa2NhbGxvYyhk ZXYsIHFjb20tPm51bV9jbG9ja3MsCisJCQkJICBzaXplb2Yoc3RydWN0IGNsayAqKSwgR0ZQX0tF Uk5FTCk7CisJaWYgKCFxY29tLT5jbGtzKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWZvciAoaSA9 IDA7IGkgPCBxY29tLT5udW1fY2xvY2tzOyBpKyspIHsKKwkJc3RydWN0IGNsawkqY2xrOworCQlp bnQJCXJldDsKKworCQljbGsgPSBvZl9jbGtfZ2V0KG5wLCBpKTsKKwkJaWYgKElTX0VSUihjbGsp KSB7CisJCQl3aGlsZSAoLS1pID49IDApCisJCQkJY2xrX3B1dChxY29tLT5jbGtzW2ldKTsKKwkJ CXJldHVybiBQVFJfRVJSKGNsayk7CisJCX0KKworCQlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUo Y2xrKTsKKwkJaWYgKHJldCA8IDApIHsKKwkJCXdoaWxlICgtLWkgPj0gMCkgeworCQkJCWNsa19k aXNhYmxlX3VucHJlcGFyZShxY29tLT5jbGtzW2ldKTsKKwkJCQljbGtfcHV0KHFjb20tPmNsa3Nb aV0pOworCQkJfQorCQkJY2xrX3B1dChjbGspOworCisJCQlyZXR1cm4gcmV0OworCQl9CisKKwkJ cWNvbS0+Y2xrc1tpXSA9IGNsazsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBk d2MzX3Fjb21fcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3Qg ZGV2aWNlX25vZGUJKm5wID0gcGRldi0+ZGV2Lm9mX25vZGUsICpkd2MzX25wOworCXN0cnVjdCBk ZXZpY2UJCSpkZXYgPSAmcGRldi0+ZGV2OworCXN0cnVjdCBkd2MzX3Fjb20JKnFjb207CisJc3Ry dWN0IHJlc291cmNlCQkqcmVzOworCWludAkJCXJldCwgaTsKKwlib29sCQkJaWdub3JlX3BpcGVf Y2xrOworCisJcWNvbSA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2YoKnFjb20pLCBH RlBfS0VSTkVMKTsKKwlpZiAoIXFjb20pCisJCXJldHVybiAtRU5PTUVNOworCisJcGxhdGZvcm1f c2V0X2RydmRhdGEocGRldiwgcWNvbSk7CisJcWNvbS0+ZGV2ID0gJnBkZXYtPmRldjsKKworCXFj b20tPnJlc2V0cyA9IGRldm1fcmVzZXRfY29udHJvbF9hcnJheV9nZXRfb3B0aW9uYWxfZXhjbHVz aXZlKGRldik7CisJaWYgKElTX0VSUihxY29tLT5yZXNldHMpKSB7CisJCXJldCA9IFBUUl9FUlIo cWNvbS0+cmVzZXRzKTsKKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFpbGVkIHRvIGdldCByZXNl dHMsIGVycj0lZFxuIiwgcmV0KTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXQgPSByZXNldF9j b250cm9sX2Fzc2VydChxY29tLT5yZXNldHMpOworCWlmIChyZXQpIHsKKwkJZGV2X2VycigmcGRl di0+ZGV2LCAiZmFpbGVkIHRvIGFzc2VydCByZXNldHMsIGVycj0lZFxuIiwgcmV0KTsKKwkJcmV0 dXJuIHJldDsKKwl9CisKKwl1c2xlZXBfcmFuZ2UoMTAsIDEwMDApOworCisJcmV0ID0gcmVzZXRf Y29udHJvbF9kZWFzc2VydChxY29tLT5yZXNldHMpOworCWlmIChyZXQpIHsKKwkJZGV2X2Vycigm cGRldi0+ZGV2LCAiZmFpbGVkIHRvIGRlYXNzZXJ0IHJlc2V0cywgZXJyPSVkXG4iLCByZXQpOwor CQlnb3RvIHJlc2V0X2Fzc2VydDsKKwl9CisKKwlyZXQgPSBkd2MzX3Fjb21fY2xrX2luaXQocWNv bSwgb2ZfY291bnRfcGhhbmRsZV93aXRoX2FyZ3MobnAsCisJCQkJCQkiY2xvY2tzIiwgIiNjbG9j ay1jZWxscyIpKTsKKwlpZiAocmV0KSB7CisJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGdldCBj bG9ja3NcbiIpOworCQlnb3RvIHJlc2V0X2Fzc2VydDsKKwl9CisKKwlyZXMgPSBwbGF0Zm9ybV9n ZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOworCXFjb20tPnFzY3JhdGNoX2Jh c2UgPSBkZXZtX2lvcmVtYXBfcmVzb3VyY2UoZGV2LCByZXMpOworCWlmIChJU19FUlIocWNvbS0+ cXNjcmF0Y2hfYmFzZSkpIHsKKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gbWFwIHFzY3JhdGNo LCBlcnI9JWRcbiIsIHJldCk7CisJCXJldCA9IFBUUl9FUlIocWNvbS0+cXNjcmF0Y2hfYmFzZSk7 CisJCWdvdG8gY2xrX2Rpc2FibGU7CisJfQorCisJcmV0ID0gZHdjM19xY29tX3NldHVwX2lycShw ZGV2KTsKKwlpZiAocmV0KQorCQlnb3RvIGNsa19kaXNhYmxlOworCisJZHdjM19ucCA9IG9mX2dl dF9jaGlsZF9ieV9uYW1lKG5wLCAiZHdjMyIpOworCWlmICghZHdjM19ucCkgeworCQlkZXZfZXJy KGRldiwgImZhaWxlZCB0byBmaW5kIGR3YzMgY29yZSBjaGlsZFxuIik7CisJCXJldCA9IC1FTk9E RVY7CisJCWdvdG8gY2xrX2Rpc2FibGU7CisJfQorCisJLyoKKwkgKiBEaXNhYmxlIHBpcGVfY2xr IHJlcXVpcmVtZW50IGlmIHNwZWNpZmllZC4gVXNlZCB3aGVuIGR3YzMKKwkgKiBvcGVyYXRlcyB3 aXRob3V0IFNTUEhZIGFuZCBvbmx5IEhTL0ZTL0xTIG1vZGVzIGFyZSBzdXBwb3J0ZWQuCisJICov CisJaWdub3JlX3BpcGVfY2xrID0gZGV2aWNlX3Byb3BlcnR5X3JlYWRfYm9vbChkZXYsCisJCQkJ InFjb20sc2VsZWN0LXV0bWktYXMtcGlwZS1jbGsiKTsKKwlpZiAoaWdub3JlX3BpcGVfY2xrKQor CQlkd2MzX3Fjb21fc2VsZWN0X3V0bWlfY2xrKHFjb20pOworCisJcmV0ID0gb2ZfcGxhdGZvcm1f cG9wdWxhdGUobnAsIE5VTEwsIE5VTEwsIGRldik7CisJaWYgKHJldCkgeworCQlkZXZfZXJyKGRl diwgImZhaWxlZCB0byByZWdpc3RlciBkd2MzIGNvcmUgLSAlZFxuIiwgcmV0KTsKKwkJZ290byBj bGtfZGlzYWJsZTsKKwl9CisKKwlxY29tLT5kd2MzID0gb2ZfZmluZF9kZXZpY2VfYnlfbm9kZShk d2MzX25wKTsKKwlpZiAoIXFjb20tPmR3YzMpIHsKKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiZmFp bGVkIHRvIGdldCBkd2MzIHBsYXRmb3JtIGRldmljZVxuIik7CisJCWdvdG8gZGVwb3B1bGF0ZTsK Kwl9CisKKwlxY29tLT5tb2RlID0gdXNiX2dldF9kcl9tb2RlKCZxY29tLT5kd2MzLT5kZXYpOwor CisJLyogZW5hYmxlIHZidXMgb3ZlcnJpZGUgZm9yIGRldmljZSBtb2RlICovCisJaWYgKHFjb20t Pm1vZGUgPT0gVVNCX0RSX01PREVfUEVSSVBIRVJBTCkKKwkJZHdjM19xY29tX3ZidXNfb3ZlcnJy aWRlX2VuYWJsZShxY29tLCB0cnVlKTsKKworCS8qIHJlZ2lzdGVyIGV4dGNvbiB0byBvdmVycmlk ZSBzd192YnVzIG9uIFZidXMgY2hhbmdlIGxhdGVyICovCisJcmV0ID0gZHdjM19xY29tX3JlZ2lz dGVyX2V4dGNvbihxY29tKTsKKwlpZiAocmV0KQorCQlnb3RvIGRlcG9wdWxhdGU7CisKKwlkZXZp Y2VfaW5pdF93YWtldXAoJnBkZXYtPmRldiwgMSk7CisJcWNvbS0+aXNfc3VzcGVuZGVkID0gZmFs c2U7CisJcG1fcnVudGltZV9zZXRfYWN0aXZlKGRldik7CisJcG1fcnVudGltZV9lbmFibGUoZGV2 KTsKKwlwbV9ydW50aW1lX2ZvcmJpZChkZXYpOworCisJcmV0dXJuIDA7CisKK2RlcG9wdWxhdGU6 CisJb2ZfcGxhdGZvcm1fZGVwb3B1bGF0ZSgmcGRldi0+ZGV2KTsKK2Nsa19kaXNhYmxlOgorCWZv ciAoaSA9IHFjb20tPm51bV9jbG9ja3MgLSAxOyBpID49IDA7IGktLSkgeworCQljbGtfZGlzYWJs ZV91bnByZXBhcmUocWNvbS0+Y2xrc1tpXSk7CisJCWNsa19wdXQocWNvbS0+Y2xrc1tpXSk7CisJ fQorcmVzZXRfYXNzZXJ0OgorCXJlc2V0X2NvbnRyb2xfYXNzZXJ0KHFjb20tPnJlc2V0cyk7CisK KwlyZXR1cm4gcmV0OworfQorCitzdGF0aWMgaW50IGR3YzNfcWNvbV9yZW1vdmUoc3RydWN0IHBs YXRmb3JtX2RldmljZSAqcGRldikKK3sKKwlzdHJ1Y3QgZHdjM19xY29tICpxY29tID0gcGxhdGZv cm1fZ2V0X2RydmRhdGEocGRldik7CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsK KwlpbnQgaTsKKworCW9mX3BsYXRmb3JtX2RlcG9wdWxhdGUoZGV2KTsKKworCWZvciAoaSA9IHFj b20tPm51bV9jbG9ja3MgLSAxOyBpID49IDA7IGktLSkgeworCQljbGtfZGlzYWJsZV91bnByZXBh cmUocWNvbS0+Y2xrc1tpXSk7CisJCWNsa19wdXQocWNvbS0+Y2xrc1tpXSk7CisJfQorCXFjb20t Pm51bV9jbG9ja3MgPSAwOworCisJcmVzZXRfY29udHJvbF9hc3NlcnQocWNvbS0+cmVzZXRzKTsK KworCXBtX3J1bnRpbWVfYWxsb3coZGV2KTsKKwlwbV9ydW50aW1lX2Rpc2FibGUoZGV2KTsKKwor CXJldHVybiAwOworfQorCisjaWZkZWYgQ09ORklHX1BNX1NMRUVQCitzdGF0aWMgaW50IGR3YzNf cWNvbV9wbV9zdXNwZW5kKHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgZHdjM19xY29t ICpxY29tID0gZGV2X2dldF9kcnZkYXRhKGRldik7CisJaW50IHJldCA9IDA7CisKKwlyZXQgPSBk d2MzX3Fjb21fc3VzcGVuZChxY29tKTsKKwlpZiAoIXJldCkKKwkJcWNvbS0+cG1fc3VzcGVuZGVk ID0gdHJ1ZTsKKworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgZHdjM19xY29tX3BtX3Jl c3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYpCit7CisJc3RydWN0IGR3YzNfcWNvbSAqcWNvbSA9IGRl dl9nZXRfZHJ2ZGF0YShkZXYpOworCWludCByZXQ7CisKKwlyZXQgPSBkd2MzX3Fjb21fcmVzdW1l KHFjb20pOworCWlmICghcmV0KQorCQlxY29tLT5wbV9zdXNwZW5kZWQgPSBmYWxzZTsKKworCXJl dHVybiByZXQ7Cit9CisjZW5kaWYKKworI2lmZGVmIENPTkZJR19QTQorc3RhdGljIGludCBkd2Mz X3Fjb21fcnVudGltZV9zdXNwZW5kKHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgZHdj M19xY29tICpxY29tID0gZGV2X2dldF9kcnZkYXRhKGRldik7CisKKwlyZXR1cm4gZHdjM19xY29t X3N1c3BlbmQocWNvbSk7Cit9CisKK3N0YXRpYyBpbnQgZHdjM19xY29tX3J1bnRpbWVfcmVzdW1l KHN0cnVjdCBkZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgZHdjM19xY29tICpxY29tID0gZGV2X2dl dF9kcnZkYXRhKGRldik7CisKKwlyZXR1cm4gZHdjM19xY29tX3Jlc3VtZShxY29tKTsKK30KKyNl bmRpZgorCitzdGF0aWMgY29uc3Qgc3RydWN0IGRldl9wbV9vcHMgZHdjM19xY29tX2Rldl9wbV9v cHMgPSB7CisJU0VUX1NZU1RFTV9TTEVFUF9QTV9PUFMoZHdjM19xY29tX3BtX3N1c3BlbmQsIGR3 YzNfcWNvbV9wbV9yZXN1bWUpCisJU0VUX1JVTlRJTUVfUE1fT1BTKGR3YzNfcWNvbV9ydW50aW1l X3N1c3BlbmQsIGR3YzNfcWNvbV9ydW50aW1lX3Jlc3VtZSwKKwkJCSAgIE5VTEwpCit9OworCitz dGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBkd2MzX3Fjb21fb2ZfbWF0Y2hbXSA9IHsK Kwl7IC5jb21wYXRpYmxlID0gInFjb20sZHdjMyIgfSwKKwl7IH0KK307CitNT0RVTEVfREVWSUNF X1RBQkxFKG9mLCBkd2MzX3Fjb21fb2ZfbWF0Y2gpOworCitzdGF0aWMgc3RydWN0IHBsYXRmb3Jt X2RyaXZlciBkd2MzX3Fjb21fZHJpdmVyID0geworCS5wcm9iZQkJPSBkd2MzX3Fjb21fcHJvYmUs CisJLnJlbW92ZQkJPSBkd2MzX3Fjb21fcmVtb3ZlLAorCS5kcml2ZXIJCT0geworCQkubmFtZQk9 ICJkd2MzLXFjb20iLAorCQkucG0JPSAmZHdjM19xY29tX2Rldl9wbV9vcHMsCisJCS5vZl9tYXRj aF90YWJsZQk9IGR3YzNfcWNvbV9vZl9tYXRjaCwKKwl9LAorfTsKKworbW9kdWxlX3BsYXRmb3Jt X2RyaXZlcihkd2MzX3Fjb21fZHJpdmVyKTsKKworTU9EVUxFX0xJQ0VOU0UoIkdQTCB2MiIpOwor TU9EVUxFX0RFU0NSSVBUSU9OKCJEZXNpZ25XYXJlIERXQzMgUUNPTSBHbHVlIERyaXZlciIpOwo=