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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id ED77EC433F5 for ; Thu, 30 Sep 2021 09:59:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CFD1D61884 for ; Thu, 30 Sep 2021 09:59:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349706AbhI3KA7 (ORCPT ); Thu, 30 Sep 2021 06:00:59 -0400 Received: from mail.kernel.org ([198.145.29.99]:60604 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349620AbhI3KAs (ORCPT ); Thu, 30 Sep 2021 06:00:48 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 92CBA619E0; Thu, 30 Sep 2021 09:59:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1632995945; bh=VXV6aJKzF810FQxyFz9CsC4/O2DiR4lkYrg572GERmg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QuhSNSVSb5RA+Z+e+hV1j26IvuWQMTM++0Z9TqLnddPoJ4KFETpGPDef9iCwHYhhE +7u2p00WXMDEExdwkzxkfQ7wbSbzapqMSYhx0KYgHtNauIRzAlOv1TKKEI7tXWc5Kz Uebr+vU0j++2sRSN/iPybzOy2RYkreMS9vCH4UAimnRJbIeE13QM7VobcpnYpVCm0R v4PG3ceNQBtNVpDKdtgC2YUa6TteqU0g6TUOo0Qz1RoWD65526Vzw6aWJfZbWlXUCr HiaRfcsaGQwkPaJugXVMydOD0MeHseUDpzmxtHvggZs4i9XasBEtId3OMLeJbhefC2 V3Ik+YnVVQOCA== Received: by pali.im (Postfix) id C9BC116B0; Thu, 30 Sep 2021 11:59:03 +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, devicetree@vger.kernel.org Subject: [PATCH v7 2/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Thu, 30 Sep 2021 11:58:34 +0200 Message-Id: <20210930095838.28145-3-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210930095838.28145-1-pali@kernel.org> References: <20210930095838.28145-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/Kconfig | 1 + drivers/tty/serial/mvebu-uart.c | 519 +++++++++++++++++++++++++++++++- 2 files changed, 518 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 131a6a587acd..fe1a54231b19 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1444,6 +1444,7 @@ config SERIAL_STM32_CONSOLE config SERIAL_MVEBU_UART bool "Marvell EBU serial port support" depends on ARCH_MVEBU || COMPILE_TEST + depends on COMMON_CLK select SERIAL_CORE help This driver is for Marvell EBU SoC's UART. If you have a machine diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c index 231de29a6452..f3fb1f3718f2 100644 --- a/drivers/tty/serial/mvebu-uart.c +++ b/drivers/tty/serial/mvebu-uart.c @@ -8,12 +8,14 @@ */ #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -68,8 +70,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 +178,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 +472,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 +491,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 +792,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 +801,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 +815,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); @@ -972,6 +1008,476 @@ 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 long flags; + unsigned int d1, d2; + u64 divisor; + 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_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) * + parent_clock_rate * prev_d1d2, + 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_U64_ROUND_CLOSEST((u64)(val & BRDV_BAUD_MASK) * + parent_clock_rate * prev_d1d2, + 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; + int i, parent_clk_idx, ret; + unsigned long div, rate; + struct resource *res; + 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; @@ -980,10 +1486,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 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7681BC433EF for ; Thu, 30 Sep 2021 10:03:53 +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 453D1615E2 for ; Thu, 30 Sep 2021 10:03:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 453D1615E2 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=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=Pq0m1LkgUBpmOQh6S6T1mpYs4TJZkFiZ9OujA98sDZo=; b=FR1U16OULJPbTA c/IRj8QhESBKhQa0QhCYg8yZvOXKDpZQ+eltK2htRLM4FaDgpHmDLRbrJQErYgMK19MgdNylN1E8K 64ssXBx455fxNaPBljLopeFXKfbtECNBcsgdSwRaFQCzny6qKYMsdD6FeJBmOJ2/Zhn0F+evHMHfB pJK0xgR4hnlQcM1pPN0VxUAQsy9fLYRSYmaly3TioAQPBLzIM9gYDiqDDPUcsqSfXh1lRaqPL+o4L v/ANmiQt81aSH/CFOH+UHHBanGuFk4aieHgUOxov64rBsqTXEInzwMlU9jSS58RYKqH7t8aL+eAdW jp6nr2WV0lZoRXdbzHcg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mVssJ-00DgtP-PO; Thu, 30 Sep 2021 10:01:12 +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 1mVsqI-00DgIs-6n for linux-arm-kernel@lists.infradead.org; Thu, 30 Sep 2021 09:59:14 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 92CBA619E0; Thu, 30 Sep 2021 09:59:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1632995945; bh=VXV6aJKzF810FQxyFz9CsC4/O2DiR4lkYrg572GERmg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QuhSNSVSb5RA+Z+e+hV1j26IvuWQMTM++0Z9TqLnddPoJ4KFETpGPDef9iCwHYhhE +7u2p00WXMDEExdwkzxkfQ7wbSbzapqMSYhx0KYgHtNauIRzAlOv1TKKEI7tXWc5Kz Uebr+vU0j++2sRSN/iPybzOy2RYkreMS9vCH4UAimnRJbIeE13QM7VobcpnYpVCm0R v4PG3ceNQBtNVpDKdtgC2YUa6TteqU0g6TUOo0Qz1RoWD65526Vzw6aWJfZbWlXUCr HiaRfcsaGQwkPaJugXVMydOD0MeHseUDpzmxtHvggZs4i9XasBEtId3OMLeJbhefC2 V3Ik+YnVVQOCA== Received: by pali.im (Postfix) id C9BC116B0; Thu, 30 Sep 2021 11:59:03 +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, devicetree@vger.kernel.org Subject: [PATCH v7 2/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Thu, 30 Sep 2021 11:58:34 +0200 Message-Id: <20210930095838.28145-3-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210930095838.28145-1-pali@kernel.org> References: <20210930095838.28145-1-pali@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210930_025906_360224_E49112F0 X-CRM114-Status: GOOD ( 33.25 ) 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 cnMvdHR5L3NlcmlhbC9LY29uZmlnICAgICAgfCAgIDEgKwogZHJpdmVycy90dHkvc2VyaWFsL212 ZWJ1LXVhcnQuYyB8IDUxOSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQogMiBmaWxl cyBjaGFuZ2VkLCA1MTggaW5zZXJ0aW9ucygrKSwgMiBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQg YS9kcml2ZXJzL3R0eS9zZXJpYWwvS2NvbmZpZyBiL2RyaXZlcnMvdHR5L3NlcmlhbC9LY29uZmln CmluZGV4IDEzMWE2YTU4N2FjZC4uZmUxYTU0MjMxYjE5IDEwMDY0NAotLS0gYS9kcml2ZXJzL3R0 eS9zZXJpYWwvS2NvbmZpZworKysgYi9kcml2ZXJzL3R0eS9zZXJpYWwvS2NvbmZpZwpAQCAtMTQ0 NCw2ICsxNDQ0LDcgQEAgY29uZmlnIFNFUklBTF9TVE0zMl9DT05TT0xFCiBjb25maWcgU0VSSUFM X01WRUJVX1VBUlQKIAlib29sICJNYXJ2ZWxsIEVCVSBzZXJpYWwgcG9ydCBzdXBwb3J0IgogCWRl cGVuZHMgb24gQVJDSF9NVkVCVSB8fCBDT01QSUxFX1RFU1QKKwlkZXBlbmRzIG9uIENPTU1PTl9D TEsKIAlzZWxlY3QgU0VSSUFMX0NPUkUKIAloZWxwCiAJICBUaGlzIGRyaXZlciBpcyBmb3IgTWFy dmVsbCBFQlUgU29DJ3MgVUFSVC4gSWYgeW91IGhhdmUgYSBtYWNoaW5lCmRpZmYgLS1naXQgYS9k cml2ZXJzL3R0eS9zZXJpYWwvbXZlYnUtdWFydC5jIGIvZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1 LXVhcnQuYwppbmRleCAyMzFkZTI5YTY0NTIuLmYzZmIxZjM3MThmMiAxMDA2NDQKLS0tIGEvZHJp dmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYworKysgYi9kcml2ZXJzL3R0eS9zZXJpYWwvbXZl YnUtdWFydC5jCkBAIC04LDEyICs4LDE0IEBACiAqLwogCiAjaW5jbHVkZSA8bGludXgvY2xrLmg+ CisjaW5jbHVkZSA8bGludXgvY2xrLXByb3ZpZGVyLmg+CiAjaW5jbHVkZSA8bGludXgvY29uc29s ZS5oPgogI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiAjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+ CiAjaW5jbHVkZSA8bGludXgvaW5pdC5oPgogI2luY2x1ZGUgPGxpbnV4L2lvLmg+CiAjaW5jbHVk ZSA8bGludXgvaW9wb2xsLmg+CisjaW5jbHVkZSA8bGludXgvbWF0aDY0Lmg+CiAjaW5jbHVkZSA8 bGludXgvb2YuaD4KICNpbmNsdWRlIDxsaW51eC9vZl9hZGRyZXNzLmg+CiAjaW5jbHVkZSA8bGlu dXgvb2ZfZGV2aWNlLmg+CkBAIC02OCw4ICs3MCwzMSBAQAogI2RlZmluZSAgU1RBVF9CUktfRVJS CQkoU1RBVF9CUktfREVUIHwgU1RBVF9GUk1fRVJSIFwKIAkJCQkgfCBTVEFUX1BBUl9FUlIgfCBT VEFUX09WUl9FUlIpCiAKKy8qCisgKiBNYXJ2ZWxsIEFybWFkYSAzNzAwIEZ1bmN0aW9uYWwgU3Bl Y2lmaWNhdGlvbnMgZGVzY3JpYmVzIHRoYXQgYml0IDIxIG9mIFVBUlQKKyAqIENsb2NrIENvbnRy b2wgcmVnaXN0ZXIgY29udHJvbHMgVUFSVDEgYW5kIGJpdCAyMCBjb250cm9scyBVQVJUMi4gQnV0 IGluCisgKiByZWFsaXR5IGJpdCAyMSBjb250cm9scyBVQVJUMiBhbmQgYml0IDIwIGNvbnRyb2xz IFVBUlQxLiBUaGlzIHNlZW1zIHRvIGJlIGEKKyAqIGJ1ZyBpbiBNYXJ2ZWxsIGRvY3VtZW50YXRp b24uIEhlbmNlIGZvbGxvd2luZyBDTEtfRElTIG1hY3JvcyBhcmUgc3dhcHBlZC4KKyAqLworCiAj ZGVmaW5lIFVBUlRfQlJEVgkJMHgxMAorLyogVGhlc2UgYml0cyBhcmUgbG9jYXRlZCBpbiBVQVJU MSBhZGRyZXNzIHNwYWNlIGFuZCBjb250cm9sIFVBUlQyICovCisjZGVmaW5lICBVQVJUMl9DTEtf RElTCQlCSVQoMjEpCisvKiBUaGVzZSBiaXRzIGFyZSBsb2NhdGVkIGluIFVBUlQxIGFkZHJlc3Mg c3BhY2UgYW5kIGNvbnRyb2wgVUFSVDEgKi8KKyNkZWZpbmUgIFVBUlQxX0NMS19ESVMJCUJJVCgy MCkKKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0ZWQgaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSBhbmQg Y29udHJvbCBib3RoIFVBUlRzICovCisjZGVmaW5lICBDTEtfTk9fWFRBTAkJQklUKDE5KQorI2Rl ZmluZSAgQ0xLX1RCR19ESVYxX1NISUZUCTE1CisjZGVmaW5lICBDTEtfVEJHX0RJVjFfTUFTSwkw eDcKKyNkZWZpbmUgIENMS19UQkdfRElWMV9NQVgJNgorI2RlZmluZSAgQ0xLX1RCR19ESVYyX1NI SUZUCTEyCisjZGVmaW5lICBDTEtfVEJHX0RJVjJfTUFTSwkweDcKKyNkZWZpbmUgIENMS19UQkdf RElWMl9NQVgJNgorI2RlZmluZSAgQ0xLX1RCR19TRUxfU0hJRlQJMTAKKyNkZWZpbmUgIENMS19U QkdfU0VMX01BU0sJMHgzCisvKiBUaGVzZSBiaXRzIGFyZSBsb2NhdGVkIGluIGJvdGggVUFSVHMg YWRkcmVzcyBzcGFjZSAqLwogI2RlZmluZSAgQlJEVl9CQVVEX01BU0sgICAgICAgICAweDNGRgor I2RlZmluZSAgQlJEVl9CQVVEX01BWAkJQlJEVl9CQVVEX01BU0sKIAogI2RlZmluZSBVQVJUX09T QU1QCQkweDE0CiAjZGVmaW5lICBPU0FNUF9ERUZBVUxUX0RJVklTT1IJMTYKQEAgLTE1Myw2ICsx NzgsOCBAQCBzdGF0aWMgc3RydWN0IG12ZWJ1X3VhcnQgKnRvX212dWFydChzdHJ1Y3QgdWFydF9w b3J0ICpwb3J0KQogCiBzdGF0aWMgc3RydWN0IHVhcnRfcG9ydCBtdmVidV91YXJ0X3BvcnRzW01W RUJVX05SX1VBUlRTXTsKIAorc3RhdGljIERFRklORV9TUElOTE9DSyhtdmVidV91YXJ0X2xvY2sp OworCiAvKiBDb3JlIFVBUlQgRHJpdmVyIE9wZXJhdGlvbnMgKi8KIHN0YXRpYyB1bnNpZ25lZCBp bnQgbXZlYnVfdWFydF90eF9lbXB0eShzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0KQogewpAQCAtNDQ1 LDYgKzQ3Miw3IEBAIHN0YXRpYyB2b2lkIG12ZWJ1X3VhcnRfc2h1dGRvd24oc3RydWN0IHVhcnRf cG9ydCAqcG9ydCkKIHN0YXRpYyBpbnQgbXZlYnVfdWFydF9iYXVkX3JhdGVfc2V0KHN0cnVjdCB1 YXJ0X3BvcnQgKnBvcnQsIHVuc2lnbmVkIGludCBiYXVkKQogewogCXVuc2lnbmVkIGludCBkX2Rp dmlzb3IsIG1fZGl2aXNvcjsKKwl1bnNpZ25lZCBsb25nIGZsYWdzOwogCXUzMiBicmR2LCBvc2Ft cDsKIAogCWlmICghcG9ydC0+dWFydGNsaykKQEAgLTQ2MywxMCArNDkxLDEyIEBAIHN0YXRpYyBp bnQgbXZlYnVfdWFydF9iYXVkX3JhdGVfc2V0KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQsIHVuc2ln bmVkIGludCBiYXVkKQogCW1fZGl2aXNvciA9IE9TQU1QX0RFRkFVTFRfRElWSVNPUjsKIAlkX2Rp dmlzb3IgPSBESVZfUk9VTkRfQ0xPU0VTVChwb3J0LT51YXJ0Y2xrLCBiYXVkICogbV9kaXZpc29y KTsKIAorCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKIAlicmR2 ID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfQlJEVik7CiAJYnJkdiAmPSB+QlJEVl9CQVVE X01BU0s7CiAJYnJkdiB8PSBkX2Rpdmlzb3I7CiAJd3JpdGVsKGJyZHYsIHBvcnQtPm1lbWJhc2Ug KyBVQVJUX0JSRFYpOworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywg ZmxhZ3MpOwogCiAJb3NhbXAgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9PU0FNUCk7CiAJ b3NhbXAgJj0gfk9TQU1QX0RJVklTT1JTX01BU0s7CkBAIC03NjIsNiArNzkyLDcgQEAgc3RhdGlj IGludCBtdmVidV91YXJ0X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQogewogCXN0cnVjdCBt dmVidV91YXJ0ICptdnVhcnQgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKIAlzdHJ1Y3QgdWFydF9w b3J0ICpwb3J0ID0gbXZ1YXJ0LT5wb3J0OworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CiAKIAl1YXJ0 X3N1c3BlbmRfcG9ydCgmbXZlYnVfdWFydF9kcml2ZXIsIHBvcnQpOwogCkBAIC03NzAsNyArODAx LDkgQEAgc3RhdGljIGludCBtdmVidV91YXJ0X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQog CW12dWFydC0+cG1fcmVncy5jdHJsID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfQ1RSTChw b3J0KSk7CiAJbXZ1YXJ0LT5wbV9yZWdzLmludHIgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFS VF9JTlRSKHBvcnQpKTsKIAltdnVhcnQtPnBtX3JlZ3Muc3RhdCA9IHJlYWRsKHBvcnQtPm1lbWJh c2UgKyBVQVJUX1NUQVQpOworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZs YWdzKTsKIAltdnVhcnQtPnBtX3JlZ3MuYnJkdiA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJU X0JSRFYpOworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3Mp OwogCW12dWFydC0+cG1fcmVncy5vc2FtcCA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX09T QU1QKTsKIAogCWRldmljZV9zZXRfd2FrZXVwX2VuYWJsZShkZXYsIHRydWUpOwpAQCAtNzgyLDEz ICs4MTUsMTYgQEAgc3RhdGljIGludCBtdmVidV91YXJ0X3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpk ZXYpCiB7CiAJc3RydWN0IG12ZWJ1X3VhcnQgKm12dWFydCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYp OwogCXN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQgPSBtdnVhcnQtPnBvcnQ7CisJdW5zaWduZWQgbG9u ZyBmbGFnczsKIAogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MucmJyLCBwb3J0LT5tZW1iYXNlICsg VUFSVF9SQlIocG9ydCkpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MudHNoLCBwb3J0LT5tZW1i YXNlICsgVUFSVF9UU0gocG9ydCkpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MuY3RybCwgcG9y dC0+bWVtYmFzZSArIFVBUlRfQ1RSTChwb3J0KSk7CiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5p bnRyLCBwb3J0LT5tZW1iYXNlICsgVUFSVF9JTlRSKHBvcnQpKTsKIAl3cml0ZWwobXZ1YXJ0LT5w bV9yZWdzLnN0YXQsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX1NUQVQpOworCXNwaW5fbG9ja19pcnFz YXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLmJy ZHYsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUo Jm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3Mub3NhbXAs IHBvcnQtPm1lbWJhc2UgKyBVQVJUX09TQU1QKTsKIAogCXVhcnRfcmVzdW1lX3BvcnQoJm12ZWJ1 X3VhcnRfZHJpdmVyLCBwb3J0KTsKQEAgLTk3Miw2ICsxMDA4LDQ3NiBAQCBzdGF0aWMgc3RydWN0 IHBsYXRmb3JtX2RyaXZlciBtdmVidV91YXJ0X3BsYXRmb3JtX2RyaXZlciA9IHsKIAl9LAogfTsK IAorLyogVGhpcyBjb2RlIGlzIGJhc2VkIG9uIGNsay1maXhlZC1mYWN0b3IuYyBkcml2ZXIgYW5k IG1vZGlmaWVkLiAqLworCitzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayB7CisJc3RydWN0IGNsa19o dyBjbGtfaHc7CisJaW50IGNsb2NrX2lkeDsKKwl1MzIgcG1fY29udGV4dF9yZWcxOworCXUzMiBw bV9jb250ZXh0X3JlZzI7Cit9OworCitzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlIHsKKwlz dHJ1Y3QgbXZlYnVfdWFydF9jbG9jayBjbG9ja3NbMl07CisJdW5zaWduZWQgaW50IHBhcmVudF9y YXRlc1s1XTsKKwlpbnQgcGFyZW50X2lkeDsKKwl1bnNpZ25lZCBpbnQgZGl2OworCXZvaWQgX19p b21lbSAqcmVnMTsKKwl2b2lkIF9faW9tZW0gKnJlZzI7CisJYm9vbCBjb25maWd1cmVkOworfTsK KworI2RlZmluZSBQQVJFTlRfQ0xPQ0tfWFRBTCA0CisKKyNkZWZpbmUgdG9fdWFydF9jbG9jayho dykgY29udGFpbmVyX29mKGh3LCBzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jaywgY2xrX2h3KQorI2Rl ZmluZSB0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jaykgY29udGFpbmVyX29mKHVhcnRfY2xv Y2ssIFwKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlLCBjbG9ja3NbdWFydF9jbG9jay0+ Y2xvY2tfaWR4XSkKKworc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3ByZXBhcmUoc3RydWN0 IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0 b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Ns b2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2ln bmVkIGludCBwcmV2X2Nsb2NrX2lkeCwgcHJldl9jbG9ja19yYXRlLCBwcmV2X2QxZDI7CisJdW5z aWduZWQgaW50IHBhcmVudF9jbG9ja19pZHgsIHBhcmVudF9jbG9ja19yYXRlOworCXVuc2lnbmVk IGxvbmcgZmxhZ3M7CisJdW5zaWduZWQgaW50IGQxLCBkMjsKKwl1NjQgZGl2aXNvcjsKKwl1MzIg dmFsOworCisJLyoKKwkgKiBUaGlzIGZ1bmN0aW9uIGp1c3QgcmVjb25maWd1cmVzIFVBUlQgQ2xv Y2sgQ29udHJvbCByZWdpc3RlciAobG9jYXRlZAorCSAqIGluIFVBUlQxIGFkZHJlc3Mgc3BhY2Ug d2hpY2ggY29udHJvbHMgYm90aCBVQVJUMSBhbmQgVUFSVDIpIHRvCisJICogc2VsZWN0ZWQgVUFS VCBiYXNlIGNsb2NrIGFuZCByZWNhbGN1bGF0ZSBjdXJyZW50IFVBUlQxL1VBUlQyIGRpdmlzb3Jz CisJICogaW4gdGhlaXIgYWRkcmVzcyBzcGFjZXMsIHNvIGZpbmFsIGJhdWRyYXRlIHdpbGwgbm90 IGJlIGNoYW5nZWQgYnkKKwkgKiBzd2l0Y2hpbmcgVUFSVCBiYXNlIGNsb2NrLiBUaGlzIGlzIHJl cXVpcmVkIG90aGVyd2lzZSBrZXJuZWwgYm9vdCBsb2cKKwkgKiBzdG9wcyB3b3JraW5nLiBJdCBp cyBuZWVkZWQgdG8gZW5zdXJlIHRoYXQgVUFSVCBiYXVkcmF0ZSBkb2VzIG5vdAorCSAqIGNoYW5n ZSBkdXJpbmcgdGhpcyBzZXR1cC4gSXQgaXMgb25lIHRpbWUgb3BlcmF0aW9uLCBzbyBiYXNlZCBv bgorCSAqICJjb25maWd1cmVkIiBtZW1iZXIgdGhpcyBmdW5jdGlvbiBpcyBza2lwcGVkIG9uIHNl Y29uZCBjYWxsLiBCZWNhdXNlCisJICogdGhpcyBVQVJUIENsb2NrIENvbnRyb2wgcmVnaXN0ZXIg KFVBUlRfQlJEVikgaXMgc2hhcmVkIGJldHdlZW4gVUFSVDEKKwkgKiBiYXVkcmF0ZSBmdW5jdGlv biwgVUFSVDEgY2xvY2sgc2VsZWN0b3IgYW5kIFVBUlQyIGNsb2NrIHNlbGVjdG9yLAorCSAqIGV2 ZXJ5IGFjY2VzcyB0byBVQVJUX0JSRFYgKHJlZzEpIG5lZWRzIHRvIGJlIHByb3RlY3RlZCBieSBs b2NrLgorCSAqLworCisJc3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3Mp OworCisJaWYgKHVhcnRfY2xvY2tfYmFzZS0+Y29uZmlndXJlZCkgeworCQlzcGluX3VubG9ja19p cnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKwkJcmV0dXJuIDA7CisJfQorCisJ cGFyZW50X2Nsb2NrX2lkeCA9IHVhcnRfY2xvY2tfYmFzZS0+cGFyZW50X2lkeDsKKwlwYXJlbnRf Y2xvY2tfcmF0ZSA9IHVhcnRfY2xvY2tfYmFzZS0+cGFyZW50X3JhdGVzW3BhcmVudF9jbG9ja19p ZHhdOworCisJdmFsID0gcmVhZGwodWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKworCWlmICh1YXJ0 X2Nsb2NrX2Jhc2UtPmRpdiA+IENMS19UQkdfRElWMV9NQVgpIHsKKwkJZDEgPSBDTEtfVEJHX0RJ VjFfTUFYOworCQlkMiA9IHVhcnRfY2xvY2tfYmFzZS0+ZGl2IC8gQ0xLX1RCR19ESVYxX01BWDsK Kwl9IGVsc2UgeworCQlkMSA9IHVhcnRfY2xvY2tfYmFzZS0+ZGl2OworCQlkMiA9IDE7CisJfQor CisJaWYgKHZhbCAmIENMS19OT19YVEFMKSB7CisJCXByZXZfY2xvY2tfaWR4ID0gKHZhbCA+PiBD TEtfVEJHX1NFTF9TSElGVCkgJiBDTEtfVEJHX1NFTF9NQVNLOworCQlwcmV2X2QxZDIgPSAoKHZh bCA+PiBDTEtfVEJHX0RJVjFfU0hJRlQpICYgQ0xLX1RCR19ESVYxX01BU0spCisJCQkgICogKCh2 YWwgPj4gQ0xLX1RCR19ESVYyX1NISUZUKSAmIENMS19UQkdfRElWMl9NQVNLKTsKKwl9IGVsc2Ug eworCQlwcmV2X2Nsb2NrX2lkeCA9IFBBUkVOVF9DTE9DS19YVEFMOworCQlwcmV2X2QxZDIgPSAx OworCX0KKworCS8qIE5vdGUgdGhhdCB1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1tpXSBt YXkgbm90IGJlIGF2YWlsYWJsZSAqLworCXByZXZfY2xvY2tfcmF0ZSA9IHVhcnRfY2xvY2tfYmFz ZS0+cGFyZW50X3JhdGVzW3ByZXZfY2xvY2tfaWR4XTsKKworCS8qIFJlY2FsY3VsYXRlIFVBUlQx IGRpdmlzb3Igc28gVUFSVDEgYmF1ZHJhdGUgZG9lcyBub3QgY2hhbmdlICovCisJaWYgKHByZXZf Y2xvY2tfcmF0ZSkgeworCQlkaXZpc29yID0gRElWX1U2NF9ST1VORF9DTE9TRVNUKCh1NjQpKHZh bCAmIEJSRFZfQkFVRF9NQVNLKSAqCisJCQkJCQlwYXJlbnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFk MiwKKwkJCQkJCXByZXZfY2xvY2tfcmF0ZSAqIGQxICogZDIpOworCQlpZiAoZGl2aXNvciA8IDEp CisJCQlkaXZpc29yID0gMTsKKwkJZWxzZSBpZiAoZGl2aXNvciA+IEJSRFZfQkFVRF9NQVgpCisJ CQlkaXZpc29yID0gQlJEVl9CQVVEX01BWDsKKwkJdmFsID0gKHZhbCAmIH5CUkRWX0JBVURfTUFT SykgfCBkaXZpc29yOworCX0KKworCWlmIChwYXJlbnRfY2xvY2tfaWR4ICE9IFBBUkVOVF9DTE9D S19YVEFMKSB7CisJCS8qIERvIG5vdCB1c2UgWFRBTCwgc2VsZWN0IFRCRyBjbG9jayBhbmQgVEJH IGQxICogZDIgZGl2aXNvcnMgKi8KKwkJdmFsIHw9IENMS19OT19YVEFMOworCQl2YWwgJj0gfihD TEtfVEJHX0RJVjFfTUFTSyA8PCBDTEtfVEJHX0RJVjFfU0hJRlQpOworCQl2YWwgfD0gZDEgPDwg Q0xLX1RCR19ESVYxX1NISUZUOworCQl2YWwgJj0gfihDTEtfVEJHX0RJVjJfTUFTSyA8PCBDTEtf VEJHX0RJVjJfU0hJRlQpOworCQl2YWwgfD0gZDIgPDwgQ0xLX1RCR19ESVYyX1NISUZUOworCQl2 YWwgJj0gfihDTEtfVEJHX1NFTF9NQVNLIDw8IENMS19UQkdfU0VMX1NISUZUKTsKKwkJdmFsIHw9 IHBhcmVudF9jbG9ja19pZHggPDwgQ0xLX1RCR19TRUxfU0hJRlQ7CisJfSBlbHNlIHsKKwkJLyog VXNlIFhUQUwsIFRCRyBiaXRzIGFyZSB0aGVuIGlnbm9yZWQgKi8KKwkJdmFsICY9IH5DTEtfTk9f WFRBTDsKKwl9CisKKwl3cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJLyog UmVjYWxjdWxhdGUgVUFSVDIgZGl2aXNvciBzbyBVQVJUMiBiYXVkcmF0ZSBkb2VzIG5vdCBjaGFu Z2UgKi8KKwlpZiAocHJldl9jbG9ja19yYXRlKSB7CisJCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tf YmFzZS0+cmVnMik7CisJCWRpdmlzb3IgPSBESVZfVTY0X1JPVU5EX0NMT1NFU1QoKHU2NCkodmFs ICYgQlJEVl9CQVVEX01BU0spICoKKwkJCQkJCXBhcmVudF9jbG9ja19yYXRlICogcHJldl9kMWQy LAorCQkJCQkJcHJldl9jbG9ja19yYXRlICogZDEgKiBkMik7CisJCWlmIChkaXZpc29yIDwgMSkK KwkJCWRpdmlzb3IgPSAxOworCQllbHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVEX01BWCkKKwkJ CWRpdmlzb3IgPSBCUkRWX0JBVURfTUFYOworCQl2YWwgPSAodmFsICYgfkJSRFZfQkFVRF9NQVNL KSB8IGRpdmlzb3I7CisJCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7CisJfQor CisJdWFydF9jbG9ja19iYXNlLT5jb25maWd1cmVkID0gdHJ1ZTsKKworCXNwaW5fdW5sb2NrX2ly cXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworCisJcmV0dXJuIDA7Cit9CisKK3N0 YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19lbmFibGUoc3RydWN0IGNsa19odyAqaHcpCit7CisJ c3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsK KwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJ dG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJ dTMyIHZhbDsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsK KworCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9jbG9j ay0+Y2xvY2tfaWR4ID09IDApCisJCXZhbCAmPSB+VUFSVDFfQ0xLX0RJUzsKKwllbHNlCisJCXZh bCAmPSB+VUFSVDJfQ0xLX0RJUzsKKworCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVn MSk7CisKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsK KworCXJldHVybiAwOworfQorCitzdGF0aWMgdm9pZCBtdmVidV91YXJ0X2Nsb2NrX2Rpc2FibGUo c3RydWN0IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xv Y2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1 YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOwor CXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJdTMyIHZhbDsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZt dmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKworCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+ cmVnMSk7CisKKwlpZiAodWFydF9jbG9jay0+Y2xvY2tfaWR4ID09IDApCisJCXZhbCB8PSBVQVJU MV9DTEtfRElTOworCWVsc2UKKwkJdmFsIHw9IFVBUlQyX0NMS19ESVM7CisKKwl3cml0ZWwodmFs LCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZl YnVfdWFydF9sb2NrLCBmbGFncyk7Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19p c19lbmFibGVkKHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2Nr ICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xv Y2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0 X2Nsb2NrKTsKKwl1MzIgdmFsOworCisJdmFsID0gcmVhZGwodWFydF9jbG9ja19iYXNlLT5yZWcx KTsKKworCWlmICh1YXJ0X2Nsb2NrLT5jbG9ja19pZHggPT0gMCkKKwkJcmV0dXJuICEodmFsICYg VUFSVDFfQ0xLX0RJUyk7CisJZWxzZQorCQlyZXR1cm4gISh2YWwgJiBVQVJUMl9DTEtfRElTKTsK K30KKworc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3NhdmVfY29udGV4dChzdHJ1Y3QgY2xr X2h3ICpodykKK3sKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3Vh cnRfY2xvY2soaHcpOworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tf YmFzZSA9CisJCQkJCQl0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7CisJdW5zaWduZWQg bG9uZyBmbGFnczsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdz KTsKKwl1YXJ0X2Nsb2NrLT5wbV9jb250ZXh0X3JlZzEgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2Ut PnJlZzEpOworCXVhcnRfY2xvY2stPnBtX2NvbnRleHRfcmVnMiA9IHJlYWRsKHVhcnRfY2xvY2tf YmFzZS0+cmVnMik7CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBm bGFncyk7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgbXZlYnVfdWFydF9jbG9ja19y ZXN0b3JlX2NvbnRleHQoc3RydWN0IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRf Y2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFy dF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNl KHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisKKwlzcGluX2xvY2tfaXJxc2F2 ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisJd3JpdGVsKHVhcnRfY2xvY2stPnBtX2NvbnRl eHRfcmVnMSwgdWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKwl3cml0ZWwodWFydF9jbG9jay0+cG1f Y29udGV4dF9yZWcyLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOworCXNwaW5fdW5sb2NrX2lycXJl c3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworfQorCitzdGF0aWMgdW5zaWduZWQgbG9u ZyBtdmVidV91YXJ0X2Nsb2NrX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LAorCQkJCQkJ ICB1bnNpZ25lZCBsb25nIHBhcmVudF9yYXRlKQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2Nr ICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xv Y2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0 X2Nsb2NrKTsKKworCXJldHVybiBwYXJlbnRfcmF0ZSAvIHVhcnRfY2xvY2tfYmFzZS0+ZGl2Owor fQorCitzdGF0aWMgbG9uZyBtdmVidV91YXJ0X2Nsb2NrX3JvdW5kX3JhdGUoc3RydWN0IGNsa19o dyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwKKwkJCQkJdW5zaWduZWQgbG9uZyAqcGFyZW50X3Jh dGUpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Ns b2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2Ug PQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCisJcmV0dXJuICpwYXJl bnRfcmF0ZSAvIHVhcnRfY2xvY2tfYmFzZS0+ZGl2OworfQorCitzdGF0aWMgaW50IG12ZWJ1X3Vh cnRfY2xvY2tfc2V0X3JhdGUoc3RydWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwK KwkJCQkgICAgIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpCit7CisJLyoKKwkgKiBXZSBtdXN0 IHJlcG9ydCBzdWNjZXNzIGJ1dCB3ZSBjYW4gZG8gc28gdW5jb25kaXRpb25hbGx5IGJlY2F1c2UK KwkgKiBtdmVidV91YXJ0X2Nsb2NrX3JvdW5kX3JhdGUgcmV0dXJucyB2YWx1ZXMgdGhhdCBlbnN1 cmUgdGhpcyBjYWxsIGlzIGEKKwkgKiBub3AuCisJICovCisKKwlyZXR1cm4gMDsKK30KKworc3Rh dGljIGNvbnN0IHN0cnVjdCBjbGtfb3BzIG12ZWJ1X3VhcnRfY2xvY2tfb3BzID0geworCS5wcmVw YXJlID0gbXZlYnVfdWFydF9jbG9ja19wcmVwYXJlLAorCS5lbmFibGUgPSBtdmVidV91YXJ0X2Ns b2NrX2VuYWJsZSwKKwkuZGlzYWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tfZGlzYWJsZSwKKwkuaXNf ZW5hYmxlZCA9IG12ZWJ1X3VhcnRfY2xvY2tfaXNfZW5hYmxlZCwKKwkuc2F2ZV9jb250ZXh0ID0g bXZlYnVfdWFydF9jbG9ja19zYXZlX2NvbnRleHQsCisJLnJlc3RvcmVfY29udGV4dCA9IG12ZWJ1 X3VhcnRfY2xvY2tfcmVzdG9yZV9jb250ZXh0LAorCS5yb3VuZF9yYXRlID0gbXZlYnVfdWFydF9j bG9ja19yb3VuZF9yYXRlLAorCS5zZXRfcmF0ZSA9IG12ZWJ1X3VhcnRfY2xvY2tfc2V0X3JhdGUs CisJLnJlY2FsY19yYXRlID0gbXZlYnVfdWFydF9jbG9ja19yZWNhbGNfcmF0ZSwKK307CisKK3N0 YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19yZWdpc3RlcihzdHJ1Y3QgZGV2aWNlICpkZXYsCisJ CQkJICAgICBzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jaywKKwkJCQkgICAgIGNv bnN0IGNoYXIgKm5hbWUsCisJCQkJICAgICBjb25zdCBjaGFyICpwYXJlbnRfbmFtZSkKK3sKKwlz dHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0ID0geyB9OworCisJdWFydF9jbG9jay0+Y2xrX2h3Lmlu aXQgPSAmaW5pdDsKKworCWluaXQubmFtZSA9IG5hbWU7CisJaW5pdC5vcHMgPSAmbXZlYnVfdWFy dF9jbG9ja19vcHM7CisJaW5pdC5mbGFncyA9IDA7CisJaW5pdC5udW1fcGFyZW50cyA9IDE7CisJ aW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50X25hbWU7CisKKwlyZXR1cm4gZGV2bV9jbGtfaHdf cmVnaXN0ZXIoZGV2LCAmdWFydF9jbG9jay0+Y2xrX2h3KTsKK30KKworc3RhdGljIGludCBtdmVi dV91YXJ0X2Nsb2NrX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3Rh dGljIGNvbnN0IGNoYXIgKmNvbnN0IHVhcnRfY2xrX25hbWVzW10gPSB7ICJ1YXJ0XzEiLCAidWFy dF8yIiB9OworCXN0YXRpYyBjb25zdCBjaGFyICpjb25zdCBwYXJlbnRfY2xrX25hbWVzW10gPSB7 ICJUQkctQS1QIiwgIlRCRy1CLVAiLAorCQkJCQkJCSJUQkctQS1TIiwgIlRCRy1CLVMiLAorCQkJ CQkJCSJ4dGFsIiB9OworCXN0cnVjdCBjbGsgKnBhcmVudF9jbGtzW0FSUkFZX1NJWkUocGFyZW50 X2Nsa19uYW1lcyldOworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tf YmFzZTsKKwlzdHJ1Y3QgY2xrX2h3X29uZWNlbGxfZGF0YSAqaHdfY2xrX2RhdGE7CisJc3RydWN0 IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKKwlpbnQgaSwgcGFyZW50X2Nsa19pZHgsIHJldDsK Kwl1bnNpZ25lZCBsb25nIGRpdiwgcmF0ZTsKKwlzdHJ1Y3QgcmVzb3VyY2UgKnJlczsKKwl1bnNp Z25lZCBpbnQgZDEsIGQyOworCisJQlVJTERfQlVHX09OKEFSUkFZX1NJWkUodWFydF9jbGtfbmFt ZXMpICE9CisJCSAgICAgQVJSQVlfU0laRSh1YXJ0X2Nsb2NrX2Jhc2UtPmNsb2NrcykpOworCUJV SUxEX0JVR19PTihBUlJBWV9TSVpFKHBhcmVudF9jbGtfbmFtZXMpICE9CisJCSAgICAgQVJSQVlf U0laRSh1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlcykpOworCisJdWFydF9jbG9ja19iYXNl ID0gZGV2bV9remFsbG9jKGRldiwKKwkJCQkgICAgICAgc2l6ZW9mKCp1YXJ0X2Nsb2NrX2Jhc2Up LAorCQkJCSAgICAgICBHRlBfS0VSTkVMKTsKKwlpZiAoIXVhcnRfY2xvY2tfYmFzZSkKKwkJcmV0 dXJuIC1FTk9NRU07CisKKwlyZXMgPSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNP VVJDRV9NRU0sIDApOworCWlmICghcmVzKSB7CisJCWRldl9lcnIoZGV2LCAiQ291bGRuJ3QgZ2V0 IGZpcnN0IHJlZ2lzdGVyXG4iKTsKKwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCisJLyoKKwkgKiBV QVJUIENsb2NrIENvbnRyb2wgcmVnaXN0ZXIgKHJlZzEgLyBVQVJUX0JSRFYpIGlzIGluIGFkZHJl c3MgcmFuZ2UKKwkgKiBvZiBVQVJUMSAoc3RhbmRhcmQgVUFSVCB2YXJpYW50KSwgY29udHJvbHMg Y2xvY2sgc291cmNlIGFuZCBkaXZpZGVycworCSAqIGZvciBib3RoIFVBUlQxIGFuZCBVQVJUMiBh bmQgaXMgc3VwcGxpZWQgdmlhIERUIGFzIGZpcnN0IHJlc291cmNlLgorCSAqIFRoZXJlZm9yZSB1 c2UgaW9yZW1hcCgpIGZ1bmN0aW9uIHJhdGhlciB0aGFuIGlvcmVtYXBfcmVzb3VyY2UoKSB0bwor CSAqIGF2b2lkIGNvbmZsaWN0cyB3aXRoIFVBUlQxIGRyaXZlci4gQWNjZXNzIHRvIFVBUlRfQlJE ViBpcyBwcm90ZWN0ZWQKKwkgKiBieSBsb2NrIHNoYXJlZCBiZXR3ZWVuIGNsb2NrIGFuZCBVQVJU IGRyaXZlci4KKwkgKi8KKwl1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEgPSBkZXZtX2lvcmVtYXAoZGV2 LCByZXMtPnN0YXJ0LAorCQkJCQkgICAgIHJlc291cmNlX3NpemUocmVzKSk7CisJaWYgKElTX0VS Uih1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpKQorCQlyZXR1cm4gUFRSX0VSUih1YXJ0X2Nsb2NrX2Jh c2UtPnJlZzEpOworCisJcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VS Q0VfTUVNLCAxKTsKKwlpZiAoIXJlcykgeworCQlkZXZfZXJyKGRldiwgIkNvdWxkbid0IGdldCBz ZWNvbmQgcmVnaXN0ZXJcbiIpOworCQlyZXR1cm4gLUVOT0VOVDsKKwl9CisKKwkvKgorCSAqIFVB UlQgMiBCYXVkIFJhdGUgRGl2aXNvciByZWdpc3RlciAocmVnMiAvIFVBUlRfQlJEVikgaXMgaW4g YWRkcmVzcworCSAqIHJhbmdlIG9mIFVBUlQyIChleHRlbmRlZCBVQVJUIHZhcmlhbnQpLCBjb250 cm9scyBvbmx5IG9uZSBVQVJUMgorCSAqIHNwZWNpZmljIGRpdmlkZXIgYW5kIGlzIHN1cHBsaWVk IHZpYSBEVCBhcyBzZWNvbmQgcmVzb3VyY2UuCisJICogVGhlcmVmb3JlIHVzZSBpb3JlbWFwKCkg ZnVuY3Rpb24gcmF0aGVyIHRoYW4gaW9yZW1hcF9yZXNvdXJjZSgpIHRvCisJICogYXZvaWQgY29u ZmxpY3RzIHdpdGggVUFSVDIgZHJpdmVyLiBBY2Nlc3MgdG8gVUFSVF9CUkRWIGlzIHByb3RlY3Rl ZAorCSAqIGJ5IGxvY2sgc2hhcmVkIGJldHdlZW4gY2xvY2sgYW5kIFVBUlQgZHJpdmVyLgorCSAq LworCXVhcnRfY2xvY2tfYmFzZS0+cmVnMiA9IGRldm1faW9yZW1hcChkZXYsIHJlcy0+c3RhcnQs CisJCQkJCSAgICAgcmVzb3VyY2Vfc2l6ZShyZXMpKTsKKwlpZiAoSVNfRVJSKHVhcnRfY2xvY2tf YmFzZS0+cmVnMikpCisJCXJldHVybiBQVFJfRVJSKHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7CisK Kwlod19jbGtfZGF0YSA9IGRldm1fa3phbGxvYyhkZXYsCisJCQkJICAgc3RydWN0X3NpemUoaHdf Y2xrX2RhdGEsIGh3cywKKwkJCQkJICAgICAgIEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpKSwK KwkJCQkgICBHRlBfS0VSTkVMKTsKKwlpZiAoIWh3X2Nsa19kYXRhKQorCQlyZXR1cm4gLUVOT01F TTsKKworCWh3X2Nsa19kYXRhLT5udW0gPSBBUlJBWV9TSVpFKHVhcnRfY2xrX25hbWVzKTsKKwlm b3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRSh1YXJ0X2Nsa19uYW1lcyk7IGkrKykgeworCQlod19j bGtfZGF0YS0+aHdzW2ldID0gJnVhcnRfY2xvY2tfYmFzZS0+Y2xvY2tzW2ldLmNsa19odzsKKwkJ dWFydF9jbG9ja19iYXNlLT5jbG9ja3NbaV0uY2xvY2tfaWR4ID0gaTsKKwl9CisKKwlwYXJlbnRf Y2xrX2lkeCA9IC0xOworCisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUocGFyZW50X2Nsa19u YW1lcyk7IGkrKykgeworCQlwYXJlbnRfY2xrc1tpXSA9IGRldm1fY2xrX2dldChkZXYsIHBhcmVu dF9jbGtfbmFtZXNbaV0pOworCQlpZiAoSVNfRVJSKHBhcmVudF9jbGtzW2ldKSkgeworCQkJaWYg KFBUUl9FUlIocGFyZW50X2Nsa3NbaV0pID09IC1FUFJPQkVfREVGRVIpCisJCQkJcmV0dXJuIC1F UFJPQkVfREVGRVI7CisJCQlkZXZfd2FybihkZXYsICJDb3VsZG4ndCBnZXQgdGhlIHBhcmVudCBj bG9jayAlczogJWxkXG4iLAorCQkJCXBhcmVudF9jbGtfbmFtZXNbaV0sIFBUUl9FUlIocGFyZW50 X2Nsa3NbaV0pKTsKKwkJCWNvbnRpbnVlOworCQl9CisKKwkJcmV0ID0gY2xrX3ByZXBhcmVfZW5h YmxlKHBhcmVudF9jbGtzW2ldKTsKKwkJaWYgKHJldCkgeworCQkJZGV2X3dhcm4oZGV2LCAiQ291 bGRuJ3QgZW5hYmxlIHBhcmVudCBjbG9jayAlczogJWRcbiIsCisJCQkJcGFyZW50X2Nsa19uYW1l c1tpXSwgcmV0KTsKKwkJCWNvbnRpbnVlOworCQl9CisJCXJhdGUgPSBjbGtfZ2V0X3JhdGUocGFy ZW50X2Nsa3NbaV0pOworCQl1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1tpXSA9IHJhdGU7 CisKKwkJaWYgKGkgIT0gUEFSRU5UX0NMT0NLX1hUQUwpIHsKKwkJCS8qCisJCQkgKiBDYWxjdWxh dGUgdGhlIHNtYWxsZXN0IFRCRyBkMSBhbmQgZDIgZGl2aXNvcnMgdGhhdAorCQkJICogc3RpbGwg Y2FuIHByb3ZpZGUgOTYwMCBiYXVkcmF0ZS4KKwkJCSAqLworCQkJZDEgPSBESVZfUk9VTkRfVVAo cmF0ZSwgOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAqCisJCQkJCQlCUkRWX0JBVURfTUFY KTsKKwkJCWlmIChkMSA8IDEpCisJCQkJZDEgPSAxOworCQkJZWxzZSBpZiAoZDEgPiBDTEtfVEJH X0RJVjFfTUFYKQorCQkJCWQxID0gQ0xLX1RCR19ESVYxX01BWDsKKworCQkJZDIgPSBESVZfUk9V TkRfVVAocmF0ZSwgOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAqCisJCQkJCQlCUkRWX0JB VURfTUFYICogZDEpOworCQkJaWYgKGQyIDwgMSkKKwkJCQlkMiA9IDE7CisJCQllbHNlIGlmIChk MiA+IENMS19UQkdfRElWMl9NQVgpCisJCQkJZDIgPSBDTEtfVEJHX0RJVjJfTUFYOworCQl9IGVs c2UgeworCQkJLyoKKwkJCSAqIFdoZW4gVUFSVCBjbG9jayB1c2VzIFhUQUwgY2xvY2sgYXMgYSBz b3VyY2UgdGhlbiBpdAorCQkJICogaXMgbm90IHBvc3NpYmxlIHRvIHVzZSBkMSBhbmQgZDIgZGl2 aXNvcnMuCisJCQkgKi8KKwkJCWQxID0gZDIgPSAxOworCQl9CisKKwkJLyogU2tpcCBjbG9jayBz b3VyY2Ugd2hpY2ggY2Fubm90IHByb3ZpZGUgOTYwMCBiYXVkcmF0ZSAqLworCQlpZiAocmF0ZSA+ IDk2MDAgKiBPU0FNUF9ERUZBVUxUX0RJVklTT1IgKiBCUkRWX0JBVURfTUFYICogZDEgKiBkMikK KwkJCWNvbnRpbnVlOworCisJCS8qCisJCSAqIENob29zZSBUQkcgY2xvY2sgc291cmNlIHdpdGgg dGhlIHNtYWxsZXN0IGRpdmlzb3JzLiBVc2UgWFRBTAorCQkgKiBjbG9jayBzb3VyY2Ugb25seSBp biBjYXNlIFRCRyBpcyBub3QgYXZhaWxhYmxlIGFzIFhUQUwgY2Fubm90CisJCSAqIGJlIHVzZWQg Zm9yIGJhdWRyYXRlcyBoaWdoZXIgdGhhbiAyMzA0MDAuCisJCSAqLworCQlpZiAocGFyZW50X2Ns a19pZHggPT0gLTEgfHwKKwkJICAgIChpICE9IFBBUkVOVF9DTE9DS19YVEFMICYmIGRpdiA+IGQx ICogZDIpKSB7CisJCQlwYXJlbnRfY2xrX2lkeCA9IGk7CisJCQlkaXYgPSBkMSAqIGQyOworCQl9 CisJfQorCisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUocGFyZW50X2Nsa19uYW1lcyk7IGkr KykgeworCQlpZiAoaSA9PSBwYXJlbnRfY2xrX2lkeCB8fCBJU19FUlIocGFyZW50X2Nsa3NbaV0p KQorCQkJY29udGludWU7CisJCWNsa19kaXNhYmxlX3VucHJlcGFyZShwYXJlbnRfY2xrc1tpXSk7 CisJCWRldm1fY2xrX3B1dChkZXYsIHBhcmVudF9jbGtzW2ldKTsKKwl9CisKKwlpZiAocGFyZW50 X2Nsa19pZHggPT0gLTEpIHsKKwkJZGV2X2VycihkZXYsICJObyB1c2FibGUgcGFyZW50IGNsb2Nr XG4iKTsKKwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCisJdWFydF9jbG9ja19iYXNlLT5wYXJlbnRf aWR4ID0gcGFyZW50X2Nsa19pZHg7CisJdWFydF9jbG9ja19iYXNlLT5kaXYgPSBkaXY7CisKKwlk ZXZfbm90aWNlKGRldiwgIlVzaW5nIHBhcmVudCBjbG9jayAlcyBhcyBiYXNlIFVBUlQgY2xvY2tc biIsCisJCSAgIF9fY2xrX2dldF9uYW1lKHBhcmVudF9jbGtzW3BhcmVudF9jbGtfaWR4XSkpOwor CisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpOyBpKyspIHsKKwkJ cmV0ID0gbXZlYnVfdWFydF9jbG9ja19yZWdpc3RlcihkZXYsCisJCQkJJnVhcnRfY2xvY2tfYmFz ZS0+Y2xvY2tzW2ldLAorCQkJCXVhcnRfY2xrX25hbWVzW2ldLAorCQkJCV9fY2xrX2dldF9uYW1l KHBhcmVudF9jbGtzW3BhcmVudF9jbGtfaWR4XSkpOworCQlpZiAocmV0KSB7CisJCQlkZXZfZXJy KGRldiwgIkNhbid0IHJlZ2lzdGVyIFVBUlQgY2xvY2sgJWQ6ICVkXG4iLAorCQkJCWksIHJldCk7 CisJCQlyZXR1cm4gcmV0OworCQl9CisJfQorCisJcmV0dXJuIGRldm1fb2ZfY2xrX2FkZF9od19w cm92aWRlcihkZXYsIG9mX2Nsa19od19vbmVjZWxsX2dldCwKKwkJCQkJICAgaHdfY2xrX2RhdGEp OworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBtdmVidV91YXJ0X2Nsb2Nr X29mX21hdGNoW10gPSB7CisJeyAuY29tcGF0aWJsZSA9ICJtYXJ2ZWxsLGFybWFkYS0zNzAwLXVh cnQtY2xvY2siLCB9LAorCXsgfQorfTsKKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIg bXZlYnVfdWFydF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIgPSB7CisJLnByb2JlID0gbXZlYnVfdWFy dF9jbG9ja19wcm9iZSwKKwkuZHJpdmVyCQk9IHsKKwkJLm5hbWUJPSAibXZlYnUtdWFydC1jbG9j ayIsCisJCS5vZl9tYXRjaF90YWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tfb2ZfbWF0Y2gsCisJfSwK K307CisKIHN0YXRpYyBpbnQgX19pbml0IG12ZWJ1X3VhcnRfaW5pdCh2b2lkKQogewogCWludCBy ZXQ7CkBAIC05ODAsMTAgKzE0ODYsMTkgQEAgc3RhdGljIGludCBfX2luaXQgbXZlYnVfdWFydF9p bml0KHZvaWQpCiAJaWYgKHJldCkKIAkJcmV0dXJuIHJldDsKIAorCXJldCA9IHBsYXRmb3JtX2Ry aXZlcl9yZWdpc3RlcigmbXZlYnVfdWFydF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIpOworCWlmIChy ZXQpIHsKKwkJdWFydF91bnJlZ2lzdGVyX2RyaXZlcigmbXZlYnVfdWFydF9kcml2ZXIpOworCQly ZXR1cm4gcmV0OworCX0KKwogCXJldCA9IHBsYXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmbXZlYnVf dWFydF9wbGF0Zm9ybV9kcml2ZXIpOwotCWlmIChyZXQpCisJaWYgKHJldCkgeworCQlwbGF0Zm9y bV9kcml2ZXJfdW5yZWdpc3RlcigmbXZlYnVfdWFydF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIpOwog CQl1YXJ0X3VucmVnaXN0ZXJfZHJpdmVyKCZtdmVidV91YXJ0X2RyaXZlcik7CisJCXJldHVybiBy ZXQ7CisJfQogCi0JcmV0dXJuIHJldDsKKwlyZXR1cm4gMDsKIH0KIGFyY2hfaW5pdGNhbGwobXZl YnVfdWFydF9pbml0KTsKLS0gCjIuMjAuMQoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFy bS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9t YWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK