From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C1FC6C49EA5 for ; Thu, 24 Jun 2021 22:50:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A9015613B9 for ; Thu, 24 Jun 2021 22:50:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232713AbhFXWwo (ORCPT ); Thu, 24 Jun 2021 18:52:44 -0400 Received: from mail.kernel.org ([198.145.29.99]:54666 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232909AbhFXWwS (ORCPT ); Thu, 24 Jun 2021 18:52:18 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id BC0476138C; Thu, 24 Jun 2021 22:49:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1624574999; bh=9edfwL/4cz9Vzqi/IVyM0oZ83o5hhf3oSSiTXQszjiE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lRYQCeKmS45/ofKsNADBDcj1wZuDn45S9PxEhb4onA4/YosxTEOmhaaawgD3iRwOo itrhWXM3E342+gmfGEclhxTnw4fwbplfyB89En6ynMgefocUObRrhBpwPfEmG3XhhJ iS36k7FbfGLd6dK5lmM+l9gbjAPln75wex3l9PPK0vlp9WoK1vhNh39qqbpfALvIaT Gvcw2a+yFHMOuYVQhAIV8a6YUHfSr8/agAmM2RW9cL4Yurb4vOWSxGVMQUtoo2Ptbk aUY01VwB4YVPMsBL79jpVi6gTWV9tYWo2hNAfeTb7gb3orsjPwPCnu5Hwq2noV75Vi 0eElgtzdb6tbQ== Received: by pali.im (Postfix) id 7AAF48A3; Fri, 25 Jun 2021 00:49:58 +0200 (CEST) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman Cc: Andrew Lunn , Gregory Clement , Sebastian Hesselbarth , Vladimir Vid , =?UTF-8?q?Marek=20Beh=C3=BAn?= , linux-clk@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 07/10] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Fri, 25 Jun 2021 00:49:06 +0200 Message-Id: <20210624224909.6350-8-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210624224909.6350-1-pali@kernel.org> References: <20210624224909.6350-1-pali@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch implements a new device driver for controlling UART clocks on Marvell Armada 3700 SoC. This device driver is loaded for devices which match compatible string "marvell,armada-3700-uart-clock". There are more pitfalls related to UART clocks. Both UARTs use same base clock source. Also divisors for TBG base clock are shared between both UARTs and are configured only from UART1 address space. Clocks can be enabled / disabled separately for UART1 and UART2, but they are controlled only from UART1 address space. Moreover Marvell Armada 3700 Functional Specifications has swapped bits for enabling/disabling UART1 and UART2 clocks. So driver for controlling UART2 needs to have access to UART1 address space as UART1 address space contains some bits exclusively used by UART2 and also bits which are shared for both UART1 and UART2. For changing UART base clock (which controls both UARTs) during boot when UART driver is not ready and only early console is active, is not simple operation as it is required to also recalculate divisors to not change UART baudrate used by early console. So for this operation UART1 clock driver needs to access also into address space of UART2 where are registers for UART2 divisors. For these reasons, this new device driver for UART clocks does not use ioremap_resource(), but only ioremap() to prevent resource conflicts between UART clock driver and UART driver. Shared between drivers are only two 4-bytes registers: UART Clock Control and UART 2 Baud Rate Divisor. Access to these two registers are protected by one spinlock to prevent any conflicts. Access is required only during probe time, changing baudrate and during suspend/resume. Hardware can be configured to use one of following clocks as UART base clock: TBG-A-P, TBG-B-P, TBG-A-S, TBG-B-S, xtal. Not every clock is usable for higher buadrates. In DT node can be specified any subset and kernel choose the best one, which still supports required baudrate 9600. For smooth boot log output it is needed to specify clock used by early console otherwise garbage would be put on UART during probing for UART clock driver and transitioning from early console to normal console. This change is required to enable and configure TBG clock as a base clock for UART. TBG clock is required to achieve higher baudrates than 230400. Signed-off-by: Pali Rohár --- drivers/tty/serial/mvebu-uart.c | 517 +++++++++++++++++++++++++++++++- 1 file changed, 515 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 414e92064ac6..e51a84be1939 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -68,8 +69,31 @@ #define STAT_BRK_ERR (STAT_BRK_DET | STAT_FRM_ERR \ | STAT_PAR_ERR | STAT_OVR_ERR) +/* + * Marvell Armada 3700 Functional Specifications describes that bit 21 of UART + * Clock Control register controls UART1 and bit 20 controls UART2. But in + * reality bit 21 controls UART2 and bit 20 controls UART1. This seems to be a + * bug in Marvell documentation. Hence following CLK_DIS macros are swapped. + */ + #define UART_BRDV 0x10 +/* These bits are located in UART1 address space and control UART2 */ +#define UART2_CLK_DIS BIT(21) +/* These bits are located in UART1 address space and control UART1 */ +#define UART1_CLK_DIS BIT(20) +/* These bits are located in UART1 address space and control both UARTs */ +#define CLK_NO_XTAL BIT(19) +#define CLK_TBG_DIV1_SHIFT 15 +#define CLK_TBG_DIV1_MASK 0x7 +#define CLK_TBG_DIV1_MAX 6 +#define CLK_TBG_DIV2_SHIFT 12 +#define CLK_TBG_DIV2_MASK 0x7 +#define CLK_TBG_DIV2_MAX 6 +#define CLK_TBG_SEL_SHIFT 10 +#define CLK_TBG_SEL_MASK 0x3 +/* These bits are located in both UARTs address space */ #define BRDV_BAUD_MASK 0x3FF +#define BRDV_BAUD_MAX BRDV_BAUD_MASK #define UART_OSAMP 0x14 #define OSAMP_DEFAULT_DIVISOR 16 @@ -153,6 +177,8 @@ static struct mvebu_uart *to_mvuart(struct uart_port *port) static struct uart_port mvebu_uart_ports[MVEBU_NR_UARTS]; +static DEFINE_SPINLOCK(mvebu_uart_lock); + /* Core UART Driver Operations */ static unsigned int mvebu_uart_tx_empty(struct uart_port *port) { @@ -445,6 +471,7 @@ static void mvebu_uart_shutdown(struct uart_port *port) static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud) { unsigned int d_divisor, m_divisor; + unsigned long flags; u32 brdv, osamp; if (!port->uartclk) @@ -463,10 +490,12 @@ static int mvebu_uart_baud_rate_set(struct uart_port *port, unsigned int baud) m_divisor = OSAMP_DEFAULT_DIVISOR; d_divisor = DIV_ROUND_CLOSEST(port->uartclk, baud * m_divisor); + spin_lock_irqsave(&mvebu_uart_lock, flags); brdv = readl(port->membase + UART_BRDV); brdv &= ~BRDV_BAUD_MASK; brdv |= d_divisor; writel(brdv, port->membase + UART_BRDV); + spin_unlock_irqrestore(&mvebu_uart_lock, flags); osamp = readl(port->membase + UART_OSAMP); osamp &= ~OSAMP_DIVISORS_MASK; @@ -762,6 +791,7 @@ static int mvebu_uart_suspend(struct device *dev) { struct mvebu_uart *mvuart = dev_get_drvdata(dev); struct uart_port *port = mvuart->port; + unsigned long flags; uart_suspend_port(&mvebu_uart_driver, port); @@ -770,7 +800,9 @@ static int mvebu_uart_suspend(struct device *dev) mvuart->pm_regs.ctrl = readl(port->membase + UART_CTRL(port)); mvuart->pm_regs.intr = readl(port->membase + UART_INTR(port)); mvuart->pm_regs.stat = readl(port->membase + UART_STAT); + spin_lock_irqsave(&mvebu_uart_lock, flags); mvuart->pm_regs.brdv = readl(port->membase + UART_BRDV); + spin_unlock_irqrestore(&mvebu_uart_lock, flags); mvuart->pm_regs.osamp = readl(port->membase + UART_OSAMP); device_set_wakeup_enable(dev, true); @@ -782,13 +814,16 @@ static int mvebu_uart_resume(struct device *dev) { struct mvebu_uart *mvuart = dev_get_drvdata(dev); struct uart_port *port = mvuart->port; + unsigned long flags; writel(mvuart->pm_regs.rbr, port->membase + UART_RBR(port)); writel(mvuart->pm_regs.tsh, port->membase + UART_TSH(port)); writel(mvuart->pm_regs.ctrl, port->membase + UART_CTRL(port)); writel(mvuart->pm_regs.intr, port->membase + UART_INTR(port)); writel(mvuart->pm_regs.stat, port->membase + UART_STAT); + spin_lock_irqsave(&mvebu_uart_lock, flags); writel(mvuart->pm_regs.brdv, port->membase + UART_BRDV); + spin_unlock_irqrestore(&mvebu_uart_lock, flags); writel(mvuart->pm_regs.osamp, port->membase + UART_OSAMP); uart_resume_port(&mvebu_uart_driver, port); @@ -975,6 +1010,475 @@ static struct platform_driver mvebu_uart_platform_driver = { }, }; +/* This code is based on clk-fixed-factor.c driver and modified. */ + +struct mvebu_uart_clock { + struct clk_hw clk_hw; + int clock_idx; + u32 pm_context_reg1; + u32 pm_context_reg2; +}; + +struct mvebu_uart_clock_base { + struct mvebu_uart_clock clocks[2]; + unsigned int parent_rates[5]; + int parent_idx; + unsigned int div; + void __iomem *reg1; + void __iomem *reg2; + bool configured; +}; + +#define PARENT_CLOCK_XTAL 4 + +#define to_uart_clock(hw) container_of(hw, struct mvebu_uart_clock, clk_hw) +#define to_uart_clock_base(uart_clock) container_of(uart_clock, \ + struct mvebu_uart_clock_base, clocks[uart_clock->clock_idx]) + +static int mvebu_uart_clock_prepare(struct clk_hw *hw) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + unsigned int prev_clock_idx, prev_clock_rate, prev_d1d2; + unsigned int parent_clock_idx, parent_clock_rate; + unsigned int d1, d2, divisor; + unsigned long flags; + u32 val; + + /* + * This function just reconfigures UART Clock Control register (located + * in UART1 address space which controls both UART1 and UART2) to + * selected UART base clock and recalculate current UART1/UART2 divisors + * in their address spaces, so final baudrate will not be changed by + * switching UART base clock. This is required otherwise kernel boot log + * stops working. It is needed to ensure that UART baudrate does not + * change during this setup. It is one time operation, so based on + * "configured" member this function is skipped on second call. Because + * this UART Clock Control register (UART_BRDV) is shared between UART1 + * baudrate function, UART1 clock selector and UART2 clock selector, + * every access to UART_BRDV (reg1) needs to be protected by lock. + */ + + spin_lock_irqsave(&mvebu_uart_lock, flags); + + if (uart_clock_base->configured) { + spin_unlock_irqrestore(&mvebu_uart_lock, flags); + return 0; + } + + parent_clock_idx = uart_clock_base->parent_idx; + parent_clock_rate = uart_clock_base->parent_rates[parent_clock_idx]; + + val = readl(uart_clock_base->reg1); + + if (uart_clock_base->div > CLK_TBG_DIV1_MAX) { + d1 = CLK_TBG_DIV1_MAX; + d2 = uart_clock_base->div / CLK_TBG_DIV1_MAX; + } else { + d1 = uart_clock_base->div; + d2 = 1; + } + + if (val & CLK_NO_XTAL) { + prev_clock_idx = (val >> CLK_TBG_SEL_SHIFT) & CLK_TBG_SEL_MASK; + prev_d1d2 = ((val >> CLK_TBG_DIV1_SHIFT) & CLK_TBG_DIV1_MASK) + * ((val >> CLK_TBG_DIV2_SHIFT) & CLK_TBG_DIV2_MASK); + } else { + prev_clock_idx = PARENT_CLOCK_XTAL; + prev_d1d2 = 1; + } + + /* Note that uart_clock_base->parent_rates[i] may not be available */ + prev_clock_rate = uart_clock_base->parent_rates[prev_clock_idx]; + + /* Recalculate UART1 divisor so UART1 baudrate does not change */ + if (prev_clock_rate) { + divisor = DIV_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) * + parent_clock_rate * prev_d1d2, + (u64)prev_clock_rate * d1 * d2); + if (divisor < 1) + divisor = 1; + else if (divisor > BRDV_BAUD_MAX) + divisor = BRDV_BAUD_MAX; + val = (val & ~BRDV_BAUD_MASK) | divisor; + } + + if (parent_clock_idx != PARENT_CLOCK_XTAL) { + /* Do not use XTAL, select TBG clock and TBG d1 * d2 divisors */ + val |= CLK_NO_XTAL; + val &= ~(CLK_TBG_DIV1_MASK << CLK_TBG_DIV1_SHIFT); + val |= d1 << CLK_TBG_DIV1_SHIFT; + val &= ~(CLK_TBG_DIV2_MASK << CLK_TBG_DIV2_SHIFT); + val |= d2 << CLK_TBG_DIV2_SHIFT; + val &= ~(CLK_TBG_SEL_MASK << CLK_TBG_SEL_SHIFT); + val |= parent_clock_idx << CLK_TBG_SEL_SHIFT; + } else { + /* Use XTAL, TBG bits are then ignored */ + val &= ~CLK_NO_XTAL; + } + + writel(val, uart_clock_base->reg1); + + /* Recalculate UART2 divisor so UART2 baudrate does not change */ + if (prev_clock_rate) { + val = readl(uart_clock_base->reg2); + divisor = DIV_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) * + parent_clock_rate * prev_d1d2, + (u64)prev_clock_rate * d1 * d2); + if (divisor < 1) + divisor = 1; + else if (divisor > BRDV_BAUD_MAX) + divisor = BRDV_BAUD_MAX; + val = (val & ~BRDV_BAUD_MASK) | divisor; + writel(val, uart_clock_base->reg2); + } + + uart_clock_base->configured = true; + + spin_unlock_irqrestore(&mvebu_uart_lock, flags); + + return 0; +} + +static int mvebu_uart_clock_enable(struct clk_hw *hw) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + unsigned long flags; + u32 val; + + spin_lock_irqsave(&mvebu_uart_lock, flags); + + val = readl(uart_clock_base->reg1); + + if (uart_clock->clock_idx == 0) + val &= ~UART1_CLK_DIS; + else + val &= ~UART2_CLK_DIS; + + writel(val, uart_clock_base->reg1); + + spin_unlock_irqrestore(&mvebu_uart_lock, flags); + + return 0; +} + +static void mvebu_uart_clock_disable(struct clk_hw *hw) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + unsigned long flags; + u32 val; + + spin_lock_irqsave(&mvebu_uart_lock, flags); + + val = readl(uart_clock_base->reg1); + + if (uart_clock->clock_idx == 0) + val |= UART1_CLK_DIS; + else + val |= UART2_CLK_DIS; + + writel(val, uart_clock_base->reg1); + + spin_unlock_irqrestore(&mvebu_uart_lock, flags); +} + +static int mvebu_uart_clock_is_enabled(struct clk_hw *hw) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + u32 val; + + val = readl(uart_clock_base->reg1); + + if (uart_clock->clock_idx == 0) + return !(val & UART1_CLK_DIS); + else + return !(val & UART2_CLK_DIS); +} + +static int mvebu_uart_clock_save_context(struct clk_hw *hw) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + unsigned long flags; + + spin_lock_irqsave(&mvebu_uart_lock, flags); + uart_clock->pm_context_reg1 = readl(uart_clock_base->reg1); + uart_clock->pm_context_reg2 = readl(uart_clock_base->reg2); + spin_unlock_irqrestore(&mvebu_uart_lock, flags); + + return 0; +} + +static void mvebu_uart_clock_restore_context(struct clk_hw *hw) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + unsigned long flags; + + spin_lock_irqsave(&mvebu_uart_lock, flags); + writel(uart_clock->pm_context_reg1, uart_clock_base->reg1); + writel(uart_clock->pm_context_reg2, uart_clock_base->reg2); + spin_unlock_irqrestore(&mvebu_uart_lock, flags); +} + +static unsigned long mvebu_uart_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + + return parent_rate / uart_clock_base->div; +} + +static long mvebu_uart_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct mvebu_uart_clock *uart_clock = to_uart_clock(hw); + struct mvebu_uart_clock_base *uart_clock_base = + to_uart_clock_base(uart_clock); + + return *parent_rate / uart_clock_base->div; +} + +static int mvebu_uart_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + /* + * We must report success but we can do so unconditionally because + * mvebu_uart_clock_round_rate returns values that ensure this call is a + * nop. + */ + + return 0; +} + +static const struct clk_ops mvebu_uart_clock_ops = { + .prepare = mvebu_uart_clock_prepare, + .enable = mvebu_uart_clock_enable, + .disable = mvebu_uart_clock_disable, + .is_enabled = mvebu_uart_clock_is_enabled, + .save_context = mvebu_uart_clock_save_context, + .restore_context = mvebu_uart_clock_restore_context, + .round_rate = mvebu_uart_clock_round_rate, + .set_rate = mvebu_uart_clock_set_rate, + .recalc_rate = mvebu_uart_clock_recalc_rate, +}; + +static int mvebu_uart_clock_register(struct device *dev, + struct mvebu_uart_clock *uart_clock, + const char *name, + const char *parent_name) +{ + struct clk_init_data init = { }; + + uart_clock->clk_hw.init = &init; + + init.name = name; + init.ops = &mvebu_uart_clock_ops; + init.flags = 0; + init.num_parents = 1; + init.parent_names = &parent_name; + + return devm_clk_hw_register(dev, &uart_clock->clk_hw); +} + +static int mvebu_uart_clock_probe(struct platform_device *pdev) +{ + static const char *const uart_clk_names[] = { "uart_1", "uart_2" }; + static const char *const parent_clk_names[] = { "TBG-A-P", "TBG-B-P", + "TBG-A-S", "TBG-B-S", + "xtal" }; + struct clk *parent_clks[ARRAY_SIZE(parent_clk_names)]; + struct mvebu_uart_clock_base *uart_clock_base; + struct clk_hw_onecell_data *hw_clk_data; + struct device *dev = &pdev->dev; + struct resource *res; + int i, parent_clk_idx, ret; + unsigned long div, rate; + unsigned int d1, d2; + + BUILD_BUG_ON(ARRAY_SIZE(uart_clk_names) != + ARRAY_SIZE(uart_clock_base->clocks)); + BUILD_BUG_ON(ARRAY_SIZE(parent_clk_names) != + ARRAY_SIZE(uart_clock_base->parent_rates)); + + uart_clock_base = devm_kzalloc(dev, + sizeof(*uart_clock_base), + GFP_KERNEL); + if (!uart_clock_base) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "Couldn't get first register\n"); + return -ENOENT; + } + + /* + * UART Clock Control register (reg1 / UART_BRDV) is in address range + * of UART1 (standard UART variant), controls clock source and dividers + * for both UART1 and UART2 and is supplied via DT as first resource. + * Therefore use ioremap() function rather than ioremap_resource() to + * avoid conflicts with UART1 driver. Access to UART_BRDV is protected + * by lock shared between clock and UART driver. + */ + uart_clock_base->reg1 = devm_ioremap(dev, res->start, + resource_size(res)); + if (IS_ERR(uart_clock_base->reg1)) + return PTR_ERR(uart_clock_base->reg1); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "Couldn't get second register\n"); + return -ENOENT; + } + + /* + * UART 2 Baud Rate Divisor register (reg2 / UART_BRDV) is in address + * range of UART2 (extended UART variant), controls only one UART2 + * specific divider and is supplied via DT as second resource. + * Therefore use ioremap() function rather than ioremap_resource() to + * avoid conflicts with UART2 driver. Access to UART_BRDV is protected + * by lock shared between clock and UART driver. + */ + uart_clock_base->reg2 = devm_ioremap(dev, res->start, + resource_size(res)); + if (IS_ERR(uart_clock_base->reg2)) + return PTR_ERR(uart_clock_base->reg2); + + hw_clk_data = devm_kzalloc(dev, + struct_size(hw_clk_data, hws, + ARRAY_SIZE(uart_clk_names)), + GFP_KERNEL); + if (!hw_clk_data) + return -ENOMEM; + + hw_clk_data->num = ARRAY_SIZE(uart_clk_names); + for (i = 0; i < ARRAY_SIZE(uart_clk_names); i++) { + hw_clk_data->hws[i] = &uart_clock_base->clocks[i].clk_hw; + uart_clock_base->clocks[i].clock_idx = i; + } + + parent_clk_idx = -1; + + for (i = 0; i < ARRAY_SIZE(parent_clk_names); i++) { + parent_clks[i] = devm_clk_get(dev, parent_clk_names[i]); + if (IS_ERR(parent_clks[i])) { + if (PTR_ERR(parent_clks[i]) == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_warn(dev, "Couldn't get the parent clock %s: %ld\n", + parent_clk_names[i], PTR_ERR(parent_clks[i])); + continue; + } + + ret = clk_prepare_enable(parent_clks[i]); + if (ret) { + dev_warn(dev, "Couldn't enable parent clock %s: %d\n", + parent_clk_names[i], ret); + continue; + } + rate = clk_get_rate(parent_clks[i]); + uart_clock_base->parent_rates[i] = rate; + + if (i != PARENT_CLOCK_XTAL) { + /* + * Calculate the smallest TBG d1 and d2 divisors that + * still can provide 9600 baudrate. + */ + d1 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR * + BRDV_BAUD_MAX); + if (d1 < 1) + d1 = 1; + else if (d1 > CLK_TBG_DIV1_MAX) + d1 = CLK_TBG_DIV1_MAX; + + d2 = DIV_ROUND_UP(rate, 9600 * OSAMP_DEFAULT_DIVISOR * + BRDV_BAUD_MAX * d1); + if (d2 < 1) + d2 = 1; + else if (d2 > CLK_TBG_DIV2_MAX) + d2 = CLK_TBG_DIV2_MAX; + } else { + /* + * When UART clock uses XTAL clock as a source then it + * is not possible to use d1 and d2 divisors. + */ + d1 = d2 = 1; + } + + /* Skip clock source which cannot provide 9600 baudrate */ + if (rate > 9600 * OSAMP_DEFAULT_DIVISOR * BRDV_BAUD_MAX * d1 * d2) + continue; + + /* + * Choose TBG clock source with the smallest divisors. Use XTAL + * clock source only in case TBG is not available as XTAL cannot + * be used for baudrates higher than 230400. + */ + if (parent_clk_idx == -1 || + (i != PARENT_CLOCK_XTAL && div > d1 * d2)) { + parent_clk_idx = i; + div = d1 * d2; + } + } + + for (i = 0; i < ARRAY_SIZE(parent_clk_names); i++) { + if (i == parent_clk_idx || IS_ERR(parent_clks[i])) + continue; + clk_disable_unprepare(parent_clks[i]); + devm_clk_put(dev, parent_clks[i]); + } + + if (parent_clk_idx == -1) { + dev_err(dev, "No usable parent clock\n"); + return -ENOENT; + } + + uart_clock_base->parent_idx = parent_clk_idx; + uart_clock_base->div = div; + + dev_notice(dev, "Using parent clock %s as base UART clock\n", + __clk_get_name(parent_clks[parent_clk_idx])); + + for (i = 0; i < ARRAY_SIZE(uart_clk_names); i++) { + ret = mvebu_uart_clock_register(dev, + &uart_clock_base->clocks[i], + uart_clk_names[i], + __clk_get_name(parent_clks[parent_clk_idx])); + if (ret) { + dev_err(dev, "Can't register UART clock %d: %d\n", + i, ret); + return ret; + } + } + + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + hw_clk_data); +} + +static const struct of_device_id mvebu_uart_clock_of_match[] = { + { .compatible = "marvell,armada-3700-uart-clock", }, + { } +}; + +static struct platform_driver mvebu_uart_clock_platform_driver = { + .probe = mvebu_uart_clock_probe, + .driver = { + .name = "mvebu-uart-clock", + .of_match_table = mvebu_uart_clock_of_match, + }, +}; + static int __init mvebu_uart_init(void) { int ret; @@ -983,10 +1487,19 @@ static int __init mvebu_uart_init(void) if (ret) return ret; + ret = platform_driver_register(&mvebu_uart_clock_platform_driver); + if (ret) { + uart_unregister_driver(&mvebu_uart_driver); + return ret; + } + ret = platform_driver_register(&mvebu_uart_platform_driver); - if (ret) + if (ret) { + platform_driver_unregister(&mvebu_uart_clock_platform_driver); uart_unregister_driver(&mvebu_uart_driver); + return ret; + } - return ret; + return 0; } arch_initcall(mvebu_uart_init); -- 2.20.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36D54C49EA5 for ; Thu, 24 Jun 2021 22:53:56 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EC8B560FEA for ; Thu, 24 Jun 2021 22:53:55 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EC8B560FEA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=0a5XX4TcPCtopQUYT2Au7y7EmekGB7TZmZBpNH0iwyQ=; b=AoDQ/ClIMRvb8E YiTQ/jtObIyG3ighNeAMwoSTZuyBfSDHVa0rbvudLH8S0yJfK2mPAsTAJhCTdEUfXoZ7S/W6+UDi1 7Ib723X7qoa7KoWgHWu9pwia5mgjSb5rtQKsKi1Ne2M6g1p3DIWakXtUlfB0xobFf54F5D4HnN9Qn jRib/6N3VNPeaNClaaQfbnuXlAD9zn78LK+Hu6UtN3tNg3HMAQq0T+cPeLsjqOOHF/CCNImSlIgoU bUHxpxpLBVCpRp6qlDRcN1YtTAyUikLktjZBuinl1xiIFuBmgX0uAXiI/eqY4UTPjuA60Rl5CSCfs 9E+lEBjzhWe6cvreXDLQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1lwYCj-00GdWJ-9w; Thu, 24 Jun 2021 22:52:13 +0000 Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1lwYAZ-00GclT-AZ for linux-arm-kernel@lists.infradead.org; Thu, 24 Jun 2021 22:50:02 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id BC0476138C; Thu, 24 Jun 2021 22:49:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1624574999; bh=9edfwL/4cz9Vzqi/IVyM0oZ83o5hhf3oSSiTXQszjiE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lRYQCeKmS45/ofKsNADBDcj1wZuDn45S9PxEhb4onA4/YosxTEOmhaaawgD3iRwOo itrhWXM3E342+gmfGEclhxTnw4fwbplfyB89En6ynMgefocUObRrhBpwPfEmG3XhhJ iS36k7FbfGLd6dK5lmM+l9gbjAPln75wex3l9PPK0vlp9WoK1vhNh39qqbpfALvIaT Gvcw2a+yFHMOuYVQhAIV8a6YUHfSr8/agAmM2RW9cL4Yurb4vOWSxGVMQUtoo2Ptbk aUY01VwB4YVPMsBL79jpVi6gTWV9tYWo2hNAfeTb7gb3orsjPwPCnu5Hwq2noV75Vi 0eElgtzdb6tbQ== Received: by pali.im (Postfix) id 7AAF48A3; Fri, 25 Jun 2021 00:49:58 +0200 (CEST) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman Cc: Andrew Lunn , Gregory Clement , Sebastian Hesselbarth , Vladimir Vid , =?UTF-8?q?Marek=20Beh=C3=BAn?= , linux-clk@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 07/10] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Fri, 25 Jun 2021 00:49:06 +0200 Message-Id: <20210624224909.6350-8-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210624224909.6350-1-pali@kernel.org> References: <20210624224909.6350-1-pali@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210624_154959_463306_7732CB5B X-CRM114-Status: GOOD ( 31.17 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org VGhpcyBwYXRjaCBpbXBsZW1lbnRzIGEgbmV3IGRldmljZSBkcml2ZXIgZm9yIGNvbnRyb2xsaW5n IFVBUlQgY2xvY2tzIG9uCk1hcnZlbGwgQXJtYWRhIDM3MDAgU29DLiBUaGlzIGRldmljZSBkcml2 ZXIgaXMgbG9hZGVkIGZvciBkZXZpY2VzIHdoaWNoCm1hdGNoIGNvbXBhdGlibGUgc3RyaW5nICJt YXJ2ZWxsLGFybWFkYS0zNzAwLXVhcnQtY2xvY2siLgoKVGhlcmUgYXJlIG1vcmUgcGl0ZmFsbHMg cmVsYXRlZCB0byBVQVJUIGNsb2Nrcy4gQm90aCBVQVJUcyB1c2Ugc2FtZSBiYXNlCmNsb2NrIHNv dXJjZS4gQWxzbyBkaXZpc29ycyBmb3IgVEJHIGJhc2UgY2xvY2sgYXJlIHNoYXJlZCBiZXR3ZWVu IGJvdGgKVUFSVHMgYW5kIGFyZSBjb25maWd1cmVkIG9ubHkgZnJvbSBVQVJUMSBhZGRyZXNzIHNw YWNlLiBDbG9ja3MgY2FuIGJlCmVuYWJsZWQgLyBkaXNhYmxlZCBzZXBhcmF0ZWx5IGZvciBVQVJU MSBhbmQgVUFSVDIsIGJ1dCB0aGV5IGFyZSBjb250cm9sbGVkCm9ubHkgZnJvbSBVQVJUMSBhZGRy ZXNzIHNwYWNlLiBNb3Jlb3ZlciBNYXJ2ZWxsIEFybWFkYSAzNzAwIEZ1bmN0aW9uYWwKU3BlY2lm aWNhdGlvbnMgaGFzIHN3YXBwZWQgYml0cyBmb3IgZW5hYmxpbmcvZGlzYWJsaW5nIFVBUlQxIGFu ZCBVQVJUMgpjbG9ja3MuCgpTbyBkcml2ZXIgZm9yIGNvbnRyb2xsaW5nIFVBUlQyIG5lZWRzIHRv IGhhdmUgYWNjZXNzIHRvIFVBUlQxIGFkZHJlc3Mgc3BhY2UKYXMgVUFSVDEgYWRkcmVzcyBzcGFj ZSBjb250YWlucyBzb21lIGJpdHMgZXhjbHVzaXZlbHkgdXNlZCBieSBVQVJUMiBhbmQKYWxzbyBi aXRzIHdoaWNoIGFyZSBzaGFyZWQgZm9yIGJvdGggVUFSVDEgYW5kIFVBUlQyLgoKRm9yIGNoYW5n aW5nIFVBUlQgYmFzZSBjbG9jayAod2hpY2ggY29udHJvbHMgYm90aCBVQVJUcykgZHVyaW5nIGJv b3Qgd2hlbgpVQVJUIGRyaXZlciBpcyBub3QgcmVhZHkgYW5kIG9ubHkgZWFybHkgY29uc29sZSBp cyBhY3RpdmUsIGlzIG5vdCBzaW1wbGUKb3BlcmF0aW9uIGFzIGl0IGlzIHJlcXVpcmVkIHRvIGFs c28gcmVjYWxjdWxhdGUgZGl2aXNvcnMgdG8gbm90IGNoYW5nZSBVQVJUCmJhdWRyYXRlIHVzZWQg YnkgZWFybHkgY29uc29sZS4gU28gZm9yIHRoaXMgb3BlcmF0aW9uIFVBUlQxIGNsb2NrIGRyaXZl cgpuZWVkcyB0byBhY2Nlc3MgYWxzbyBpbnRvIGFkZHJlc3Mgc3BhY2Ugb2YgVUFSVDIgd2hlcmUg YXJlIHJlZ2lzdGVycyBmb3IKVUFSVDIgZGl2aXNvcnMuCgpGb3IgdGhlc2UgcmVhc29ucywgdGhp cyBuZXcgZGV2aWNlIGRyaXZlciBmb3IgVUFSVCBjbG9ja3MgZG9lcyBub3QgdXNlCmlvcmVtYXBf cmVzb3VyY2UoKSwgYnV0IG9ubHkgaW9yZW1hcCgpIHRvIHByZXZlbnQgcmVzb3VyY2UgY29uZmxp Y3RzCmJldHdlZW4gVUFSVCBjbG9jayBkcml2ZXIgYW5kIFVBUlQgZHJpdmVyLgoKU2hhcmVkIGJl dHdlZW4gZHJpdmVycyBhcmUgb25seSB0d28gNC1ieXRlcyByZWdpc3RlcnM6IFVBUlQgQ2xvY2sg Q29udHJvbAphbmQgVUFSVCAyIEJhdWQgUmF0ZSBEaXZpc29yLiBBY2Nlc3MgdG8gdGhlc2UgdHdv IHJlZ2lzdGVycyBhcmUgcHJvdGVjdGVkCmJ5IG9uZSBzcGlubG9jayB0byBwcmV2ZW50IGFueSBj b25mbGljdHMuIEFjY2VzcyBpcyByZXF1aXJlZCBvbmx5IGR1cmluZwpwcm9iZSB0aW1lLCBjaGFu Z2luZyBiYXVkcmF0ZSBhbmQgZHVyaW5nIHN1c3BlbmQvcmVzdW1lLgoKSGFyZHdhcmUgY2FuIGJl IGNvbmZpZ3VyZWQgdG8gdXNlIG9uZSBvZiBmb2xsb3dpbmcgY2xvY2tzIGFzIFVBUlQgYmFzZQpj bG9jazogVEJHLUEtUCwgVEJHLUItUCwgVEJHLUEtUywgVEJHLUItUywgeHRhbC4gTm90IGV2ZXJ5 IGNsb2NrIGlzIHVzYWJsZQpmb3IgaGlnaGVyIGJ1YWRyYXRlcy4gSW4gRFQgbm9kZSBjYW4gYmUg c3BlY2lmaWVkIGFueSBzdWJzZXQgYW5kIGtlcm5lbApjaG9vc2UgdGhlIGJlc3Qgb25lLCB3aGlj aCBzdGlsbCBzdXBwb3J0cyByZXF1aXJlZCBiYXVkcmF0ZSA5NjAwLiBGb3IKc21vb3RoIGJvb3Qg bG9nIG91dHB1dCBpdCBpcyBuZWVkZWQgdG8gc3BlY2lmeSBjbG9jayB1c2VkIGJ5IGVhcmx5IGNv bnNvbGUKb3RoZXJ3aXNlIGdhcmJhZ2Ugd291bGQgYmUgcHV0IG9uIFVBUlQgZHVyaW5nIHByb2Jp bmcgZm9yIFVBUlQgY2xvY2sgZHJpdmVyCmFuZCB0cmFuc2l0aW9uaW5nIGZyb20gZWFybHkgY29u c29sZSB0byBub3JtYWwgY29uc29sZS4KClRoaXMgY2hhbmdlIGlzIHJlcXVpcmVkIHRvIGVuYWJs ZSBhbmQgY29uZmlndXJlIFRCRyBjbG9jayBhcyBhIGJhc2UgY2xvY2sKZm9yIFVBUlQuIFRCRyBj bG9jayBpcyByZXF1aXJlZCB0byBhY2hpZXZlIGhpZ2hlciBiYXVkcmF0ZXMgdGhhbiAyMzA0MDAu CgpTaWduZWQtb2ZmLWJ5OiBQYWxpIFJvaMOhciA8cGFsaUBrZXJuZWwub3JnPgotLS0KIGRyaXZl cnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMgfCA1MTcgKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKy0KIDEgZmlsZSBjaGFuZ2VkLCA1MTUgaW5zZXJ0aW9ucygrKSwgMiBkZWxldGlvbnMo LSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL3R0eS9zZXJpYWwvbXZlYnUtdWFydC5jIGIvZHJpdmVy cy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYwppbmRleCA0MTRlOTIwNjRhYzYuLmU1MWE4NGJlMTkz OSAxMDA2NDQKLS0tIGEvZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYworKysgYi9kcml2 ZXJzL3R0eS9zZXJpYWwvbXZlYnUtdWFydC5jCkBAIC04LDYgKzgsNyBAQAogKi8KIAogI2luY2x1 ZGUgPGxpbnV4L2Nsay5oPgorI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92aWRlci5oPgogI2luY2x1 ZGUgPGxpbnV4L2NvbnNvbGUuaD4KICNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgogI2luY2x1ZGUg PGxpbnV4L2RldmljZS5oPgpAQCAtNjgsOCArNjksMzEgQEAKICNkZWZpbmUgIFNUQVRfQlJLX0VS UgkJKFNUQVRfQlJLX0RFVCB8IFNUQVRfRlJNX0VSUiBcCiAJCQkJIHwgU1RBVF9QQVJfRVJSIHwg U1RBVF9PVlJfRVJSKQogCisvKgorICogTWFydmVsbCBBcm1hZGEgMzcwMCBGdW5jdGlvbmFsIFNw ZWNpZmljYXRpb25zIGRlc2NyaWJlcyB0aGF0IGJpdCAyMSBvZiBVQVJUCisgKiBDbG9jayBDb250 cm9sIHJlZ2lzdGVyIGNvbnRyb2xzIFVBUlQxIGFuZCBiaXQgMjAgY29udHJvbHMgVUFSVDIuIEJ1 dCBpbgorICogcmVhbGl0eSBiaXQgMjEgY29udHJvbHMgVUFSVDIgYW5kIGJpdCAyMCBjb250cm9s cyBVQVJUMS4gVGhpcyBzZWVtcyB0byBiZSBhCisgKiBidWcgaW4gTWFydmVsbCBkb2N1bWVudGF0 aW9uLiBIZW5jZSBmb2xsb3dpbmcgQ0xLX0RJUyBtYWNyb3MgYXJlIHN3YXBwZWQuCisgKi8KKwog I2RlZmluZSBVQVJUX0JSRFYJCTB4MTAKKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0ZWQgaW4gVUFS VDEgYWRkcmVzcyBzcGFjZSBhbmQgY29udHJvbCBVQVJUMiAqLworI2RlZmluZSAgVUFSVDJfQ0xL X0RJUwkJQklUKDIxKQorLyogVGhlc2UgYml0cyBhcmUgbG9jYXRlZCBpbiBVQVJUMSBhZGRyZXNz IHNwYWNlIGFuZCBjb250cm9sIFVBUlQxICovCisjZGVmaW5lICBVQVJUMV9DTEtfRElTCQlCSVQo MjApCisvKiBUaGVzZSBiaXRzIGFyZSBsb2NhdGVkIGluIFVBUlQxIGFkZHJlc3Mgc3BhY2UgYW5k IGNvbnRyb2wgYm90aCBVQVJUcyAqLworI2RlZmluZSAgQ0xLX05PX1hUQUwJCUJJVCgxOSkKKyNk ZWZpbmUgIENMS19UQkdfRElWMV9TSElGVAkxNQorI2RlZmluZSAgQ0xLX1RCR19ESVYxX01BU0sJ MHg3CisjZGVmaW5lICBDTEtfVEJHX0RJVjFfTUFYCTYKKyNkZWZpbmUgIENMS19UQkdfRElWMl9T SElGVAkxMgorI2RlZmluZSAgQ0xLX1RCR19ESVYyX01BU0sJMHg3CisjZGVmaW5lICBDTEtfVEJH X0RJVjJfTUFYCTYKKyNkZWZpbmUgIENMS19UQkdfU0VMX1NISUZUCTEwCisjZGVmaW5lICBDTEtf VEJHX1NFTF9NQVNLCTB4MworLyogVGhlc2UgYml0cyBhcmUgbG9jYXRlZCBpbiBib3RoIFVBUlRz IGFkZHJlc3Mgc3BhY2UgKi8KICNkZWZpbmUgIEJSRFZfQkFVRF9NQVNLICAgICAgICAgMHgzRkYK KyNkZWZpbmUgIEJSRFZfQkFVRF9NQVgJCUJSRFZfQkFVRF9NQVNLCiAKICNkZWZpbmUgVUFSVF9P U0FNUAkJMHgxNAogI2RlZmluZSAgT1NBTVBfREVGQVVMVF9ESVZJU09SCTE2CkBAIC0xNTMsNiAr MTc3LDggQEAgc3RhdGljIHN0cnVjdCBtdmVidV91YXJ0ICp0b19tdnVhcnQoc3RydWN0IHVhcnRf cG9ydCAqcG9ydCkKIAogc3RhdGljIHN0cnVjdCB1YXJ0X3BvcnQgbXZlYnVfdWFydF9wb3J0c1tN VkVCVV9OUl9VQVJUU107CiAKK3N0YXRpYyBERUZJTkVfU1BJTkxPQ0sobXZlYnVfdWFydF9sb2Nr KTsKKwogLyogQ29yZSBVQVJUIERyaXZlciBPcGVyYXRpb25zICovCiBzdGF0aWMgdW5zaWduZWQg aW50IG12ZWJ1X3VhcnRfdHhfZW1wdHkoc3RydWN0IHVhcnRfcG9ydCAqcG9ydCkKIHsKQEAgLTQ0 NSw2ICs0NzEsNyBAQCBzdGF0aWMgdm9pZCBtdmVidV91YXJ0X3NodXRkb3duKHN0cnVjdCB1YXJ0 X3BvcnQgKnBvcnQpCiBzdGF0aWMgaW50IG12ZWJ1X3VhcnRfYmF1ZF9yYXRlX3NldChzdHJ1Y3Qg dWFydF9wb3J0ICpwb3J0LCB1bnNpZ25lZCBpbnQgYmF1ZCkKIHsKIAl1bnNpZ25lZCBpbnQgZF9k aXZpc29yLCBtX2Rpdmlzb3I7CisJdW5zaWduZWQgbG9uZyBmbGFnczsKIAl1MzIgYnJkdiwgb3Nh bXA7CiAKIAlpZiAoIXBvcnQtPnVhcnRjbGspCkBAIC00NjMsMTAgKzQ5MCwxMiBAQCBzdGF0aWMg aW50IG12ZWJ1X3VhcnRfYmF1ZF9yYXRlX3NldChzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0LCB1bnNp Z25lZCBpbnQgYmF1ZCkKIAltX2Rpdmlzb3IgPSBPU0FNUF9ERUZBVUxUX0RJVklTT1I7CiAJZF9k aXZpc29yID0gRElWX1JPVU5EX0NMT1NFU1QocG9ydC0+dWFydGNsaywgYmF1ZCAqIG1fZGl2aXNv cik7CiAKKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CiAJYnJk diA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOwogCWJyZHYgJj0gfkJSRFZfQkFV RF9NQVNLOwogCWJyZHYgfD0gZF9kaXZpc29yOwogCXdyaXRlbChicmR2LCBwb3J0LT5tZW1iYXNl ICsgVUFSVF9CUkRWKTsKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ss IGZsYWdzKTsKIAogCW9zYW1wID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfT1NBTVApOwog CW9zYW1wICY9IH5PU0FNUF9ESVZJU09SU19NQVNLOwpAQCAtNzYyLDYgKzc5MSw3IEBAIHN0YXRp YyBpbnQgbXZlYnVfdWFydF9zdXNwZW5kKHN0cnVjdCBkZXZpY2UgKmRldikKIHsKIAlzdHJ1Y3Qg bXZlYnVfdWFydCAqbXZ1YXJ0ID0gZGV2X2dldF9kcnZkYXRhKGRldik7CiAJc3RydWN0IHVhcnRf cG9ydCAqcG9ydCA9IG12dWFydC0+cG9ydDsKKwl1bnNpZ25lZCBsb25nIGZsYWdzOwogCiAJdWFy dF9zdXNwZW5kX3BvcnQoJm12ZWJ1X3VhcnRfZHJpdmVyLCBwb3J0KTsKIApAQCAtNzcwLDcgKzgw MCw5IEBAIHN0YXRpYyBpbnQgbXZlYnVfdWFydF9zdXNwZW5kKHN0cnVjdCBkZXZpY2UgKmRldikK IAltdnVhcnQtPnBtX3JlZ3MuY3RybCA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX0NUUkwo cG9ydCkpOwogCW12dWFydC0+cG1fcmVncy5pbnRyID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVB UlRfSU5UUihwb3J0KSk7CiAJbXZ1YXJ0LT5wbV9yZWdzLnN0YXQgPSByZWFkbChwb3J0LT5tZW1i YXNlICsgVUFSVF9TVEFUKTsKKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBm bGFncyk7CiAJbXZ1YXJ0LT5wbV9yZWdzLmJyZHYgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFS VF9CUkRWKTsKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdz KTsKIAltdnVhcnQtPnBtX3JlZ3Mub3NhbXAgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9P U0FNUCk7CiAKIAlkZXZpY2Vfc2V0X3dha2V1cF9lbmFibGUoZGV2LCB0cnVlKTsKQEAgLTc4Miwx MyArODE0LDE2IEBAIHN0YXRpYyBpbnQgbXZlYnVfdWFydF9yZXN1bWUoc3RydWN0IGRldmljZSAq ZGV2KQogewogCXN0cnVjdCBtdmVidV91YXJ0ICptdnVhcnQgPSBkZXZfZ2V0X2RydmRhdGEoZGV2 KTsKIAlzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0ID0gbXZ1YXJ0LT5wb3J0OworCXVuc2lnbmVkIGxv bmcgZmxhZ3M7CiAKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLnJiciwgcG9ydC0+bWVtYmFzZSAr IFVBUlRfUkJSKHBvcnQpKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLnRzaCwgcG9ydC0+bWVt YmFzZSArIFVBUlRfVFNIKHBvcnQpKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLmN0cmwsIHBv cnQtPm1lbWJhc2UgKyBVQVJUX0NUUkwocG9ydCkpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3Mu aW50ciwgcG9ydC0+bWVtYmFzZSArIFVBUlRfSU5UUihwb3J0KSk7CiAJd3JpdGVsKG12dWFydC0+ cG1fcmVncy5zdGF0LCBwb3J0LT5tZW1iYXNlICsgVUFSVF9TVEFUKTsKKwlzcGluX2xvY2tfaXJx c2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5i cmR2LCBwb3J0LT5tZW1iYXNlICsgVUFSVF9CUkRWKTsKKwlzcGluX3VubG9ja19pcnFyZXN0b3Jl KCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLm9zYW1w LCBwb3J0LT5tZW1iYXNlICsgVUFSVF9PU0FNUCk7CiAKIAl1YXJ0X3Jlc3VtZV9wb3J0KCZtdmVi dV91YXJ0X2RyaXZlciwgcG9ydCk7CkBAIC05NzUsNiArMTAxMCw0NzUgQEAgc3RhdGljIHN0cnVj dCBwbGF0Zm9ybV9kcml2ZXIgbXZlYnVfdWFydF9wbGF0Zm9ybV9kcml2ZXIgPSB7CiAJfSwKIH07 CiAKKy8qIFRoaXMgY29kZSBpcyBiYXNlZCBvbiBjbGstZml4ZWQtZmFjdG9yLmMgZHJpdmVyIGFu ZCBtb2RpZmllZC4gKi8KKworc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgeworCXN0cnVjdCBjbGtf aHcgY2xrX2h3OworCWludCBjbG9ja19pZHg7CisJdTMyIHBtX2NvbnRleHRfcmVnMTsKKwl1MzIg cG1fY29udGV4dF9yZWcyOworfTsKKworc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSB7CisJ c3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgY2xvY2tzWzJdOworCXVuc2lnbmVkIGludCBwYXJlbnRf cmF0ZXNbNV07CisJaW50IHBhcmVudF9pZHg7CisJdW5zaWduZWQgaW50IGRpdjsKKwl2b2lkIF9f aW9tZW0gKnJlZzE7CisJdm9pZCBfX2lvbWVtICpyZWcyOworCWJvb2wgY29uZmlndXJlZDsKK307 CisKKyNkZWZpbmUgUEFSRU5UX0NMT0NLX1hUQUwgNAorCisjZGVmaW5lIHRvX3VhcnRfY2xvY2so aHcpIGNvbnRhaW5lcl9vZihodywgc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2ssIGNsa19odykKKyNk ZWZpbmUgdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spIGNvbnRhaW5lcl9vZih1YXJ0X2Ns b2NrLCBcCisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSwgY2xvY2tzW3VhcnRfY2xvY2st PmNsb2NrX2lkeF0pCisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19wcmVwYXJlKHN0cnVj dCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0g dG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9j bG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKKwl1bnNp Z25lZCBpbnQgcHJldl9jbG9ja19pZHgsIHByZXZfY2xvY2tfcmF0ZSwgcHJldl9kMWQyOworCXVu c2lnbmVkIGludCBwYXJlbnRfY2xvY2tfaWR4LCBwYXJlbnRfY2xvY2tfcmF0ZTsKKwl1bnNpZ25l ZCBpbnQgZDEsIGQyLCBkaXZpc29yOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJdTMyIHZhbDsK KworCS8qCisJICogVGhpcyBmdW5jdGlvbiBqdXN0IHJlY29uZmlndXJlcyBVQVJUIENsb2NrIENv bnRyb2wgcmVnaXN0ZXIgKGxvY2F0ZWQKKwkgKiBpbiBVQVJUMSBhZGRyZXNzIHNwYWNlIHdoaWNo IGNvbnRyb2xzIGJvdGggVUFSVDEgYW5kIFVBUlQyKSB0bworCSAqIHNlbGVjdGVkIFVBUlQgYmFz ZSBjbG9jayBhbmQgcmVjYWxjdWxhdGUgY3VycmVudCBVQVJUMS9VQVJUMiBkaXZpc29ycworCSAq IGluIHRoZWlyIGFkZHJlc3Mgc3BhY2VzLCBzbyBmaW5hbCBiYXVkcmF0ZSB3aWxsIG5vdCBiZSBj aGFuZ2VkIGJ5CisJICogc3dpdGNoaW5nIFVBUlQgYmFzZSBjbG9jay4gVGhpcyBpcyByZXF1aXJl ZCBvdGhlcndpc2Uga2VybmVsIGJvb3QgbG9nCisJICogc3RvcHMgd29ya2luZy4gSXQgaXMgbmVl ZGVkIHRvIGVuc3VyZSB0aGF0IFVBUlQgYmF1ZHJhdGUgZG9lcyBub3QKKwkgKiBjaGFuZ2UgZHVy aW5nIHRoaXMgc2V0dXAuIEl0IGlzIG9uZSB0aW1lIG9wZXJhdGlvbiwgc28gYmFzZWQgb24KKwkg KiAiY29uZmlndXJlZCIgbWVtYmVyIHRoaXMgZnVuY3Rpb24gaXMgc2tpcHBlZCBvbiBzZWNvbmQg Y2FsbC4gQmVjYXVzZQorCSAqIHRoaXMgVUFSVCBDbG9jayBDb250cm9sIHJlZ2lzdGVyIChVQVJU X0JSRFYpIGlzIHNoYXJlZCBiZXR3ZWVuIFVBUlQxCisJICogYmF1ZHJhdGUgZnVuY3Rpb24sIFVB UlQxIGNsb2NrIHNlbGVjdG9yIGFuZCBVQVJUMiBjbG9jayBzZWxlY3RvciwKKwkgKiBldmVyeSBh Y2Nlc3MgdG8gVUFSVF9CUkRWIChyZWcxKSBuZWVkcyB0byBiZSBwcm90ZWN0ZWQgYnkgbG9jay4K KwkgKi8KKworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKwor CWlmICh1YXJ0X2Nsb2NrX2Jhc2UtPmNvbmZpZ3VyZWQpIHsKKwkJc3Bpbl91bmxvY2tfaXJxcmVz dG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisJCXJldHVybiAwOworCX0KKworCXBhcmVu dF9jbG9ja19pZHggPSB1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9pZHg7CisJcGFyZW50X2Nsb2Nr X3JhdGUgPSB1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1twYXJlbnRfY2xvY2tfaWR4XTsK KworCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9jbG9j a19iYXNlLT5kaXYgPiBDTEtfVEJHX0RJVjFfTUFYKSB7CisJCWQxID0gQ0xLX1RCR19ESVYxX01B WDsKKwkJZDIgPSB1YXJ0X2Nsb2NrX2Jhc2UtPmRpdiAvIENMS19UQkdfRElWMV9NQVg7CisJfSBl bHNlIHsKKwkJZDEgPSB1YXJ0X2Nsb2NrX2Jhc2UtPmRpdjsKKwkJZDIgPSAxOworCX0KKworCWlm ICh2YWwgJiBDTEtfTk9fWFRBTCkgeworCQlwcmV2X2Nsb2NrX2lkeCA9ICh2YWwgPj4gQ0xLX1RC R19TRUxfU0hJRlQpICYgQ0xLX1RCR19TRUxfTUFTSzsKKwkJcHJldl9kMWQyID0gKCh2YWwgPj4g Q0xLX1RCR19ESVYxX1NISUZUKSAmIENMS19UQkdfRElWMV9NQVNLKQorCQkJICAqICgodmFsID4+ IENMS19UQkdfRElWMl9TSElGVCkgJiBDTEtfVEJHX0RJVjJfTUFTSyk7CisJfSBlbHNlIHsKKwkJ cHJldl9jbG9ja19pZHggPSBQQVJFTlRfQ0xPQ0tfWFRBTDsKKwkJcHJldl9kMWQyID0gMTsKKwl9 CisKKwkvKiBOb3RlIHRoYXQgdWFydF9jbG9ja19iYXNlLT5wYXJlbnRfcmF0ZXNbaV0gbWF5IG5v dCBiZSBhdmFpbGFibGUgKi8KKwlwcmV2X2Nsb2NrX3JhdGUgPSB1YXJ0X2Nsb2NrX2Jhc2UtPnBh cmVudF9yYXRlc1twcmV2X2Nsb2NrX2lkeF07CisKKwkvKiBSZWNhbGN1bGF0ZSBVQVJUMSBkaXZp c29yIHNvIFVBUlQxIGJhdWRyYXRlIGRvZXMgbm90IGNoYW5nZSAqLworCWlmIChwcmV2X2Nsb2Nr X3JhdGUpIHsKKwkJZGl2aXNvciA9IERJVl9ST1VORF9DTE9TRVNUKCh1NjQpKHZhbCAmIEJSRFZf QkFVRF9NQVNLKSAqCisJCQkJCSAgICBwYXJlbnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFkMiwKKwkJ CQkJICAgICh1NjQpcHJldl9jbG9ja19yYXRlICogZDEgKiBkMik7CisJCWlmIChkaXZpc29yIDwg MSkKKwkJCWRpdmlzb3IgPSAxOworCQllbHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVEX01BWCkK KwkJCWRpdmlzb3IgPSBCUkRWX0JBVURfTUFYOworCQl2YWwgPSAodmFsICYgfkJSRFZfQkFVRF9N QVNLKSB8IGRpdmlzb3I7CisJfQorCisJaWYgKHBhcmVudF9jbG9ja19pZHggIT0gUEFSRU5UX0NM T0NLX1hUQUwpIHsKKwkJLyogRG8gbm90IHVzZSBYVEFMLCBzZWxlY3QgVEJHIGNsb2NrIGFuZCBU QkcgZDEgKiBkMiBkaXZpc29ycyAqLworCQl2YWwgfD0gQ0xLX05PX1hUQUw7CisJCXZhbCAmPSB+ KENMS19UQkdfRElWMV9NQVNLIDw8IENMS19UQkdfRElWMV9TSElGVCk7CisJCXZhbCB8PSBkMSA8 PCBDTEtfVEJHX0RJVjFfU0hJRlQ7CisJCXZhbCAmPSB+KENMS19UQkdfRElWMl9NQVNLIDw8IENM S19UQkdfRElWMl9TSElGVCk7CisJCXZhbCB8PSBkMiA8PCBDTEtfVEJHX0RJVjJfU0hJRlQ7CisJ CXZhbCAmPSB+KENMS19UQkdfU0VMX01BU0sgPDwgQ0xLX1RCR19TRUxfU0hJRlQpOworCQl2YWwg fD0gcGFyZW50X2Nsb2NrX2lkeCA8PCBDTEtfVEJHX1NFTF9TSElGVDsKKwl9IGVsc2UgeworCQkv KiBVc2UgWFRBTCwgVEJHIGJpdHMgYXJlIHRoZW4gaWdub3JlZCAqLworCQl2YWwgJj0gfkNMS19O T19YVEFMOworCX0KKworCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwkv KiBSZWNhbGN1bGF0ZSBVQVJUMiBkaXZpc29yIHNvIFVBUlQyIGJhdWRyYXRlIGRvZXMgbm90IGNo YW5nZSAqLworCWlmIChwcmV2X2Nsb2NrX3JhdGUpIHsKKwkJdmFsID0gcmVhZGwodWFydF9jbG9j a19iYXNlLT5yZWcyKTsKKwkJZGl2aXNvciA9IERJVl9ST1VORF9DTE9TRVNUKCh1NjQpKHZhbCAm IEJSRFZfQkFVRF9NQVNLKSAqCisJCQkJCSAgICBwYXJlbnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFk MiwKKwkJCQkJICAgICh1NjQpcHJldl9jbG9ja19yYXRlICogZDEgKiBkMik7CisJCWlmIChkaXZp c29yIDwgMSkKKwkJCWRpdmlzb3IgPSAxOworCQllbHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVE X01BWCkKKwkJCWRpdmlzb3IgPSBCUkRWX0JBVURfTUFYOworCQl2YWwgPSAodmFsICYgfkJSRFZf QkFVRF9NQVNLKSB8IGRpdmlzb3I7CisJCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVn Mik7CisJfQorCisJdWFydF9jbG9ja19iYXNlLT5jb25maWd1cmVkID0gdHJ1ZTsKKworCXNwaW5f dW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworCisJcmV0dXJuIDA7 Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19lbmFibGUoc3RydWN0IGNsa19odyAq aHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Ns b2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2Ug PQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcg ZmxhZ3M7CisJdTMyIHZhbDsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ss IGZsYWdzKTsKKworCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAo dWFydF9jbG9jay0+Y2xvY2tfaWR4ID09IDApCisJCXZhbCAmPSB+VUFSVDFfQ0xLX0RJUzsKKwll bHNlCisJCXZhbCAmPSB+VUFSVDJfQ0xLX0RJUzsKKworCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tf YmFzZS0+cmVnMSk7CisKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ss IGZsYWdzKTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCBtdmVidV91YXJ0X2Nsb2Nr X2Rpc2FibGUoc3RydWN0IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sg KnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9j a19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRf Y2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJdTMyIHZhbDsKKworCXNwaW5fbG9ja19p cnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKworCXZhbCA9IHJlYWRsKHVhcnRfY2xv Y2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9jbG9jay0+Y2xvY2tfaWR4ID09IDApCisJCXZh bCB8PSBVQVJUMV9DTEtfRElTOworCWVsc2UKKwkJdmFsIHw9IFVBUlQyX0NMS19ESVM7CisKKwl3 cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJc3Bpbl91bmxvY2tfaXJxcmVz dG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFy dF9jbG9ja19pc19lbmFibGVkKHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBtdmVidV91 YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1 X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tf YmFzZSh1YXJ0X2Nsb2NrKTsKKwl1MzIgdmFsOworCisJdmFsID0gcmVhZGwodWFydF9jbG9ja19i YXNlLT5yZWcxKTsKKworCWlmICh1YXJ0X2Nsb2NrLT5jbG9ja19pZHggPT0gMCkKKwkJcmV0dXJu ICEodmFsICYgVUFSVDFfQ0xLX0RJUyk7CisJZWxzZQorCQlyZXR1cm4gISh2YWwgJiBVQVJUMl9D TEtfRElTKTsKK30KKworc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3NhdmVfY29udGV4dChz dHJ1Y3QgY2xrX2h3ICpodykKK3sKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9j ayA9IHRvX3VhcnRfY2xvY2soaHcpOworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVh cnRfY2xvY2tfYmFzZSA9CisJCQkJCQl0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7CisJ dW5zaWduZWQgbG9uZyBmbGFnczsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xv Y2ssIGZsYWdzKTsKKwl1YXJ0X2Nsb2NrLT5wbV9jb250ZXh0X3JlZzEgPSByZWFkbCh1YXJ0X2Ns b2NrX2Jhc2UtPnJlZzEpOworCXVhcnRfY2xvY2stPnBtX2NvbnRleHRfcmVnMiA9IHJlYWRsKHVh cnRfY2xvY2tfYmFzZS0+cmVnMik7CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFy dF9sb2NrLCBmbGFncyk7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgbXZlYnVfdWFy dF9jbG9ja19yZXN0b3JlX2NvbnRleHQoc3RydWN0IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12 ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3Qg bXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9j bG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisKKwlzcGluX2xv Y2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisJd3JpdGVsKHVhcnRfY2xvY2st PnBtX2NvbnRleHRfcmVnMSwgdWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKwl3cml0ZWwodWFydF9j bG9jay0+cG1fY29udGV4dF9yZWcyLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOworCXNwaW5fdW5s b2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworfQorCitzdGF0aWMgdW5z aWduZWQgbG9uZyBtdmVidV91YXJ0X2Nsb2NrX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3 LAorCQkJCQkJICB1bnNpZ25lZCBsb25nIHBhcmVudF9yYXRlKQoreworCXN0cnVjdCBtdmVidV91 YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1 X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tf YmFzZSh1YXJ0X2Nsb2NrKTsKKworCXJldHVybiBwYXJlbnRfcmF0ZSAvIHVhcnRfY2xvY2tfYmFz ZS0+ZGl2OworfQorCitzdGF0aWMgbG9uZyBtdmVidV91YXJ0X2Nsb2NrX3JvdW5kX3JhdGUoc3Ry dWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwKKwkJCQkJdW5zaWduZWQgbG9uZyAq cGFyZW50X3JhdGUpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0 b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Ns b2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCisJcmV0 dXJuICpwYXJlbnRfcmF0ZSAvIHVhcnRfY2xvY2tfYmFzZS0+ZGl2OworfQorCitzdGF0aWMgaW50 IG12ZWJ1X3VhcnRfY2xvY2tfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxv bmcgcmF0ZSwKKwkJCQkgICAgIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpCit7CisJLyoKKwkg KiBXZSBtdXN0IHJlcG9ydCBzdWNjZXNzIGJ1dCB3ZSBjYW4gZG8gc28gdW5jb25kaXRpb25hbGx5 IGJlY2F1c2UKKwkgKiBtdmVidV91YXJ0X2Nsb2NrX3JvdW5kX3JhdGUgcmV0dXJucyB2YWx1ZXMg dGhhdCBlbnN1cmUgdGhpcyBjYWxsIGlzIGEKKwkgKiBub3AuCisJICovCisKKwlyZXR1cm4gMDsK K30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBjbGtfb3BzIG12ZWJ1X3VhcnRfY2xvY2tfb3BzID0g eworCS5wcmVwYXJlID0gbXZlYnVfdWFydF9jbG9ja19wcmVwYXJlLAorCS5lbmFibGUgPSBtdmVi dV91YXJ0X2Nsb2NrX2VuYWJsZSwKKwkuZGlzYWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tfZGlzYWJs ZSwKKwkuaXNfZW5hYmxlZCA9IG12ZWJ1X3VhcnRfY2xvY2tfaXNfZW5hYmxlZCwKKwkuc2F2ZV9j b250ZXh0ID0gbXZlYnVfdWFydF9jbG9ja19zYXZlX2NvbnRleHQsCisJLnJlc3RvcmVfY29udGV4 dCA9IG12ZWJ1X3VhcnRfY2xvY2tfcmVzdG9yZV9jb250ZXh0LAorCS5yb3VuZF9yYXRlID0gbXZl YnVfdWFydF9jbG9ja19yb3VuZF9yYXRlLAorCS5zZXRfcmF0ZSA9IG12ZWJ1X3VhcnRfY2xvY2tf c2V0X3JhdGUsCisJLnJlY2FsY19yYXRlID0gbXZlYnVfdWFydF9jbG9ja19yZWNhbGNfcmF0ZSwK K307CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19yZWdpc3RlcihzdHJ1Y3QgZGV2aWNl ICpkZXYsCisJCQkJICAgICBzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jaywKKwkJ CQkgICAgIGNvbnN0IGNoYXIgKm5hbWUsCisJCQkJICAgICBjb25zdCBjaGFyICpwYXJlbnRfbmFt ZSkKK3sKKwlzdHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9OworCisJdWFydF9jbG9jay0+ Y2xrX2h3LmluaXQgPSAmaW5pdDsKKworCWluaXQubmFtZSA9IG5hbWU7CisJaW5pdC5vcHMgPSAm bXZlYnVfdWFydF9jbG9ja19vcHM7CisJaW5pdC5mbGFncyA9IDA7CisJaW5pdC5udW1fcGFyZW50 cyA9IDE7CisJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50X25hbWU7CisKKwlyZXR1cm4gZGV2 bV9jbGtfaHdfcmVnaXN0ZXIoZGV2LCAmdWFydF9jbG9jay0+Y2xrX2h3KTsKK30KKworc3RhdGlj IGludCBtdmVidV91YXJ0X2Nsb2NrX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYp Cit7CisJc3RhdGljIGNvbnN0IGNoYXIgKmNvbnN0IHVhcnRfY2xrX25hbWVzW10gPSB7ICJ1YXJ0 XzEiLCAidWFydF8yIiB9OworCXN0YXRpYyBjb25zdCBjaGFyICpjb25zdCBwYXJlbnRfY2xrX25h bWVzW10gPSB7ICJUQkctQS1QIiwgIlRCRy1CLVAiLAorCQkJCQkJCSJUQkctQS1TIiwgIlRCRy1C LVMiLAorCQkJCQkJCSJ4dGFsIiB9OworCXN0cnVjdCBjbGsgKnBhcmVudF9jbGtzW0FSUkFZX1NJ WkUocGFyZW50X2Nsa19uYW1lcyldOworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVh cnRfY2xvY2tfYmFzZTsKKwlzdHJ1Y3QgY2xrX2h3X29uZWNlbGxfZGF0YSAqaHdfY2xrX2RhdGE7 CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwlzdHJ1Y3QgcmVzb3VyY2UgKnJl czsKKwlpbnQgaSwgcGFyZW50X2Nsa19pZHgsIHJldDsKKwl1bnNpZ25lZCBsb25nIGRpdiwgcmF0 ZTsKKwl1bnNpZ25lZCBpbnQgZDEsIGQyOworCisJQlVJTERfQlVHX09OKEFSUkFZX1NJWkUodWFy dF9jbGtfbmFtZXMpICE9CisJCSAgICAgQVJSQVlfU0laRSh1YXJ0X2Nsb2NrX2Jhc2UtPmNsb2Nr cykpOworCUJVSUxEX0JVR19PTihBUlJBWV9TSVpFKHBhcmVudF9jbGtfbmFtZXMpICE9CisJCSAg ICAgQVJSQVlfU0laRSh1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlcykpOworCisJdWFydF9j bG9ja19iYXNlID0gZGV2bV9remFsbG9jKGRldiwKKwkJCQkgICAgICAgc2l6ZW9mKCp1YXJ0X2Ns b2NrX2Jhc2UpLAorCQkJCSAgICAgICBHRlBfS0VSTkVMKTsKKwlpZiAoIXVhcnRfY2xvY2tfYmFz ZSkKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRl diwgSU9SRVNPVVJDRV9NRU0sIDApOworCWlmICghcmVzKSB7CisJCWRldl9lcnIoZGV2LCAiQ291 bGRuJ3QgZ2V0IGZpcnN0IHJlZ2lzdGVyXG4iKTsKKwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCisJ LyoKKwkgKiBVQVJUIENsb2NrIENvbnRyb2wgcmVnaXN0ZXIgKHJlZzEgLyBVQVJUX0JSRFYpIGlz IGluIGFkZHJlc3MgcmFuZ2UKKwkgKiBvZiBVQVJUMSAoc3RhbmRhcmQgVUFSVCB2YXJpYW50KSwg Y29udHJvbHMgY2xvY2sgc291cmNlIGFuZCBkaXZpZGVycworCSAqIGZvciBib3RoIFVBUlQxIGFu ZCBVQVJUMiBhbmQgaXMgc3VwcGxpZWQgdmlhIERUIGFzIGZpcnN0IHJlc291cmNlLgorCSAqIFRo ZXJlZm9yZSB1c2UgaW9yZW1hcCgpIGZ1bmN0aW9uIHJhdGhlciB0aGFuIGlvcmVtYXBfcmVzb3Vy Y2UoKSB0bworCSAqIGF2b2lkIGNvbmZsaWN0cyB3aXRoIFVBUlQxIGRyaXZlci4gQWNjZXNzIHRv IFVBUlRfQlJEViBpcyBwcm90ZWN0ZWQKKwkgKiBieSBsb2NrIHNoYXJlZCBiZXR3ZWVuIGNsb2Nr IGFuZCBVQVJUIGRyaXZlci4KKwkgKi8KKwl1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEgPSBkZXZtX2lv cmVtYXAoZGV2LCByZXMtPnN0YXJ0LAorCQkJCQkgICAgIHJlc291cmNlX3NpemUocmVzKSk7CisJ aWYgKElTX0VSUih1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpKQorCQlyZXR1cm4gUFRSX0VSUih1YXJ0 X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYs IElPUkVTT1VSQ0VfTUVNLCAxKTsKKwlpZiAoIXJlcykgeworCQlkZXZfZXJyKGRldiwgIkNvdWxk bid0IGdldCBzZWNvbmQgcmVnaXN0ZXJcbiIpOworCQlyZXR1cm4gLUVOT0VOVDsKKwl9CisKKwkv KgorCSAqIFVBUlQgMiBCYXVkIFJhdGUgRGl2aXNvciByZWdpc3RlciAocmVnMiAvIFVBUlRfQlJE VikgaXMgaW4gYWRkcmVzcworCSAqIHJhbmdlIG9mIFVBUlQyIChleHRlbmRlZCBVQVJUIHZhcmlh bnQpLCBjb250cm9scyBvbmx5IG9uZSBVQVJUMgorCSAqIHNwZWNpZmljIGRpdmlkZXIgYW5kIGlz IHN1cHBsaWVkIHZpYSBEVCBhcyBzZWNvbmQgcmVzb3VyY2UuCisJICogVGhlcmVmb3JlIHVzZSBp b3JlbWFwKCkgZnVuY3Rpb24gcmF0aGVyIHRoYW4gaW9yZW1hcF9yZXNvdXJjZSgpIHRvCisJICog YXZvaWQgY29uZmxpY3RzIHdpdGggVUFSVDIgZHJpdmVyLiBBY2Nlc3MgdG8gVUFSVF9CUkRWIGlz IHByb3RlY3RlZAorCSAqIGJ5IGxvY2sgc2hhcmVkIGJldHdlZW4gY2xvY2sgYW5kIFVBUlQgZHJp dmVyLgorCSAqLworCXVhcnRfY2xvY2tfYmFzZS0+cmVnMiA9IGRldm1faW9yZW1hcChkZXYsIHJl cy0+c3RhcnQsCisJCQkJCSAgICAgcmVzb3VyY2Vfc2l6ZShyZXMpKTsKKwlpZiAoSVNfRVJSKHVh cnRfY2xvY2tfYmFzZS0+cmVnMikpCisJCXJldHVybiBQVFJfRVJSKHVhcnRfY2xvY2tfYmFzZS0+ cmVnMik7CisKKwlod19jbGtfZGF0YSA9IGRldm1fa3phbGxvYyhkZXYsCisJCQkJICAgc3RydWN0 X3NpemUoaHdfY2xrX2RhdGEsIGh3cywKKwkJCQkJICAgICAgIEFSUkFZX1NJWkUodWFydF9jbGtf bmFtZXMpKSwKKwkJCQkgICBHRlBfS0VSTkVMKTsKKwlpZiAoIWh3X2Nsa19kYXRhKQorCQlyZXR1 cm4gLUVOT01FTTsKKworCWh3X2Nsa19kYXRhLT5udW0gPSBBUlJBWV9TSVpFKHVhcnRfY2xrX25h bWVzKTsKKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRSh1YXJ0X2Nsa19uYW1lcyk7IGkrKykg eworCQlod19jbGtfZGF0YS0+aHdzW2ldID0gJnVhcnRfY2xvY2tfYmFzZS0+Y2xvY2tzW2ldLmNs a19odzsKKwkJdWFydF9jbG9ja19iYXNlLT5jbG9ja3NbaV0uY2xvY2tfaWR4ID0gaTsKKwl9CisK KwlwYXJlbnRfY2xrX2lkeCA9IC0xOworCisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUocGFy ZW50X2Nsa19uYW1lcyk7IGkrKykgeworCQlwYXJlbnRfY2xrc1tpXSA9IGRldm1fY2xrX2dldChk ZXYsIHBhcmVudF9jbGtfbmFtZXNbaV0pOworCQlpZiAoSVNfRVJSKHBhcmVudF9jbGtzW2ldKSkg eworCQkJaWYgKFBUUl9FUlIocGFyZW50X2Nsa3NbaV0pID09IC1FUFJPQkVfREVGRVIpCisJCQkJ cmV0dXJuIC1FUFJPQkVfREVGRVI7CisJCQlkZXZfd2FybihkZXYsICJDb3VsZG4ndCBnZXQgdGhl IHBhcmVudCBjbG9jayAlczogJWxkXG4iLAorCQkJCXBhcmVudF9jbGtfbmFtZXNbaV0sIFBUUl9F UlIocGFyZW50X2Nsa3NbaV0pKTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJcmV0ID0gY2xrX3By ZXBhcmVfZW5hYmxlKHBhcmVudF9jbGtzW2ldKTsKKwkJaWYgKHJldCkgeworCQkJZGV2X3dhcm4o ZGV2LCAiQ291bGRuJ3QgZW5hYmxlIHBhcmVudCBjbG9jayAlczogJWRcbiIsCisJCQkJcGFyZW50 X2Nsa19uYW1lc1tpXSwgcmV0KTsKKwkJCWNvbnRpbnVlOworCQl9CisJCXJhdGUgPSBjbGtfZ2V0 X3JhdGUocGFyZW50X2Nsa3NbaV0pOworCQl1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1tp XSA9IHJhdGU7CisKKwkJaWYgKGkgIT0gUEFSRU5UX0NMT0NLX1hUQUwpIHsKKwkJCS8qCisJCQkg KiBDYWxjdWxhdGUgdGhlIHNtYWxsZXN0IFRCRyBkMSBhbmQgZDIgZGl2aXNvcnMgdGhhdAorCQkJ ICogc3RpbGwgY2FuIHByb3ZpZGUgOTYwMCBiYXVkcmF0ZS4KKwkJCSAqLworCQkJZDEgPSBESVZf Uk9VTkRfVVAocmF0ZSwgOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAqCisJCQkJCQlCUkRW X0JBVURfTUFYKTsKKwkJCWlmIChkMSA8IDEpCisJCQkJZDEgPSAxOworCQkJZWxzZSBpZiAoZDEg PiBDTEtfVEJHX0RJVjFfTUFYKQorCQkJCWQxID0gQ0xLX1RCR19ESVYxX01BWDsKKworCQkJZDIg PSBESVZfUk9VTkRfVVAocmF0ZSwgOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAqCisJCQkJ CQlCUkRWX0JBVURfTUFYICogZDEpOworCQkJaWYgKGQyIDwgMSkKKwkJCQlkMiA9IDE7CisJCQll bHNlIGlmIChkMiA+IENMS19UQkdfRElWMl9NQVgpCisJCQkJZDIgPSBDTEtfVEJHX0RJVjJfTUFY OworCQl9IGVsc2UgeworCQkJLyoKKwkJCSAqIFdoZW4gVUFSVCBjbG9jayB1c2VzIFhUQUwgY2xv Y2sgYXMgYSBzb3VyY2UgdGhlbiBpdAorCQkJICogaXMgbm90IHBvc3NpYmxlIHRvIHVzZSBkMSBh bmQgZDIgZGl2aXNvcnMuCisJCQkgKi8KKwkJCWQxID0gZDIgPSAxOworCQl9CisKKwkJLyogU2tp cCBjbG9jayBzb3VyY2Ugd2hpY2ggY2Fubm90IHByb3ZpZGUgOTYwMCBiYXVkcmF0ZSAqLworCQlp ZiAocmF0ZSA+IDk2MDAgKiBPU0FNUF9ERUZBVUxUX0RJVklTT1IgKiBCUkRWX0JBVURfTUFYICog ZDEgKiBkMikKKwkJCWNvbnRpbnVlOworCisJCS8qCisJCSAqIENob29zZSBUQkcgY2xvY2sgc291 cmNlIHdpdGggdGhlIHNtYWxsZXN0IGRpdmlzb3JzLiBVc2UgWFRBTAorCQkgKiBjbG9jayBzb3Vy Y2Ugb25seSBpbiBjYXNlIFRCRyBpcyBub3QgYXZhaWxhYmxlIGFzIFhUQUwgY2Fubm90CisJCSAq IGJlIHVzZWQgZm9yIGJhdWRyYXRlcyBoaWdoZXIgdGhhbiAyMzA0MDAuCisJCSAqLworCQlpZiAo cGFyZW50X2Nsa19pZHggPT0gLTEgfHwKKwkJICAgIChpICE9IFBBUkVOVF9DTE9DS19YVEFMICYm IGRpdiA+IGQxICogZDIpKSB7CisJCQlwYXJlbnRfY2xrX2lkeCA9IGk7CisJCQlkaXYgPSBkMSAq IGQyOworCQl9CisJfQorCisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUocGFyZW50X2Nsa19u YW1lcyk7IGkrKykgeworCQlpZiAoaSA9PSBwYXJlbnRfY2xrX2lkeCB8fCBJU19FUlIocGFyZW50 X2Nsa3NbaV0pKQorCQkJY29udGludWU7CisJCWNsa19kaXNhYmxlX3VucHJlcGFyZShwYXJlbnRf Y2xrc1tpXSk7CisJCWRldm1fY2xrX3B1dChkZXYsIHBhcmVudF9jbGtzW2ldKTsKKwl9CisKKwlp ZiAocGFyZW50X2Nsa19pZHggPT0gLTEpIHsKKwkJZGV2X2VycihkZXYsICJObyB1c2FibGUgcGFy ZW50IGNsb2NrXG4iKTsKKwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCisJdWFydF9jbG9ja19iYXNl LT5wYXJlbnRfaWR4ID0gcGFyZW50X2Nsa19pZHg7CisJdWFydF9jbG9ja19iYXNlLT5kaXYgPSBk aXY7CisKKwlkZXZfbm90aWNlKGRldiwgIlVzaW5nIHBhcmVudCBjbG9jayAlcyBhcyBiYXNlIFVB UlQgY2xvY2tcbiIsCisJCSAgIF9fY2xrX2dldF9uYW1lKHBhcmVudF9jbGtzW3BhcmVudF9jbGtf aWR4XSkpOworCisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpOyBp KyspIHsKKwkJcmV0ID0gbXZlYnVfdWFydF9jbG9ja19yZWdpc3RlcihkZXYsCisJCQkJJnVhcnRf Y2xvY2tfYmFzZS0+Y2xvY2tzW2ldLAorCQkJCXVhcnRfY2xrX25hbWVzW2ldLAorCQkJCV9fY2xr X2dldF9uYW1lKHBhcmVudF9jbGtzW3BhcmVudF9jbGtfaWR4XSkpOworCQlpZiAocmV0KSB7CisJ CQlkZXZfZXJyKGRldiwgIkNhbid0IHJlZ2lzdGVyIFVBUlQgY2xvY2sgJWQ6ICVkXG4iLAorCQkJ CWksIHJldCk7CisJCQlyZXR1cm4gcmV0OworCQl9CisJfQorCisJcmV0dXJuIGRldm1fb2ZfY2xr X2FkZF9od19wcm92aWRlcihkZXYsIG9mX2Nsa19od19vbmVjZWxsX2dldCwKKwkJCQkJICAgaHdf Y2xrX2RhdGEpOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBtdmVidV91 YXJ0X2Nsb2NrX29mX21hdGNoW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJtYXJ2ZWxsLGFybWFk YS0zNzAwLXVhcnQtY2xvY2siLCB9LAorCXsgfQorfTsKKworc3RhdGljIHN0cnVjdCBwbGF0Zm9y bV9kcml2ZXIgbXZlYnVfdWFydF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIgPSB7CisJLnByb2JlID0g bXZlYnVfdWFydF9jbG9ja19wcm9iZSwKKwkuZHJpdmVyCQk9IHsKKwkJLm5hbWUJPSAibXZlYnUt dWFydC1jbG9jayIsCisJCS5vZl9tYXRjaF90YWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tfb2ZfbWF0 Y2gsCisJfSwKK307CisKIHN0YXRpYyBpbnQgX19pbml0IG12ZWJ1X3VhcnRfaW5pdCh2b2lkKQog ewogCWludCByZXQ7CkBAIC05ODMsMTAgKzE0ODcsMTkgQEAgc3RhdGljIGludCBfX2luaXQgbXZl YnVfdWFydF9pbml0KHZvaWQpCiAJaWYgKHJldCkKIAkJcmV0dXJuIHJldDsKIAorCXJldCA9IHBs YXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmbXZlYnVfdWFydF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIp OworCWlmIChyZXQpIHsKKwkJdWFydF91bnJlZ2lzdGVyX2RyaXZlcigmbXZlYnVfdWFydF9kcml2 ZXIpOworCQlyZXR1cm4gcmV0OworCX0KKwogCXJldCA9IHBsYXRmb3JtX2RyaXZlcl9yZWdpc3Rl cigmbXZlYnVfdWFydF9wbGF0Zm9ybV9kcml2ZXIpOwotCWlmIChyZXQpCisJaWYgKHJldCkgewor CQlwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmbXZlYnVfdWFydF9jbG9ja19wbGF0Zm9ybV9k cml2ZXIpOwogCQl1YXJ0X3VucmVnaXN0ZXJfZHJpdmVyKCZtdmVidV91YXJ0X2RyaXZlcik7CisJ CXJldHVybiByZXQ7CisJfQogCi0JcmV0dXJuIHJldDsKKwlyZXR1cm4gMDsKIH0KIGFyY2hfaW5p dGNhbGwobXZlYnVfdWFydF9pbml0KTsKLS0gCjIuMjAuMQoKCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0 CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFk ZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK