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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15C69C433FE for ; Fri, 11 Feb 2022 19:13:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1350492AbiBKTNC (ORCPT ); Fri, 11 Feb 2022 14:13:02 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:39670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346625AbiBKTMy (ORCPT ); Fri, 11 Feb 2022 14:12:54 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 85E9838F; Fri, 11 Feb 2022 11:12:51 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 16A7761F40; Fri, 11 Feb 2022 19:12:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4FC07C340F0; Fri, 11 Feb 2022 19:12:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1644606770; bh=/CHCxS/xFV985M7WTg7mDvHkZaKIjAXfsV3msKFVdgo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dDtEYva4tcV4zI1gSUcRQDln7MD3ZUpkvlBTiedMMpBQcgH2iJhWzlK8+lI9MXl4b qR9mfnLLRP1arT2xAcHKnUMDxN9RFha+hgdEG+iUvy9PJwZAIIvmuqd2vUGgCwPEWR g7aZqLOHr94IRrCaLYiGhKOw3kM9KkY1StrrWO7CHvS7b8rM+cV+VfKVCa5eaa/C7I 76bhcfvCGY/0NYK0G6Uxcqj1qH/u1P+tAlhSlRiAvxk51fNpRy3FeTTIF4ZCkhne7L SdtHIBfxvW7mzegqY6c7wIJ/RkVZUnMGtezyt900adZQf194RdIjboLsmy9YCR4/wM yrVqn27YXO/dQ== From: =?UTF-8?q?Marek=20Beh=C3=BAn?= To: Stephen Boyd , Michael Turquette , Greg Kroah-Hartman , Gregory Clement Cc: =?UTF-8?q?Pali=20Roh=C3=A1r?= , linux-clk@vger.kernel.org, linux-serial@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Marek=20Beh=C3=BAn?= Subject: [PATCH v8 3/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Fri, 11 Feb 2022 20:12:35 +0100 Message-Id: <20220211191238.2142-4-kabel@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220211191238.2142-1-kabel@kernel.org> References: <20220211191238.2142-1-kabel@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org From: Pali Rohár Implement a new device driver for controlling UART clocks on Marvell Armada 3700 SoC. This device driver is loaded for devices which match the compatible string "marvell,armada-3700-uart-clock". There are more pitfalls related to UART clocks: - both UARTs use same parent clock source (which can be xtal or one of the TBG clocks), - if a TBG clock is used as the parent clock, there are two additional divisors that can both be configured to divide the rate by 1, 2, ... 6, but these divisors are again shared between the two UART controllers on the SOC, - the configuration of the parent clock source and divisors is done in the address space of the first UART controller, UART1. Clocks can be gated separately for UART1 and UART2, but this setting also lives in the address space of UART1, - Marvell's Functional Specification for Armada 3720 document has the clock gating bits swapped, so the one described to gate UART1 clock actually gates UART2 and vice versa, - each UART has it's own "special divisor", and this uses the parent clock described above. These divisors are configure in each UART's address space separately. Thus the driver for UART2 controller needs to have access to UART1 address space, since UART1 address space contains some bits exclusive for UART2 and also some bits which are shared between UART1 and UART2. Also, during boot, when early console is active on one of the UARTs, and we want to switch parent clock from xtal (default) to TBG (to be more flexible with baudrates), the driver changing UART clocks also needs to be able to change the "special divisor", so that the baudrate of earlycon is not changed when swtiching to normal console. Thus the clock driver also needs to be able to access UART2 register space, for UART2's "special divisor". For these reasons, this new UART clock driver does not use ioremap_resource(), but only ioremap() to prevent resource conflicts between UART clock driver and UART driver. === We need to share only two 32-bit registers between the UART driver and the UART clock driver: - UART Clock Control - UART 2 Baud Rate Divisor Access to these two registers are protected by one spinlock to prevent any conflicts. Access is required only during probing, when changing baudrate or during suspend/resume. Hardware can be configured to use one of following clocks as UART parent clock: TBG-A-P, TBG-B-P, TBG-A-S, TBG-B-S, xtal. Not every clock is usable for higher buadrates. Any subset can be specified in the device-tree and the driver will choose the best one which also still supports the mandatory baudrate of 9600 Bd. For smooth boot log output it is needed to specify clock used by early console, otherwise garbage would be printed on UART during probe of UART clock driver and transitioning from early console to normal console. We are implementing this to be able to configure TBG clock as UART parent clock, which is required to be able to achieve higher baudrates than 230400 Bd. We achieve this by referencing this new UART clock device node in UART's device node. UART clock device driver automatically chooses the best clock source for UART driver. Until now, UART's device-tree node needed to reference one of the static clocks (xtal or one of the TBGs) as parent clock in the `clocks` phandle - the parent clock which was configured before booting the kernel. If bootloader changed UART's parent clock, it needed to change the `clocks` phandle in DTB correspondingly before booting. >From now on both the old mechanism (xtal or TBG referenced as parent clock in `clocks` phandle) and the new one (UART clock referenced in the `clocks` phandle) are supported, to provide full backward compatibility with existing DTS files, full backward compatibility with existing boot loaders, and to provide new features (runtime clock configuration to allow higher baudrates than 230400 Bd). New features are available only with new DTS files. There was also a discussion about how the UART node and the clock-controller node could be wrapped together in a new binding [1, 2]. As explained there, this is not possible if we want to keep backwards compatibility with existing bootloaders, and thus we are doing this by putting the UART clock-controller node inside the UART1 node. [1] https://lore.kernel.org/linux-serial/20220120000651.in7s6nazif5qjkme@pali/ [2] https://lore.kernel.org/linux-serial/20220125204006.A6D09C340E0@smtp.kernel.org/ Signed-off-by: Pali Rohár Reviewed-by: Marek Behún Signed-off-by: Marek Behún --- Changes since v7: - commit message was rewritten - changed comments a little - fixed indentation at some places - added Marek's Reviewed-by tag --- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/mvebu-uart.c | 521 +++++++++++++++++++++++++++++++- 2 files changed, 520 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 0e5ccb25bdb1..9bc1325dd7ba 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1445,6 +1445,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 ab226da75f7b..56278b29f5f5 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 an + * error in Marvell's 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,478 @@ 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 recalculates current UART1/UART2 + * divisors in their address spaces, so that final baudrate will not be + * changed by switching UART parent clock. This is required for + * otherwise kernel's boot log stops working - we need to ensure that + * UART baudrate does not change during this setup. It is a one time + * operation, it will execute only once and set `configured` to true, + * and be skipped on subsequent calls. 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 a 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 the address + * space of UART1 (standard UART variant), controls parent clock and + * dividers for both UART1 and UART2 and is supplied via DT as the first + * resource. Therefore use ioremap() rather than ioremap_resource() to + * avoid conflicts with UART1 driver. Access to UART_BRDV is protected + * by a 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 + * space of UART2 (extended UART variant), controls only one UART2 + * specific divider and is supplied via DT as second resource. + * Therefore use ioremap() rather than ioremap_resource() to avoid + * conflicts with UART2 driver. Access to UART_BRDV is protected by a + * 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 +1488,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.34.1 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id D9E93C433F5 for ; Fri, 11 Feb 2022 19:15:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jXb2P9STP0XpS6KOAQo8KSb8R20iOHAwW4o/YCjn4Jk=; b=xgNxQTJvVCGhlu wmEX0bLNsq/OYzDFm4kFyASwR6osz3SFQ/9cNLfZ0dpcuSYFwWfGscgd3CQIKuPoYwJHakNpVEWyP ZMwQcA5q9pg68HtvTIbcuvUNIy8GegfbQK+dIQAlnpGETG7nYo2k2PHDN9SefXq4QABu6hX/CoKGf hMgJNtlfRbuxWjfbFbTkyCYaaCrGyxV88LR21Gbm0ShHLYuKRN8nGDs8TwOh9BENI0/0NTyF83uth gmqaTgqX7nm7Z/pfCFfFb0jf8XlxBujrIWFs0sQDivvBmjovxujBaJ9/AG+PqbX/djPhDguTUwoJ/ /zZaI4FIeiJxwHME6MOQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nIbN3-008XFd-Gm; Fri, 11 Feb 2022 19:14:17 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nIbLr-008We9-6n for linux-arm-kernel@lists.infradead.org; Fri, 11 Feb 2022 19:13:08 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AA89561F35; Fri, 11 Feb 2022 19:12:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4FC07C340F0; Fri, 11 Feb 2022 19:12:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1644606770; bh=/CHCxS/xFV985M7WTg7mDvHkZaKIjAXfsV3msKFVdgo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dDtEYva4tcV4zI1gSUcRQDln7MD3ZUpkvlBTiedMMpBQcgH2iJhWzlK8+lI9MXl4b qR9mfnLLRP1arT2xAcHKnUMDxN9RFha+hgdEG+iUvy9PJwZAIIvmuqd2vUGgCwPEWR g7aZqLOHr94IRrCaLYiGhKOw3kM9KkY1StrrWO7CHvS7b8rM+cV+VfKVCa5eaa/C7I 76bhcfvCGY/0NYK0G6Uxcqj1qH/u1P+tAlhSlRiAvxk51fNpRy3FeTTIF4ZCkhne7L SdtHIBfxvW7mzegqY6c7wIJ/RkVZUnMGtezyt900adZQf194RdIjboLsmy9YCR4/wM yrVqn27YXO/dQ== From: =?UTF-8?q?Marek=20Beh=C3=BAn?= To: Stephen Boyd , Michael Turquette , Greg Kroah-Hartman , Gregory Clement Cc: =?UTF-8?q?Pali=20Roh=C3=A1r?= , linux-clk@vger.kernel.org, linux-serial@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, =?UTF-8?q?Marek=20Beh=C3=BAn?= Subject: [PATCH v8 3/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Fri, 11 Feb 2022 20:12:35 +0100 Message-Id: <20220211191238.2142-4-kabel@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220211191238.2142-1-kabel@kernel.org> References: <20220211191238.2142-1-kabel@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220211_111303_441555_1ECC5822 X-CRM114-Status: GOOD ( 42.54 ) 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 RnJvbTogUGFsaSBSb2jDoXIgPHBhbGlAa2VybmVsLm9yZz4KCkltcGxlbWVudCBhIG5ldyBkZXZp Y2UgZHJpdmVyIGZvciBjb250cm9sbGluZyBVQVJUIGNsb2NrcyBvbiBNYXJ2ZWxsCkFybWFkYSAz NzAwIFNvQy4gVGhpcyBkZXZpY2UgZHJpdmVyIGlzIGxvYWRlZCBmb3IgZGV2aWNlcyB3aGljaCBt YXRjaAp0aGUgY29tcGF0aWJsZSBzdHJpbmcgIm1hcnZlbGwsYXJtYWRhLTM3MDAtdWFydC1jbG9j ayIuCgpUaGVyZSBhcmUgbW9yZSBwaXRmYWxscyByZWxhdGVkIHRvIFVBUlQgY2xvY2tzOgotIGJv dGggVUFSVHMgdXNlIHNhbWUgcGFyZW50IGNsb2NrIHNvdXJjZSAod2hpY2ggY2FuIGJlIHh0YWwg b3Igb25lIG9mCiAgdGhlIFRCRyBjbG9ja3MpLAotIGlmIGEgVEJHIGNsb2NrIGlzIHVzZWQgYXMg dGhlIHBhcmVudCBjbG9jaywgdGhlcmUgYXJlIHR3byBhZGRpdGlvbmFsCiAgZGl2aXNvcnMgdGhh dCBjYW4gYm90aCBiZSBjb25maWd1cmVkIHRvIGRpdmlkZSB0aGUgcmF0ZSBieSAxLCAyLCAuLi4g NiwKICBidXQgdGhlc2UgZGl2aXNvcnMgYXJlIGFnYWluIHNoYXJlZCBiZXR3ZWVuIHRoZSB0d28g VUFSVCBjb250cm9sbGVycwogIG9uIHRoZSBTT0MsCi0gdGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhl IHBhcmVudCBjbG9jayBzb3VyY2UgYW5kIGRpdmlzb3JzIGlzIGRvbmUgaW4KICB0aGUgYWRkcmVz cyBzcGFjZSBvZiB0aGUgZmlyc3QgVUFSVCBjb250cm9sbGVyLCBVQVJUMS4gQ2xvY2tzIGNhbiBi ZQogIGdhdGVkIHNlcGFyYXRlbHkgZm9yIFVBUlQxIGFuZCBVQVJUMiwgYnV0IHRoaXMgc2V0dGlu ZyBhbHNvIGxpdmVzIGluCiAgdGhlIGFkZHJlc3Mgc3BhY2Ugb2YgVUFSVDEsCi0gTWFydmVsbCdz IEZ1bmN0aW9uYWwgU3BlY2lmaWNhdGlvbiBmb3IgQXJtYWRhIDM3MjAgZG9jdW1lbnQgaGFzIHRo ZQogIGNsb2NrIGdhdGluZyBiaXRzIHN3YXBwZWQsIHNvIHRoZSBvbmUgZGVzY3JpYmVkIHRvIGdh dGUgVUFSVDEgY2xvY2sKICBhY3R1YWxseSBnYXRlcyBVQVJUMiBhbmQgdmljZSB2ZXJzYSwKLSBl YWNoIFVBUlQgaGFzIGl0J3Mgb3duICJzcGVjaWFsIGRpdmlzb3IiLCBhbmQgdGhpcyB1c2VzIHRo ZSBwYXJlbnQKICBjbG9jayBkZXNjcmliZWQgYWJvdmUuIFRoZXNlIGRpdmlzb3JzIGFyZSBjb25m aWd1cmUgaW4gZWFjaCBVQVJUJ3MKICBhZGRyZXNzIHNwYWNlIHNlcGFyYXRlbHkuCgpUaHVzIHRo ZSBkcml2ZXIgZm9yIFVBUlQyIGNvbnRyb2xsZXIgbmVlZHMgdG8gaGF2ZSBhY2Nlc3MgdG8gVUFS VDEKYWRkcmVzcyBzcGFjZSwgc2luY2UgVUFSVDEgYWRkcmVzcyBzcGFjZSBjb250YWlucyBzb21l IGJpdHMgZXhjbHVzaXZlCmZvciBVQVJUMiBhbmQgYWxzbyBzb21lIGJpdHMgd2hpY2ggYXJlIHNo YXJlZCBiZXR3ZWVuIFVBUlQxIGFuZCBVQVJUMi4KCkFsc28sIGR1cmluZyBib290LCB3aGVuIGVh cmx5IGNvbnNvbGUgaXMgYWN0aXZlIG9uIG9uZSBvZiB0aGUgVUFSVHMsCmFuZCB3ZSB3YW50IHRv IHN3aXRjaCBwYXJlbnQgY2xvY2sgZnJvbSB4dGFsIChkZWZhdWx0KSB0byBUQkcgKHRvIGJlCm1v cmUgZmxleGlibGUgd2l0aCBiYXVkcmF0ZXMpLCB0aGUgZHJpdmVyIGNoYW5naW5nIFVBUlQgY2xv Y2tzIGFsc28KbmVlZHMgdG8gYmUgYWJsZSB0byBjaGFuZ2UgdGhlICJzcGVjaWFsIGRpdmlzb3Ii LCBzbyB0aGF0IHRoZSBiYXVkcmF0ZQpvZiBlYXJseWNvbiBpcyBub3QgY2hhbmdlZCB3aGVuIHN3 dGljaGluZyB0byBub3JtYWwgY29uc29sZS4gVGh1cyB0aGUKY2xvY2sgZHJpdmVyIGFsc28gbmVl ZHMgdG8gYmUgYWJsZSB0byBhY2Nlc3MgVUFSVDIgcmVnaXN0ZXIgc3BhY2UsCmZvciBVQVJUMidz ICJzcGVjaWFsIGRpdmlzb3IiLgoKRm9yIHRoZXNlIHJlYXNvbnMsIHRoaXMgbmV3IFVBUlQgY2xv Y2sgZHJpdmVyIGRvZXMgbm90IHVzZQppb3JlbWFwX3Jlc291cmNlKCksIGJ1dCBvbmx5IGlvcmVt YXAoKSB0byBwcmV2ZW50IHJlc291cmNlIGNvbmZsaWN0cwpiZXR3ZWVuIFVBUlQgY2xvY2sgZHJp dmVyIGFuZCBVQVJUIGRyaXZlci4KPT09CldlIG5lZWQgdG8gc2hhcmUgb25seSB0d28gMzItYml0 IHJlZ2lzdGVycyBiZXR3ZWVuIHRoZSBVQVJUIGRyaXZlciBhbmQKdGhlIFVBUlQgY2xvY2sgZHJp dmVyOgotIFVBUlQgQ2xvY2sgQ29udHJvbAotIFVBUlQgMiBCYXVkIFJhdGUgRGl2aXNvcgpBY2Nl c3MgdG8gdGhlc2UgdHdvIHJlZ2lzdGVycyBhcmUgcHJvdGVjdGVkIGJ5IG9uZSBzcGlubG9jayB0 byBwcmV2ZW50CmFueSBjb25mbGljdHMuIEFjY2VzcyBpcyByZXF1aXJlZCBvbmx5IGR1cmluZyBw cm9iaW5nLCB3aGVuIGNoYW5naW5nCmJhdWRyYXRlIG9yIGR1cmluZyBzdXNwZW5kL3Jlc3VtZS4K CkhhcmR3YXJlIGNhbiBiZSBjb25maWd1cmVkIHRvIHVzZSBvbmUgb2YgZm9sbG93aW5nIGNsb2Nr cyBhcyBVQVJUIHBhcmVudApjbG9jazogVEJHLUEtUCwgVEJHLUItUCwgVEJHLUEtUywgVEJHLUIt UywgeHRhbC4gTm90IGV2ZXJ5IGNsb2NrIGlzCnVzYWJsZSBmb3IgaGlnaGVyIGJ1YWRyYXRlcy4g QW55IHN1YnNldCBjYW4gYmUgc3BlY2lmaWVkIGluIHRoZQpkZXZpY2UtdHJlZSBhbmQgdGhlIGRy aXZlciB3aWxsIGNob29zZSB0aGUgYmVzdCBvbmUgd2hpY2ggYWxzbyBzdGlsbApzdXBwb3J0cyB0 aGUgbWFuZGF0b3J5IGJhdWRyYXRlIG9mIDk2MDAgQmQuIEZvciBzbW9vdGggYm9vdCBsb2cgb3V0 cHV0Cml0IGlzIG5lZWRlZCB0byBzcGVjaWZ5IGNsb2NrIHVzZWQgYnkgZWFybHkgY29uc29sZSwg b3RoZXJ3aXNlIGdhcmJhZ2UKd291bGQgYmUgcHJpbnRlZCBvbiBVQVJUIGR1cmluZyBwcm9iZSBv ZiBVQVJUIGNsb2NrIGRyaXZlciBhbmQKdHJhbnNpdGlvbmluZyBmcm9tIGVhcmx5IGNvbnNvbGUg dG8gbm9ybWFsIGNvbnNvbGUuCgpXZSBhcmUgaW1wbGVtZW50aW5nIHRoaXMgdG8gYmUgYWJsZSB0 byBjb25maWd1cmUgVEJHIGNsb2NrIGFzIFVBUlQKcGFyZW50IGNsb2NrLCB3aGljaCBpcyByZXF1 aXJlZCB0byBiZSBhYmxlIHRvIGFjaGlldmUgaGlnaGVyIGJhdWRyYXRlcwp0aGFuIDIzMDQwMCBC ZC4gV2UgYWNoaWV2ZSB0aGlzIGJ5IHJlZmVyZW5jaW5nIHRoaXMgbmV3IFVBUlQgY2xvY2sKZGV2 aWNlIG5vZGUgaW4gVUFSVCdzIGRldmljZSBub2RlLiBVQVJUIGNsb2NrIGRldmljZSBkcml2ZXIK YXV0b21hdGljYWxseSBjaG9vc2VzIHRoZSBiZXN0IGNsb2NrIHNvdXJjZSBmb3IgVUFSVCBkcml2 ZXIuCgpVbnRpbCBub3csIFVBUlQncyBkZXZpY2UtdHJlZSBub2RlIG5lZWRlZCB0byByZWZlcmVu Y2Ugb25lIG9mIHRoZSBzdGF0aWMKY2xvY2tzICh4dGFsIG9yIG9uZSBvZiB0aGUgVEJHcykgYXMg cGFyZW50IGNsb2NrIGluIHRoZSBgY2xvY2tzYApwaGFuZGxlIC0gdGhlIHBhcmVudCBjbG9jayB3 aGljaCB3YXMgY29uZmlndXJlZCBiZWZvcmUgYm9vdGluZyB0aGUKa2VybmVsLiBJZiBib290bG9h ZGVyIGNoYW5nZWQgVUFSVCdzIHBhcmVudCBjbG9jaywgaXQgbmVlZGVkIHRvIGNoYW5nZQp0aGUg YGNsb2Nrc2AgcGhhbmRsZSBpbiBEVEIgY29ycmVzcG9uZGluZ2x5IGJlZm9yZSBib290aW5nLgoK RnJvbSBub3cgb24gYm90aCB0aGUgb2xkIG1lY2hhbmlzbSAoeHRhbCBvciBUQkcgcmVmZXJlbmNl ZCBhcyBwYXJlbnQKY2xvY2sgaW4gYGNsb2Nrc2AgcGhhbmRsZSkgYW5kIHRoZSBuZXcgb25lIChV QVJUIGNsb2NrIHJlZmVyZW5jZWQgaW4gdGhlCmBjbG9ja3NgIHBoYW5kbGUpIGFyZSBzdXBwb3J0 ZWQsIHRvIHByb3ZpZGUgZnVsbCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CndpdGggZXhpc3Rpbmcg RFRTIGZpbGVzLCBmdWxsIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBleGlzdGluZyBib290 CmxvYWRlcnMsIGFuZCB0byBwcm92aWRlIG5ldyBmZWF0dXJlcyAocnVudGltZSBjbG9jayBjb25m aWd1cmF0aW9uIHRvCmFsbG93IGhpZ2hlciBiYXVkcmF0ZXMgdGhhbiAyMzA0MDAgQmQpLiBOZXcg ZmVhdHVyZXMgYXJlIGF2YWlsYWJsZSBvbmx5CndpdGggbmV3IERUUyBmaWxlcy4KClRoZXJlIHdh cyBhbHNvIGEgZGlzY3Vzc2lvbiBhYm91dCBob3cgdGhlIFVBUlQgbm9kZSBhbmQgdGhlCmNsb2Nr LWNvbnRyb2xsZXIgbm9kZSBjb3VsZCBiZSB3cmFwcGVkIHRvZ2V0aGVyIGluIGEgbmV3IGJpbmRp bmcgWzEsIDJdLgpBcyBleHBsYWluZWQgdGhlcmUsIHRoaXMgaXMgbm90IHBvc3NpYmxlIGlmIHdl IHdhbnQgdG8ga2VlcCBiYWNrd2FyZHMKY29tcGF0aWJpbGl0eSB3aXRoIGV4aXN0aW5nIGJvb3Rs b2FkZXJzLCBhbmQgdGh1cyB3ZSBhcmUgZG9pbmcgdGhpcyBieQpwdXR0aW5nIHRoZSBVQVJUIGNs b2NrLWNvbnRyb2xsZXIgbm9kZSBpbnNpZGUgdGhlIFVBUlQxIG5vZGUuCgpbMV0gaHR0cHM6Ly9s b3JlLmtlcm5lbC5vcmcvbGludXgtc2VyaWFsLzIwMjIwMTIwMDAwNjUxLmluN3M2bmF6aWY1cWpr bWVAcGFsaS8KWzJdIGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2xpbnV4LXNlcmlhbC8yMDIyMDEy NTIwNDAwNi5BNkQwOUMzNDBFMEBzbXRwLmtlcm5lbC5vcmcvCgpTaWduZWQtb2ZmLWJ5OiBQYWxp IFJvaMOhciA8cGFsaUBrZXJuZWwub3JnPgpSZXZpZXdlZC1ieTogTWFyZWsgQmVow7puIDxrYWJl bEBrZXJuZWwub3JnPgpTaWduZWQtb2ZmLWJ5OiBNYXJlayBCZWjDum4gPGthYmVsQGtlcm5lbC5v cmc+Ci0tLQpDaGFuZ2VzIHNpbmNlIHY3OgotIGNvbW1pdCBtZXNzYWdlIHdhcyByZXdyaXR0ZW4K LSBjaGFuZ2VkIGNvbW1lbnRzIGEgbGl0dGxlCi0gZml4ZWQgaW5kZW50YXRpb24gYXQgc29tZSBw bGFjZXMKLSBhZGRlZCBNYXJlaydzIFJldmlld2VkLWJ5IHRhZwotLS0KIGRyaXZlcnMvdHR5L3Nl cmlhbC9LY29uZmlnICAgICAgfCAgIDEgKwogZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQu YyB8IDUyMSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrLQogMiBmaWxlcyBjaGFuZ2Vk LCA1MjAgaW5zZXJ0aW9ucygrKSwgMiBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJz L3R0eS9zZXJpYWwvS2NvbmZpZyBiL2RyaXZlcnMvdHR5L3NlcmlhbC9LY29uZmlnCmluZGV4IDBl NWNjYjI1YmRiMS4uOWJjMTMyNWRkN2JhIDEwMDY0NAotLS0gYS9kcml2ZXJzL3R0eS9zZXJpYWwv S2NvbmZpZworKysgYi9kcml2ZXJzL3R0eS9zZXJpYWwvS2NvbmZpZwpAQCAtMTQ0NSw2ICsxNDQ1 LDcgQEAgY29uZmlnIFNFUklBTF9TVE0zMl9DT05TT0xFCiBjb25maWcgU0VSSUFMX01WRUJVX1VB UlQKIAlib29sICJNYXJ2ZWxsIEVCVSBzZXJpYWwgcG9ydCBzdXBwb3J0IgogCWRlcGVuZHMgb24g QVJDSF9NVkVCVSB8fCBDT01QSUxFX1RFU1QKKwlkZXBlbmRzIG9uIENPTU1PTl9DTEsKIAlzZWxl Y3QgU0VSSUFMX0NPUkUKIAloZWxwCiAJICBUaGlzIGRyaXZlciBpcyBmb3IgTWFydmVsbCBFQlUg U29DJ3MgVUFSVC4gSWYgeW91IGhhdmUgYSBtYWNoaW5lCmRpZmYgLS1naXQgYS9kcml2ZXJzL3R0 eS9zZXJpYWwvbXZlYnUtdWFydC5jIGIvZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYwpp bmRleCBhYjIyNmRhNzVmN2IuLjU2Mjc4YjI5ZjVmNSAxMDA2NDQKLS0tIGEvZHJpdmVycy90dHkv c2VyaWFsL212ZWJ1LXVhcnQuYworKysgYi9kcml2ZXJzL3R0eS9zZXJpYWwvbXZlYnUtdWFydC5j CkBAIC04LDEyICs4LDE0IEBACiAqLwogCiAjaW5jbHVkZSA8bGludXgvY2xrLmg+CisjaW5jbHVk ZSA8bGludXgvY2xrLXByb3ZpZGVyLmg+CiAjaW5jbHVkZSA8bGludXgvY29uc29sZS5oPgogI2lu Y2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiAjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiAjaW5jbHVk ZSA8bGludXgvaW5pdC5oPgogI2luY2x1ZGUgPGxpbnV4L2lvLmg+CiAjaW5jbHVkZSA8bGludXgv aW9wb2xsLmg+CisjaW5jbHVkZSA8bGludXgvbWF0aDY0Lmg+CiAjaW5jbHVkZSA8bGludXgvb2Yu aD4KICNpbmNsdWRlIDxsaW51eC9vZl9hZGRyZXNzLmg+CiAjaW5jbHVkZSA8bGludXgvb2ZfZGV2 aWNlLmg+CkBAIC02OCw4ICs3MCwzMSBAQAogI2RlZmluZSAgU1RBVF9CUktfRVJSCQkoU1RBVF9C UktfREVUIHwgU1RBVF9GUk1fRVJSIFwKIAkJCQkgfCBTVEFUX1BBUl9FUlIgfCBTVEFUX09WUl9F UlIpCiAKKy8qCisgKiBNYXJ2ZWxsIEFybWFkYSAzNzAwIEZ1bmN0aW9uYWwgU3BlY2lmaWNhdGlv bnMgZGVzY3JpYmVzIHRoYXQgYml0IDIxIG9mIFVBUlQKKyAqIENsb2NrIENvbnRyb2wgcmVnaXN0 ZXIgY29udHJvbHMgVUFSVDEgYW5kIGJpdCAyMCBjb250cm9scyBVQVJUMi4gQnV0IGluCisgKiBy ZWFsaXR5IGJpdCAyMSBjb250cm9scyBVQVJUMiBhbmQgYml0IDIwIGNvbnRyb2xzIFVBUlQxLiBU aGlzIHNlZW1zIHRvIGJlIGFuCisgKiBlcnJvciBpbiBNYXJ2ZWxsJ3MgZG9jdW1lbnRhdGlvbi4g SGVuY2UgZm9sbG93aW5nIENMS19ESVMgbWFjcm9zIGFyZSBzd2FwcGVkLgorICovCisKICNkZWZp bmUgVUFSVF9CUkRWCQkweDEwCisvKiBUaGVzZSBiaXRzIGFyZSBsb2NhdGVkIGluIFVBUlQxIGFk ZHJlc3Mgc3BhY2UgYW5kIGNvbnRyb2wgVUFSVDIgKi8KKyNkZWZpbmUgIFVBUlQyX0NMS19ESVMJ CUJJVCgyMSkKKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0ZWQgaW4gVUFSVDEgYWRkcmVzcyBzcGFj ZSBhbmQgY29udHJvbCBVQVJUMSAqLworI2RlZmluZSAgVUFSVDFfQ0xLX0RJUwkJQklUKDIwKQor LyogVGhlc2UgYml0cyBhcmUgbG9jYXRlZCBpbiBVQVJUMSBhZGRyZXNzIHNwYWNlIGFuZCBjb250 cm9sIGJvdGggVUFSVHMgKi8KKyNkZWZpbmUgIENMS19OT19YVEFMCQlCSVQoMTkpCisjZGVmaW5l ICBDTEtfVEJHX0RJVjFfU0hJRlQJMTUKKyNkZWZpbmUgIENMS19UQkdfRElWMV9NQVNLCTB4Nwor I2RlZmluZSAgQ0xLX1RCR19ESVYxX01BWAk2CisjZGVmaW5lICBDTEtfVEJHX0RJVjJfU0hJRlQJ MTIKKyNkZWZpbmUgIENMS19UQkdfRElWMl9NQVNLCTB4NworI2RlZmluZSAgQ0xLX1RCR19ESVYy X01BWAk2CisjZGVmaW5lICBDTEtfVEJHX1NFTF9TSElGVAkxMAorI2RlZmluZSAgQ0xLX1RCR19T RUxfTUFTSwkweDMKKy8qIFRoZXNlIGJpdHMgYXJlIGxvY2F0ZWQgaW4gYm90aCBVQVJUcyBhZGRy ZXNzIHNwYWNlICovCiAjZGVmaW5lICBCUkRWX0JBVURfTUFTSyAgICAgICAgIDB4M0ZGCisjZGVm aW5lICBCUkRWX0JBVURfTUFYCQlCUkRWX0JBVURfTUFTSwogCiAjZGVmaW5lIFVBUlRfT1NBTVAJ CTB4MTQKICNkZWZpbmUgIE9TQU1QX0RFRkFVTFRfRElWSVNPUgkxNgpAQCAtMTUzLDYgKzE3OCw4 IEBAIHN0YXRpYyBzdHJ1Y3QgbXZlYnVfdWFydCAqdG9fbXZ1YXJ0KHN0cnVjdCB1YXJ0X3BvcnQg KnBvcnQpCiAKIHN0YXRpYyBzdHJ1Y3QgdWFydF9wb3J0IG12ZWJ1X3VhcnRfcG9ydHNbTVZFQlVf TlJfVUFSVFNdOwogCitzdGF0aWMgREVGSU5FX1NQSU5MT0NLKG12ZWJ1X3VhcnRfbG9jayk7CisK IC8qIENvcmUgVUFSVCBEcml2ZXIgT3BlcmF0aW9ucyAqLwogc3RhdGljIHVuc2lnbmVkIGludCBt dmVidV91YXJ0X3R4X2VtcHR5KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQpCiB7CkBAIC00NDUsNiAr NDcyLDcgQEAgc3RhdGljIHZvaWQgbXZlYnVfdWFydF9zaHV0ZG93bihzdHJ1Y3QgdWFydF9wb3J0 ICpwb3J0KQogc3RhdGljIGludCBtdmVidV91YXJ0X2JhdWRfcmF0ZV9zZXQoc3RydWN0IHVhcnRf cG9ydCAqcG9ydCwgdW5zaWduZWQgaW50IGJhdWQpCiB7CiAJdW5zaWduZWQgaW50IGRfZGl2aXNv ciwgbV9kaXZpc29yOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CiAJdTMyIGJyZHYsIG9zYW1wOwog CiAJaWYgKCFwb3J0LT51YXJ0Y2xrKQpAQCAtNDYzLDEwICs0OTEsMTIgQEAgc3RhdGljIGludCBt dmVidV91YXJ0X2JhdWRfcmF0ZV9zZXQoc3RydWN0IHVhcnRfcG9ydCAqcG9ydCwgdW5zaWduZWQg aW50IGJhdWQpCiAJbV9kaXZpc29yID0gT1NBTVBfREVGQVVMVF9ESVZJU09SOwogCWRfZGl2aXNv ciA9IERJVl9ST1VORF9DTE9TRVNUKHBvcnQtPnVhcnRjbGssIGJhdWQgKiBtX2Rpdmlzb3IpOwog CisJc3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwogCWJyZHYgPSBy ZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9CUkRWKTsKIAlicmR2ICY9IH5CUkRWX0JBVURfTUFT SzsKIAlicmR2IHw9IGRfZGl2aXNvcjsKIAl3cml0ZWwoYnJkdiwgcG9ydC0+bWVtYmFzZSArIFVB UlRfQlJEVik7CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFn cyk7CiAKIAlvc2FtcCA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX09TQU1QKTsKIAlvc2Ft cCAmPSB+T1NBTVBfRElWSVNPUlNfTUFTSzsKQEAgLTc2Miw2ICs3OTIsNyBAQCBzdGF0aWMgaW50 IG12ZWJ1X3VhcnRfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCiB7CiAJc3RydWN0IG12ZWJ1 X3VhcnQgKm12dWFydCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwogCXN0cnVjdCB1YXJ0X3BvcnQg KnBvcnQgPSBtdnVhcnQtPnBvcnQ7CisJdW5zaWduZWQgbG9uZyBmbGFnczsKIAogCXVhcnRfc3Vz cGVuZF9wb3J0KCZtdmVidV91YXJ0X2RyaXZlciwgcG9ydCk7CiAKQEAgLTc3MCw3ICs4MDEsOSBA QCBzdGF0aWMgaW50IG12ZWJ1X3VhcnRfc3VzcGVuZChzdHJ1Y3QgZGV2aWNlICpkZXYpCiAJbXZ1 YXJ0LT5wbV9yZWdzLmN0cmwgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9DVFJMKHBvcnQp KTsKIAltdnVhcnQtPnBtX3JlZ3MuaW50ciA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX0lO VFIocG9ydCkpOwogCW12dWFydC0+cG1fcmVncy5zdGF0ID0gcmVhZGwocG9ydC0+bWVtYmFzZSAr IFVBUlRfU1RBVCk7CisJc3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3Mp OwogCW12dWFydC0+cG1fcmVncy5icmR2ID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfQlJE Vik7CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CiAJ bXZ1YXJ0LT5wbV9yZWdzLm9zYW1wID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfT1NBTVAp OwogCiAJZGV2aWNlX3NldF93YWtldXBfZW5hYmxlKGRldiwgdHJ1ZSk7CkBAIC03ODIsMTMgKzgx NSwxNiBAQCBzdGF0aWMgaW50IG12ZWJ1X3VhcnRfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikK IHsKIAlzdHJ1Y3QgbXZlYnVfdWFydCAqbXZ1YXJ0ID0gZGV2X2dldF9kcnZkYXRhKGRldik7CiAJ c3RydWN0IHVhcnRfcG9ydCAqcG9ydCA9IG12dWFydC0+cG9ydDsKKwl1bnNpZ25lZCBsb25nIGZs YWdzOwogCiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5yYnIsIHBvcnQtPm1lbWJhc2UgKyBVQVJU X1JCUihwb3J0KSk7CiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy50c2gsIHBvcnQtPm1lbWJhc2Ug KyBVQVJUX1RTSChwb3J0KSk7CiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5jdHJsLCBwb3J0LT5t ZW1iYXNlICsgVUFSVF9DVFJMKHBvcnQpKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLmludHIs IHBvcnQtPm1lbWJhc2UgKyBVQVJUX0lOVFIocG9ydCkpOwogCXdyaXRlbChtdnVhcnQtPnBtX3Jl Z3Muc3RhdCwgcG9ydC0+bWVtYmFzZSArIFVBUlRfU1RBVCk7CisJc3Bpbl9sb2NrX2lycXNhdmUo Jm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MuYnJkdiwg cG9ydC0+bWVtYmFzZSArIFVBUlRfQlJEVik7CisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZl YnVfdWFydF9sb2NrLCBmbGFncyk7CiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5vc2FtcCwgcG9y dC0+bWVtYmFzZSArIFVBUlRfT1NBTVApOwogCiAJdWFydF9yZXN1bWVfcG9ydCgmbXZlYnVfdWFy dF9kcml2ZXIsIHBvcnQpOwpAQCAtOTcyLDYgKzEwMDgsNDc4IEBAIHN0YXRpYyBzdHJ1Y3QgcGxh dGZvcm1fZHJpdmVyIG12ZWJ1X3VhcnRfcGxhdGZvcm1fZHJpdmVyID0gewogCX0sCiB9OwogCisv KiBUaGlzIGNvZGUgaXMgYmFzZWQgb24gY2xrLWZpeGVkLWZhY3Rvci5jIGRyaXZlciBhbmQgbW9k aWZpZWQuICovCisKK3N0cnVjdCBtdmVidV91YXJ0X2Nsb2NrIHsKKwlzdHJ1Y3QgY2xrX2h3IGNs a19odzsKKwlpbnQgY2xvY2tfaWR4OworCXUzMiBwbV9jb250ZXh0X3JlZzE7CisJdTMyIHBtX2Nv bnRleHRfcmVnMjsKK307CisKK3N0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgeworCXN0cnVj dCBtdmVidV91YXJ0X2Nsb2NrIGNsb2Nrc1syXTsKKwl1bnNpZ25lZCBpbnQgcGFyZW50X3JhdGVz WzVdOworCWludCBwYXJlbnRfaWR4OworCXVuc2lnbmVkIGludCBkaXY7CisJdm9pZCBfX2lvbWVt ICpyZWcxOworCXZvaWQgX19pb21lbSAqcmVnMjsKKwlib29sIGNvbmZpZ3VyZWQ7Cit9OworCisj ZGVmaW5lIFBBUkVOVF9DTE9DS19YVEFMIDQKKworI2RlZmluZSB0b191YXJ0X2Nsb2NrKGh3KSBj b250YWluZXJfb2YoaHcsIHN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrLCBjbGtfaHcpCisjZGVmaW5l IHRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKSBjb250YWluZXJfb2YodWFydF9jbG9jaywg XAorCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UsIGNsb2Nrc1t1YXJ0X2Nsb2NrLT5jbG9j a19pZHhdKQorCitzdGF0aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfcHJlcGFyZShzdHJ1Y3QgY2xr X2h3ICpodykKK3sKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3Vh cnRfY2xvY2soaHcpOworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tf YmFzZSA9CisJCQkJCQl0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7CisJdW5zaWduZWQg aW50IHByZXZfY2xvY2tfaWR4LCBwcmV2X2Nsb2NrX3JhdGUsIHByZXZfZDFkMjsKKwl1bnNpZ25l ZCBpbnQgcGFyZW50X2Nsb2NrX2lkeCwgcGFyZW50X2Nsb2NrX3JhdGU7CisJdW5zaWduZWQgbG9u ZyBmbGFnczsKKwl1bnNpZ25lZCBpbnQgZDEsIGQyOworCXU2NCBkaXZpc29yOworCXUzMiB2YWw7 CisKKwkvKgorCSAqIFRoaXMgZnVuY3Rpb24ganVzdCByZWNvbmZpZ3VyZXMgVUFSVCBDbG9jayBD b250cm9sIHJlZ2lzdGVyIChsb2NhdGVkCisJICogaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSB3aGlj aCBjb250cm9scyBib3RoIFVBUlQxIGFuZCBVQVJUMikgdG8KKwkgKiBzZWxlY3RlZCBVQVJUIGJh c2UgY2xvY2sgYW5kIHJlY2FsY3VsYXRlcyBjdXJyZW50IFVBUlQxL1VBUlQyCisJICogZGl2aXNv cnMgaW4gdGhlaXIgYWRkcmVzcyBzcGFjZXMsIHNvIHRoYXQgZmluYWwgYmF1ZHJhdGUgd2lsbCBu b3QgYmUKKwkgKiBjaGFuZ2VkIGJ5IHN3aXRjaGluZyBVQVJUIHBhcmVudCBjbG9jay4gVGhpcyBp cyByZXF1aXJlZCBmb3IKKwkgKiBvdGhlcndpc2Uga2VybmVsJ3MgYm9vdCBsb2cgc3RvcHMgd29y a2luZyAtIHdlIG5lZWQgdG8gZW5zdXJlIHRoYXQKKwkgKiBVQVJUIGJhdWRyYXRlIGRvZXMgbm90 IGNoYW5nZSBkdXJpbmcgdGhpcyBzZXR1cC4gSXQgaXMgYSBvbmUgdGltZQorCSAqIG9wZXJhdGlv biwgaXQgd2lsbCBleGVjdXRlIG9ubHkgb25jZSBhbmQgc2V0IGBjb25maWd1cmVkYCB0byB0cnVl LAorCSAqIGFuZCBiZSBza2lwcGVkIG9uIHN1YnNlcXVlbnQgY2FsbHMuIEJlY2F1c2UgdGhpcyBV QVJUIENsb2NrIENvbnRyb2wKKwkgKiByZWdpc3RlciAoVUFSVF9CUkRWKSBpcyBzaGFyZWQgYmV0 d2VlbiBVQVJUMSBiYXVkcmF0ZSBmdW5jdGlvbiwKKwkgKiBVQVJUMSBjbG9jayBzZWxlY3RvciBh bmQgVUFSVDIgY2xvY2sgc2VsZWN0b3IsIGV2ZXJ5IGFjY2VzcyB0bworCSAqIFVBUlRfQlJEViAo cmVnMSkgbmVlZHMgdG8gYmUgcHJvdGVjdGVkIGJ5IGEgbG9jay4KKwkgKi8KKworCXNwaW5fbG9j a19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKworCWlmICh1YXJ0X2Nsb2NrX2Jh c2UtPmNvbmZpZ3VyZWQpIHsKKwkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9s b2NrLCBmbGFncyk7CisJCXJldHVybiAwOworCX0KKworCXBhcmVudF9jbG9ja19pZHggPSB1YXJ0 X2Nsb2NrX2Jhc2UtPnBhcmVudF9pZHg7CisJcGFyZW50X2Nsb2NrX3JhdGUgPSB1YXJ0X2Nsb2Nr X2Jhc2UtPnBhcmVudF9yYXRlc1twYXJlbnRfY2xvY2tfaWR4XTsKKworCXZhbCA9IHJlYWRsKHVh cnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9jbG9ja19iYXNlLT5kaXYgPiBDTEtf VEJHX0RJVjFfTUFYKSB7CisJCWQxID0gQ0xLX1RCR19ESVYxX01BWDsKKwkJZDIgPSB1YXJ0X2Ns b2NrX2Jhc2UtPmRpdiAvIENMS19UQkdfRElWMV9NQVg7CisJfSBlbHNlIHsKKwkJZDEgPSB1YXJ0 X2Nsb2NrX2Jhc2UtPmRpdjsKKwkJZDIgPSAxOworCX0KKworCWlmICh2YWwgJiBDTEtfTk9fWFRB TCkgeworCQlwcmV2X2Nsb2NrX2lkeCA9ICh2YWwgPj4gQ0xLX1RCR19TRUxfU0hJRlQpICYgQ0xL X1RCR19TRUxfTUFTSzsKKwkJcHJldl9kMWQyID0gKCh2YWwgPj4gQ0xLX1RCR19ESVYxX1NISUZU KSAmIENMS19UQkdfRElWMV9NQVNLKSAqCisJCQkgICAgKCh2YWwgPj4gQ0xLX1RCR19ESVYyX1NI SUZUKSAmIENMS19UQkdfRElWMl9NQVNLKTsKKwl9IGVsc2UgeworCQlwcmV2X2Nsb2NrX2lkeCA9 IFBBUkVOVF9DTE9DS19YVEFMOworCQlwcmV2X2QxZDIgPSAxOworCX0KKworCS8qIE5vdGUgdGhh dCB1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1tpXSBtYXkgbm90IGJlIGF2YWlsYWJsZSAq LworCXByZXZfY2xvY2tfcmF0ZSA9IHVhcnRfY2xvY2tfYmFzZS0+cGFyZW50X3JhdGVzW3ByZXZf Y2xvY2tfaWR4XTsKKworCS8qIFJlY2FsY3VsYXRlIFVBUlQxIGRpdmlzb3Igc28gVUFSVDEgYmF1 ZHJhdGUgZG9lcyBub3QgY2hhbmdlICovCisJaWYgKHByZXZfY2xvY2tfcmF0ZSkgeworCQlkaXZp c29yID0gRElWX1U2NF9ST1VORF9DTE9TRVNUKCh1NjQpKHZhbCAmIEJSRFZfQkFVRF9NQVNLKSAq CisJCQkJCQlwYXJlbnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFkMiwKKwkJCQkJCXByZXZfY2xvY2tf cmF0ZSAqIGQxICogZDIpOworCQlpZiAoZGl2aXNvciA8IDEpCisJCQlkaXZpc29yID0gMTsKKwkJ ZWxzZSBpZiAoZGl2aXNvciA+IEJSRFZfQkFVRF9NQVgpCisJCQlkaXZpc29yID0gQlJEVl9CQVVE X01BWDsKKwkJdmFsID0gKHZhbCAmIH5CUkRWX0JBVURfTUFTSykgfCBkaXZpc29yOworCX0KKwor CWlmIChwYXJlbnRfY2xvY2tfaWR4ICE9IFBBUkVOVF9DTE9DS19YVEFMKSB7CisJCS8qIERvIG5v dCB1c2UgWFRBTCwgc2VsZWN0IFRCRyBjbG9jayBhbmQgVEJHIGQxICogZDIgZGl2aXNvcnMgKi8K KwkJdmFsIHw9IENMS19OT19YVEFMOworCQl2YWwgJj0gfihDTEtfVEJHX0RJVjFfTUFTSyA8PCBD TEtfVEJHX0RJVjFfU0hJRlQpOworCQl2YWwgfD0gZDEgPDwgQ0xLX1RCR19ESVYxX1NISUZUOwor CQl2YWwgJj0gfihDTEtfVEJHX0RJVjJfTUFTSyA8PCBDTEtfVEJHX0RJVjJfU0hJRlQpOworCQl2 YWwgfD0gZDIgPDwgQ0xLX1RCR19ESVYyX1NISUZUOworCQl2YWwgJj0gfihDTEtfVEJHX1NFTF9N QVNLIDw8IENMS19UQkdfU0VMX1NISUZUKTsKKwkJdmFsIHw9IHBhcmVudF9jbG9ja19pZHggPDwg Q0xLX1RCR19TRUxfU0hJRlQ7CisJfSBlbHNlIHsKKwkJLyogVXNlIFhUQUwsIFRCRyBiaXRzIGFy ZSB0aGVuIGlnbm9yZWQgKi8KKwkJdmFsICY9IH5DTEtfTk9fWFRBTDsKKwl9CisKKwl3cml0ZWwo dmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJLyogUmVjYWxjdWxhdGUgVUFSVDIgZGl2 aXNvciBzbyBVQVJUMiBiYXVkcmF0ZSBkb2VzIG5vdCBjaGFuZ2UgKi8KKwlpZiAocHJldl9jbG9j a19yYXRlKSB7CisJCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7CisJCWRpdmlz b3IgPSBESVZfVTY0X1JPVU5EX0NMT1NFU1QoKHU2NCkodmFsICYgQlJEVl9CQVVEX01BU0spICoK KwkJCQkJCXBhcmVudF9jbG9ja19yYXRlICogcHJldl9kMWQyLAorCQkJCQkJcHJldl9jbG9ja19y YXRlICogZDEgKiBkMik7CisJCWlmIChkaXZpc29yIDwgMSkKKwkJCWRpdmlzb3IgPSAxOworCQll bHNlIGlmIChkaXZpc29yID4gQlJEVl9CQVVEX01BWCkKKwkJCWRpdmlzb3IgPSBCUkRWX0JBVURf TUFYOworCQl2YWwgPSAodmFsICYgfkJSRFZfQkFVRF9NQVNLKSB8IGRpdmlzb3I7CisJCXdyaXRl bCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7CisJfQorCisJdWFydF9jbG9ja19iYXNlLT5j b25maWd1cmVkID0gdHJ1ZTsKKworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRf bG9jaywgZmxhZ3MpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9j bG9ja19lbmFibGUoc3RydWN0IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xv Y2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9j bG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVh cnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJdTMyIHZhbDsKKworCXNwaW5fbG9j a19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKworCXZhbCA9IHJlYWRsKHVhcnRf Y2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9jbG9jay0+Y2xvY2tfaWR4ID09IDApCisJ CXZhbCAmPSB+VUFSVDFfQ0xLX0RJUzsKKwllbHNlCisJCXZhbCAmPSB+VUFSVDJfQ0xLX0RJUzsK KworCXdyaXRlbCh2YWwsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlzcGluX3VubG9ja19p cnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKworCXJldHVybiAwOworfQorCitz dGF0aWMgdm9pZCBtdmVidV91YXJ0X2Nsb2NrX2Rpc2FibGUoc3RydWN0IGNsa19odyAqaHcpCit7 CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3 KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJ CQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7 CisJdTMyIHZhbDsKKworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdz KTsKKworCXZhbCA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9j bG9jay0+Y2xvY2tfaWR4ID09IDApCisJCXZhbCB8PSBVQVJUMV9DTEtfRElTOworCWVsc2UKKwkJ dmFsIHw9IFVBUlQyX0NMS19ESVM7CisKKwl3cml0ZWwodmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJl ZzEpOworCisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7 Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19pc19lbmFibGVkKHN0cnVjdCBjbGtf aHcgKmh3KQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFy dF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19i YXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKKwl1MzIgdmFsOwor CisJdmFsID0gcmVhZGwodWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKworCWlmICh1YXJ0X2Nsb2Nr LT5jbG9ja19pZHggPT0gMCkKKwkJcmV0dXJuICEodmFsICYgVUFSVDFfQ0xLX0RJUyk7CisJZWxz ZQorCQlyZXR1cm4gISh2YWwgJiBVQVJUMl9DTEtfRElTKTsKK30KKworc3RhdGljIGludCBtdmVi dV91YXJ0X2Nsb2NrX3NhdmVfY29udGV4dChzdHJ1Y3QgY2xrX2h3ICpodykKK3sKKwlzdHJ1Y3Qg bXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcpOworCXN0cnVj dCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZSA9CisJCQkJCQl0b191YXJ0 X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7CisJdW5zaWduZWQgbG9uZyBmbGFnczsKKworCXNwaW5f bG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKKwl1YXJ0X2Nsb2NrLT5wbV9j b250ZXh0X3JlZzEgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCXVhcnRfY2xvY2st PnBtX2NvbnRleHRfcmVnMiA9IHJlYWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7CisJc3Bpbl91 bmxvY2tfaXJxcmVzdG9yZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisKKwlyZXR1cm4gMDsK K30KKworc3RhdGljIHZvaWQgbXZlYnVfdWFydF9jbG9ja19yZXN0b3JlX2NvbnRleHQoc3RydWN0 IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0 b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Ns b2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2ln bmVkIGxvbmcgZmxhZ3M7CisKKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBm bGFncyk7CisJd3JpdGVsKHVhcnRfY2xvY2stPnBtX2NvbnRleHRfcmVnMSwgdWFydF9jbG9ja19i YXNlLT5yZWcxKTsKKwl3cml0ZWwodWFydF9jbG9jay0+cG1fY29udGV4dF9yZWcyLCB1YXJ0X2Ns b2NrX2Jhc2UtPnJlZzIpOworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9j aywgZmxhZ3MpOworfQorCitzdGF0aWMgdW5zaWduZWQgbG9uZyBtdmVidV91YXJ0X2Nsb2NrX3Jl Y2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LAorCQkJCQkJICB1bnNpZ25lZCBsb25nIHBhcmVu dF9yYXRlKQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFy dF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19i YXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKKworCXJldHVybiBw YXJlbnRfcmF0ZSAvIHVhcnRfY2xvY2tfYmFzZS0+ZGl2OworfQorCitzdGF0aWMgbG9uZyBtdmVi dV91YXJ0X2Nsb2NrX3JvdW5kX3JhdGUoc3RydWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcg cmF0ZSwKKwkJCQkJdW5zaWduZWQgbG9uZyAqcGFyZW50X3JhdGUpCit7CisJc3RydWN0IG12ZWJ1 X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZl YnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9j a19iYXNlKHVhcnRfY2xvY2spOworCisJcmV0dXJuICpwYXJlbnRfcmF0ZSAvIHVhcnRfY2xvY2tf YmFzZS0+ZGl2OworfQorCitzdGF0aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfc2V0X3JhdGUoc3Ry dWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwKKwkJCQkgICAgIHVuc2lnbmVkIGxv bmcgcGFyZW50X3JhdGUpCit7CisJLyoKKwkgKiBXZSBtdXN0IHJlcG9ydCBzdWNjZXNzIGJ1dCB3 ZSBjYW4gZG8gc28gdW5jb25kaXRpb25hbGx5IGJlY2F1c2UKKwkgKiBtdmVidV91YXJ0X2Nsb2Nr X3JvdW5kX3JhdGUgcmV0dXJucyB2YWx1ZXMgdGhhdCBlbnN1cmUgdGhpcyBjYWxsIGlzIGEKKwkg KiBub3AuCisJICovCisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGNvbnN0IHN0cnVjdCBjbGtf b3BzIG12ZWJ1X3VhcnRfY2xvY2tfb3BzID0geworCS5wcmVwYXJlID0gbXZlYnVfdWFydF9jbG9j a19wcmVwYXJlLAorCS5lbmFibGUgPSBtdmVidV91YXJ0X2Nsb2NrX2VuYWJsZSwKKwkuZGlzYWJs ZSA9IG12ZWJ1X3VhcnRfY2xvY2tfZGlzYWJsZSwKKwkuaXNfZW5hYmxlZCA9IG12ZWJ1X3VhcnRf Y2xvY2tfaXNfZW5hYmxlZCwKKwkuc2F2ZV9jb250ZXh0ID0gbXZlYnVfdWFydF9jbG9ja19zYXZl X2NvbnRleHQsCisJLnJlc3RvcmVfY29udGV4dCA9IG12ZWJ1X3VhcnRfY2xvY2tfcmVzdG9yZV9j b250ZXh0LAorCS5yb3VuZF9yYXRlID0gbXZlYnVfdWFydF9jbG9ja19yb3VuZF9yYXRlLAorCS5z ZXRfcmF0ZSA9IG12ZWJ1X3VhcnRfY2xvY2tfc2V0X3JhdGUsCisJLnJlY2FsY19yYXRlID0gbXZl YnVfdWFydF9jbG9ja19yZWNhbGNfcmF0ZSwKK307CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9j bG9ja19yZWdpc3RlcihzdHJ1Y3QgZGV2aWNlICpkZXYsCisJCQkJICAgICBzdHJ1Y3QgbXZlYnVf dWFydF9jbG9jayAqdWFydF9jbG9jaywKKwkJCQkgICAgIGNvbnN0IGNoYXIgKm5hbWUsCisJCQkJ ICAgICBjb25zdCBjaGFyICpwYXJlbnRfbmFtZSkKK3sKKwlzdHJ1Y3QgY2xrX2luaXRfZGF0YSBp bml0ID0geyB9OworCisJdWFydF9jbG9jay0+Y2xrX2h3LmluaXQgPSAmaW5pdDsKKworCWluaXQu bmFtZSA9IG5hbWU7CisJaW5pdC5vcHMgPSAmbXZlYnVfdWFydF9jbG9ja19vcHM7CisJaW5pdC5m bGFncyA9IDA7CisJaW5pdC5udW1fcGFyZW50cyA9IDE7CisJaW5pdC5wYXJlbnRfbmFtZXMgPSAm cGFyZW50X25hbWU7CisKKwlyZXR1cm4gZGV2bV9jbGtfaHdfcmVnaXN0ZXIoZGV2LCAmdWFydF9j bG9jay0+Y2xrX2h3KTsKK30KKworc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3Byb2JlKHN0 cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3RhdGljIGNvbnN0IGNoYXIgKmNvbnN0 IHVhcnRfY2xrX25hbWVzW10gPSB7ICJ1YXJ0XzEiLCAidWFydF8yIiB9OworCXN0YXRpYyBjb25z dCBjaGFyICpjb25zdCBwYXJlbnRfY2xrX25hbWVzW10gPSB7ICJUQkctQS1QIiwgIlRCRy1CLVAi LAorCQkJCQkJCSJUQkctQS1TIiwgIlRCRy1CLVMiLAorCQkJCQkJCSJ4dGFsIiB9OworCXN0cnVj dCBjbGsgKnBhcmVudF9jbGtzW0FSUkFZX1NJWkUocGFyZW50X2Nsa19uYW1lcyldOworCXN0cnVj dCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZTsKKwlzdHJ1Y3QgY2xrX2h3 X29uZWNlbGxfZGF0YSAqaHdfY2xrX2RhdGE7CisJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYt PmRldjsKKwlpbnQgaSwgcGFyZW50X2Nsa19pZHgsIHJldDsKKwl1bnNpZ25lZCBsb25nIGRpdiwg cmF0ZTsKKwlzdHJ1Y3QgcmVzb3VyY2UgKnJlczsKKwl1bnNpZ25lZCBpbnQgZDEsIGQyOworCisJ QlVJTERfQlVHX09OKEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpICE9CisJCSAgICAgQVJSQVlf U0laRSh1YXJ0X2Nsb2NrX2Jhc2UtPmNsb2NrcykpOworCUJVSUxEX0JVR19PTihBUlJBWV9TSVpF KHBhcmVudF9jbGtfbmFtZXMpICE9CisJCSAgICAgQVJSQVlfU0laRSh1YXJ0X2Nsb2NrX2Jhc2Ut PnBhcmVudF9yYXRlcykpOworCisJdWFydF9jbG9ja19iYXNlID0gZGV2bV9remFsbG9jKGRldiwK KwkJCQkgICAgICAgc2l6ZW9mKCp1YXJ0X2Nsb2NrX2Jhc2UpLAorCQkJCSAgICAgICBHRlBfS0VS TkVMKTsKKwlpZiAoIXVhcnRfY2xvY2tfYmFzZSkKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlyZXMg PSBwbGF0Zm9ybV9nZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDApOworCWlmICgh cmVzKSB7CisJCWRldl9lcnIoZGV2LCAiQ291bGRuJ3QgZ2V0IGZpcnN0IHJlZ2lzdGVyXG4iKTsK KwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCisJLyoKKwkgKiBVQVJUIENsb2NrIENvbnRyb2wgcmVn aXN0ZXIgKHJlZzEgLyBVQVJUX0JSRFYpIGlzIGluIHRoZSBhZGRyZXNzCisJICogc3BhY2Ugb2Yg VUFSVDEgKHN0YW5kYXJkIFVBUlQgdmFyaWFudCksIGNvbnRyb2xzIHBhcmVudCBjbG9jayBhbmQK KwkgKiBkaXZpZGVycyBmb3IgYm90aCBVQVJUMSBhbmQgVUFSVDIgYW5kIGlzIHN1cHBsaWVkIHZp YSBEVCBhcyB0aGUgZmlyc3QKKwkgKiByZXNvdXJjZS4gVGhlcmVmb3JlIHVzZSBpb3JlbWFwKCkg cmF0aGVyIHRoYW4gaW9yZW1hcF9yZXNvdXJjZSgpIHRvCisJICogYXZvaWQgY29uZmxpY3RzIHdp dGggVUFSVDEgZHJpdmVyLiBBY2Nlc3MgdG8gVUFSVF9CUkRWIGlzIHByb3RlY3RlZAorCSAqIGJ5 IGEgbG9jayBzaGFyZWQgYmV0d2VlbiBjbG9jayBhbmQgVUFSVCBkcml2ZXIuCisJICovCisJdWFy dF9jbG9ja19iYXNlLT5yZWcxID0gZGV2bV9pb3JlbWFwKGRldiwgcmVzLT5zdGFydCwKKwkJCQkJ ICAgICByZXNvdXJjZV9zaXplKHJlcykpOworCWlmIChJU19FUlIodWFydF9jbG9ja19iYXNlLT5y ZWcxKSkKKwkJcmV0dXJuIFBUUl9FUlIodWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKworCXJlcyA9 IHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMSk7CisJaWYgKCFy ZXMpIHsKKwkJZGV2X2VycihkZXYsICJDb3VsZG4ndCBnZXQgc2Vjb25kIHJlZ2lzdGVyXG4iKTsK KwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCisJLyoKKwkgKiBVQVJUIDIgQmF1ZCBSYXRlIERpdmlz b3IgcmVnaXN0ZXIgKHJlZzIgLyBVQVJUX0JSRFYpIGlzIGluIGFkZHJlc3MKKwkgKiBzcGFjZSBv ZiBVQVJUMiAoZXh0ZW5kZWQgVUFSVCB2YXJpYW50KSwgY29udHJvbHMgb25seSBvbmUgVUFSVDIK KwkgKiBzcGVjaWZpYyBkaXZpZGVyIGFuZCBpcyBzdXBwbGllZCB2aWEgRFQgYXMgc2Vjb25kIHJl c291cmNlLgorCSAqIFRoZXJlZm9yZSB1c2UgaW9yZW1hcCgpIHJhdGhlciB0aGFuIGlvcmVtYXBf cmVzb3VyY2UoKSB0byBhdm9pZAorCSAqIGNvbmZsaWN0cyB3aXRoIFVBUlQyIGRyaXZlci4gQWNj ZXNzIHRvIFVBUlRfQlJEViBpcyBwcm90ZWN0ZWQgYnkgYQorCSAqIGJ5IGxvY2sgc2hhcmVkIGJl dHdlZW4gY2xvY2sgYW5kIFVBUlQgZHJpdmVyLgorCSAqLworCXVhcnRfY2xvY2tfYmFzZS0+cmVn MiA9IGRldm1faW9yZW1hcChkZXYsIHJlcy0+c3RhcnQsCisJCQkJCSAgICAgcmVzb3VyY2Vfc2l6 ZShyZXMpKTsKKwlpZiAoSVNfRVJSKHVhcnRfY2xvY2tfYmFzZS0+cmVnMikpCisJCXJldHVybiBQ VFJfRVJSKHVhcnRfY2xvY2tfYmFzZS0+cmVnMik7CisKKwlod19jbGtfZGF0YSA9IGRldm1fa3ph bGxvYyhkZXYsCisJCQkJICAgc3RydWN0X3NpemUoaHdfY2xrX2RhdGEsIGh3cywKKwkJCQkJICAg ICAgIEFSUkFZX1NJWkUodWFydF9jbGtfbmFtZXMpKSwKKwkJCQkgICBHRlBfS0VSTkVMKTsKKwlp ZiAoIWh3X2Nsa19kYXRhKQorCQlyZXR1cm4gLUVOT01FTTsKKworCWh3X2Nsa19kYXRhLT5udW0g PSBBUlJBWV9TSVpFKHVhcnRfY2xrX25hbWVzKTsKKwlmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0la RSh1YXJ0X2Nsa19uYW1lcyk7IGkrKykgeworCQlod19jbGtfZGF0YS0+aHdzW2ldID0gJnVhcnRf Y2xvY2tfYmFzZS0+Y2xvY2tzW2ldLmNsa19odzsKKwkJdWFydF9jbG9ja19iYXNlLT5jbG9ja3Nb aV0uY2xvY2tfaWR4ID0gaTsKKwl9CisKKwlwYXJlbnRfY2xrX2lkeCA9IC0xOworCisJZm9yIChp ID0gMDsgaSA8IEFSUkFZX1NJWkUocGFyZW50X2Nsa19uYW1lcyk7IGkrKykgeworCQlwYXJlbnRf Y2xrc1tpXSA9IGRldm1fY2xrX2dldChkZXYsIHBhcmVudF9jbGtfbmFtZXNbaV0pOworCQlpZiAo SVNfRVJSKHBhcmVudF9jbGtzW2ldKSkgeworCQkJaWYgKFBUUl9FUlIocGFyZW50X2Nsa3NbaV0p ID09IC1FUFJPQkVfREVGRVIpCisJCQkJcmV0dXJuIC1FUFJPQkVfREVGRVI7CisJCQlkZXZfd2Fy bihkZXYsICJDb3VsZG4ndCBnZXQgdGhlIHBhcmVudCBjbG9jayAlczogJWxkXG4iLAorCQkJCSBw YXJlbnRfY2xrX25hbWVzW2ldLCBQVFJfRVJSKHBhcmVudF9jbGtzW2ldKSk7CisJCQljb250aW51 ZTsKKwkJfQorCisJCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShwYXJlbnRfY2xrc1tpXSk7CisJ CWlmIChyZXQpIHsKKwkJCWRldl93YXJuKGRldiwgIkNvdWxkbid0IGVuYWJsZSBwYXJlbnQgY2xv Y2sgJXM6ICVkXG4iLAorCQkJCSBwYXJlbnRfY2xrX25hbWVzW2ldLCByZXQpOworCQkJY29udGlu dWU7CisJCX0KKwkJcmF0ZSA9IGNsa19nZXRfcmF0ZShwYXJlbnRfY2xrc1tpXSk7CisJCXVhcnRf Y2xvY2tfYmFzZS0+cGFyZW50X3JhdGVzW2ldID0gcmF0ZTsKKworCQlpZiAoaSAhPSBQQVJFTlRf Q0xPQ0tfWFRBTCkgeworCQkJLyoKKwkJCSAqIENhbGN1bGF0ZSB0aGUgc21hbGxlc3QgVEJHIGQx IGFuZCBkMiBkaXZpc29ycyB0aGF0CisJCQkgKiBzdGlsbCBjYW4gcHJvdmlkZSA5NjAwIGJhdWRy YXRlLgorCQkJICovCisJCQlkMSA9IERJVl9ST1VORF9VUChyYXRlLCA5NjAwICogT1NBTVBfREVG QVVMVF9ESVZJU09SICoKKwkJCQkJICBCUkRWX0JBVURfTUFYKTsKKwkJCWlmIChkMSA8IDEpCisJ CQkJZDEgPSAxOworCQkJZWxzZSBpZiAoZDEgPiBDTEtfVEJHX0RJVjFfTUFYKQorCQkJCWQxID0g Q0xLX1RCR19ESVYxX01BWDsKKworCQkJZDIgPSBESVZfUk9VTkRfVVAocmF0ZSwgOTYwMCAqIE9T QU1QX0RFRkFVTFRfRElWSVNPUiAqCisJCQkJCSAgQlJEVl9CQVVEX01BWCAqIGQxKTsKKwkJCWlm IChkMiA8IDEpCisJCQkJZDIgPSAxOworCQkJZWxzZSBpZiAoZDIgPiBDTEtfVEJHX0RJVjJfTUFY KQorCQkJCWQyID0gQ0xLX1RCR19ESVYyX01BWDsKKwkJfSBlbHNlIHsKKwkJCS8qCisJCQkgKiBX aGVuIFVBUlQgY2xvY2sgdXNlcyBYVEFMIGNsb2NrIGFzIGEgc291cmNlIHRoZW4gaXQKKwkJCSAq IGlzIG5vdCBwb3NzaWJsZSB0byB1c2UgZDEgYW5kIGQyIGRpdmlzb3JzLgorCQkJICovCisJCQlk MSA9IGQyID0gMTsKKwkJfQorCisJCS8qIFNraXAgY2xvY2sgc291cmNlIHdoaWNoIGNhbm5vdCBw cm92aWRlIDk2MDAgYmF1ZHJhdGUgKi8KKwkJaWYgKHJhdGUgPiA5NjAwICogT1NBTVBfREVGQVVM VF9ESVZJU09SICogQlJEVl9CQVVEX01BWCAqIGQxICoKKwkJCSAgIGQyKQorCQkJY29udGludWU7 CisKKwkJLyoKKwkJICogQ2hvb3NlIFRCRyBjbG9jayBzb3VyY2Ugd2l0aCB0aGUgc21hbGxlc3Qg ZGl2aXNvcnMuIFVzZSBYVEFMCisJCSAqIGNsb2NrIHNvdXJjZSBvbmx5IGluIGNhc2UgVEJHIGlz IG5vdCBhdmFpbGFibGUgYXMgWFRBTCBjYW5ub3QKKwkJICogYmUgdXNlZCBmb3IgYmF1ZHJhdGVz IGhpZ2hlciB0aGFuIDIzMDQwMC4KKwkJICovCisJCWlmIChwYXJlbnRfY2xrX2lkeCA9PSAtMSB8 fAorCQkgICAgKGkgIT0gUEFSRU5UX0NMT0NLX1hUQUwgJiYgZGl2ID4gZDEgKiBkMikpIHsKKwkJ CXBhcmVudF9jbGtfaWR4ID0gaTsKKwkJCWRpdiA9IGQxICogZDI7CisJCX0KKwl9CisKKwlmb3Ig KGkgPSAwOyBpIDwgQVJSQVlfU0laRShwYXJlbnRfY2xrX25hbWVzKTsgaSsrKSB7CisJCWlmIChp ID09IHBhcmVudF9jbGtfaWR4IHx8IElTX0VSUihwYXJlbnRfY2xrc1tpXSkpCisJCQljb250aW51 ZTsKKwkJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHBhcmVudF9jbGtzW2ldKTsKKwkJZGV2bV9jbGtf cHV0KGRldiwgcGFyZW50X2Nsa3NbaV0pOworCX0KKworCWlmIChwYXJlbnRfY2xrX2lkeCA9PSAt MSkgeworCQlkZXZfZXJyKGRldiwgIk5vIHVzYWJsZSBwYXJlbnQgY2xvY2tcbiIpOworCQlyZXR1 cm4gLUVOT0VOVDsKKwl9CisKKwl1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9pZHggPSBwYXJlbnRf Y2xrX2lkeDsKKwl1YXJ0X2Nsb2NrX2Jhc2UtPmRpdiA9IGRpdjsKKworCWRldl9ub3RpY2UoZGV2 LCAiVXNpbmcgcGFyZW50IGNsb2NrICVzIGFzIGJhc2UgVUFSVCBjbG9ja1xuIiwKKwkJICAgX19j bGtfZ2V0X25hbWUocGFyZW50X2Nsa3NbcGFyZW50X2Nsa19pZHhdKSk7CisKKwlmb3IgKGkgPSAw OyBpIDwgQVJSQVlfU0laRSh1YXJ0X2Nsa19uYW1lcyk7IGkrKykgeworCQlyZXQgPSBtdmVidV91 YXJ0X2Nsb2NrX3JlZ2lzdGVyKGRldiwKKwkJCQkmdWFydF9jbG9ja19iYXNlLT5jbG9ja3NbaV0s CisJCQkJdWFydF9jbGtfbmFtZXNbaV0sCisJCQkJX19jbGtfZ2V0X25hbWUocGFyZW50X2Nsa3Nb cGFyZW50X2Nsa19pZHhdKSk7CisJCWlmIChyZXQpIHsKKwkJCWRldl9lcnIoZGV2LCAiQ2FuJ3Qg cmVnaXN0ZXIgVUFSVCBjbG9jayAlZDogJWRcbiIsCisJCQkJaSwgcmV0KTsKKwkJCXJldHVybiBy ZXQ7CisJCX0KKwl9CisKKwlyZXR1cm4gZGV2bV9vZl9jbGtfYWRkX2h3X3Byb3ZpZGVyKGRldiwg b2ZfY2xrX2h3X29uZWNlbGxfZ2V0LAorCQkJCQkgICBod19jbGtfZGF0YSk7Cit9CisKK3N0YXRp YyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG12ZWJ1X3VhcnRfY2xvY2tfb2ZfbWF0Y2hbXSA9 IHsKKwl7IC5jb21wYXRpYmxlID0gIm1hcnZlbGwsYXJtYWRhLTM3MDAtdWFydC1jbG9jayIsIH0s CisJeyB9Cit9OworCitzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBtdmVidV91YXJ0X2Ns b2NrX3BsYXRmb3JtX2RyaXZlciA9IHsKKwkucHJvYmUgPSBtdmVidV91YXJ0X2Nsb2NrX3Byb2Jl LAorCS5kcml2ZXIJCT0geworCQkubmFtZQk9ICJtdmVidS11YXJ0LWNsb2NrIiwKKwkJLm9mX21h dGNoX3RhYmxlID0gbXZlYnVfdWFydF9jbG9ja19vZl9tYXRjaCwKKwl9LAorfTsKKwogc3RhdGlj IGludCBfX2luaXQgbXZlYnVfdWFydF9pbml0KHZvaWQpCiB7CiAJaW50IHJldDsKQEAgLTk4MCwx MCArMTQ4OCwxOSBAQCBzdGF0aWMgaW50IF9faW5pdCBtdmVidV91YXJ0X2luaXQodm9pZCkKIAlp ZiAocmV0KQogCQlyZXR1cm4gcmV0OwogCisJcmV0ID0gcGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVy KCZtdmVidV91YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZlcik7CisJaWYgKHJldCkgeworCQl1YXJ0 X3VucmVnaXN0ZXJfZHJpdmVyKCZtdmVidV91YXJ0X2RyaXZlcik7CisJCXJldHVybiByZXQ7CisJ fQorCiAJcmV0ID0gcGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVyKCZtdmVidV91YXJ0X3BsYXRmb3Jt X2RyaXZlcik7Ci0JaWYgKHJldCkKKwlpZiAocmV0KSB7CisJCXBsYXRmb3JtX2RyaXZlcl91bnJl Z2lzdGVyKCZtdmVidV91YXJ0X2Nsb2NrX3BsYXRmb3JtX2RyaXZlcik7CiAJCXVhcnRfdW5yZWdp c3Rlcl9kcml2ZXIoJm12ZWJ1X3VhcnRfZHJpdmVyKTsKKwkJcmV0dXJuIHJldDsKKwl9CiAKLQly ZXR1cm4gcmV0OworCXJldHVybiAwOwogfQogYXJjaF9pbml0Y2FsbChtdmVidV91YXJ0X2luaXQp OwotLSAKMi4zNC4xCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5lbEBsaXN0 cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4vbGlzdGlu Zm8vbGludXgtYXJtLWtlcm5lbAo=