From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from m12-16.163.com ([220.181.12.16]:33492 "EHLO m12-16.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751096AbeEEKL0 (ORCPT ); Sat, 5 May 2018 06:11:26 -0400 From: sunjg79@163.com Subject: [PATCH v2 2/2] xhci: hisilicon: support HiSilicon STB xHCI host controller Date: Sat, 5 May 2018 18:09:50 +0800 Message-Id: <1525514990-18207-3-git-send-email-sunjg79@163.com> In-Reply-To: <1525514990-18207-1-git-send-email-sunjg79@163.com> References: <1525514990-18207-1-git-send-email-sunjg79@163.com> Sender: devicetree-owner@vger.kernel.org To: mathias.nyman@intel.com, gregkh@linuxfoundation.org, robh+dt@kernel.org Cc: shawn.guo@linaro.org, xuejiancheng@hisilicon.com, chunfeng.yun@mediatek.com, linux-usb@vger.kernel.org, devicetree@vger.kernel.org, Jianguo Sun List-ID: From: Jianguo Sun This commit adds support for HiSilicon STB xHCI host controller. There are two xHCI host controllers on HiSilicon STB SoCs. Each one requires additional configuration before exposing interface compliant with xHCI. Reviewed-by: Chunfeng Yun Signed-off-by: Jianguo Sun --- drivers/usb/host/Kconfig | 7 + drivers/usb/host/Makefile | 1 + drivers/usb/host/xhci-histb.c | 413 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 421 insertions(+) create mode 100644 drivers/usb/host/xhci-histb.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5d958da..c813fc4 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -52,6 +52,13 @@ config USB_XHCI_PLATFORM If unsure, say N. +config USB_XHCI_HISTB + tristate "xHCI support for HiSilicon STB SoCs" + depends on USB_XHCI_PLATFORM && (ARCH_HISI || COMPILE_TEST) + help + Say 'Y' to enable the support for the xHCI host controller + found in HiSilicon STB SoCs. + config USB_XHCI_MTK tristate "xHCI support for MediaTek SoCs" select MFD_SYSCON diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 8a8cffe..9b669c9 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -74,6 +74,7 @@ obj-$(CONFIG_USB_FHCI_HCD) += fhci.o obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o obj-$(CONFIG_USB_XHCI_PLATFORM) += xhci-plat-hcd.o +obj-$(CONFIG_USB_XHCI_HISTB) += xhci-histb.o obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o obj-$(CONFIG_USB_XHCI_TEGRA) += xhci-tegra.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o diff --git a/drivers/usb/host/xhci-histb.c b/drivers/usb/host/xhci-histb.c new file mode 100644 index 0000000..dda547e --- /dev/null +++ b/drivers/usb/host/xhci-histb.c @@ -0,0 +1,413 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * xHCI host controller driver for HiSilicon STB SoCs + * + * Copyright (C) 2017-2018 HiSilicon Co., Ltd. http://www.hisilicon.com + * + * Authors: Jianguo Sun + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xhci.h" + +#define GTXTHRCFG 0xc108 +#define GRXTHRCFG 0xc10c +#define REG_GUSB2PHYCFG0 0xc200 +#define BIT_UTMI_8_16 BIT(3) +#define BIT_UTMI_ULPI BIT(4) +#define BIT_FREECLK_EXIST BIT(30) + +#define REG_GUSB3PIPECTL0 0xc2c0 +#define USB3_DEEMPHASIS_MASK GENMASK(2, 1) +#define USB3_DEEMPHASIS0 BIT(1) +#define USB3_TX_MARGIN1 BIT(4) + +struct xhci_hcd_histb { + struct device *dev; + struct usb_hcd *hcd; + void __iomem *ctrl; + struct clk *bus_clk; + struct clk *utmi_clk; + struct clk *pipe_clk; + struct clk *suspend_clk; + struct reset_control *soft_reset; +}; + +static inline struct xhci_hcd_histb *hcd_to_histb(struct usb_hcd *hcd) +{ + return dev_get_drvdata(hcd->self.controller); +} + +static int xhci_histb_config(struct xhci_hcd_histb *histb) +{ + struct device_node *np = histb->dev->of_node; + u32 regval; + + if (of_property_match_string(np, "phys-names", "inno") >= 0) { + /* USB2 PHY chose ulpi 8bit interface */ + regval = readl(histb->ctrl + REG_GUSB2PHYCFG0); + regval &= ~BIT_UTMI_ULPI; + regval &= ~(BIT_UTMI_8_16); + regval &= ~BIT_FREECLK_EXIST; + writel(regval, histb->ctrl + REG_GUSB2PHYCFG0); + } + + if (of_property_match_string(np, "phys-names", "combo") >= 0) { + /* + * write 0x010c0012 to GUSB3PIPECTL0 + * GUSB3PIPECTL0[5:3] = 010 : Tx Margin = 900mV , + * decrease TX voltage + * GUSB3PIPECTL0[2:1] = 01 : Tx Deemphasis = -3.5dB, + * refer to xHCI spec + */ + regval = readl(histb->ctrl + REG_GUSB3PIPECTL0); + regval &= ~USB3_DEEMPHASIS_MASK; + regval |= USB3_DEEMPHASIS0; + regval |= USB3_TX_MARGIN1; + writel(regval, histb->ctrl + REG_GUSB3PIPECTL0); + } + + writel(0x23100000, histb->ctrl + GTXTHRCFG); + writel(0x23100000, histb->ctrl + GRXTHRCFG); + + return 0; +} + +static int xhci_histb_clks_get(struct xhci_hcd_histb *histb) +{ + struct device *dev = histb->dev; + + histb->bus_clk = devm_clk_get(dev, "bus"); + if (IS_ERR(histb->bus_clk)) { + dev_err(dev, "fail to get bus clk\n"); + return PTR_ERR(histb->bus_clk); + } + + histb->utmi_clk = devm_clk_get(dev, "utmi"); + if (IS_ERR(histb->utmi_clk)) { + dev_err(dev, "fail to get utmi clk\n"); + return PTR_ERR(histb->utmi_clk); + } + + histb->pipe_clk = devm_clk_get(dev, "pipe"); + if (IS_ERR(histb->pipe_clk)) { + dev_err(dev, "fail to get pipe clk\n"); + return PTR_ERR(histb->pipe_clk); + } + + histb->suspend_clk = devm_clk_get(dev, "suspend"); + if (IS_ERR(histb->suspend_clk)) { + dev_err(dev, "fail to get suspend clk\n"); + return PTR_ERR(histb->suspend_clk); + } + + return 0; +} + +static int xhci_histb_host_enable(struct xhci_hcd_histb *histb) +{ + int ret; + + ret = clk_prepare_enable(histb->bus_clk); + if (ret) { + dev_err(histb->dev, "failed to enable bus clk\n"); + return ret; + } + + ret = clk_prepare_enable(histb->utmi_clk); + if (ret) { + dev_err(histb->dev, "failed to enable utmi clk\n"); + goto err_utmi_clk; + } + + ret = clk_prepare_enable(histb->pipe_clk); + if (ret) { + dev_err(histb->dev, "failed to enable pipe clk\n"); + goto err_pipe_clk; + } + + ret = clk_prepare_enable(histb->suspend_clk); + if (ret) { + dev_err(histb->dev, "failed to enable suspend clk\n"); + goto err_suspend_clk; + } + + reset_control_deassert(histb->soft_reset); + + return 0; + +err_suspend_clk: + clk_disable_unprepare(histb->pipe_clk); +err_pipe_clk: + clk_disable_unprepare(histb->utmi_clk); +err_utmi_clk: + clk_disable_unprepare(histb->bus_clk); + + return ret; +} + +static void xhci_histb_host_disable(struct xhci_hcd_histb *histb) +{ + reset_control_assert(histb->soft_reset); + + clk_disable_unprepare(histb->suspend_clk); + clk_disable_unprepare(histb->pipe_clk); + clk_disable_unprepare(histb->utmi_clk); + clk_disable_unprepare(histb->bus_clk); +} + +static void xhci_histb_quirks(struct device *dev, struct xhci_hcd *xhci) +{ + /* + * As of now platform drivers don't provide MSI support so we ensure + * here that the generic code does not try to make a pci_dev from our + * dev struct in order to setup MSI + */ + xhci->quirks |= XHCI_PLAT; +} + +/* called during probe() after chip reset completes */ +static int xhci_histb_setup(struct usb_hcd *hcd) +{ + struct xhci_hcd_histb *histb = hcd_to_histb(hcd); + int ret; + + if (usb_hcd_is_primary_hcd(hcd)) { + ret = xhci_histb_config(histb); + if (ret) + return ret; + } + + return xhci_gen_setup(hcd, xhci_histb_quirks); +} + +static const struct xhci_driver_overrides xhci_histb_overrides __initconst = { + .reset = xhci_histb_setup, +}; + +static struct hc_driver __read_mostly xhci_histb_hc_driver; +static int xhci_histb_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct xhci_hcd_histb *histb; + const struct hc_driver *driver; + struct usb_hcd *hcd; + struct xhci_hcd *xhci; + struct resource *res; + int irq; + int ret = -ENODEV; + + if (usb_disabled()) + return -ENODEV; + + driver = &xhci_histb_hc_driver; + histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL); + if (!histb) + return -ENOMEM; + + histb->dev = dev; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + histb->ctrl = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(histb->ctrl)) + return PTR_ERR(histb->ctrl); + + ret = xhci_histb_clks_get(histb); + if (ret) + return ret; + + histb->soft_reset = devm_reset_control_get(dev, "soft"); + if (IS_ERR(histb->soft_reset)) { + dev_err(dev, "failed to get soft reset\n"); + return PTR_ERR(histb->soft_reset); + } + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + device_enable_async_suspend(dev); + + /* Initialize dma_mask and coherent_dma_mask to 32-bits */ + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + + hcd = usb_create_hcd(driver, dev, dev_name(dev)); + if (!hcd) { + ret = -ENOMEM; + goto disable_pm; + } + + hcd->regs = histb->ctrl; + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + + histb->hcd = hcd; + dev_set_drvdata(hcd->self.controller, histb); + + ret = xhci_histb_host_enable(histb); + if (ret) + goto put_hcd; + + xhci = hcd_to_xhci(hcd); + + device_wakeup_enable(hcd->self.controller); + + xhci->main_hcd = hcd; + xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev), + hcd); + if (!xhci->shared_hcd) { + ret = -ENOMEM; + goto disable_host; + } + + if (device_property_read_bool(dev, "usb2-lpm-disable")) + xhci->quirks |= XHCI_HW_LPM_DISABLE; + + if (device_property_read_bool(dev, "usb3-lpm-capable")) + xhci->quirks |= XHCI_LPM_SUPPORT; + + if (device_property_read_bool(dev, "quirk-broken-port-ped")) + xhci->quirks |= XHCI_BROKEN_PORT_PED; + + /* imod_interval is the interrupt moderation value in nanoseconds. */ + xhci->imod_interval = 40000; + device_property_read_u32(dev, "imod-interval-ns", + &xhci->imod_interval); + + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (ret) + goto put_usb3_hcd; + + if (HCC_MAX_PSA(xhci->hcc_params) >= 4) + xhci->shared_hcd->can_do_streams = 1; + + ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); + if (ret) + goto dealloc_usb2_hcd; + + device_enable_async_suspend(dev); + pm_runtime_put_noidle(dev); + + /* + * Prevent runtime pm from being on as default, users should enable + * runtime pm using power/control in sysfs. + */ + pm_runtime_forbid(dev); + + return 0; + +dealloc_usb2_hcd: + usb_remove_hcd(hcd); +put_usb3_hcd: + usb_put_hcd(xhci->shared_hcd); +disable_host: + xhci_histb_host_disable(histb); +put_hcd: + usb_put_hcd(hcd); +disable_pm: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + + return ret; +} + +static int xhci_histb_remove(struct platform_device *dev) +{ + struct xhci_hcd_histb *histb = platform_get_drvdata(dev); + struct usb_hcd *hcd = histb->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + xhci->xhc_state |= XHCI_STATE_REMOVING; + + usb_remove_hcd(xhci->shared_hcd); + device_wakeup_disable(&dev->dev); + + usb_remove_hcd(hcd); + usb_put_hcd(xhci->shared_hcd); + + xhci_histb_host_disable(histb); + usb_put_hcd(hcd); + pm_runtime_put_sync(&dev->dev); + pm_runtime_disable(&dev->dev); + + return 0; +} + +static int __maybe_unused xhci_histb_suspend(struct device *dev) +{ + struct xhci_hcd_histb *histb = dev_get_drvdata(dev); + struct usb_hcd *hcd = histb->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + int ret; + + ret = xhci_suspend(xhci, device_may_wakeup(dev)); + + if (!device_may_wakeup(dev)) + xhci_histb_host_disable(histb); + + return ret; +} + +static int __maybe_unused xhci_histb_resume(struct device *dev) +{ + struct xhci_hcd_histb *histb = dev_get_drvdata(dev); + struct usb_hcd *hcd = histb->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + if (!device_may_wakeup(dev)) + xhci_histb_host_enable(histb); + + return xhci_resume(xhci, 0); +} + +static const struct dev_pm_ops xhci_histb_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(xhci_histb_suspend, xhci_histb_resume) +}; +#define DEV_PM_OPS (IS_ENABLED(CONFIG_PM) ? &xhci_histb_pm_ops : NULL) + +#ifdef CONFIG_OF +static const struct of_device_id histb_xhci_of_match[] = { + { .compatible = "hisilicon,hi3798cv200-xhci"}, + { }, +}; +MODULE_DEVICE_TABLE(of, histb_xhci_of_match); +#endif + +static struct platform_driver histb_xhci_driver = { + .probe = xhci_histb_probe, + .remove = xhci_histb_remove, + .driver = { + .name = "xhci-histb", + .pm = DEV_PM_OPS, + .of_match_table = of_match_ptr(histb_xhci_of_match), + }, +}; +MODULE_ALIAS("platform:xhci-histb"); + +static int __init xhci_histb_init(void) +{ + xhci_init_driver(&xhci_histb_hc_driver, &xhci_histb_overrides); + return platform_driver_register(&histb_xhci_driver); +} +module_init(xhci_histb_init); + +static void __exit xhci_histb_exit(void) +{ + platform_driver_unregister(&histb_xhci_driver); +} +module_exit(xhci_histb_exit); + +MODULE_DESCRIPTION("HiSilicon STB xHCI Host Controller Driver"); +MODULE_LICENSE("GPL v2"); -- 2.7.4 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/2] xhci: hisilicon: support HiSilicon STB xHCI host controller From: sunjg79@163.com Message-Id: <1525514990-18207-3-git-send-email-sunjg79@163.com> Date: Sat, 5 May 2018 18:09:50 +0800 To: mathias.nyman@intel.com, gregkh@linuxfoundation.org, robh+dt@kernel.org Cc: shawn.guo@linaro.org, xuejiancheng@hisilicon.com, chunfeng.yun@mediatek.com, linux-usb@vger.kernel.org, devicetree@vger.kernel.org, Jianguo Sun List-ID: RnJvbTogSmlhbmd1byBTdW4gPHN1bmppYW5ndW8xQGh1YXdlaS5jb20+CgpUaGlzIGNvbW1pdCBh ZGRzIHN1cHBvcnQgZm9yIEhpU2lsaWNvbiBTVEIgeEhDSSBob3N0IGNvbnRyb2xsZXIuClRoZXJl IGFyZSB0d28geEhDSSBob3N0IGNvbnRyb2xsZXJzIG9uIEhpU2lsaWNvbiBTVEIgU29Dcy4gRWFj aApvbmUgcmVxdWlyZXMgYWRkaXRpb25hbCBjb25maWd1cmF0aW9uIGJlZm9yZSBleHBvc2luZyBp bnRlcmZhY2UKY29tcGxpYW50IHdpdGggeEhDSS4KClJldmlld2VkLWJ5OiBDaHVuZmVuZyBZdW4g PGNodW5mZW5nLnl1bkBtZWRpYXRlay5jb20+ClNpZ25lZC1vZmYtYnk6IEppYW5ndW8gU3VuIDxz dW5qaWFuZ3VvMUBodWF3ZWkuY29tPgotLS0KIGRyaXZlcnMvdXNiL2hvc3QvS2NvbmZpZyAgICAg IHwgICA3ICsKIGRyaXZlcnMvdXNiL2hvc3QvTWFrZWZpbGUgICAgIHwgICAxICsKIGRyaXZlcnMv dXNiL2hvc3QveGhjaS1oaXN0Yi5jIHwgNDEzICsrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKwogMyBmaWxlcyBjaGFuZ2VkLCA0MjEgaW5zZXJ0aW9ucygrKQogY3JlYXRl IG1vZGUgMTAwNjQ0IGRyaXZlcnMvdXNiL2hvc3QveGhjaS1oaXN0Yi5jCgpkaWZmIC0tZ2l0IGEv ZHJpdmVycy91c2IvaG9zdC9LY29uZmlnIGIvZHJpdmVycy91c2IvaG9zdC9LY29uZmlnCmluZGV4 IDVkOTU4ZGEuLmM4MTNmYzQgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdXNiL2hvc3QvS2NvbmZpZwor KysgYi9kcml2ZXJzL3VzYi9ob3N0L0tjb25maWcKQEAgLTUyLDYgKzUyLDEzIEBAIGNvbmZpZyBV U0JfWEhDSV9QTEFURk9STQogCiAJICBJZiB1bnN1cmUsIHNheSBOLgogCitjb25maWcgVVNCX1hI Q0lfSElTVEIKKwl0cmlzdGF0ZSAieEhDSSBzdXBwb3J0IGZvciBIaVNpbGljb24gU1RCIFNvQ3Mi CisJZGVwZW5kcyBvbiBVU0JfWEhDSV9QTEFURk9STSAmJiAoQVJDSF9ISVNJIHx8IENPTVBJTEVf VEVTVCkKKwloZWxwCisJICBTYXkgJ1knIHRvIGVuYWJsZSB0aGUgc3VwcG9ydCBmb3IgdGhlIHhI Q0kgaG9zdCBjb250cm9sbGVyCisJICBmb3VuZCBpbiBIaVNpbGljb24gU1RCIFNvQ3MuCisKIGNv bmZpZyBVU0JfWEhDSV9NVEsKIAl0cmlzdGF0ZSAieEhDSSBzdXBwb3J0IGZvciBNZWRpYVRlayBT b0NzIgogCXNlbGVjdCBNRkRfU1lTQ09OCmRpZmYgLS1naXQgYS9kcml2ZXJzL3VzYi9ob3N0L01h a2VmaWxlIGIvZHJpdmVycy91c2IvaG9zdC9NYWtlZmlsZQppbmRleCA4YThjZmZlLi45YjY2OWM5 IDEwMDY0NAotLS0gYS9kcml2ZXJzL3VzYi9ob3N0L01ha2VmaWxlCisrKyBiL2RyaXZlcnMvdXNi L2hvc3QvTWFrZWZpbGUKQEAgLTc0LDYgKzc0LDcgQEAgb2JqLSQoQ09ORklHX1VTQl9GSENJX0hD RCkJKz0gZmhjaS5vCiBvYmotJChDT05GSUdfVVNCX1hIQ0lfSENEKQkrPSB4aGNpLWhjZC5vCiBv YmotJChDT05GSUdfVVNCX1hIQ0lfUENJKQkrPSB4aGNpLXBjaS5vCiBvYmotJChDT05GSUdfVVNC X1hIQ0lfUExBVEZPUk0pICs9IHhoY2ktcGxhdC1oY2Qubworb2JqLSQoQ09ORklHX1VTQl9YSENJ X0hJU1RCKQkrPSB4aGNpLWhpc3RiLm8KIG9iai0kKENPTkZJR19VU0JfWEhDSV9NVEspCSs9IHho Y2ktbXRrLm8KIG9iai0kKENPTkZJR19VU0JfWEhDSV9URUdSQSkJKz0geGhjaS10ZWdyYS5vCiBv YmotJChDT05GSUdfVVNCX1NMODExX0hDRCkJKz0gc2w4MTEtaGNkLm8KZGlmZiAtLWdpdCBhL2Ry aXZlcnMvdXNiL2hvc3QveGhjaS1oaXN0Yi5jIGIvZHJpdmVycy91c2IvaG9zdC94aGNpLWhpc3Ri LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGRhNTQ3ZQotLS0gL2Rldi9u dWxsCisrKyBiL2RyaXZlcnMvdXNiL2hvc3QveGhjaS1oaXN0Yi5jCkBAIC0wLDAgKzEsNDEzIEBA CisvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAorLyoKKyAqIHhIQ0kgaG9zdCBj b250cm9sbGVyIGRyaXZlciBmb3IgSGlTaWxpY29uIFNUQiBTb0NzCisgKgorICogQ29weXJpZ2h0 IChDKSAyMDE3LTIwMTggSGlTaWxpY29uIENvLiwgTHRkLiBodHRwOi8vd3d3Lmhpc2lsaWNvbi5j b20KKyAqCisgKiBBdXRob3JzOiBKaWFuZ3VvIFN1biA8c3Vuamlhbmd1bzFAaHVhd2VpLmNvbT4K KyAqLworCisjaW5jbHVkZSA8bGludXgvY2xrLmg+CisjaW5jbHVkZSA8bGludXgvZG1hLW1hcHBp bmcuaD4KKyNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUu aD4KKyNpbmNsdWRlIDxsaW51eC9vZi5oPgorI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2Rldmlj ZS5oPgorI2luY2x1ZGUgPGxpbnV4L3BtX3J1bnRpbWUuaD4KKyNpbmNsdWRlIDxsaW51eC9yZXNl dC5oPgorCisjaW5jbHVkZSAieGhjaS5oIgorCisjZGVmaW5lIEdUWFRIUkNGRwkJMHhjMTA4Cisj ZGVmaW5lIEdSWFRIUkNGRwkJMHhjMTBjCisjZGVmaW5lIFJFR19HVVNCMlBIWUNGRzAJMHhjMjAw CisjZGVmaW5lIEJJVF9VVE1JXzhfMTYJCUJJVCgzKQorI2RlZmluZSBCSVRfVVRNSV9VTFBJCQlC SVQoNCkKKyNkZWZpbmUgQklUX0ZSRUVDTEtfRVhJU1QJQklUKDMwKQorCisjZGVmaW5lIFJFR19H VVNCM1BJUEVDVEwwCTB4YzJjMAorI2RlZmluZSBVU0IzX0RFRU1QSEFTSVNfTUFTSwlHRU5NQVNL KDIsIDEpCisjZGVmaW5lIFVTQjNfREVFTVBIQVNJUzAJQklUKDEpCisjZGVmaW5lIFVTQjNfVFhf TUFSR0lOMQkJQklUKDQpCisKK3N0cnVjdCB4aGNpX2hjZF9oaXN0YiB7CisJc3RydWN0IGRldmlj ZQkJKmRldjsKKwlzdHJ1Y3QgdXNiX2hjZAkJKmhjZDsKKwl2b2lkIF9faW9tZW0JCSpjdHJsOwor CXN0cnVjdCBjbGsJCSpidXNfY2xrOworCXN0cnVjdCBjbGsJCSp1dG1pX2NsazsKKwlzdHJ1Y3Qg Y2xrCQkqcGlwZV9jbGs7CisJc3RydWN0IGNsawkJKnN1c3BlbmRfY2xrOworCXN0cnVjdCByZXNl dF9jb250cm9sCSpzb2Z0X3Jlc2V0OworfTsKKworc3RhdGljIGlubGluZSBzdHJ1Y3QgeGhjaV9o Y2RfaGlzdGIgKmhjZF90b19oaXN0YihzdHJ1Y3QgdXNiX2hjZCAqaGNkKQoreworCXJldHVybiBk ZXZfZ2V0X2RydmRhdGEoaGNkLT5zZWxmLmNvbnRyb2xsZXIpOworfQorCitzdGF0aWMgaW50IHho Y2lfaGlzdGJfY29uZmlnKHN0cnVjdCB4aGNpX2hjZF9oaXN0YiAqaGlzdGIpCit7CisJc3RydWN0 IGRldmljZV9ub2RlICpucCA9IGhpc3RiLT5kZXYtPm9mX25vZGU7CisJdTMyIHJlZ3ZhbDsKKwor CWlmIChvZl9wcm9wZXJ0eV9tYXRjaF9zdHJpbmcobnAsICJwaHlzLW5hbWVzIiwgImlubm8iKSA+ PSAwKSB7CisJCS8qIFVTQjIgUEhZIGNob3NlIHVscGkgOGJpdCBpbnRlcmZhY2UgKi8KKwkJcmVn dmFsID0gcmVhZGwoaGlzdGItPmN0cmwgKyBSRUdfR1VTQjJQSFlDRkcwKTsKKwkJcmVndmFsICY9 IH5CSVRfVVRNSV9VTFBJOworCQlyZWd2YWwgJj0gfihCSVRfVVRNSV84XzE2KTsKKwkJcmVndmFs ICY9IH5CSVRfRlJFRUNMS19FWElTVDsKKwkJd3JpdGVsKHJlZ3ZhbCwgaGlzdGItPmN0cmwgKyBS RUdfR1VTQjJQSFlDRkcwKTsKKwl9CisKKwlpZiAob2ZfcHJvcGVydHlfbWF0Y2hfc3RyaW5nKG5w LCAicGh5cy1uYW1lcyIsICJjb21ibyIpID49IDApIHsKKwkJLyoKKwkJICogd3JpdGUgMHgwMTBj MDAxMiB0byBHVVNCM1BJUEVDVEwwCisJCSAqIEdVU0IzUElQRUNUTDBbNTozXSA9IDAxMCA6IFR4 IE1hcmdpbiA9IDkwMG1WICwKKwkJICogZGVjcmVhc2UgVFggdm9sdGFnZQorCQkgKiBHVVNCM1BJ UEVDVEwwWzI6MV0gPSAwMSA6IFR4IERlZW1waGFzaXMgPSAtMy41ZEIsCisJCSAqIHJlZmVyIHRv IHhIQ0kgc3BlYworCQkgKi8KKwkJcmVndmFsID0gcmVhZGwoaGlzdGItPmN0cmwgKyBSRUdfR1VT QjNQSVBFQ1RMMCk7CisJCXJlZ3ZhbCAmPSB+VVNCM19ERUVNUEhBU0lTX01BU0s7CisJCXJlZ3Zh bCB8PSBVU0IzX0RFRU1QSEFTSVMwOworCQlyZWd2YWwgfD0gVVNCM19UWF9NQVJHSU4xOworCQl3 cml0ZWwocmVndmFsLCBoaXN0Yi0+Y3RybCArIFJFR19HVVNCM1BJUEVDVEwwKTsKKwl9CisKKwl3 cml0ZWwoMHgyMzEwMDAwMCwgaGlzdGItPmN0cmwgKyBHVFhUSFJDRkcpOworCXdyaXRlbCgweDIz MTAwMDAwLCBoaXN0Yi0+Y3RybCArIEdSWFRIUkNGRyk7CisKKwlyZXR1cm4gMDsKK30KKworc3Rh dGljIGludCB4aGNpX2hpc3RiX2Nsa3NfZ2V0KHN0cnVjdCB4aGNpX2hjZF9oaXN0YiAqaGlzdGIp Cit7CisJc3RydWN0IGRldmljZSAqZGV2ID0gaGlzdGItPmRldjsKKworCWhpc3RiLT5idXNfY2xr ID0gZGV2bV9jbGtfZ2V0KGRldiwgImJ1cyIpOworCWlmIChJU19FUlIoaGlzdGItPmJ1c19jbGsp KSB7CisJCWRldl9lcnIoZGV2LCAiZmFpbCB0byBnZXQgYnVzIGNsa1xuIik7CisJCXJldHVybiBQ VFJfRVJSKGhpc3RiLT5idXNfY2xrKTsKKwl9CisKKwloaXN0Yi0+dXRtaV9jbGsgPSBkZXZtX2Ns a19nZXQoZGV2LCAidXRtaSIpOworCWlmIChJU19FUlIoaGlzdGItPnV0bWlfY2xrKSkgeworCQlk ZXZfZXJyKGRldiwgImZhaWwgdG8gZ2V0IHV0bWkgY2xrXG4iKTsKKwkJcmV0dXJuIFBUUl9FUlIo aGlzdGItPnV0bWlfY2xrKTsKKwl9CisKKwloaXN0Yi0+cGlwZV9jbGsgPSBkZXZtX2Nsa19nZXQo ZGV2LCAicGlwZSIpOworCWlmIChJU19FUlIoaGlzdGItPnBpcGVfY2xrKSkgeworCQlkZXZfZXJy KGRldiwgImZhaWwgdG8gZ2V0IHBpcGUgY2xrXG4iKTsKKwkJcmV0dXJuIFBUUl9FUlIoaGlzdGIt PnBpcGVfY2xrKTsKKwl9CisKKwloaXN0Yi0+c3VzcGVuZF9jbGsgPSBkZXZtX2Nsa19nZXQoZGV2 LCAic3VzcGVuZCIpOworCWlmIChJU19FUlIoaGlzdGItPnN1c3BlbmRfY2xrKSkgeworCQlkZXZf ZXJyKGRldiwgImZhaWwgdG8gZ2V0IHN1c3BlbmQgY2xrXG4iKTsKKwkJcmV0dXJuIFBUUl9FUlIo aGlzdGItPnN1c3BlbmRfY2xrKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCB4 aGNpX2hpc3RiX2hvc3RfZW5hYmxlKHN0cnVjdCB4aGNpX2hjZF9oaXN0YiAqaGlzdGIpCit7CisJ aW50IHJldDsKKworCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShoaXN0Yi0+YnVzX2Nsayk7CisJ aWYgKHJldCkgeworCQlkZXZfZXJyKGhpc3RiLT5kZXYsICJmYWlsZWQgdG8gZW5hYmxlIGJ1cyBj bGtcbiIpOworCQlyZXR1cm4gcmV0OworCX0KKworCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZSho aXN0Yi0+dXRtaV9jbGspOworCWlmIChyZXQpIHsKKwkJZGV2X2VycihoaXN0Yi0+ZGV2LCAiZmFp bGVkIHRvIGVuYWJsZSB1dG1pIGNsa1xuIik7CisJCWdvdG8gZXJyX3V0bWlfY2xrOworCX0KKwor CXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShoaXN0Yi0+cGlwZV9jbGspOworCWlmIChyZXQpIHsK KwkJZGV2X2VycihoaXN0Yi0+ZGV2LCAiZmFpbGVkIHRvIGVuYWJsZSBwaXBlIGNsa1xuIik7CisJ CWdvdG8gZXJyX3BpcGVfY2xrOworCX0KKworCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShoaXN0 Yi0+c3VzcGVuZF9jbGspOworCWlmIChyZXQpIHsKKwkJZGV2X2VycihoaXN0Yi0+ZGV2LCAiZmFp bGVkIHRvIGVuYWJsZSBzdXNwZW5kIGNsa1xuIik7CisJCWdvdG8gZXJyX3N1c3BlbmRfY2xrOwor CX0KKworCXJlc2V0X2NvbnRyb2xfZGVhc3NlcnQoaGlzdGItPnNvZnRfcmVzZXQpOworCisJcmV0 dXJuIDA7CisKK2Vycl9zdXNwZW5kX2NsazoKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaGlzdGIt PnBpcGVfY2xrKTsKK2Vycl9waXBlX2NsazoKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaGlzdGIt PnV0bWlfY2xrKTsKK2Vycl91dG1pX2NsazoKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaGlzdGIt PmJ1c19jbGspOworCisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIHZvaWQgeGhjaV9oaXN0Yl9o b3N0X2Rpc2FibGUoc3RydWN0IHhoY2lfaGNkX2hpc3RiICpoaXN0YikKK3sKKwlyZXNldF9jb250 cm9sX2Fzc2VydChoaXN0Yi0+c29mdF9yZXNldCk7CisKKwljbGtfZGlzYWJsZV91bnByZXBhcmUo aGlzdGItPnN1c3BlbmRfY2xrKTsKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaGlzdGItPnBpcGVf Y2xrKTsKKwljbGtfZGlzYWJsZV91bnByZXBhcmUoaGlzdGItPnV0bWlfY2xrKTsKKwljbGtfZGlz YWJsZV91bnByZXBhcmUoaGlzdGItPmJ1c19jbGspOworfQorCitzdGF0aWMgdm9pZCB4aGNpX2hp c3RiX3F1aXJrcyhzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCB4aGNpX2hjZCAqeGhjaSkKK3sK KwkvKgorCSAqIEFzIG9mIG5vdyBwbGF0Zm9ybSBkcml2ZXJzIGRvbid0IHByb3ZpZGUgTVNJIHN1 cHBvcnQgc28gd2UgZW5zdXJlCisJICogaGVyZSB0aGF0IHRoZSBnZW5lcmljIGNvZGUgZG9lcyBu b3QgdHJ5IHRvIG1ha2UgYSBwY2lfZGV2IGZyb20gb3VyCisJICogZGV2IHN0cnVjdCBpbiBvcmRl ciB0byBzZXR1cCBNU0kKKwkgKi8KKwl4aGNpLT5xdWlya3MgfD0gWEhDSV9QTEFUOworfQorCisv KiBjYWxsZWQgZHVyaW5nIHByb2JlKCkgYWZ0ZXIgY2hpcCByZXNldCBjb21wbGV0ZXMgKi8KK3N0 YXRpYyBpbnQgeGhjaV9oaXN0Yl9zZXR1cChzdHJ1Y3QgdXNiX2hjZCAqaGNkKQoreworCXN0cnVj dCB4aGNpX2hjZF9oaXN0YiAqaGlzdGIgPSBoY2RfdG9faGlzdGIoaGNkKTsKKwlpbnQgcmV0Owor CisJaWYgKHVzYl9oY2RfaXNfcHJpbWFyeV9oY2QoaGNkKSkgeworCQlyZXQgPSB4aGNpX2hpc3Ri X2NvbmZpZyhoaXN0Yik7CisJCWlmIChyZXQpCisJCQlyZXR1cm4gcmV0OworCX0KKworCXJldHVy biB4aGNpX2dlbl9zZXR1cChoY2QsIHhoY2lfaGlzdGJfcXVpcmtzKTsKK30KKworc3RhdGljIGNv bnN0IHN0cnVjdCB4aGNpX2RyaXZlcl9vdmVycmlkZXMgeGhjaV9oaXN0Yl9vdmVycmlkZXMgX19p bml0Y29uc3QgPSB7CisJLnJlc2V0ID0geGhjaV9oaXN0Yl9zZXR1cCwKK307CisKK3N0YXRpYyBz dHJ1Y3QgaGNfZHJpdmVyIF9fcmVhZF9tb3N0bHkgeGhjaV9oaXN0Yl9oY19kcml2ZXI7CitzdGF0 aWMgaW50IHhoY2lfaGlzdGJfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKK3sK KwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmcGRldi0+ZGV2OworCXN0cnVjdCB4aGNpX2hjZF9oaXN0 YiAqaGlzdGI7CisJY29uc3Qgc3RydWN0IGhjX2RyaXZlciAqZHJpdmVyOworCXN0cnVjdCB1c2Jf aGNkICpoY2Q7CisJc3RydWN0IHhoY2lfaGNkICp4aGNpOworCXN0cnVjdCByZXNvdXJjZSAqcmVz OworCWludCBpcnE7CisJaW50IHJldCA9IC1FTk9ERVY7CisKKwlpZiAodXNiX2Rpc2FibGVkKCkp CisJCXJldHVybiAtRU5PREVWOworCisJZHJpdmVyID0gJnhoY2lfaGlzdGJfaGNfZHJpdmVyOwor CWhpc3RiID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpoaXN0YiksIEdGUF9LRVJORUwpOwor CWlmICghaGlzdGIpCisJCXJldHVybiAtRU5PTUVNOworCisJaGlzdGItPmRldiA9IGRldjsKKwor CWlycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7CisJaWYgKGlycSA8IDApCisJCXJldHVy biBpcnE7CisKKwlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9N RU0sIDApOworCWhpc3RiLT5jdHJsID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYs IHJlcyk7CisJaWYgKElTX0VSUihoaXN0Yi0+Y3RybCkpCisJCXJldHVybiBQVFJfRVJSKGhpc3Ri LT5jdHJsKTsKKworCXJldCA9IHhoY2lfaGlzdGJfY2xrc19nZXQoaGlzdGIpOworCWlmIChyZXQp CisJCXJldHVybiByZXQ7CisKKwloaXN0Yi0+c29mdF9yZXNldCA9IGRldm1fcmVzZXRfY29udHJv bF9nZXQoZGV2LCAic29mdCIpOworCWlmIChJU19FUlIoaGlzdGItPnNvZnRfcmVzZXQpKSB7CisJ CWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIGdldCBzb2Z0IHJlc2V0XG4iKTsKKwkJcmV0dXJuIFBU Ul9FUlIoaGlzdGItPnNvZnRfcmVzZXQpOworCX0KKworCXBtX3J1bnRpbWVfZW5hYmxlKGRldik7 CisJcG1fcnVudGltZV9nZXRfc3luYyhkZXYpOworCWRldmljZV9lbmFibGVfYXN5bmNfc3VzcGVu ZChkZXYpOworCisJLyogSW5pdGlhbGl6ZSBkbWFfbWFzayBhbmQgY29oZXJlbnRfZG1hX21hc2sg dG8gMzItYml0cyAqLworCXJldCA9IGRtYV9zZXRfbWFza19hbmRfY29oZXJlbnQoZGV2LCBETUFf QklUX01BU0soMzIpKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gcmV0OworCisJaGNkID0gdXNiX2Ny ZWF0ZV9oY2QoZHJpdmVyLCBkZXYsIGRldl9uYW1lKGRldikpOworCWlmICghaGNkKSB7CisJCXJl dCA9IC1FTk9NRU07CisJCWdvdG8gZGlzYWJsZV9wbTsKKwl9CisKKwloY2QtPnJlZ3MgPSBoaXN0 Yi0+Y3RybDsKKwloY2QtPnJzcmNfc3RhcnQgPSByZXMtPnN0YXJ0OworCWhjZC0+cnNyY19sZW4g PSByZXNvdXJjZV9zaXplKHJlcyk7CisKKwloaXN0Yi0+aGNkID0gaGNkOworCWRldl9zZXRfZHJ2 ZGF0YShoY2QtPnNlbGYuY29udHJvbGxlciwgaGlzdGIpOworCisJcmV0ID0geGhjaV9oaXN0Yl9o b3N0X2VuYWJsZShoaXN0Yik7CisJaWYgKHJldCkKKwkJZ290byBwdXRfaGNkOworCisJeGhjaSA9 IGhjZF90b194aGNpKGhjZCk7CisKKwlkZXZpY2Vfd2FrZXVwX2VuYWJsZShoY2QtPnNlbGYuY29u dHJvbGxlcik7CisKKwl4aGNpLT5tYWluX2hjZCA9IGhjZDsKKwl4aGNpLT5zaGFyZWRfaGNkID0g dXNiX2NyZWF0ZV9zaGFyZWRfaGNkKGRyaXZlciwgZGV2LCBkZXZfbmFtZShkZXYpLAorCQkJCQkJ IGhjZCk7CisJaWYgKCF4aGNpLT5zaGFyZWRfaGNkKSB7CisJCXJldCA9IC1FTk9NRU07CisJCWdv dG8gZGlzYWJsZV9ob3N0OworCX0KKworCWlmIChkZXZpY2VfcHJvcGVydHlfcmVhZF9ib29sKGRl diwgInVzYjItbHBtLWRpc2FibGUiKSkKKwkJeGhjaS0+cXVpcmtzIHw9IFhIQ0lfSFdfTFBNX0RJ U0FCTEU7CisKKwlpZiAoZGV2aWNlX3Byb3BlcnR5X3JlYWRfYm9vbChkZXYsICJ1c2IzLWxwbS1j YXBhYmxlIikpCisJCXhoY2ktPnF1aXJrcyB8PSBYSENJX0xQTV9TVVBQT1JUOworCisJaWYgKGRl dmljZV9wcm9wZXJ0eV9yZWFkX2Jvb2woZGV2LCAicXVpcmstYnJva2VuLXBvcnQtcGVkIikpCisJ CXhoY2ktPnF1aXJrcyB8PSBYSENJX0JST0tFTl9QT1JUX1BFRDsKKworCS8qIGltb2RfaW50ZXJ2 YWwgaXMgdGhlIGludGVycnVwdCBtb2RlcmF0aW9uIHZhbHVlIGluIG5hbm9zZWNvbmRzLiAqLwor CXhoY2ktPmltb2RfaW50ZXJ2YWwgPSA0MDAwMDsKKwlkZXZpY2VfcHJvcGVydHlfcmVhZF91MzIo ZGV2LCAiaW1vZC1pbnRlcnZhbC1ucyIsCisJCQkJICZ4aGNpLT5pbW9kX2ludGVydmFsKTsKKwor CXJldCA9IHVzYl9hZGRfaGNkKGhjZCwgaXJxLCBJUlFGX1NIQVJFRCk7CisJaWYgKHJldCkKKwkJ Z290byBwdXRfdXNiM19oY2Q7CisKKwlpZiAoSENDX01BWF9QU0EoeGhjaS0+aGNjX3BhcmFtcykg Pj0gNCkKKwkJeGhjaS0+c2hhcmVkX2hjZC0+Y2FuX2RvX3N0cmVhbXMgPSAxOworCisJcmV0ID0g dXNiX2FkZF9oY2QoeGhjaS0+c2hhcmVkX2hjZCwgaXJxLCBJUlFGX1NIQVJFRCk7CisJaWYgKHJl dCkKKwkJZ290byBkZWFsbG9jX3VzYjJfaGNkOworCisJZGV2aWNlX2VuYWJsZV9hc3luY19zdXNw ZW5kKGRldik7CisJcG1fcnVudGltZV9wdXRfbm9pZGxlKGRldik7CisKKwkvKgorCSAqIFByZXZl bnQgcnVudGltZSBwbSBmcm9tIGJlaW5nIG9uIGFzIGRlZmF1bHQsIHVzZXJzIHNob3VsZCBlbmFi bGUKKwkgKiBydW50aW1lIHBtIHVzaW5nIHBvd2VyL2NvbnRyb2wgaW4gc3lzZnMuCisJICovCisJ cG1fcnVudGltZV9mb3JiaWQoZGV2KTsKKworCXJldHVybiAwOworCitkZWFsbG9jX3VzYjJfaGNk OgorCXVzYl9yZW1vdmVfaGNkKGhjZCk7CitwdXRfdXNiM19oY2Q6CisJdXNiX3B1dF9oY2QoeGhj aS0+c2hhcmVkX2hjZCk7CitkaXNhYmxlX2hvc3Q6CisJeGhjaV9oaXN0Yl9ob3N0X2Rpc2FibGUo aGlzdGIpOworcHV0X2hjZDoKKwl1c2JfcHV0X2hjZChoY2QpOworZGlzYWJsZV9wbToKKwlwbV9y dW50aW1lX3B1dF9zeW5jKGRldik7CisJcG1fcnVudGltZV9kaXNhYmxlKGRldik7CisKKwlyZXR1 cm4gcmV0OworfQorCitzdGF0aWMgaW50IHhoY2lfaGlzdGJfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9y bV9kZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgeGhjaV9oY2RfaGlzdGIgKmhpc3RiID0gcGxhdGZv cm1fZ2V0X2RydmRhdGEoZGV2KTsKKwlzdHJ1Y3QgdXNiX2hjZCAqaGNkID0gaGlzdGItPmhjZDsK KwlzdHJ1Y3QgeGhjaV9oY2QJKnhoY2kgPSBoY2RfdG9feGhjaShoY2QpOworCisJeGhjaS0+eGhj X3N0YXRlIHw9IFhIQ0lfU1RBVEVfUkVNT1ZJTkc7CisKKwl1c2JfcmVtb3ZlX2hjZCh4aGNpLT5z aGFyZWRfaGNkKTsKKwlkZXZpY2Vfd2FrZXVwX2Rpc2FibGUoJmRldi0+ZGV2KTsKKworCXVzYl9y ZW1vdmVfaGNkKGhjZCk7CisJdXNiX3B1dF9oY2QoeGhjaS0+c2hhcmVkX2hjZCk7CisKKwl4aGNp X2hpc3RiX2hvc3RfZGlzYWJsZShoaXN0Yik7CisJdXNiX3B1dF9oY2QoaGNkKTsKKwlwbV9ydW50 aW1lX3B1dF9zeW5jKCZkZXYtPmRldik7CisJcG1fcnVudGltZV9kaXNhYmxlKCZkZXYtPmRldik7 CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBfX21heWJlX3VudXNlZCB4aGNpX2hpc3Ri X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQoreworCXN0cnVjdCB4aGNpX2hjZF9oaXN0YiAq aGlzdGIgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKwlzdHJ1Y3QgdXNiX2hjZCAqaGNkID0gaGlz dGItPmhjZDsKKwlzdHJ1Y3QgeGhjaV9oY2QJKnhoY2kgPSBoY2RfdG9feGhjaShoY2QpOworCWlu dCByZXQ7CisKKwlyZXQgPSB4aGNpX3N1c3BlbmQoeGhjaSwgZGV2aWNlX21heV93YWtldXAoZGV2 KSk7CisKKwlpZiAoIWRldmljZV9tYXlfd2FrZXVwKGRldikpCisJCXhoY2lfaGlzdGJfaG9zdF9k aXNhYmxlKGhpc3RiKTsKKworCXJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgX19tYXliZV91 bnVzZWQgeGhjaV9oaXN0Yl9yZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQoreworCXN0cnVjdCB4 aGNpX2hjZF9oaXN0YiAqaGlzdGIgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKKwlzdHJ1Y3QgdXNi X2hjZCAqaGNkID0gaGlzdGItPmhjZDsKKwlzdHJ1Y3QgeGhjaV9oY2QgKnhoY2kgPSBoY2RfdG9f eGhjaShoY2QpOworCisJaWYgKCFkZXZpY2VfbWF5X3dha2V1cChkZXYpKQorCQl4aGNpX2hpc3Ri X2hvc3RfZW5hYmxlKGhpc3RiKTsKKworCXJldHVybiB4aGNpX3Jlc3VtZSh4aGNpLCAwKTsKK30K Kworc3RhdGljIGNvbnN0IHN0cnVjdCBkZXZfcG1fb3BzIHhoY2lfaGlzdGJfcG1fb3BzID0gewor CVNFVF9TWVNURU1fU0xFRVBfUE1fT1BTKHhoY2lfaGlzdGJfc3VzcGVuZCwgeGhjaV9oaXN0Yl9y ZXN1bWUpCit9OworI2RlZmluZSBERVZfUE1fT1BTIChJU19FTkFCTEVEKENPTkZJR19QTSkgPyAm eGhjaV9oaXN0Yl9wbV9vcHMgOiBOVUxMKQorCisjaWZkZWYgQ09ORklHX09GCitzdGF0aWMgY29u c3Qgc3RydWN0IG9mX2RldmljZV9pZCBoaXN0Yl94aGNpX29mX21hdGNoW10gPSB7CisJeyAuY29t cGF0aWJsZSA9ICJoaXNpbGljb24saGkzNzk4Y3YyMDAteGhjaSJ9LAorCXsgfSwKK307CitNT0RV TEVfREVWSUNFX1RBQkxFKG9mLCBoaXN0Yl94aGNpX29mX21hdGNoKTsKKyNlbmRpZgorCitzdGF0 aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBoaXN0Yl94aGNpX2RyaXZlciA9IHsKKwkucHJvYmUJ PSB4aGNpX2hpc3RiX3Byb2JlLAorCS5yZW1vdmUJPSB4aGNpX2hpc3RiX3JlbW92ZSwKKwkuZHJp dmVyCT0geworCQkubmFtZSA9ICJ4aGNpLWhpc3RiIiwKKwkJLnBtID0gREVWX1BNX09QUywKKwkJ Lm9mX21hdGNoX3RhYmxlID0gb2ZfbWF0Y2hfcHRyKGhpc3RiX3hoY2lfb2ZfbWF0Y2gpLAorCX0s Cit9OworTU9EVUxFX0FMSUFTKCJwbGF0Zm9ybTp4aGNpLWhpc3RiIik7CisKK3N0YXRpYyBpbnQg X19pbml0IHhoY2lfaGlzdGJfaW5pdCh2b2lkKQoreworCXhoY2lfaW5pdF9kcml2ZXIoJnhoY2lf aGlzdGJfaGNfZHJpdmVyLCAmeGhjaV9oaXN0Yl9vdmVycmlkZXMpOworCXJldHVybiBwbGF0Zm9y bV9kcml2ZXJfcmVnaXN0ZXIoJmhpc3RiX3hoY2lfZHJpdmVyKTsKK30KK21vZHVsZV9pbml0KHho Y2lfaGlzdGJfaW5pdCk7CisKK3N0YXRpYyB2b2lkIF9fZXhpdCB4aGNpX2hpc3RiX2V4aXQodm9p ZCkKK3sKKwlwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmaGlzdGJfeGhjaV9kcml2ZXIpOwor fQorbW9kdWxlX2V4aXQoeGhjaV9oaXN0Yl9leGl0KTsKKworTU9EVUxFX0RFU0NSSVBUSU9OKCJI aVNpbGljb24gU1RCIHhIQ0kgSG9zdCBDb250cm9sbGVyIERyaXZlciIpOworTU9EVUxFX0xJQ0VO U0UoIkdQTCB2MiIpOwo=