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 D3B46C43217 for ; Sat, 19 Feb 2022 15:28:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242538AbiBSP2z (ORCPT ); Sat, 19 Feb 2022 10:28:55 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:42712 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231300AbiBSP2x (ORCPT ); Sat, 19 Feb 2022 10:28:53 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE2685D1B8; Sat, 19 Feb 2022 07:28:33 -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 ams.source.kernel.org (Postfix) with ESMTPS id 24F8BB80757; Sat, 19 Feb 2022 15:28:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ACED2C340EF; Sat, 19 Feb 2022 15:28:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645284510; bh=ORQrNJck3y+vTxPsxb5R4Ugx936Ozv1wZAPpdgksmXU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d6MCk0KMXRaMBJ29tLBPVqlXSUEFb/00BE7/G7VioMDd20z5vq3bUpOOjW7LkDuJv Ffx+JRzzZoIjiOy7JnyUzwpj0iXInbJBJF3ZrjdjHdJrG+K93w2Cvva82URdvcpLTZ 3B95qnIkc4o2rhbHmFZHsWBL5F87Q3JNzh6A8gTjJSOFyzYjwRbl/0LPZnsZBNf7FV 5/WZ+gGRAsW/EVR96FTrso9yXIGIBu9MkRiOlnvE9OrAYalqFyDWfuYeY9KPkJjacB imzO0nbKVkrGmXQBnWdYxqlJWUz8cFZRKxhNH/fYoNxHgaz77x3IntsuZDqICuaSP3 EAZETCDnYVnNg== From: =?UTF-8?q?Marek=20Beh=C3=BAn?= To: Greg Kroah-Hartman , Stephen Boyd Cc: Gregory Clement , =?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 v9 3/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Sat, 19 Feb 2022 16:28:15 +0100 Message-Id: <20220219152818.4319-4-kabel@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219152818.4319-1-kabel@kernel.org> References: <20220219152818.4319-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 v8: - fixed typo in commit message 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 DA7B7C433F5 for ; Sat, 19 Feb 2022 15:30:33 +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=gzIoLGl5SNMYMSkPFPWiFphtobwSEFCsH2VMlwHKNf8=; b=bib0hoKT4Lu9cT JtzWmj06Qffrvkuf7ouQRLLlp/dg6QZtTkfckAHlUYFoVUe3CRL3WZo+m4gfnVnB6DDaJDWkedaZ8 UtdFS/Mg+6dL8p3lK8PsgJFaECTa2ZyNjqOOBnSb9G5L55S9txmn9QZfZ8hfQSdTuAh0+lsNen7N+ cFKkJWrzeaCS4uVyXHOYWlZNhfP1y1Qecjvb/TSYqoZwmKGsI0IxubNT1HmqzrHQ7Ad7B+L31CijV eq+3P8QDXgZYpLA7f5dVUaQxKJEH/vcVsJM/PDmRM9dYkKBy0LGmsp6q3OnVQmMrXU7yJS5vnrO+E 4RalzKYb9iAgh8xp2UXQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nLRfb-00HAKL-Bf; Sat, 19 Feb 2022 15:29:11 +0000 Received: from ams.source.kernel.org ([145.40.68.75]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nLRey-00HA5T-OA for linux-arm-kernel@lists.infradead.org; Sat, 19 Feb 2022 15:28:37 +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 ams.source.kernel.org (Postfix) with ESMTPS id 1A1E8B80B40; Sat, 19 Feb 2022 15:28:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id ACED2C340EF; Sat, 19 Feb 2022 15:28:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1645284510; bh=ORQrNJck3y+vTxPsxb5R4Ugx936Ozv1wZAPpdgksmXU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d6MCk0KMXRaMBJ29tLBPVqlXSUEFb/00BE7/G7VioMDd20z5vq3bUpOOjW7LkDuJv Ffx+JRzzZoIjiOy7JnyUzwpj0iXInbJBJF3ZrjdjHdJrG+K93w2Cvva82URdvcpLTZ 3B95qnIkc4o2rhbHmFZHsWBL5F87Q3JNzh6A8gTjJSOFyzYjwRbl/0LPZnsZBNf7FV 5/WZ+gGRAsW/EVR96FTrso9yXIGIBu9MkRiOlnvE9OrAYalqFyDWfuYeY9KPkJjacB imzO0nbKVkrGmXQBnWdYxqlJWUz8cFZRKxhNH/fYoNxHgaz77x3IntsuZDqICuaSP3 EAZETCDnYVnNg== From: =?UTF-8?q?Marek=20Beh=C3=BAn?= To: Greg Kroah-Hartman , Stephen Boyd Cc: Gregory Clement , =?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 v9 3/6] serial: mvebu-uart: implement UART clock driver for configuring UART base clock Date: Sat, 19 Feb 2022 16:28:15 +0100 Message-Id: <20220219152818.4319-4-kabel@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220219152818.4319-1-kabel@kernel.org> References: <20220219152818.4319-1-kabel@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220219_072833_232329_4B2647A5 X-CRM114-Status: GOOD ( 42.77 ) 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 dmVyIGFuZCBVQVJUIGRyaXZlci4KCldlIG5lZWQgdG8gc2hhcmUgb25seSB0d28gMzItYml0IHJl Z2lzdGVycyBiZXR3ZWVuIHRoZSBVQVJUIGRyaXZlciBhbmQKdGhlIFVBUlQgY2xvY2sgZHJpdmVy OgotIFVBUlQgQ2xvY2sgQ29udHJvbAotIFVBUlQgMiBCYXVkIFJhdGUgRGl2aXNvcgpBY2Nlc3Mg dG8gdGhlc2UgdHdvIHJlZ2lzdGVycyBhcmUgcHJvdGVjdGVkIGJ5IG9uZSBzcGlubG9jayB0byBw cmV2ZW50CmFueSBjb25mbGljdHMuIEFjY2VzcyBpcyByZXF1aXJlZCBvbmx5IGR1cmluZyBwcm9i aW5nLCB3aGVuIGNoYW5naW5nCmJhdWRyYXRlIG9yIGR1cmluZyBzdXNwZW5kL3Jlc3VtZS4KCkhh cmR3YXJlIGNhbiBiZSBjb25maWd1cmVkIHRvIHVzZSBvbmUgb2YgZm9sbG93aW5nIGNsb2NrcyBh cyBVQVJUIHBhcmVudApjbG9jazogVEJHLUEtUCwgVEJHLUItUCwgVEJHLUEtUywgVEJHLUItUywg eHRhbC4gTm90IGV2ZXJ5IGNsb2NrIGlzCnVzYWJsZSBmb3IgaGlnaGVyIGJ1YWRyYXRlcy4gQW55 IHN1YnNldCBjYW4gYmUgc3BlY2lmaWVkIGluIHRoZQpkZXZpY2UtdHJlZSBhbmQgdGhlIGRyaXZl ciB3aWxsIGNob29zZSB0aGUgYmVzdCBvbmUgd2hpY2ggYWxzbyBzdGlsbApzdXBwb3J0cyB0aGUg bWFuZGF0b3J5IGJhdWRyYXRlIG9mIDk2MDAgQmQuIEZvciBzbW9vdGggYm9vdCBsb2cgb3V0cHV0 Cml0IGlzIG5lZWRlZCB0byBzcGVjaWZ5IGNsb2NrIHVzZWQgYnkgZWFybHkgY29uc29sZSwgb3Ro ZXJ3aXNlIGdhcmJhZ2UKd291bGQgYmUgcHJpbnRlZCBvbiBVQVJUIGR1cmluZyBwcm9iZSBvZiBV QVJUIGNsb2NrIGRyaXZlciBhbmQKdHJhbnNpdGlvbmluZyBmcm9tIGVhcmx5IGNvbnNvbGUgdG8g bm9ybWFsIGNvbnNvbGUuCgpXZSBhcmUgaW1wbGVtZW50aW5nIHRoaXMgdG8gYmUgYWJsZSB0byBj b25maWd1cmUgVEJHIGNsb2NrIGFzIFVBUlQKcGFyZW50IGNsb2NrLCB3aGljaCBpcyByZXF1aXJl ZCB0byBiZSBhYmxlIHRvIGFjaGlldmUgaGlnaGVyIGJhdWRyYXRlcwp0aGFuIDIzMDQwMCBCZC4g V2UgYWNoaWV2ZSB0aGlzIGJ5IHJlZmVyZW5jaW5nIHRoaXMgbmV3IFVBUlQgY2xvY2sKZGV2aWNl IG5vZGUgaW4gVUFSVCdzIGRldmljZSBub2RlLiBVQVJUIGNsb2NrIGRldmljZSBkcml2ZXIKYXV0 b21hdGljYWxseSBjaG9vc2VzIHRoZSBiZXN0IGNsb2NrIHNvdXJjZSBmb3IgVUFSVCBkcml2ZXIu CgpVbnRpbCBub3csIFVBUlQncyBkZXZpY2UtdHJlZSBub2RlIG5lZWRlZCB0byByZWZlcmVuY2Ug b25lIG9mIHRoZSBzdGF0aWMKY2xvY2tzICh4dGFsIG9yIG9uZSBvZiB0aGUgVEJHcykgYXMgcGFy ZW50IGNsb2NrIGluIHRoZSBgY2xvY2tzYApwaGFuZGxlIC0gdGhlIHBhcmVudCBjbG9jayB3aGlj aCB3YXMgY29uZmlndXJlZCBiZWZvcmUgYm9vdGluZyB0aGUKa2VybmVsLiBJZiBib290bG9hZGVy IGNoYW5nZWQgVUFSVCdzIHBhcmVudCBjbG9jaywgaXQgbmVlZGVkIHRvIGNoYW5nZQp0aGUgYGNs b2Nrc2AgcGhhbmRsZSBpbiBEVEIgY29ycmVzcG9uZGluZ2x5IGJlZm9yZSBib290aW5nLgoKRnJv bSBub3cgb24gYm90aCB0aGUgb2xkIG1lY2hhbmlzbSAoeHRhbCBvciBUQkcgcmVmZXJlbmNlZCBh cyBwYXJlbnQKY2xvY2sgaW4gYGNsb2Nrc2AgcGhhbmRsZSkgYW5kIHRoZSBuZXcgb25lIChVQVJU IGNsb2NrIHJlZmVyZW5jZWQgaW4gdGhlCmBjbG9ja3NgIHBoYW5kbGUpIGFyZSBzdXBwb3J0ZWQs IHRvIHByb3ZpZGUgZnVsbCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5CndpdGggZXhpc3RpbmcgRFRT IGZpbGVzLCBmdWxsIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCBleGlzdGluZyBib290Cmxv YWRlcnMsIGFuZCB0byBwcm92aWRlIG5ldyBmZWF0dXJlcyAocnVudGltZSBjbG9jayBjb25maWd1 cmF0aW9uIHRvCmFsbG93IGhpZ2hlciBiYXVkcmF0ZXMgdGhhbiAyMzA0MDAgQmQpLiBOZXcgZmVh dHVyZXMgYXJlIGF2YWlsYWJsZSBvbmx5CndpdGggbmV3IERUUyBmaWxlcy4KClRoZXJlIHdhcyBh bHNvIGEgZGlzY3Vzc2lvbiBhYm91dCBob3cgdGhlIFVBUlQgbm9kZSBhbmQgdGhlCmNsb2NrLWNv bnRyb2xsZXIgbm9kZSBjb3VsZCBiZSB3cmFwcGVkIHRvZ2V0aGVyIGluIGEgbmV3IGJpbmRpbmcg WzEsIDJdLgpBcyBleHBsYWluZWQgdGhlcmUsIHRoaXMgaXMgbm90IHBvc3NpYmxlIGlmIHdlIHdh bnQgdG8ga2VlcCBiYWNrd2FyZHMKY29tcGF0aWJpbGl0eSB3aXRoIGV4aXN0aW5nIGJvb3Rsb2Fk ZXJzLCBhbmQgdGh1cyB3ZSBhcmUgZG9pbmcgdGhpcyBieQpwdXR0aW5nIHRoZSBVQVJUIGNsb2Nr LWNvbnRyb2xsZXIgbm9kZSBpbnNpZGUgdGhlIFVBUlQxIG5vZGUuCgpbMV0gaHR0cHM6Ly9sb3Jl Lmtlcm5lbC5vcmcvbGludXgtc2VyaWFsLzIwMjIwMTIwMDAwNjUxLmluN3M2bmF6aWY1cWprbWVA cGFsaS8KWzJdIGh0dHBzOi8vbG9yZS5rZXJuZWwub3JnL2xpbnV4LXNlcmlhbC8yMDIyMDEyNTIw NDAwNi5BNkQwOUMzNDBFMEBzbXRwLmtlcm5lbC5vcmcvCgpTaWduZWQtb2ZmLWJ5OiBQYWxpIFJv aMOhciA8cGFsaUBrZXJuZWwub3JnPgpSZXZpZXdlZC1ieTogTWFyZWsgQmVow7puIDxrYWJlbEBr ZXJuZWwub3JnPgpTaWduZWQtb2ZmLWJ5OiBNYXJlayBCZWjDum4gPGthYmVsQGtlcm5lbC5vcmc+ Ci0tLQpDaGFuZ2VzIHNpbmNlIHY4OgotIGZpeGVkIHR5cG8gaW4gY29tbWl0IG1lc3NhZ2UKQ2hh bmdlcyBzaW5jZSB2NzoKLSBjb21taXQgbWVzc2FnZSB3YXMgcmV3cml0dGVuCi0gY2hhbmdlZCBj b21tZW50cyBhIGxpdHRsZQotIGZpeGVkIGluZGVudGF0aW9uIGF0IHNvbWUgcGxhY2VzCi0gYWRk ZWQgTWFyZWsncyBSZXZpZXdlZC1ieSB0YWcKLS0tCiBkcml2ZXJzL3R0eS9zZXJpYWwvS2NvbmZp ZyAgICAgIHwgICAxICsKIGRyaXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMgfCA1MjEgKysr KysrKysrKysrKysrKysrKysrKysrKysrKysrKy0KIDIgZmlsZXMgY2hhbmdlZCwgNTIwIGluc2Vy dGlvbnMoKyksIDIgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvZHJpdmVycy90dHkvc2VyaWFs L0tjb25maWcgYi9kcml2ZXJzL3R0eS9zZXJpYWwvS2NvbmZpZwppbmRleCAwZTVjY2IyNWJkYjEu LjliYzEzMjVkZDdiYSAxMDA2NDQKLS0tIGEvZHJpdmVycy90dHkvc2VyaWFsL0tjb25maWcKKysr IGIvZHJpdmVycy90dHkvc2VyaWFsL0tjb25maWcKQEAgLTE0NDUsNiArMTQ0NSw3IEBAIGNvbmZp ZyBTRVJJQUxfU1RNMzJfQ09OU09MRQogY29uZmlnIFNFUklBTF9NVkVCVV9VQVJUCiAJYm9vbCAi TWFydmVsbCBFQlUgc2VyaWFsIHBvcnQgc3VwcG9ydCIKIAlkZXBlbmRzIG9uIEFSQ0hfTVZFQlUg fHwgQ09NUElMRV9URVNUCisJZGVwZW5kcyBvbiBDT01NT05fQ0xLCiAJc2VsZWN0IFNFUklBTF9D T1JFCiAJaGVscAogCSAgVGhpcyBkcml2ZXIgaXMgZm9yIE1hcnZlbGwgRUJVIFNvQydzIFVBUlQu IElmIHlvdSBoYXZlIGEgbWFjaGluZQpkaWZmIC0tZ2l0IGEvZHJpdmVycy90dHkvc2VyaWFsL212 ZWJ1LXVhcnQuYyBiL2RyaXZlcnMvdHR5L3NlcmlhbC9tdmVidS11YXJ0LmMKaW5kZXggYWIyMjZk YTc1ZjdiLi41NjI3OGIyOWY1ZjUgMTAwNjQ0Ci0tLSBhL2RyaXZlcnMvdHR5L3NlcmlhbC9tdmVi dS11YXJ0LmMKKysrIGIvZHJpdmVycy90dHkvc2VyaWFsL212ZWJ1LXVhcnQuYwpAQCAtOCwxMiAr OCwxNCBAQAogKi8KIAogI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgorI2luY2x1ZGUgPGxpbnV4L2Ns ay1wcm92aWRlci5oPgogI2luY2x1ZGUgPGxpbnV4L2NvbnNvbGUuaD4KICNpbmNsdWRlIDxsaW51 eC9kZWxheS5oPgogI2luY2x1ZGUgPGxpbnV4L2RldmljZS5oPgogI2luY2x1ZGUgPGxpbnV4L2lu aXQuaD4KICNpbmNsdWRlIDxsaW51eC9pby5oPgogI2luY2x1ZGUgPGxpbnV4L2lvcG9sbC5oPgor I2luY2x1ZGUgPGxpbnV4L21hdGg2NC5oPgogI2luY2x1ZGUgPGxpbnV4L29mLmg+CiAjaW5jbHVk ZSA8bGludXgvb2ZfYWRkcmVzcy5oPgogI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPgpAQCAt NjgsOCArNzAsMzEgQEAKICNkZWZpbmUgIFNUQVRfQlJLX0VSUgkJKFNUQVRfQlJLX0RFVCB8IFNU QVRfRlJNX0VSUiBcCiAJCQkJIHwgU1RBVF9QQVJfRVJSIHwgU1RBVF9PVlJfRVJSKQogCisvKgor ICogTWFydmVsbCBBcm1hZGEgMzcwMCBGdW5jdGlvbmFsIFNwZWNpZmljYXRpb25zIGRlc2NyaWJl cyB0aGF0IGJpdCAyMSBvZiBVQVJUCisgKiBDbG9jayBDb250cm9sIHJlZ2lzdGVyIGNvbnRyb2xz IFVBUlQxIGFuZCBiaXQgMjAgY29udHJvbHMgVUFSVDIuIEJ1dCBpbgorICogcmVhbGl0eSBiaXQg MjEgY29udHJvbHMgVUFSVDIgYW5kIGJpdCAyMCBjb250cm9scyBVQVJUMS4gVGhpcyBzZWVtcyB0 byBiZSBhbgorICogZXJyb3IgaW4gTWFydmVsbCdzIGRvY3VtZW50YXRpb24uIEhlbmNlIGZvbGxv d2luZyBDTEtfRElTIG1hY3JvcyBhcmUgc3dhcHBlZC4KKyAqLworCiAjZGVmaW5lIFVBUlRfQlJE VgkJMHgxMAorLyogVGhlc2UgYml0cyBhcmUgbG9jYXRlZCBpbiBVQVJUMSBhZGRyZXNzIHNwYWNl IGFuZCBjb250cm9sIFVBUlQyICovCisjZGVmaW5lICBVQVJUMl9DTEtfRElTCQlCSVQoMjEpCisv KiBUaGVzZSBiaXRzIGFyZSBsb2NhdGVkIGluIFVBUlQxIGFkZHJlc3Mgc3BhY2UgYW5kIGNvbnRy b2wgVUFSVDEgKi8KKyNkZWZpbmUgIFVBUlQxX0NMS19ESVMJCUJJVCgyMCkKKy8qIFRoZXNlIGJp dHMgYXJlIGxvY2F0ZWQgaW4gVUFSVDEgYWRkcmVzcyBzcGFjZSBhbmQgY29udHJvbCBib3RoIFVB UlRzICovCisjZGVmaW5lICBDTEtfTk9fWFRBTAkJQklUKDE5KQorI2RlZmluZSAgQ0xLX1RCR19E SVYxX1NISUZUCTE1CisjZGVmaW5lICBDTEtfVEJHX0RJVjFfTUFTSwkweDcKKyNkZWZpbmUgIENM S19UQkdfRElWMV9NQVgJNgorI2RlZmluZSAgQ0xLX1RCR19ESVYyX1NISUZUCTEyCisjZGVmaW5l ICBDTEtfVEJHX0RJVjJfTUFTSwkweDcKKyNkZWZpbmUgIENMS19UQkdfRElWMl9NQVgJNgorI2Rl ZmluZSAgQ0xLX1RCR19TRUxfU0hJRlQJMTAKKyNkZWZpbmUgIENMS19UQkdfU0VMX01BU0sJMHgz CisvKiBUaGVzZSBiaXRzIGFyZSBsb2NhdGVkIGluIGJvdGggVUFSVHMgYWRkcmVzcyBzcGFjZSAq LwogI2RlZmluZSAgQlJEVl9CQVVEX01BU0sgICAgICAgICAweDNGRgorI2RlZmluZSAgQlJEVl9C QVVEX01BWAkJQlJEVl9CQVVEX01BU0sKIAogI2RlZmluZSBVQVJUX09TQU1QCQkweDE0CiAjZGVm aW5lICBPU0FNUF9ERUZBVUxUX0RJVklTT1IJMTYKQEAgLTE1Myw2ICsxNzgsOCBAQCBzdGF0aWMg c3RydWN0IG12ZWJ1X3VhcnQgKnRvX212dWFydChzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0KQogCiBz dGF0aWMgc3RydWN0IHVhcnRfcG9ydCBtdmVidV91YXJ0X3BvcnRzW01WRUJVX05SX1VBUlRTXTsK IAorc3RhdGljIERFRklORV9TUElOTE9DSyhtdmVidV91YXJ0X2xvY2spOworCiAvKiBDb3JlIFVB UlQgRHJpdmVyIE9wZXJhdGlvbnMgKi8KIHN0YXRpYyB1bnNpZ25lZCBpbnQgbXZlYnVfdWFydF90 eF9lbXB0eShzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0KQogewpAQCAtNDQ1LDYgKzQ3Miw3IEBAIHN0 YXRpYyB2b2lkIG12ZWJ1X3VhcnRfc2h1dGRvd24oc3RydWN0IHVhcnRfcG9ydCAqcG9ydCkKIHN0 YXRpYyBpbnQgbXZlYnVfdWFydF9iYXVkX3JhdGVfc2V0KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQs IHVuc2lnbmVkIGludCBiYXVkKQogewogCXVuc2lnbmVkIGludCBkX2Rpdmlzb3IsIG1fZGl2aXNv cjsKKwl1bnNpZ25lZCBsb25nIGZsYWdzOwogCXUzMiBicmR2LCBvc2FtcDsKIAogCWlmICghcG9y dC0+dWFydGNsaykKQEAgLTQ2MywxMCArNDkxLDEyIEBAIHN0YXRpYyBpbnQgbXZlYnVfdWFydF9i YXVkX3JhdGVfc2V0KHN0cnVjdCB1YXJ0X3BvcnQgKnBvcnQsIHVuc2lnbmVkIGludCBiYXVkKQog CW1fZGl2aXNvciA9IE9TQU1QX0RFRkFVTFRfRElWSVNPUjsKIAlkX2Rpdmlzb3IgPSBESVZfUk9V TkRfQ0xPU0VTVChwb3J0LT51YXJ0Y2xrLCBiYXVkICogbV9kaXZpc29yKTsKIAorCXNwaW5fbG9j a19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKIAlicmR2ID0gcmVhZGwocG9ydC0+ bWVtYmFzZSArIFVBUlRfQlJEVik7CiAJYnJkdiAmPSB+QlJEVl9CQVVEX01BU0s7CiAJYnJkdiB8 PSBkX2Rpdmlzb3I7CiAJd3JpdGVsKGJyZHYsIHBvcnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOwor CXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwogCiAJb3Nh bXAgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9PU0FNUCk7CiAJb3NhbXAgJj0gfk9TQU1Q X0RJVklTT1JTX01BU0s7CkBAIC03NjIsNiArNzkyLDcgQEAgc3RhdGljIGludCBtdmVidV91YXJ0 X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQogewogCXN0cnVjdCBtdmVidV91YXJ0ICptdnVh cnQgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKIAlzdHJ1Y3QgdWFydF9wb3J0ICpwb3J0ID0gbXZ1 YXJ0LT5wb3J0OworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CiAKIAl1YXJ0X3N1c3BlbmRfcG9ydCgm bXZlYnVfdWFydF9kcml2ZXIsIHBvcnQpOwogCkBAIC03NzAsNyArODAxLDkgQEAgc3RhdGljIGlu dCBtdmVidV91YXJ0X3N1c3BlbmQoc3RydWN0IGRldmljZSAqZGV2KQogCW12dWFydC0+cG1fcmVn cy5jdHJsID0gcmVhZGwocG9ydC0+bWVtYmFzZSArIFVBUlRfQ1RSTChwb3J0KSk7CiAJbXZ1YXJ0 LT5wbV9yZWdzLmludHIgPSByZWFkbChwb3J0LT5tZW1iYXNlICsgVUFSVF9JTlRSKHBvcnQpKTsK IAltdnVhcnQtPnBtX3JlZ3Muc3RhdCA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX1NUQVQp OworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsKIAltdnVhcnQt PnBtX3JlZ3MuYnJkdiA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX0JSRFYpOworCXNwaW5f dW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOwogCW12dWFydC0+cG1f cmVncy5vc2FtcCA9IHJlYWRsKHBvcnQtPm1lbWJhc2UgKyBVQVJUX09TQU1QKTsKIAogCWRldmlj ZV9zZXRfd2FrZXVwX2VuYWJsZShkZXYsIHRydWUpOwpAQCAtNzgyLDEzICs4MTUsMTYgQEAgc3Rh dGljIGludCBtdmVidV91YXJ0X3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICpkZXYpCiB7CiAJc3RydWN0 IG12ZWJ1X3VhcnQgKm12dWFydCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwogCXN0cnVjdCB1YXJ0 X3BvcnQgKnBvcnQgPSBtdnVhcnQtPnBvcnQ7CisJdW5zaWduZWQgbG9uZyBmbGFnczsKIAogCXdy aXRlbChtdnVhcnQtPnBtX3JlZ3MucmJyLCBwb3J0LT5tZW1iYXNlICsgVUFSVF9SQlIocG9ydCkp OwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MudHNoLCBwb3J0LT5tZW1iYXNlICsgVUFSVF9UU0go cG9ydCkpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3MuY3RybCwgcG9ydC0+bWVtYmFzZSArIFVB UlRfQ1RSTChwb3J0KSk7CiAJd3JpdGVsKG12dWFydC0+cG1fcmVncy5pbnRyLCBwb3J0LT5tZW1i YXNlICsgVUFSVF9JTlRSKHBvcnQpKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLnN0YXQsIHBv cnQtPm1lbWJhc2UgKyBVQVJUX1NUQVQpOworCXNwaW5fbG9ja19pcnFzYXZlKCZtdmVidV91YXJ0 X2xvY2ssIGZsYWdzKTsKIAl3cml0ZWwobXZ1YXJ0LT5wbV9yZWdzLmJyZHYsIHBvcnQtPm1lbWJh c2UgKyBVQVJUX0JSRFYpOworCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9j aywgZmxhZ3MpOwogCXdyaXRlbChtdnVhcnQtPnBtX3JlZ3Mub3NhbXAsIHBvcnQtPm1lbWJhc2Ug KyBVQVJUX09TQU1QKTsKIAogCXVhcnRfcmVzdW1lX3BvcnQoJm12ZWJ1X3VhcnRfZHJpdmVyLCBw b3J0KTsKQEAgLTk3Miw2ICsxMDA4LDQ3OCBAQCBzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZl ciBtdmVidV91YXJ0X3BsYXRmb3JtX2RyaXZlciA9IHsKIAl9LAogfTsKIAorLyogVGhpcyBjb2Rl IGlzIGJhc2VkIG9uIGNsay1maXhlZC1mYWN0b3IuYyBkcml2ZXIgYW5kIG1vZGlmaWVkLiAqLwor CitzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayB7CisJc3RydWN0IGNsa19odyBjbGtfaHc7CisJaW50 IGNsb2NrX2lkeDsKKwl1MzIgcG1fY29udGV4dF9yZWcxOworCXUzMiBwbV9jb250ZXh0X3JlZzI7 Cit9OworCitzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlIHsKKwlzdHJ1Y3QgbXZlYnVfdWFy dF9jbG9jayBjbG9ja3NbMl07CisJdW5zaWduZWQgaW50IHBhcmVudF9yYXRlc1s1XTsKKwlpbnQg cGFyZW50X2lkeDsKKwl1bnNpZ25lZCBpbnQgZGl2OworCXZvaWQgX19pb21lbSAqcmVnMTsKKwl2 b2lkIF9faW9tZW0gKnJlZzI7CisJYm9vbCBjb25maWd1cmVkOworfTsKKworI2RlZmluZSBQQVJF TlRfQ0xPQ0tfWFRBTCA0CisKKyNkZWZpbmUgdG9fdWFydF9jbG9jayhodykgY29udGFpbmVyX29m KGh3LCBzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jaywgY2xrX2h3KQorI2RlZmluZSB0b191YXJ0X2Ns b2NrX2Jhc2UodWFydF9jbG9jaykgY29udGFpbmVyX29mKHVhcnRfY2xvY2ssIFwKKwlzdHJ1Y3Qg bXZlYnVfdWFydF9jbG9ja19iYXNlLCBjbG9ja3NbdWFydF9jbG9jay0+Y2xvY2tfaWR4XSkKKwor c3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3ByZXBhcmUoc3RydWN0IGNsa19odyAqaHcpCit7 CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3 KTsKKwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJ CQkJdG9fdWFydF9jbG9ja19iYXNlKHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGludCBwcmV2X2Ns b2NrX2lkeCwgcHJldl9jbG9ja19yYXRlLCBwcmV2X2QxZDI7CisJdW5zaWduZWQgaW50IHBhcmVu dF9jbG9ja19pZHgsIHBhcmVudF9jbG9ja19yYXRlOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisJ dW5zaWduZWQgaW50IGQxLCBkMjsKKwl1NjQgZGl2aXNvcjsKKwl1MzIgdmFsOworCisJLyoKKwkg KiBUaGlzIGZ1bmN0aW9uIGp1c3QgcmVjb25maWd1cmVzIFVBUlQgQ2xvY2sgQ29udHJvbCByZWdp c3RlciAobG9jYXRlZAorCSAqIGluIFVBUlQxIGFkZHJlc3Mgc3BhY2Ugd2hpY2ggY29udHJvbHMg Ym90aCBVQVJUMSBhbmQgVUFSVDIpIHRvCisJICogc2VsZWN0ZWQgVUFSVCBiYXNlIGNsb2NrIGFu ZCByZWNhbGN1bGF0ZXMgY3VycmVudCBVQVJUMS9VQVJUMgorCSAqIGRpdmlzb3JzIGluIHRoZWly IGFkZHJlc3Mgc3BhY2VzLCBzbyB0aGF0IGZpbmFsIGJhdWRyYXRlIHdpbGwgbm90IGJlCisJICog Y2hhbmdlZCBieSBzd2l0Y2hpbmcgVUFSVCBwYXJlbnQgY2xvY2suIFRoaXMgaXMgcmVxdWlyZWQg Zm9yCisJICogb3RoZXJ3aXNlIGtlcm5lbCdzIGJvb3QgbG9nIHN0b3BzIHdvcmtpbmcgLSB3ZSBu ZWVkIHRvIGVuc3VyZSB0aGF0CisJICogVUFSVCBiYXVkcmF0ZSBkb2VzIG5vdCBjaGFuZ2UgZHVy aW5nIHRoaXMgc2V0dXAuIEl0IGlzIGEgb25lIHRpbWUKKwkgKiBvcGVyYXRpb24sIGl0IHdpbGwg ZXhlY3V0ZSBvbmx5IG9uY2UgYW5kIHNldCBgY29uZmlndXJlZGAgdG8gdHJ1ZSwKKwkgKiBhbmQg YmUgc2tpcHBlZCBvbiBzdWJzZXF1ZW50IGNhbGxzLiBCZWNhdXNlIHRoaXMgVUFSVCBDbG9jayBD b250cm9sCisJICogcmVnaXN0ZXIgKFVBUlRfQlJEVikgaXMgc2hhcmVkIGJldHdlZW4gVUFSVDEg YmF1ZHJhdGUgZnVuY3Rpb24sCisJICogVUFSVDEgY2xvY2sgc2VsZWN0b3IgYW5kIFVBUlQyIGNs b2NrIHNlbGVjdG9yLCBldmVyeSBhY2Nlc3MgdG8KKwkgKiBVQVJUX0JSRFYgKHJlZzEpIG5lZWRz IHRvIGJlIHByb3RlY3RlZCBieSBhIGxvY2suCisJICovCisKKwlzcGluX2xvY2tfaXJxc2F2ZSgm bXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisKKwlpZiAodWFydF9jbG9ja19iYXNlLT5jb25maWd1 cmVkKSB7CisJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3Mp OworCQlyZXR1cm4gMDsKKwl9CisKKwlwYXJlbnRfY2xvY2tfaWR4ID0gdWFydF9jbG9ja19iYXNl LT5wYXJlbnRfaWR4OworCXBhcmVudF9jbG9ja19yYXRlID0gdWFydF9jbG9ja19iYXNlLT5wYXJl bnRfcmF0ZXNbcGFyZW50X2Nsb2NrX2lkeF07CisKKwl2YWwgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jh c2UtPnJlZzEpOworCisJaWYgKHVhcnRfY2xvY2tfYmFzZS0+ZGl2ID4gQ0xLX1RCR19ESVYxX01B WCkgeworCQlkMSA9IENMS19UQkdfRElWMV9NQVg7CisJCWQyID0gdWFydF9jbG9ja19iYXNlLT5k aXYgLyBDTEtfVEJHX0RJVjFfTUFYOworCX0gZWxzZSB7CisJCWQxID0gdWFydF9jbG9ja19iYXNl LT5kaXY7CisJCWQyID0gMTsKKwl9CisKKwlpZiAodmFsICYgQ0xLX05PX1hUQUwpIHsKKwkJcHJl dl9jbG9ja19pZHggPSAodmFsID4+IENMS19UQkdfU0VMX1NISUZUKSAmIENMS19UQkdfU0VMX01B U0s7CisJCXByZXZfZDFkMiA9ICgodmFsID4+IENMS19UQkdfRElWMV9TSElGVCkgJiBDTEtfVEJH X0RJVjFfTUFTSykgKgorCQkJICAgICgodmFsID4+IENMS19UQkdfRElWMl9TSElGVCkgJiBDTEtf VEJHX0RJVjJfTUFTSyk7CisJfSBlbHNlIHsKKwkJcHJldl9jbG9ja19pZHggPSBQQVJFTlRfQ0xP Q0tfWFRBTDsKKwkJcHJldl9kMWQyID0gMTsKKwl9CisKKwkvKiBOb3RlIHRoYXQgdWFydF9jbG9j a19iYXNlLT5wYXJlbnRfcmF0ZXNbaV0gbWF5IG5vdCBiZSBhdmFpbGFibGUgKi8KKwlwcmV2X2Ns b2NrX3JhdGUgPSB1YXJ0X2Nsb2NrX2Jhc2UtPnBhcmVudF9yYXRlc1twcmV2X2Nsb2NrX2lkeF07 CisKKwkvKiBSZWNhbGN1bGF0ZSBVQVJUMSBkaXZpc29yIHNvIFVBUlQxIGJhdWRyYXRlIGRvZXMg bm90IGNoYW5nZSAqLworCWlmIChwcmV2X2Nsb2NrX3JhdGUpIHsKKwkJZGl2aXNvciA9IERJVl9V NjRfUk9VTkRfQ0xPU0VTVCgodTY0KSh2YWwgJiBCUkRWX0JBVURfTUFTSykgKgorCQkJCQkJcGFy ZW50X2Nsb2NrX3JhdGUgKiBwcmV2X2QxZDIsCisJCQkJCQlwcmV2X2Nsb2NrX3JhdGUgKiBkMSAq IGQyKTsKKwkJaWYgKGRpdmlzb3IgPCAxKQorCQkJZGl2aXNvciA9IDE7CisJCWVsc2UgaWYgKGRp dmlzb3IgPiBCUkRWX0JBVURfTUFYKQorCQkJZGl2aXNvciA9IEJSRFZfQkFVRF9NQVg7CisJCXZh bCA9ICh2YWwgJiB+QlJEVl9CQVVEX01BU0spIHwgZGl2aXNvcjsKKwl9CisKKwlpZiAocGFyZW50 X2Nsb2NrX2lkeCAhPSBQQVJFTlRfQ0xPQ0tfWFRBTCkgeworCQkvKiBEbyBub3QgdXNlIFhUQUws IHNlbGVjdCBUQkcgY2xvY2sgYW5kIFRCRyBkMSAqIGQyIGRpdmlzb3JzICovCisJCXZhbCB8PSBD TEtfTk9fWFRBTDsKKwkJdmFsICY9IH4oQ0xLX1RCR19ESVYxX01BU0sgPDwgQ0xLX1RCR19ESVYx X1NISUZUKTsKKwkJdmFsIHw9IGQxIDw8IENMS19UQkdfRElWMV9TSElGVDsKKwkJdmFsICY9IH4o Q0xLX1RCR19ESVYyX01BU0sgPDwgQ0xLX1RCR19ESVYyX1NISUZUKTsKKwkJdmFsIHw9IGQyIDw8 IENMS19UQkdfRElWMl9TSElGVDsKKwkJdmFsICY9IH4oQ0xLX1RCR19TRUxfTUFTSyA8PCBDTEtf VEJHX1NFTF9TSElGVCk7CisJCXZhbCB8PSBwYXJlbnRfY2xvY2tfaWR4IDw8IENMS19UQkdfU0VM X1NISUZUOworCX0gZWxzZSB7CisJCS8qIFVzZSBYVEFMLCBUQkcgYml0cyBhcmUgdGhlbiBpZ25v cmVkICovCisJCXZhbCAmPSB+Q0xLX05PX1hUQUw7CisJfQorCisJd3JpdGVsKHZhbCwgdWFydF9j bG9ja19iYXNlLT5yZWcxKTsKKworCS8qIFJlY2FsY3VsYXRlIFVBUlQyIGRpdmlzb3Igc28gVUFS VDIgYmF1ZHJhdGUgZG9lcyBub3QgY2hhbmdlICovCisJaWYgKHByZXZfY2xvY2tfcmF0ZSkgewor CQl2YWwgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOworCQlkaXZpc29yID0gRElWX1U2 NF9ST1VORF9DTE9TRVNUKCh1NjQpKHZhbCAmIEJSRFZfQkFVRF9NQVNLKSAqCisJCQkJCQlwYXJl bnRfY2xvY2tfcmF0ZSAqIHByZXZfZDFkMiwKKwkJCQkJCXByZXZfY2xvY2tfcmF0ZSAqIGQxICog ZDIpOworCQlpZiAoZGl2aXNvciA8IDEpCisJCQlkaXZpc29yID0gMTsKKwkJZWxzZSBpZiAoZGl2 aXNvciA+IEJSRFZfQkFVRF9NQVgpCisJCQlkaXZpc29yID0gQlJEVl9CQVVEX01BWDsKKwkJdmFs ID0gKHZhbCAmIH5CUkRWX0JBVURfTUFTSykgfCBkaXZpc29yOworCQl3cml0ZWwodmFsLCB1YXJ0 X2Nsb2NrX2Jhc2UtPnJlZzIpOworCX0KKworCXVhcnRfY2xvY2tfYmFzZS0+Y29uZmlndXJlZCA9 IHRydWU7CisKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdz KTsKKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfZW5hYmxl KHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Ns b2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAq dWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsK Kwl1bnNpZ25lZCBsb25nIGZsYWdzOworCXUzMiB2YWw7CisKKwlzcGluX2xvY2tfaXJxc2F2ZSgm bXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisKKwl2YWwgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2Ut PnJlZzEpOworCisJaWYgKHVhcnRfY2xvY2stPmNsb2NrX2lkeCA9PSAwKQorCQl2YWwgJj0gflVB UlQxX0NMS19ESVM7CisJZWxzZQorCQl2YWwgJj0gflVBUlQyX0NMS19ESVM7CisKKwl3cml0ZWwo dmFsLCB1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgm bXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQg bXZlYnVfdWFydF9jbG9ja19kaXNhYmxlKHN0cnVjdCBjbGtfaHcgKmh3KQoreworCXN0cnVjdCBt dmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0 IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRf Y2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKKwl1bnNpZ25lZCBsb25nIGZsYWdzOworCXUzMiB2YWw7 CisKKwlzcGluX2xvY2tfaXJxc2F2ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisKKwl2YWwg PSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzEpOworCisJaWYgKHVhcnRfY2xvY2stPmNsb2Nr X2lkeCA9PSAwKQorCQl2YWwgfD0gVUFSVDFfQ0xLX0RJUzsKKwllbHNlCisJCXZhbCB8PSBVQVJU Ml9DTEtfRElTOworCisJd3JpdGVsKHZhbCwgdWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKworCXNw aW5fdW5sb2NrX2lycXJlc3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworfQorCitzdGF0 aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfaXNfZW5hYmxlZChzdHJ1Y3QgY2xrX2h3ICpodykKK3sK KwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcp OworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZSA9CisJCQkJ CQl0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7CisJdTMyIHZhbDsKKworCXZhbCA9IHJl YWRsKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlpZiAodWFydF9jbG9jay0+Y2xvY2tfaWR4 ID09IDApCisJCXJldHVybiAhKHZhbCAmIFVBUlQxX0NMS19ESVMpOworCWVsc2UKKwkJcmV0dXJu ICEodmFsICYgVUFSVDJfQ0xLX0RJUyk7Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9j a19zYXZlX2NvbnRleHQoc3RydWN0IGNsa19odyAqaHcpCit7CisJc3RydWN0IG12ZWJ1X3VhcnRf Y2xvY2sgKnVhcnRfY2xvY2sgPSB0b191YXJ0X2Nsb2NrKGh3KTsKKwlzdHJ1Y3QgbXZlYnVfdWFy dF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2UgPQorCQkJCQkJdG9fdWFydF9jbG9ja19iYXNl KHVhcnRfY2xvY2spOworCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CisKKwlzcGluX2xvY2tfaXJxc2F2 ZSgmbXZlYnVfdWFydF9sb2NrLCBmbGFncyk7CisJdWFydF9jbG9jay0+cG1fY29udGV4dF9yZWcx ID0gcmVhZGwodWFydF9jbG9ja19iYXNlLT5yZWcxKTsKKwl1YXJ0X2Nsb2NrLT5wbV9jb250ZXh0 X3JlZzIgPSByZWFkbCh1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpOworCXNwaW5fdW5sb2NrX2lycXJl c3RvcmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRp YyB2b2lkIG12ZWJ1X3VhcnRfY2xvY2tfcmVzdG9yZV9jb250ZXh0KHN0cnVjdCBjbGtfaHcgKmh3 KQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9j ayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0K KwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0X2Nsb2NrKTsKKwl1bnNpZ25lZCBsb25nIGZs YWdzOworCisJc3Bpbl9sb2NrX2lycXNhdmUoJm12ZWJ1X3VhcnRfbG9jaywgZmxhZ3MpOworCXdy aXRlbCh1YXJ0X2Nsb2NrLT5wbV9jb250ZXh0X3JlZzEsIHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7 CisJd3JpdGVsKHVhcnRfY2xvY2stPnBtX2NvbnRleHRfcmVnMiwgdWFydF9jbG9ja19iYXNlLT5y ZWcyKTsKKwlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZtdmVidV91YXJ0X2xvY2ssIGZsYWdzKTsK K30KKworc3RhdGljIHVuc2lnbmVkIGxvbmcgbXZlYnVfdWFydF9jbG9ja19yZWNhbGNfcmF0ZShz dHJ1Y3QgY2xrX2h3ICpodywKKwkJCQkJCSAgdW5zaWduZWQgbG9uZyBwYXJlbnRfcmF0ZSkKK3sK KwlzdHJ1Y3QgbXZlYnVfdWFydF9jbG9jayAqdWFydF9jbG9jayA9IHRvX3VhcnRfY2xvY2soaHcp OworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2NrX2Jhc2UgKnVhcnRfY2xvY2tfYmFzZSA9CisJCQkJ CQl0b191YXJ0X2Nsb2NrX2Jhc2UodWFydF9jbG9jayk7CisKKwlyZXR1cm4gcGFyZW50X3JhdGUg LyB1YXJ0X2Nsb2NrX2Jhc2UtPmRpdjsKK30KKworc3RhdGljIGxvbmcgbXZlYnVfdWFydF9jbG9j a19yb3VuZF9yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LCB1bnNpZ25lZCBsb25nIHJhdGUsCisJCQkJ CXVuc2lnbmVkIGxvbmcgKnBhcmVudF9yYXRlKQoreworCXN0cnVjdCBtdmVidV91YXJ0X2Nsb2Nr ICp1YXJ0X2Nsb2NrID0gdG9fdWFydF9jbG9jayhodyk7CisJc3RydWN0IG12ZWJ1X3VhcnRfY2xv Y2tfYmFzZSAqdWFydF9jbG9ja19iYXNlID0KKwkJCQkJCXRvX3VhcnRfY2xvY2tfYmFzZSh1YXJ0 X2Nsb2NrKTsKKworCXJldHVybiAqcGFyZW50X3JhdGUgLyB1YXJ0X2Nsb2NrX2Jhc2UtPmRpdjsK K30KKworc3RhdGljIGludCBtdmVidV91YXJ0X2Nsb2NrX3NldF9yYXRlKHN0cnVjdCBjbGtfaHcg Kmh3LCB1bnNpZ25lZCBsb25nIHJhdGUsCisJCQkJICAgICB1bnNpZ25lZCBsb25nIHBhcmVudF9y YXRlKQoreworCS8qCisJICogV2UgbXVzdCByZXBvcnQgc3VjY2VzcyBidXQgd2UgY2FuIGRvIHNv IHVuY29uZGl0aW9uYWxseSBiZWNhdXNlCisJICogbXZlYnVfdWFydF9jbG9ja19yb3VuZF9yYXRl IHJldHVybnMgdmFsdWVzIHRoYXQgZW5zdXJlIHRoaXMgY2FsbCBpcyBhCisJICogbm9wLgorCSAq LworCisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgY2xrX29wcyBtdmVidV91 YXJ0X2Nsb2NrX29wcyA9IHsKKwkucHJlcGFyZSA9IG12ZWJ1X3VhcnRfY2xvY2tfcHJlcGFyZSwK KwkuZW5hYmxlID0gbXZlYnVfdWFydF9jbG9ja19lbmFibGUsCisJLmRpc2FibGUgPSBtdmVidV91 YXJ0X2Nsb2NrX2Rpc2FibGUsCisJLmlzX2VuYWJsZWQgPSBtdmVidV91YXJ0X2Nsb2NrX2lzX2Vu YWJsZWQsCisJLnNhdmVfY29udGV4dCA9IG12ZWJ1X3VhcnRfY2xvY2tfc2F2ZV9jb250ZXh0LAor CS5yZXN0b3JlX2NvbnRleHQgPSBtdmVidV91YXJ0X2Nsb2NrX3Jlc3RvcmVfY29udGV4dCwKKwku cm91bmRfcmF0ZSA9IG12ZWJ1X3VhcnRfY2xvY2tfcm91bmRfcmF0ZSwKKwkuc2V0X3JhdGUgPSBt dmVidV91YXJ0X2Nsb2NrX3NldF9yYXRlLAorCS5yZWNhbGNfcmF0ZSA9IG12ZWJ1X3VhcnRfY2xv Y2tfcmVjYWxjX3JhdGUsCit9OworCitzdGF0aWMgaW50IG12ZWJ1X3VhcnRfY2xvY2tfcmVnaXN0 ZXIoc3RydWN0IGRldmljZSAqZGV2LAorCQkJCSAgICAgc3RydWN0IG12ZWJ1X3VhcnRfY2xvY2sg KnVhcnRfY2xvY2ssCisJCQkJICAgICBjb25zdCBjaGFyICpuYW1lLAorCQkJCSAgICAgY29uc3Qg Y2hhciAqcGFyZW50X25hbWUpCit7CisJc3RydWN0IGNsa19pbml0X2RhdGEgaW5pdCA9IHsgfTsK KworCXVhcnRfY2xvY2stPmNsa19ody5pbml0ID0gJmluaXQ7CisKKwlpbml0Lm5hbWUgPSBuYW1l OworCWluaXQub3BzID0gJm12ZWJ1X3VhcnRfY2xvY2tfb3BzOworCWluaXQuZmxhZ3MgPSAwOwor CWluaXQubnVtX3BhcmVudHMgPSAxOworCWluaXQucGFyZW50X25hbWVzID0gJnBhcmVudF9uYW1l OworCisJcmV0dXJuIGRldm1fY2xrX2h3X3JlZ2lzdGVyKGRldiwgJnVhcnRfY2xvY2stPmNsa19o dyk7Cit9CisKK3N0YXRpYyBpbnQgbXZlYnVfdWFydF9jbG9ja19wcm9iZShzdHJ1Y3QgcGxhdGZv cm1fZGV2aWNlICpwZGV2KQoreworCXN0YXRpYyBjb25zdCBjaGFyICpjb25zdCB1YXJ0X2Nsa19u YW1lc1tdID0geyAidWFydF8xIiwgInVhcnRfMiIgfTsKKwlzdGF0aWMgY29uc3QgY2hhciAqY29u c3QgcGFyZW50X2Nsa19uYW1lc1tdID0geyAiVEJHLUEtUCIsICJUQkctQi1QIiwKKwkJCQkJCQki VEJHLUEtUyIsICJUQkctQi1TIiwKKwkJCQkJCQkieHRhbCIgfTsKKwlzdHJ1Y3QgY2xrICpwYXJl bnRfY2xrc1tBUlJBWV9TSVpFKHBhcmVudF9jbGtfbmFtZXMpXTsKKwlzdHJ1Y3QgbXZlYnVfdWFy dF9jbG9ja19iYXNlICp1YXJ0X2Nsb2NrX2Jhc2U7CisJc3RydWN0IGNsa19od19vbmVjZWxsX2Rh dGEgKmh3X2Nsa19kYXRhOworCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7CisJaW50 IGksIHBhcmVudF9jbGtfaWR4LCByZXQ7CisJdW5zaWduZWQgbG9uZyBkaXYsIHJhdGU7CisJc3Ry dWN0IHJlc291cmNlICpyZXM7CisJdW5zaWduZWQgaW50IGQxLCBkMjsKKworCUJVSUxEX0JVR19P TihBUlJBWV9TSVpFKHVhcnRfY2xrX25hbWVzKSAhPQorCQkgICAgIEFSUkFZX1NJWkUodWFydF9j bG9ja19iYXNlLT5jbG9ja3MpKTsKKwlCVUlMRF9CVUdfT04oQVJSQVlfU0laRShwYXJlbnRfY2xr X25hbWVzKSAhPQorCQkgICAgIEFSUkFZX1NJWkUodWFydF9jbG9ja19iYXNlLT5wYXJlbnRfcmF0 ZXMpKTsKKworCXVhcnRfY2xvY2tfYmFzZSA9IGRldm1fa3phbGxvYyhkZXYsCisJCQkJICAgICAg IHNpemVvZigqdWFydF9jbG9ja19iYXNlKSwKKwkJCQkgICAgICAgR0ZQX0tFUk5FTCk7CisJaWYg KCF1YXJ0X2Nsb2NrX2Jhc2UpCisJCXJldHVybiAtRU5PTUVNOworCisJcmVzID0gcGxhdGZvcm1f Z2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKKwlpZiAoIXJlcykgeworCQlk ZXZfZXJyKGRldiwgIkNvdWxkbid0IGdldCBmaXJzdCByZWdpc3RlclxuIik7CisJCXJldHVybiAt RU5PRU5UOworCX0KKworCS8qCisJICogVUFSVCBDbG9jayBDb250cm9sIHJlZ2lzdGVyIChyZWcx IC8gVUFSVF9CUkRWKSBpcyBpbiB0aGUgYWRkcmVzcworCSAqIHNwYWNlIG9mIFVBUlQxIChzdGFu ZGFyZCBVQVJUIHZhcmlhbnQpLCBjb250cm9scyBwYXJlbnQgY2xvY2sgYW5kCisJICogZGl2aWRl cnMgZm9yIGJvdGggVUFSVDEgYW5kIFVBUlQyIGFuZCBpcyBzdXBwbGllZCB2aWEgRFQgYXMgdGhl IGZpcnN0CisJICogcmVzb3VyY2UuIFRoZXJlZm9yZSB1c2UgaW9yZW1hcCgpIHJhdGhlciB0aGFu IGlvcmVtYXBfcmVzb3VyY2UoKSB0bworCSAqIGF2b2lkIGNvbmZsaWN0cyB3aXRoIFVBUlQxIGRy aXZlci4gQWNjZXNzIHRvIFVBUlRfQlJEViBpcyBwcm90ZWN0ZWQKKwkgKiBieSBhIGxvY2sgc2hh cmVkIGJldHdlZW4gY2xvY2sgYW5kIFVBUlQgZHJpdmVyLgorCSAqLworCXVhcnRfY2xvY2tfYmFz ZS0+cmVnMSA9IGRldm1faW9yZW1hcChkZXYsIHJlcy0+c3RhcnQsCisJCQkJCSAgICAgcmVzb3Vy Y2Vfc2l6ZShyZXMpKTsKKwlpZiAoSVNfRVJSKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSkpCisJCXJl dHVybiBQVFJfRVJSKHVhcnRfY2xvY2tfYmFzZS0+cmVnMSk7CisKKwlyZXMgPSBwbGF0Zm9ybV9n ZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEpOworCWlmICghcmVzKSB7CisJCWRl dl9lcnIoZGV2LCAiQ291bGRuJ3QgZ2V0IHNlY29uZCByZWdpc3RlclxuIik7CisJCXJldHVybiAt RU5PRU5UOworCX0KKworCS8qCisJICogVUFSVCAyIEJhdWQgUmF0ZSBEaXZpc29yIHJlZ2lzdGVy IChyZWcyIC8gVUFSVF9CUkRWKSBpcyBpbiBhZGRyZXNzCisJICogc3BhY2Ugb2YgVUFSVDIgKGV4 dGVuZGVkIFVBUlQgdmFyaWFudCksIGNvbnRyb2xzIG9ubHkgb25lIFVBUlQyCisJICogc3BlY2lm aWMgZGl2aWRlciBhbmQgaXMgc3VwcGxpZWQgdmlhIERUIGFzIHNlY29uZCByZXNvdXJjZS4KKwkg KiBUaGVyZWZvcmUgdXNlIGlvcmVtYXAoKSByYXRoZXIgdGhhbiBpb3JlbWFwX3Jlc291cmNlKCkg dG8gYXZvaWQKKwkgKiBjb25mbGljdHMgd2l0aCBVQVJUMiBkcml2ZXIuIEFjY2VzcyB0byBVQVJU X0JSRFYgaXMgcHJvdGVjdGVkIGJ5IGEKKwkgKiBieSBsb2NrIHNoYXJlZCBiZXR3ZWVuIGNsb2Nr IGFuZCBVQVJUIGRyaXZlci4KKwkgKi8KKwl1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIgPSBkZXZtX2lv cmVtYXAoZGV2LCByZXMtPnN0YXJ0LAorCQkJCQkgICAgIHJlc291cmNlX3NpemUocmVzKSk7CisJ aWYgKElTX0VSUih1YXJ0X2Nsb2NrX2Jhc2UtPnJlZzIpKQorCQlyZXR1cm4gUFRSX0VSUih1YXJ0 X2Nsb2NrX2Jhc2UtPnJlZzIpOworCisJaHdfY2xrX2RhdGEgPSBkZXZtX2t6YWxsb2MoZGV2LAor CQkJCSAgIHN0cnVjdF9zaXplKGh3X2Nsa19kYXRhLCBod3MsCisJCQkJCSAgICAgICBBUlJBWV9T SVpFKHVhcnRfY2xrX25hbWVzKSksCisJCQkJICAgR0ZQX0tFUk5FTCk7CisJaWYgKCFod19jbGtf ZGF0YSkKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlod19jbGtfZGF0YS0+bnVtID0gQVJSQVlfU0la RSh1YXJ0X2Nsa19uYW1lcyk7CisJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUodWFydF9jbGtf bmFtZXMpOyBpKyspIHsKKwkJaHdfY2xrX2RhdGEtPmh3c1tpXSA9ICZ1YXJ0X2Nsb2NrX2Jhc2Ut PmNsb2Nrc1tpXS5jbGtfaHc7CisJCXVhcnRfY2xvY2tfYmFzZS0+Y2xvY2tzW2ldLmNsb2NrX2lk eCA9IGk7CisJfQorCisJcGFyZW50X2Nsa19pZHggPSAtMTsKKworCWZvciAoaSA9IDA7IGkgPCBB UlJBWV9TSVpFKHBhcmVudF9jbGtfbmFtZXMpOyBpKyspIHsKKwkJcGFyZW50X2Nsa3NbaV0gPSBk ZXZtX2Nsa19nZXQoZGV2LCBwYXJlbnRfY2xrX25hbWVzW2ldKTsKKwkJaWYgKElTX0VSUihwYXJl bnRfY2xrc1tpXSkpIHsKKwkJCWlmIChQVFJfRVJSKHBhcmVudF9jbGtzW2ldKSA9PSAtRVBST0JF X0RFRkVSKQorCQkJCXJldHVybiAtRVBST0JFX0RFRkVSOworCQkJZGV2X3dhcm4oZGV2LCAiQ291 bGRuJ3QgZ2V0IHRoZSBwYXJlbnQgY2xvY2sgJXM6ICVsZFxuIiwKKwkJCQkgcGFyZW50X2Nsa19u YW1lc1tpXSwgUFRSX0VSUihwYXJlbnRfY2xrc1tpXSkpOworCQkJY29udGludWU7CisJCX0KKwor CQlyZXQgPSBjbGtfcHJlcGFyZV9lbmFibGUocGFyZW50X2Nsa3NbaV0pOworCQlpZiAocmV0KSB7 CisJCQlkZXZfd2FybihkZXYsICJDb3VsZG4ndCBlbmFibGUgcGFyZW50IGNsb2NrICVzOiAlZFxu IiwKKwkJCQkgcGFyZW50X2Nsa19uYW1lc1tpXSwgcmV0KTsKKwkJCWNvbnRpbnVlOworCQl9CisJ CXJhdGUgPSBjbGtfZ2V0X3JhdGUocGFyZW50X2Nsa3NbaV0pOworCQl1YXJ0X2Nsb2NrX2Jhc2Ut PnBhcmVudF9yYXRlc1tpXSA9IHJhdGU7CisKKwkJaWYgKGkgIT0gUEFSRU5UX0NMT0NLX1hUQUwp IHsKKwkJCS8qCisJCQkgKiBDYWxjdWxhdGUgdGhlIHNtYWxsZXN0IFRCRyBkMSBhbmQgZDIgZGl2 aXNvcnMgdGhhdAorCQkJICogc3RpbGwgY2FuIHByb3ZpZGUgOTYwMCBiYXVkcmF0ZS4KKwkJCSAq LworCQkJZDEgPSBESVZfUk9VTkRfVVAocmF0ZSwgOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNP UiAqCisJCQkJCSAgQlJEVl9CQVVEX01BWCk7CisJCQlpZiAoZDEgPCAxKQorCQkJCWQxID0gMTsK KwkJCWVsc2UgaWYgKGQxID4gQ0xLX1RCR19ESVYxX01BWCkKKwkJCQlkMSA9IENMS19UQkdfRElW MV9NQVg7CisKKwkJCWQyID0gRElWX1JPVU5EX1VQKHJhdGUsIDk2MDAgKiBPU0FNUF9ERUZBVUxU X0RJVklTT1IgKgorCQkJCQkgIEJSRFZfQkFVRF9NQVggKiBkMSk7CisJCQlpZiAoZDIgPCAxKQor CQkJCWQyID0gMTsKKwkJCWVsc2UgaWYgKGQyID4gQ0xLX1RCR19ESVYyX01BWCkKKwkJCQlkMiA9 IENMS19UQkdfRElWMl9NQVg7CisJCX0gZWxzZSB7CisJCQkvKgorCQkJICogV2hlbiBVQVJUIGNs b2NrIHVzZXMgWFRBTCBjbG9jayBhcyBhIHNvdXJjZSB0aGVuIGl0CisJCQkgKiBpcyBub3QgcG9z c2libGUgdG8gdXNlIGQxIGFuZCBkMiBkaXZpc29ycy4KKwkJCSAqLworCQkJZDEgPSBkMiA9IDE7 CisJCX0KKworCQkvKiBTa2lwIGNsb2NrIHNvdXJjZSB3aGljaCBjYW5ub3QgcHJvdmlkZSA5NjAw IGJhdWRyYXRlICovCisJCWlmIChyYXRlID4gOTYwMCAqIE9TQU1QX0RFRkFVTFRfRElWSVNPUiAq IEJSRFZfQkFVRF9NQVggKiBkMSAqCisJCQkgICBkMikKKwkJCWNvbnRpbnVlOworCisJCS8qCisJ CSAqIENob29zZSBUQkcgY2xvY2sgc291cmNlIHdpdGggdGhlIHNtYWxsZXN0IGRpdmlzb3JzLiBV c2UgWFRBTAorCQkgKiBjbG9jayBzb3VyY2Ugb25seSBpbiBjYXNlIFRCRyBpcyBub3QgYXZhaWxh YmxlIGFzIFhUQUwgY2Fubm90CisJCSAqIGJlIHVzZWQgZm9yIGJhdWRyYXRlcyBoaWdoZXIgdGhh biAyMzA0MDAuCisJCSAqLworCQlpZiAocGFyZW50X2Nsa19pZHggPT0gLTEgfHwKKwkJICAgIChp ICE9IFBBUkVOVF9DTE9DS19YVEFMICYmIGRpdiA+IGQxICogZDIpKSB7CisJCQlwYXJlbnRfY2xr X2lkeCA9IGk7CisJCQlkaXYgPSBkMSAqIGQyOworCQl9CisJfQorCisJZm9yIChpID0gMDsgaSA8 IEFSUkFZX1NJWkUocGFyZW50X2Nsa19uYW1lcyk7IGkrKykgeworCQlpZiAoaSA9PSBwYXJlbnRf Y2xrX2lkeCB8fCBJU19FUlIocGFyZW50X2Nsa3NbaV0pKQorCQkJY29udGludWU7CisJCWNsa19k aXNhYmxlX3VucHJlcGFyZShwYXJlbnRfY2xrc1tpXSk7CisJCWRldm1fY2xrX3B1dChkZXYsIHBh cmVudF9jbGtzW2ldKTsKKwl9CisKKwlpZiAocGFyZW50X2Nsa19pZHggPT0gLTEpIHsKKwkJZGV2 X2VycihkZXYsICJObyB1c2FibGUgcGFyZW50IGNsb2NrXG4iKTsKKwkJcmV0dXJuIC1FTk9FTlQ7 CisJfQorCisJdWFydF9jbG9ja19iYXNlLT5wYXJlbnRfaWR4ID0gcGFyZW50X2Nsa19pZHg7CisJ dWFydF9jbG9ja19iYXNlLT5kaXYgPSBkaXY7CisKKwlkZXZfbm90aWNlKGRldiwgIlVzaW5nIHBh cmVudCBjbG9jayAlcyBhcyBiYXNlIFVBUlQgY2xvY2tcbiIsCisJCSAgIF9fY2xrX2dldF9uYW1l KHBhcmVudF9jbGtzW3BhcmVudF9jbGtfaWR4XSkpOworCisJZm9yIChpID0gMDsgaSA8IEFSUkFZ X1NJWkUodWFydF9jbGtfbmFtZXMpOyBpKyspIHsKKwkJcmV0ID0gbXZlYnVfdWFydF9jbG9ja19y ZWdpc3RlcihkZXYsCisJCQkJJnVhcnRfY2xvY2tfYmFzZS0+Y2xvY2tzW2ldLAorCQkJCXVhcnRf Y2xrX25hbWVzW2ldLAorCQkJCV9fY2xrX2dldF9uYW1lKHBhcmVudF9jbGtzW3BhcmVudF9jbGtf aWR4XSkpOworCQlpZiAocmV0KSB7CisJCQlkZXZfZXJyKGRldiwgIkNhbid0IHJlZ2lzdGVyIFVB UlQgY2xvY2sgJWQ6ICVkXG4iLAorCQkJCWksIHJldCk7CisJCQlyZXR1cm4gcmV0OworCQl9CisJ fQorCisJcmV0dXJuIGRldm1fb2ZfY2xrX2FkZF9od19wcm92aWRlcihkZXYsIG9mX2Nsa19od19v bmVjZWxsX2dldCwKKwkJCQkJICAgaHdfY2xrX2RhdGEpOworfQorCitzdGF0aWMgY29uc3Qgc3Ry dWN0IG9mX2RldmljZV9pZCBtdmVidV91YXJ0X2Nsb2NrX29mX21hdGNoW10gPSB7CisJeyAuY29t cGF0aWJsZSA9ICJtYXJ2ZWxsLGFybWFkYS0zNzAwLXVhcnQtY2xvY2siLCB9LAorCXsgfQorfTsK Kworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbXZlYnVfdWFydF9jbG9ja19wbGF0Zm9y bV9kcml2ZXIgPSB7CisJLnByb2JlID0gbXZlYnVfdWFydF9jbG9ja19wcm9iZSwKKwkuZHJpdmVy CQk9IHsKKwkJLm5hbWUJPSAibXZlYnUtdWFydC1jbG9jayIsCisJCS5vZl9tYXRjaF90YWJsZSA9 IG12ZWJ1X3VhcnRfY2xvY2tfb2ZfbWF0Y2gsCisJfSwKK307CisKIHN0YXRpYyBpbnQgX19pbml0 IG12ZWJ1X3VhcnRfaW5pdCh2b2lkKQogewogCWludCByZXQ7CkBAIC05ODAsMTAgKzE0ODgsMTkg QEAgc3RhdGljIGludCBfX2luaXQgbXZlYnVfdWFydF9pbml0KHZvaWQpCiAJaWYgKHJldCkKIAkJ cmV0dXJuIHJldDsKIAorCXJldCA9IHBsYXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmbXZlYnVfdWFy dF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIpOworCWlmIChyZXQpIHsKKwkJdWFydF91bnJlZ2lzdGVy X2RyaXZlcigmbXZlYnVfdWFydF9kcml2ZXIpOworCQlyZXR1cm4gcmV0OworCX0KKwogCXJldCA9 IHBsYXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmbXZlYnVfdWFydF9wbGF0Zm9ybV9kcml2ZXIpOwot CWlmIChyZXQpCisJaWYgKHJldCkgeworCQlwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmbXZl YnVfdWFydF9jbG9ja19wbGF0Zm9ybV9kcml2ZXIpOwogCQl1YXJ0X3VucmVnaXN0ZXJfZHJpdmVy KCZtdmVidV91YXJ0X2RyaXZlcik7CisJCXJldHVybiByZXQ7CisJfQogCi0JcmV0dXJuIHJldDsK KwlyZXR1cm4gMDsKIH0KIGFyY2hfaW5pdGNhbGwobXZlYnVfdWFydF9pbml0KTsKLS0gCjIuMzQu MQoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4 LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFk Lm9yZwpodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFy bS1rZXJuZWwK