From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758180AbdEOMBr (ORCPT ); Mon, 15 May 2017 08:01:47 -0400 Received: from szxga02-in.huawei.com ([45.249.212.188]:5881 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753875AbdEOMBo (ORCPT ); Mon, 15 May 2017 08:01:44 -0400 From: songxiaowei To: Niklas Cassel , "bhelgaas@google.com" , "kishon@ti.com" , "jingoohan1@gmail.com" , "arnd@arndb.de" , "tn@semihalf.com" , "keith.busch@intel.com" , "dhdang@apm.com" , "liudongdong (C)" CC: "Chenfeng (puck)" , "guodong.xu@linaro.org" , Wangbinghui , Suzhuangluan , "linux-kernel@vger.kernel.org" , "linux-pci@vger.kernel.org" Subject: =?utf-8?B?562U5aSNOiBbUEFUQ0ggMi8zXSBQQ0k6IGR3Yzoga2lyaW46IGFkZCBQQ0ll?= =?utf-8?Q?_Driver_for_HiSilicon_Kirin_SoC?= Thread-Topic: [PATCH 2/3] PCI: dwc: kirin: add PCIe Driver for HiSilicon Kirin SoC Thread-Index: AQHSzURiG6fS+hOnhk+BVRs1Q/HMo6H0h8GAgADCDTA= Date: Mon, 15 May 2017 11:57:36 +0000 Message-ID: <99B4C6BADD9E3241B25E52B02BA737C54115DD79@DGGEMA505-MBS.china.huawei.com> References: <20170515062745.70082-1-songxiaowei@hisilicon.com> <20170515062745.70082-2-songxiaowei@hisilicon.com> <60c1bdf6-1c5b-2b55-0d4c-60ff08fdff36@axis.com> In-Reply-To: <60c1bdf6-1c5b-2b55-0d4c-60ff08fdff36@axis.com> Accept-Language: zh-CN, en-US Content-Language: zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.142.52.233] Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090205.591997BC.007C,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=169.254.4.112, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 810218c9490f860f3bcee73732b3e0ac Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by mail.home.local id v4FC27qZ026247 Hi Niklas, I was so sorry for my carelessness, The patch was update. Thanks a lot. Best wishes, Song. -----邮件原件----- 发件人: Niklas Cassel [mailto:niklas.cassel@axis.com] 发送时间: 2017年5月15日 16:21 收件人: songxiaowei; bhelgaas@google.com; kishon@ti.com; jingoohan1@gmail.com; arnd@arndb.de; tn@semihalf.com; keith.busch@intel.com; dhdang@apm.com; liudongdong (C) 抄送: Chenfeng (puck); guodong.xu@linaro.org; Wangbinghui; Suzhuangluan; linux-kernel@vger.kernel.org; linux-pci@vger.kernel.org 主题: Re: [PATCH 2/3] PCI: dwc: kirin: add PCIe Driver for HiSilicon Kirin SoC On 05/15/2017 08:27 AM, Song Xiaowei wrote: > Hisilicon PCIe Driver shares the common functions fo PCIe dw-host > > The poweron functions is developed on hi3660 SoC, while Others > Functions are common for Kirin series SoCs. > > Lowpower(L1ss and SR), hotplug and MSI feature are not supported > currently. > > Cc: Guodong Xu > Signed-off-by: Song Xiaowei > --- > drivers/pci/dwc/Kconfig | 10 + > drivers/pci/dwc/Makefile | 1 + > drivers/pci/dwc/pcie-kirin.c | 521 > +++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 532 insertions(+) > create mode 100644 drivers/pci/dwc/pcie-kirin.c > > diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig index > d2d2ba5b8a68..13e617b78430 100644 > --- a/drivers/pci/dwc/Kconfig > +++ b/drivers/pci/dwc/Kconfig > @@ -130,4 +130,14 @@ config PCIE_ARTPEC6 > Say Y here to enable PCIe controller support on Axis ARTPEC-6 > SoCs. This PCIe controller uses the DesignWare core. > > +config PCIE_KIRIN > + depends on OF && ARM64 > + bool "HiSilicon Kirin series SoCs PCIe controllers" > + depends on PCI > + select PCIEPORTBUS > + select PCIE_DW_HOST > + help > + Say Y here if you want PCIe controller support on HiSilicon Kirin series SoCs > + kirin960 SoC > + > endmenu > diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index > a2df13c28798..4bd69bacd4ab 100644 > --- a/drivers/pci/dwc/Makefile > +++ b/drivers/pci/dwc/Makefile > @@ -10,6 +10,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o > obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o > obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o > obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o > +obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o > > # The following drivers are for devices that use the generic ACPI # > pci_root.c driver but don't support standard ECAM config access. > diff --git a/drivers/pci/dwc/pcie-kirin.c > b/drivers/pci/dwc/pcie-kirin.c new file mode 100644 index > 000000000000..a19d1732ad9f > --- /dev/null > +++ b/drivers/pci/dwc/pcie-kirin.c > @@ -0,0 +1,521 @@ > +/* > + * PCIe host controller driver for Kirin Phone SoCs > + * > + * Copyright (C) 2015 Hilisicon Electronics Co., Ltd. > + * http://www.huawei.com > + * > + * Author: Xiaowei Song > + * > + * This program is free software; you can redistribute it and/or > +modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "pcie-designware.h" > + > +#define to_kirin_pcie(x) dev_get_drvdata((x)->dev) > + > +#define REF_CLK_FREQ 100000000 > + > +/* PCIe ELBI registers */ > +#define SOC_PCIECTRL_CTRL0_ADDR 0x000 #define SOC_PCIECTRL_CTRL1_ADDR > +0x004 #define SOC_PCIEPHY_CTRL2_ADDR 0x008 #define > +SOC_PCIEPHY_CTRL3_ADDR 0x00c > +#define PCIE_ELBI_SLV_DBI_ENABLE (0x1 << 21) > + > +#define PCIE_APP_LTSSM_ENABLE 0x01c > +#define PCIE_APB_PHY_CTRL0 0x0 > +#define PCIE_APB_PHY_CTRL1 0x4 > +#define PCIE_APB_PHY_STATUS0 0x400 > +#define PCIE_LINKUP_ENABLE (0x8020) > +#define PCIE_LTSSM_ENABLE_BIT (0x1 << 11) > +#define PIPE_CLK_STABLE (0x1 << 19) > +#define PIPE_CLK_MAX_TRY_TIMES 10 > +#define PHY_REF_PAD_BIT (0x1 << 8) > +#define PHY_PWR_DOWN_BIT (0x1 << 22) > +#define PHY_RST_ACK_BIT (0x1 << 16) > + > +/* info lacated in sysctrl */ > +#define SCTRL_PCIE_CMOS_OFFSET 0x60 > +#define SCTRL_PCIE_CMOS_BIT 0x10 > +#define SCTRL_PCIE_ISO_OFFSET 0x44 > +#define SCTRL_PCIE_ISO_BIT 0x30 > +#define SCTRL_PCIE_HPCLK_OFFSET 0x190 > +#define SCTRL_PCIE_HPCLK_BIT 0x184000 > +#define SCTRL_PCIE_OE_OFFSET 0x14a > +#define PCIE_DEBOUNCE_PARAM 0xF0F400 > +#define PCIE_OE_BYPASS (0x3 << 28) > + > +/*peri_crg ctrl*/ > +#define CRGCTRL_PCIE_ASSERT_OFFSET 0x88 > +#define CRGCTRL_PCIE_ASSERT_BIT 0x8c000000 > + > +/* Time for delay*/ > +#define REF_2_PERST_MIN (20000) > +#define REF_2_PERST_MAX (25000) > +#define PERST_2_ACCESS_MIN (10000) > +#define PERST_2_ACCESS_MAX (12000) > +#define LINK_WAIT_MIN (900) > +#define LINK_WAIT_MAX (1000) > + > +struct kirin_pcie { > + void __iomem *apb_base; > + void __iomem *phy_base; > + struct regmap *crgctrl; > + struct regmap *sysctrl; > + struct clk *apb_sys_clk; > + struct clk *apb_phy_clk; > + struct clk *phy_ref_clk; > + struct clk *pcie_aclk; > + struct clk *pcie_aux_clk; > + int gpio_id_reset; > + struct dw_pcie *pci; > +}; > + > +static inline void kirin_apb_ctrl_writel(struct kirin_pcie *kirin_pcie, > + u32 val, u32 reg) > +{ > + writel(val, kirin_pcie->apb_base + reg); } > + > +static inline u32 kirin_apb_ctrl_readl(struct kirin_pcie *kirin_pcie, > + u32 reg) > +{ > + return readl(kirin_pcie->apb_base + reg); } > + > +/*Registers in PCIePHY*/ > +static inline void kirin_apb_phy_writel(struct kirin_pcie *kirin_pcie, > + u32 val, u32 reg) > +{ > + writel(val, kirin_pcie->phy_base + reg); } > + > +static inline u32 kirin_apb_phy_readl(struct kirin_pcie *kirin_pcie, > + u32 reg) > +{ > + return readl(kirin_pcie->phy_base + reg); } > + > +static int32_t kirin_pcie_get_clk(struct kirin_pcie *kirin_pcie, > + struct platform_device *pdev) > +{ > + kirin_pcie->phy_ref_clk = devm_clk_get(&pdev->dev, "pcie_phy_ref"); > + if (IS_ERR(kirin_pcie->phy_ref_clk)) > + return PTR_ERR(kirin_pcie->phy_ref_clk); > + > + kirin_pcie->pcie_aux_clk = devm_clk_get(&pdev->dev, "pcie_aux"); > + if (IS_ERR(kirin_pcie->pcie_aux_clk)) > + return PTR_ERR(kirin_pcie->pcie_aux_clk); > + > + kirin_pcie->apb_phy_clk = devm_clk_get(&pdev->dev, "pcie_apb_phy"); > + if (IS_ERR(kirin_pcie->apb_phy_clk)) > + return PTR_ERR(kirin_pcie->apb_phy_clk); > + > + kirin_pcie->apb_sys_clk = devm_clk_get(&pdev->dev, "pcie_apb_sys"); > + if (IS_ERR(kirin_pcie->apb_sys_clk)) > + return PTR_ERR(kirin_pcie->apb_sys_clk); > + > + kirin_pcie->pcie_aclk = devm_clk_get(&pdev->dev, "pcie_aclk"); > + if (IS_ERR(kirin_pcie->pcie_aclk)) > + return PTR_ERR(kirin_pcie->pcie_aclk); > + > + return 0; > +} > + > +static int32_t kirin_pcie_get_resource(struct kirin_pcie *kirin_pcie, > + struct platform_device *pdev) > +{ > + struct resource *apb; > + struct resource *phy; > + struct resource *dbi; > + > + apb = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb"); > + kirin_pcie->apb_base = devm_ioremap_resource(&pdev->dev, apb); > + if (IS_ERR(kirin_pcie->apb_base)) > + return PTR_ERR(kirin_pcie->apb_base); > + > + phy = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); > + kirin_pcie->phy_base = devm_ioremap_resource(&pdev->dev, phy); > + if (IS_ERR(kirin_pcie->phy_base)) > + return PTR_ERR(kirin_pcie->phy_base); > + > + dbi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); > + kirin_pcie->pci->dbi_base = devm_ioremap_resource(&pdev->dev, dbi); > + if (IS_ERR(kirin_pcie->pci->dbi_base)) > + return PTR_ERR(kirin_pcie->pci->dbi_base); > + > + kirin_pcie->crgctrl = > + syscon_regmap_lookup_by_compatible("hisilicon,hi3660-crgctrl"); > + if (IS_ERR(kirin_pcie->crgctrl)) > + return PTR_ERR(kirin_pcie->crgctrl); > + > + kirin_pcie->sysctrl = > + syscon_regmap_lookup_by_compatible("hisilicon,hi3660-sctrl"); > + if (IS_ERR(kirin_pcie->sysctrl)) > + return PTR_ERR(kirin_pcie->sysctrl); > + > + return 0; > +} > + > +static int kirin_pcie_phy_init(struct kirin_pcie *kirin_pcie) { > + u32 reg_val; > + u32 time = PIPE_CLK_MAX_TRY_TIMES; > + > + reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL1); > + reg_val &= ~PHY_REF_PAD_BIT; > + kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL1); > + > + reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL0); > + reg_val &= ~PHY_PWR_DOWN_BIT; > + kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL0); > + udelay(10); > + > + reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_CTRL1); > + reg_val &= ~PHY_RST_ACK_BIT; > + kirin_apb_phy_writel(kirin_pcie, reg_val, PCIE_APB_PHY_CTRL1); > + > + reg_val = kirin_apb_phy_readl(kirin_pcie, PCIE_APB_PHY_STATUS0); > + while (reg_val & PIPE_CLK_STABLE) { > + udelay(100); > + if (time == 0) { > + dev_err(kirin_pcie->pci->dev, "PIPE clk is not stable\n"); > + return -EINVAL; > + } > + time--; > + reg_val = kirin_apb_phy_readl(kirin_pcie, > + PCIE_APB_PHY_STATUS0); > + } > + > + return 0; > +} > + > +static void kirin_pcie_oe_enable(struct kirin_pcie *kirin_pcie) { > + u32 val; > + > + regmap_read(kirin_pcie->sysctrl, SCTRL_PCIE_OE_OFFSET, &val); > + val |= PCIE_DEBOUNCE_PARAM; > + val &= ~PCIE_OE_BYPASS; > + regmap_write(kirin_pcie->sysctrl, SCTRL_PCIE_OE_OFFSET, val); } > + > +static int kirin_pcie_clk_ctrl(struct kirin_pcie *kirin_pcie, bool > +enable) { > + int ret = 0; > + > + if (!enable) > + goto close_clk; > + > + ret = clk_set_rate(kirin_pcie->phy_ref_clk, REF_CLK_FREQ); > + if (ret) > + return ret; > + > + ret = clk_prepare_enable(kirin_pcie->phy_ref_clk); > + if (ret) > + return ret; > + > + ret = clk_prepare_enable(kirin_pcie->apb_sys_clk); > + if (ret) > + goto apb_sys_fail; > + > + ret = clk_prepare_enable(kirin_pcie->apb_phy_clk); > + if (ret) > + goto apb_phy_fail; > + > + ret = clk_prepare_enable(kirin_pcie->pcie_aclk); > + if (ret) > + goto aclk_fail; > + > + ret = clk_prepare_enable(kirin_pcie->pcie_aux_clk); > + if (ret) > + goto aux_clk_fail; > + > + return 0; > +close_clk: > + clk_disable_unprepare(kirin_pcie->pcie_aux_clk); > +aux_clk_fail: > + clk_disable_unprepare(kirin_pcie->pcie_aclk); > +aclk_fail: > + clk_disable_unprepare(kirin_pcie->apb_phy_clk); > +apb_phy_fail: > + clk_disable_unprepare(kirin_pcie->apb_sys_clk); > +apb_sys_fail: > + clk_disable_unprepare(kirin_pcie->phy_ref_clk); > + return ret; > +} > + > +static int kirin_pcie_power_on(struct kirin_pcie *kirin_pcie) { > + int ret; > + > + /*Power supply for Host*/ > + regmap_write(kirin_pcie->sysctrl, > + SCTRL_PCIE_CMOS_OFFSET, SCTRL_PCIE_CMOS_BIT); > + udelay(100); > + kirin_pcie_oe_enable(kirin_pcie); > + > + ret = kirin_pcie_clk_ctrl(kirin_pcie, true); > + if (ret) > + return ret; > + > + /*deasset PCIeCtrl&PCIePHY*/ > + regmap_write(kirin_pcie->sysctrl, > + SCTRL_PCIE_ISO_OFFSET, SCTRL_PCIE_ISO_BIT); > + regmap_write(kirin_pcie->crgctrl, > + CRGCTRL_PCIE_ASSERT_OFFSET, CRGCTRL_PCIE_ASSERT_BIT); > + regmap_write(kirin_pcie->sysctrl, > + SCTRL_PCIE_HPCLK_OFFSET, SCTRL_PCIE_HPCLK_BIT); > + > + ret = kirin_pcie_phy_init(kirin_pcie); > + if (ret) > + goto close_clk; > + > + /*perst assert Endpoint*/ > + if (!gpio_request(kirin_pcie->gpio_id_reset, "pcie_perst")) { > + usleep_range(REF_2_PERST_MIN, REF_2_PERST_MAX); > + ret = gpio_direction_output(kirin_pcie->gpio_id_reset, 1); > + if (ret) > + goto close_clk; > + usleep_range(PERST_2_ACCESS_MIN, PERST_2_ACCESS_MAX); > + > + return 0; > + } > + > +close_clk: > + kirin_pcie_clk_ctrl(kirin_pcie, false); > + return ret; > +} > + > +static void kirin_pcie_sideband_dbi_w_mode(struct kirin_pcie *kirin_pcie, > + bool on) > +{ > + u32 val; > + > + val = kirin_apb_ctrl_readl(kirin_pcie, SOC_PCIECTRL_CTRL0_ADDR); > + if (on) > + val = val | PCIE_ELBI_SLV_DBI_ENABLE; > + else > + val = val & ~PCIE_ELBI_SLV_DBI_ENABLE; > + > + kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL0_ADDR); } > + > +static void kirin_pcie_sideband_dbi_r_mode(struct kirin_pcie *kirin_pcie, > + bool on) > +{ > + u32 val; > + > + val = kirin_apb_ctrl_readl(kirin_pcie, SOC_PCIECTRL_CTRL1_ADDR); > + if (on) > + val = val | PCIE_ELBI_SLV_DBI_ENABLE; > + else > + val = val & ~PCIE_ELBI_SLV_DBI_ENABLE; > + > + kirin_apb_ctrl_writel(kirin_pcie, val, SOC_PCIECTRL_CTRL1_ADDR); } > + > +static int kirin_pcie_rd_own_conf(struct pcie_port *pp, > + int where, int size, u32 *val) > +{ > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > + struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); > + int ret; > + > + kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true); > + ret = dw_pcie_read(pci->dbi_base + where, size, val); > + kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false); > + > + return ret; > +} > + > +static int kirin_pcie_wr_own_conf(struct pcie_port *pp, > + int where, int size, u32 val) > +{ > + int ret; > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > + struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); > + > + kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true); > + ret = dw_pcie_write(pci->dbi_base + where, size, val); > + kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false); > + > + return ret; > +} > + > +static u32 kirin_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, > + u32 reg, size_t size) > +{ > + u32 ret; > + struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); > + > + kirin_pcie_sideband_dbi_r_mode(kirin_pcie, true); > + dw_pcie_read(base + reg, size, &ret); > + kirin_pcie_sideband_dbi_r_mode(kirin_pcie, false); > + > + return ret; > +} > + > +static void kirin_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, > + u32 reg, size_t size, u32 val) > +{ > + struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); > + > + kirin_pcie_sideband_dbi_w_mode(kirin_pcie, true); > + dw_pcie_write(base + reg, size, val); > + kirin_pcie_sideband_dbi_w_mode(kirin_pcie, false); } > + > +static int kirin_pcie_link_up(struct dw_pcie *pci) { > + struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); > + u32 val = kirin_apb_ctrl_readl(kirin_pcie, PCIE_APB_PHY_STATUS0); > + > + if ((val & PCIE_LINKUP_ENABLE) == PCIE_LINKUP_ENABLE) > + return 1; > + > + return 0; > +} > + > +static int kirin_pcie_establish_link(struct pcie_port *pp) { > + int count = 0; > + > + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); > + struct kirin_pcie *kirin_pcie = to_kirin_pcie(pci); > + > + if (kirin_pcie_link_up(pci)) > + return 0; > + > + dw_pcie_setup_rc(pp); > + > + /* assert LTSSM enable */ > + kirin_apb_ctrl_writel(kirin_pcie, PCIE_LTSSM_ENABLE_BIT, > + PCIE_APP_LTSSM_ENABLE); > + > + /* check if the link is up or not */ > + while (!kirin_pcie_link_up(pci)) { > + usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX); > + count++; > + if (count == 1000) { > + dev_err(pci->dev, "Link Fail\n"); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +static void kirin_pcie_host_init(struct pcie_port *pp) { > + kirin_pcie_establish_link(pp); > +} > + > +static struct dw_pcie_ops kirin_dw_pcie_ops = { > + .read_dbi = kirin_pcie_read_dbi, > + .write_dbi = kirin_pcie_write_dbi, > + .link_up = kirin_pcie_link_up, > +}; > + > +static struct dw_pcie_host_ops kirin_pcie_host_ops = { > + .rd_own_conf = kirin_pcie_rd_own_conf, > + .wr_own_conf = kirin_pcie_wr_own_conf, > + .host_init = kirin_pcie_host_init, > +}; > + > +static int __init kirin_add_pcie_port(struct dw_pcie *pci, > + struct platform_device *pdev) > +{ > + int ret; > + > + pci->pp.ops = &kirin_pcie_host_ops; > + > + ret = dw_pcie_host_init(&pci->pp); > + > + return ret; > +} > + > +static int kirin_pcie_probe(struct platform_device *pdev) { > + struct kirin_pcie *kirin_pcie; > + struct dw_pcie *pci; > + struct device *dev = &pdev->dev; > + int ret; > + > + if (!pdev->dev.of_node) { > + dev_err(&pdev->dev, "NULL node\n"); > + return -EINVAL; > + } > + > + kirin_pcie = devm_kzalloc(&pdev->dev, > + sizeof(struct kirin_pcie), GFP_KERNEL); > + if (!kirin_pcie) > + return -ENOMEM; > + > + pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); > + if (!pci) > + return -ENOMEM; > + > + pci->dev = dev; > + pci->ops = &kirin_dw_pcie_ops; > + kirin_pcie->pci = pci; > + > + ret = kirin_pcie_get_clk(kirin_pcie, pdev); > + if (ret) > + return ret; > + > + ret = kirin_pcie_get_resource(kirin_pcie, pdev); > + if (ret) > + return ret; > + > + kirin_pcie->gpio_id_reset = of_get_named_gpio(pdev->dev.of_node, > + "reset-gpio", 0); > + if (kirin_pcie->gpio_id_reset < 0) > + return -ENODEV; > + > + ret = kirin_pcie_power_on(kirin_pcie); > + if (ret) > + return ret; > + > + platform_set_drvdata(pdev, kirin_pcie); > + > + ret = kirin_add_pcie_port(pci, pdev); > + if (ret) > + return ret; > + > + return 0; > +} > + > +static const struct of_device_id kirin_pcie_match[] = { > + { .compatible = "hisilicon,kirin-pcie" }, > + {}, > +}; > + > +struct platform_driver kirin_pcie_driver = { > + .probe = kirin_pcie_probe, > + .driver = { > + .name = "Kirin-pcie", > + .of_match_table = kirin_pcie_match, > + }, > +}; Hello Song, You forgot to add .suppress_bind_attrs = true, See the following commit as to why this is needed: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git/commit/drivers/pci/dwc?id=a5f40e8098fe6d983fdb3beb7b50a8067c136141 Regards, Niklas > + > +builtin_platform_driver(kirin_pcie_driver); > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from szxga02-in.huawei.com ([45.249.212.188]:5881 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753875AbdEOMBo (ORCPT ); Mon, 15 May 2017 08:01:44 -0400 From: songxiaowei To: Niklas Cassel , "bhelgaas@google.com" , "kishon@ti.com" , "jingoohan1@gmail.com" , "arnd@arndb.de" , "tn@semihalf.com" , "keith.busch@intel.com" , "dhdang@apm.com" , "liudongdong (C)" CC: "Chenfeng (puck)" , "guodong.xu@linaro.org" , Wangbinghui , Suzhuangluan , "linux-kernel@vger.kernel.org" , "linux-pci@vger.kernel.org" Subject: =?utf-8?B?562U5aSNOiBbUEFUQ0ggMi8zXSBQQ0k6IGR3Yzoga2lyaW46IGFkZCBQQ0ll?= =?utf-8?Q?_Driver_for_HiSilicon_Kirin_SoC?= Date: Mon, 15 May 2017 11:57:36 +0000 Message-ID: <99B4C6BADD9E3241B25E52B02BA737C54115DD79@DGGEMA505-MBS.china.huawei.com> References: <20170515062745.70082-1-songxiaowei@hisilicon.com> <20170515062745.70082-2-songxiaowei@hisilicon.com> <60c1bdf6-1c5b-2b55-0d4c-60ff08fdff36@axis.com> In-Reply-To: <60c1bdf6-1c5b-2b55-0d4c-60ff08fdff36@axis.com> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org List-ID: SGkgTmlrbGFzLA0KDQpJIHdhcyBzbyBzb3JyeSBmb3IgbXkgY2FyZWxlc3NuZXNzLA0KDQpUaGUg cGF0Y2ggd2FzIHVwZGF0ZS4NCg0KDQpUaGFua3MgYSBsb3QuDQoNCg0KQmVzdCB3aXNoZXMsDQoN ClNvbmcuDQoNCi0tLS0t6YKu5Lu25Y6f5Lu2LS0tLS0NCuWPkeS7tuS6ujogTmlrbGFzIENhc3Nl bCBbbWFpbHRvOm5pa2xhcy5jYXNzZWxAYXhpcy5jb21dIA0K5Y+R6YCB5pe26Ze0OiAyMDE35bm0 NeaciDE15pelIDE2OjIxDQrmlLbku7bkuro6IHNvbmd4aWFvd2VpOyBiaGVsZ2Fhc0Bnb29nbGUu Y29tOyBraXNob25AdGkuY29tOyBqaW5nb29oYW4xQGdtYWlsLmNvbTsgYXJuZEBhcm5kYi5kZTsg dG5Ac2VtaWhhbGYuY29tOyBrZWl0aC5idXNjaEBpbnRlbC5jb207IGRoZGFuZ0BhcG0uY29tOyBs aXVkb25nZG9uZyAoQykNCuaKhOmAgTogQ2hlbmZlbmcgKHB1Y2spOyBndW9kb25nLnh1QGxpbmFy by5vcmc7IFdhbmdiaW5naHVpOyBTdXpodWFuZ2x1YW47IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5l bC5vcmc7IGxpbnV4LXBjaUB2Z2VyLmtlcm5lbC5vcmcNCuS4u+mimDogUmU6IFtQQVRDSCAyLzNd IFBDSTogZHdjOiBraXJpbjogYWRkIFBDSWUgRHJpdmVyIGZvciBIaVNpbGljb24gS2lyaW4gU29D DQoNCk9uIDA1LzE1LzIwMTcgMDg6MjcgQU0sIFNvbmcgWGlhb3dlaSB3cm90ZToNCj4gSGlzaWxp Y29uIFBDSWUgRHJpdmVyIHNoYXJlcyB0aGUgY29tbW9uIGZ1bmN0aW9ucyBmbyBQQ0llIGR3LWhv c3QNCj4gDQo+IFRoZSBwb3dlcm9uIGZ1bmN0aW9ucyBpcyBkZXZlbG9wZWQgb24gaGkzNjYwIFNv Qywgd2hpbGUgT3RoZXJzIA0KPiBGdW5jdGlvbnMgYXJlIGNvbW1vbiBmb3IgS2lyaW4gc2VyaWVz IFNvQ3MuDQo+IA0KPiBMb3dwb3dlcihMMXNzIGFuZCBTUiksIGhvdHBsdWcgYW5kIE1TSSBmZWF0 dXJlIGFyZSBub3Qgc3VwcG9ydGVkIA0KPiBjdXJyZW50bHkuDQo+IA0KPiBDYzogR3VvZG9uZyBY dSA8Z3VvZG9uZy54dUBsaW5hcm8ub3JnPg0KPiBTaWduZWQtb2ZmLWJ5OiBTb25nIFhpYW93ZWkg PHNvbmd4aWFvd2VpQGhpc2lsaWNvbi5jb20+DQo+IC0tLQ0KPiAgZHJpdmVycy9wY2kvZHdjL0tj b25maWcgICAgICB8ICAxMCArDQo+ICBkcml2ZXJzL3BjaS9kd2MvTWFrZWZpbGUgICAgIHwgICAx ICsNCj4gIGRyaXZlcnMvcGNpL2R3Yy9wY2llLWtpcmluLmMgfCA1MjEgDQo+ICsrKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysNCj4gIDMgZmlsZXMgY2hhbmdlZCwgNTMy IGluc2VydGlvbnMoKykNCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3BjaS9kd2MvcGNp ZS1raXJpbi5jDQo+IA0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvZHdjL0tjb25maWcgYi9k cml2ZXJzL3BjaS9kd2MvS2NvbmZpZyBpbmRleCANCj4gZDJkMmJhNWI4YTY4Li4xM2U2MTdiNzg0 MzAgMTAwNjQ0DQo+IC0tLSBhL2RyaXZlcnMvcGNpL2R3Yy9LY29uZmlnDQo+ICsrKyBiL2RyaXZl cnMvcGNpL2R3Yy9LY29uZmlnDQo+IEBAIC0xMzAsNCArMTMwLDE0IEBAIGNvbmZpZyBQQ0lFX0FS VFBFQzYNCj4gIAkgIFNheSBZIGhlcmUgdG8gZW5hYmxlIFBDSWUgY29udHJvbGxlciBzdXBwb3J0 IG9uIEF4aXMgQVJUUEVDLTYNCj4gIAkgIFNvQ3MuICBUaGlzIFBDSWUgY29udHJvbGxlciB1c2Vz IHRoZSBEZXNpZ25XYXJlIGNvcmUuDQo+ICANCj4gK2NvbmZpZyBQQ0lFX0tJUklODQo+ICsJZGVw ZW5kcyBvbiBPRiAmJiBBUk02NA0KPiArCWJvb2wgIkhpU2lsaWNvbiBLaXJpbiBzZXJpZXMgU29D cyBQQ0llIGNvbnRyb2xsZXJzIg0KPiArCWRlcGVuZHMgb24gUENJDQo+ICsJc2VsZWN0IFBDSUVQ T1JUQlVTDQo+ICsJc2VsZWN0IFBDSUVfRFdfSE9TVA0KPiArCWhlbHANCj4gKwkgIFNheSBZIGhl cmUgaWYgeW91IHdhbnQgUENJZSBjb250cm9sbGVyIHN1cHBvcnQgb24gSGlTaWxpY29uIEtpcmlu IHNlcmllcyBTb0NzDQo+ICsJICBraXJpbjk2MCBTb0MNCj4gKw0KPiAgZW5kbWVudQ0KPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9wY2kvZHdjL01ha2VmaWxlIGIvZHJpdmVycy9wY2kvZHdjL01ha2Vm aWxlIGluZGV4IA0KPiBhMmRmMTNjMjg3OTguLjRiZDY5YmFjZDRhYiAxMDA2NDQNCj4gLS0tIGEv ZHJpdmVycy9wY2kvZHdjL01ha2VmaWxlDQo+ICsrKyBiL2RyaXZlcnMvcGNpL2R3Yy9NYWtlZmls ZQ0KPiBAQCAtMTAsNiArMTAsNyBAQCBvYmotJChDT05GSUdfUENJX0xBWUVSU0NBUEUpICs9IHBj aS1sYXllcnNjYXBlLm8NCj4gIG9iai0kKENPTkZJR19QQ0lFX1FDT00pICs9IHBjaWUtcWNvbS5v DQo+ICBvYmotJChDT05GSUdfUENJRV9BUk1BREFfOEspICs9IHBjaWUtYXJtYWRhOGsubw0KPiAg b2JqLSQoQ09ORklHX1BDSUVfQVJUUEVDNikgKz0gcGNpZS1hcnRwZWM2Lm8NCj4gK29iai0kKENP TkZJR19QQ0lFX0tJUklOKSArPSBwY2llLWtpcmluLm8NCj4gIA0KPiAgIyBUaGUgZm9sbG93aW5n IGRyaXZlcnMgYXJlIGZvciBkZXZpY2VzIHRoYXQgdXNlIHRoZSBnZW5lcmljIEFDUEkgICMgDQo+ IHBjaV9yb290LmMgZHJpdmVyIGJ1dCBkb24ndCBzdXBwb3J0IHN0YW5kYXJkIEVDQU0gY29uZmln IGFjY2Vzcy4NCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNpL2R3Yy9wY2llLWtpcmluLmMgDQo+ IGIvZHJpdmVycy9wY2kvZHdjL3BjaWUta2lyaW4uYyBuZXcgZmlsZSBtb2RlIDEwMDY0NCBpbmRl eCANCj4gMDAwMDAwMDAwMDAwLi5hMTlkMTczMmFkOWYNCj4gLS0tIC9kZXYvbnVsbA0KPiArKysg Yi9kcml2ZXJzL3BjaS9kd2MvcGNpZS1raXJpbi5jDQo+IEBAIC0wLDAgKzEsNTIxIEBADQo+ICsv Kg0KPiArICogUENJZSBob3N0IGNvbnRyb2xsZXIgZHJpdmVyIGZvciBLaXJpbiBQaG9uZSBTb0Nz DQo+ICsgKg0KPiArICogQ29weXJpZ2h0IChDKSAyMDE1IEhpbGlzaWNvbiBFbGVjdHJvbmljcyBD by4sIEx0ZC4NCj4gKyAqCQlodHRwOi8vd3d3Lmh1YXdlaS5jb20NCj4gKyAqDQo+ICsgKiBBdXRo b3I6IFhpYW93ZWkgU29uZyA8c29uZ3hpYW93ZWlAaHVhd2VpLmNvbT4NCj4gKyAqDQo+ICsgKiBU aGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5k L29yIA0KPiArbW9kaWZ5DQo+ICsgKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5l cmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcw0KPiArICogcHVibGlzaGVkIGJ5IHRoZSBG cmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uDQo+ICsgKi8NCj4gKw0KPiArI2luY2x1ZGUgPGxpbnV4 L21mZC9zeXNjb24uaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9yZWdtYXAuaD4NCj4gKyNpbmNsdWRl IDxhc20vY29tcGlsZXIuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9jb21waWxlci5oPg0KPiArI2lu Y2x1ZGUgPGxpbnV4L2Nsay5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+DQo+ICsjaW5j bHVkZSA8bGludXgvZ3Bpby5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPg0KPiArI2luY2x1 ZGUgPGxpbnV4L2ludGVycnVwdC5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L29mX2dwaW8uaD4NCj4g KyNpbmNsdWRlIDxsaW51eC9wY2kuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9vZl9wY2kuaD4NCj4g KyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4NCj4gKyNpbmNsdWRlIDxsaW51eC9y ZXNvdXJjZS5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+DQo+ICsjaW5jbHVkZSA8bGlu dXgvb2ZfYWRkcmVzcy5oPg0KPiArI2luY2x1ZGUgPGxpbnV4L3BjaV9yZWdzLmg+DQo+ICsjaW5j bHVkZSAicGNpZS1kZXNpZ253YXJlLmgiDQo+ICsNCj4gKyNkZWZpbmUgdG9fa2lyaW5fcGNpZSh4 KSBkZXZfZ2V0X2RydmRhdGEoKHgpLT5kZXYpDQo+ICsNCj4gKyNkZWZpbmUgUkVGX0NMS19GUkVR IDEwMDAwMDAwMA0KPiArDQo+ICsvKiBQQ0llIEVMQkkgcmVnaXN0ZXJzICovDQo+ICsjZGVmaW5l IFNPQ19QQ0lFQ1RSTF9DVFJMMF9BRERSIDB4MDAwICNkZWZpbmUgU09DX1BDSUVDVFJMX0NUUkwx X0FERFIgDQo+ICsweDAwNCAjZGVmaW5lIFNPQ19QQ0lFUEhZX0NUUkwyX0FERFIgMHgwMDggI2Rl ZmluZSANCj4gK1NPQ19QQ0lFUEhZX0NUUkwzX0FERFIgMHgwMGMNCj4gKyNkZWZpbmUgUENJRV9F TEJJX1NMVl9EQklfRU5BQkxFCSgweDEgPDwgMjEpDQo+ICsNCj4gKyNkZWZpbmUgUENJRV9BUFBf TFRTU01fRU5BQkxFCQkweDAxYw0KPiArI2RlZmluZSBQQ0lFX0FQQl9QSFlfQ1RSTDAJCTB4MA0K PiArI2RlZmluZSBQQ0lFX0FQQl9QSFlfQ1RSTDEJCTB4NA0KPiArI2RlZmluZSBQQ0lFX0FQQl9Q SFlfU1RBVFVTMAkJMHg0MDANCj4gKyNkZWZpbmUgUENJRV9MSU5LVVBfRU5BQkxFCQkoMHg4MDIw KQ0KPiArI2RlZmluZSBQQ0lFX0xUU1NNX0VOQUJMRV9CSVQJICAoMHgxIDw8IDExKQ0KPiArI2Rl ZmluZSBQSVBFX0NMS19TVEFCTEUJCSgweDEgPDwgMTkpDQo+ICsjZGVmaW5lIFBJUEVfQ0xLX01B WF9UUllfVElNRVMJMTANCj4gKyNkZWZpbmUgUEhZX1JFRl9QQURfQklUCSgweDEgPDwgOCkNCj4g KyNkZWZpbmUgUEhZX1BXUl9ET1dOX0JJVAkoMHgxIDw8IDIyKQ0KPiArI2RlZmluZSBQSFlfUlNU X0FDS19CSVQJKDB4MSA8PCAxNikNCj4gKw0KPiArLyogaW5mbyBsYWNhdGVkIGluIHN5c2N0cmwg Ki8NCj4gKyNkZWZpbmUgU0NUUkxfUENJRV9DTU9TX09GRlNFVAkJMHg2MA0KPiArI2RlZmluZSBT Q1RSTF9QQ0lFX0NNT1NfQklUCQkweDEwDQo+ICsjZGVmaW5lIFNDVFJMX1BDSUVfSVNPX09GRlNF VAkJMHg0NA0KPiArI2RlZmluZSBTQ1RSTF9QQ0lFX0lTT19CSVQJCTB4MzANCj4gKyNkZWZpbmUg U0NUUkxfUENJRV9IUENMS19PRkZTRVQJCTB4MTkwDQo+ICsjZGVmaW5lIFNDVFJMX1BDSUVfSFBD TEtfQklUCQkweDE4NDAwMA0KPiArI2RlZmluZSBTQ1RSTF9QQ0lFX09FX09GRlNFVAkJMHgxNGEN Cj4gKyNkZWZpbmUgUENJRV9ERUJPVU5DRV9QQVJBTQkJMHhGMEY0MDANCj4gKyNkZWZpbmUgUENJ RV9PRV9CWVBBU1MJCSgweDMgPDwgMjgpDQo+ICsNCj4gKy8qcGVyaV9jcmcgY3RybCovDQo+ICsj ZGVmaW5lIENSR0NUUkxfUENJRV9BU1NFUlRfT0ZGU0VUCQkweDg4DQo+ICsjZGVmaW5lIENSR0NU UkxfUENJRV9BU1NFUlRfQklUCQkweDhjMDAwMDAwDQo+ICsNCj4gKy8qIFRpbWUgZm9yIGRlbGF5 Ki8NCj4gKyNkZWZpbmUgUkVGXzJfUEVSU1RfTUlOCQkoMjAwMDApDQo+ICsjZGVmaW5lIFJFRl8y X1BFUlNUX01BWAkJKDI1MDAwKQ0KPiArI2RlZmluZSBQRVJTVF8yX0FDQ0VTU19NSU4JKDEwMDAw KQ0KPiArI2RlZmluZSBQRVJTVF8yX0FDQ0VTU19NQVgJKDEyMDAwKQ0KPiArI2RlZmluZSBMSU5L X1dBSVRfTUlOCSg5MDApDQo+ICsjZGVmaW5lIExJTktfV0FJVF9NQVgJCSgxMDAwKQ0KPiArDQo+ ICtzdHJ1Y3Qga2lyaW5fcGNpZSB7DQo+ICsJdm9pZCBfX2lvbWVtCQkqYXBiX2Jhc2U7DQo+ICsJ dm9pZCBfX2lvbWVtCQkqcGh5X2Jhc2U7DQo+ICsJc3RydWN0IHJlZ21hcCAqY3JnY3RybDsNCj4g KwlzdHJ1Y3QgcmVnbWFwICpzeXNjdHJsOw0KPiArCXN0cnVjdCBjbGsJCQkqYXBiX3N5c19jbGs7 DQo+ICsJc3RydWN0IGNsawkJCSphcGJfcGh5X2NsazsNCj4gKwlzdHJ1Y3QgY2xrCQkJKnBoeV9y ZWZfY2xrOw0KPiArCXN0cnVjdCBjbGsJCQkqcGNpZV9hY2xrOw0KPiArCXN0cnVjdCBjbGsJCQkq cGNpZV9hdXhfY2xrOw0KPiArCWludCAgICAgICAgICAgICAgICAgZ3Bpb19pZF9yZXNldDsNCj4g KwlzdHJ1Y3QgZHdfcGNpZQkJKnBjaTsNCj4gK307DQo+ICsNCj4gK3N0YXRpYyBpbmxpbmUgdm9p ZCBraXJpbl9hcGJfY3RybF93cml0ZWwoc3RydWN0IGtpcmluX3BjaWUgKmtpcmluX3BjaWUsDQo+ ICsJCXUzMiB2YWwsIHUzMiByZWcpDQo+ICt7DQo+ICsJd3JpdGVsKHZhbCwga2lyaW5fcGNpZS0+ YXBiX2Jhc2UgKyByZWcpOyB9DQo+ICsNCj4gK3N0YXRpYyBpbmxpbmUgdTMyIGtpcmluX2FwYl9j dHJsX3JlYWRsKHN0cnVjdCBraXJpbl9wY2llICpraXJpbl9wY2llLA0KPiArCQl1MzIgcmVnKQ0K PiArew0KPiArCXJldHVybiByZWFkbChraXJpbl9wY2llLT5hcGJfYmFzZSArIHJlZyk7IH0NCj4g Kw0KPiArLypSZWdpc3RlcnMgaW4gUENJZVBIWSovDQo+ICtzdGF0aWMgaW5saW5lIHZvaWQga2ly aW5fYXBiX3BoeV93cml0ZWwoc3RydWN0IGtpcmluX3BjaWUgKmtpcmluX3BjaWUsDQo+ICsJCXUz MiB2YWwsIHUzMiByZWcpDQo+ICt7DQo+ICsJd3JpdGVsKHZhbCwga2lyaW5fcGNpZS0+cGh5X2Jh c2UgKyByZWcpOyB9DQo+ICsNCj4gK3N0YXRpYyBpbmxpbmUgdTMyIGtpcmluX2FwYl9waHlfcmVh ZGwoc3RydWN0IGtpcmluX3BjaWUgKmtpcmluX3BjaWUsDQo+ICsJCXUzMiByZWcpDQo+ICt7DQo+ ICsJcmV0dXJuIHJlYWRsKGtpcmluX3BjaWUtPnBoeV9iYXNlICsgcmVnKTsgfQ0KPiArDQo+ICtz dGF0aWMgaW50MzJfdCBraXJpbl9wY2llX2dldF9jbGsoc3RydWN0IGtpcmluX3BjaWUgKmtpcmlu X3BjaWUsDQo+ICsJCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ICt7DQo+ICsJa2ly aW5fcGNpZS0+cGh5X3JlZl9jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRldiwgInBjaWVfcGh5 X3JlZiIpOw0KPiArCWlmIChJU19FUlIoa2lyaW5fcGNpZS0+cGh5X3JlZl9jbGspKQ0KPiArCQly ZXR1cm4gUFRSX0VSUihraXJpbl9wY2llLT5waHlfcmVmX2Nsayk7DQo+ICsNCj4gKwlraXJpbl9w Y2llLT5wY2llX2F1eF9jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRldiwgInBjaWVfYXV4Iik7 DQo+ICsJaWYgKElTX0VSUihraXJpbl9wY2llLT5wY2llX2F1eF9jbGspKQ0KPiArCQlyZXR1cm4g UFRSX0VSUihraXJpbl9wY2llLT5wY2llX2F1eF9jbGspOw0KPiArDQo+ICsJa2lyaW5fcGNpZS0+ YXBiX3BoeV9jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRldiwgInBjaWVfYXBiX3BoeSIpOw0K PiArCWlmIChJU19FUlIoa2lyaW5fcGNpZS0+YXBiX3BoeV9jbGspKQ0KPiArCQlyZXR1cm4gUFRS X0VSUihraXJpbl9wY2llLT5hcGJfcGh5X2Nsayk7DQo+ICsNCj4gKwlraXJpbl9wY2llLT5hcGJf c3lzX2NsayA9IGRldm1fY2xrX2dldCgmcGRldi0+ZGV2LCAicGNpZV9hcGJfc3lzIik7DQo+ICsJ aWYgKElTX0VSUihraXJpbl9wY2llLT5hcGJfc3lzX2NsaykpDQo+ICsJCXJldHVybiBQVFJfRVJS KGtpcmluX3BjaWUtPmFwYl9zeXNfY2xrKTsNCj4gKw0KPiArCWtpcmluX3BjaWUtPnBjaWVfYWNs ayA9IGRldm1fY2xrX2dldCgmcGRldi0+ZGV2LCAicGNpZV9hY2xrIik7DQo+ICsJaWYgKElTX0VS UihraXJpbl9wY2llLT5wY2llX2FjbGspKQ0KPiArCQlyZXR1cm4gUFRSX0VSUihraXJpbl9wY2ll LT5wY2llX2FjbGspOw0KPiArDQo+ICsJcmV0dXJuIDA7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBp bnQzMl90IGtpcmluX3BjaWVfZ2V0X3Jlc291cmNlKHN0cnVjdCBraXJpbl9wY2llICpraXJpbl9w Y2llLA0KPiArCQlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiArew0KPiArCXN0cnVj dCByZXNvdXJjZSAqYXBiOw0KPiArCXN0cnVjdCByZXNvdXJjZSAqcGh5Ow0KPiArCXN0cnVjdCBy ZXNvdXJjZSAqZGJpOw0KPiArDQo+ICsJYXBiID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlX2J5bmFt ZShwZGV2LCBJT1JFU09VUkNFX01FTSwgImFwYiIpOw0KPiArCWtpcmluX3BjaWUtPmFwYl9iYXNl ID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKCZwZGV2LT5kZXYsIGFwYik7DQo+ICsJaWYgKElTX0VS UihraXJpbl9wY2llLT5hcGJfYmFzZSkpDQo+ICsJCXJldHVybiBQVFJfRVJSKGtpcmluX3BjaWUt PmFwYl9iYXNlKTsNCj4gKw0KPiArCXBoeSA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZV9ieW5hbWUo cGRldiwgSU9SRVNPVVJDRV9NRU0sICJwaHkiKTsNCj4gKwlraXJpbl9wY2llLT5waHlfYmFzZSA9 IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCBwaHkpOw0KPiArCWlmIChJU19FUlIo a2lyaW5fcGNpZS0+cGh5X2Jhc2UpKQ0KPiArCQlyZXR1cm4gUFRSX0VSUihraXJpbl9wY2llLT5w aHlfYmFzZSk7DQo+ICsNCj4gKwlkYmkgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2VfYnluYW1lKHBk ZXYsIElPUkVTT1VSQ0VfTUVNLCAiZGJpIik7DQo+ICsJa2lyaW5fcGNpZS0+cGNpLT5kYmlfYmFz ZSA9IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCBkYmkpOw0KPiArCWlmIChJU19F UlIoa2lyaW5fcGNpZS0+cGNpLT5kYmlfYmFzZSkpDQo+ICsJCXJldHVybiBQVFJfRVJSKGtpcmlu X3BjaWUtPnBjaS0+ZGJpX2Jhc2UpOw0KPiArDQo+ICsJa2lyaW5fcGNpZS0+Y3JnY3RybCA9DQo+ ICsJCXN5c2Nvbl9yZWdtYXBfbG9va3VwX2J5X2NvbXBhdGlibGUoImhpc2lsaWNvbixoaTM2NjAt Y3JnY3RybCIpOw0KPiArCWlmIChJU19FUlIoa2lyaW5fcGNpZS0+Y3JnY3RybCkpDQo+ICsJCXJl dHVybiBQVFJfRVJSKGtpcmluX3BjaWUtPmNyZ2N0cmwpOw0KPiArDQo+ICsJa2lyaW5fcGNpZS0+ c3lzY3RybCA9DQo+ICsJCXN5c2Nvbl9yZWdtYXBfbG9va3VwX2J5X2NvbXBhdGlibGUoImhpc2ls aWNvbixoaTM2NjAtc2N0cmwiKTsNCj4gKwlpZiAoSVNfRVJSKGtpcmluX3BjaWUtPnN5c2N0cmwp KQ0KPiArCQlyZXR1cm4gUFRSX0VSUihraXJpbl9wY2llLT5zeXNjdHJsKTsNCj4gKw0KPiArCXJl dHVybiAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IGtpcmluX3BjaWVfcGh5X2luaXQoc3Ry dWN0IGtpcmluX3BjaWUgKmtpcmluX3BjaWUpIHsNCj4gKwl1MzIgcmVnX3ZhbDsNCj4gKwl1MzIg dGltZSA9IFBJUEVfQ0xLX01BWF9UUllfVElNRVM7DQo+ICsNCj4gKwlyZWdfdmFsID0ga2lyaW5f YXBiX3BoeV9yZWFkbChraXJpbl9wY2llLCBQQ0lFX0FQQl9QSFlfQ1RSTDEpOw0KPiArCXJlZ192 YWwgJj0gflBIWV9SRUZfUEFEX0JJVDsNCj4gKwlraXJpbl9hcGJfcGh5X3dyaXRlbChraXJpbl9w Y2llLCByZWdfdmFsLCBQQ0lFX0FQQl9QSFlfQ1RSTDEpOw0KPiArDQo+ICsJcmVnX3ZhbCA9IGtp cmluX2FwYl9waHlfcmVhZGwoa2lyaW5fcGNpZSwgUENJRV9BUEJfUEhZX0NUUkwwKTsNCj4gKwly ZWdfdmFsICY9IH5QSFlfUFdSX0RPV05fQklUOw0KPiArCWtpcmluX2FwYl9waHlfd3JpdGVsKGtp cmluX3BjaWUsIHJlZ192YWwsIFBDSUVfQVBCX1BIWV9DVFJMMCk7DQo+ICsJdWRlbGF5KDEwKTsN Cj4gKw0KPiArCXJlZ192YWwgPSBraXJpbl9hcGJfcGh5X3JlYWRsKGtpcmluX3BjaWUsIFBDSUVf QVBCX1BIWV9DVFJMMSk7DQo+ICsJcmVnX3ZhbCAmPSB+UEhZX1JTVF9BQ0tfQklUOw0KPiArCWtp cmluX2FwYl9waHlfd3JpdGVsKGtpcmluX3BjaWUsIHJlZ192YWwsIFBDSUVfQVBCX1BIWV9DVFJM MSk7DQo+ICsNCj4gKwlyZWdfdmFsID0ga2lyaW5fYXBiX3BoeV9yZWFkbChraXJpbl9wY2llLCBQ Q0lFX0FQQl9QSFlfU1RBVFVTMCk7DQo+ICsJd2hpbGUgKHJlZ192YWwgJiBQSVBFX0NMS19TVEFC TEUpIHsNCj4gKwkJdWRlbGF5KDEwMCk7DQo+ICsJCWlmICh0aW1lID09IDApIHsNCj4gKwkJCWRl dl9lcnIoa2lyaW5fcGNpZS0+cGNpLT5kZXYsICJQSVBFIGNsayBpcyBub3Qgc3RhYmxlXG4iKTsN Cj4gKwkJCXJldHVybiAtRUlOVkFMOw0KPiArCQl9DQo+ICsJCXRpbWUtLTsNCj4gKwkJcmVnX3Zh bCA9IGtpcmluX2FwYl9waHlfcmVhZGwoa2lyaW5fcGNpZSwNCj4gKwkJCQlQQ0lFX0FQQl9QSFlf U1RBVFVTMCk7DQo+ICsJfQ0KPiArDQo+ICsJcmV0dXJuIDA7DQo+ICt9DQo+ICsNCj4gK3N0YXRp YyB2b2lkIGtpcmluX3BjaWVfb2VfZW5hYmxlKHN0cnVjdCBraXJpbl9wY2llICpraXJpbl9wY2ll KSB7DQo+ICsJdTMyIHZhbDsNCj4gKw0KPiArCXJlZ21hcF9yZWFkKGtpcmluX3BjaWUtPnN5c2N0 cmwsIFNDVFJMX1BDSUVfT0VfT0ZGU0VULCAmdmFsKTsNCj4gKwl2YWwgfD0gUENJRV9ERUJPVU5D RV9QQVJBTTsNCj4gKwl2YWwgJj0gflBDSUVfT0VfQllQQVNTOw0KPiArCXJlZ21hcF93cml0ZShr aXJpbl9wY2llLT5zeXNjdHJsLCBTQ1RSTF9QQ0lFX09FX09GRlNFVCwgdmFsKTsgfQ0KPiArDQo+ ICtzdGF0aWMgaW50IGtpcmluX3BjaWVfY2xrX2N0cmwoc3RydWN0IGtpcmluX3BjaWUgKmtpcmlu X3BjaWUsIGJvb2wgDQo+ICtlbmFibGUpIHsNCj4gKwlpbnQgcmV0ID0gMDsNCj4gKw0KPiArCWlm ICghZW5hYmxlKQ0KPiArCQlnb3RvIGNsb3NlX2NsazsNCj4gKw0KPiArCXJldCA9IGNsa19zZXRf cmF0ZShraXJpbl9wY2llLT5waHlfcmVmX2NsaywgUkVGX0NMS19GUkVRKTsNCj4gKwlpZiAocmV0 KQ0KPiArCQlyZXR1cm4gcmV0Ow0KPiArDQo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKGtp cmluX3BjaWUtPnBoeV9yZWZfY2xrKTsNCj4gKwlpZiAocmV0KQ0KPiArCQlyZXR1cm4gcmV0Ow0K PiArDQo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKGtpcmluX3BjaWUtPmFwYl9zeXNfY2xr KTsNCj4gKwlpZiAocmV0KQ0KPiArCQlnb3RvIGFwYl9zeXNfZmFpbDsNCj4gKw0KPiArCXJldCA9 IGNsa19wcmVwYXJlX2VuYWJsZShraXJpbl9wY2llLT5hcGJfcGh5X2Nsayk7DQo+ICsJaWYgKHJl dCkNCj4gKwkJZ290byBhcGJfcGh5X2ZhaWw7DQo+ICsNCj4gKwlyZXQgPSBjbGtfcHJlcGFyZV9l bmFibGUoa2lyaW5fcGNpZS0+cGNpZV9hY2xrKTsNCj4gKwlpZiAocmV0KQ0KPiArCQlnb3RvIGFj bGtfZmFpbDsNCj4gKw0KPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShraXJpbl9wY2llLT5w Y2llX2F1eF9jbGspOw0KPiArCWlmIChyZXQpDQo+ICsJCWdvdG8gYXV4X2Nsa19mYWlsOw0KPiAr DQo+ICsJcmV0dXJuIDA7DQo+ICtjbG9zZV9jbGs6DQo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJl KGtpcmluX3BjaWUtPnBjaWVfYXV4X2Nsayk7DQo+ICthdXhfY2xrX2ZhaWw6DQo+ICsJY2xrX2Rp c2FibGVfdW5wcmVwYXJlKGtpcmluX3BjaWUtPnBjaWVfYWNsayk7DQo+ICthY2xrX2ZhaWw6DQo+ ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGtpcmluX3BjaWUtPmFwYl9waHlfY2xrKTsNCj4gK2Fw Yl9waHlfZmFpbDoNCj4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUoa2lyaW5fcGNpZS0+YXBiX3N5 c19jbGspOw0KPiArYXBiX3N5c19mYWlsOg0KPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShraXJp bl9wY2llLT5waHlfcmVmX2Nsayk7DQo+ICsJcmV0dXJuIHJldDsNCj4gK30NCj4gKw0KPiArc3Rh dGljIGludCBraXJpbl9wY2llX3Bvd2VyX29uKHN0cnVjdCBraXJpbl9wY2llICpraXJpbl9wY2ll KSB7DQo+ICsJaW50IHJldDsNCj4gKw0KPiArCS8qUG93ZXIgc3VwcGx5IGZvciBIb3N0Ki8NCj4g KwlyZWdtYXBfd3JpdGUoa2lyaW5fcGNpZS0+c3lzY3RybCwNCj4gKwkJU0NUUkxfUENJRV9DTU9T X09GRlNFVCwgU0NUUkxfUENJRV9DTU9TX0JJVCk7DQo+ICsJdWRlbGF5KDEwMCk7DQo+ICsJa2ly aW5fcGNpZV9vZV9lbmFibGUoa2lyaW5fcGNpZSk7DQo+ICsNCj4gKwlyZXQgPSBraXJpbl9wY2ll X2Nsa19jdHJsKGtpcmluX3BjaWUsIHRydWUpOw0KPiArCWlmIChyZXQpDQo+ICsJCXJldHVybiBy ZXQ7DQo+ICsNCj4gKwkvKmRlYXNzZXQgUENJZUN0cmwmUENJZVBIWSovDQo+ICsJcmVnbWFwX3dy aXRlKGtpcmluX3BjaWUtPnN5c2N0cmwsDQo+ICsJCVNDVFJMX1BDSUVfSVNPX09GRlNFVCwgU0NU UkxfUENJRV9JU09fQklUKTsNCj4gKwlyZWdtYXBfd3JpdGUoa2lyaW5fcGNpZS0+Y3JnY3RybCwN Cj4gKwkJQ1JHQ1RSTF9QQ0lFX0FTU0VSVF9PRkZTRVQsIENSR0NUUkxfUENJRV9BU1NFUlRfQklU KTsNCj4gKwlyZWdtYXBfd3JpdGUoa2lyaW5fcGNpZS0+c3lzY3RybCwNCj4gKwkJU0NUUkxfUENJ RV9IUENMS19PRkZTRVQsIFNDVFJMX1BDSUVfSFBDTEtfQklUKTsNCj4gKw0KPiArCXJldCA9IGtp cmluX3BjaWVfcGh5X2luaXQoa2lyaW5fcGNpZSk7DQo+ICsJaWYgKHJldCkNCj4gKwkJZ290byBj bG9zZV9jbGs7DQo+ICsNCj4gKwkvKnBlcnN0IGFzc2VydCBFbmRwb2ludCovDQo+ICsJaWYgKCFn cGlvX3JlcXVlc3Qoa2lyaW5fcGNpZS0+Z3Bpb19pZF9yZXNldCwgInBjaWVfcGVyc3QiKSkgew0K PiArCQl1c2xlZXBfcmFuZ2UoUkVGXzJfUEVSU1RfTUlOLCBSRUZfMl9QRVJTVF9NQVgpOw0KPiAr CQlyZXQgPSBncGlvX2RpcmVjdGlvbl9vdXRwdXQoa2lyaW5fcGNpZS0+Z3Bpb19pZF9yZXNldCwg MSk7DQo+ICsJCWlmIChyZXQpDQo+ICsJCQlnb3RvIGNsb3NlX2NsazsNCj4gKwkJdXNsZWVwX3Jh bmdlKFBFUlNUXzJfQUNDRVNTX01JTiwgUEVSU1RfMl9BQ0NFU1NfTUFYKTsNCj4gKw0KPiArCQly ZXR1cm4gMDsNCj4gKwl9DQo+ICsNCj4gK2Nsb3NlX2NsazoNCj4gKwlraXJpbl9wY2llX2Nsa19j dHJsKGtpcmluX3BjaWUsIGZhbHNlKTsNCj4gKwlyZXR1cm4gcmV0Ow0KPiArfQ0KPiArDQo+ICtz dGF0aWMgdm9pZCBraXJpbl9wY2llX3NpZGViYW5kX2RiaV93X21vZGUoc3RydWN0IGtpcmluX3Bj aWUgKmtpcmluX3BjaWUsDQo+ICsJCWJvb2wgb24pDQo+ICt7DQo+ICsJdTMyIHZhbDsNCj4gKw0K PiArCXZhbCA9IGtpcmluX2FwYl9jdHJsX3JlYWRsKGtpcmluX3BjaWUsIFNPQ19QQ0lFQ1RSTF9D VFJMMF9BRERSKTsNCj4gKwlpZiAob24pDQo+ICsJCXZhbCA9IHZhbCB8IFBDSUVfRUxCSV9TTFZf REJJX0VOQUJMRTsNCj4gKwllbHNlDQo+ICsJCXZhbCA9IHZhbCAmIH5QQ0lFX0VMQklfU0xWX0RC SV9FTkFCTEU7DQo+ICsNCj4gKwlraXJpbl9hcGJfY3RybF93cml0ZWwoa2lyaW5fcGNpZSwgdmFs LCBTT0NfUENJRUNUUkxfQ1RSTDBfQUREUik7IH0NCj4gKw0KPiArc3RhdGljIHZvaWQga2lyaW5f cGNpZV9zaWRlYmFuZF9kYmlfcl9tb2RlKHN0cnVjdCBraXJpbl9wY2llICpraXJpbl9wY2llLA0K PiArCQlib29sIG9uKQ0KPiArew0KPiArCXUzMiB2YWw7DQo+ICsNCj4gKwl2YWwgPSBraXJpbl9h cGJfY3RybF9yZWFkbChraXJpbl9wY2llLCBTT0NfUENJRUNUUkxfQ1RSTDFfQUREUik7DQo+ICsJ aWYgKG9uKQ0KPiArCQl2YWwgPSB2YWwgfCBQQ0lFX0VMQklfU0xWX0RCSV9FTkFCTEU7DQo+ICsJ ZWxzZQ0KPiArCQl2YWwgPSB2YWwgJiB+UENJRV9FTEJJX1NMVl9EQklfRU5BQkxFOw0KPiArDQo+ ICsJa2lyaW5fYXBiX2N0cmxfd3JpdGVsKGtpcmluX3BjaWUsIHZhbCwgU09DX1BDSUVDVFJMX0NU UkwxX0FERFIpOyB9DQo+ICsNCj4gK3N0YXRpYyBpbnQga2lyaW5fcGNpZV9yZF9vd25fY29uZihz dHJ1Y3QgcGNpZV9wb3J0ICpwcCwNCj4gKwkJaW50IHdoZXJlLCBpbnQgc2l6ZSwgdTMyICp2YWwp DQo+ICt7DQo+ICsJc3RydWN0IGR3X3BjaWUgKnBjaSA9IHRvX2R3X3BjaWVfZnJvbV9wcChwcCk7 DQo+ICsJc3RydWN0IGtpcmluX3BjaWUgKmtpcmluX3BjaWUgPSB0b19raXJpbl9wY2llKHBjaSk7 DQo+ICsJaW50IHJldDsNCj4gKw0KPiArCWtpcmluX3BjaWVfc2lkZWJhbmRfZGJpX3JfbW9kZShr aXJpbl9wY2llLCB0cnVlKTsNCj4gKwlyZXQgPSBkd19wY2llX3JlYWQocGNpLT5kYmlfYmFzZSAr IHdoZXJlLCBzaXplLCB2YWwpOw0KPiArCWtpcmluX3BjaWVfc2lkZWJhbmRfZGJpX3JfbW9kZShr aXJpbl9wY2llLCBmYWxzZSk7DQo+ICsNCj4gKwlyZXR1cm4gcmV0Ow0KPiArfQ0KPiArDQo+ICtz dGF0aWMgaW50IGtpcmluX3BjaWVfd3Jfb3duX2NvbmYoc3RydWN0IHBjaWVfcG9ydCAqcHAsDQo+ ICsJCWludCB3aGVyZSwgaW50IHNpemUsIHUzMiB2YWwpDQo+ICt7DQo+ICsJaW50IHJldDsNCj4g KwlzdHJ1Y3QgZHdfcGNpZSAqcGNpID0gdG9fZHdfcGNpZV9mcm9tX3BwKHBwKTsNCj4gKwlzdHJ1 Y3Qga2lyaW5fcGNpZSAqa2lyaW5fcGNpZSA9IHRvX2tpcmluX3BjaWUocGNpKTsNCj4gKw0KPiAr CWtpcmluX3BjaWVfc2lkZWJhbmRfZGJpX3dfbW9kZShraXJpbl9wY2llLCB0cnVlKTsNCj4gKwly ZXQgPSBkd19wY2llX3dyaXRlKHBjaS0+ZGJpX2Jhc2UgKyB3aGVyZSwgc2l6ZSwgdmFsKTsNCj4g KwlraXJpbl9wY2llX3NpZGViYW5kX2RiaV93X21vZGUoa2lyaW5fcGNpZSwgZmFsc2UpOw0KPiAr DQo+ICsJcmV0dXJuIHJldDsNCj4gK30NCj4gKw0KPiArc3RhdGljIHUzMiBraXJpbl9wY2llX3Jl YWRfZGJpKHN0cnVjdCBkd19wY2llICpwY2ksIHZvaWQgX19pb21lbSAqYmFzZSwNCj4gKwkJdTMy IHJlZywgc2l6ZV90IHNpemUpDQo+ICt7DQo+ICsJdTMyIHJldDsNCj4gKwlzdHJ1Y3Qga2lyaW5f cGNpZSAqa2lyaW5fcGNpZSA9IHRvX2tpcmluX3BjaWUocGNpKTsNCj4gKw0KPiArCWtpcmluX3Bj aWVfc2lkZWJhbmRfZGJpX3JfbW9kZShraXJpbl9wY2llLCB0cnVlKTsNCj4gKwlkd19wY2llX3Jl YWQoYmFzZSArIHJlZywgc2l6ZSwgJnJldCk7DQo+ICsJa2lyaW5fcGNpZV9zaWRlYmFuZF9kYmlf cl9tb2RlKGtpcmluX3BjaWUsIGZhbHNlKTsNCj4gKw0KPiArCXJldHVybiByZXQ7DQo+ICt9DQo+ ICsNCj4gK3N0YXRpYyB2b2lkIGtpcmluX3BjaWVfd3JpdGVfZGJpKHN0cnVjdCBkd19wY2llICpw Y2ksIHZvaWQgX19pb21lbSAqYmFzZSwNCj4gKwkJdTMyIHJlZywgc2l6ZV90IHNpemUsIHUzMiB2 YWwpDQo+ICt7DQo+ICsJc3RydWN0IGtpcmluX3BjaWUgKmtpcmluX3BjaWUgPSB0b19raXJpbl9w Y2llKHBjaSk7DQo+ICsNCj4gKwlraXJpbl9wY2llX3NpZGViYW5kX2RiaV93X21vZGUoa2lyaW5f cGNpZSwgdHJ1ZSk7DQo+ICsJZHdfcGNpZV93cml0ZShiYXNlICsgcmVnLCBzaXplLCB2YWwpOw0K PiArCWtpcmluX3BjaWVfc2lkZWJhbmRfZGJpX3dfbW9kZShraXJpbl9wY2llLCBmYWxzZSk7IH0N Cj4gKw0KPiArc3RhdGljIGludCBraXJpbl9wY2llX2xpbmtfdXAoc3RydWN0IGR3X3BjaWUgKnBj aSkgew0KPiArCXN0cnVjdCBraXJpbl9wY2llICpraXJpbl9wY2llID0gdG9fa2lyaW5fcGNpZShw Y2kpOw0KPiArCXUzMiB2YWwgPSBraXJpbl9hcGJfY3RybF9yZWFkbChraXJpbl9wY2llLCBQQ0lF X0FQQl9QSFlfU1RBVFVTMCk7DQo+ICsNCj4gKwlpZiAoKHZhbCAmIFBDSUVfTElOS1VQX0VOQUJM RSkgPT0gUENJRV9MSU5LVVBfRU5BQkxFKQ0KPiArCQlyZXR1cm4gMTsNCj4gKw0KPiArCXJldHVy biAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IGtpcmluX3BjaWVfZXN0YWJsaXNoX2xpbmso c3RydWN0IHBjaWVfcG9ydCAqcHApIHsNCj4gKwlpbnQgY291bnQgPSAwOw0KPiArDQo+ICsJc3Ry dWN0IGR3X3BjaWUgKnBjaSA9IHRvX2R3X3BjaWVfZnJvbV9wcChwcCk7DQo+ICsJc3RydWN0IGtp cmluX3BjaWUgKmtpcmluX3BjaWUgPSB0b19raXJpbl9wY2llKHBjaSk7DQo+ICsNCj4gKwlpZiAo a2lyaW5fcGNpZV9saW5rX3VwKHBjaSkpDQo+ICsJCXJldHVybiAwOw0KPiArDQo+ICsJZHdfcGNp ZV9zZXR1cF9yYyhwcCk7DQo+ICsNCj4gKwkvKiBhc3NlcnQgTFRTU00gZW5hYmxlICovDQo+ICsJ a2lyaW5fYXBiX2N0cmxfd3JpdGVsKGtpcmluX3BjaWUsIFBDSUVfTFRTU01fRU5BQkxFX0JJVCwN Cj4gKwkJUENJRV9BUFBfTFRTU01fRU5BQkxFKTsNCj4gKw0KPiArCS8qIGNoZWNrIGlmIHRoZSBs aW5rIGlzIHVwIG9yIG5vdCAqLw0KPiArCXdoaWxlICgha2lyaW5fcGNpZV9saW5rX3VwKHBjaSkp IHsNCj4gKwkJdXNsZWVwX3JhbmdlKExJTktfV0FJVF9NSU4sIExJTktfV0FJVF9NQVgpOw0KPiAr CQljb3VudCsrOw0KPiArCQlpZiAoY291bnQgPT0gMTAwMCkgew0KPiArCQkJZGV2X2VycihwY2kt PmRldiwgIkxpbmsgRmFpbFxuIik7DQo+ICsJCQlyZXR1cm4gLUVJTlZBTDsNCj4gKwkJfQ0KPiAr CX0NCj4gKw0KPiArCXJldHVybiAwOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgdm9pZCBraXJpbl9w Y2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCkgew0KPiArCWtpcmluX3BjaWVfZXN0 YWJsaXNoX2xpbmsocHApOw0KPiArfQ0KPiArDQo+ICtzdGF0aWMgc3RydWN0IGR3X3BjaWVfb3Bz IGtpcmluX2R3X3BjaWVfb3BzID0gew0KPiArCS5yZWFkX2RiaSA9IGtpcmluX3BjaWVfcmVhZF9k YmksDQo+ICsJLndyaXRlX2RiaSA9IGtpcmluX3BjaWVfd3JpdGVfZGJpLA0KPiArCS5saW5rX3Vw ID0ga2lyaW5fcGNpZV9saW5rX3VwLA0KPiArfTsNCj4gKw0KPiArc3RhdGljIHN0cnVjdCBkd19w Y2llX2hvc3Rfb3BzIGtpcmluX3BjaWVfaG9zdF9vcHMgPSB7DQo+ICsJLnJkX293bl9jb25mID0g a2lyaW5fcGNpZV9yZF9vd25fY29uZiwNCj4gKwkud3Jfb3duX2NvbmYgPSBraXJpbl9wY2llX3dy X293bl9jb25mLA0KPiArCS5ob3N0X2luaXQgPSBraXJpbl9wY2llX2hvc3RfaW5pdCwNCj4gK307 DQo+ICsNCj4gK3N0YXRpYyBpbnQgX19pbml0IGtpcmluX2FkZF9wY2llX3BvcnQoc3RydWN0IGR3 X3BjaWUgKnBjaSwNCj4gKwkJCXN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ICt7DQo+ ICsJaW50IHJldDsNCj4gKw0KPiArCXBjaS0+cHAub3BzID0gJmtpcmluX3BjaWVfaG9zdF9vcHM7 DQo+ICsNCj4gKwlyZXQgPSBkd19wY2llX2hvc3RfaW5pdCgmcGNpLT5wcCk7DQo+ICsNCj4gKwly ZXR1cm4gcmV0Ow0KPiArfQ0KPiArDQo+ICtzdGF0aWMgaW50IGtpcmluX3BjaWVfcHJvYmUoc3Ry dWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikgew0KPiArCXN0cnVjdCBraXJpbl9wY2llICpraXJp bl9wY2llOw0KPiArCXN0cnVjdCBkd19wY2llICpwY2k7DQo+ICsJc3RydWN0IGRldmljZSAqZGV2 ID0gJnBkZXYtPmRldjsNCj4gKwlpbnQgcmV0Ow0KPiArDQo+ICsJaWYgKCFwZGV2LT5kZXYub2Zf bm9kZSkgew0KPiArCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJOVUxMIG5vZGVcbiIpOw0KPiArCQly ZXR1cm4gLUVJTlZBTDsNCj4gKwl9DQo+ICsNCj4gKwlraXJpbl9wY2llID0gZGV2bV9remFsbG9j KCZwZGV2LT5kZXYsDQo+ICsJCQlzaXplb2Yoc3RydWN0IGtpcmluX3BjaWUpLCBHRlBfS0VSTkVM KTsNCj4gKwlpZiAoIWtpcmluX3BjaWUpDQo+ICsJCXJldHVybiAtRU5PTUVNOw0KPiArDQo+ICsJ cGNpID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwY2kpLCBHRlBfS0VSTkVMKTsNCj4gKwlp ZiAoIXBjaSkNCj4gKwkJcmV0dXJuIC1FTk9NRU07DQo+ICsNCj4gKwlwY2ktPmRldiA9IGRldjsN Cj4gKwlwY2ktPm9wcyA9ICZraXJpbl9kd19wY2llX29wczsNCj4gKwlraXJpbl9wY2llLT5wY2kg PSBwY2k7DQo+ICsNCj4gKwlyZXQgPSBraXJpbl9wY2llX2dldF9jbGsoa2lyaW5fcGNpZSwgcGRl dik7DQo+ICsJaWYgKHJldCkNCj4gKwkJcmV0dXJuIHJldDsNCj4gKw0KPiArCXJldCA9IGtpcmlu X3BjaWVfZ2V0X3Jlc291cmNlKGtpcmluX3BjaWUsIHBkZXYpOw0KPiArCWlmIChyZXQpDQo+ICsJ CXJldHVybiByZXQ7DQo+ICsNCj4gKwlraXJpbl9wY2llLT5ncGlvX2lkX3Jlc2V0ID0gb2ZfZ2V0 X25hbWVkX2dwaW8ocGRldi0+ZGV2Lm9mX25vZGUsDQo+ICsJCQkicmVzZXQtZ3BpbyIsIDApOw0K PiArCWlmIChraXJpbl9wY2llLT5ncGlvX2lkX3Jlc2V0IDwgMCkNCj4gKwkJcmV0dXJuIC1FTk9E RVY7DQo+ICsNCj4gKwlyZXQgPSBraXJpbl9wY2llX3Bvd2VyX29uKGtpcmluX3BjaWUpOw0KPiAr CWlmIChyZXQpDQo+ICsJCXJldHVybiByZXQ7DQo+ICsNCj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0 YShwZGV2LCBraXJpbl9wY2llKTsNCj4gKw0KPiArCXJldCA9IGtpcmluX2FkZF9wY2llX3BvcnQo cGNpLCBwZGV2KTsNCj4gKwlpZiAocmV0KQ0KPiArCQlyZXR1cm4gcmV0Ow0KPiArDQo+ICsJcmV0 dXJuIDA7DQo+ICt9DQo+ICsNCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIGtp cmluX3BjaWVfbWF0Y2hbXSA9IHsNCj4gKwl7IC5jb21wYXRpYmxlID0gImhpc2lsaWNvbixraXJp bi1wY2llIiB9LA0KPiArCXt9LA0KPiArfTsNCj4gKw0KPiArc3RydWN0IHBsYXRmb3JtX2RyaXZl ciBraXJpbl9wY2llX2RyaXZlciA9IHsNCj4gKwkucHJvYmUJCQk9IGtpcmluX3BjaWVfcHJvYmUs DQo+ICsJLmRyaXZlcgkJCT0gew0KPiArCQkubmFtZQkJCT0gIktpcmluLXBjaWUiLA0KPiArCQku b2ZfbWF0Y2hfdGFibGUgPSBraXJpbl9wY2llX21hdGNoLA0KPiArCX0sDQo+ICt9Ow0KDQpIZWxs byBTb25nLA0KDQoNCllvdSBmb3Jnb3QgdG8gYWRkDQouc3VwcHJlc3NfYmluZF9hdHRycyA9IHRy dWUsDQoNClNlZSB0aGUgZm9sbG93aW5nIGNvbW1pdCBhcyB0byB3aHkgdGhpcyBpcyBuZWVkZWQ6 DQpodHRwczovL2dpdC5rZXJuZWwub3JnL3B1Yi9zY20vbGludXgva2VybmVsL2dpdC9oZWxnYWFz L3BjaS5naXQvY29tbWl0L2RyaXZlcnMvcGNpL2R3Yz9pZD1hNWY0MGU4MDk4ZmU2ZDk4M2ZkYjNi ZWI3YjUwYTgwNjdjMTM2MTQxDQoNCg0KUmVnYXJkcywNCk5pa2xhcw0KDQo+ICsNCj4gK2J1aWx0 aW5fcGxhdGZvcm1fZHJpdmVyKGtpcmluX3BjaWVfZHJpdmVyKTsNCj4gDQo=