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 4963EC433F5 for ; Wed, 13 Oct 2021 14:17:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2A75E60ED4 for ; Wed, 13 Oct 2021 14:17:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232784AbhJMOTv convert rfc822-to-8bit (ORCPT ); Wed, 13 Oct 2021 10:19:51 -0400 Received: from mslow1.mail.gandi.net ([217.70.178.240]:38173 "EHLO mslow1.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229562AbhJMOTv (ORCPT ); Wed, 13 Oct 2021 10:19:51 -0400 Received: from relay9-d.mail.gandi.net (unknown [217.70.183.199]) by mslow1.mail.gandi.net (Postfix) with ESMTP id 4CBA2D22C8; Wed, 13 Oct 2021 14:16:41 +0000 (UTC) Received: (Authenticated sender: gregory.clement@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 8E986FF816; Wed, 13 Oct 2021 14:16:16 +0000 (UTC) From: Gregory CLEMENT To: Pali =?utf-8?Q?Roh=C3=A1r?= , Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman Cc: Andrew Lunn , Sebastian Hesselbarth , Vladimir Vid , Marek =?utf-8?Q?Beh=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: Re: [PATCH v7 2/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock In-Reply-To: <20210930095838.28145-3-pali@kernel.org> References: <20210930095838.28145-1-pali@kernel.org> <20210930095838.28145-3-pali@kernel.org> Date: Wed, 13 Oct 2021 16:16:10 +0200 Message-ID: <87o87tdn85.fsf@BL-laptop> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org 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 ? I found it very unusual to have the implementation of a clok driver inside an uart driver. 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 8BF1DC433EF for ; Wed, 13 Oct 2021 14:18:03 +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 4E9BC610C8 for ; Wed, 13 Oct 2021 14:18:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 4E9BC610C8 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=bootlin.com 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:Message-ID:Date:References :In-Reply-To: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=WCpYoacrNflwoL0BS6dSpwO//lceEy5fiyfI/IobOhc=; b=U2Ay07EPkQJY/p NEQ8In6zSbrsf1GnFWZCeT0VLz7ftLVEBeCbl5pXbIKIztub4qLy1yph61VRR29767txJByM+YHvx rKUPKmM0uN0NPLYeUag14W81l8RFGkD5P1lwIx/PSoBH1T+81waP6OdaqPG9OlUR6J5P1aKVbKvC3 vsjYx6QVxsQ6+FdFFJn7PVMZ2/wLcT5MKx17PbyEqPtyLNvXedJ+3Vu1zNRXyzpN7s26SfP6miUI4 5fz0xriuplgrv9ImUqYmFizu90tALbRgBAhB8HtvthYgsfe9FVFIN91pt3UaL3bHMTpwecZRnRmci EIlfyynFkBMwULvKqk6g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1maf3W-00H67A-2s; Wed, 13 Oct 2021 14:16:30 +0000 Received: from relay9-d.mail.gandi.net ([217.70.183.199]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1maf3O-00H63j-8u for linux-arm-kernel@lists.infradead.org; Wed, 13 Oct 2021 14:16:26 +0000 Received: (Authenticated sender: gregory.clement@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 8E986FF816; Wed, 13 Oct 2021 14:16:16 +0000 (UTC) From: Gregory CLEMENT To: Pali =?utf-8?Q?Roh=C3=A1r?= , Michael Turquette , Stephen Boyd , Rob Herring , Greg Kroah-Hartman Cc: Andrew Lunn , Sebastian Hesselbarth , Vladimir Vid , Marek =?utf-8?Q?Beh=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: Re: [PATCH v7 2/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock In-Reply-To: <20210930095838.28145-3-pali@kernel.org> References: <20210930095838.28145-1-pali@kernel.org> <20210930095838.28145-3-pali@kernel.org> Date: Wed, 13 Oct 2021 16:16:10 +0200 Message-ID: <87o87tdn85.fsf@BL-laptop> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211013_071622_662482_F2AFE450 X-CRM114-Status: GOOD ( 45.83 ) 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 SGVsbG8gUGFsaSwKCj4gVGhpcyBwYXRjaCBpbXBsZW1lbnRzIGEgbmV3IGRldmljZSBkcml2ZXIg Zm9yIGNvbnRyb2xsaW5nIFVBUlQgY2xvY2tzIG9uCj4gTWFydmVsbCBBcm1hZGEgMzcwMCBTb0Mu IFRoaXMgZGV2aWNlIGRyaXZlciBpcyBsb2FkZWQgZm9yIGRldmljZXMgd2hpY2gKPiBtYXRjaCBj b21wYXRpYmxlIHN0cmluZyAibWFydmVsbCxhcm1hZGEtMzcwMC11YXJ0LWNsb2NrIi4KPgo+IFRo ZXJlIGFyZSBtb3JlIHBpdGZhbGxzIHJlbGF0ZWQgdG8gVUFSVCBjbG9ja3MuIEJvdGggVUFSVHMg dXNlIHNhbWUgYmFzZQo+IGNsb2NrIHNvdXJjZS4gQWxzbyBkaXZpc29ycyBmb3IgVEJHIGJhc2Ug Y2xvY2sgYXJlIHNoYXJlZCBiZXR3ZWVuIGJvdGgKPiBVQVJUcyBhbmQgYXJlIGNvbmZpZ3VyZWQg b25seSBmcm9tIFVBUlQxIGFkZHJlc3Mgc3BhY2UuIENsb2NrcyBjYW4gYmUKPiBlbmFibGVkIC8g ZGlzYWJsZWQgc2VwYXJhdGVseSBmb3IgVUFSVDEgYW5kIFVBUlQyLCBidXQgdGhleSBhcmUgY29u dHJvbGxlZAo+IG9ubHkgZnJvbSBVQVJUMSBhZGRyZXNzIHNwYWNlLiBNb3Jlb3ZlciBNYXJ2ZWxs IEFybWFkYSAzNzAwIEZ1bmN0aW9uYWwKPiBTcGVjaWZpY2F0aW9ucyBoYXMgc3dhcHBlZCBiaXRz IGZvciBlbmFibGluZy9kaXNhYmxpbmcgVUFSVDEgYW5kIFVBUlQyCj4gY2xvY2tzLgo+Cj4gU28g ZHJpdmVyIGZvciBjb250cm9sbGluZyBVQVJUMiBuZWVkcyB0byBoYXZlIGFjY2VzcyB0byBVQVJU MSBhZGRyZXNzIHNwYWNlCj4gYXMgVUFSVDEgYWRkcmVzcyBzcGFjZSBjb250YWlucyBzb21lIGJp dHMgZXhjbHVzaXZlbHkgdXNlZCBieSBVQVJUMiBhbmQKPiBhbHNvIGJpdHMgd2hpY2ggYXJlIHNo YXJlZCBmb3IgYm90aCBVQVJUMSBhbmQgVUFSVDIuCj4KPiBGb3IgY2hhbmdpbmcgVUFSVCBiYXNl IGNsb2NrICh3aGljaCBjb250cm9scyBib3RoIFVBUlRzKSBkdXJpbmcgYm9vdCB3aGVuCj4gVUFS VCBkcml2ZXIgaXMgbm90IHJlYWR5IGFuZCBvbmx5IGVhcmx5IGNvbnNvbGUgaXMgYWN0aXZlLCBp cyBub3Qgc2ltcGxlCj4gb3BlcmF0aW9uIGFzIGl0IGlzIHJlcXVpcmVkIHRvIGFsc28gcmVjYWxj dWxhdGUgZGl2aXNvcnMgdG8gbm90IGNoYW5nZSBVQVJUCj4gYmF1ZHJhdGUgdXNlZCBieSBlYXJs eSBjb25zb2xlLiBTbyBmb3IgdGhpcyBvcGVyYXRpb24gVUFSVDEgY2xvY2sgZHJpdmVyCj4gbmVl ZHMgdG8gYWNjZXNzIGFsc28gaW50byBhZGRyZXNzIHNwYWNlIG9mIFVBUlQyIHdoZXJlIGFyZSBy ZWdpc3RlcnMgZm9yCj4gVUFSVDIgZGl2aXNvcnMuCj4KPiBGb3IgdGhlc2UgcmVhc29ucywgdGhp cyBuZXcgZGV2aWNlIGRyaXZlciBmb3IgVUFSVCBjbG9ja3MgZG9lcyBub3QgdXNlCj4gaW9yZW1h cF9yZXNvdXJjZSgpLCBidXQgb25seSBpb3JlbWFwKCkgdG8gcHJldmVudCByZXNvdXJjZSBjb25m bGljdHMKPiBiZXR3ZWVuIFVBUlQgY2xvY2sgZHJpdmVyIGFuZCBVQVJUIGRyaXZlci4KPgo+IFNo YXJlZCBiZXR3ZWVuIGRyaXZlcnMgYXJlIG9ubHkgdHdvIDQtYnl0ZXMgcmVnaXN0ZXJzOiBVQVJU IENsb2NrIENvbnRyb2wKPiBhbmQgVUFSVCAyIEJhdWQgUmF0ZSBEaXZpc29yLiBBY2Nlc3MgdG8g dGhlc2UgdHdvIHJlZ2lzdGVycyBhcmUgcHJvdGVjdGVkCj4gYnkgb25lIHNwaW5sb2NrIHRvIHBy ZXZlbnQgYW55IGNvbmZsaWN0cy4gQWNjZXNzIGlzIHJlcXVpcmVkIG9ubHkgZHVyaW5nCj4gcHJv YmUgdGltZSwgY2hhbmdpbmcgYmF1ZHJhdGUgYW5kIGR1cmluZyBzdXNwZW5kL3Jlc3VtZS4KPgo+ IEhhcmR3YXJlIGNhbiBiZSBjb25maWd1cmVkIHRvIHVzZSBvbmUgb2YgZm9sbG93aW5nIGNsb2Nr cyBhcyBVQVJUIGJhc2UKPiBjbG9jazogVEJHLUEtUCwgVEJHLUItUCwgVEJHLUEtUywgVEJHLUIt UywgeHRhbC4gTm90IGV2ZXJ5IGNsb2NrIGlzIHVzYWJsZQo+IGZvciBoaWdoZXIgYnVhZHJhdGVz LiBJbiBEVCBub2RlIGNhbiBiZSBzcGVjaWZpZWQgYW55IHN1YnNldCBhbmQga2VybmVsCj4gY2hv b3NlIHRoZSBiZXN0IG9uZSwgd2hpY2ggc3RpbGwgc3VwcG9ydHMgcmVxdWlyZWQgYmF1ZHJhdGUg OTYwMC4gRm9yCj4gc21vb3RoIGJvb3QgbG9nIG91dHB1dCBpdCBpcyBuZWVkZWQgdG8gc3BlY2lm eSBjbG9jayB1c2VkIGJ5IGVhcmx5IGNvbnNvbGUKPiBvdGhlcndpc2UgZ2FyYmFnZSB3b3VsZCBi ZSBwdXQgb24gVUFSVCBkdXJpbmcgcHJvYmluZyBmb3IgVUFSVCBjbG9jayBkcml2ZXIKPiBhbmQg dHJhbnNpdGlvbmluZyBmcm9tIGVhcmx5IGNvbnNvbGUgdG8gbm9ybWFsIGNvbnNvbGUuCj4KPiBU aGlzIGNoYW5nZSBpcyByZXF1aXJlZCB0byBlbmFibGUgYW5kIGNvbmZpZ3VyZSBUQkcgY2xvY2sg YXMgYSBiYXNlIGNsb2NrCj4gZm9yIFVBUlQuIFRCRyBjbG9jayBpcyByZXF1aXJlZCB0byBhY2hp ZXZlIGhpZ2hlciBiYXVkcmF0ZXMgdGhhbgo+IDIzMDQwMC4KCkRpZCB5b3UgaGF2ZSBhIHJldmll dyBmcm9tIHRoZSBjbG9jayBtYWludGFpbmVyIGZvciB0aGlzIGRyaXZlciA/CgpJIGZvdW5kIGl0 IHZlcnkgdW51c3VhbCB0byBoYXZlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBhIGNsb2sgZHJpdmVy Cmluc2lkZSBhbiB1YXJ0IGRyaXZlci4KCkdyZWdvcnkKCj4KPiBTaWduZWQtb2ZmLWJ5OiBQYWxp IFJvaMOhciA8cGFsaUBrZXJuZWwub3JnPgo+IC0tLQo+ICBkcml2ZXJzL3R0eS9zZXJpYWwvS2Nv bmZpZyAgICAgIHwgICAxICsKPiAgZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYyB8IDUx OSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQo+ICAyIGZpbGVzIGNoYW5nZWQsIDUx OCBpbnNlcnRpb25zKCspLCAyIGRlbGV0aW9ucygtKQo+Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv dHR5L3NlcmlhbC9LY29uZmlnIGIvZHJpdmVycy90dHkvc2VyaWFsL0tjb25maWcKPiBpbmRleCAx MzFhNmE1ODdhY2QuLmZlMWE1NDIzMWIxOSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL3R0eS9zZXJp YWwvS2NvbmZpZwo+ICsrKyBiL2RyaXZlcnMvdHR5L3NlcmlhbC9LY29uZmlnCj4gQEAgLTE0NDQs NiArMTQ0NCw3IEBAIGNvbmZpZyBTRVJJQUxfU1RNMzJfQ09OU09MRQo+ICBjb25maWcgU0VSSUFM X01WRUJVX1VBUlQKPiAgCWJvb2wgIk1hcnZlbGwgRUJVIHNlcmlhbCBwb3J0IHN1cHBvcnQiCj4g IAlkZXBlbmRzIG9uIEFSQ0hfTVZFQlUgfHwgQ09NUElMRV9URVNUCj4gKwlkZXBlbmRzIG9uIENP TU1PTl9DTEsKPiAgCXNlbGVjdCBTRVJJQUxfQ09SRQo+ICAJaGVscAo+ICAJICBUaGlzIGRyaXZl ciBpcyBmb3IgTWFydmVsbCBFQlUgU29DJ3MgVUFSVC4gSWYgeW91IGhhdmUgYSBtYWNoaW5lCj4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMgYi9kcml2ZXJzL3R0 eS9zZXJpYWwvbXZlYnUtdWFydC5jCj4gaW5kZXggMjMxZGUyOWE2NDUyLi5mM2ZiMWYzNzE4ZjIg MTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYwo+ICsrKyBiL2Ry aXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMKPiBAQCAtOCwxMiArOCwxNCBAQAo+ICAqLwo+ ICAKPiAgI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLXByb3Zp ZGVyLmg+Cj4gICNpbmNsdWRlIDxsaW51eC9jb25zb2xlLmg+Cj4gICNpbmNsdWRlIDxsaW51eC9k ZWxheS5oPgo+ICAjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+Cj4gICNpbmNsdWRlIDxsaW51eC9p bml0Lmg+Cj4gICNpbmNsdWRlIDxsaW51eC9pby5oPgo+ICAjaW5jbHVkZSA8bGludXgvaW9wb2xs Lmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9tYXRoNjQuaD4KPiAgI2luY2x1ZGUgPGxpbnV4L29mLmg+ Cj4gICNpbmNsdWRlIDxsaW51eC9vZl9hZGRyZXNzLmg+Cj4gICNpbmNsdWRlIDxsaW51eC9vZl9k ZXZpY2UuaD4KPiBAQCAtNjgsOCArNzAsMzEgQEAKPiAgI2RlZmluZSAgU1RBVF9CUktfRVJSCQko U1RBVF9CUktfREVUIHwgU1RBVF9GUk1fRVJSIFwKPiAgCQkJCSB8IFNUQVRfUEFSX0VSUiB8IFNU QVRfT1ZSX0VSUikKPiAgCj4gKy8qCj4gKyAqIE1hcnZlbGwgQXJtYWRhIDM3MDAgRnVuY3Rpb25h bCBTcGVjaWZpY2F0aW9ucyBkZXNjcmliZXMgdGhhdCBiaXQgMjEgb2YgVUFSVAo+ICsgKiBDbG9j ayBDb250cm9sIHJlZ2lzdGVyIGNvbnRyb2xzIFVBUlQxIGFuZCBiaXQgMjAgY29udHJvbHMgVUFS VDIuIEJ1dCBpbgo+ICsgKiByZWFsaXR5IGJpdCAyMSBjb250cm9scyBVQVJUMiBhbmQgYml0IDIw IGNvbnRyb2xzIFVBUlQxLiBUaGlzIHNlZW1zIHRvIGJlIGEKPiArICogYnVnIGluIE1hcnZlbGwg ZG9jdW1lbnRhdGlvbi4gSGVuY2UgZm9sbG93aW5nIENMS19ESVMgbWFjcm9zIGFyZSBzd2FwcGVk Lgo+ICsgKi8KPiArCj4gICNkZWZpbmUgVUFSVF9CUkRWCQkweDEwCj4gKy8qIFRoZXNlIGJpdHMg YXJlIGxvY2F0ZWQgaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSBhbmQgY29udHJvbCBVQVJUMiAqLwo+ ICsjZGVmaW5lICBVQVJUMl9DTEtfRElTCQlCSVQoMjEpCj4gKy8qIFRoZXNlIGJpdHMgYXJlIGxv Y2F0ZWQgaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSBhbmQgY29udHJvbCBVQVJUMSAqLwo+ICsjZGVm aW5lICBVQVJUMV9DTEtfRElTCQlCSVQoMjApCj4gKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0ZWQg aW4gVUFSVDEgYWRkcmVzcyBzcGFjZSBhbmQgY29udHJvbCBib3RoIFVBUlRzICovCj4gKyNkZWZp bmUgIENMS19OT19YVEFMCQlCSVQoMTkpCj4gKyNkZWZpbmUgIENMS19UQkdfRElWMV9TSElGVAkx NQo+ICsjZGVmaW5lICBDTEtfVEJHX0RJVjFfTUFTSwkweDcKPiArI2RlZmluZSAgQ0xLX1RCR19E SVYxX01BWAk2Cj4gKyNkZWZpbmUgIENMS19UQkdfRElWMl9TSElGVAkxMgo+ICsjZGVmaW5lICBD TEtfVEJHX0RJVjJfTUFTSwkweDcKPiArI2RlZmluZSAgQ0xLX1RCR19ESVYyX01BWAk2Cj4gKyNk ZWZpbmUgIENMS19UQkdfU0VMX1NISUZUCTEwCj4gKyNkZWZpbmUgIENMS19UQkdfU0VMX01BU0sJ MHgzCj4gKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0ZWQgaW4gYm90aCBVQVJUcyBhZGRyZXNzIHNw YWNlICovCj4gICNkZWZpbmUgIEJSRFZfQkFVRF9NQVNLICAgICAgICAgMHgzRkYKPiArI2RlZmlu ZSAgQlJEVl9CQVVEX01BWAkJQlJEVl9CQVVEX01BU0sKPiAgCj4gICNkZWZpbmUgVUFSVF9PU0FN UAkJMHgxNAo+ICAjZGVmaW5lICBPU0FNUF9ERUZBVUxUX0RJVklTT1IJMTYKPiBAQCAtMTUzLDYg KzE3OCw4IEBAIHN0YXRpYyBzdHJ1Y3QgbXZlYnVfdWFydCAqdG9fbXZ1YXJ0KHN0cnVjdCB1YXJ0 X3BvcnQgKnBvcnQpCj4gIAo+ICBzdGF0aWMgc3RydWN0IHVhcnRfcG9ydCBtdmVidV91YXJ0X3Bv cnRzW01WRUJVX05SX1VBUlRTXTsKPiAgCj4gK3N0YXRpYyBERUZJTkVfU1BJTkxPQ0sobXZlYnVf dWFydF9sb2NrKTsKPiArCj4gIC8qIENvcmUgVUFSVCBEcml2ZXIgT3BlcmF0aW9ucyAqLwo+ICBz dGF0aWMgdW5zaWduZWQgaW50IG12ZWJ1X3VhcnRfdHhfZW1wdHkoc3RydWN0IHVhcnRfcG9ydCAq cG9ydCkKPiAgewo+IEBAIC00NDUsNiArNDcyLDcgQEAgc3RhdGljIHZvaWQgbXZlYnVfdWFydF9z aHV0ZG93bihzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0KQo+ICBzdGF0aWMgaW50IG12ZWJ1X3VhcnRf YmF1ZF9yYXRlX3NldChzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0LCB1bnNpZ25lZCBpbnQgYmF1ZCkK PiAgewo+ICAJdW5zaWduZWQgaW50IGRfZGl2aXNvciwgbV9kaXZpc29yOwo+ICsJdW5zaWduZWQg bG9uZyBmbGFnczsKPiAgCXUzMiBicmR2LCBvc2FtcDsKPiAgCj4gIAlpZiAoIXBvcnQtPnVhcnRj bGspCj4gQEAgLTQ2MywxMCArNDkxLDEyIEBAIHN0YXRpYyBpbnQgbXZlYnVfdWFydF9iYXVkX3Jh dGVfc2V0KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQsIHVuc2lnbmVkIGludCBiYXVkKQo+ICAJbV9k aXZpc29yID0gT1NBTVBfREVGQVVMVF9ESVZJU09SOwo+ICAJZF9kaXZpc29yID0gRElWX1JPVU5E X0NMT1NFU1QocG9ydC0+dWFydGNsaywgYmF1ZCAqIG1fZGl2aXNvcik7Cj4gIAo+ICsJc3Bpbl9s b2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ICAJYnJkdiA9IHJlYWRsKHBv cnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOwo+ICAJYnJkdiAmPSB+QlJEVl9CQVVEX01BU0s7Cj4g IAlicmR2IHw9IGRfZGl2aXNvcjsKPiAgCXdyaXRlbChicmR2LCBwb3J0LT5tZW1iYXNlICsgVUFS VF9CUkRWKTsKPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxh Z3MpOwo+ICAKPiAgCW9zYW1wID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfT1NBTVApOwo+ ICAJb3NhbXAgJj0gfk9TQU1QX0RJVklTT1JTX01BU0s7Cj4gQEAgLTc2Miw2ICs3OTIsNyBAQCBz dGF0aWMgaW50IG12ZWJ1X3VhcnRfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCj4gIHsKPiAg CXN0cnVjdCBtdmVidV91YXJ0ICptdnVhcnQgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiAgCXN0 cnVjdCB1YXJ0X3BvcnQgKnBvcnQgPSBtdnVhcnQtPnBvcnQ7Cj4gKwl1bnNpZ25lZCBsb25nIGZs YWdzOwo+ICAKPiAgCXVhcnRfc3VzcGVuZF9wb3J0KCZtdmVidV91YXJ0X2RyaXZlciwgcG9ydCk7 Cj4gIAo+IEBAIC03NzAsNyArODAxLDkgQEAgc3RhdGljIGludCBtdmVidV91YXJ0X3N1c3BlbmQo c3RydWN0IGRldmljZSAqZGV2KQo+ICAJbXZ1YXJ0LT5wbV9yZWdzLmN0cmwgPSByZWFkbChwb3J0 LT5tZW1iYXNlICsgVUFSVF9DVFJMKHBvcnQpKTsKPiAgCW12dWFydC0+cG1fcmVncy5pbnRyID0g cmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfSU5UUihwb3J0KSk7Cj4gIAltdnVhcnQtPnBtX3Jl Z3Muc3RhdCA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX1NUQVQpOwo+ICsJc3Bpbl9sb2Nr X2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ICAJbXZ1YXJ0LT5wbV9yZWdzLmJy ZHYgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9CUkRWKTsKPiArCXNwaW5fdW5sb2NrX2ly cXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ICAJbXZ1YXJ0LT5wbV9yZWdzLm9z YW1wID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfT1NBTVApOwo+ICAKPiAgCWRldmljZV9z ZXRfd2FrZXVwX2VuYWJsZShkZXYsIHRydWUpOwo+IEBAIC03ODIsMTMgKzgxNSwxNiBAQCBzdGF0 aWMgaW50IG12ZWJ1X3VhcnRfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKPiAgewo+ICAJc3Ry dWN0IG12ZWJ1X3VhcnQgKm12dWFydCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+ICAJc3RydWN0 IHVhcnRfcG9ydCAqcG9ydCA9IG12dWFydC0+cG9ydDsKPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7 Cj4gIAo+ICAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5yYnIsIHBvcnQtPm1lbWJhc2UgKyBVQVJU X1JCUihwb3J0KSk7Cj4gIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLnRzaCwgcG9ydC0+bWVtYmFz ZSArIFVBUlRfVFNIKHBvcnQpKTsKPiAgCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MuY3RybCwgcG9y dC0+bWVtYmFzZSArIFVBUlRfQ1RSTChwb3J0KSk7Cj4gIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdz LmludHIsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX0lOVFIocG9ydCkpOwo+ICAJd3JpdGVsKG12dWFy dC0+cG1fcmVncy5zdGF0LCBwb3J0LT5tZW1iYXNlICsgVUFSVF9TVEFUKTsKPiArCXNwaW5fbG9j a19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiAgCXdyaXRlbChtdnVhcnQtPnBt X3JlZ3MuYnJkdiwgcG9ydC0+bWVtYmFzZSArIFVBUlRfQlJEVik7Cj4gKwlzcGluX3VubG9ja19p cnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiAgCXdyaXRlbChtdnVhcnQtPnBt X3JlZ3Mub3NhbXAsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX09TQU1QKTsKPiAgCj4gIAl1YXJ0X3Jl c3VtZV9wb3J0KCZtdmVidV91YXJ0X2RyaXZlciwgcG9ydCk7Cj4gQEAgLTk3Miw2ICsxMDA4LDQ3 NiBAQCBzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBtdmVidV91YXJ0X3BsYXRmb3JtX2Ry aXZlciA9IHsKPiAgCX0sCj4gIH07Cj4gIAo+ICsvKiBUaGlzIGNvZGUgaXMgYmFzZWQgb24gY2xr LWZpeGVkLWZhY3Rvci5jIGRyaXZlciBhbmQgbW9kaWZpZWQuICovCj4gKwo+ICtzdHJ1Y3QgbXZl YnVfdWFydF9jbG9jayB7Cj4gKwlzdHJ1Y3QgY2xrX2h3IGNsa19odzsKPiArCWludCBjbG9ja19p ZHg7Cj4gKwl1MzIgcG1fY29udGV4dF9yZWcxOwo+ICsJdTMyIHBtX2NvbnRleHRfcmVnMjsKPiAr fTsKPiArCj4gK3N0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2Ugewo+ICsJc3RydWN0IG12ZWJ1 X3VhcnRfY2xvY2sgY2xvY2tzWzJdOwo+ICsJdW5zaWduZWQgaW50IHBhcmVudF9yYXRlc1s1XTsK PiArCWludCBwYXJlbnRfaWR4Owo+ICsJdW5zaWduZWQgaW50IGRpdjsKPiArCXZvaWQgX19pb21l bSAqcmVnMTsKPiArCXZvaWQgX19pb21lbSAqcmVnMjsKPiArCWJvb2wgY29uZmlndXJlZDsKPiAr fTsKPiArCj4gKyNkZWZpbmUgUEFSRU5UX0NMT0NLX1hUQUwgNAo+ICsKPiArI2RlZmluZSB0b191 YXJ0X2Nsb2NrKGh3KSBjb250YWluZXJfb2YoaHcsIHN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrLCBj bGtfaHcpCj4gKyNkZWZpbmUgdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spIGNvbnRhaW5l cl9vZih1YXJ0X2Nsb2NrLCBcCj4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlLCBjbG9j a3NbdWFydF9jbG9jay0+Y2xvY2tfaWR4XSkKPiArCj4gK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9j bG9ja19wcmVwYXJlKHN0cnVjdCBjbGtfaHcgKmh3KQo+ICt7Cj4gKwlzdHJ1Y3QgbXZlYnVfdWFy dF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOwo+ICsJc3RydWN0IG12ZWJ1 X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KPiArCQkJCQkJdG9fdWFydF9jbG9j a19iYXNlKHVhcnRfY2xvY2spOwo+ICsJdW5zaWduZWQgaW50IHByZXZfY2xvY2tfaWR4LCBwcmV2 X2Nsb2NrX3JhdGUsIHByZXZfZDFkMjsKPiArCXVuc2lnbmVkIGludCBwYXJlbnRfY2xvY2tfaWR4 LCBwYXJlbnRfY2xvY2tfcmF0ZTsKPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwl1bnNpZ25l ZCBpbnQgZDEsIGQyOwo+ICsJdTY0IGRpdmlzb3I7Cj4gKwl1MzIgdmFsOwo+ICsKPiArCS8qCj4g KwkgKiBUaGlzIGZ1bmN0aW9uIGp1c3QgcmVjb25maWd1cmVzIFVBUlQgQ2xvY2sgQ29udHJvbCBy ZWdpc3RlciAobG9jYXRlZAo+ICsJICogaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSB3aGljaCBjb250 cm9scyBib3RoIFVBUlQxIGFuZCBVQVJUMikgdG8KPiArCSAqIHNlbGVjdGVkIFVBUlQgYmFzZSBj bG9jayBhbmQgcmVjYWxjdWxhdGUgY3VycmVudCBVQVJUMS9VQVJUMiBkaXZpc29ycwo+ICsJICog aW4gdGhlaXIgYWRkcmVzcyBzcGFjZXMsIHNvIGZpbmFsIGJhdWRyYXRlIHdpbGwgbm90IGJlIGNo YW5nZWQgYnkKPiArCSAqIHN3aXRjaGluZyBVQVJUIGJhc2UgY2xvY2suIFRoaXMgaXMgcmVxdWly ZWQgb3RoZXJ3aXNlIGtlcm5lbCBib290IGxvZwo+ICsJICogc3RvcHMgd29ya2luZy4gSXQgaXMg bmVlZGVkIHRvIGVuc3VyZSB0aGF0IFVBUlQgYmF1ZHJhdGUgZG9lcyBub3QKPiArCSAqIGNoYW5n ZSBkdXJpbmcgdGhpcyBzZXR1cC4gSXQgaXMgb25lIHRpbWUgb3BlcmF0aW9uLCBzbyBiYXNlZCBv bgo+ICsJICogImNvbmZpZ3VyZWQiIG1lbWJlciB0aGlzIGZ1bmN0aW9uIGlzIHNraXBwZWQgb24g c2Vjb25kIGNhbGwuIEJlY2F1c2UKPiArCSAqIHRoaXMgVUFSVCBDbG9jayBDb250cm9sIHJlZ2lz dGVyIChVQVJUX0JSRFYpIGlzIHNoYXJlZCBiZXR3ZWVuIFVBUlQxCj4gKwkgKiBiYXVkcmF0ZSBm dW5jdGlvbiwgVUFSVDEgY2xvY2sgc2VsZWN0b3IgYW5kIFVBUlQyIGNsb2NrIHNlbGVjdG9yLAo+ ICsJICogZXZlcnkgYWNjZXNzIHRvIFVBUlRfQlJEViAocmVnMSkgbmVlZHMgdG8gYmUgcHJvdGVj dGVkIGJ5IGxvY2suCj4gKwkgKi8KPiArCj4gKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZlYnVfdWFy dF9sb2NrLCBmbGFncyk7Cj4gKwo+ICsJaWYgKHVhcnRfY2xvY2tfYmFzZS0+Y29uZmlndXJlZCkg ewo+ICsJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ ICsJCXJldHVybiAwOwo+ICsJfQo+ICsKPiArCXBhcmVudF9jbG9ja19pZHggPSB1YXJ0X2Nsb2Nr X2Jhc2UtPnBhcmVudF9pZHg7Cj4gKwlwYXJlbnRfY2xvY2tfcmF0ZSA9IHVhcnRfY2xvY2tfYmFz ZS0+cGFyZW50X3JhdGVzW3BhcmVudF9jbG9ja19pZHhdOwo+ICsKPiArCXZhbCA9IHJlYWRsKHVh cnRfY2xvY2tfYmFzZS0+cmVnMSk7Cj4gKwo+ICsJaWYgKHVhcnRfY2xvY2tfYmFzZS0+ZGl2ID4g Q0xLX1RCR19ESVYxX01BWCkgewo+ICsJCWQxID0gQ0xLX1RCR19ESVYxX01BWDsKPiArCQlkMiA9 IHVhcnRfY2xvY2tfYmFzZS0+ZGl2IC8gQ0xLX1RCR19ESVYxX01BWDsKPiArCX0gZWxzZSB7Cj4g KwkJZDEgPSB1YXJ0X2Nsb2NrX2Jhc2UtPmRpdjsKPiArCQlkMiA9IDE7Cj4gKwl9Cj4gKwo+ICsJ aWYgKHZhbCAmIENMS19OT19YVEFMKSB7Cj4gKwkJcHJldl9jbG9ja19pZHggPSAodmFsID4+IENM S19UQkdfU0VMX1NISUZUKSAmIENMS19UQkdfU0VMX01BU0s7Cj4gKwkJcHJldl9kMWQyID0gKCh2 YWwgPj4gQ0xLX1RCR19ESVYxX1NISUZUKSAmIENMS19UQkdfRElWMV9NQVNLKQo+ICsJCQkgICog KCh2YWwgPj4gQ0xLX1RCR19ESVYyX1NISUZUKSAmIENMS19UQkdfRElWMl9NQVNLKTsKPiArCX0g ZWxzZSB7Cj4gKwkJcHJldl9jbG9ja19pZHggPSBQQVJFTlRfQ0xPQ0tfWFRBTDsKPiArCQlwcmV2 X2QxZDIgPSAxOwo+ICsJfQo+ICsKPiArCS8qIE5vdGUgdGhhdCB1YXJ0X2Nsb2NrX2Jhc2UtPnBh cmVudF9yYXRlc1tpXSBtYXkgbm90IGJlIGF2YWlsYWJsZSAqLwo+ICsJcHJldl9jbG9ja19yYXRl ID0gdWFydF9jbG9ja19iYXNlLT5wYXJlbnRfcmF0ZXNbcHJldl9jbG9ja19pZHhdOwo+ICsKPiAr CS8qIFJlY2FsY3VsYXRlIFVBUlQxIGRpdmlzb3Igc28gVUFSVDEgYmF1ZHJhdGUgZG9lcyBub3Qg Y2hhbmdlICovCj4gKwlpZiAocHJldl9jbG9ja19yYXRlKSB7Cj4gKwkJZGl2aXNvciA9IERJVl9V NjRfUk9VTkRfQ0xPU0VTVCgodTY0KSh2YWwgJiBCUkRWX0JBVURfTUFTSykgKgo+ICsJCQkJCQlw YXJlbnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFkMiwKPiArCQkJCQkJcHJldl9jbG9ja19yYXRlICog ZDEgKiBkMik7Cj4gKwkJaWYgKGRpdmlzb3IgPCAxKQo+ICsJCQlkaXZpc29yID0gMTsKPiArCQll bHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVEX01BWCkKPiArCQkJZGl2aXNvciA9IEJSRFZfQkFV RF9NQVg7Cj4gKwkJdmFsID0gKHZhbCAmIH5CUkRWX0JBVURfTUFTSykgfCBkaXZpc29yOwo+ICsJ fQo+ICsKPiArCWlmIChwYXJlbnRfY2xvY2tfaWR4ICE9IFBBUkVOVF9DTE9DS19YVEFMKSB7Cj4g KwkJLyogRG8gbm90IHVzZSBYVEFMLCBzZWxlY3QgVEJHIGNsb2NrIGFuZCBUQkcgZDEgKiBkMiBk aXZpc29ycyAqLwo+ICsJCXZhbCB8PSBDTEtfTk9fWFRBTDsKPiArCQl2YWwgJj0gfihDTEtfVEJH X0RJVjFfTUFTSyA8PCBDTEtfVEJHX0RJVjFfU0hJRlQpOwo+ICsJCXZhbCB8PSBkMSA8PCBDTEtf VEJHX0RJVjFfU0hJRlQ7Cj4gKwkJdmFsICY9IH4oQ0xLX1RCR19ESVYyX01BU0sgPDwgQ0xLX1RC R19ESVYyX1NISUZUKTsKPiArCQl2YWwgfD0gZDIgPDwgQ0xLX1RCR19ESVYyX1NISUZUOwo+ICsJ CXZhbCAmPSB+KENMS19UQkdfU0VMX01BU0sgPDwgQ0xLX1RCR19TRUxfU0hJRlQpOwo+ICsJCXZh bCB8PSBwYXJlbnRfY2xvY2tfaWR4IDw8IENMS19UQkdfU0VMX1NISUZUOwo+ICsJfSBlbHNlIHsK PiArCQkvKiBVc2UgWFRBTCwgVEJHIGJpdHMgYXJlIHRoZW4gaWdub3JlZCAqLwo+ICsJCXZhbCAm PSB+Q0xLX05PX1hUQUw7Cj4gKwl9Cj4gKwo+ICsJd3JpdGVsKHZhbCwgdWFydF9jbG9ja19iYXNl LT5yZWcxKTsKPiArCj4gKwkvKiBSZWNhbGN1bGF0ZSBVQVJUMiBkaXZpc29yIHNvIFVBUlQyIGJh dWRyYXRlIGRvZXMgbm90IGNoYW5nZSAqLwo+ICsJaWYgKHByZXZfY2xvY2tfcmF0ZSkgewo+ICsJ CXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7Cj4gKwkJZGl2aXNvciA9IERJVl9V NjRfUk9VTkRfQ0xPU0VTVCgodTY0KSh2YWwgJiBCUkRWX0JBVURfTUFTSykgKgo+ICsJCQkJCQlw YXJlbnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFkMiwKPiArCQkJCQkJcHJldl9jbG9ja19yYXRlICog ZDEgKiBkMik7Cj4gKwkJaWYgKGRpdmlzb3IgPCAxKQo+ICsJCQlkaXZpc29yID0gMTsKPiArCQll bHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVEX01BWCkKPiArCQkJZGl2aXNvciA9IEJSRFZfQkFV RF9NQVg7Cj4gKwkJdmFsID0gKHZhbCAmIH5CUkRWX0JBVURfTUFTSykgfCBkaXZpc29yOwo+ICsJ CXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7Cj4gKwl9Cj4gKwo+ICsJdWFydF9j bG9ja19iYXNlLT5jb25maWd1cmVkID0gdHJ1ZTsKPiArCj4gKwlzcGluX3VubG9ja19pcnFyZXN0 b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiArc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX2VuYWJsZShzdHJ1Y3QgY2xrX2h3ICpodykK PiArewo+ICsJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Ns b2NrKGh3KTsKPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFz ZSA9Cj4gKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKPiArCXVuc2lnbmVk IGxvbmcgZmxhZ3M7Cj4gKwl1MzIgdmFsOwo+ICsKPiArCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVi dV91YXJ0X2xvY2ssIGZsYWdzKTsKPiArCj4gKwl2YWwgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2Ut PnJlZzEpOwo+ICsKPiArCWlmICh1YXJ0X2Nsb2NrLT5jbG9ja19pZHggPT0gMCkKPiArCQl2YWwg Jj0gflVBUlQxX0NMS19ESVM7Cj4gKwllbHNlCj4gKwkJdmFsICY9IH5VQVJUMl9DTEtfRElTOwo+ ICsKPiArCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7Cj4gKwo+ICsJc3Bpbl91 bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gKwo+ICsJcmV0dXJu IDA7Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG12ZWJ1X3VhcnRfY2xvY2tfZGlzYWJsZShzdHJ1 Y3QgY2xrX2h3ICpodykKPiArewo+ICsJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xv Y2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2Ug KnVhcnRfY2xvY2tfYmFzZSA9Cj4gKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2Nr KTsKPiArCXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwl1MzIgdmFsOwo+ICsKPiArCXNwaW5fbG9j a19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiArCj4gKwl2YWwgPSByZWFkbCh1 YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOwo+ICsKPiArCWlmICh1YXJ0X2Nsb2NrLT5jbG9ja19pZHgg PT0gMCkKPiArCQl2YWwgfD0gVUFSVDFfQ0xLX0RJUzsKPiArCWVsc2UKPiArCQl2YWwgfD0gVUFS VDJfQ0xLX0RJUzsKPiArCj4gKwl3cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOwo+ ICsKPiArCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfaXNfZW5hYmxlZChzdHJ1Y3Qg Y2xrX2h3ICpodykKPiArewo+ICsJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sg PSB0b191YXJ0X2Nsb2NrKGh3KTsKPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVh cnRfY2xvY2tfYmFzZSA9Cj4gKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsK PiArCXUzMiB2YWw7Cj4gKwo+ICsJdmFsID0gcmVhZGwodWFydF9jbG9ja19iYXNlLT5yZWcxKTsK PiArCj4gKwlpZiAodWFydF9jbG9jay0+Y2xvY2tfaWR4ID09IDApCj4gKwkJcmV0dXJuICEodmFs ICYgVUFSVDFfQ0xLX0RJUyk7Cj4gKwllbHNlCj4gKwkJcmV0dXJuICEodmFsICYgVUFSVDJfQ0xL X0RJUyk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19zYXZlX2NvbnRl eHQoc3RydWN0IGNsa19odyAqaHcpCj4gK3sKPiArCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1 YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7Cj4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9j a19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQo+ICsJCQkJCQl0b191YXJ0X2Nsb2NrX2Jhc2UodWFy dF9jbG9jayk7Cj4gKwl1bnNpZ25lZCBsb25nIGZsYWdzOwo+ICsKPiArCXNwaW5fbG9ja19pcnFz YXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKPiArCXVhcnRfY2xvY2stPnBtX2NvbnRleHRf cmVnMSA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7Cj4gKwl1YXJ0X2Nsb2NrLT5wbV9j b250ZXh0X3JlZzIgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOwo+ICsJc3Bpbl91bmxv Y2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIG12ZWJ1X3VhcnRfY2xvY2tfcmVzdG9yZV9jb250ZXh0 KHN0cnVjdCBjbGtfaHcgKmh3KQo+ICt7Cj4gKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFy dF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOwo+ICsJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tf YmFzZSAqdWFydF9jbG9ja19iYXNlID0KPiArCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRf Y2xvY2spOwo+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsKPiArCj4gKwlzcGluX2xvY2tfaXJxc2F2 ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7Cj4gKwl3cml0ZWwodWFydF9jbG9jay0+cG1fY29u dGV4dF9yZWcxLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOwo+ICsJd3JpdGVsKHVhcnRfY2xvY2st PnBtX2NvbnRleHRfcmVnMiwgdWFydF9jbG9ja19iYXNlLT5yZWcyKTsKPiArCXNwaW5fdW5sb2Nr X2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg dW5zaWduZWQgbG9uZyBtdmVidV91YXJ0X2Nsb2NrX3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcg Kmh3LAo+ICsJCQkJCQkgIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpCj4gK3sKPiArCXN0cnVj dCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7Cj4gKwlz dHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQo+ICsJCQkJCQl0 b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7Cj4gKwo+ICsJcmV0dXJuIHBhcmVudF9yYXRl IC8gdWFydF9jbG9ja19iYXNlLT5kaXY7Cj4gK30KPiArCj4gK3N0YXRpYyBsb25nIG12ZWJ1X3Vh cnRfY2xvY2tfcm91bmRfcmF0ZShzdHJ1Y3QgY2xrX2h3ICpodywgdW5zaWduZWQgbG9uZyByYXRl LAo+ICsJCQkJCXVuc2lnbmVkIGxvbmcgKnBhcmVudF9yYXRlKQo+ICt7Cj4gKwlzdHJ1Y3QgbXZl YnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOwo+ICsJc3RydWN0 IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KPiArCQkJCQkJdG9fdWFy dF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOwo+ICsKPiArCXJldHVybiAqcGFyZW50X3JhdGUgLyB1 YXJ0X2Nsb2NrX2Jhc2UtPmRpdjsKPiArfQo+ICsKPiArc3RhdGljIGludCBtdmVidV91YXJ0X2Ns b2NrX3NldF9yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LCB1bnNpZ25lZCBsb25nIHJhdGUsCj4gKwkJ CQkgICAgIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUpCj4gK3sKPiArCS8qCj4gKwkgKiBXZSBt dXN0IHJlcG9ydCBzdWNjZXNzIGJ1dCB3ZSBjYW4gZG8gc28gdW5jb25kaXRpb25hbGx5IGJlY2F1 c2UKPiArCSAqIG12ZWJ1X3VhcnRfY2xvY2tfcm91bmRfcmF0ZSByZXR1cm5zIHZhbHVlcyB0aGF0 IGVuc3VyZSB0aGlzIGNhbGwgaXMgYQo+ICsJICogbm9wLgo+ICsJICovCj4gKwo+ICsJcmV0dXJu IDA7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xrX29wcyBtdmVidV91YXJ0X2Ns b2NrX29wcyA9IHsKPiArCS5wcmVwYXJlID0gbXZlYnVfdWFydF9jbG9ja19wcmVwYXJlLAo+ICsJ LmVuYWJsZSA9IG12ZWJ1X3VhcnRfY2xvY2tfZW5hYmxlLAo+ICsJLmRpc2FibGUgPSBtdmVidV91 YXJ0X2Nsb2NrX2Rpc2FibGUsCj4gKwkuaXNfZW5hYmxlZCA9IG12ZWJ1X3VhcnRfY2xvY2tfaXNf ZW5hYmxlZCwKPiArCS5zYXZlX2NvbnRleHQgPSBtdmVidV91YXJ0X2Nsb2NrX3NhdmVfY29udGV4 dCwKPiArCS5yZXN0b3JlX2NvbnRleHQgPSBtdmVidV91YXJ0X2Nsb2NrX3Jlc3RvcmVfY29udGV4 dCwKPiArCS5yb3VuZF9yYXRlID0gbXZlYnVfdWFydF9jbG9ja19yb3VuZF9yYXRlLAo+ICsJLnNl dF9yYXRlID0gbXZlYnVfdWFydF9jbG9ja19zZXRfcmF0ZSwKPiArCS5yZWNhbGNfcmF0ZSA9IG12 ZWJ1X3VhcnRfY2xvY2tfcmVjYWxjX3JhdGUsCj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IG12ZWJ1 X3VhcnRfY2xvY2tfcmVnaXN0ZXIoc3RydWN0IGRldmljZSAqZGV2LAo+ICsJCQkJICAgICBzdHJ1 Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jaywKPiArCQkJCSAgICAgY29uc3QgY2hhciAq bmFtZSwKPiArCQkJCSAgICAgY29uc3QgY2hhciAqcGFyZW50X25hbWUpCj4gK3sKPiArCXN0cnVj dCBjbGtfaW5pdF9kYXRhIGluaXQgPSB7IH07Cj4gKwo+ICsJdWFydF9jbG9jay0+Y2xrX2h3Lmlu aXQgPSAmaW5pdDsKPiArCj4gKwlpbml0Lm5hbWUgPSBuYW1lOwo+ICsJaW5pdC5vcHMgPSAmbXZl YnVfdWFydF9jbG9ja19vcHM7Cj4gKwlpbml0LmZsYWdzID0gMDsKPiArCWluaXQubnVtX3BhcmVu dHMgPSAxOwo+ICsJaW5pdC5wYXJlbnRfbmFtZXMgPSAmcGFyZW50X25hbWU7Cj4gKwo+ICsJcmV0 dXJuIGRldm1fY2xrX2h3X3JlZ2lzdGVyKGRldiwgJnVhcnRfY2xvY2stPmNsa19odyk7Cj4gK30K PiArCj4gK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19wcm9iZShzdHJ1Y3QgcGxhdGZvcm1f ZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlzdGF0aWMgY29uc3QgY2hhciAqY29uc3QgdWFydF9jbGtf bmFtZXNbXSA9IHsgInVhcnRfMSIsICJ1YXJ0XzIiIH07Cj4gKwlzdGF0aWMgY29uc3QgY2hhciAq Y29uc3QgcGFyZW50X2Nsa19uYW1lc1tdID0geyAiVEJHLUEtUCIsICJUQkctQi1QIiwKPiArCQkJ CQkJCSJUQkctQS1TIiwgIlRCRy1CLVMiLAo+ICsJCQkJCQkJInh0YWwiIH07Cj4gKwlzdHJ1Y3Qg Y2xrICpwYXJlbnRfY2xrc1tBUlJBWV9TSVpFKHBhcmVudF9jbGtfbmFtZXMpXTsKPiArCXN0cnVj dCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZTsKPiArCXN0cnVjdCBjbGtf aHdfb25lY2VsbF9kYXRhICpod19jbGtfZGF0YTsKPiArCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZw ZGV2LT5kZXY7Cj4gKwlpbnQgaSwgcGFyZW50X2Nsa19pZHgsIHJldDsKPiArCXVuc2lnbmVkIGxv bmcgZGl2LCByYXRlOwo+ICsJc3RydWN0IHJlc291cmNlICpyZXM7Cj4gKwl1bnNpZ25lZCBpbnQg ZDEsIGQyOwo+ICsKPiArCUJVSUxEX0JVR19PTihBUlJBWV9TSVpFKHVhcnRfY2xrX25hbWVzKSAh PQo+ICsJCSAgICAgQVJSQVlfU0laRSh1YXJ0X2Nsb2NrX2Jhc2UtPmNsb2NrcykpOwo+ICsJQlVJ TERfQlVHX09OKEFSUkFZX1NJWkUocGFyZW50X2Nsa19uYW1lcykgIT0KPiArCQkgICAgIEFSUkFZ X1NJWkUodWFydF9jbG9ja19iYXNlLT5wYXJlbnRfcmF0ZXMpKTsKPiArCj4gKwl1YXJ0X2Nsb2Nr X2Jhc2UgPSBkZXZtX2t6YWxsb2MoZGV2LAo+ICsJCQkJICAgICAgIHNpemVvZigqdWFydF9jbG9j a19iYXNlKSwKPiArCQkJCSAgICAgICBHRlBfS0VSTkVMKTsKPiArCWlmICghdWFydF9jbG9ja19i YXNlKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNv dXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCk7Cj4gKwlpZiAoIXJlcykgewo+ICsJCWRldl9l cnIoZGV2LCAiQ291bGRuJ3QgZ2V0IGZpcnN0IHJlZ2lzdGVyXG4iKTsKPiArCQlyZXR1cm4gLUVO T0VOVDsKPiArCX0KPiArCj4gKwkvKgo+ICsJICogVUFSVCBDbG9jayBDb250cm9sIHJlZ2lzdGVy IChyZWcxIC8gVUFSVF9CUkRWKSBpcyBpbiBhZGRyZXNzIHJhbmdlCj4gKwkgKiBvZiBVQVJUMSAo c3RhbmRhcmQgVUFSVCB2YXJpYW50KSwgY29udHJvbHMgY2xvY2sgc291cmNlIGFuZCBkaXZpZGVy cwo+ICsJICogZm9yIGJvdGggVUFSVDEgYW5kIFVBUlQyIGFuZCBpcyBzdXBwbGllZCB2aWEgRFQg YXMgZmlyc3QgcmVzb3VyY2UuCj4gKwkgKiBUaGVyZWZvcmUgdXNlIGlvcmVtYXAoKSBmdW5jdGlv biByYXRoZXIgdGhhbiBpb3JlbWFwX3Jlc291cmNlKCkgdG8KPiArCSAqIGF2b2lkIGNvbmZsaWN0 cyB3aXRoIFVBUlQxIGRyaXZlci4gQWNjZXNzIHRvIFVBUlRfQlJEViBpcyBwcm90ZWN0ZWQKPiAr CSAqIGJ5IGxvY2sgc2hhcmVkIGJldHdlZW4gY2xvY2sgYW5kIFVBUlQgZHJpdmVyLgo+ICsJICov Cj4gKwl1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEgPSBkZXZtX2lvcmVtYXAoZGV2LCByZXMtPnN0YXJ0 LAo+ICsJCQkJCSAgICAgcmVzb3VyY2Vfc2l6ZShyZXMpKTsKPiArCWlmIChJU19FUlIodWFydF9j bG9ja19iYXNlLT5yZWcxKSkKPiArCQlyZXR1cm4gUFRSX0VSUih1YXJ0X2Nsb2NrX2Jhc2UtPnJl ZzEpOwo+ICsKPiArCXJlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNF X01FTSwgMSk7Cj4gKwlpZiAoIXJlcykgewo+ICsJCWRldl9lcnIoZGV2LCAiQ291bGRuJ3QgZ2V0 IHNlY29uZCByZWdpc3RlclxuIik7Cj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwl9Cj4gKwo+ICsJ LyoKPiArCSAqIFVBUlQgMiBCYXVkIFJhdGUgRGl2aXNvciByZWdpc3RlciAocmVnMiAvIFVBUlRf QlJEVikgaXMgaW4gYWRkcmVzcwo+ICsJICogcmFuZ2Ugb2YgVUFSVDIgKGV4dGVuZGVkIFVBUlQg dmFyaWFudCksIGNvbnRyb2xzIG9ubHkgb25lIFVBUlQyCj4gKwkgKiBzcGVjaWZpYyBkaXZpZGVy IGFuZCBpcyBzdXBwbGllZCB2aWEgRFQgYXMgc2Vjb25kIHJlc291cmNlLgo+ICsJICogVGhlcmVm b3JlIHVzZSBpb3JlbWFwKCkgZnVuY3Rpb24gcmF0aGVyIHRoYW4gaW9yZW1hcF9yZXNvdXJjZSgp IHRvCj4gKwkgKiBhdm9pZCBjb25mbGljdHMgd2l0aCBVQVJUMiBkcml2ZXIuIEFjY2VzcyB0byBV QVJUX0JSRFYgaXMgcHJvdGVjdGVkCj4gKwkgKiBieSBsb2NrIHNoYXJlZCBiZXR3ZWVuIGNsb2Nr IGFuZCBVQVJUIGRyaXZlci4KPiArCSAqLwo+ICsJdWFydF9jbG9ja19iYXNlLT5yZWcyID0gZGV2 bV9pb3JlbWFwKGRldiwgcmVzLT5zdGFydCwKPiArCQkJCQkgICAgIHJlc291cmNlX3NpemUocmVz KSk7Cj4gKwlpZiAoSVNfRVJSKHVhcnRfY2xvY2tfYmFzZS0+cmVnMikpCj4gKwkJcmV0dXJuIFBU Ul9FUlIodWFydF9jbG9ja19iYXNlLT5yZWcyKTsKPiArCj4gKwlod19jbGtfZGF0YSA9IGRldm1f a3phbGxvYyhkZXYsCj4gKwkJCQkgICBzdHJ1Y3Rfc2l6ZShod19jbGtfZGF0YSwgaHdzLAo+ICsJ CQkJCSAgICAgICBBUlJBWV9TSVpFKHVhcnRfY2xrX25hbWVzKSksCj4gKwkJCQkgICBHRlBfS0VS TkVMKTsKPiArCWlmICghaHdfY2xrX2RhdGEpCj4gKwkJcmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJ aHdfY2xrX2RhdGEtPm51bSA9IEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpOwo+ICsJZm9yIChp ID0gMDsgaSA8IEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpOyBpKyspIHsKPiArCQlod19jbGtf ZGF0YS0+aHdzW2ldID0gJnVhcnRfY2xvY2tfYmFzZS0+Y2xvY2tzW2ldLmNsa19odzsKPiArCQl1 YXJ0X2Nsb2NrX2Jhc2UtPmNsb2Nrc1tpXS5jbG9ja19pZHggPSBpOwo+ICsJfQo+ICsKPiArCXBh cmVudF9jbGtfaWR4ID0gLTE7Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUocGFy ZW50X2Nsa19uYW1lcyk7IGkrKykgewo+ICsJCXBhcmVudF9jbGtzW2ldID0gZGV2bV9jbGtfZ2V0 KGRldiwgcGFyZW50X2Nsa19uYW1lc1tpXSk7Cj4gKwkJaWYgKElTX0VSUihwYXJlbnRfY2xrc1tp XSkpIHsKPiArCQkJaWYgKFBUUl9FUlIocGFyZW50X2Nsa3NbaV0pID09IC1FUFJPQkVfREVGRVIp Cj4gKwkJCQlyZXR1cm4gLUVQUk9CRV9ERUZFUjsKPiArCQkJZGV2X3dhcm4oZGV2LCAiQ291bGRu J3QgZ2V0IHRoZSBwYXJlbnQgY2xvY2sgJXM6ICVsZFxuIiwKPiArCQkJCXBhcmVudF9jbGtfbmFt ZXNbaV0sIFBUUl9FUlIocGFyZW50X2Nsa3NbaV0pKTsKPiArCQkJY29udGludWU7Cj4gKwkJfQo+ ICsKPiArCQlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUocGFyZW50X2Nsa3NbaV0pOwo+ICsJCWlm IChyZXQpIHsKPiArCQkJZGV2X3dhcm4oZGV2LCAiQ291bGRuJ3QgZW5hYmxlIHBhcmVudCBjbG9j ayAlczogJWRcbiIsCj4gKwkJCQlwYXJlbnRfY2xrX25hbWVzW2ldLCByZXQpOwo+ICsJCQljb250 aW51ZTsKPiArCQl9Cj4gKwkJcmF0ZSA9IGNsa19nZXRfcmF0ZShwYXJlbnRfY2xrc1tpXSk7Cj4g KwkJdWFydF9jbG9ja19iYXNlLT5wYXJlbnRfcmF0ZXNbaV0gPSByYXRlOwo+ICsKPiArCQlpZiAo aSAhPSBQQVJFTlRfQ0xPQ0tfWFRBTCkgewo+ICsJCQkvKgo+ICsJCQkgKiBDYWxjdWxhdGUgdGhl IHNtYWxsZXN0IFRCRyBkMSBhbmQgZDIgZGl2aXNvcnMgdGhhdAo+ICsJCQkgKiBzdGlsbCBjYW4g cHJvdmlkZSA5NjAwIGJhdWRyYXRlLgo+ICsJCQkgKi8KPiArCQkJZDEgPSBESVZfUk9VTkRfVVAo cmF0ZSwgOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAqCj4gKwkJCQkJCUJSRFZfQkFVRF9N QVgpOwo+ICsJCQlpZiAoZDEgPCAxKQo+ICsJCQkJZDEgPSAxOwo+ICsJCQllbHNlIGlmIChkMSA+ IENMS19UQkdfRElWMV9NQVgpCj4gKwkJCQlkMSA9IENMS19UQkdfRElWMV9NQVg7Cj4gKwo+ICsJ CQlkMiA9IERJVl9ST1VORF9VUChyYXRlLCA5NjAwICogT1NBTVBfREVGQVVMVF9ESVZJU09SICoK PiArCQkJCQkJQlJEVl9CQVVEX01BWCAqIGQxKTsKPiArCQkJaWYgKGQyIDwgMSkKPiArCQkJCWQy ID0gMTsKPiArCQkJZWxzZSBpZiAoZDIgPiBDTEtfVEJHX0RJVjJfTUFYKQo+ICsJCQkJZDIgPSBD TEtfVEJHX0RJVjJfTUFYOwo+ICsJCX0gZWxzZSB7Cj4gKwkJCS8qCj4gKwkJCSAqIFdoZW4gVUFS VCBjbG9jayB1c2VzIFhUQUwgY2xvY2sgYXMgYSBzb3VyY2UgdGhlbiBpdAo+ICsJCQkgKiBpcyBu b3QgcG9zc2libGUgdG8gdXNlIGQxIGFuZCBkMiBkaXZpc29ycy4KPiArCQkJICovCj4gKwkJCWQx ID0gZDIgPSAxOwo+ICsJCX0KPiArCj4gKwkJLyogU2tpcCBjbG9jayBzb3VyY2Ugd2hpY2ggY2Fu bm90IHByb3ZpZGUgOTYwMCBiYXVkcmF0ZSAqLwo+ICsJCWlmIChyYXRlID4gOTYwMCAqIE9TQU1Q X0RFRkFVTFRfRElWSVNPUiAqIEJSRFZfQkFVRF9NQVggKiBkMSAqIGQyKQo+ICsJCQljb250aW51 ZTsKPiArCj4gKwkJLyoKPiArCQkgKiBDaG9vc2UgVEJHIGNsb2NrIHNvdXJjZSB3aXRoIHRoZSBz bWFsbGVzdCBkaXZpc29ycy4gVXNlIFhUQUwKPiArCQkgKiBjbG9jayBzb3VyY2Ugb25seSBpbiBj YXNlIFRCRyBpcyBub3QgYXZhaWxhYmxlIGFzIFhUQUwgY2Fubm90Cj4gKwkJICogYmUgdXNlZCBm b3IgYmF1ZHJhdGVzIGhpZ2hlciB0aGFuIDIzMDQwMC4KPiArCQkgKi8KPiArCQlpZiAocGFyZW50 X2Nsa19pZHggPT0gLTEgfHwKPiArCQkgICAgKGkgIT0gUEFSRU5UX0NMT0NLX1hUQUwgJiYgZGl2 ID4gZDEgKiBkMikpIHsKPiArCQkJcGFyZW50X2Nsa19pZHggPSBpOwo+ICsJCQlkaXYgPSBkMSAq IGQyOwo+ICsJCX0KPiArCX0KPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShwYXJl bnRfY2xrX25hbWVzKTsgaSsrKSB7Cj4gKwkJaWYgKGkgPT0gcGFyZW50X2Nsa19pZHggfHwgSVNf RVJSKHBhcmVudF9jbGtzW2ldKSkKPiArCQkJY29udGludWU7Cj4gKwkJY2xrX2Rpc2FibGVfdW5w cmVwYXJlKHBhcmVudF9jbGtzW2ldKTsKPiArCQlkZXZtX2Nsa19wdXQoZGV2LCBwYXJlbnRfY2xr c1tpXSk7Cj4gKwl9Cj4gKwo+ICsJaWYgKHBhcmVudF9jbGtfaWR4ID09IC0xKSB7Cj4gKwkJZGV2 X2VycihkZXYsICJObyB1c2FibGUgcGFyZW50IGNsb2NrXG4iKTsKPiArCQlyZXR1cm4gLUVOT0VO VDsKPiArCX0KPiArCj4gKwl1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9pZHggPSBwYXJlbnRfY2xr X2lkeDsKPiArCXVhcnRfY2xvY2tfYmFzZS0+ZGl2ID0gZGl2Owo+ICsKPiArCWRldl9ub3RpY2Uo ZGV2LCAiVXNpbmcgcGFyZW50IGNsb2NrICVzIGFzIGJhc2UgVUFSVCBjbG9ja1xuIiwKPiArCQkg ICBfX2Nsa19nZXRfbmFtZShwYXJlbnRfY2xrc1twYXJlbnRfY2xrX2lkeF0pKTsKPiArCj4gKwlm b3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRSh1YXJ0X2Nsa19uYW1lcyk7IGkrKykgewo+ICsJCXJl dCA9IG12ZWJ1X3VhcnRfY2xvY2tfcmVnaXN0ZXIoZGV2LAo+ICsJCQkJJnVhcnRfY2xvY2tfYmFz ZS0+Y2xvY2tzW2ldLAo+ICsJCQkJdWFydF9jbGtfbmFtZXNbaV0sCj4gKwkJCQlfX2Nsa19nZXRf bmFtZShwYXJlbnRfY2xrc1twYXJlbnRfY2xrX2lkeF0pKTsKPiArCQlpZiAocmV0KSB7Cj4gKwkJ CWRldl9lcnIoZGV2LCAiQ2FuJ3QgcmVnaXN0ZXIgVUFSVCBjbG9jayAlZDogJWRcbiIsCj4gKwkJ CQlpLCByZXQpOwo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCX0KPiArCX0KPiArCj4gKwlyZXR1cm4g ZGV2bV9vZl9jbGtfYWRkX2h3X3Byb3ZpZGVyKGRldiwgb2ZfY2xrX2h3X29uZWNlbGxfZ2V0LAo+ ICsJCQkJCSAgIGh3X2Nsa19kYXRhKTsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBv Zl9kZXZpY2VfaWQgbXZlYnVfdWFydF9jbG9ja19vZl9tYXRjaFtdID0gewo+ICsJeyAuY29tcGF0 aWJsZSA9ICJtYXJ2ZWxsLGFybWFkYS0zNzAwLXVhcnQtY2xvY2siLCB9LAo+ICsJeyB9Cj4gK307 Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBtdmVidV91YXJ0X2Nsb2NrX3Bs YXRmb3JtX2RyaXZlciA9IHsKPiArCS5wcm9iZSA9IG12ZWJ1X3VhcnRfY2xvY2tfcHJvYmUsCj4g KwkuZHJpdmVyCQk9IHsKPiArCQkubmFtZQk9ICJtdmVidS11YXJ0LWNsb2NrIiwKPiArCQkub2Zf bWF0Y2hfdGFibGUgPSBtdmVidV91YXJ0X2Nsb2NrX29mX21hdGNoLAo+ICsJfSwKPiArfTsKPiAr Cj4gIHN0YXRpYyBpbnQgX19pbml0IG12ZWJ1X3VhcnRfaW5pdCh2b2lkKQo+ICB7Cj4gIAlpbnQg cmV0Owo+IEBAIC05ODAsMTAgKzE0ODYsMTkgQEAgc3RhdGljIGludCBfX2luaXQgbXZlYnVfdWFy dF9pbml0KHZvaWQpCj4gIAlpZiAocmV0KQo+ICAJCXJldHVybiByZXQ7Cj4gIAo+ICsJcmV0ID0g cGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVyKCZtdmVidV91YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZl cik7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJdWFydF91bnJlZ2lzdGVyX2RyaXZlcigmbXZlYnVfdWFy dF9kcml2ZXIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICAJcmV0ID0gcGxhdGZvcm1f ZHJpdmVyX3JlZ2lzdGVyKCZtdmVidV91YXJ0X3BsYXRmb3JtX2RyaXZlcik7Cj4gLQlpZiAocmV0 KQo+ICsJaWYgKHJldCkgewo+ICsJCXBsYXRmb3JtX2RyaXZlcl91bnJlZ2lzdGVyKCZtdmVidV91 YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZlcik7Cj4gIAkJdWFydF91bnJlZ2lzdGVyX2RyaXZlcigm bXZlYnVfdWFydF9kcml2ZXIpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gIAo+IC0JcmV0dXJu IHJldDsKPiArCXJldHVybiAwOwo+ICB9Cj4gIGFyY2hfaW5pdGNhbGwobXZlYnVfdWFydF9pbml0 KTsKPiAtLSAKPiAyLjIwLjEKPgoKLS0gCkdyZWdvcnkgQ2xlbWVudCwgQm9vdGxpbgpFbWJlZGRl ZCBMaW51eCBhbmQgS2VybmVsIGVuZ2luZWVyaW5nCmh0dHA6Ly9ib290bGluLmNvbQoKX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5l bCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6 Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=