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 6E63DC433F5 for ; Wed, 13 Oct 2021 14:21:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 518FF610A2 for ; Wed, 13 Oct 2021 14:21:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236211AbhJMOXq (ORCPT ); Wed, 13 Oct 2021 10:23:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:39892 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232587AbhJMOXo (ORCPT ); Wed, 13 Oct 2021 10:23:44 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 04D38610A2; Wed, 13 Oct 2021 14:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634134901; bh=18EAghoiQwsB+TCgiOpGJOXQFsntlP+PTH65Ti+8Q9k=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=CiidYqv4/iT/itwmOcsec/V9wFA+AQsi9bgqVTkSPi+0rl6dZYM3DmL83rtKQ0Inw f/qaCBR1LHBy54MF6VNPDSw+QSDWuk5gz8xJv9O8Nzp//MyrdS/+kHCI61Qhi6JlYq UHjoVSwyF4ebBnwquKgvi7Ch4UBwyctbZcQ4KbUDBEm43xAf4yuIEomdZG1rzax/ZD mpPpIkC5gfSlWZZbMxSR5lbBeAL3D52kTGr4PkPFbIa5BmEN6uJ0NjkJcQ+5U9MHpm hSJQOAeAtmiVJkiVazjgjzsvYpMeBgdqGU7zPtuK0Ts/Amnnq//IkN3q0ZM9vFuIv7 Dneqlc4hfqpWA== Received: by pali.im (Postfix) id C25A07FF; Wed, 13 Oct 2021 16:21:38 +0200 (CEST) Date: Wed, 13 Oct 2021 16:21:38 +0200 From: Pali =?utf-8?B?Um9ow6Fy?= To: Gregory CLEMENT Cc: Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman , Andrew Lunn , Sebastian Hesselbarth , Vladimir Vid , Marek =?utf-8?B?QmVow7pu?= , 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: Re: [PATCH v7 2/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Message-ID: <20211013142138.wcd32dyqizy6livc@pali> References: <20210930095838.28145-1-pali@kernel.org> <20210930095838.28145-3-pali@kernel.org> <87o87tdn85.fsf@BL-laptop> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <87o87tdn85.fsf@BL-laptop> User-Agent: NeoMutt/20180716 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wednesday 13 October 2021 16:16:10 Gregory CLEMENT wrote: > Hello Pali, > > > 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. > > Did you have a review from the clock maintainer for this driver ? Nobody did review (yet). > I found it very unusual to have the implementation of a clok driver > inside an uart driver. Yes, it is unusual, but nothing better can be done with current HW design (UART1 regs controls UART2) and already used DTS file to provide backward compatibility. > Gregory > > > > > 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 > > > > -- > Gregory Clement, Bootlin > Embedded Linux and Kernel engineering > http://bootlin.com 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 9FBF2C433EF for ; Wed, 13 Oct 2021 14:24:21 +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 65457610EA for ; Wed, 13 Oct 2021 14:24:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 65457610EA 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:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Hg4AVvxBUwG8AvzQyPLkgmkD1aoABc+cXC2E/zXiJBM=; b=RisGfos52QmMS8 Funy/JpxrxH+jim99n4nAB5v/GA3ea6CvXtB78ZwD4gizhRdZ4LGyYHSewqHkk/UPYu9Bh+T1YUxr kKAAjyZnHZx/UJpQX5hbI9Q4r6h5TIfRZpNl/Cse1LEeYFGPIb3ANbM6ghuTZzSo2lHgVV0CFIJfn 7P994rynI352JGctypk5Zl5MlDui+IcTas7/D7qEu1Uszkox+XUi2f5e6bo1K4VX+IGdBR+Cf9HgS rrbMRjUWCiXXV9toytuZkRfSveAY0Mxq+blMmtP9VfLK2ejBvqN/fz5V49D2bbd7ZKgcgy0pJpj/r tofjShdzuLIYKl3Jxafw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1maf8f-00H7W9-JX; Wed, 13 Oct 2021 14:21:49 +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 1maf8X-00H7TV-KB for linux-arm-kernel@lists.infradead.org; Wed, 13 Oct 2021 14:21:45 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 04D38610A2; Wed, 13 Oct 2021 14:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634134901; bh=18EAghoiQwsB+TCgiOpGJOXQFsntlP+PTH65Ti+8Q9k=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=CiidYqv4/iT/itwmOcsec/V9wFA+AQsi9bgqVTkSPi+0rl6dZYM3DmL83rtKQ0Inw f/qaCBR1LHBy54MF6VNPDSw+QSDWuk5gz8xJv9O8Nzp//MyrdS/+kHCI61Qhi6JlYq UHjoVSwyF4ebBnwquKgvi7Ch4UBwyctbZcQ4KbUDBEm43xAf4yuIEomdZG1rzax/ZD mpPpIkC5gfSlWZZbMxSR5lbBeAL3D52kTGr4PkPFbIa5BmEN6uJ0NjkJcQ+5U9MHpm hSJQOAeAtmiVJkiVazjgjzsvYpMeBgdqGU7zPtuK0Ts/Amnnq//IkN3q0ZM9vFuIv7 Dneqlc4hfqpWA== Received: by pali.im (Postfix) id C25A07FF; Wed, 13 Oct 2021 16:21:38 +0200 (CEST) Date: Wed, 13 Oct 2021 16:21:38 +0200 From: Pali =?utf-8?B?Um9ow6Fy?= To: Gregory CLEMENT Cc: Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman , Andrew Lunn , Sebastian Hesselbarth , Vladimir Vid , Marek =?utf-8?B?QmVow7pu?= , 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: Re: [PATCH v7 2/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Message-ID: <20211013142138.wcd32dyqizy6livc@pali> References: <20210930095838.28145-1-pali@kernel.org> <20210930095838.28145-3-pali@kernel.org> <87o87tdn85.fsf@BL-laptop> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <87o87tdn85.fsf@BL-laptop> User-Agent: NeoMutt/20180716 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211013_072141_768519_29347A3B X-CRM114-Status: GOOD ( 53.55 ) 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 T24gV2VkbmVzZGF5IDEzIE9jdG9iZXIgMjAyMSAxNjoxNjoxMCBHcmVnb3J5IENMRU1FTlQgd3Jv dGU6Cj4gSGVsbG8gUGFsaSwKPiAKPiA+IFRoaXMgcGF0Y2ggaW1wbGVtZW50cyBhIG5ldyBkZXZp Y2UgZHJpdmVyIGZvciBjb250cm9sbGluZyBVQVJUIGNsb2NrcyBvbgo+ID4gTWFydmVsbCBBcm1h ZGEgMzcwMCBTb0MuIFRoaXMgZGV2aWNlIGRyaXZlciBpcyBsb2FkZWQgZm9yIGRldmljZXMgd2hp Y2gKPiA+IG1hdGNoIGNvbXBhdGlibGUgc3RyaW5nICJtYXJ2ZWxsLGFybWFkYS0zNzAwLXVhcnQt Y2xvY2siLgo+ID4KPiA+IFRoZXJlIGFyZSBtb3JlIHBpdGZhbGxzIHJlbGF0ZWQgdG8gVUFSVCBj bG9ja3MuIEJvdGggVUFSVHMgdXNlIHNhbWUgYmFzZQo+ID4gY2xvY2sgc291cmNlLiBBbHNvIGRp dmlzb3JzIGZvciBUQkcgYmFzZSBjbG9jayBhcmUgc2hhcmVkIGJldHdlZW4gYm90aAo+ID4gVUFS VHMgYW5kIGFyZSBjb25maWd1cmVkIG9ubHkgZnJvbSBVQVJUMSBhZGRyZXNzIHNwYWNlLiBDbG9j a3MgY2FuIGJlCj4gPiBlbmFibGVkIC8gZGlzYWJsZWQgc2VwYXJhdGVseSBmb3IgVUFSVDEgYW5k IFVBUlQyLCBidXQgdGhleSBhcmUgY29udHJvbGxlZAo+ID4gb25seSBmcm9tIFVBUlQxIGFkZHJl c3Mgc3BhY2UuIE1vcmVvdmVyIE1hcnZlbGwgQXJtYWRhIDM3MDAgRnVuY3Rpb25hbAo+ID4gU3Bl Y2lmaWNhdGlvbnMgaGFzIHN3YXBwZWQgYml0cyBmb3IgZW5hYmxpbmcvZGlzYWJsaW5nIFVBUlQx IGFuZCBVQVJUMgo+ID4gY2xvY2tzLgo+ID4KPiA+IFNvIGRyaXZlciBmb3IgY29udHJvbGxpbmcg VUFSVDIgbmVlZHMgdG8gaGF2ZSBhY2Nlc3MgdG8gVUFSVDEgYWRkcmVzcyBzcGFjZQo+ID4gYXMg VUFSVDEgYWRkcmVzcyBzcGFjZSBjb250YWlucyBzb21lIGJpdHMgZXhjbHVzaXZlbHkgdXNlZCBi eSBVQVJUMiBhbmQKPiA+IGFsc28gYml0cyB3aGljaCBhcmUgc2hhcmVkIGZvciBib3RoIFVBUlQx IGFuZCBVQVJUMi4KPiA+Cj4gPiBGb3IgY2hhbmdpbmcgVUFSVCBiYXNlIGNsb2NrICh3aGljaCBj b250cm9scyBib3RoIFVBUlRzKSBkdXJpbmcgYm9vdCB3aGVuCj4gPiBVQVJUIGRyaXZlciBpcyBu b3QgcmVhZHkgYW5kIG9ubHkgZWFybHkgY29uc29sZSBpcyBhY3RpdmUsIGlzIG5vdCBzaW1wbGUK PiA+IG9wZXJhdGlvbiBhcyBpdCBpcyByZXF1aXJlZCB0byBhbHNvIHJlY2FsY3VsYXRlIGRpdmlz b3JzIHRvIG5vdCBjaGFuZ2UgVUFSVAo+ID4gYmF1ZHJhdGUgdXNlZCBieSBlYXJseSBjb25zb2xl LiBTbyBmb3IgdGhpcyBvcGVyYXRpb24gVUFSVDEgY2xvY2sgZHJpdmVyCj4gPiBuZWVkcyB0byBh Y2Nlc3MgYWxzbyBpbnRvIGFkZHJlc3Mgc3BhY2Ugb2YgVUFSVDIgd2hlcmUgYXJlIHJlZ2lzdGVy cyBmb3IKPiA+IFVBUlQyIGRpdmlzb3JzLgo+ID4KPiA+IEZvciB0aGVzZSByZWFzb25zLCB0aGlz IG5ldyBkZXZpY2UgZHJpdmVyIGZvciBVQVJUIGNsb2NrcyBkb2VzIG5vdCB1c2UKPiA+IGlvcmVt YXBfcmVzb3VyY2UoKSwgYnV0IG9ubHkgaW9yZW1hcCgpIHRvIHByZXZlbnQgcmVzb3VyY2UgY29u ZmxpY3RzCj4gPiBiZXR3ZWVuIFVBUlQgY2xvY2sgZHJpdmVyIGFuZCBVQVJUIGRyaXZlci4KPiA+ Cj4gPiBTaGFyZWQgYmV0d2VlbiBkcml2ZXJzIGFyZSBvbmx5IHR3byA0LWJ5dGVzIHJlZ2lzdGVy czogVUFSVCBDbG9jayBDb250cm9sCj4gPiBhbmQgVUFSVCAyIEJhdWQgUmF0ZSBEaXZpc29yLiBB Y2Nlc3MgdG8gdGhlc2UgdHdvIHJlZ2lzdGVycyBhcmUgcHJvdGVjdGVkCj4gPiBieSBvbmUgc3Bp bmxvY2sgdG8gcHJldmVudCBhbnkgY29uZmxpY3RzLiBBY2Nlc3MgaXMgcmVxdWlyZWQgb25seSBk dXJpbmcKPiA+IHByb2JlIHRpbWUsIGNoYW5naW5nIGJhdWRyYXRlIGFuZCBkdXJpbmcgc3VzcGVu ZC9yZXN1bWUuCj4gPgo+ID4gSGFyZHdhcmUgY2FuIGJlIGNvbmZpZ3VyZWQgdG8gdXNlIG9uZSBv ZiBmb2xsb3dpbmcgY2xvY2tzIGFzIFVBUlQgYmFzZQo+ID4gY2xvY2s6IFRCRy1BLVAsIFRCRy1C LVAsIFRCRy1BLVMsIFRCRy1CLVMsIHh0YWwuIE5vdCBldmVyeSBjbG9jayBpcyB1c2FibGUKPiA+ IGZvciBoaWdoZXIgYnVhZHJhdGVzLiBJbiBEVCBub2RlIGNhbiBiZSBzcGVjaWZpZWQgYW55IHN1 YnNldCBhbmQga2VybmVsCj4gPiBjaG9vc2UgdGhlIGJlc3Qgb25lLCB3aGljaCBzdGlsbCBzdXBw b3J0cyByZXF1aXJlZCBiYXVkcmF0ZSA5NjAwLiBGb3IKPiA+IHNtb290aCBib290IGxvZyBvdXRw dXQgaXQgaXMgbmVlZGVkIHRvIHNwZWNpZnkgY2xvY2sgdXNlZCBieSBlYXJseSBjb25zb2xlCj4g PiBvdGhlcndpc2UgZ2FyYmFnZSB3b3VsZCBiZSBwdXQgb24gVUFSVCBkdXJpbmcgcHJvYmluZyBm b3IgVUFSVCBjbG9jayBkcml2ZXIKPiA+IGFuZCB0cmFuc2l0aW9uaW5nIGZyb20gZWFybHkgY29u c29sZSB0byBub3JtYWwgY29uc29sZS4KPiA+Cj4gPiBUaGlzIGNoYW5nZSBpcyByZXF1aXJlZCB0 byBlbmFibGUgYW5kIGNvbmZpZ3VyZSBUQkcgY2xvY2sgYXMgYSBiYXNlIGNsb2NrCj4gPiBmb3Ig VUFSVC4gVEJHIGNsb2NrIGlzIHJlcXVpcmVkIHRvIGFjaGlldmUgaGlnaGVyIGJhdWRyYXRlcyB0 aGFuCj4gPiAyMzA0MDAuCj4gCj4gRGlkIHlvdSBoYXZlIGEgcmV2aWV3IGZyb20gdGhlIGNsb2Nr IG1haW50YWluZXIgZm9yIHRoaXMgZHJpdmVyID8KCk5vYm9keSBkaWQgcmV2aWV3ICh5ZXQpLgoK PiBJIGZvdW5kIGl0IHZlcnkgdW51c3VhbCB0byBoYXZlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBh IGNsb2sgZHJpdmVyCj4gaW5zaWRlIGFuIHVhcnQgZHJpdmVyLgoKWWVzLCBpdCBpcyB1bnVzdWFs LCBidXQgbm90aGluZyBiZXR0ZXIgY2FuIGJlIGRvbmUgd2l0aCBjdXJyZW50IEhXCmRlc2lnbiAo VUFSVDEgcmVncyBjb250cm9scyBVQVJUMikgYW5kIGFscmVhZHkgdXNlZCBEVFMgZmlsZSB0byBw cm92aWRlCmJhY2t3YXJkIGNvbXBhdGliaWxpdHkuCgo+IEdyZWdvcnkKPiAKPiA+Cj4gPiBTaWdu ZWQtb2ZmLWJ5OiBQYWxpIFJvaMOhciA8cGFsaUBrZXJuZWwub3JnPgo+ID4gLS0tCj4gPiAgZHJp dmVycy90dHkvc2VyaWFsL0tjb25maWcgICAgICB8ICAgMSArCj4gPiAgZHJpdmVycy90dHkvc2Vy aWFsL212ZWJ1LXVhcnQuYyB8IDUxOSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQo+ ID4gIDIgZmlsZXMgY2hhbmdlZCwgNTE4IGluc2VydGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCj4g Pgo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdHR5L3NlcmlhbC9LY29uZmlnIGIvZHJpdmVycy90 dHkvc2VyaWFsL0tjb25maWcKPiA+IGluZGV4IDEzMWE2YTU4N2FjZC4uZmUxYTU0MjMxYjE5IDEw MDY0NAo+ID4gLS0tIGEvZHJpdmVycy90dHkvc2VyaWFsL0tjb25maWcKPiA+ICsrKyBiL2RyaXZl cnMvdHR5L3NlcmlhbC9LY29uZmlnCj4gPiBAQCAtMTQ0NCw2ICsxNDQ0LDcgQEAgY29uZmlnIFNF UklBTF9TVE0zMl9DT05TT0xFCj4gPiAgY29uZmlnIFNFUklBTF9NVkVCVV9VQVJUCj4gPiAgCWJv b2wgIk1hcnZlbGwgRUJVIHNlcmlhbCBwb3J0IHN1cHBvcnQiCj4gPiAgCWRlcGVuZHMgb24gQVJD SF9NVkVCVSB8fCBDT01QSUxFX1RFU1QKPiA+ICsJZGVwZW5kcyBvbiBDT01NT05fQ0xLCj4gPiAg CXNlbGVjdCBTRVJJQUxfQ09SRQo+ID4gIAloZWxwCj4gPiAgCSAgVGhpcyBkcml2ZXIgaXMgZm9y IE1hcnZlbGwgRUJVIFNvQydzIFVBUlQuIElmIHlvdSBoYXZlIGEgbWFjaGluZQo+ID4gZGlmZiAt LWdpdCBhL2RyaXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMgYi9kcml2ZXJzL3R0eS9zZXJp YWwvbXZlYnUtdWFydC5jCj4gPiBpbmRleCAyMzFkZTI5YTY0NTIuLmYzZmIxZjM3MThmMiAxMDA2 NDQKPiA+IC0tLSBhL2RyaXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMKPiA+ICsrKyBiL2Ry aXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMKPiA+IEBAIC04LDEyICs4LDE0IEBACj4gPiAg Ki8KPiA+ICAKPiA+ICAjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gPiArI2luY2x1ZGUgPGxpbnV4 L2Nsay1wcm92aWRlci5oPgo+ID4gICNpbmNsdWRlIDxsaW51eC9jb25zb2xlLmg+Cj4gPiAgI2lu Y2x1ZGUgPGxpbnV4L2RlbGF5Lmg+Cj4gPiAgI2luY2x1ZGUgPGxpbnV4L2RldmljZS5oPgo+ID4g ICNpbmNsdWRlIDxsaW51eC9pbml0Lmg+Cj4gPiAgI2luY2x1ZGUgPGxpbnV4L2lvLmg+Cj4gPiAg I2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgo+ID4gKyNpbmNsdWRlIDxsaW51eC9tYXRoNjQuaD4K PiA+ICAjaW5jbHVkZSA8bGludXgvb2YuaD4KPiA+ICAjaW5jbHVkZSA8bGludXgvb2ZfYWRkcmVz cy5oPgo+ID4gICNpbmNsdWRlIDxsaW51eC9vZl9kZXZpY2UuaD4KPiA+IEBAIC02OCw4ICs3MCwz MSBAQAo+ID4gICNkZWZpbmUgIFNUQVRfQlJLX0VSUgkJKFNUQVRfQlJLX0RFVCB8IFNUQVRfRlJN X0VSUiBcCj4gPiAgCQkJCSB8IFNUQVRfUEFSX0VSUiB8IFNUQVRfT1ZSX0VSUikKPiA+ICAKPiA+ ICsvKgo+ID4gKyAqIE1hcnZlbGwgQXJtYWRhIDM3MDAgRnVuY3Rpb25hbCBTcGVjaWZpY2F0aW9u cyBkZXNjcmliZXMgdGhhdCBiaXQgMjEgb2YgVUFSVAo+ID4gKyAqIENsb2NrIENvbnRyb2wgcmVn aXN0ZXIgY29udHJvbHMgVUFSVDEgYW5kIGJpdCAyMCBjb250cm9scyBVQVJUMi4gQnV0IGluCj4g PiArICogcmVhbGl0eSBiaXQgMjEgY29udHJvbHMgVUFSVDIgYW5kIGJpdCAyMCBjb250cm9scyBV QVJUMS4gVGhpcyBzZWVtcyB0byBiZSBhCj4gPiArICogYnVnIGluIE1hcnZlbGwgZG9jdW1lbnRh dGlvbi4gSGVuY2UgZm9sbG93aW5nIENMS19ESVMgbWFjcm9zIGFyZSBzd2FwcGVkLgo+ID4gKyAq Lwo+ID4gKwo+ID4gICNkZWZpbmUgVUFSVF9CUkRWCQkweDEwCj4gPiArLyogVGhlc2UgYml0cyBh cmUgbG9jYXRlZCBpbiBVQVJUMSBhZGRyZXNzIHNwYWNlIGFuZCBjb250cm9sIFVBUlQyICovCj4g PiArI2RlZmluZSAgVUFSVDJfQ0xLX0RJUwkJQklUKDIxKQo+ID4gKy8qIFRoZXNlIGJpdHMgYXJl IGxvY2F0ZWQgaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSBhbmQgY29udHJvbCBVQVJUMSAqLwo+ID4g KyNkZWZpbmUgIFVBUlQxX0NMS19ESVMJCUJJVCgyMCkKPiA+ICsvKiBUaGVzZSBiaXRzIGFyZSBs b2NhdGVkIGluIFVBUlQxIGFkZHJlc3Mgc3BhY2UgYW5kIGNvbnRyb2wgYm90aCBVQVJUcyAqLwo+ ID4gKyNkZWZpbmUgIENMS19OT19YVEFMCQlCSVQoMTkpCj4gPiArI2RlZmluZSAgQ0xLX1RCR19E SVYxX1NISUZUCTE1Cj4gPiArI2RlZmluZSAgQ0xLX1RCR19ESVYxX01BU0sJMHg3Cj4gPiArI2Rl ZmluZSAgQ0xLX1RCR19ESVYxX01BWAk2Cj4gPiArI2RlZmluZSAgQ0xLX1RCR19ESVYyX1NISUZU CTEyCj4gPiArI2RlZmluZSAgQ0xLX1RCR19ESVYyX01BU0sJMHg3Cj4gPiArI2RlZmluZSAgQ0xL X1RCR19ESVYyX01BWAk2Cj4gPiArI2RlZmluZSAgQ0xLX1RCR19TRUxfU0hJRlQJMTAKPiA+ICsj ZGVmaW5lICBDTEtfVEJHX1NFTF9NQVNLCTB4Mwo+ID4gKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0 ZWQgaW4gYm90aCBVQVJUcyBhZGRyZXNzIHNwYWNlICovCj4gPiAgI2RlZmluZSAgQlJEVl9CQVVE X01BU0sgICAgICAgICAweDNGRgo+ID4gKyNkZWZpbmUgIEJSRFZfQkFVRF9NQVgJCUJSRFZfQkFV RF9NQVNLCj4gPiAgCj4gPiAgI2RlZmluZSBVQVJUX09TQU1QCQkweDE0Cj4gPiAgI2RlZmluZSAg T1NBTVBfREVGQVVMVF9ESVZJU09SCTE2Cj4gPiBAQCAtMTUzLDYgKzE3OCw4IEBAIHN0YXRpYyBz dHJ1Y3QgbXZlYnVfdWFydCAqdG9fbXZ1YXJ0KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQpCj4gPiAg Cj4gPiAgc3RhdGljIHN0cnVjdCB1YXJ0X3BvcnQgbXZlYnVfdWFydF9wb3J0c1tNVkVCVV9OUl9V QVJUU107Cj4gPiAgCj4gPiArc3RhdGljIERFRklORV9TUElOTE9DSyhtdmVidV91YXJ0X2xvY2sp Owo+ID4gKwo+ID4gIC8qIENvcmUgVUFSVCBEcml2ZXIgT3BlcmF0aW9ucyAqLwo+ID4gIHN0YXRp YyB1bnNpZ25lZCBpbnQgbXZlYnVfdWFydF90eF9lbXB0eShzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0 KQo+ID4gIHsKPiA+IEBAIC00NDUsNiArNDcyLDcgQEAgc3RhdGljIHZvaWQgbXZlYnVfdWFydF9z aHV0ZG93bihzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0KQo+ID4gIHN0YXRpYyBpbnQgbXZlYnVfdWFy dF9iYXVkX3JhdGVfc2V0KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQsIHVuc2lnbmVkIGludCBiYXVk KQo+ID4gIHsKPiA+ICAJdW5zaWduZWQgaW50IGRfZGl2aXNvciwgbV9kaXZpc29yOwo+ID4gKwl1 bnNpZ25lZCBsb25nIGZsYWdzOwo+ID4gIAl1MzIgYnJkdiwgb3NhbXA7Cj4gPiAgCj4gPiAgCWlm ICghcG9ydC0+dWFydGNsaykKPiA+IEBAIC00NjMsMTAgKzQ5MSwxMiBAQCBzdGF0aWMgaW50IG12 ZWJ1X3VhcnRfYmF1ZF9yYXRlX3NldChzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0LCB1bnNpZ25lZCBp bnQgYmF1ZCkKPiA+ICAJbV9kaXZpc29yID0gT1NBTVBfREVGQVVMVF9ESVZJU09SOwo+ID4gIAlk X2Rpdmlzb3IgPSBESVZfUk9VTkRfQ0xPU0VTVChwb3J0LT51YXJ0Y2xrLCBiYXVkICogbV9kaXZp c29yKTsKPiA+ICAKPiA+ICsJc3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxh Z3MpOwo+ID4gIAlicmR2ID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfQlJEVik7Cj4gPiAg CWJyZHYgJj0gfkJSRFZfQkFVRF9NQVNLOwo+ID4gIAlicmR2IHw9IGRfZGl2aXNvcjsKPiA+ICAJ d3JpdGVsKGJyZHYsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOwo+ID4gKwlzcGluX3VubG9j a19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiA+ICAKPiA+ICAJb3NhbXAg PSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9PU0FNUCk7Cj4gPiAgCW9zYW1wICY9IH5PU0FN UF9ESVZJU09SU19NQVNLOwo+ID4gQEAgLTc2Miw2ICs3OTIsNyBAQCBzdGF0aWMgaW50IG12ZWJ1 X3VhcnRfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gPiAgewo+ID4gIAlzdHJ1Y3QgbXZl YnVfdWFydCAqbXZ1YXJ0ID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gPiAgCXN0cnVjdCB1YXJ0 X3BvcnQgKnBvcnQgPSBtdnVhcnQtPnBvcnQ7Cj4gPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4g PiAgCj4gPiAgCXVhcnRfc3VzcGVuZF9wb3J0KCZtdmVidV91YXJ0X2RyaXZlciwgcG9ydCk7Cj4g PiAgCj4gPiBAQCAtNzcwLDcgKzgwMSw5IEBAIHN0YXRpYyBpbnQgbXZlYnVfdWFydF9zdXNwZW5k KHN0cnVjdCBkZXZpY2UgKmRldikKPiA+ICAJbXZ1YXJ0LT5wbV9yZWdzLmN0cmwgPSByZWFkbChw b3J0LT5tZW1iYXNlICsgVUFSVF9DVFJMKHBvcnQpKTsKPiA+ICAJbXZ1YXJ0LT5wbV9yZWdzLmlu dHIgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9JTlRSKHBvcnQpKTsKPiA+ICAJbXZ1YXJ0 LT5wbV9yZWdzLnN0YXQgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9TVEFUKTsKPiA+ICsJ c3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ID4gIAltdnVhcnQt PnBtX3JlZ3MuYnJkdiA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOwo+ID4gKwlz cGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiA+ICAJbXZ1 YXJ0LT5wbV9yZWdzLm9zYW1wID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfT1NBTVApOwo+ ID4gIAo+ID4gIAlkZXZpY2Vfc2V0X3dha2V1cF9lbmFibGUoZGV2LCB0cnVlKTsKPiA+IEBAIC03 ODIsMTMgKzgxNSwxNiBAQCBzdGF0aWMgaW50IG12ZWJ1X3VhcnRfcmVzdW1lKHN0cnVjdCBkZXZp Y2UgKmRldikKPiA+ICB7Cj4gPiAgCXN0cnVjdCBtdmVidV91YXJ0ICptdnVhcnQgPSBkZXZfZ2V0 X2RydmRhdGEoZGV2KTsKPiA+ICAJc3RydWN0IHVhcnRfcG9ydCAqcG9ydCA9IG12dWFydC0+cG9y dDsKPiA+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsKPiA+ICAKPiA+ICAJd3JpdGVsKG12dWFydC0+ cG1fcmVncy5yYnIsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX1JCUihwb3J0KSk7Cj4gPiAgCXdyaXRl bChtdnVhcnQtPnBtX3JlZ3MudHNoLCBwb3J0LT5tZW1iYXNlICsgVUFSVF9UU0gocG9ydCkpOwo+ ID4gIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLmN0cmwsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX0NU UkwocG9ydCkpOwo+ID4gIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLmludHIsIHBvcnQtPm1lbWJh c2UgKyBVQVJUX0lOVFIocG9ydCkpOwo+ID4gIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLnN0YXQs IHBvcnQtPm1lbWJhc2UgKyBVQVJUX1NUQVQpOwo+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZl YnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gPiAgCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MuYnJkdiwg cG9ydC0+bWVtYmFzZSArIFVBUlRfQlJEVik7Cj4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUo Jm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ID4gIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLm9z YW1wLCBwb3J0LT5tZW1iYXNlICsgVUFSVF9PU0FNUCk7Cj4gPiAgCj4gPiAgCXVhcnRfcmVzdW1l X3BvcnQoJm12ZWJ1X3VhcnRfZHJpdmVyLCBwb3J0KTsKPiA+IEBAIC05NzIsNiArMTAwOCw0NzYg QEAgc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbXZlYnVfdWFydF9wbGF0Zm9ybV9kcml2 ZXIgPSB7Cj4gPiAgCX0sCj4gPiAgfTsKPiA+ICAKPiA+ICsvKiBUaGlzIGNvZGUgaXMgYmFzZWQg b24gY2xrLWZpeGVkLWZhY3Rvci5jIGRyaXZlciBhbmQgbW9kaWZpZWQuICovCj4gPiArCj4gPiAr c3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgewo+ID4gKwlzdHJ1Y3QgY2xrX2h3IGNsa19odzsKPiA+ ICsJaW50IGNsb2NrX2lkeDsKPiA+ICsJdTMyIHBtX2NvbnRleHRfcmVnMTsKPiA+ICsJdTMyIHBt X2NvbnRleHRfcmVnMjsKPiA+ICt9Owo+ID4gKwo+ID4gK3N0cnVjdCBtdmVidV91YXJ0X2Nsb2Nr X2Jhc2Ugewo+ID4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayBjbG9ja3NbMl07Cj4gPiArCXVu c2lnbmVkIGludCBwYXJlbnRfcmF0ZXNbNV07Cj4gPiArCWludCBwYXJlbnRfaWR4Owo+ID4gKwl1 bnNpZ25lZCBpbnQgZGl2Owo+ID4gKwl2b2lkIF9faW9tZW0gKnJlZzE7Cj4gPiArCXZvaWQgX19p b21lbSAqcmVnMjsKPiA+ICsJYm9vbCBjb25maWd1cmVkOwo+ID4gK307Cj4gPiArCj4gPiArI2Rl ZmluZSBQQVJFTlRfQ0xPQ0tfWFRBTCA0Cj4gPiArCj4gPiArI2RlZmluZSB0b191YXJ0X2Nsb2Nr KGh3KSBjb250YWluZXJfb2YoaHcsIHN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrLCBjbGtfaHcpCj4g PiArI2RlZmluZSB0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jaykgY29udGFpbmVyX29mKHVh cnRfY2xvY2ssIFwKPiA+ICsJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSwgY2xvY2tzW3Vh cnRfY2xvY2stPmNsb2NrX2lkeF0pCj4gPiArCj4gPiArc3RhdGljIGludCBtdmVidV91YXJ0X2Ns b2NrX3ByZXBhcmUoc3RydWN0IGNsa19odyAqaHcpCj4gPiArewo+ID4gKwlzdHJ1Y3QgbXZlYnVf dWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOwo+ID4gKwlzdHJ1Y3Qg bXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQo+ID4gKwkJCQkJCXRvX3Vh cnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKPiA+ICsJdW5zaWduZWQgaW50IHByZXZfY2xvY2tf aWR4LCBwcmV2X2Nsb2NrX3JhdGUsIHByZXZfZDFkMjsKPiA+ICsJdW5zaWduZWQgaW50IHBhcmVu dF9jbG9ja19pZHgsIHBhcmVudF9jbG9ja19yYXRlOwo+ID4gKwl1bnNpZ25lZCBsb25nIGZsYWdz Owo+ID4gKwl1bnNpZ25lZCBpbnQgZDEsIGQyOwo+ID4gKwl1NjQgZGl2aXNvcjsKPiA+ICsJdTMy IHZhbDsKPiA+ICsKPiA+ICsJLyoKPiA+ICsJICogVGhpcyBmdW5jdGlvbiBqdXN0IHJlY29uZmln dXJlcyBVQVJUIENsb2NrIENvbnRyb2wgcmVnaXN0ZXIgKGxvY2F0ZWQKPiA+ICsJICogaW4gVUFS VDEgYWRkcmVzcyBzcGFjZSB3aGljaCBjb250cm9scyBib3RoIFVBUlQxIGFuZCBVQVJUMikgdG8K PiA+ICsJICogc2VsZWN0ZWQgVUFSVCBiYXNlIGNsb2NrIGFuZCByZWNhbGN1bGF0ZSBjdXJyZW50 IFVBUlQxL1VBUlQyIGRpdmlzb3JzCj4gPiArCSAqIGluIHRoZWlyIGFkZHJlc3Mgc3BhY2VzLCBz byBmaW5hbCBiYXVkcmF0ZSB3aWxsIG5vdCBiZSBjaGFuZ2VkIGJ5Cj4gPiArCSAqIHN3aXRjaGlu ZyBVQVJUIGJhc2UgY2xvY2suIFRoaXMgaXMgcmVxdWlyZWQgb3RoZXJ3aXNlIGtlcm5lbCBib290 IGxvZwo+ID4gKwkgKiBzdG9wcyB3b3JraW5nLiBJdCBpcyBuZWVkZWQgdG8gZW5zdXJlIHRoYXQg VUFSVCBiYXVkcmF0ZSBkb2VzIG5vdAo+ID4gKwkgKiBjaGFuZ2UgZHVyaW5nIHRoaXMgc2V0dXAu IEl0IGlzIG9uZSB0aW1lIG9wZXJhdGlvbiwgc28gYmFzZWQgb24KPiA+ICsJICogImNvbmZpZ3Vy ZWQiIG1lbWJlciB0aGlzIGZ1bmN0aW9uIGlzIHNraXBwZWQgb24gc2Vjb25kIGNhbGwuIEJlY2F1 c2UKPiA+ICsJICogdGhpcyBVQVJUIENsb2NrIENvbnRyb2wgcmVnaXN0ZXIgKFVBUlRfQlJEVikg aXMgc2hhcmVkIGJldHdlZW4gVUFSVDEKPiA+ICsJICogYmF1ZHJhdGUgZnVuY3Rpb24sIFVBUlQx IGNsb2NrIHNlbGVjdG9yIGFuZCBVQVJUMiBjbG9jayBzZWxlY3RvciwKPiA+ICsJICogZXZlcnkg YWNjZXNzIHRvIFVBUlRfQlJEViAocmVnMSkgbmVlZHMgdG8gYmUgcHJvdGVjdGVkIGJ5IGxvY2su Cj4gPiArCSAqLwo+ID4gKwo+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2Nr LCBmbGFncyk7Cj4gPiArCj4gPiArCWlmICh1YXJ0X2Nsb2NrX2Jhc2UtPmNvbmZpZ3VyZWQpIHsK PiA+ICsJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ ID4gKwkJcmV0dXJuIDA7Cj4gPiArCX0KPiA+ICsKPiA+ICsJcGFyZW50X2Nsb2NrX2lkeCA9IHVh cnRfY2xvY2tfYmFzZS0+cGFyZW50X2lkeDsKPiA+ICsJcGFyZW50X2Nsb2NrX3JhdGUgPSB1YXJ0 X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1twYXJlbnRfY2xvY2tfaWR4XTsKPiA+ICsKPiA+ICsJ dmFsID0gcmVhZGwodWFydF9jbG9ja19iYXNlLT5yZWcxKTsKPiA+ICsKPiA+ICsJaWYgKHVhcnRf Y2xvY2tfYmFzZS0+ZGl2ID4gQ0xLX1RCR19ESVYxX01BWCkgewo+ID4gKwkJZDEgPSBDTEtfVEJH X0RJVjFfTUFYOwo+ID4gKwkJZDIgPSB1YXJ0X2Nsb2NrX2Jhc2UtPmRpdiAvIENMS19UQkdfRElW MV9NQVg7Cj4gPiArCX0gZWxzZSB7Cj4gPiArCQlkMSA9IHVhcnRfY2xvY2tfYmFzZS0+ZGl2Owo+ ID4gKwkJZDIgPSAxOwo+ID4gKwl9Cj4gPiArCj4gPiArCWlmICh2YWwgJiBDTEtfTk9fWFRBTCkg ewo+ID4gKwkJcHJldl9jbG9ja19pZHggPSAodmFsID4+IENMS19UQkdfU0VMX1NISUZUKSAmIENM S19UQkdfU0VMX01BU0s7Cj4gPiArCQlwcmV2X2QxZDIgPSAoKHZhbCA+PiBDTEtfVEJHX0RJVjFf U0hJRlQpICYgQ0xLX1RCR19ESVYxX01BU0spCj4gPiArCQkJICAqICgodmFsID4+IENMS19UQkdf RElWMl9TSElGVCkgJiBDTEtfVEJHX0RJVjJfTUFTSyk7Cj4gPiArCX0gZWxzZSB7Cj4gPiArCQlw cmV2X2Nsb2NrX2lkeCA9IFBBUkVOVF9DTE9DS19YVEFMOwo+ID4gKwkJcHJldl9kMWQyID0gMTsK PiA+ICsJfQo+ID4gKwo+ID4gKwkvKiBOb3RlIHRoYXQgdWFydF9jbG9ja19iYXNlLT5wYXJlbnRf cmF0ZXNbaV0gbWF5IG5vdCBiZSBhdmFpbGFibGUgKi8KPiA+ICsJcHJldl9jbG9ja19yYXRlID0g dWFydF9jbG9ja19iYXNlLT5wYXJlbnRfcmF0ZXNbcHJldl9jbG9ja19pZHhdOwo+ID4gKwo+ID4g KwkvKiBSZWNhbGN1bGF0ZSBVQVJUMSBkaXZpc29yIHNvIFVBUlQxIGJhdWRyYXRlIGRvZXMgbm90 IGNoYW5nZSAqLwo+ID4gKwlpZiAocHJldl9jbG9ja19yYXRlKSB7Cj4gPiArCQlkaXZpc29yID0g RElWX1U2NF9ST1VORF9DTE9TRVNUKCh1NjQpKHZhbCAmIEJSRFZfQkFVRF9NQVNLKSAqCj4gPiAr CQkJCQkJcGFyZW50X2Nsb2NrX3JhdGUgKiBwcmV2X2QxZDIsCj4gPiArCQkJCQkJcHJldl9jbG9j a19yYXRlICogZDEgKiBkMik7Cj4gPiArCQlpZiAoZGl2aXNvciA8IDEpCj4gPiArCQkJZGl2aXNv ciA9IDE7Cj4gPiArCQllbHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVEX01BWCkKPiA+ICsJCQlk aXZpc29yID0gQlJEVl9CQVVEX01BWDsKPiA+ICsJCXZhbCA9ICh2YWwgJiB+QlJEVl9CQVVEX01B U0spIHwgZGl2aXNvcjsKPiA+ICsJfQo+ID4gKwo+ID4gKwlpZiAocGFyZW50X2Nsb2NrX2lkeCAh PSBQQVJFTlRfQ0xPQ0tfWFRBTCkgewo+ID4gKwkJLyogRG8gbm90IHVzZSBYVEFMLCBzZWxlY3Qg VEJHIGNsb2NrIGFuZCBUQkcgZDEgKiBkMiBkaXZpc29ycyAqLwo+ID4gKwkJdmFsIHw9IENMS19O T19YVEFMOwo+ID4gKwkJdmFsICY9IH4oQ0xLX1RCR19ESVYxX01BU0sgPDwgQ0xLX1RCR19ESVYx X1NISUZUKTsKPiA+ICsJCXZhbCB8PSBkMSA8PCBDTEtfVEJHX0RJVjFfU0hJRlQ7Cj4gPiArCQl2 YWwgJj0gfihDTEtfVEJHX0RJVjJfTUFTSyA8PCBDTEtfVEJHX0RJVjJfU0hJRlQpOwo+ID4gKwkJ dmFsIHw9IGQyIDw8IENMS19UQkdfRElWMl9TSElGVDsKPiA+ICsJCXZhbCAmPSB+KENMS19UQkdf U0VMX01BU0sgPDwgQ0xLX1RCR19TRUxfU0hJRlQpOwo+ID4gKwkJdmFsIHw9IHBhcmVudF9jbG9j a19pZHggPDwgQ0xLX1RCR19TRUxfU0hJRlQ7Cj4gPiArCX0gZWxzZSB7Cj4gPiArCQkvKiBVc2Ug WFRBTCwgVEJHIGJpdHMgYXJlIHRoZW4gaWdub3JlZCAqLwo+ID4gKwkJdmFsICY9IH5DTEtfTk9f WFRBTDsKPiA+ICsJfQo+ID4gKwo+ID4gKwl3cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJl ZzEpOwo+ID4gKwo+ID4gKwkvKiBSZWNhbGN1bGF0ZSBVQVJUMiBkaXZpc29yIHNvIFVBUlQyIGJh dWRyYXRlIGRvZXMgbm90IGNoYW5nZSAqLwo+ID4gKwlpZiAocHJldl9jbG9ja19yYXRlKSB7Cj4g PiArCQl2YWwgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOwo+ID4gKwkJZGl2aXNvciA9 IERJVl9VNjRfUk9VTkRfQ0xPU0VTVCgodTY0KSh2YWwgJiBCUkRWX0JBVURfTUFTSykgKgo+ID4g KwkJCQkJCXBhcmVudF9jbG9ja19yYXRlICogcHJldl9kMWQyLAo+ID4gKwkJCQkJCXByZXZfY2xv Y2tfcmF0ZSAqIGQxICogZDIpOwo+ID4gKwkJaWYgKGRpdmlzb3IgPCAxKQo+ID4gKwkJCWRpdmlz b3IgPSAxOwo+ID4gKwkJZWxzZSBpZiAoZGl2aXNvciA+IEJSRFZfQkFVRF9NQVgpCj4gPiArCQkJ ZGl2aXNvciA9IEJSRFZfQkFVRF9NQVg7Cj4gPiArCQl2YWwgPSAodmFsICYgfkJSRFZfQkFVRF9N QVNLKSB8IGRpdmlzb3I7Cj4gPiArCQl3cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIp Owo+ID4gKwl9Cj4gPiArCj4gPiArCXVhcnRfY2xvY2tfYmFzZS0+Y29uZmlndXJlZCA9IHRydWU7 Cj4gPiArCj4gPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxh Z3MpOwo+ID4gKwo+ID4gKwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIGludCBt dmVidV91YXJ0X2Nsb2NrX2VuYWJsZShzdHJ1Y3QgY2xrX2h3ICpodykKPiA+ICt7Cj4gPiArCXN0 cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7Cj4g PiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZSA9Cj4gPiAr CQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOwo+ID4gKwl1bnNpZ25lZCBsb25n IGZsYWdzOwo+ID4gKwl1MzIgdmFsOwo+ID4gKwo+ID4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZl YnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gPiArCj4gPiArCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tf YmFzZS0+cmVnMSk7Cj4gPiArCj4gPiArCWlmICh1YXJ0X2Nsb2NrLT5jbG9ja19pZHggPT0gMCkK PiA+ICsJCXZhbCAmPSB+VUFSVDFfQ0xLX0RJUzsKPiA+ICsJZWxzZQo+ID4gKwkJdmFsICY9IH5V QVJUMl9DTEtfRElTOwo+ID4gKwo+ID4gKwl3cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJl ZzEpOwo+ID4gKwo+ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ss IGZsYWdzKTsKPiA+ICsKPiA+ICsJcmV0dXJuIDA7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyB2 b2lkIG12ZWJ1X3VhcnRfY2xvY2tfZGlzYWJsZShzdHJ1Y3QgY2xrX2h3ICpodykKPiA+ICt7Cj4g PiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayho dyk7Cj4gPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZSA9 Cj4gPiArCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOwo+ID4gKwl1bnNpZ25l ZCBsb25nIGZsYWdzOwo+ID4gKwl1MzIgdmFsOwo+ID4gKwo+ID4gKwlzcGluX2xvY2tfaXJxc2F2 ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gPiArCj4gPiArCXZhbCA9IHJlYWRsKHVhcnRf Y2xvY2tfYmFzZS0+cmVnMSk7Cj4gPiArCj4gPiArCWlmICh1YXJ0X2Nsb2NrLT5jbG9ja19pZHgg PT0gMCkKPiA+ICsJCXZhbCB8PSBVQVJUMV9DTEtfRElTOwo+ID4gKwllbHNlCj4gPiArCQl2YWwg fD0gVUFSVDJfQ0xLX0RJUzsKPiA+ICsKPiA+ICsJd3JpdGVsKHZhbCwgdWFydF9jbG9ja19iYXNl LT5yZWcxKTsKPiA+ICsKPiA+ICsJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9s b2NrLCBmbGFncyk7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9j a19pc19lbmFibGVkKHN0cnVjdCBjbGtfaHcgKmh3KQo+ID4gK3sKPiA+ICsJc3RydWN0IG12ZWJ1 X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKPiA+ICsJc3RydWN0 IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KPiA+ICsJCQkJCQl0b191 YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7Cj4gPiArCXUzMiB2YWw7Cj4gPiArCj4gPiArCXZh bCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7Cj4gPiArCj4gPiArCWlmICh1YXJ0X2Ns b2NrLT5jbG9ja19pZHggPT0gMCkKPiA+ICsJCXJldHVybiAhKHZhbCAmIFVBUlQxX0NMS19ESVMp Owo+ID4gKwllbHNlCj4gPiArCQlyZXR1cm4gISh2YWwgJiBVQVJUMl9DTEtfRElTKTsKPiA+ICt9 Cj4gPiArCj4gPiArc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3NhdmVfY29udGV4dChzdHJ1 Y3QgY2xrX2h3ICpodykKPiA+ICt7Cj4gPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0 X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7Cj4gPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2Nr X2Jhc2UgKnVhcnRfY2xvY2tfYmFzZSA9Cj4gPiArCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVh cnRfY2xvY2spOwo+ID4gKwl1bnNpZ25lZCBsb25nIGZsYWdzOwo+ID4gKwo+ID4gKwlzcGluX2xv Y2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gPiArCXVhcnRfY2xvY2stPnBt X2NvbnRleHRfcmVnMSA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7Cj4gPiArCXVhcnRf Y2xvY2stPnBtX2NvbnRleHRfcmVnMiA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7Cj4g PiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ID4g Kwo+ID4gKwlyZXR1cm4gMDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgbXZlYnVfdWFy dF9jbG9ja19yZXN0b3JlX2NvbnRleHQoc3RydWN0IGNsa19odyAqaHcpCj4gPiArewo+ID4gKwlz dHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOwo+ ID4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQo+ID4g KwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKPiA+ICsJdW5zaWduZWQgbG9u ZyBmbGFnczsKPiA+ICsKPiA+ICsJc3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywg ZmxhZ3MpOwo+ID4gKwl3cml0ZWwodWFydF9jbG9jay0+cG1fY29udGV4dF9yZWcxLCB1YXJ0X2Ns b2NrX2Jhc2UtPnJlZzEpOwo+ID4gKwl3cml0ZWwodWFydF9jbG9jay0+cG1fY29udGV4dF9yZWcy LCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOwo+ID4gKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZt dmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHVuc2lnbmVk IGxvbmcgbXZlYnVfdWFydF9jbG9ja19yZWNhbGNfcmF0ZShzdHJ1Y3QgY2xrX2h3ICpodywKPiA+ ICsJCQkJCQkgIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpCj4gPiArewo+ID4gKwlzdHJ1Y3Qg bXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOwo+ID4gKwlz dHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQo+ID4gKwkJCQkJ CXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKPiA+ICsKPiA+ICsJcmV0dXJuIHBhcmVu dF9yYXRlIC8gdWFydF9jbG9ja19iYXNlLT5kaXY7Cj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBs b25nIG12ZWJ1X3VhcnRfY2xvY2tfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3ICpodywgdW5zaWdu ZWQgbG9uZyByYXRlLAo+ID4gKwkJCQkJdW5zaWduZWQgbG9uZyAqcGFyZW50X3JhdGUpCj4gPiAr ewo+ID4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xv Y2soaHcpOwo+ID4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jh c2UgPQo+ID4gKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKPiA+ICsKPiA+ ICsJcmV0dXJuICpwYXJlbnRfcmF0ZSAvIHVhcnRfY2xvY2tfYmFzZS0+ZGl2Owo+ID4gK30KPiA+ ICsKPiA+ICtzdGF0aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfc2V0X3JhdGUoc3RydWN0IGNsa19o dyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwKPiA+ICsJCQkJICAgICB1bnNpZ25lZCBsb25nIHBh cmVudF9yYXRlKQo+ID4gK3sKPiA+ICsJLyoKPiA+ICsJICogV2UgbXVzdCByZXBvcnQgc3VjY2Vz cyBidXQgd2UgY2FuIGRvIHNvIHVuY29uZGl0aW9uYWxseSBiZWNhdXNlCj4gPiArCSAqIG12ZWJ1 X3VhcnRfY2xvY2tfcm91bmRfcmF0ZSByZXR1cm5zIHZhbHVlcyB0aGF0IGVuc3VyZSB0aGlzIGNh bGwgaXMgYQo+ID4gKwkgKiBub3AuCj4gPiArCSAqLwo+ID4gKwo+ID4gKwlyZXR1cm4gMDsKPiA+ ICt9Cj4gPiArCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBjbGtfb3BzIG12ZWJ1X3VhcnRfY2xv Y2tfb3BzID0gewo+ID4gKwkucHJlcGFyZSA9IG12ZWJ1X3VhcnRfY2xvY2tfcHJlcGFyZSwKPiA+ ICsJLmVuYWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tfZW5hYmxlLAo+ID4gKwkuZGlzYWJsZSA9IG12 ZWJ1X3VhcnRfY2xvY2tfZGlzYWJsZSwKPiA+ICsJLmlzX2VuYWJsZWQgPSBtdmVidV91YXJ0X2Ns b2NrX2lzX2VuYWJsZWQsCj4gPiArCS5zYXZlX2NvbnRleHQgPSBtdmVidV91YXJ0X2Nsb2NrX3Nh dmVfY29udGV4dCwKPiA+ICsJLnJlc3RvcmVfY29udGV4dCA9IG12ZWJ1X3VhcnRfY2xvY2tfcmVz dG9yZV9jb250ZXh0LAo+ID4gKwkucm91bmRfcmF0ZSA9IG12ZWJ1X3VhcnRfY2xvY2tfcm91bmRf cmF0ZSwKPiA+ICsJLnNldF9yYXRlID0gbXZlYnVfdWFydF9jbG9ja19zZXRfcmF0ZSwKPiA+ICsJ LnJlY2FsY19yYXRlID0gbXZlYnVfdWFydF9jbG9ja19yZWNhbGNfcmF0ZSwKPiA+ICt9Owo+ID4g Kwo+ID4gK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19yZWdpc3RlcihzdHJ1Y3QgZGV2aWNl ICpkZXYsCj4gPiArCQkJCSAgICAgc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2ss Cj4gPiArCQkJCSAgICAgY29uc3QgY2hhciAqbmFtZSwKPiA+ICsJCQkJICAgICBjb25zdCBjaGFy ICpwYXJlbnRfbmFtZSkKPiA+ICt7Cj4gPiArCXN0cnVjdCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7 IH07Cj4gPiArCj4gPiArCXVhcnRfY2xvY2stPmNsa19ody5pbml0ID0gJmluaXQ7Cj4gPiArCj4g PiArCWluaXQubmFtZSA9IG5hbWU7Cj4gPiArCWluaXQub3BzID0gJm12ZWJ1X3VhcnRfY2xvY2tf b3BzOwo+ID4gKwlpbml0LmZsYWdzID0gMDsKPiA+ICsJaW5pdC5udW1fcGFyZW50cyA9IDE7Cj4g PiArCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1lOwo+ID4gKwo+ID4gKwlyZXR1cm4g ZGV2bV9jbGtfaHdfcmVnaXN0ZXIoZGV2LCAmdWFydF9jbG9jay0+Y2xrX2h3KTsKPiA+ICt9Cj4g PiArCj4gPiArc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3Byb2JlKHN0cnVjdCBwbGF0Zm9y bV9kZXZpY2UgKnBkZXYpCj4gPiArewo+ID4gKwlzdGF0aWMgY29uc3QgY2hhciAqY29uc3QgdWFy dF9jbGtfbmFtZXNbXSA9IHsgInVhcnRfMSIsICJ1YXJ0XzIiIH07Cj4gPiArCXN0YXRpYyBjb25z dCBjaGFyICpjb25zdCBwYXJlbnRfY2xrX25hbWVzW10gPSB7ICJUQkctQS1QIiwgIlRCRy1CLVAi LAo+ID4gKwkJCQkJCQkiVEJHLUEtUyIsICJUQkctQi1TIiwKPiA+ICsJCQkJCQkJInh0YWwiIH07 Cj4gPiArCXN0cnVjdCBjbGsgKnBhcmVudF9jbGtzW0FSUkFZX1NJWkUocGFyZW50X2Nsa19uYW1l cyldOwo+ID4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2U7 Cj4gPiArCXN0cnVjdCBjbGtfaHdfb25lY2VsbF9kYXRhICpod19jbGtfZGF0YTsKPiA+ICsJc3Ry dWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKPiA+ICsJaW50IGksIHBhcmVudF9jbGtfaWR4 LCByZXQ7Cj4gPiArCXVuc2lnbmVkIGxvbmcgZGl2LCByYXRlOwo+ID4gKwlzdHJ1Y3QgcmVzb3Vy Y2UgKnJlczsKPiA+ICsJdW5zaWduZWQgaW50IGQxLCBkMjsKPiA+ICsKPiA+ICsJQlVJTERfQlVH X09OKEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpICE9Cj4gPiArCQkgICAgIEFSUkFZX1NJWkUo dWFydF9jbG9ja19iYXNlLT5jbG9ja3MpKTsKPiA+ICsJQlVJTERfQlVHX09OKEFSUkFZX1NJWkUo cGFyZW50X2Nsa19uYW1lcykgIT0KPiA+ICsJCSAgICAgQVJSQVlfU0laRSh1YXJ0X2Nsb2NrX2Jh c2UtPnBhcmVudF9yYXRlcykpOwo+ID4gKwo+ID4gKwl1YXJ0X2Nsb2NrX2Jhc2UgPSBkZXZtX2t6 YWxsb2MoZGV2LAo+ID4gKwkJCQkgICAgICAgc2l6ZW9mKCp1YXJ0X2Nsb2NrX2Jhc2UpLAo+ID4g KwkJCQkgICAgICAgR0ZQX0tFUk5FTCk7Cj4gPiArCWlmICghdWFydF9jbG9ja19iYXNlKQo+ID4g KwkJcmV0dXJuIC1FTk9NRU07Cj4gPiArCj4gPiArCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJj ZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7Cj4gPiArCWlmICghcmVzKSB7Cj4gPiArCQlkZXZf ZXJyKGRldiwgIkNvdWxkbid0IGdldCBmaXJzdCByZWdpc3RlclxuIik7Cj4gPiArCQlyZXR1cm4g LUVOT0VOVDsKPiA+ICsJfQo+ID4gKwo+ID4gKwkvKgo+ID4gKwkgKiBVQVJUIENsb2NrIENvbnRy b2wgcmVnaXN0ZXIgKHJlZzEgLyBVQVJUX0JSRFYpIGlzIGluIGFkZHJlc3MgcmFuZ2UKPiA+ICsJ ICogb2YgVUFSVDEgKHN0YW5kYXJkIFVBUlQgdmFyaWFudCksIGNvbnRyb2xzIGNsb2NrIHNvdXJj ZSBhbmQgZGl2aWRlcnMKPiA+ICsJICogZm9yIGJvdGggVUFSVDEgYW5kIFVBUlQyIGFuZCBpcyBz dXBwbGllZCB2aWEgRFQgYXMgZmlyc3QgcmVzb3VyY2UuCj4gPiArCSAqIFRoZXJlZm9yZSB1c2Ug aW9yZW1hcCgpIGZ1bmN0aW9uIHJhdGhlciB0aGFuIGlvcmVtYXBfcmVzb3VyY2UoKSB0bwo+ID4g KwkgKiBhdm9pZCBjb25mbGljdHMgd2l0aCBVQVJUMSBkcml2ZXIuIEFjY2VzcyB0byBVQVJUX0JS RFYgaXMgcHJvdGVjdGVkCj4gPiArCSAqIGJ5IGxvY2sgc2hhcmVkIGJldHdlZW4gY2xvY2sgYW5k IFVBUlQgZHJpdmVyLgo+ID4gKwkgKi8KPiA+ICsJdWFydF9jbG9ja19iYXNlLT5yZWcxID0gZGV2 bV9pb3JlbWFwKGRldiwgcmVzLT5zdGFydCwKPiA+ICsJCQkJCSAgICAgcmVzb3VyY2Vfc2l6ZShy ZXMpKTsKPiA+ICsJaWYgKElTX0VSUih1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpKQo+ID4gKwkJcmV0 dXJuIFBUUl9FUlIodWFydF9jbG9ja19iYXNlLT5yZWcxKTsKPiA+ICsKPiA+ICsJcmVzID0gcGxh dGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAxKTsKPiA+ICsJaWYgKCFy ZXMpIHsKPiA+ICsJCWRldl9lcnIoZGV2LCAiQ291bGRuJ3QgZ2V0IHNlY29uZCByZWdpc3Rlclxu Iik7Cj4gPiArCQlyZXR1cm4gLUVOT0VOVDsKPiA+ICsJfQo+ID4gKwo+ID4gKwkvKgo+ID4gKwkg KiBVQVJUIDIgQmF1ZCBSYXRlIERpdmlzb3IgcmVnaXN0ZXIgKHJlZzIgLyBVQVJUX0JSRFYpIGlz IGluIGFkZHJlc3MKPiA+ICsJICogcmFuZ2Ugb2YgVUFSVDIgKGV4dGVuZGVkIFVBUlQgdmFyaWFu dCksIGNvbnRyb2xzIG9ubHkgb25lIFVBUlQyCj4gPiArCSAqIHNwZWNpZmljIGRpdmlkZXIgYW5k IGlzIHN1cHBsaWVkIHZpYSBEVCBhcyBzZWNvbmQgcmVzb3VyY2UuCj4gPiArCSAqIFRoZXJlZm9y ZSB1c2UgaW9yZW1hcCgpIGZ1bmN0aW9uIHJhdGhlciB0aGFuIGlvcmVtYXBfcmVzb3VyY2UoKSB0 bwo+ID4gKwkgKiBhdm9pZCBjb25mbGljdHMgd2l0aCBVQVJUMiBkcml2ZXIuIEFjY2VzcyB0byBV QVJUX0JSRFYgaXMgcHJvdGVjdGVkCj4gPiArCSAqIGJ5IGxvY2sgc2hhcmVkIGJldHdlZW4gY2xv Y2sgYW5kIFVBUlQgZHJpdmVyLgo+ID4gKwkgKi8KPiA+ICsJdWFydF9jbG9ja19iYXNlLT5yZWcy ID0gZGV2bV9pb3JlbWFwKGRldiwgcmVzLT5zdGFydCwKPiA+ICsJCQkJCSAgICAgcmVzb3VyY2Vf c2l6ZShyZXMpKTsKPiA+ICsJaWYgKElTX0VSUih1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpKQo+ID4g KwkJcmV0dXJuIFBUUl9FUlIodWFydF9jbG9ja19iYXNlLT5yZWcyKTsKPiA+ICsKPiA+ICsJaHdf Y2xrX2RhdGEgPSBkZXZtX2t6YWxsb2MoZGV2LAo+ID4gKwkJCQkgICBzdHJ1Y3Rfc2l6ZShod19j bGtfZGF0YSwgaHdzLAo+ID4gKwkJCQkJICAgICAgIEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMp KSwKPiA+ICsJCQkJICAgR0ZQX0tFUk5FTCk7Cj4gPiArCWlmICghaHdfY2xrX2RhdGEpCj4gPiAr CQlyZXR1cm4gLUVOT01FTTsKPiA+ICsKPiA+ICsJaHdfY2xrX2RhdGEtPm51bSA9IEFSUkFZX1NJ WkUodWFydF9jbGtfbmFtZXMpOwo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRSh1YXJ0 X2Nsa19uYW1lcyk7IGkrKykgewo+ID4gKwkJaHdfY2xrX2RhdGEtPmh3c1tpXSA9ICZ1YXJ0X2Ns b2NrX2Jhc2UtPmNsb2Nrc1tpXS5jbGtfaHc7Cj4gPiArCQl1YXJ0X2Nsb2NrX2Jhc2UtPmNsb2Nr c1tpXS5jbG9ja19pZHggPSBpOwo+ID4gKwl9Cj4gPiArCj4gPiArCXBhcmVudF9jbGtfaWR4ID0g LTE7Cj4gPiArCj4gPiArCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKHBhcmVudF9jbGtfbmFt ZXMpOyBpKyspIHsKPiA+ICsJCXBhcmVudF9jbGtzW2ldID0gZGV2bV9jbGtfZ2V0KGRldiwgcGFy ZW50X2Nsa19uYW1lc1tpXSk7Cj4gPiArCQlpZiAoSVNfRVJSKHBhcmVudF9jbGtzW2ldKSkgewo+ ID4gKwkJCWlmIChQVFJfRVJSKHBhcmVudF9jbGtzW2ldKSA9PSAtRVBST0JFX0RFRkVSKQo+ID4g KwkJCQlyZXR1cm4gLUVQUk9CRV9ERUZFUjsKPiA+ICsJCQlkZXZfd2FybihkZXYsICJDb3VsZG4n dCBnZXQgdGhlIHBhcmVudCBjbG9jayAlczogJWxkXG4iLAo+ID4gKwkJCQlwYXJlbnRfY2xrX25h bWVzW2ldLCBQVFJfRVJSKHBhcmVudF9jbGtzW2ldKSk7Cj4gPiArCQkJY29udGludWU7Cj4gPiAr CQl9Cj4gPiArCj4gPiArCQlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUocGFyZW50X2Nsa3NbaV0p Owo+ID4gKwkJaWYgKHJldCkgewo+ID4gKwkJCWRldl93YXJuKGRldiwgIkNvdWxkbid0IGVuYWJs ZSBwYXJlbnQgY2xvY2sgJXM6ICVkXG4iLAo+ID4gKwkJCQlwYXJlbnRfY2xrX25hbWVzW2ldLCBy ZXQpOwo+ID4gKwkJCWNvbnRpbnVlOwo+ID4gKwkJfQo+ID4gKwkJcmF0ZSA9IGNsa19nZXRfcmF0 ZShwYXJlbnRfY2xrc1tpXSk7Cj4gPiArCQl1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1tp XSA9IHJhdGU7Cj4gPiArCj4gPiArCQlpZiAoaSAhPSBQQVJFTlRfQ0xPQ0tfWFRBTCkgewo+ID4g KwkJCS8qCj4gPiArCQkJICogQ2FsY3VsYXRlIHRoZSBzbWFsbGVzdCBUQkcgZDEgYW5kIGQyIGRp dmlzb3JzIHRoYXQKPiA+ICsJCQkgKiBzdGlsbCBjYW4gcHJvdmlkZSA5NjAwIGJhdWRyYXRlLgo+ ID4gKwkJCSAqLwo+ID4gKwkJCWQxID0gRElWX1JPVU5EX1VQKHJhdGUsIDk2MDAgKiBPU0FNUF9E RUZBVUxUX0RJVklTT1IgKgo+ID4gKwkJCQkJCUJSRFZfQkFVRF9NQVgpOwo+ID4gKwkJCWlmIChk MSA8IDEpCj4gPiArCQkJCWQxID0gMTsKPiA+ICsJCQllbHNlIGlmIChkMSA+IENMS19UQkdfRElW MV9NQVgpCj4gPiArCQkJCWQxID0gQ0xLX1RCR19ESVYxX01BWDsKPiA+ICsKPiA+ICsJCQlkMiA9 IERJVl9ST1VORF9VUChyYXRlLCA5NjAwICogT1NBTVBfREVGQVVMVF9ESVZJU09SICoKPiA+ICsJ CQkJCQlCUkRWX0JBVURfTUFYICogZDEpOwo+ID4gKwkJCWlmIChkMiA8IDEpCj4gPiArCQkJCWQy ID0gMTsKPiA+ICsJCQllbHNlIGlmIChkMiA+IENMS19UQkdfRElWMl9NQVgpCj4gPiArCQkJCWQy ID0gQ0xLX1RCR19ESVYyX01BWDsKPiA+ICsJCX0gZWxzZSB7Cj4gPiArCQkJLyoKPiA+ICsJCQkg KiBXaGVuIFVBUlQgY2xvY2sgdXNlcyBYVEFMIGNsb2NrIGFzIGEgc291cmNlIHRoZW4gaXQKPiA+ ICsJCQkgKiBpcyBub3QgcG9zc2libGUgdG8gdXNlIGQxIGFuZCBkMiBkaXZpc29ycy4KPiA+ICsJ CQkgKi8KPiA+ICsJCQlkMSA9IGQyID0gMTsKPiA+ICsJCX0KPiA+ICsKPiA+ICsJCS8qIFNraXAg Y2xvY2sgc291cmNlIHdoaWNoIGNhbm5vdCBwcm92aWRlIDk2MDAgYmF1ZHJhdGUgKi8KPiA+ICsJ CWlmIChyYXRlID4gOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAqIEJSRFZfQkFVRF9NQVgg KiBkMSAqIGQyKQo+ID4gKwkJCWNvbnRpbnVlOwo+ID4gKwo+ID4gKwkJLyoKPiA+ICsJCSAqIENo b29zZSBUQkcgY2xvY2sgc291cmNlIHdpdGggdGhlIHNtYWxsZXN0IGRpdmlzb3JzLiBVc2UgWFRB TAo+ID4gKwkJICogY2xvY2sgc291cmNlIG9ubHkgaW4gY2FzZSBUQkcgaXMgbm90IGF2YWlsYWJs ZSBhcyBYVEFMIGNhbm5vdAo+ID4gKwkJICogYmUgdXNlZCBmb3IgYmF1ZHJhdGVzIGhpZ2hlciB0 aGFuIDIzMDQwMC4KPiA+ICsJCSAqLwo+ID4gKwkJaWYgKHBhcmVudF9jbGtfaWR4ID09IC0xIHx8 Cj4gPiArCQkgICAgKGkgIT0gUEFSRU5UX0NMT0NLX1hUQUwgJiYgZGl2ID4gZDEgKiBkMikpIHsK PiA+ICsJCQlwYXJlbnRfY2xrX2lkeCA9IGk7Cj4gPiArCQkJZGl2ID0gZDEgKiBkMjsKPiA+ICsJ CX0KPiA+ICsJfQo+ID4gKwo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShwYXJlbnRf Y2xrX25hbWVzKTsgaSsrKSB7Cj4gPiArCQlpZiAoaSA9PSBwYXJlbnRfY2xrX2lkeCB8fCBJU19F UlIocGFyZW50X2Nsa3NbaV0pKQo+ID4gKwkJCWNvbnRpbnVlOwo+ID4gKwkJY2xrX2Rpc2FibGVf dW5wcmVwYXJlKHBhcmVudF9jbGtzW2ldKTsKPiA+ICsJCWRldm1fY2xrX3B1dChkZXYsIHBhcmVu dF9jbGtzW2ldKTsKPiA+ICsJfQo+ID4gKwo+ID4gKwlpZiAocGFyZW50X2Nsa19pZHggPT0gLTEp IHsKPiA+ICsJCWRldl9lcnIoZGV2LCAiTm8gdXNhYmxlIHBhcmVudCBjbG9ja1xuIik7Cj4gPiAr CQlyZXR1cm4gLUVOT0VOVDsKPiA+ICsJfQo+ID4gKwo+ID4gKwl1YXJ0X2Nsb2NrX2Jhc2UtPnBh cmVudF9pZHggPSBwYXJlbnRfY2xrX2lkeDsKPiA+ICsJdWFydF9jbG9ja19iYXNlLT5kaXYgPSBk aXY7Cj4gPiArCj4gPiArCWRldl9ub3RpY2UoZGV2LCAiVXNpbmcgcGFyZW50IGNsb2NrICVzIGFz IGJhc2UgVUFSVCBjbG9ja1xuIiwKPiA+ICsJCSAgIF9fY2xrX2dldF9uYW1lKHBhcmVudF9jbGtz W3BhcmVudF9jbGtfaWR4XSkpOwo+ID4gKwo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0la RSh1YXJ0X2Nsa19uYW1lcyk7IGkrKykgewo+ID4gKwkJcmV0ID0gbXZlYnVfdWFydF9jbG9ja19y ZWdpc3RlcihkZXYsCj4gPiArCQkJCSZ1YXJ0X2Nsb2NrX2Jhc2UtPmNsb2Nrc1tpXSwKPiA+ICsJ CQkJdWFydF9jbGtfbmFtZXNbaV0sCj4gPiArCQkJCV9fY2xrX2dldF9uYW1lKHBhcmVudF9jbGtz W3BhcmVudF9jbGtfaWR4XSkpOwo+ID4gKwkJaWYgKHJldCkgewo+ID4gKwkJCWRldl9lcnIoZGV2 LCAiQ2FuJ3QgcmVnaXN0ZXIgVUFSVCBjbG9jayAlZDogJWRcbiIsCj4gPiArCQkJCWksIHJldCk7 Cj4gPiArCQkJcmV0dXJuIHJldDsKPiA+ICsJCX0KPiA+ICsJfQo+ID4gKwo+ID4gKwlyZXR1cm4g ZGV2bV9vZl9jbGtfYWRkX2h3X3Byb3ZpZGVyKGRldiwgb2ZfY2xrX2h3X29uZWNlbGxfZ2V0LAo+ ID4gKwkJCQkJICAgaHdfY2xrX2RhdGEpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMgY29uc3Qg c3RydWN0IG9mX2RldmljZV9pZCBtdmVidV91YXJ0X2Nsb2NrX29mX21hdGNoW10gPSB7Cj4gPiAr CXsgLmNvbXBhdGlibGUgPSAibWFydmVsbCxhcm1hZGEtMzcwMC11YXJ0LWNsb2NrIiwgfSwKPiA+ ICsJeyB9Cj4gPiArfTsKPiA+ICsKPiA+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBt dmVidV91YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZlciA9IHsKPiA+ICsJLnByb2JlID0gbXZlYnVf dWFydF9jbG9ja19wcm9iZSwKPiA+ICsJLmRyaXZlcgkJPSB7Cj4gPiArCQkubmFtZQk9ICJtdmVi dS11YXJ0LWNsb2NrIiwKPiA+ICsJCS5vZl9tYXRjaF90YWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tf b2ZfbWF0Y2gsCj4gPiArCX0sCj4gPiArfTsKPiA+ICsKPiA+ICBzdGF0aWMgaW50IF9faW5pdCBt dmVidV91YXJ0X2luaXQodm9pZCkKPiA+ICB7Cj4gPiAgCWludCByZXQ7Cj4gPiBAQCAtOTgwLDEw ICsxNDg2LDE5IEBAIHN0YXRpYyBpbnQgX19pbml0IG12ZWJ1X3VhcnRfaW5pdCh2b2lkKQo+ID4g IAlpZiAocmV0KQo+ID4gIAkJcmV0dXJuIHJldDsKPiA+ICAKPiA+ICsJcmV0ID0gcGxhdGZvcm1f ZHJpdmVyX3JlZ2lzdGVyKCZtdmVidV91YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZlcik7Cj4gPiAr CWlmIChyZXQpIHsKPiA+ICsJCXVhcnRfdW5yZWdpc3Rlcl9kcml2ZXIoJm12ZWJ1X3VhcnRfZHJp dmVyKTsKPiA+ICsJCXJldHVybiByZXQ7Cj4gPiArCX0KPiA+ICsKPiA+ICAJcmV0ID0gcGxhdGZv cm1fZHJpdmVyX3JlZ2lzdGVyKCZtdmVidV91YXJ0X3BsYXRmb3JtX2RyaXZlcik7Cj4gPiAtCWlm IChyZXQpCj4gPiArCWlmIChyZXQpIHsKPiA+ICsJCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVy KCZtdmVidV91YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZlcik7Cj4gPiAgCQl1YXJ0X3VucmVnaXN0 ZXJfZHJpdmVyKCZtdmVidV91YXJ0X2RyaXZlcik7Cj4gPiArCQlyZXR1cm4gcmV0Owo+ID4gKwl9 Cj4gPiAgCj4gPiAtCXJldHVybiByZXQ7Cj4gPiArCXJldHVybiAwOwo+ID4gIH0KPiA+ICBhcmNo X2luaXRjYWxsKG12ZWJ1X3VhcnRfaW5pdCk7Cj4gPiAtLSAKPiA+IDIuMjAuMQo+ID4KPiAKPiAt LSAKPiBHcmVnb3J5IENsZW1lbnQsIEJvb3RsaW4KPiBFbWJlZGRlZCBMaW51eCBhbmQgS2VybmVs IGVuZ2luZWVyaW5nCj4gaHR0cDovL2Jvb3RsaW4uY29tCgpfX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fXwpsaW51eC1hcm0ta2VybmVsIG1haWxpbmcgbGlzdAps aW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKaHR0cDovL2xpc3RzLmluZnJhZGVh ZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsCg==