* [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support
@ 2018-01-08 22:16 Jolly Shah
2018-01-08 22:16 ` [RFC PATCH 1/2] drivers: clk: Add clk_get_children support Jolly Shah
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Jolly Shah @ 2018-01-08 22:16 UTC (permalink / raw)
To: mturquette, sboyd, michal.simek, linux-clk
Cc: linux-arm-kernel, linux-kernel, Jolly Shah
Add clock driver for ZynqMP
Jolly Shah (2):
drivers: clk: Add clk_get_children support
drivers: clk: Add ZynqMP clock driver
.../devicetree/bindings/clock/zynq_mpsoc.txt | 163 +++++
drivers/clk/Kconfig | 1 +
drivers/clk/Makefile | 1 +
drivers/clk/clk.c | 28 +
drivers/clk/zynqmp/Kconfig | 8 +
drivers/clk/zynqmp/Makefile | 3 +
drivers/clk/zynqmp/clk-gate-zynqmp.c | 158 +++++
drivers/clk/zynqmp/clk-mux-zynqmp.c | 190 ++++++
drivers/clk/zynqmp/clkc.c | 707 +++++++++++++++++++++
drivers/clk/zynqmp/divider.c | 239 +++++++
drivers/clk/zynqmp/pll.c | 384 +++++++++++
include/linux/clk-provider.h | 1 +
include/linux/clk/zynqmp.h | 46 ++
13 files changed, 1929 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/zynq_mpsoc.txt
create mode 100644 drivers/clk/zynqmp/Kconfig
create mode 100644 drivers/clk/zynqmp/Makefile
create mode 100644 drivers/clk/zynqmp/clk-gate-zynqmp.c
create mode 100644 drivers/clk/zynqmp/clk-mux-zynqmp.c
create mode 100644 drivers/clk/zynqmp/clkc.c
create mode 100644 drivers/clk/zynqmp/divider.c
create mode 100644 drivers/clk/zynqmp/pll.c
create mode 100644 include/linux/clk/zynqmp.h
--
2.7.4
^ permalink raw reply [flat|nested] 10+ messages in thread* [RFC PATCH 1/2] drivers: clk: Add clk_get_children support 2018-01-08 22:16 [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Jolly Shah @ 2018-01-08 22:16 ` Jolly Shah 2018-01-08 22:16 ` [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver Jolly Shah 2018-01-11 10:54 ` [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Sudeep Holla 2 siblings, 0 replies; 10+ messages in thread From: Jolly Shah @ 2018-01-08 22:16 UTC (permalink / raw) To: mturquette, sboyd, michal.simek, linux-clk Cc: linux-arm-kernel, linux-kernel, Jolly Shah, Tejas Patel, Shubhrajyoti Datta This API helps to determine the users for any clock. Signed-off-by: Jolly Shah <jollys@xilinx.com> Signed-off-by: Tejas Patel <tejasp@xilinx.com> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com> --- drivers/clk/clk.c | 28 ++++++++++++++++++++++++++++ include/linux/clk-provider.h | 1 + 2 files changed, 29 insertions(+) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b56c11f..7488787 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -258,6 +258,34 @@ struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_get_parent); +static unsigned int sibling; + +static void clk_show_subtree(struct clk_core *c, + int level) +{ + struct clk_core *child; + + if (!c) + return; + + if (level == 1) + sibling++; + + hlist_for_each_entry(child, &c->children, child_node) + clk_show_subtree(child, level + 1); +} + +unsigned int clk_get_children(char *name) +{ + struct clk_core *core; + struct clk *pclk = __clk_lookup(name); + + sibling = 0; + core = pclk->core; + clk_show_subtree(core, 0); + return sibling; +} + static struct clk_core *__clk_lookup_subtree(const char *name, struct clk_core *core) { diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 7c925e6..8191a32a 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -743,6 +743,7 @@ unsigned int __clk_get_enable_count(struct clk *clk); unsigned long clk_hw_get_rate(const struct clk_hw *hw); unsigned long __clk_get_flags(struct clk *clk); unsigned long clk_hw_get_flags(const struct clk_hw *hw); +unsigned int clk_get_children(char *name); bool clk_hw_is_prepared(const struct clk_hw *hw); bool clk_hw_is_enabled(const struct clk_hw *hw); bool __clk_is_enabled(struct clk *clk); -- 2.7.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver 2018-01-08 22:16 [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Jolly Shah 2018-01-08 22:16 ` [RFC PATCH 1/2] drivers: clk: Add clk_get_children support Jolly Shah @ 2018-01-08 22:16 ` Jolly Shah 2018-01-09 12:52 ` Philippe Ombredanne 2018-01-11 10:54 ` [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Sudeep Holla 2 siblings, 1 reply; 10+ messages in thread From: Jolly Shah @ 2018-01-08 22:16 UTC (permalink / raw) To: mturquette, sboyd, michal.simek, linux-clk Cc: linux-arm-kernel, linux-kernel, Jolly Shah, Rajan Vaja, Tejas Patel, Shubhrajyoti Datta This patch adds CCF compliant clock driver for ZynqMP. Clock driver queries supported clock information from firmware and regiters pll and output clocks with CCF. Signed-off-by: Jolly Shah <jollys@xilinx.com> Signed-off-by: Rajan Vaja <rajanv@xilinx.com> Signed-off-by: Tejas Patel <tejasp@xilinx.com> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com> --- .../devicetree/bindings/clock/zynq_mpsoc.txt | 163 +++++ drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/zynqmp/Kconfig | 8 + drivers/clk/zynqmp/Makefile | 3 + drivers/clk/zynqmp/clk-gate-zynqmp.c | 158 +++++ drivers/clk/zynqmp/clk-mux-zynqmp.c | 190 ++++++ drivers/clk/zynqmp/clkc.c | 707 +++++++++++++++++++++ drivers/clk/zynqmp/divider.c | 239 +++++++ drivers/clk/zynqmp/pll.c | 384 +++++++++++ include/linux/clk/zynqmp.h | 46 ++ 11 files changed, 1900 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/zynq_mpsoc.txt create mode 100644 drivers/clk/zynqmp/Kconfig create mode 100644 drivers/clk/zynqmp/Makefile create mode 100644 drivers/clk/zynqmp/clk-gate-zynqmp.c create mode 100644 drivers/clk/zynqmp/clk-mux-zynqmp.c create mode 100644 drivers/clk/zynqmp/clkc.c create mode 100644 drivers/clk/zynqmp/divider.c create mode 100644 drivers/clk/zynqmp/pll.c create mode 100644 include/linux/clk/zynqmp.h diff --git a/Documentation/devicetree/bindings/clock/zynq_mpsoc.txt b/Documentation/devicetree/bindings/clock/zynq_mpsoc.txt new file mode 100644 index 0000000..9061b57 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zynq_mpsoc.txt @@ -0,0 +1,163 @@ +Device Tree Clock bindings for the Zynq Ultrascale+ MPSoC + +The Zynq Ultrascale+ MPSoC has several different clk providers, +each with there own bindings. +The purpose of this document is to document their usage. + +See clock_bindings.txt for more information on the generic clock bindings. + +== Clock Controller == +The clock controller is a logical abstraction of Zynq Ultrascale+ MPSoC clock +tree. It reads required input clock frequencies from the devicetree and acts +as clock provider for all clock consumers of PS clocks. + +Required properties: + - #clock-cells : Must be 1 + - compatible : "xlnx,zynqmp-clkc" + - clocks : list of clock specifiers which are external input clocks to the + given clock controller. Please refer the next section to find + the input clocks for a given controller. + - clock-names : list of names of clocks which are exteral input clocks to the + given clock controller. Please refer to the clock bindings + for more details + +Input clocks for zynqmp Ultrascale+ clock controller: +The Zynq UltraScale+ MPSoC has one primary and four alternative reference clock +inputs. +These required clock inputs are the + - pss_ref_clk (PS reference clock) + - video_clk (reference clock for video system ) + - pss_alt_ref_clk (alternative PS reference clock) + - aux_ref_clk + - gt_crx_ref_clk (transceiver reference clock) + +The following strings are optional parameters to the 'clock-names' property in +order to provide an optional (E)MIO clock source. + - swdt0_ext_clk + - swdt1_ext_clk + - gem0_emio_clk + - gem1_emio_clk + - gem2_emio_clk + - gem3_emio_clk + - mio_clk_XX # with XX = 00..77 + - mio_clk_50_or_51 #for the mux clock to gem tsu from 50 or 51 + + +Output clocks for zynqmp Ultrascale+ clock controller: +Output clocks are registered based on clock information received from firmware. +Output clock indexes are mentioned below: + +Clock ID: Output clock name: +------------------------------------- +0 iopll +1 rpll +2 apll +3 dpll +4 vpll +5 iopll_to_fpd +6 rpll_to_fpd +7 apll_to_lpd +8 dpll_to_lpd +9 vpll_to_lpd +10 acpu +11 acpu_half +12 dbf_fpd +13 dbf_lpd +14 dbg_trace +15 dbg_tstmp +16 dp_video_ref +17 dp_audio_ref +18 dp_stc_ref +19 gdma_ref +20 dpdma_ref +21 ddr_ref +22 sata_ref +23 pcie_ref +24 gpu_ref +25 gpu_pp0_ref +26 gpu_pp1_ref +27 topsw_main +28 topsw_lsbus +29 gtgref0_ref +30 lpd_switch +31 lpd_lsbus +32 usb0_bus_ref +33 usb1_bus_ref +34 usb3_dual_ref +35 usb0 +36 usb1 +37 cpu_r5 +38 cpu_r5_core +39 csu_spb +40 csu_pll +41 pcap +42 iou_switch +43 gem_tsu_ref +44 gem_tsu +45 gem0_ref +46 gem1_ref +47 gem2_ref +48 gem3_ref +49 gem0_tx +50 gem1_tx +51 gem2_tx +52 gem3_tx +53 qspi_ref +54 sdio0_ref +55 sdio1_ref +56 uart0_ref +57 uart1_ref +58 spi0_ref +59 spi1_ref +60 nand_ref +61 i2c0_ref +62 i2c1_ref +63 can0_ref +64 can1_ref +65 can0 +66 can1 +67 dll_ref +68 adma_ref +69 timestamp_ref +70 ams_ref +71 pl0_ref +72 pl1_ref +73 pl2_ref +74 pl3_ref +75 wdt +76 iopll_int +77 iopll_pre_src +78 iopll_half +79 iopll_int_mux +80 iopll_post_src +81 rpll_int +82 rpll_pre_src +83 rpll_half +84 rpll_int_mux +85 rpll_post_src +86 apll_int +87 apll_pre_src +88 apll_half +89 apll_int_mux +90 apll_post_src +91 dpll_int +92 dpll_pre_src +93 dpll_half +94 dpll_int_mux +95 dpll_post_src +96 vpll_int +97 vpll_pre_src +98 vpll_half +99 vpll_int_mux +100 vpll_post_src +101 can0_mio +102 can1_mio + +Example: + +clkc: clkc@ff5e0020 { + #clock-cells = <1>; + compatible = "xlnx,zynqmp-clkc"; + clocks = <&pss_ref_clk>, <&video_clk>, <&pss_alt_ref_clk>, <&aux_ref_clk>, <>_crx_ref_clk>; + clock-names = "pss_ref_clk", "video_clk", "pss_alt_ref_clk","aux_ref_clk", "gt_crx_ref_clk" +}; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1c4e1aa..526f4f5 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -239,6 +239,7 @@ source "drivers/clk/samsung/Kconfig" source "drivers/clk/sunxi-ng/Kconfig" source "drivers/clk/tegra/Kconfig" source "drivers/clk/ti/Kconfig" +source "drivers/clk/zynqmp/Kconfig" source "drivers/clk/uniphier/Kconfig" endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index f7f761b..d7328b4 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -98,3 +98,4 @@ obj-$(CONFIG_X86) += x86/ endif obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/ +obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/ diff --git a/drivers/clk/zynqmp/Kconfig b/drivers/clk/zynqmp/Kconfig new file mode 100644 index 0000000..a6d54e9 --- /dev/null +++ b/drivers/clk/zynqmp/Kconfig @@ -0,0 +1,8 @@ +config COMMON_CLK_ZYNQMP + bool "Support for Xilinx ZynqMP Ultrascale+ clock controllers" + depends on OF + depends on ARCH_ZYNQMP || COMPILE_TEST + help + Support for the Zynqmp Ultrascale clock controller. + It has a dependency on the PMU firmware. + Say Y if you want to support clock support diff --git a/drivers/clk/zynqmp/Makefile b/drivers/clk/zynqmp/Makefile new file mode 100644 index 0000000..7d50f7a --- /dev/null +++ b/drivers/clk/zynqmp/Makefile @@ -0,0 +1,3 @@ +# Zynq Ultrascale+ MPSoC clock specific Makefile + +obj-$(CONFIG_ARCH_ZYNQMP) += pll.o clk-gate-zynqmp.o divider.o clk-mux-zynqmp.o clkc.o diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c new file mode 100644 index 0000000..45eeed8 --- /dev/null +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c @@ -0,0 +1,158 @@ +/* + * Zynq UltraScale+ MPSoC clock controller + * + * Copyright (C) 2016-2017 Xilinx + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Gated clock implementation + */ + +#include <linux/clk-provider.h> +#include <linux/clk/zynqmp.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/string.h> + +/** + * struct clk_gate - gating clock + * + * @hw: handle between common and hardware-specific interfaces + * @flags: hardware-specific flags + * @clk_id: Id of clock + */ +struct zynqmp_clk_gate { + struct clk_hw hw; + u8 flags; + u32 clk_id; +}; + +#define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, hw) + +/** + * zynqmp_clk_gate_enable - Enable clock + * @hw: handle between common and hardware-specific interfaces + * + * Return: 0 always + */ +static int zynqmp_clk_gate_enable(struct clk_hw *hw) +{ + struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = gate->clk_id; + int ret = 0; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_enable) + return -ENXIO; + + ret = eemi_ops->clock_enable(clk_id); + + if (ret) + pr_warn_once("%s() clock enabled failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return 0; +} + +/* + * zynqmp_clk_gate_disable - Disable clock + * @hw: handle between common and hardware-specific interfaces + */ +static void zynqmp_clk_gate_disable(struct clk_hw *hw) +{ + struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = gate->clk_id; + int ret = 0; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_disable) + return; + + ret = eemi_ops->clock_disable(clk_id); + + if (ret) + pr_warn_once("%s() clock disable failed for %s, ret = %d\n", + __func__, clk_name, ret); +} + +/** + * zynqmp_clk_gate_is_enable - Check clock state + * @hw: handle between common and hardware-specific interfaces + * + * Return: 1 if enabled + * 0 if disabled + */ +static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw) +{ + struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = gate->clk_id; + int state, ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_getstate) + return 0; + + ret = eemi_ops->clock_getstate(clk_id, &state); + if (ret) + pr_warn_once("%s() clock get state failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return state ? 1 : 0; +} + +const struct clk_ops zynqmp_clk_gate_ops = { + .enable = zynqmp_clk_gate_enable, + .disable = zynqmp_clk_gate_disable, + .is_enabled = zynqmp_clk_gate_is_enabled, +}; +EXPORT_SYMBOL_GPL(zynqmp_clk_gate_ops); + +/** + * zynqmp_clk_register_gate - register a gate clock with the clock framework + * @dev: device that is registering this clock + * @name: name of this clock + * @clk_id: Id of this clock + * @parents: name of this clock's parents + * @num_parents: number of parents + * @flags: framework-specific flags for this clock + * @clk_gate_flags: gate-specific flags for this clock + * + * Return: clock handle of the registered clock gate + */ +struct clk *zynqmp_clk_register_gate(struct device *dev, const char *name, + u32 clk_id, const char * const *parents, + u8 num_parents, unsigned long flags, + u8 clk_gate_flags) +{ + struct zynqmp_clk_gate *gate; + struct clk *clk; + struct clk_init_data init; + + /* allocate the gate */ + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &zynqmp_clk_gate_ops; + init.flags = flags; + init.parent_names = parents; + init.num_parents = num_parents; + + /* struct clk_gate assignments */ + gate->flags = clk_gate_flags; + gate->hw.init = &init; + gate->clk_id = clk_id; + + clk = clk_register(dev, &gate->hw); + + if (IS_ERR(clk)) + kfree(gate); + + return clk; +} diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c new file mode 100644 index 0000000..ee36244 --- /dev/null +++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c @@ -0,0 +1,190 @@ +/* + * Zynq UltraScale+ MPSoC mux + * + * Copyright (C) 2016-2017 Xilinx + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/clk-provider.h> +#include <linux/clk/zynqmp.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> + +/* + * DOC: basic adjustable multiplexer clock that cannot gate + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is only affected by parent switching. No clk_set_rate support + * parent - parent is adjustable through clk_set_parent + */ + +/** + * struct zynqmp_clk_mux - multiplexer clock + * + * @hw: handle between common and hardware-specific interfaces + * @flags: hardware-specific flags + * @clk_id: Id of clock + */ +struct zynqmp_clk_mux { + struct clk_hw hw; + u8 flags; + u32 clk_id; +}; + +#define to_zynqmp_clk_mux(_hw) container_of(_hw, struct zynqmp_clk_mux, hw) + +/** + * zynqmp_clk_mux_get_parent - Get parent of clock + * @hw: handle between common and hardware-specific interfaces + * + * Return: Parent index + */ +static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) +{ + struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = mux->clk_id; + u32 val; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_getparent) + return -ENXIO; + + ret = eemi_ops->clock_getparent(clk_id, &val); + + if (ret) + pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n", + __func__, clk_name, ret); + + if (val && (mux->flags & CLK_MUX_INDEX_BIT)) + val = ffs(val) - 1; + + if (val && (mux->flags & CLK_MUX_INDEX_ONE)) + val--; + + return val; +} + +/** + * zynqmp_clk_mux_set_parent - Set parent of clock + * @hw: handle between common and hardware-specific interfaces + * @index: Parent index + * + * Return: 0 always + */ +static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = mux->clk_id; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_setparent) + return -ENXIO; + + if (mux->flags & CLK_MUX_INDEX_BIT) + index = 1 << index; + + if (mux->flags & CLK_MUX_INDEX_ONE) + index++; + + ret = eemi_ops->clock_setparent(clk_id, index); + + if (ret) + pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n", + __func__, clk_name, ret); + + return 0; +} + +const struct clk_ops zynqmp_clk_mux_ops = { + .get_parent = zynqmp_clk_mux_get_parent, + .set_parent = zynqmp_clk_mux_set_parent, + .determine_rate = __clk_mux_determine_rate, +}; +EXPORT_SYMBOL_GPL(zynqmp_clk_mux_ops); + +const struct clk_ops zynqmp_clk_mux_ro_ops = { + .get_parent = zynqmp_clk_mux_get_parent, +}; +EXPORT_SYMBOL_GPL(zynqmp_clk_mux_ro_ops); + +/** + * zynqmp_clk_register_mux_table - register a mux table with the clock framework + * @dev: device that is registering this clock + * @name: name of this clock + * @clk_id: Id of this clock + * @parent_names: name of this clock's parents + * @num_parents: number of parents + * @flags: framework-specific flags for this clock + * @clk_mux_flags: mux-specific flags for this clock + * + * Return: clock handle of the registered clock mux + */ +struct clk *zynqmp_clk_register_mux_table(struct device *dev, const char *name, + u32 clk_id, + const char * const *parent_names, + u8 num_parents, + unsigned long flags, + u8 clk_mux_flags) +{ + struct zynqmp_clk_mux *mux; + struct clk *clk; + struct clk_init_data init; + + /* allocate the mux */ + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + init.name = name; + if (clk_mux_flags & CLK_MUX_READ_ONLY) + init.ops = &zynqmp_clk_mux_ro_ops; + else + init.ops = &zynqmp_clk_mux_ops; + init.flags = flags; + init.parent_names = parent_names; + init.num_parents = num_parents; + + /* struct clk_mux assignments */ + mux->flags = clk_mux_flags; + mux->hw.init = &init; + mux->clk_id = clk_id; + + clk = clk_register(dev, &mux->hw); + + if (IS_ERR(clk)) + kfree(mux); + + return clk; +} +EXPORT_SYMBOL_GPL(zynqmp_clk_register_mux_table); + +/** + * zynqmp_clk_register_mux - register a mux clock with the clock framework + * @dev: device that is registering this clock + * @name: name of this clock + * @clk_id: Id of this clock + * @parent_names: name of this clock's parents + * @num_parents: number of parents + * @flags: framework-specific flags for this clock + * @clk_mux_flags: mux-specific flags for this clock + * + * Return: clock handle of the registered clock mux + */ +struct clk *zynqmp_clk_register_mux(struct device *dev, const char *name, + u32 clk_id, const char **parent_names, + u8 num_parents, unsigned long flags, + u8 clk_mux_flags) +{ + return zynqmp_clk_register_mux_table(dev, name, clk_id, parent_names, + num_parents, flags, clk_mux_flags); +} +EXPORT_SYMBOL_GPL(zynqmp_clk_register_mux); diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c new file mode 100644 index 0000000..36bf1c1 --- /dev/null +++ b/drivers/clk/zynqmp/clkc.c @@ -0,0 +1,707 @@ +/* + * Zynq UltraScale+ MPSoC clock controller + * + * Copyright (C) 2016-2017 Xilinx + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Based on drivers/clk/zynq/clkc.c + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clk/zynqmp.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <linux/string.h> + +#define MAX_PARENT 100 +#define MAX_NODES 6 +#define MAX_NAME_LEN 50 +#define MAX_CLOCK 300 + +#define CLK_INIT_ENABLE_SHIFT 1 +#define CLK_TYPE_SHIFT 2 + +#define PM_API_PAYLOAD_LEN 3 + +#define NA_PARENT -1 +#define DUMMY_PARENT -2 + +#define CLK_TYPE_FIELD_LEN 4 +#define CLK_TOPOLOGY_NODE_OFFSET 16 +#define NODES_PER_RESP 3 + +#define CLK_TYPE_FIELD_MASK 0xF +#define CLK_FLAG_FIELD_SHIFT 8 +#define CLK_FLAG_FIELD_MASK 0x3FFF +#define CLK_TYPE_FLAG_FIELD_SHIFT 24 +#define CLK_TYPE_FLAG_FIELD_MASK 0xFF + +#define CLK_PARENTS_ID_LEN 16 +#define CLK_PARENTS_ID_MASK 0xFFFF + +/* Flags for parents */ +#define PARENT_CLK_SELF 0 +#define PARENT_CLK_NODE1 1 +#define PARENT_CLK_NODE2 2 +#define PARENT_CLK_NODE3 3 +#define PARENT_CLK_NODE4 4 +#define PARENT_CLK_EXTERNAL 5 + +#define END_OF_CLK_NAME "END_OF_CLK" +#define RESERVED_CLK_NAME "" + +#define CLK_VALID_MASK 0x1 +#define CLK_INIT_ENABLE_MASK (0x1 << CLK_INIT_ENABLE_SHIFT) + +enum clk_type { + CLK_TYPE_OUTPUT, + CLK_TYPE_EXTERNAL, +}; + +/** + * struct clock_parent - Structure for parent of clock + * @id: Parent clock ID + * @flag: Parent flags + */ +struct clock_parent { + char name[MAX_NAME_LEN]; + int id; + u32 flag; +}; + +/** + * struct clock_topology - Structure for topology of clock + * @type: Type of topology + * @flag: Topology flags + * @type_flag: Topology type specific flag + */ +struct clock_topology { + u32 type; + u32 flag; + u32 type_flag; +}; + +/** + * struct zynqmp_clock - Structure for clock + * @clk_name: Clock name + * @valid: Validity flag of clock + * @init_enable: init_enable flag of clock + * @topology: structure of topology of clock + * @num_node: Number of nodes present in topology + * @parent: structure of parent of clock + * @num_parents: Number of parents of clock + * @type: Type of clock + */ +struct zynqmp_clock { + char clk_name[MAX_NAME_LEN]; + u32 valid; + u32 init_enable; + enum clk_type type; + struct clock_topology node[MAX_NODES]; + u32 num_nodes; + struct clock_parent parent[MAX_PARENT]; + u32 num_parents; +}; + +static const char clk_type_postfix[][10] = { + [TYPE_INVALID] = "", + [TYPE_MUX] = "_mux", + [TYPE_GATE] = "", + [TYPE_DIV1] = "_div1", + [TYPE_DIV2] = "_div2", + [TYPE_FIXEDFACTOR] = "_ff", + [TYPE_PLL] = "" +}; + +static struct zynqmp_clock clock[MAX_CLOCK]; +static struct clk_onecell_data zynqmp_clk_data; +static struct clk *zynqmp_clks[MAX_CLOCK]; +static unsigned int clock_max_idx; +static const struct zynqmp_eemi_ops *eemi_ops; + +/** + * is_valid_clock - Check whether clock is valid or not + * @clk_id: Clock Index + * @valid: 1: if clock is valid + * 0: invalid clock + * + * Return: 0 Success + * Error code: Failure + */ +static int is_valid_clock(u32 clk_id, u32 *valid) +{ + if (clk_id < 0 || clk_id > clock_max_idx) + return -ENODEV; + + *valid = clock[clk_id].valid; + + return *valid ? 0 : -EINVAL; +} + +/** + * zynqmp_get_clock_name - Get name of clock from clock index + * @clk_id: Clock index + * @clk_name: Name of clock + * + * Return: 0: Success + * Error code: failure + */ +static int zynqmp_get_clock_name(u32 clk_id, char *clk_name) +{ + int ret; + u32 valid; + + ret = is_valid_clock(clk_id, &valid); + if (!ret && valid) { + strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN); + return 0; + } else { + return ret; + } +} + +/** + * get_clock_type - Get type of clock + * @clk_id: Clock Index + * @type: Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL + * + * Return: 0: Success + * Error code: failure + */ +static int get_clock_type(u32 clk_id, u32 *type) +{ + int ret; + u32 valid; + + ret = is_valid_clock(clk_id, &valid); + if (!ret && valid) { + *type = clock[clk_id].type; + return 0; + } else { + return ret; + } +} + +/** + * zynqmp_pm_clock_get_name - Get the name of clock for given id + * @clock_id: ID of the clock to be queried + * @name: Name of given clock + * + * This function is used to get name of clock specified by given + * clock ID. + * + * Return: Returns status, in case of error name would be 0. + */ +static int zynqmp_pm_clock_get_name(u32 clock_id, char *name) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + qdata.qid = PM_QID_CLOCK_GET_NAME; + qdata.arg1 = clock_id; + + eemi_ops->query_data(qdata, ret_payload); + memcpy(name, ret_payload, CLK_GET_NAME_RESP_LEN); + + return 0; +} + +/** + * zynqmp_pm_clock_get_topology - Get the topology of clock for given id + * @clock_id: ID of the clock to be queried + * @index: Node index of clock topology + * @topology: Buffer to store nodes in topology and flags + * + * This function is used to get topology information for the clock + * specified by given clock ID. + * + * This API will return 3 node of topology with a single response. To get + * other nodes, master should call same API in loop with new + * index till error is returned. E.g First call should have + * index 0 which will return nodes 0,1 and 2. Next call, index + * should be 3 which will return nodes 3,4 and 5 and so on. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, u32 *topology) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY; + qdata.arg1 = clock_id; + qdata.arg2 = index; + + eemi_ops->query_data(qdata, ret_payload); + memcpy(topology, &ret_payload[1], CLK_GET_TOPOLOGY_RESP_WORDS * 4); + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_clock_get_fixedfactor_params - Get the clock's fixed factor + * parameters for fixed clock + * @clock_id: Clock ID + * @mul: Multiplication value + * @div: Divisor value + * + * This function is used to get fixed factor parameers for the fixed + * clock. This API is application only for the fixed clock. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_get_fixedfactor_params(u32 clock_id, + u32 *mul, + u32 *div) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS; + qdata.arg1 = clock_id; + + eemi_ops->query_data(qdata, ret_payload); + *mul = ret_payload[1]; + *div = ret_payload[2]; + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_clock_get_parents - Get the first 3 parents of clock for given id + * @clock_id: Clock ID + * @index: Parent index + * @parents: 3 parents of the given clock + * + * This function is used to get 3 parents for the clock specified by + * given clock ID. + * + * This API will return 3 parents with a single response. To get + * other parents, master should call same API in loop with new + * parent index till error is returned. E.g First call should have + * index 0 which will return parents 0,1 and 2. Next call, index + * should be 3 which will return parent 3,4 and 5 and so on. + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + qdata.qid = PM_QID_CLOCK_GET_PARENTS; + qdata.arg1 = clock_id; + qdata.arg2 = index; + + eemi_ops->query_data(qdata, ret_payload); + memcpy(parents, &ret_payload[1], CLK_GET_PARENTS_RESP_WORDS * 4); + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * zynqmp_pm_clock_get_attributes - Get the attributes of clock for given id + * @clock_id: Clock ID + * @attributes: Clock attributes + * + * This function is used to get clock's attributes(e.g. valid, clock type, etc). + * + * Return: Returns status, either success or error+reason. + */ +static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr) +{ + struct zynqmp_pm_query_data qdata = {0}; + u32 ret_payload[PAYLOAD_ARG_CNT]; + + qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES; + qdata.arg1 = clock_id; + + eemi_ops->query_data(qdata, ret_payload); + memcpy(attr, &ret_payload[1], CLK_GET_ATTR_RESP_WORDS * 4); + + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); +} + +/** + * clock_get_topology: Get topology of clock from firmware using PM_API + * @clk_id: Clock Index + * @clk_topology: Structure of clock topology + * @num_nodes: number of nodes + * + * Return: 0: Success + * Error Code: Failure + */ +static int clock_get_topology(u32 clk_id, struct clock_topology *clk_topology, + u32 *num_nodes) +{ + int j, k = 0, ret; + u32 pm_resp[PM_API_PAYLOAD_LEN] = {0}; + + *num_nodes = 0; + for (j = 0; j <= MAX_NODES; j += 3) { + ret = zynqmp_pm_clock_get_topology(clk_id, j, pm_resp); + if (ret) + return ret; + for (k = 0; k < PM_API_PAYLOAD_LEN; k++) { + if (!(pm_resp[k] & CLK_TYPE_FIELD_MASK)) + goto done; + clk_topology[*num_nodes].type = pm_resp[k] & + CLK_TYPE_FIELD_MASK; + clk_topology[*num_nodes].flag = + (pm_resp[k] >> CLK_FLAG_FIELD_SHIFT) & + CLK_FLAG_FIELD_MASK; + clk_topology[*num_nodes].type_flag = + (pm_resp[k] >> CLK_TYPE_FLAG_FIELD_SHIFT) & + CLK_TYPE_FLAG_FIELD_MASK; + (*num_nodes)++; + } + } +done: + return 0; +} + +/** + * clock_get_parents: Get parents info from firmware using PM_API + * @clk_id: Clock Index + * @parent: Structure of parent information + * @num_parents: Total number of parents + * + * Return: 0: Success + * Error code: Failure + */ +static int clock_get_parents(u32 clk_id, struct clock_parent *parents, + u32 *num_parents) +{ + int j = 0, k, ret, total_parents = 0; + u32 pm_resp[PM_API_PAYLOAD_LEN] = {0}; + + do { + /* Get parents from firmware */ + ret = zynqmp_pm_clock_get_parents(clk_id, j, pm_resp); + if (ret) + return ret; + + for (k = 0; k < PM_API_PAYLOAD_LEN; k++) { + if (pm_resp[k] == (u32)NA_PARENT) { + *num_parents = total_parents; + return 0; + } + + parents[k + j].id = pm_resp[k] & CLK_PARENTS_ID_MASK; + if (parents[k + j].id == DUMMY_PARENT) { + strncpy(parents[k + j].name, + "dummy_name", MAX_NAME_LEN); + parents[k + j].flag = 0; + } else { + parents[k + j].flag = pm_resp[k] >> + CLK_PARENTS_ID_LEN; + if (zynqmp_get_clock_name(parents[k + j].id, + parents[k + j].name)) + continue; + } + total_parents++; + } + j += PM_API_PAYLOAD_LEN; + } while (total_parents <= MAX_PARENT); + return 0; +} + +/** + * get_parent_list: Create list of parents name + * @np: Device node + * @clk_id: Clock Index + * @parent_list List of parent's name + * @num_parents: Total number of parents + * + # Return: 0: Success + * Error code: Failure + */ +static int get_parent_list(struct device_node *np, u32 clk_id, + const char **parent_list, u32 *num_parents) +{ + int i = 0, ret; + u32 total_parents = clock[clk_id].num_parents; + struct clock_topology *clk_nodes; + struct clock_parent *parents; + + clk_nodes = clock[clk_id].node; + parents = clock[clk_id].parent; + + for (i = 0; i < total_parents; i++) { + if (!parents[i].flag) { + parent_list[i] = parents[i].name; + } else if (parents[i].flag == PARENT_CLK_EXTERNAL) { + ret = of_property_match_string(np, "clock-names", + parents[i].name); + if (ret < 0) + strncpy(parents[i].name, + "dummy_name", MAX_NAME_LEN); + parent_list[i] = parents[i].name; + } else { + strcat(parents[i].name, + clk_type_postfix[clk_nodes[parents[i].flag - 1]. + type]); + parent_list[i] = parents[i].name; + } + } + + *num_parents = total_parents; + return 0; +} + +/** + * zynqmp_register_clk_topology: Register clock topology + * @clk_id: Clock Index + * @clk_name: Clock Name + * @num_parents: Total number of parents + * @parent_names: List of parents name + * + * Return: 0: Success + * Error code: Failure + */ +static struct clk *zynqmp_register_clk_topology(int clk_id, char *clk_name, + int num_parents, + const char **parent_names) +{ + int j, ret; + u32 num_nodes, mult, div; + char *clk_out = NULL; + struct clock_topology *nodes; + struct clk *clk = NULL; + + nodes = clock[clk_id].node; + num_nodes = clock[clk_id].num_nodes; + + for (j = 0; j < num_nodes; j++) { + if (j != (num_nodes - 1)) { + clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name, + clk_type_postfix[nodes[j].type]); + } else { + clk_out = kasprintf(GFP_KERNEL, "%s", clk_name); + } + + switch (nodes[j].type) { + case TYPE_MUX: + clk = zynqmp_clk_register_mux(NULL, clk_out, + clk_id, parent_names, + num_parents, + nodes[j].flag, + nodes[j].type_flag); + break; + case TYPE_PLL: + clk = clk_register_zynqmp_pll(clk_out, clk_id, + parent_names, 1, + nodes[j].flag); + break; + case TYPE_FIXEDFACTOR: + ret = zynqmp_pm_clock_get_fixedfactor_params(clk_id, + &mult, + &div); + clk = clk_register_fixed_factor(NULL, clk_out, + parent_names[0], + nodes[j].flag, mult, + div); + break; + case TYPE_DIV1: + case TYPE_DIV2: + clk = zynqmp_clk_register_divider(NULL, clk_out, clk_id, + nodes[j].type, + parent_names, 1, + nodes[j].flag, + nodes[j].type_flag); + break; + case TYPE_GATE: + clk = zynqmp_clk_register_gate(NULL, clk_out, clk_id, + parent_names, 1, + nodes[j].flag, + nodes[j].type_flag); + break; + default: + pr_err("%s() Unknown topology for %s\n", + __func__, clk_out); + break; + } + if (IS_ERR(clk)) + pr_warn_once("%s() %s register fail with %ld\n", + __func__, clk_name, PTR_ERR(clk)); + + parent_names[0] = clk_out; + } + kfree(clk_out); + return clk; +} + +/** + * zynqmp_register_clocks: Register clocks + * @np: Device node + * + * Return: 0: Success + * Error code: failure + */ +static int zynqmp_register_clocks(struct device_node *np) +{ + int ret; + u32 i, total_parents = 0, type = 0; + const char *parent_names[MAX_PARENT]; + + for (i = 0; i < clock_max_idx; i++) { + char clk_name[MAX_NAME_LEN]; + + /* get clock name, continue to next clock if name not found */ + if (zynqmp_get_clock_name(i, clk_name)) + continue; + + /* Check if clock is valid and output clock. + * Do not regiter invalid or external clock. + */ + ret = get_clock_type(i, &type); + if (ret || type != CLK_TYPE_OUTPUT) + continue; + + /* Get parents of clock*/ + if (get_parent_list(np, i, parent_names, &total_parents)) { + WARN_ONCE(1, "No parents found for %s\n", + clock[i].clk_name); + continue; + } + + zynqmp_clks[i] = zynqmp_register_clk_topology(i, clk_name, + total_parents, + parent_names); + + /* Enable clock if init_enable flag is 1 */ + if (clock[i].init_enable) + clk_prepare_enable(zynqmp_clks[i]); + } + + for (i = 0; i < clock_max_idx; i++) { + if (IS_ERR(zynqmp_clks[i])) { + pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n", + clock[i].clk_name, PTR_ERR(zynqmp_clks[i])); + WARN_ON(1); + } + } + return 0; +} + +/** + * zynqmp_get_clock_info - Get clock information from firmware using PM_API + */ +static void zynqmp_get_clock_info(void) +{ + int i, ret; + u32 attr, type = 0; + + memset(clock, 0, sizeof(clock)); + for (i = 0; i < MAX_CLOCK; i++) { + zynqmp_pm_clock_get_name(i, clock[i].clk_name); + if (!strncmp(clock[i].clk_name, END_OF_CLK_NAME, + MAX_NAME_LEN)) { + clock_max_idx = i; + break; + } else if (!strncmp(clock[i].clk_name, RESERVED_CLK_NAME, + MAX_NAME_LEN)) { + continue; + } + + ret = zynqmp_pm_clock_get_attributes(i, &attr); + if (ret) + continue; + + clock[i].valid = attr & CLK_VALID_MASK; + clock[i].init_enable = !!(attr & CLK_INIT_ENABLE_MASK); + clock[i].type = attr >> CLK_TYPE_SHIFT ? CLK_TYPE_EXTERNAL : + CLK_TYPE_OUTPUT; + } + + /* Get topology of all clock */ + for (i = 0; i < clock_max_idx; i++) { + ret = get_clock_type(i, &type); + if (ret || type != CLK_TYPE_OUTPUT) + continue; + + ret = clock_get_topology(i, clock[i].node, &clock[i].num_nodes); + if (ret) + continue; + + ret = clock_get_parents(i, clock[i].parent, + &clock[i].num_parents); + if (ret) + continue; + } +} + +/** + * zynqmp_clk_setup - Setup the clock framework and register clocks + * @np: Device node + */ +static void __init zynqmp_clk_setup(struct device_node *np) +{ + int idx; + + idx = of_property_match_string(np, "clock-names", "pss_ref_clk"); + if (idx < 0) { + pr_err("pss_ref_clk not provided\n"); + return; + } + idx = of_property_match_string(np, "clock-names", "video_clk"); + if (idx < 0) { + pr_err("video_clk not provided\n"); + return; + } + idx = of_property_match_string(np, "clock-names", "pss_alt_ref_clk"); + if (idx < 0) { + pr_err("pss_alt_ref_clk not provided\n"); + return; + } + idx = of_property_match_string(np, "clock-names", "aux_ref_clk"); + if (idx < 0) { + pr_err("aux_ref_clk not provided\n"); + return; + } + idx = of_property_match_string(np, "clock-names", "gt_crx_ref_clk"); + if (idx < 0) { + pr_err("aux_ref_clk not provided\n"); + return; + } + + zynqmp_get_clock_info(); + zynqmp_register_clocks(np); + + zynqmp_clk_data.clks = zynqmp_clks; + zynqmp_clk_data.clk_num = clock_max_idx; + of_clk_add_provider(np, of_clk_src_onecell_get, &zynqmp_clk_data); +} + +/** + * zynqmp_clock_init - Initialize zynqmp clocks + * + * Return: 0 always + */ +static int __init zynqmp_clock_init(void) +{ + struct device_node *np; + + np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-clkc"); + if (!np) { + pr_err("%s: clkc node not found\n", __func__); + of_node_put(np); + return 0; + } + + eemi_ops = get_eemi_ops(); + if (!eemi_ops || !eemi_ops->query_data) { + pr_err("%s: clk data not found\n", __func__); + of_node_put(np); + return 0; + } + + zynqmp_clk_setup(np); + + return 0; +} +arch_initcall(zynqmp_clock_init); diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c new file mode 100644 index 0000000..1a1473c --- /dev/null +++ b/drivers/clk/zynqmp/divider.c @@ -0,0 +1,239 @@ +/* + * Zynq UltraScale+ MPSoC Divider support + * + * Copyright (C) 2016-2017 Xilinx + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Adjustable divider clock implementation + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clk/zynqmp.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/io.h> +#include <linux/err.h> +#include <linux/string.h> +#include <linux/log2.h> + +/* + * DOC: basic adjustable divider clock that cannot gate + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor) + * parent - fixed parent. No clk_set_parent support + */ + +#define to_zynqmp_clk_divider(_hw) \ + container_of(_hw, struct zynqmp_clk_divider, hw) + +/** + * struct zynqmp_clk_divider - adjustable divider clock + * + * @hw: handle between common and hardware-specific interfaces + * @flags: Hardware specific flags + * @clk_id: Id of clock + * @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2) + */ +struct zynqmp_clk_divider { + struct clk_hw hw; + u8 flags; + u32 clk_id; + u32 div_type; +}; + +static int zynqmp_divider_get_val(unsigned long parent_rate, unsigned long rate) +{ + return DIV_ROUND_UP_ULL((u64)parent_rate, rate); +} + +static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = divider->clk_id; + u32 div_type = divider->div_type; + u32 div, value; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_getdivider) + return -ENXIO; + + ret = eemi_ops->clock_getdivider(clk_id, &div); + + if (ret) + pr_warn_once("%s() get divider failed for %s, ret = %d\n", + __func__, clk_name, ret); + + if (div_type == TYPE_DIV1) + value = div & 0xFFFF; + else + value = (div >> 16) & 0xFFFF; + + return zynqmp_divider_get_val((u64)parent_rate, value); +} + +static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = divider->clk_id; + u32 div_type = divider->div_type; + u32 bestdiv; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_getdivider) + return -ENXIO; + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + ret = eemi_ops->clock_getdivider(clk_id, &bestdiv); + + if (ret) + pr_warn_once("%s() get divider failed for %s, ret = %d\n", + __func__, clk_name, ret); + if (div_type == TYPE_DIV1) + bestdiv = bestdiv & 0xFFFF; + else + bestdiv = (bestdiv >> 16) & 0xFFFF; + + return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); + } + + bestdiv = zynqmp_divider_get_val(*prate, rate); + + if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && + ((clk_hw_get_flags(hw) & CLK_FRAC))) + bestdiv = rate % *prate ? 1 : bestdiv; + *prate = rate * bestdiv; + + return rate; +} + +/** + * zynqmp_clk_divider_set_rate - Set rate of divider clock + * @hw: handle between common and hardware-specific interfaces + * @rate: rate of clock to be set + * @parent_rate: rate of parent clock + * + * Return: 0 always + */ +static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = divider->clk_id; + u32 div_type = divider->div_type; + u32 value, div; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_setdivider) + return -ENXIO; + + value = zynqmp_divider_get_val(parent_rate, rate); + if (div_type == TYPE_DIV1) { + div = value & 0xFFFF; + div |= ((u16)-1) << 16; + } else { + div = ((u16)-1); + div |= value << 16; + } + + ret = eemi_ops->clock_setdivider(clk_id, div); + + if (ret) + pr_warn_once("%s() set divider failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return 0; +} + +static const struct clk_ops zynqmp_clk_divider_ops = { + .recalc_rate = zynqmp_clk_divider_recalc_rate, + .round_rate = zynqmp_clk_divider_round_rate, + .set_rate = zynqmp_clk_divider_set_rate, +}; + +/** + * _register_divider - register a divider clock + * @dev: device registering this clock + * @name: name of this clock + * @clk_id: Id of clock + * @div_type: Type of divisor + * @parents: name of clock's parents + * @num_parents: number of parents + * @flags: framework-specific flags + * @clk_divider_flags: divider-specific flags for this clock + * + * Return: handle to registered clock divider + */ +static struct clk *_register_divider(struct device *dev, const char *name, + u32 clk_id, u32 div_type, + const char * const *parents, + u8 num_parents, unsigned long flags, + u8 clk_divider_flags) +{ + struct zynqmp_clk_divider *div; + struct clk *clk; + struct clk_init_data init; + + /* allocate the divider */ + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &zynqmp_clk_divider_ops; + init.flags = flags; + init.parent_names = parents; + init.num_parents = num_parents; + + /* struct clk_divider assignments */ + div->flags = clk_divider_flags; + div->hw.init = &init; + div->clk_id = clk_id; + div->div_type = div_type; + + /* register the clock */ + clk = clk_register(dev, &div->hw); + + if (IS_ERR(clk)) + kfree(div); + + return clk; +} + +/** + * zynqmp_clk_register_divider - register a divider clock + * @dev: device registering this clock + * @name: name of this clock + * @clk_id: Id of clock + * @div_type: Type of divisor + * @parents: name of clock's parents + * @num_parents: number of parents + * @flags: framework-specific flags + * @clk_divider_flags: divider-specific flags for this clock + * + * Return: handle to registered clock divider + */ +struct clk *zynqmp_clk_register_divider(struct device *dev, const char *name, + u32 clk_id, u32 div_type, + const char * const *parents, + u8 num_parents, unsigned long flags, + u8 clk_divider_flags) +{ + return _register_divider(dev, name, clk_id, div_type, parents, + num_parents, flags, clk_divider_flags); +} +EXPORT_SYMBOL_GPL(zynqmp_clk_register_divider); diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c new file mode 100644 index 0000000..75def21 --- /dev/null +++ b/drivers/clk/zynqmp/pll.c @@ -0,0 +1,384 @@ +/* + * Zynq UltraScale+ MPSoC PLL driver + * + * Copyright (C) 2016-2017 Xilinx + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <linux/clk.h> +#include <linux/clk/zynqmp.h> +#include <linux/clk-provider.h> +#include <linux/slab.h> +#include <linux/io.h> + +/** + * struct zynqmp_pll - Structure for PLL clock + * @hw: Handle between common and hardware-specific interfaces + * @clk_id: PLL clock ID + */ +struct zynqmp_pll { + struct clk_hw hw; + u32 clk_id; +}; + +#define to_zynqmp_pll(_hw) container_of(_hw, struct zynqmp_pll, hw) + +/* Register bitfield defines */ +#define PLLCTRL_FBDIV_MASK 0x7f00 +#define PLLCTRL_FBDIV_SHIFT 8 +#define PLLCTRL_BP_MASK BIT(3) +#define PLLCTRL_DIV2_MASK BIT(16) +#define PLLCTRL_RESET_MASK 1 +#define PLLCTRL_RESET_VAL 1 +#define PLL_STATUS_LOCKED 1 +#define PLLCTRL_RESET_SHIFT 0 +#define PLLCTRL_DIV2_SHIFT 16 + +#define PLL_FBDIV_MIN 25 +#define PLL_FBDIV_MAX 125 + +#define PS_PLL_VCO_MIN 1500000000 +#define PS_PLL_VCO_MAX 3000000000UL + +enum pll_mode { + PLL_MODE_INT, + PLL_MODE_FRAC, +}; + +#define FRAC_OFFSET 0x8 +#define PLLFCFG_FRAC_EN BIT(31) +#define FRAC_DIV 0x10000 /* 2^16 */ + +/** + * pll_get_mode - Get mode of PLL + * @hw: Handle between common and hardware-specific interfaces + * + * Return: Mode of PLL + */ +static inline enum pll_mode pll_get_mode(struct clk_hw *hw) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + u32 clk_id = clk->clk_id; + const char *clk_name = clk_hw_get_name(hw); + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->ioctl) + return -ENXIO; + + ret = eemi_ops->ioctl(0, IOCTL_GET_PLL_FRAC_MODE, clk_id, 0, + ret_payload); + if (ret) + pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return ret_payload[1]; +} + +/** + * pll_set_mode - Set the PLL mode + * @hw: Handle between common and hardware-specific interfaces + * @on: Flag to determine the mode + */ +static inline void pll_set_mode(struct clk_hw *hw, bool on) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + u32 clk_id = clk->clk_id; + const char *clk_name = clk_hw_get_name(hw); + int ret; + u32 mode; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->ioctl) { + pr_warn_once("eemi_ops not found\n"); + return; + } + + if (on) + mode = PLL_MODE_FRAC; + else + mode = PLL_MODE_INT; + + ret = eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_MODE, clk_id, mode, NULL); + if (ret) + pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n", + __func__, clk_name, ret); +} + +/** + * zynqmp_pll_round_rate - Round a clock frequency + * @hw: Handle between common and hardware-specific interfaces + * @rate: Desired clock frequency + * @prate: Clock frequency of parent clock + * + * Return: Frequency closest to @rate the hardware can generate + */ +static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + u32 fbdiv; + long rate_div, f; + + /* Enable the fractional mode if needed */ + rate_div = ((rate * FRAC_DIV) / *prate); + f = rate_div % FRAC_DIV; + pll_set_mode(hw, !!f); + + if (pll_get_mode(hw) == PLL_MODE_FRAC) { + if (rate > PS_PLL_VCO_MAX) { + fbdiv = rate / PS_PLL_VCO_MAX; + rate = rate / (fbdiv + 1); + } + if (rate < PS_PLL_VCO_MIN) { + fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); + rate = rate * fbdiv; + } + return rate; + } + + fbdiv = DIV_ROUND_CLOSEST(rate, *prate); + fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); + return *prate * fbdiv; +} + +/** + * zynqmp_pll_recalc_rate - Recalculate clock frequency + * @hw: Handle between common and hardware-specific interfaces + * @parent_rate: Clock frequency of parent clock + * Return: Current clock frequency + */ +static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + u32 clk_id = clk->clk_id; + const char *clk_name = clk_hw_get_name(hw); + u32 fbdiv, data; + unsigned long rate, frac; + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_getdivider) + return 0; + + /* + * makes probably sense to redundantly save fbdiv in the struct + * zynqmp_pll to save the IO access. + */ + ret = eemi_ops->clock_getdivider(clk_id, &fbdiv); + if (ret) + pr_warn_once("%s() get divider failed for %s, ret = %d\n", + __func__, clk_name, ret); + + rate = parent_rate * fbdiv; + if (pll_get_mode(hw) == PLL_MODE_FRAC) { + eemi_ops->ioctl(0, IOCTL_GET_PLL_FRAC_DATA, clk_id, 0, + ret_payload); + data = ret_payload[1]; + frac = (parent_rate * data) / FRAC_DIV; + rate = rate + frac; + } + + return rate; +} + +/** + * zynqmp_pll_set_rate - Set rate of PLL + * @hw: Handle between common and hardware-specific interfaces + * @rate: Frequency of clock to be set + * @parent_rate: Clock frequency of parent clock + */ +static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + u32 clk_id = clk->clk_id; + const char *clk_name = clk_hw_get_name(hw); + u32 fbdiv, data; + long rate_div, frac, m, f; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_setdivider) + return -ENXIO; + + if (pll_get_mode(hw) == PLL_MODE_FRAC) { + unsigned int children; + + /* + * We're running on a ZynqMP compatible machine, make sure the + * VPLL only has one child. + */ + children = clk_get_children("vpll"); + + /* Account for vpll_to_lpd and dp_video_ref */ + if (children > 2) + WARN(1, "Two devices are using vpll which is forbidden\n"); + + rate_div = ((rate * FRAC_DIV) / parent_rate); + m = rate_div / FRAC_DIV; + f = rate_div % FRAC_DIV; + m = clamp_t(u32, m, (PLL_FBDIV_MIN), (PLL_FBDIV_MAX)); + rate = parent_rate * m; + frac = (parent_rate * f) / FRAC_DIV; + + ret = eemi_ops->clock_setdivider(clk_id, m); + if (ret) + pr_warn_once("%s() set divider failed for %s, ret = %d\n", + __func__, clk_name, ret); + + data = (FRAC_DIV * f) / FRAC_DIV; + eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_DATA, clk_id, data, NULL); + + return (rate + frac); + } + + fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate); + fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); + ret = eemi_ops->clock_setdivider(clk_id, fbdiv); + if (ret) + pr_warn_once("%s() set divider failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return parent_rate * fbdiv; +} + +/** + * zynqmp_pll_is_enabled - Check if a clock is enabled + * @hw: Handle between common and hardware-specific interfaces + * + * Return: 1 if the clock is enabled, 0 otherwise + */ +static int zynqmp_pll_is_enabled(struct clk_hw *hw) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = clk->clk_id; + unsigned int state; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_getstate) + return 0; + + ret = eemi_ops->clock_getstate(clk_id, &state); + if (ret) + pr_warn_once("%s() clock get state failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return state ? 1 : 0; +} + +/** + * zynqmp_pll_enable - Enable clock + * @hw: Handle between common and hardware-specific interfaces + * + * Return: 0 always + */ +static int zynqmp_pll_enable(struct clk_hw *hw) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = clk->clk_id; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_enable) + return 0; + + if (zynqmp_pll_is_enabled(hw)) + return 0; + + pr_info("PLL: enable\n"); + + ret = eemi_ops->clock_enable(clk_id); + if (ret) + pr_warn_once("%s() clock enable failed for %s, ret = %d\n", + __func__, clk_name, ret); + + return 0; +} + +/** + * zynqmp_pll_disable - Disable clock + * @hw: Handle between common and hardware-specific interfaces + * + */ +static void zynqmp_pll_disable(struct clk_hw *hw) +{ + struct zynqmp_pll *clk = to_zynqmp_pll(hw); + const char *clk_name = clk_hw_get_name(hw); + u32 clk_id = clk->clk_id; + int ret; + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); + + if (!eemi_ops || !eemi_ops->clock_disable) + return; + + if (!zynqmp_pll_is_enabled(hw)) + return; + + pr_info("PLL: shutdown\n"); + + ret = eemi_ops->clock_disable(clk_id); + if (ret) + pr_warn_once("%s() clock disable failed for %s, ret = %d\n", + __func__, clk_name, ret); +} + +static const struct clk_ops zynqmp_pll_ops = { + .enable = zynqmp_pll_enable, + .disable = zynqmp_pll_disable, + .is_enabled = zynqmp_pll_is_enabled, + .round_rate = zynqmp_pll_round_rate, + .recalc_rate = zynqmp_pll_recalc_rate, + .set_rate = zynqmp_pll_set_rate, +}; + +/** + * clk_register_zynqmp_pll - Register PLL with the clock framework + * @name: PLL name + * @flag: PLL flags + * @parents: Parent clock names + * @num_parents:Number of parents + * @pll_ctrl: Pointer to PLL control register + * @pll_status: Pointer to PLL status register + * @lock_index: Bit index to this PLL's lock status bit in @pll_status + * + * Return: Handle to the registered clock + */ +struct clk *clk_register_zynqmp_pll(const char *name, u32 clk_id, + const char * const *parents, + u8 num_parents, unsigned long flag) +{ + struct zynqmp_pll *pll; + struct clk *clk; + struct clk_init_data init; + int status; + + init.name = name; + init.ops = &zynqmp_pll_ops; + init.flags = flag; + init.parent_names = parents; + init.num_parents = num_parents; + + pll = kmalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + /* Populate the struct */ + pll->hw.init = &init; + pll->clk_id = clk_id; + + clk = clk_register(NULL, &pll->hw); + if (WARN_ON(IS_ERR(clk))) + kfree(pll); + + status = clk_set_rate_range(clk, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX); + if (status < 0) + pr_err("%s:ERROR clk_set_rate_range failed %d\n", name, status); + + return clk; +} diff --git a/include/linux/clk/zynqmp.h b/include/linux/clk/zynqmp.h new file mode 100644 index 0000000..024ebf8 --- /dev/null +++ b/include/linux/clk/zynqmp.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016-2017 Xilinx + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LINUX_CLK_ZYNQMP_H_ +#define __LINUX_CLK_ZYNQMP_H_ + +#include <linux/spinlock.h> +#include <linux/firmware/xilinx/zynqmp/firmware.h> + +#define CLK_FRAC BIT(13) /* has a fractional parent */ + +struct device; + +struct clk *clk_register_zynqmp_pll(const char *name, u32 clk_id, + const char * const *parent, u8 num_parents, + unsigned long flag); + +struct clk *zynqmp_clk_register_gate(struct device *dev, const char *name, + u32 clk_id, + const char * const *parent_name, + u8 num_parents, unsigned long flags, + u8 clk_gate_flags); + +struct clk *zynqmp_clk_register_divider(struct device *dev, const char *name, + u32 clk_id, u32 div_type, + const char * const *parent_name, + u8 num_parents, + unsigned long flags, + u8 clk_divider_flags); + +struct clk *zynqmp_clk_register_mux(struct device *dev, const char *name, + u32 clk_id, + const char **parent_names, + u8 num_parents, unsigned long flags, + u8 clk_mux_flags); + +struct clk *zynqmp_clk_register_mux_table(struct device *dev, const char *name, + u32 clk_id, + const char * const *parent_names, + u8 num_parents, unsigned long flags, + u8 clk_mux_flags); + +#endif -- 2.7.4 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver 2018-01-08 22:16 ` [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver Jolly Shah @ 2018-01-09 12:52 ` Philippe Ombredanne 2018-01-10 20:06 ` Jolly Shah 2018-01-10 20:15 ` Jolly Shah 0 siblings, 2 replies; 10+ messages in thread From: Philippe Ombredanne @ 2018-01-09 12:52 UTC (permalink / raw) To: Jolly Shah Cc: Michael Turquette, Stephen Boyd, Michal Simek, linux-clk, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, LKML, Jolly Shah, Rajan Vaja, Tejas Patel, Shubhrajyoti Datta Jolly, On Mon, Jan 8, 2018 at 11:16 PM, Jolly Shah <jolly.shah@xilinx.com> wrote: > This patch adds CCF compliant clock driver for ZynqMP. > Clock driver queries supported clock information from > firmware and regiters pll and output clocks with CCF. > > Signed-off-by: Jolly Shah <jollys@xilinx.com> > Signed-off-by: Rajan Vaja <rajanv@xilinx.com> > Signed-off-by: Tejas Patel <tejasp@xilinx.com> > Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com> > --- <snip> > .../devicetree/bindings/clock/zynq_mpsoc.txt | 163 +++++ > drivers/clk/Kconfig | 1 + > drivers/clk/Makefile | 1 + > drivers/clk/zynqmp/Kconfig | 8 + > drivers/clk/zynqmp/Makefile | 3 + > drivers/clk/zynqmp/clk-gate-zynqmp.c | 158 +++++ > drivers/clk/zynqmp/clk-mux-zynqmp.c | 190 ++++++ > drivers/clk/zynqmp/clkc.c | 707 +++++++++++++++++++++ > drivers/clk/zynqmp/divider.c | 239 +++++++ > drivers/clk/zynqmp/pll.c | 384 +++++++++++ > include/linux/clk/zynqmp.h | 46 ++ > 11 files changed, 1900 insertions(+) > create mode 100644 Documentation/devicetree/bindings/clock/zynq_mpsoc.txt > create mode 100644 drivers/clk/zynqmp/Kconfig > create mode 100644 drivers/clk/zynqmp/Makefile > create mode 100644 drivers/clk/zynqmp/clk-gate-zynqmp.c > create mode 100644 drivers/clk/zynqmp/clk-mux-zynqmp.c > create mode 100644 drivers/clk/zynqmp/clkc.c > create mode 100644 drivers/clk/zynqmp/divider.c > create mode 100644 drivers/clk/zynqmp/pll.c > create mode 100644 include/linux/clk/zynqmp.h > > diff --git a/Documentation/devicetree/bindings/clock/zynq_mpsoc.txt b/Documentation/devicetree/bindings/clock/zynq_mpsoc.txt > new file mode 100644 > index 0000000..9061b57 > --- /dev/null > +++ b/Documentation/devicetree/bindings/clock/zynq_mpsoc.txt > @@ -0,0 +1,163 @@ > +Device Tree Clock bindings for the Zynq Ultrascale+ MPSoC > + > +The Zynq Ultrascale+ MPSoC has several different clk providers, > +each with there own bindings. > +The purpose of this document is to document their usage. > + > +See clock_bindings.txt for more information on the generic clock bindings. > + > +== Clock Controller == > +The clock controller is a logical abstraction of Zynq Ultrascale+ MPSoC clock > +tree. It reads required input clock frequencies from the devicetree and acts > +as clock provider for all clock consumers of PS clocks. > + > +Required properties: > + - #clock-cells : Must be 1 > + - compatible : "xlnx,zynqmp-clkc" > + - clocks : list of clock specifiers which are external input clocks to the > + given clock controller. Please refer the next section to find > + the input clocks for a given controller. > + - clock-names : list of names of clocks which are exteral input clocks to the > + given clock controller. Please refer to the clock bindings > + for more details > + > +Input clocks for zynqmp Ultrascale+ clock controller: > +The Zynq UltraScale+ MPSoC has one primary and four alternative reference clock > +inputs. > +These required clock inputs are the > + - pss_ref_clk (PS reference clock) > + - video_clk (reference clock for video system ) > + - pss_alt_ref_clk (alternative PS reference clock) > + - aux_ref_clk > + - gt_crx_ref_clk (transceiver reference clock) > + > +The following strings are optional parameters to the 'clock-names' property in > +order to provide an optional (E)MIO clock source. > + - swdt0_ext_clk > + - swdt1_ext_clk > + - gem0_emio_clk > + - gem1_emio_clk > + - gem2_emio_clk > + - gem3_emio_clk > + - mio_clk_XX # with XX = 00..77 > + - mio_clk_50_or_51 #for the mux clock to gem tsu from 50 or 51 > + > + > +Output clocks for zynqmp Ultrascale+ clock controller: > +Output clocks are registered based on clock information received from firmware. > +Output clock indexes are mentioned below: > + > +Clock ID: Output clock name: > +------------------------------------- > +0 iopll > +1 rpll > +2 apll > +3 dpll > +4 vpll > +5 iopll_to_fpd > +6 rpll_to_fpd > +7 apll_to_lpd > +8 dpll_to_lpd > +9 vpll_to_lpd > +10 acpu > +11 acpu_half > +12 dbf_fpd > +13 dbf_lpd > +14 dbg_trace > +15 dbg_tstmp > +16 dp_video_ref > +17 dp_audio_ref > +18 dp_stc_ref > +19 gdma_ref > +20 dpdma_ref > +21 ddr_ref > +22 sata_ref > +23 pcie_ref > +24 gpu_ref > +25 gpu_pp0_ref > +26 gpu_pp1_ref > +27 topsw_main > +28 topsw_lsbus > +29 gtgref0_ref > +30 lpd_switch > +31 lpd_lsbus > +32 usb0_bus_ref > +33 usb1_bus_ref > +34 usb3_dual_ref > +35 usb0 > +36 usb1 > +37 cpu_r5 > +38 cpu_r5_core > +39 csu_spb > +40 csu_pll > +41 pcap > +42 iou_switch > +43 gem_tsu_ref > +44 gem_tsu > +45 gem0_ref > +46 gem1_ref > +47 gem2_ref > +48 gem3_ref > +49 gem0_tx > +50 gem1_tx > +51 gem2_tx > +52 gem3_tx > +53 qspi_ref > +54 sdio0_ref > +55 sdio1_ref > +56 uart0_ref > +57 uart1_ref > +58 spi0_ref > +59 spi1_ref > +60 nand_ref > +61 i2c0_ref > +62 i2c1_ref > +63 can0_ref > +64 can1_ref > +65 can0 > +66 can1 > +67 dll_ref > +68 adma_ref > +69 timestamp_ref > +70 ams_ref > +71 pl0_ref > +72 pl1_ref > +73 pl2_ref > +74 pl3_ref > +75 wdt > +76 iopll_int > +77 iopll_pre_src > +78 iopll_half > +79 iopll_int_mux > +80 iopll_post_src > +81 rpll_int > +82 rpll_pre_src > +83 rpll_half > +84 rpll_int_mux > +85 rpll_post_src > +86 apll_int > +87 apll_pre_src > +88 apll_half > +89 apll_int_mux > +90 apll_post_src > +91 dpll_int > +92 dpll_pre_src > +93 dpll_half > +94 dpll_int_mux > +95 dpll_post_src > +96 vpll_int > +97 vpll_pre_src > +98 vpll_half > +99 vpll_int_mux > +100 vpll_post_src > +101 can0_mio > +102 can1_mio > + > +Example: > + > +clkc: clkc@ff5e0020 { > + #clock-cells = <1>; > + compatible = "xlnx,zynqmp-clkc"; > + clocks = <&pss_ref_clk>, <&video_clk>, <&pss_alt_ref_clk>, <&aux_ref_clk>, <>_crx_ref_clk>; > + clock-names = "pss_ref_clk", "video_clk", "pss_alt_ref_clk","aux_ref_clk", "gt_crx_ref_clk" > +}; > diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig > index 1c4e1aa..526f4f5 100644 > --- a/drivers/clk/Kconfig > +++ b/drivers/clk/Kconfig > @@ -239,6 +239,7 @@ source "drivers/clk/samsung/Kconfig" > source "drivers/clk/sunxi-ng/Kconfig" > source "drivers/clk/tegra/Kconfig" > source "drivers/clk/ti/Kconfig" > +source "drivers/clk/zynqmp/Kconfig" > source "drivers/clk/uniphier/Kconfig" > > endmenu > diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile > index f7f761b..d7328b4 100644 > --- a/drivers/clk/Makefile > +++ b/drivers/clk/Makefile > @@ -98,3 +98,4 @@ obj-$(CONFIG_X86) += x86/ > endif > obj-$(CONFIG_ARCH_ZX) += zte/ > obj-$(CONFIG_ARCH_ZYNQ) += zynq/ > +obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/ > diff --git a/drivers/clk/zynqmp/Kconfig b/drivers/clk/zynqmp/Kconfig > new file mode 100644 > index 0000000..a6d54e9 > --- /dev/null > +++ b/drivers/clk/zynqmp/Kconfig > @@ -0,0 +1,8 @@ > +config COMMON_CLK_ZYNQMP > + bool "Support for Xilinx ZynqMP Ultrascale+ clock controllers" > + depends on OF > + depends on ARCH_ZYNQMP || COMPILE_TEST > + help > + Support for the Zynqmp Ultrascale clock controller. > + It has a dependency on the PMU firmware. > + Say Y if you want to support clock support > diff --git a/drivers/clk/zynqmp/Makefile b/drivers/clk/zynqmp/Makefile > new file mode 100644 > index 0000000..7d50f7a > --- /dev/null > +++ b/drivers/clk/zynqmp/Makefile > @@ -0,0 +1,3 @@ > +# Zynq Ultrascale+ MPSoC clock specific Makefile > + > +obj-$(CONFIG_ARCH_ZYNQMP) += pll.o clk-gate-zynqmp.o divider.o clk-mux-zynqmp.o clkc.o > diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c > new file mode 100644 > index 0000000..45eeed8 > --- /dev/null > +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c > @@ -0,0 +1,158 @@ > +/* > + * Zynq UltraScale+ MPSoC clock controller > + * > + * Copyright (C) 2016-2017 Xilinx > + * > + * SPDX-License-Identifier: GPL-2.0+ This tag should be on the fist line this way: // SPDX-License-Identifier: GPL-2.0+ > + > +#include <linux/clk-provider.h> > +#include <linux/clk/zynqmp.h> > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/io.h> > +#include <linux/err.h> > +#include <linux/string.h> > + > +/** > + * struct clk_gate - gating clock > + * > + * @hw: handle between common and hardware-specific interfaces > + * @flags: hardware-specific flags > + * @clk_id: Id of clock > + */ > +struct zynqmp_clk_gate { > + struct clk_hw hw; > + u8 flags; > + u32 clk_id; > +}; > + > +#define to_zynqmp_clk_gate(_hw) container_of(_hw, struct zynqmp_clk_gate, hw) > + > +/** > + * zynqmp_clk_gate_enable - Enable clock > + * @hw: handle between common and hardware-specific interfaces > + * > + * Return: 0 always > + */ > +static int zynqmp_clk_gate_enable(struct clk_hw *hw) > +{ > + struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = gate->clk_id; > + int ret = 0; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_enable) > + return -ENXIO; > + > + ret = eemi_ops->clock_enable(clk_id); > + > + if (ret) > + pr_warn_once("%s() clock enabled failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return 0; > +} > + > +/* > + * zynqmp_clk_gate_disable - Disable clock > + * @hw: handle between common and hardware-specific interfaces > + */ > +static void zynqmp_clk_gate_disable(struct clk_hw *hw) > +{ > + struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = gate->clk_id; > + int ret = 0; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_disable) > + return; > + > + ret = eemi_ops->clock_disable(clk_id); > + > + if (ret) > + pr_warn_once("%s() clock disable failed for %s, ret = %d\n", > + __func__, clk_name, ret); > +} > + > +/** > + * zynqmp_clk_gate_is_enable - Check clock state > + * @hw: handle between common and hardware-specific interfaces > + * > + * Return: 1 if enabled > + * 0 if disabled > + */ > +static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw) > +{ > + struct zynqmp_clk_gate *gate = to_zynqmp_clk_gate(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = gate->clk_id; > + int state, ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_getstate) > + return 0; > + > + ret = eemi_ops->clock_getstate(clk_id, &state); > + if (ret) > + pr_warn_once("%s() clock get state failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return state ? 1 : 0; > +} > + > +const struct clk_ops zynqmp_clk_gate_ops = { > + .enable = zynqmp_clk_gate_enable, > + .disable = zynqmp_clk_gate_disable, > + .is_enabled = zynqmp_clk_gate_is_enabled, > +}; > +EXPORT_SYMBOL_GPL(zynqmp_clk_gate_ops); > + > +/** > + * zynqmp_clk_register_gate - register a gate clock with the clock framework > + * @dev: device that is registering this clock > + * @name: name of this clock > + * @clk_id: Id of this clock > + * @parents: name of this clock's parents > + * @num_parents: number of parents > + * @flags: framework-specific flags for this clock > + * @clk_gate_flags: gate-specific flags for this clock > + * > + * Return: clock handle of the registered clock gate > + */ > +struct clk *zynqmp_clk_register_gate(struct device *dev, const char *name, > + u32 clk_id, const char * const *parents, > + u8 num_parents, unsigned long flags, > + u8 clk_gate_flags) > +{ > + struct zynqmp_clk_gate *gate; > + struct clk *clk; > + struct clk_init_data init; > + > + /* allocate the gate */ > + gate = kzalloc(sizeof(*gate), GFP_KERNEL); > + if (!gate) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.ops = &zynqmp_clk_gate_ops; > + init.flags = flags; > + init.parent_names = parents; > + init.num_parents = num_parents; > + > + /* struct clk_gate assignments */ > + gate->flags = clk_gate_flags; > + gate->hw.init = &init; > + gate->clk_id = clk_id; > + > + clk = clk_register(dev, &gate->hw); > + > + if (IS_ERR(clk)) > + kfree(gate); > + > + return clk; > +} > diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c > new file mode 100644 > index 0000000..ee36244 > --- /dev/null > +++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c > @@ -0,0 +1,190 @@ > +/* > + * Zynq UltraScale+ MPSoC mux > + * > + * Copyright (C) 2016-2017 Xilinx > + * > + * SPDX-License-Identifier: GPL-2.0+ This tag should be on the fist line this way: // SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <linux/clk-provider.h> > +#include <linux/clk/zynqmp.h> > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/io.h> > +#include <linux/err.h> > + > +/* > + * DOC: basic adjustable multiplexer clock that cannot gate > + * > + * Traits of this clock: > + * prepare - clk_prepare only ensures that parents are prepared > + * enable - clk_enable only ensures that parents are enabled > + * rate - rate is only affected by parent switching. No clk_set_rate support > + * parent - parent is adjustable through clk_set_parent > + */ > + > +/** > + * struct zynqmp_clk_mux - multiplexer clock > + * > + * @hw: handle between common and hardware-specific interfaces > + * @flags: hardware-specific flags > + * @clk_id: Id of clock > + */ > +struct zynqmp_clk_mux { > + struct clk_hw hw; > + u8 flags; > + u32 clk_id; > +}; > + > +#define to_zynqmp_clk_mux(_hw) container_of(_hw, struct zynqmp_clk_mux, hw) > + > +/** > + * zynqmp_clk_mux_get_parent - Get parent of clock > + * @hw: handle between common and hardware-specific interfaces > + * > + * Return: Parent index > + */ > +static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) > +{ > + struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = mux->clk_id; > + u32 val; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_getparent) > + return -ENXIO; > + > + ret = eemi_ops->clock_getparent(clk_id, &val); > + > + if (ret) > + pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n", > + __func__, clk_name, ret); > + > + if (val && (mux->flags & CLK_MUX_INDEX_BIT)) > + val = ffs(val) - 1; > + > + if (val && (mux->flags & CLK_MUX_INDEX_ONE)) > + val--; > + > + return val; > +} > + > +/** > + * zynqmp_clk_mux_set_parent - Set parent of clock > + * @hw: handle between common and hardware-specific interfaces > + * @index: Parent index > + * > + * Return: 0 always > + */ > +static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index) > +{ > + struct zynqmp_clk_mux *mux = to_zynqmp_clk_mux(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = mux->clk_id; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_setparent) > + return -ENXIO; > + > + if (mux->flags & CLK_MUX_INDEX_BIT) > + index = 1 << index; > + > + if (mux->flags & CLK_MUX_INDEX_ONE) > + index++; > + > + ret = eemi_ops->clock_setparent(clk_id, index); > + > + if (ret) > + pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return 0; > +} > + > +const struct clk_ops zynqmp_clk_mux_ops = { > + .get_parent = zynqmp_clk_mux_get_parent, > + .set_parent = zynqmp_clk_mux_set_parent, > + .determine_rate = __clk_mux_determine_rate, > +}; > +EXPORT_SYMBOL_GPL(zynqmp_clk_mux_ops); > + > +const struct clk_ops zynqmp_clk_mux_ro_ops = { > + .get_parent = zynqmp_clk_mux_get_parent, > +}; > +EXPORT_SYMBOL_GPL(zynqmp_clk_mux_ro_ops); > + > +/** > + * zynqmp_clk_register_mux_table - register a mux table with the clock framework > + * @dev: device that is registering this clock > + * @name: name of this clock > + * @clk_id: Id of this clock > + * @parent_names: name of this clock's parents > + * @num_parents: number of parents > + * @flags: framework-specific flags for this clock > + * @clk_mux_flags: mux-specific flags for this clock > + * > + * Return: clock handle of the registered clock mux > + */ > +struct clk *zynqmp_clk_register_mux_table(struct device *dev, const char *name, > + u32 clk_id, > + const char * const *parent_names, > + u8 num_parents, > + unsigned long flags, > + u8 clk_mux_flags) > +{ > + struct zynqmp_clk_mux *mux; > + struct clk *clk; > + struct clk_init_data init; > + > + /* allocate the mux */ > + mux = kzalloc(sizeof(*mux), GFP_KERNEL); > + if (!mux) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + if (clk_mux_flags & CLK_MUX_READ_ONLY) > + init.ops = &zynqmp_clk_mux_ro_ops; > + else > + init.ops = &zynqmp_clk_mux_ops; > + init.flags = flags; > + init.parent_names = parent_names; > + init.num_parents = num_parents; > + > + /* struct clk_mux assignments */ > + mux->flags = clk_mux_flags; > + mux->hw.init = &init; > + mux->clk_id = clk_id; > + > + clk = clk_register(dev, &mux->hw); > + > + if (IS_ERR(clk)) > + kfree(mux); > + > + return clk; > +} > +EXPORT_SYMBOL_GPL(zynqmp_clk_register_mux_table); > + > +/** > + * zynqmp_clk_register_mux - register a mux clock with the clock framework > + * @dev: device that is registering this clock > + * @name: name of this clock > + * @clk_id: Id of this clock > + * @parent_names: name of this clock's parents > + * @num_parents: number of parents > + * @flags: framework-specific flags for this clock > + * @clk_mux_flags: mux-specific flags for this clock > + * > + * Return: clock handle of the registered clock mux > + */ > +struct clk *zynqmp_clk_register_mux(struct device *dev, const char *name, > + u32 clk_id, const char **parent_names, > + u8 num_parents, unsigned long flags, > + u8 clk_mux_flags) > +{ > + return zynqmp_clk_register_mux_table(dev, name, clk_id, parent_names, > + num_parents, flags, clk_mux_flags); > +} > +EXPORT_SYMBOL_GPL(zynqmp_clk_register_mux); > diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c > new file mode 100644 > index 0000000..36bf1c1 > --- /dev/null > +++ b/drivers/clk/zynqmp/clkc.c > @@ -0,0 +1,707 @@ > +/* > + * Zynq UltraScale+ MPSoC clock controller > + * > + * Copyright (C) 2016-2017 Xilinx > + * > + * SPDX-License-Identifier: GPL-2.0+ This tag should be on the fist line this way: // SPDX-License-Identifier: GPL-2.0+ > + * > + * Based on drivers/clk/zynq/clkc.c > + */ > + > +#include <linux/clk.h> > +#include <linux/clk-provider.h> > +#include <linux/clk/zynqmp.h> > +#include <linux/io.h> > +#include <linux/of.h> > +#include <linux/of_address.h> > +#include <linux/slab.h> > +#include <linux/string.h> > + > +#define MAX_PARENT 100 > +#define MAX_NODES 6 > +#define MAX_NAME_LEN 50 > +#define MAX_CLOCK 300 > + > +#define CLK_INIT_ENABLE_SHIFT 1 > +#define CLK_TYPE_SHIFT 2 > + > +#define PM_API_PAYLOAD_LEN 3 > + > +#define NA_PARENT -1 > +#define DUMMY_PARENT -2 > + > +#define CLK_TYPE_FIELD_LEN 4 > +#define CLK_TOPOLOGY_NODE_OFFSET 16 > +#define NODES_PER_RESP 3 > + > +#define CLK_TYPE_FIELD_MASK 0xF > +#define CLK_FLAG_FIELD_SHIFT 8 > +#define CLK_FLAG_FIELD_MASK 0x3FFF > +#define CLK_TYPE_FLAG_FIELD_SHIFT 24 > +#define CLK_TYPE_FLAG_FIELD_MASK 0xFF > + > +#define CLK_PARENTS_ID_LEN 16 > +#define CLK_PARENTS_ID_MASK 0xFFFF > + > +/* Flags for parents */ > +#define PARENT_CLK_SELF 0 > +#define PARENT_CLK_NODE1 1 > +#define PARENT_CLK_NODE2 2 > +#define PARENT_CLK_NODE3 3 > +#define PARENT_CLK_NODE4 4 > +#define PARENT_CLK_EXTERNAL 5 > + > +#define END_OF_CLK_NAME "END_OF_CLK" > +#define RESERVED_CLK_NAME "" > + > +#define CLK_VALID_MASK 0x1 > +#define CLK_INIT_ENABLE_MASK (0x1 << CLK_INIT_ENABLE_SHIFT) > + > +enum clk_type { > + CLK_TYPE_OUTPUT, > + CLK_TYPE_EXTERNAL, > +}; > + > +/** > + * struct clock_parent - Structure for parent of clock > + * @id: Parent clock ID > + * @flag: Parent flags > + */ > +struct clock_parent { > + char name[MAX_NAME_LEN]; > + int id; > + u32 flag; > +}; > + > +/** > + * struct clock_topology - Structure for topology of clock > + * @type: Type of topology > + * @flag: Topology flags > + * @type_flag: Topology type specific flag > + */ > +struct clock_topology { > + u32 type; > + u32 flag; > + u32 type_flag; > +}; > + > +/** > + * struct zynqmp_clock - Structure for clock > + * @clk_name: Clock name > + * @valid: Validity flag of clock > + * @init_enable: init_enable flag of clock > + * @topology: structure of topology of clock > + * @num_node: Number of nodes present in topology > + * @parent: structure of parent of clock > + * @num_parents: Number of parents of clock > + * @type: Type of clock > + */ > +struct zynqmp_clock { > + char clk_name[MAX_NAME_LEN]; > + u32 valid; > + u32 init_enable; > + enum clk_type type; > + struct clock_topology node[MAX_NODES]; > + u32 num_nodes; > + struct clock_parent parent[MAX_PARENT]; > + u32 num_parents; > +}; > + > +static const char clk_type_postfix[][10] = { > + [TYPE_INVALID] = "", > + [TYPE_MUX] = "_mux", > + [TYPE_GATE] = "", > + [TYPE_DIV1] = "_div1", > + [TYPE_DIV2] = "_div2", > + [TYPE_FIXEDFACTOR] = "_ff", > + [TYPE_PLL] = "" > +}; > + > +static struct zynqmp_clock clock[MAX_CLOCK]; > +static struct clk_onecell_data zynqmp_clk_data; > +static struct clk *zynqmp_clks[MAX_CLOCK]; > +static unsigned int clock_max_idx; > +static const struct zynqmp_eemi_ops *eemi_ops; > + > +/** > + * is_valid_clock - Check whether clock is valid or not > + * @clk_id: Clock Index > + * @valid: 1: if clock is valid > + * 0: invalid clock > + * > + * Return: 0 Success > + * Error code: Failure > + */ > +static int is_valid_clock(u32 clk_id, u32 *valid) > +{ > + if (clk_id < 0 || clk_id > clock_max_idx) > + return -ENODEV; > + > + *valid = clock[clk_id].valid; > + > + return *valid ? 0 : -EINVAL; > +} > + > +/** > + * zynqmp_get_clock_name - Get name of clock from clock index > + * @clk_id: Clock index > + * @clk_name: Name of clock > + * > + * Return: 0: Success > + * Error code: failure > + */ > +static int zynqmp_get_clock_name(u32 clk_id, char *clk_name) > +{ > + int ret; > + u32 valid; > + > + ret = is_valid_clock(clk_id, &valid); > + if (!ret && valid) { > + strncpy(clk_name, clock[clk_id].clk_name, MAX_NAME_LEN); > + return 0; > + } else { > + return ret; > + } > +} > + > +/** > + * get_clock_type - Get type of clock > + * @clk_id: Clock Index > + * @type: Clock type: CLK_TYPE_OUTPUT or CLK_TYPE_EXTERNAL > + * > + * Return: 0: Success > + * Error code: failure > + */ > +static int get_clock_type(u32 clk_id, u32 *type) > +{ > + int ret; > + u32 valid; > + > + ret = is_valid_clock(clk_id, &valid); > + if (!ret && valid) { > + *type = clock[clk_id].type; > + return 0; > + } else { > + return ret; > + } > +} > + > +/** > + * zynqmp_pm_clock_get_name - Get the name of clock for given id > + * @clock_id: ID of the clock to be queried > + * @name: Name of given clock > + * > + * This function is used to get name of clock specified by given > + * clock ID. > + * > + * Return: Returns status, in case of error name would be 0. > + */ > +static int zynqmp_pm_clock_get_name(u32 clock_id, char *name) > +{ > + struct zynqmp_pm_query_data qdata = {0}; > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + > + qdata.qid = PM_QID_CLOCK_GET_NAME; > + qdata.arg1 = clock_id; > + > + eemi_ops->query_data(qdata, ret_payload); > + memcpy(name, ret_payload, CLK_GET_NAME_RESP_LEN); > + > + return 0; > +} > + > +/** > + * zynqmp_pm_clock_get_topology - Get the topology of clock for given id > + * @clock_id: ID of the clock to be queried > + * @index: Node index of clock topology > + * @topology: Buffer to store nodes in topology and flags > + * > + * This function is used to get topology information for the clock > + * specified by given clock ID. > + * > + * This API will return 3 node of topology with a single response. To get > + * other nodes, master should call same API in loop with new > + * index till error is returned. E.g First call should have > + * index 0 which will return nodes 0,1 and 2. Next call, index > + * should be 3 which will return nodes 3,4 and 5 and so on. > + * > + * Return: Returns status, either success or error+reason. > + */ > +static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, u32 *topology) > +{ > + struct zynqmp_pm_query_data qdata = {0}; > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + > + qdata.qid = PM_QID_CLOCK_GET_TOPOLOGY; > + qdata.arg1 = clock_id; > + qdata.arg2 = index; > + > + eemi_ops->query_data(qdata, ret_payload); > + memcpy(topology, &ret_payload[1], CLK_GET_TOPOLOGY_RESP_WORDS * 4); > + > + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); > +} > + > +/** > + * zynqmp_pm_clock_get_fixedfactor_params - Get the clock's fixed factor > + * parameters for fixed clock > + * @clock_id: Clock ID > + * @mul: Multiplication value > + * @div: Divisor value > + * > + * This function is used to get fixed factor parameers for the fixed > + * clock. This API is application only for the fixed clock. > + * > + * Return: Returns status, either success or error+reason. > + */ > +static int zynqmp_pm_clock_get_fixedfactor_params(u32 clock_id, > + u32 *mul, > + u32 *div) > +{ > + struct zynqmp_pm_query_data qdata = {0}; > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + > + qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS; > + qdata.arg1 = clock_id; > + > + eemi_ops->query_data(qdata, ret_payload); > + *mul = ret_payload[1]; > + *div = ret_payload[2]; > + > + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); > +} > + > +/** > + * zynqmp_pm_clock_get_parents - Get the first 3 parents of clock for given id > + * @clock_id: Clock ID > + * @index: Parent index > + * @parents: 3 parents of the given clock > + * > + * This function is used to get 3 parents for the clock specified by > + * given clock ID. > + * > + * This API will return 3 parents with a single response. To get > + * other parents, master should call same API in loop with new > + * parent index till error is returned. E.g First call should have > + * index 0 which will return parents 0,1 and 2. Next call, index > + * should be 3 which will return parent 3,4 and 5 and so on. > + * > + * Return: Returns status, either success or error+reason. > + */ > +static int zynqmp_pm_clock_get_parents(u32 clock_id, u32 index, u32 *parents) > +{ > + struct zynqmp_pm_query_data qdata = {0}; > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + > + qdata.qid = PM_QID_CLOCK_GET_PARENTS; > + qdata.arg1 = clock_id; > + qdata.arg2 = index; > + > + eemi_ops->query_data(qdata, ret_payload); > + memcpy(parents, &ret_payload[1], CLK_GET_PARENTS_RESP_WORDS * 4); > + > + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); > +} > + > +/** > + * zynqmp_pm_clock_get_attributes - Get the attributes of clock for given id > + * @clock_id: Clock ID > + * @attributes: Clock attributes > + * > + * This function is used to get clock's attributes(e.g. valid, clock type, etc). > + * > + * Return: Returns status, either success or error+reason. > + */ > +static int zynqmp_pm_clock_get_attributes(u32 clock_id, u32 *attr) > +{ > + struct zynqmp_pm_query_data qdata = {0}; > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + > + qdata.qid = PM_QID_CLOCK_GET_ATTRIBUTES; > + qdata.arg1 = clock_id; > + > + eemi_ops->query_data(qdata, ret_payload); > + memcpy(attr, &ret_payload[1], CLK_GET_ATTR_RESP_WORDS * 4); > + > + return zynqmp_pm_ret_code((enum pm_ret_status)ret_payload[0]); > +} > + > +/** > + * clock_get_topology: Get topology of clock from firmware using PM_API > + * @clk_id: Clock Index > + * @clk_topology: Structure of clock topology > + * @num_nodes: number of nodes > + * > + * Return: 0: Success > + * Error Code: Failure > + */ > +static int clock_get_topology(u32 clk_id, struct clock_topology *clk_topology, > + u32 *num_nodes) > +{ > + int j, k = 0, ret; > + u32 pm_resp[PM_API_PAYLOAD_LEN] = {0}; > + > + *num_nodes = 0; > + for (j = 0; j <= MAX_NODES; j += 3) { > + ret = zynqmp_pm_clock_get_topology(clk_id, j, pm_resp); > + if (ret) > + return ret; > + for (k = 0; k < PM_API_PAYLOAD_LEN; k++) { > + if (!(pm_resp[k] & CLK_TYPE_FIELD_MASK)) > + goto done; > + clk_topology[*num_nodes].type = pm_resp[k] & > + CLK_TYPE_FIELD_MASK; > + clk_topology[*num_nodes].flag = > + (pm_resp[k] >> CLK_FLAG_FIELD_SHIFT) & > + CLK_FLAG_FIELD_MASK; > + clk_topology[*num_nodes].type_flag = > + (pm_resp[k] >> CLK_TYPE_FLAG_FIELD_SHIFT) & > + CLK_TYPE_FLAG_FIELD_MASK; > + (*num_nodes)++; > + } > + } > +done: > + return 0; > +} > + > +/** > + * clock_get_parents: Get parents info from firmware using PM_API > + * @clk_id: Clock Index > + * @parent: Structure of parent information > + * @num_parents: Total number of parents > + * > + * Return: 0: Success > + * Error code: Failure > + */ > +static int clock_get_parents(u32 clk_id, struct clock_parent *parents, > + u32 *num_parents) > +{ > + int j = 0, k, ret, total_parents = 0; > + u32 pm_resp[PM_API_PAYLOAD_LEN] = {0}; > + > + do { > + /* Get parents from firmware */ > + ret = zynqmp_pm_clock_get_parents(clk_id, j, pm_resp); > + if (ret) > + return ret; > + > + for (k = 0; k < PM_API_PAYLOAD_LEN; k++) { > + if (pm_resp[k] == (u32)NA_PARENT) { > + *num_parents = total_parents; > + return 0; > + } > + > + parents[k + j].id = pm_resp[k] & CLK_PARENTS_ID_MASK; > + if (parents[k + j].id == DUMMY_PARENT) { > + strncpy(parents[k + j].name, > + "dummy_name", MAX_NAME_LEN); > + parents[k + j].flag = 0; > + } else { > + parents[k + j].flag = pm_resp[k] >> > + CLK_PARENTS_ID_LEN; > + if (zynqmp_get_clock_name(parents[k + j].id, > + parents[k + j].name)) > + continue; > + } > + total_parents++; > + } > + j += PM_API_PAYLOAD_LEN; > + } while (total_parents <= MAX_PARENT); > + return 0; > +} > + > +/** > + * get_parent_list: Create list of parents name > + * @np: Device node > + * @clk_id: Clock Index > + * @parent_list List of parent's name > + * @num_parents: Total number of parents > + * > + # Return: 0: Success > + * Error code: Failure > + */ > +static int get_parent_list(struct device_node *np, u32 clk_id, > + const char **parent_list, u32 *num_parents) > +{ > + int i = 0, ret; > + u32 total_parents = clock[clk_id].num_parents; > + struct clock_topology *clk_nodes; > + struct clock_parent *parents; > + > + clk_nodes = clock[clk_id].node; > + parents = clock[clk_id].parent; > + > + for (i = 0; i < total_parents; i++) { > + if (!parents[i].flag) { > + parent_list[i] = parents[i].name; > + } else if (parents[i].flag == PARENT_CLK_EXTERNAL) { > + ret = of_property_match_string(np, "clock-names", > + parents[i].name); > + if (ret < 0) > + strncpy(parents[i].name, > + "dummy_name", MAX_NAME_LEN); > + parent_list[i] = parents[i].name; > + } else { > + strcat(parents[i].name, > + clk_type_postfix[clk_nodes[parents[i].flag - 1]. > + type]); > + parent_list[i] = parents[i].name; > + } > + } > + > + *num_parents = total_parents; > + return 0; > +} > + > +/** > + * zynqmp_register_clk_topology: Register clock topology > + * @clk_id: Clock Index > + * @clk_name: Clock Name > + * @num_parents: Total number of parents > + * @parent_names: List of parents name > + * > + * Return: 0: Success > + * Error code: Failure > + */ > +static struct clk *zynqmp_register_clk_topology(int clk_id, char *clk_name, > + int num_parents, > + const char **parent_names) > +{ > + int j, ret; > + u32 num_nodes, mult, div; > + char *clk_out = NULL; > + struct clock_topology *nodes; > + struct clk *clk = NULL; > + > + nodes = clock[clk_id].node; > + num_nodes = clock[clk_id].num_nodes; > + > + for (j = 0; j < num_nodes; j++) { > + if (j != (num_nodes - 1)) { > + clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name, > + clk_type_postfix[nodes[j].type]); > + } else { > + clk_out = kasprintf(GFP_KERNEL, "%s", clk_name); > + } > + > + switch (nodes[j].type) { > + case TYPE_MUX: > + clk = zynqmp_clk_register_mux(NULL, clk_out, > + clk_id, parent_names, > + num_parents, > + nodes[j].flag, > + nodes[j].type_flag); > + break; > + case TYPE_PLL: > + clk = clk_register_zynqmp_pll(clk_out, clk_id, > + parent_names, 1, > + nodes[j].flag); > + break; > + case TYPE_FIXEDFACTOR: > + ret = zynqmp_pm_clock_get_fixedfactor_params(clk_id, > + &mult, > + &div); > + clk = clk_register_fixed_factor(NULL, clk_out, > + parent_names[0], > + nodes[j].flag, mult, > + div); > + break; > + case TYPE_DIV1: > + case TYPE_DIV2: > + clk = zynqmp_clk_register_divider(NULL, clk_out, clk_id, > + nodes[j].type, > + parent_names, 1, > + nodes[j].flag, > + nodes[j].type_flag); > + break; > + case TYPE_GATE: > + clk = zynqmp_clk_register_gate(NULL, clk_out, clk_id, > + parent_names, 1, > + nodes[j].flag, > + nodes[j].type_flag); > + break; > + default: > + pr_err("%s() Unknown topology for %s\n", > + __func__, clk_out); > + break; > + } > + if (IS_ERR(clk)) > + pr_warn_once("%s() %s register fail with %ld\n", > + __func__, clk_name, PTR_ERR(clk)); > + > + parent_names[0] = clk_out; > + } > + kfree(clk_out); > + return clk; > +} > + > +/** > + * zynqmp_register_clocks: Register clocks > + * @np: Device node > + * > + * Return: 0: Success > + * Error code: failure > + */ > +static int zynqmp_register_clocks(struct device_node *np) > +{ > + int ret; > + u32 i, total_parents = 0, type = 0; > + const char *parent_names[MAX_PARENT]; > + > + for (i = 0; i < clock_max_idx; i++) { > + char clk_name[MAX_NAME_LEN]; > + > + /* get clock name, continue to next clock if name not found */ > + if (zynqmp_get_clock_name(i, clk_name)) > + continue; > + > + /* Check if clock is valid and output clock. > + * Do not regiter invalid or external clock. > + */ > + ret = get_clock_type(i, &type); > + if (ret || type != CLK_TYPE_OUTPUT) > + continue; > + > + /* Get parents of clock*/ > + if (get_parent_list(np, i, parent_names, &total_parents)) { > + WARN_ONCE(1, "No parents found for %s\n", > + clock[i].clk_name); > + continue; > + } > + > + zynqmp_clks[i] = zynqmp_register_clk_topology(i, clk_name, > + total_parents, > + parent_names); > + > + /* Enable clock if init_enable flag is 1 */ > + if (clock[i].init_enable) > + clk_prepare_enable(zynqmp_clks[i]); > + } > + > + for (i = 0; i < clock_max_idx; i++) { > + if (IS_ERR(zynqmp_clks[i])) { > + pr_err("Zynq Ultrascale+ MPSoC clk %s: register failed with %ld\n", > + clock[i].clk_name, PTR_ERR(zynqmp_clks[i])); > + WARN_ON(1); > + } > + } > + return 0; > +} > + > +/** > + * zynqmp_get_clock_info - Get clock information from firmware using PM_API > + */ > +static void zynqmp_get_clock_info(void) > +{ > + int i, ret; > + u32 attr, type = 0; > + > + memset(clock, 0, sizeof(clock)); > + for (i = 0; i < MAX_CLOCK; i++) { > + zynqmp_pm_clock_get_name(i, clock[i].clk_name); > + if (!strncmp(clock[i].clk_name, END_OF_CLK_NAME, > + MAX_NAME_LEN)) { > + clock_max_idx = i; > + break; > + } else if (!strncmp(clock[i].clk_name, RESERVED_CLK_NAME, > + MAX_NAME_LEN)) { > + continue; > + } > + > + ret = zynqmp_pm_clock_get_attributes(i, &attr); > + if (ret) > + continue; > + > + clock[i].valid = attr & CLK_VALID_MASK; > + clock[i].init_enable = !!(attr & CLK_INIT_ENABLE_MASK); > + clock[i].type = attr >> CLK_TYPE_SHIFT ? CLK_TYPE_EXTERNAL : > + CLK_TYPE_OUTPUT; > + } > + > + /* Get topology of all clock */ > + for (i = 0; i < clock_max_idx; i++) { > + ret = get_clock_type(i, &type); > + if (ret || type != CLK_TYPE_OUTPUT) > + continue; > + > + ret = clock_get_topology(i, clock[i].node, &clock[i].num_nodes); > + if (ret) > + continue; > + > + ret = clock_get_parents(i, clock[i].parent, > + &clock[i].num_parents); > + if (ret) > + continue; > + } > +} > + > +/** > + * zynqmp_clk_setup - Setup the clock framework and register clocks > + * @np: Device node > + */ > +static void __init zynqmp_clk_setup(struct device_node *np) > +{ > + int idx; > + > + idx = of_property_match_string(np, "clock-names", "pss_ref_clk"); > + if (idx < 0) { > + pr_err("pss_ref_clk not provided\n"); > + return; > + } > + idx = of_property_match_string(np, "clock-names", "video_clk"); > + if (idx < 0) { > + pr_err("video_clk not provided\n"); > + return; > + } > + idx = of_property_match_string(np, "clock-names", "pss_alt_ref_clk"); > + if (idx < 0) { > + pr_err("pss_alt_ref_clk not provided\n"); > + return; > + } > + idx = of_property_match_string(np, "clock-names", "aux_ref_clk"); > + if (idx < 0) { > + pr_err("aux_ref_clk not provided\n"); > + return; > + } > + idx = of_property_match_string(np, "clock-names", "gt_crx_ref_clk"); > + if (idx < 0) { > + pr_err("aux_ref_clk not provided\n"); > + return; > + } > + > + zynqmp_get_clock_info(); > + zynqmp_register_clocks(np); > + > + zynqmp_clk_data.clks = zynqmp_clks; > + zynqmp_clk_data.clk_num = clock_max_idx; > + of_clk_add_provider(np, of_clk_src_onecell_get, &zynqmp_clk_data); > +} > + > +/** > + * zynqmp_clock_init - Initialize zynqmp clocks > + * > + * Return: 0 always > + */ > +static int __init zynqmp_clock_init(void) > +{ > + struct device_node *np; > + > + np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp-clkc"); > + if (!np) { > + pr_err("%s: clkc node not found\n", __func__); > + of_node_put(np); > + return 0; > + } > + > + eemi_ops = get_eemi_ops(); > + if (!eemi_ops || !eemi_ops->query_data) { > + pr_err("%s: clk data not found\n", __func__); > + of_node_put(np); > + return 0; > + } > + > + zynqmp_clk_setup(np); > + > + return 0; > +} > +arch_initcall(zynqmp_clock_init); > diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c > new file mode 100644 > index 0000000..1a1473c > --- /dev/null > +++ b/drivers/clk/zynqmp/divider.c > @@ -0,0 +1,239 @@ > +/* > + * Zynq UltraScale+ MPSoC Divider support > + * > + * Copyright (C) 2016-2017 Xilinx > + * > + * SPDX-License-Identifier: GPL-2.0+ Same as above: This tag should be on the fist line this way: // SPDX-License-Identifier: GPL-2.0+ > + * > + * Adjustable divider clock implementation > + */ > + > +#include <linux/clk.h> > +#include <linux/clk-provider.h> > +#include <linux/clk/zynqmp.h> > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/io.h> > +#include <linux/err.h> > +#include <linux/string.h> > +#include <linux/log2.h> > + > +/* > + * DOC: basic adjustable divider clock that cannot gate > + * > + * Traits of this clock: > + * prepare - clk_prepare only ensures that parents are prepared > + * enable - clk_enable only ensures that parents are enabled > + * rate - rate is adjustable. clk->rate = ceiling(parent->rate / divisor) > + * parent - fixed parent. No clk_set_parent support > + */ > + > +#define to_zynqmp_clk_divider(_hw) \ > + container_of(_hw, struct zynqmp_clk_divider, hw) > + > +/** > + * struct zynqmp_clk_divider - adjustable divider clock > + * > + * @hw: handle between common and hardware-specific interfaces > + * @flags: Hardware specific flags > + * @clk_id: Id of clock > + * @div_type: divisor type (TYPE_DIV1 or TYPE_DIV2) > + */ > +struct zynqmp_clk_divider { > + struct clk_hw hw; > + u8 flags; > + u32 clk_id; > + u32 div_type; > +}; > + > +static int zynqmp_divider_get_val(unsigned long parent_rate, unsigned long rate) > +{ > + return DIV_ROUND_UP_ULL((u64)parent_rate, rate); > +} > + > +static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = divider->clk_id; > + u32 div_type = divider->div_type; > + u32 div, value; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_getdivider) > + return -ENXIO; > + > + ret = eemi_ops->clock_getdivider(clk_id, &div); > + > + if (ret) > + pr_warn_once("%s() get divider failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + if (div_type == TYPE_DIV1) > + value = div & 0xFFFF; > + else > + value = (div >> 16) & 0xFFFF; > + > + return zynqmp_divider_get_val((u64)parent_rate, value); > +} > + > +static long zynqmp_clk_divider_round_rate(struct clk_hw *hw, > + unsigned long rate, > + unsigned long *prate) > +{ > + struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = divider->clk_id; > + u32 div_type = divider->div_type; > + u32 bestdiv; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_getdivider) > + return -ENXIO; > + > + /* if read only, just return current value */ > + if (divider->flags & CLK_DIVIDER_READ_ONLY) { > + ret = eemi_ops->clock_getdivider(clk_id, &bestdiv); > + > + if (ret) > + pr_warn_once("%s() get divider failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + if (div_type == TYPE_DIV1) > + bestdiv = bestdiv & 0xFFFF; > + else > + bestdiv = (bestdiv >> 16) & 0xFFFF; > + > + return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); > + } > + > + bestdiv = zynqmp_divider_get_val(*prate, rate); > + > + if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && > + ((clk_hw_get_flags(hw) & CLK_FRAC))) > + bestdiv = rate % *prate ? 1 : bestdiv; > + *prate = rate * bestdiv; > + > + return rate; > +} > + > +/** > + * zynqmp_clk_divider_set_rate - Set rate of divider clock > + * @hw: handle between common and hardware-specific interfaces > + * @rate: rate of clock to be set > + * @parent_rate: rate of parent clock > + * > + * Return: 0 always > + */ > +static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long parent_rate) > +{ > + struct zynqmp_clk_divider *divider = to_zynqmp_clk_divider(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = divider->clk_id; > + u32 div_type = divider->div_type; > + u32 value, div; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_setdivider) > + return -ENXIO; > + > + value = zynqmp_divider_get_val(parent_rate, rate); > + if (div_type == TYPE_DIV1) { > + div = value & 0xFFFF; > + div |= ((u16)-1) << 16; > + } else { > + div = ((u16)-1); > + div |= value << 16; > + } > + > + ret = eemi_ops->clock_setdivider(clk_id, div); > + > + if (ret) > + pr_warn_once("%s() set divider failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return 0; > +} > + > +static const struct clk_ops zynqmp_clk_divider_ops = { > + .recalc_rate = zynqmp_clk_divider_recalc_rate, > + .round_rate = zynqmp_clk_divider_round_rate, > + .set_rate = zynqmp_clk_divider_set_rate, > +}; > + > +/** > + * _register_divider - register a divider clock > + * @dev: device registering this clock > + * @name: name of this clock > + * @clk_id: Id of clock > + * @div_type: Type of divisor > + * @parents: name of clock's parents > + * @num_parents: number of parents > + * @flags: framework-specific flags > + * @clk_divider_flags: divider-specific flags for this clock > + * > + * Return: handle to registered clock divider > + */ > +static struct clk *_register_divider(struct device *dev, const char *name, > + u32 clk_id, u32 div_type, > + const char * const *parents, > + u8 num_parents, unsigned long flags, > + u8 clk_divider_flags) > +{ > + struct zynqmp_clk_divider *div; > + struct clk *clk; > + struct clk_init_data init; > + > + /* allocate the divider */ > + div = kzalloc(sizeof(*div), GFP_KERNEL); > + if (!div) > + return ERR_PTR(-ENOMEM); > + > + init.name = name; > + init.ops = &zynqmp_clk_divider_ops; > + init.flags = flags; > + init.parent_names = parents; > + init.num_parents = num_parents; > + > + /* struct clk_divider assignments */ > + div->flags = clk_divider_flags; > + div->hw.init = &init; > + div->clk_id = clk_id; > + div->div_type = div_type; > + > + /* register the clock */ > + clk = clk_register(dev, &div->hw); > + > + if (IS_ERR(clk)) > + kfree(div); > + > + return clk; > +} > + > +/** > + * zynqmp_clk_register_divider - register a divider clock > + * @dev: device registering this clock > + * @name: name of this clock > + * @clk_id: Id of clock > + * @div_type: Type of divisor > + * @parents: name of clock's parents > + * @num_parents: number of parents > + * @flags: framework-specific flags > + * @clk_divider_flags: divider-specific flags for this clock > + * > + * Return: handle to registered clock divider > + */ > +struct clk *zynqmp_clk_register_divider(struct device *dev, const char *name, > + u32 clk_id, u32 div_type, > + const char * const *parents, > + u8 num_parents, unsigned long flags, > + u8 clk_divider_flags) > +{ > + return _register_divider(dev, name, clk_id, div_type, parents, > + num_parents, flags, clk_divider_flags); > +} > +EXPORT_SYMBOL_GPL(zynqmp_clk_register_divider); > diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c > new file mode 100644 > index 0000000..75def21 > --- /dev/null > +++ b/drivers/clk/zynqmp/pll.c > @@ -0,0 +1,384 @@ > +/* > + * Zynq UltraScale+ MPSoC PLL driver > + * > + * Copyright (C) 2016-2017 Xilinx > + * > + * SPDX-License-Identifier: GPL-2.0+ Same as above: This tag should be on the fist line this way: // SPDX-License-Identifier: GPL-2.0+ > + */ > +#include <linux/clk.h> > +#include <linux/clk/zynqmp.h> > +#include <linux/clk-provider.h> > +#include <linux/slab.h> > +#include <linux/io.h> > + > +/** > + * struct zynqmp_pll - Structure for PLL clock > + * @hw: Handle between common and hardware-specific interfaces > + * @clk_id: PLL clock ID > + */ > +struct zynqmp_pll { > + struct clk_hw hw; > + u32 clk_id; > +}; > + > +#define to_zynqmp_pll(_hw) container_of(_hw, struct zynqmp_pll, hw) > + > +/* Register bitfield defines */ > +#define PLLCTRL_FBDIV_MASK 0x7f00 > +#define PLLCTRL_FBDIV_SHIFT 8 > +#define PLLCTRL_BP_MASK BIT(3) > +#define PLLCTRL_DIV2_MASK BIT(16) > +#define PLLCTRL_RESET_MASK 1 > +#define PLLCTRL_RESET_VAL 1 > +#define PLL_STATUS_LOCKED 1 > +#define PLLCTRL_RESET_SHIFT 0 > +#define PLLCTRL_DIV2_SHIFT 16 > + > +#define PLL_FBDIV_MIN 25 > +#define PLL_FBDIV_MAX 125 > + > +#define PS_PLL_VCO_MIN 1500000000 > +#define PS_PLL_VCO_MAX 3000000000UL > + > +enum pll_mode { > + PLL_MODE_INT, > + PLL_MODE_FRAC, > +}; > + > +#define FRAC_OFFSET 0x8 > +#define PLLFCFG_FRAC_EN BIT(31) > +#define FRAC_DIV 0x10000 /* 2^16 */ > + > +/** > + * pll_get_mode - Get mode of PLL > + * @hw: Handle between common and hardware-specific interfaces > + * > + * Return: Mode of PLL > + */ > +static inline enum pll_mode pll_get_mode(struct clk_hw *hw) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + u32 clk_id = clk->clk_id; > + const char *clk_name = clk_hw_get_name(hw); > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->ioctl) > + return -ENXIO; > + > + ret = eemi_ops->ioctl(0, IOCTL_GET_PLL_FRAC_MODE, clk_id, 0, > + ret_payload); > + if (ret) > + pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return ret_payload[1]; > +} > + > +/** > + * pll_set_mode - Set the PLL mode > + * @hw: Handle between common and hardware-specific interfaces > + * @on: Flag to determine the mode > + */ > +static inline void pll_set_mode(struct clk_hw *hw, bool on) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + u32 clk_id = clk->clk_id; > + const char *clk_name = clk_hw_get_name(hw); > + int ret; > + u32 mode; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->ioctl) { > + pr_warn_once("eemi_ops not found\n"); > + return; > + } > + > + if (on) > + mode = PLL_MODE_FRAC; > + else > + mode = PLL_MODE_INT; > + > + ret = eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_MODE, clk_id, mode, NULL); > + if (ret) > + pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n", > + __func__, clk_name, ret); > +} > + > +/** > + * zynqmp_pll_round_rate - Round a clock frequency > + * @hw: Handle between common and hardware-specific interfaces > + * @rate: Desired clock frequency > + * @prate: Clock frequency of parent clock > + * > + * Return: Frequency closest to @rate the hardware can generate > + */ > +static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long *prate) > +{ > + u32 fbdiv; > + long rate_div, f; > + > + /* Enable the fractional mode if needed */ > + rate_div = ((rate * FRAC_DIV) / *prate); > + f = rate_div % FRAC_DIV; > + pll_set_mode(hw, !!f); > + > + if (pll_get_mode(hw) == PLL_MODE_FRAC) { > + if (rate > PS_PLL_VCO_MAX) { > + fbdiv = rate / PS_PLL_VCO_MAX; > + rate = rate / (fbdiv + 1); > + } > + if (rate < PS_PLL_VCO_MIN) { > + fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); > + rate = rate * fbdiv; > + } > + return rate; > + } > + > + fbdiv = DIV_ROUND_CLOSEST(rate, *prate); > + fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); > + return *prate * fbdiv; > +} > + > +/** > + * zynqmp_pll_recalc_rate - Recalculate clock frequency > + * @hw: Handle between common and hardware-specific interfaces > + * @parent_rate: Clock frequency of parent clock > + * Return: Current clock frequency > + */ > +static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + u32 clk_id = clk->clk_id; > + const char *clk_name = clk_hw_get_name(hw); > + u32 fbdiv, data; > + unsigned long rate, frac; > + u32 ret_payload[PAYLOAD_ARG_CNT]; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_getdivider) > + return 0; > + > + /* > + * makes probably sense to redundantly save fbdiv in the struct > + * zynqmp_pll to save the IO access. > + */ > + ret = eemi_ops->clock_getdivider(clk_id, &fbdiv); > + if (ret) > + pr_warn_once("%s() get divider failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + rate = parent_rate * fbdiv; > + if (pll_get_mode(hw) == PLL_MODE_FRAC) { > + eemi_ops->ioctl(0, IOCTL_GET_PLL_FRAC_DATA, clk_id, 0, > + ret_payload); > + data = ret_payload[1]; > + frac = (parent_rate * data) / FRAC_DIV; > + rate = rate + frac; > + } > + > + return rate; > +} > + > +/** > + * zynqmp_pll_set_rate - Set rate of PLL > + * @hw: Handle between common and hardware-specific interfaces > + * @rate: Frequency of clock to be set > + * @parent_rate: Clock frequency of parent clock > + */ > +static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long parent_rate) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + u32 clk_id = clk->clk_id; > + const char *clk_name = clk_hw_get_name(hw); > + u32 fbdiv, data; > + long rate_div, frac, m, f; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_setdivider) > + return -ENXIO; > + > + if (pll_get_mode(hw) == PLL_MODE_FRAC) { > + unsigned int children; > + > + /* > + * We're running on a ZynqMP compatible machine, make sure the > + * VPLL only has one child. > + */ > + children = clk_get_children("vpll"); > + > + /* Account for vpll_to_lpd and dp_video_ref */ > + if (children > 2) > + WARN(1, "Two devices are using vpll which is forbidden\n"); > + > + rate_div = ((rate * FRAC_DIV) / parent_rate); > + m = rate_div / FRAC_DIV; > + f = rate_div % FRAC_DIV; > + m = clamp_t(u32, m, (PLL_FBDIV_MIN), (PLL_FBDIV_MAX)); > + rate = parent_rate * m; > + frac = (parent_rate * f) / FRAC_DIV; > + > + ret = eemi_ops->clock_setdivider(clk_id, m); > + if (ret) > + pr_warn_once("%s() set divider failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + data = (FRAC_DIV * f) / FRAC_DIV; > + eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_DATA, clk_id, data, NULL); > + > + return (rate + frac); > + } > + > + fbdiv = DIV_ROUND_CLOSEST(rate, parent_rate); > + fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); > + ret = eemi_ops->clock_setdivider(clk_id, fbdiv); > + if (ret) > + pr_warn_once("%s() set divider failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return parent_rate * fbdiv; > +} > + > +/** > + * zynqmp_pll_is_enabled - Check if a clock is enabled > + * @hw: Handle between common and hardware-specific interfaces > + * > + * Return: 1 if the clock is enabled, 0 otherwise > + */ > +static int zynqmp_pll_is_enabled(struct clk_hw *hw) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = clk->clk_id; > + unsigned int state; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_getstate) > + return 0; > + > + ret = eemi_ops->clock_getstate(clk_id, &state); > + if (ret) > + pr_warn_once("%s() clock get state failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return state ? 1 : 0; > +} > + > +/** > + * zynqmp_pll_enable - Enable clock > + * @hw: Handle between common and hardware-specific interfaces > + * > + * Return: 0 always > + */ > +static int zynqmp_pll_enable(struct clk_hw *hw) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = clk->clk_id; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_enable) > + return 0; > + > + if (zynqmp_pll_is_enabled(hw)) > + return 0; > + > + pr_info("PLL: enable\n"); > + > + ret = eemi_ops->clock_enable(clk_id); > + if (ret) > + pr_warn_once("%s() clock enable failed for %s, ret = %d\n", > + __func__, clk_name, ret); > + > + return 0; > +} > + > +/** > + * zynqmp_pll_disable - Disable clock > + * @hw: Handle between common and hardware-specific interfaces > + * > + */ > +static void zynqmp_pll_disable(struct clk_hw *hw) > +{ > + struct zynqmp_pll *clk = to_zynqmp_pll(hw); > + const char *clk_name = clk_hw_get_name(hw); > + u32 clk_id = clk->clk_id; > + int ret; > + const struct zynqmp_eemi_ops *eemi_ops = get_eemi_ops(); > + > + if (!eemi_ops || !eemi_ops->clock_disable) > + return; > + > + if (!zynqmp_pll_is_enabled(hw)) > + return; > + > + pr_info("PLL: shutdown\n"); > + > + ret = eemi_ops->clock_disable(clk_id); > + if (ret) > + pr_warn_once("%s() clock disable failed for %s, ret = %d\n", > + __func__, clk_name, ret); > +} > + > +static const struct clk_ops zynqmp_pll_ops = { > + .enable = zynqmp_pll_enable, > + .disable = zynqmp_pll_disable, > + .is_enabled = zynqmp_pll_is_enabled, > + .round_rate = zynqmp_pll_round_rate, > + .recalc_rate = zynqmp_pll_recalc_rate, > + .set_rate = zynqmp_pll_set_rate, > +}; > + > +/** > + * clk_register_zynqmp_pll - Register PLL with the clock framework > + * @name: PLL name > + * @flag: PLL flags > + * @parents: Parent clock names > + * @num_parents:Number of parents > + * @pll_ctrl: Pointer to PLL control register > + * @pll_status: Pointer to PLL status register > + * @lock_index: Bit index to this PLL's lock status bit in @pll_status > + * > + * Return: Handle to the registered clock > + */ > +struct clk *clk_register_zynqmp_pll(const char *name, u32 clk_id, > + const char * const *parents, > + u8 num_parents, unsigned long flag) > +{ > + struct zynqmp_pll *pll; > + struct clk *clk; > + struct clk_init_data init; > + int status; > + > + init.name = name; > + init.ops = &zynqmp_pll_ops; > + init.flags = flag; > + init.parent_names = parents; > + init.num_parents = num_parents; > + > + pll = kmalloc(sizeof(*pll), GFP_KERNEL); > + if (!pll) > + return ERR_PTR(-ENOMEM); > + > + /* Populate the struct */ > + pll->hw.init = &init; > + pll->clk_id = clk_id; > + > + clk = clk_register(NULL, &pll->hw); > + if (WARN_ON(IS_ERR(clk))) > + kfree(pll); > + > + status = clk_set_rate_range(clk, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX); > + if (status < 0) > + pr_err("%s:ERROR clk_set_rate_range failed %d\n", name, status); > + > + return clk; > +} > diff --git a/include/linux/clk/zynqmp.h b/include/linux/clk/zynqmp.h > new file mode 100644 > index 0000000..024ebf8 > --- /dev/null > +++ b/include/linux/clk/zynqmp.h > @@ -0,0 +1,46 @@ > +/* > + * Copyright (C) 2016-2017 Xilinx > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ This tag should be on the fist line this way: /* SPDX-License-Identifier: GPL-2.0+ */ > + > +#ifndef __LINUX_CLK_ZYNQMP_H_ > +#define __LINUX_CLK_ZYNQMP_H_ > + > +#include <linux/spinlock.h> > +#include <linux/firmware/xilinx/zynqmp/firmware.h> > + > +#define CLK_FRAC BIT(13) /* has a fractional parent */ > + > +struct device; > + > +struct clk *clk_register_zynqmp_pll(const char *name, u32 clk_id, > + const char * const *parent, u8 num_parents, > + unsigned long flag); > + > +struct clk *zynqmp_clk_register_gate(struct device *dev, const char *name, > + u32 clk_id, > + const char * const *parent_name, > + u8 num_parents, unsigned long flags, > + u8 clk_gate_flags); > + > +struct clk *zynqmp_clk_register_divider(struct device *dev, const char *name, > + u32 clk_id, u32 div_type, > + const char * const *parent_name, > + u8 num_parents, > + unsigned long flags, > + u8 clk_divider_flags); > + > +struct clk *zynqmp_clk_register_mux(struct device *dev, const char *name, > + u32 clk_id, > + const char **parent_names, > + u8 num_parents, unsigned long flags, > + u8 clk_mux_flags); > + > +struct clk *zynqmp_clk_register_mux_table(struct device *dev, const char *name, > + u32 clk_id, > + const char * const *parent_names, > + u8 num_parents, unsigned long flags, > + u8 clk_mux_flags); > + > +#endif > -- > 2.7.4 > -- Cordially Philippe Ombredanne ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver 2018-01-09 12:52 ` Philippe Ombredanne @ 2018-01-10 20:06 ` Jolly Shah 2018-01-10 20:15 ` Jolly Shah 1 sibling, 0 replies; 10+ messages in thread From: Jolly Shah @ 2018-01-10 20:06 UTC (permalink / raw) To: Philippe Ombredanne Cc: Michael Turquette, Stephen Boyd, Michal Simek, linux-clk@vger.kernel.org, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, LKML, Rajan Vaja, Tejas Patel, Shubhrajyoti Datta VGhhbmtzIFBoaWxpcHBlIGZvciByZXZpZXcuDQpXaWxsIGZpeCBhbGwgU1BEWCB0YWdzIGluIG5l eHQgdmVyc2lvbi4NCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBQaGls aXBwZSBPbWJyZWRhbm5lIFttYWlsdG86cG9tYnJlZGFubmVAbmV4Yi5jb21dDQo+IFNlbnQ6IFR1 ZXNkYXksIEphbnVhcnkgMDksIDIwMTggNDo1MyBBTQ0KPiBUbzogSm9sbHkgU2hhaCA8Sk9MTFlT QHhpbGlueC5jb20+DQo+IENjOiBNaWNoYWVsIFR1cnF1ZXR0ZSA8bXR1cnF1ZXR0ZUBiYXlsaWJy ZS5jb20+OyBTdGVwaGVuIEJveWQNCj4gPHNib3lkQGNvZGVhdXJvcmEub3JnPjsgTWljaGFsIFNp bWVrIDxtaWNoYWwuc2ltZWtAeGlsaW54LmNvbT47IGxpbnV4LQ0KPiBjbGtAdmdlci5rZXJuZWwu b3JnOyBtb2RlcmF0ZWQgbGlzdDpBUk0vRlJFRVNDQUxFIElNWCAvIE1YQyBBUk0NCj4gQVJDSElU RUNUVVJFIDxsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmc+OyBMS01MIDxsaW51 eC0NCj4ga2VybmVsQHZnZXIua2VybmVsLm9yZz47IEpvbGx5IFNoYWggPEpPTExZU0B4aWxpbngu Y29tPjsgUmFqYW4gVmFqYQ0KPiA8UkFKQU5WQHhpbGlueC5jb20+OyBUZWphcyBQYXRlbCA8VEVK QVNQQHhpbGlueC5jb20+OyBTaHViaHJhanlvdGkgRGF0dGENCj4gPHNodWJocmFqQHhpbGlueC5j b20+DQo+IFN1YmplY3Q6IFJlOiBbUkZDIFBBVENIIDIvMl0gZHJpdmVyczogY2xrOiBBZGQgWnlu cU1QIGNsb2NrIGRyaXZlcg0KPiANCj4gSm9sbHksDQo+IA0KPiBPbiBNb24sIEphbiA4LCAyMDE4 IGF0IDExOjE2IFBNLCBKb2xseSBTaGFoIDxqb2xseS5zaGFoQHhpbGlueC5jb20+IHdyb3RlOg0K PiA+IFRoaXMgcGF0Y2ggYWRkcyBDQ0YgY29tcGxpYW50IGNsb2NrIGRyaXZlciBmb3IgWnlucU1Q Lg0KPiA+IENsb2NrIGRyaXZlciBxdWVyaWVzIHN1cHBvcnRlZCBjbG9jayBpbmZvcm1hdGlvbiBm cm9tDQo+ID4gZmlybXdhcmUgYW5kIHJlZ2l0ZXJzIHBsbCBhbmQgb3V0cHV0IGNsb2NrcyB3aXRo IENDRi4NCj4gPg0KPiA+IFNpZ25lZC1vZmYtYnk6IEpvbGx5IFNoYWggPGpvbGx5c0B4aWxpbngu Y29tPg0KPiA+IFNpZ25lZC1vZmYtYnk6IFJhamFuIFZhamEgPHJhamFudkB4aWxpbnguY29tPg0K PiA+IFNpZ25lZC1vZmYtYnk6IFRlamFzIFBhdGVsIDx0ZWphc3BAeGlsaW54LmNvbT4NCj4gPiBT aWduZWQtb2ZmLWJ5OiBTaHViaHJhanlvdGkgRGF0dGEgPHNodWJocmFqeW90aS5kYXR0YUB4aWxp bnguY29tPg0KPiA+IC0tLQ0KPiANCj4gPHNuaXA+DQo+IA0KPiANCj4gPiAgLi4uL2RldmljZXRy ZWUvYmluZGluZ3MvY2xvY2svenlucV9tcHNvYy50eHQgICAgICAgfCAxNjMgKysrKysNCj4gPiAg ZHJpdmVycy9jbGsvS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDEg Kw0KPiA+ICBkcml2ZXJzL2Nsay9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICB8ICAgMSArDQo+ID4gIGRyaXZlcnMvY2xrL3p5bnFtcC9LY29uZmlnICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICA4ICsNCj4gPiAgZHJpdmVycy9jbGsvenlucW1wL01ha2VmaWxlICAgICAg ICAgICAgICAgICAgICAgICAgfCAgIDMgKw0KPiA+ICBkcml2ZXJzL2Nsay96eW5xbXAvY2xrLWdh dGUtenlucW1wLmMgICAgICAgICAgICAgICB8IDE1OCArKysrKw0KPiA+ICBkcml2ZXJzL2Nsay96 eW5xbXAvY2xrLW11eC16eW5xbXAuYyAgICAgICAgICAgICAgICB8IDE5MCArKysrKysNCj4gPiAg ZHJpdmVycy9jbGsvenlucW1wL2Nsa2MuYyAgICAgICAgICAgICAgICAgICAgICAgICAgfCA3MDcg KysrKysrKysrKysrKysrKysrKysrDQo+ID4gIGRyaXZlcnMvY2xrL3p5bnFtcC9kaXZpZGVyLmMg ICAgICAgICAgICAgICAgICAgICAgIHwgMjM5ICsrKysrKysNCj4gPiAgZHJpdmVycy9jbGsvenlu cW1wL3BsbC5jICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAzODQgKysrKysrKysrKysNCj4g PiAgaW5jbHVkZS9saW51eC9jbGsvenlucW1wLmggICAgICAgICAgICAgICAgICAgICAgICAgfCAg NDYgKysNCj4gPiAgMTEgZmlsZXMgY2hhbmdlZCwgMTkwMCBpbnNlcnRpb25zKCspDQo+ID4gIGNy ZWF0ZSBtb2RlIDEwMDY0NA0KPiBEb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xv Y2svenlucV9tcHNvYy50eHQNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY2xrL3p5 bnFtcC9LY29uZmlnDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2Nsay96eW5xbXAv TWFrZWZpbGUNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY2xrL3p5bnFtcC9jbGst Z2F0ZS16eW5xbXAuYw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvenlucW1w L2Nsay1tdXgtenlucW1wLmMNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY2xrL3p5 bnFtcC9jbGtjLmMNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY2xrL3p5bnFtcC9k aXZpZGVyLmMNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvY2xrL3p5bnFtcC9wbGwu Yw0KPiA+ICBjcmVhdGUgbW9kZSAxMDA2NDQgaW5jbHVkZS9saW51eC9jbGsvenlucW1wLmgNCj4g Pg0KPiA+IGRpZmYgLS1naXQgYS9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvY2xv Y2svenlucV9tcHNvYy50eHQNCj4gYi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3Mv Y2xvY2svenlucV9tcHNvYy50eHQNCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4 IDAwMDAwMDAuLjkwNjFiNTcNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvRG9jdW1lbnRh dGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Nsb2NrL3p5bnFfbXBzb2MudHh0DQo+ID4gQEAgLTAs MCArMSwxNjMgQEANCj4gPiArRGV2aWNlIFRyZWUgQ2xvY2sgYmluZGluZ3MgZm9yIHRoZSBaeW5x IFVsdHJhc2NhbGUrIE1QU29DDQo+ID4gKw0KPiA+ICtUaGUgWnlucSBVbHRyYXNjYWxlKyBNUFNv QyBoYXMgc2V2ZXJhbCBkaWZmZXJlbnQgY2xrIHByb3ZpZGVycywNCj4gPiArZWFjaCB3aXRoIHRo ZXJlIG93biBiaW5kaW5ncy4NCj4gPiArVGhlIHB1cnBvc2Ugb2YgdGhpcyBkb2N1bWVudCBpcyB0 byBkb2N1bWVudCB0aGVpciB1c2FnZS4NCj4gPiArDQo+ID4gK1NlZSBjbG9ja19iaW5kaW5ncy50 eHQgZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIGdlbmVyaWMgY2xvY2sgYmluZGluZ3MuDQo+ ID4gKw0KPiA+ICs9PSBDbG9jayBDb250cm9sbGVyID09DQo+ID4gK1RoZSBjbG9jayBjb250cm9s bGVyIGlzIGEgbG9naWNhbCBhYnN0cmFjdGlvbiBvZiBaeW5xIFVsdHJhc2NhbGUrIE1QU29DIGNs b2NrDQo+ID4gK3RyZWUuIEl0IHJlYWRzIHJlcXVpcmVkIGlucHV0IGNsb2NrIGZyZXF1ZW5jaWVz IGZyb20gdGhlIGRldmljZXRyZWUgYW5kIGFjdHMNCj4gPiArYXMgY2xvY2sgcHJvdmlkZXIgZm9y IGFsbCBjbG9jayBjb25zdW1lcnMgb2YgUFMgY2xvY2tzLg0KPiA+ICsNCj4gPiArUmVxdWlyZWQg cHJvcGVydGllczoNCj4gPiArIC0gI2Nsb2NrLWNlbGxzIDogTXVzdCBiZSAxDQo+ID4gKyAtIGNv bXBhdGlibGUgOiAieGxueCx6eW5xbXAtY2xrYyINCj4gPiArIC0gY2xvY2tzIDogbGlzdCBvZiBj bG9jayBzcGVjaWZpZXJzIHdoaWNoIGFyZSBleHRlcm5hbCBpbnB1dCBjbG9ja3MgdG8gdGhlDQo+ ID4gKyAgICAgICAgICAgZ2l2ZW4gY2xvY2sgY29udHJvbGxlci4gUGxlYXNlIHJlZmVyIHRoZSBu ZXh0IHNlY3Rpb24gdG8gZmluZA0KPiA+ICsgICAgICAgICAgIHRoZSBpbnB1dCBjbG9ja3MgZm9y IGEgZ2l2ZW4gY29udHJvbGxlci4NCj4gPiArIC0gY2xvY2stbmFtZXMgOiBsaXN0IG9mIG5hbWVz IG9mIGNsb2NrcyB3aGljaCBhcmUgZXh0ZXJhbCBpbnB1dCBjbG9ja3MgdG8gdGhlDQo+ID4gKyAg ICAgICAgICAgICAgICBnaXZlbiBjbG9jayBjb250cm9sbGVyLiBQbGVhc2UgcmVmZXIgdG8gdGhl IGNsb2NrIGJpbmRpbmdzDQo+ID4gKyAgICAgICAgICAgICAgICBmb3IgbW9yZSBkZXRhaWxzDQo+ ID4gKw0KPiA+ICtJbnB1dCBjbG9ja3MgZm9yIHp5bnFtcCBVbHRyYXNjYWxlKyBjbG9jayBjb250 cm9sbGVyOg0KPiA+ICtUaGUgWnlucSBVbHRyYVNjYWxlKyBNUFNvQyBoYXMgb25lIHByaW1hcnkg YW5kIGZvdXIgYWx0ZXJuYXRpdmUgcmVmZXJlbmNlDQo+IGNsb2NrDQo+ID4gK2lucHV0cy4NCj4g PiArVGhlc2UgcmVxdWlyZWQgY2xvY2sgaW5wdXRzIGFyZSB0aGUNCj4gPiArIC0gcHNzX3JlZl9j bGsgKFBTIHJlZmVyZW5jZSBjbG9jaykNCj4gPiArIC0gdmlkZW9fY2xrIChyZWZlcmVuY2UgY2xv Y2sgZm9yIHZpZGVvIHN5c3RlbSApDQo+ID4gKyAtIHBzc19hbHRfcmVmX2NsayAoYWx0ZXJuYXRp dmUgUFMgcmVmZXJlbmNlIGNsb2NrKQ0KPiA+ICsgLSBhdXhfcmVmX2Nsaw0KPiA+ICsgLSBndF9j cnhfcmVmX2NsayAodHJhbnNjZWl2ZXIgcmVmZXJlbmNlIGNsb2NrKQ0KPiA+ICsNCj4gPiArVGhl IGZvbGxvd2luZyBzdHJpbmdzIGFyZSBvcHRpb25hbCBwYXJhbWV0ZXJzIHRvIHRoZSAnY2xvY2st bmFtZXMnIHByb3BlcnR5DQo+IGluDQo+ID4gK29yZGVyIHRvIHByb3ZpZGUgYW4gb3B0aW9uYWwg KEUpTUlPIGNsb2NrIHNvdXJjZS4NCj4gPiArIC0gc3dkdDBfZXh0X2Nsaw0KPiA+ICsgLSBzd2R0 MV9leHRfY2xrDQo+ID4gKyAtIGdlbTBfZW1pb19jbGsNCj4gPiArIC0gZ2VtMV9lbWlvX2Nsaw0K PiA+ICsgLSBnZW0yX2VtaW9fY2xrDQo+ID4gKyAtIGdlbTNfZW1pb19jbGsNCj4gPiArIC0gbWlv X2Nsa19YWCAgICAgICAgICAjIHdpdGggWFggPSAwMC4uNzcNCj4gPiArIC0gbWlvX2Nsa181MF9v cl81MSAgICAjZm9yIHRoZSBtdXggY2xvY2sgdG8gZ2VtIHRzdSBmcm9tIDUwIG9yIDUxDQo+ID4g Kw0KPiA+ICsNCj4gPiArT3V0cHV0IGNsb2NrcyBmb3IgenlucW1wIFVsdHJhc2NhbGUrIGNsb2Nr IGNvbnRyb2xsZXI6DQo+ID4gK091dHB1dCBjbG9ja3MgYXJlIHJlZ2lzdGVyZWQgYmFzZWQgb24g Y2xvY2sgaW5mb3JtYXRpb24gcmVjZWl2ZWQgZnJvbQ0KPiBmaXJtd2FyZS4NCj4gPiArT3V0cHV0 IGNsb2NrIGluZGV4ZXMgYXJlIG1lbnRpb25lZCBiZWxvdzoNCj4gPiArDQo+ID4gK0Nsb2NrIElE OiAgICAgIE91dHB1dCBjbG9jayBuYW1lOg0KPiA+ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tDQo+ID4gKzAgICAgICAgICAgICAgIGlvcGxsDQo+ID4gKzEgICAgICAgICAg ICAgIHJwbGwNCj4gPiArMiAgICAgICAgICAgICAgYXBsbA0KPiA+ICszICAgICAgICAgICAgICBk cGxsDQo+ID4gKzQgICAgICAgICAgICAgIHZwbGwNCj4gPiArNSAgICAgICAgICAgICAgaW9wbGxf dG9fZnBkDQo+ID4gKzYgICAgICAgICAgICAgIHJwbGxfdG9fZnBkDQo+ID4gKzcgICAgICAgICAg ICAgIGFwbGxfdG9fbHBkDQo+ID4gKzggICAgICAgICAgICAgIGRwbGxfdG9fbHBkDQo+ID4gKzkg ICAgICAgICAgICAgIHZwbGxfdG9fbHBkDQo+ID4gKzEwICAgICAgICAgICAgIGFjcHUNCj4gPiAr MTEgICAgICAgICAgICAgYWNwdV9oYWxmDQo+ID4gKzEyICAgICAgICAgICAgIGRiZl9mcGQNCj4g PiArMTMgICAgICAgICAgICAgZGJmX2xwZA0KPiA+ICsxNCAgICAgICAgICAgICBkYmdfdHJhY2UN Cj4gPiArMTUgICAgICAgICAgICAgZGJnX3RzdG1wDQo+ID4gKzE2ICAgICAgICAgICAgIGRwX3Zp ZGVvX3JlZg0KPiA+ICsxNyAgICAgICAgICAgICBkcF9hdWRpb19yZWYNCj4gPiArMTggICAgICAg ICAgICAgZHBfc3RjX3JlZg0KPiA+ICsxOSAgICAgICAgICAgICBnZG1hX3JlZg0KPiA+ICsyMCAg ICAgICAgICAgICBkcGRtYV9yZWYNCj4gPiArMjEgICAgICAgICAgICAgZGRyX3JlZg0KPiA+ICsy MiAgICAgICAgICAgICBzYXRhX3JlZg0KPiA+ICsyMyAgICAgICAgICAgICBwY2llX3JlZg0KPiA+ ICsyNCAgICAgICAgICAgICBncHVfcmVmDQo+ID4gKzI1ICAgICAgICAgICAgIGdwdV9wcDBfcmVm DQo+ID4gKzI2ICAgICAgICAgICAgIGdwdV9wcDFfcmVmDQo+ID4gKzI3ICAgICAgICAgICAgIHRv cHN3X21haW4NCj4gPiArMjggICAgICAgICAgICAgdG9wc3dfbHNidXMNCj4gPiArMjkgICAgICAg ICAgICAgZ3RncmVmMF9yZWYNCj4gPiArMzAgICAgICAgICAgICAgbHBkX3N3aXRjaA0KPiA+ICsz MSAgICAgICAgICAgICBscGRfbHNidXMNCj4gPiArMzIgICAgICAgICAgICAgdXNiMF9idXNfcmVm DQo+ID4gKzMzICAgICAgICAgICAgIHVzYjFfYnVzX3JlZg0KPiA+ICszNCAgICAgICAgICAgICB1 c2IzX2R1YWxfcmVmDQo+ID4gKzM1ICAgICAgICAgICAgIHVzYjANCj4gPiArMzYgICAgICAgICAg ICAgdXNiMQ0KPiA+ICszNyAgICAgICAgICAgICBjcHVfcjUNCj4gPiArMzggICAgICAgICAgICAg Y3B1X3I1X2NvcmUNCj4gPiArMzkgICAgICAgICAgICAgY3N1X3NwYg0KPiA+ICs0MCAgICAgICAg ICAgICBjc3VfcGxsDQo+ID4gKzQxICAgICAgICAgICAgIHBjYXANCj4gPiArNDIgICAgICAgICAg ICAgaW91X3N3aXRjaA0KPiA+ICs0MyAgICAgICAgICAgICBnZW1fdHN1X3JlZg0KPiA+ICs0NCAg ICAgICAgICAgICBnZW1fdHN1DQo+ID4gKzQ1ICAgICAgICAgICAgIGdlbTBfcmVmDQo+ID4gKzQ2 ICAgICAgICAgICAgIGdlbTFfcmVmDQo+ID4gKzQ3ICAgICAgICAgICAgIGdlbTJfcmVmDQo+ID4g KzQ4ICAgICAgICAgICAgIGdlbTNfcmVmDQo+ID4gKzQ5ICAgICAgICAgICAgIGdlbTBfdHgNCj4g PiArNTAgICAgICAgICAgICAgZ2VtMV90eA0KPiA+ICs1MSAgICAgICAgICAgICBnZW0yX3R4DQo+ ID4gKzUyICAgICAgICAgICAgIGdlbTNfdHgNCj4gPiArNTMgICAgICAgICAgICAgcXNwaV9yZWYN Cj4gPiArNTQgICAgICAgICAgICAgc2RpbzBfcmVmDQo+ID4gKzU1ICAgICAgICAgICAgIHNkaW8x X3JlZg0KPiA+ICs1NiAgICAgICAgICAgICB1YXJ0MF9yZWYNCj4gPiArNTcgICAgICAgICAgICAg dWFydDFfcmVmDQo+ID4gKzU4ICAgICAgICAgICAgIHNwaTBfcmVmDQo+ID4gKzU5ICAgICAgICAg ICAgIHNwaTFfcmVmDQo+ID4gKzYwICAgICAgICAgICAgIG5hbmRfcmVmDQo+ID4gKzYxICAgICAg ICAgICAgIGkyYzBfcmVmDQo+ID4gKzYyICAgICAgICAgICAgIGkyYzFfcmVmDQo+ID4gKzYzICAg ICAgICAgICAgIGNhbjBfcmVmDQo+ID4gKzY0ICAgICAgICAgICAgIGNhbjFfcmVmDQo+ID4gKzY1 ICAgICAgICAgICAgIGNhbjANCj4gPiArNjYgICAgICAgICAgICAgY2FuMQ0KPiA+ICs2NyAgICAg ICAgICAgICBkbGxfcmVmDQo+ID4gKzY4ICAgICAgICAgICAgIGFkbWFfcmVmDQo+ID4gKzY5ICAg ICAgICAgICAgIHRpbWVzdGFtcF9yZWYNCj4gPiArNzAgICAgICAgICAgICAgYW1zX3JlZg0KPiA+ ICs3MSAgICAgICAgICAgICBwbDBfcmVmDQo+ID4gKzcyICAgICAgICAgICAgIHBsMV9yZWYNCj4g PiArNzMgICAgICAgICAgICAgcGwyX3JlZg0KPiA+ICs3NCAgICAgICAgICAgICBwbDNfcmVmDQo+ ID4gKzc1ICAgICAgICAgICAgIHdkdA0KPiA+ICs3NiAgICAgICAgICAgICBpb3BsbF9pbnQNCj4g PiArNzcgICAgICAgICAgICAgaW9wbGxfcHJlX3NyYw0KPiA+ICs3OCAgICAgICAgICAgICBpb3Bs bF9oYWxmDQo+ID4gKzc5ICAgICAgICAgICAgIGlvcGxsX2ludF9tdXgNCj4gPiArODAgICAgICAg ICAgICAgaW9wbGxfcG9zdF9zcmMNCj4gPiArODEgICAgICAgICAgICAgcnBsbF9pbnQNCj4gPiAr ODIgICAgICAgICAgICAgcnBsbF9wcmVfc3JjDQo+ID4gKzgzICAgICAgICAgICAgIHJwbGxfaGFs Zg0KPiA+ICs4NCAgICAgICAgICAgICBycGxsX2ludF9tdXgNCj4gPiArODUgICAgICAgICAgICAg cnBsbF9wb3N0X3NyYw0KPiA+ICs4NiAgICAgICAgICAgICBhcGxsX2ludA0KPiA+ICs4NyAgICAg ICAgICAgICBhcGxsX3ByZV9zcmMNCj4gPiArODggICAgICAgICAgICAgYXBsbF9oYWxmDQo+ID4g Kzg5ICAgICAgICAgICAgIGFwbGxfaW50X211eA0KPiA+ICs5MCAgICAgICAgICAgICBhcGxsX3Bv c3Rfc3JjDQo+ID4gKzkxICAgICAgICAgICAgIGRwbGxfaW50DQo+ID4gKzkyICAgICAgICAgICAg IGRwbGxfcHJlX3NyYw0KPiA+ICs5MyAgICAgICAgICAgICBkcGxsX2hhbGYNCj4gPiArOTQgICAg ICAgICAgICAgZHBsbF9pbnRfbXV4DQo+ID4gKzk1ICAgICAgICAgICAgIGRwbGxfcG9zdF9zcmMN Cj4gPiArOTYgICAgICAgICAgICAgdnBsbF9pbnQNCj4gPiArOTcgICAgICAgICAgICAgdnBsbF9w cmVfc3JjDQo+ID4gKzk4ICAgICAgICAgICAgIHZwbGxfaGFsZg0KPiA+ICs5OSAgICAgICAgICAg ICB2cGxsX2ludF9tdXgNCj4gPiArMTAwICAgICAgICAgICAgdnBsbF9wb3N0X3NyYw0KPiA+ICsx MDEgICAgICAgICAgICBjYW4wX21pbw0KPiA+ICsxMDIgICAgICAgICAgICBjYW4xX21pbw0KPiA+ ICsNCj4gPiArRXhhbXBsZToNCj4gPiArDQo+ID4gK2Nsa2M6IGNsa2NAZmY1ZTAwMjAgew0KPiA+ ICsgICAgICAgI2Nsb2NrLWNlbGxzID0gPDE+Ow0KPiA+ICsgICAgICAgY29tcGF0aWJsZSA9ICJ4 bG54LHp5bnFtcC1jbGtjIjsNCj4gPiArICAgICAgIGNsb2NrcyA9IDwmcHNzX3JlZl9jbGs+LCA8 JnZpZGVvX2Nsaz4sIDwmcHNzX2FsdF9yZWZfY2xrPiwNCj4gPCZhdXhfcmVmX2Nsaz4sIDwmZ3Rf Y3J4X3JlZl9jbGs+Ow0KPiA+ICsgICAgICAgY2xvY2stbmFtZXMgPSAicHNzX3JlZl9jbGsiLCAi dmlkZW9fY2xrIiwNCj4gInBzc19hbHRfcmVmX2NsayIsImF1eF9yZWZfY2xrIiwgImd0X2NyeF9y ZWZfY2xrIg0KPiA+ICt9Ow0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Nsay9LY29uZmlnIGIv ZHJpdmVycy9jbGsvS2NvbmZpZw0KPiA+IGluZGV4IDFjNGUxYWEuLjUyNmY0ZjUgMTAwNjQ0DQo+ ID4gLS0tIGEvZHJpdmVycy9jbGsvS2NvbmZpZw0KPiA+ICsrKyBiL2RyaXZlcnMvY2xrL0tjb25m aWcNCj4gPiBAQCAtMjM5LDYgKzIzOSw3IEBAIHNvdXJjZSAiZHJpdmVycy9jbGsvc2Ftc3VuZy9L Y29uZmlnIg0KPiA+ICBzb3VyY2UgImRyaXZlcnMvY2xrL3N1bnhpLW5nL0tjb25maWciDQo+ID4g IHNvdXJjZSAiZHJpdmVycy9jbGsvdGVncmEvS2NvbmZpZyINCj4gPiAgc291cmNlICJkcml2ZXJz L2Nsay90aS9LY29uZmlnIg0KPiA+ICtzb3VyY2UgImRyaXZlcnMvY2xrL3p5bnFtcC9LY29uZmln Ig0KPiA+ICBzb3VyY2UgImRyaXZlcnMvY2xrL3VuaXBoaWVyL0tjb25maWciDQo+ID4NCj4gPiAg ZW5kbWVudQ0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Nsay9NYWtlZmlsZSBiL2RyaXZlcnMv Y2xrL01ha2VmaWxlDQo+ID4gaW5kZXggZjdmNzYxYi4uZDczMjhiNCAxMDA2NDQNCj4gPiAtLS0g YS9kcml2ZXJzL2Nsay9NYWtlZmlsZQ0KPiA+ICsrKyBiL2RyaXZlcnMvY2xrL01ha2VmaWxlDQo+ ID4gQEAgLTk4LDMgKzk4LDQgQEAgb2JqLSQoQ09ORklHX1g4NikgICAgICAgICAgICAgICAgICAg ICArPSB4ODYvDQo+ID4gIGVuZGlmDQo+ID4gIG9iai0kKENPTkZJR19BUkNIX1pYKSAgICAgICAg ICAgICAgICAgICs9IHp0ZS8NCj4gPiAgb2JqLSQoQ09ORklHX0FSQ0hfWllOUSkgICAgICAgICAg ICAgICAgICAgICAgICArPSB6eW5xLw0KPiA+ICtvYmotJChDT05GSUdfQ09NTU9OX0NMS19aWU5R TVApICAgICAgICAgKz0genlucW1wLw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Nsay96eW5x bXAvS2NvbmZpZyBiL2RyaXZlcnMvY2xrL3p5bnFtcC9LY29uZmlnDQo+ID4gbmV3IGZpbGUgbW9k ZSAxMDA2NDQNCj4gPiBpbmRleCAwMDAwMDAwLi5hNmQ1NGU5DQo+ID4gLS0tIC9kZXYvbnVsbA0K PiA+ICsrKyBiL2RyaXZlcnMvY2xrL3p5bnFtcC9LY29uZmlnDQo+ID4gQEAgLTAsMCArMSw4IEBA DQo+ID4gK2NvbmZpZyBDT01NT05fQ0xLX1pZTlFNUA0KPiA+ICsgICAgICAgYm9vbCAiU3VwcG9y dCBmb3IgWGlsaW54IFp5bnFNUCBVbHRyYXNjYWxlKyBjbG9jayBjb250cm9sbGVycyINCj4gPiAr ICAgICAgIGRlcGVuZHMgb24gT0YNCj4gPiArICAgICAgIGRlcGVuZHMgb24gQVJDSF9aWU5RTVAg fHwgQ09NUElMRV9URVNUDQo+ID4gKyAgICAgICBoZWxwDQo+ID4gKyAgICAgICAgIFN1cHBvcnQg Zm9yIHRoZSBaeW5xbXAgVWx0cmFzY2FsZSBjbG9jayBjb250cm9sbGVyLg0KPiA+ICsgICAgICAg ICBJdCBoYXMgYSBkZXBlbmRlbmN5IG9uIHRoZSBQTVUgZmlybXdhcmUuDQo+ID4gKyAgICAgICAg IFNheSBZIGlmIHlvdSB3YW50IHRvIHN1cHBvcnQgY2xvY2sgc3VwcG9ydA0KPiA+IGRpZmYgLS1n aXQgYS9kcml2ZXJzL2Nsay96eW5xbXAvTWFrZWZpbGUgYi9kcml2ZXJzL2Nsay96eW5xbXAvTWFr ZWZpbGUNCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjdkNTBm N2ENCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9jbGsvenlucW1wL01ha2Vm aWxlDQo+ID4gQEAgLTAsMCArMSwzIEBADQo+ID4gKyMgWnlucSBVbHRyYXNjYWxlKyBNUFNvQyBj bG9jayBzcGVjaWZpYyBNYWtlZmlsZQ0KPiA+ICsNCj4gPiArb2JqLSQoQ09ORklHX0FSQ0hfWllO UU1QKSAgICAgICs9IHBsbC5vIGNsay1nYXRlLXp5bnFtcC5vIGRpdmlkZXIubyBjbGstDQo+IG11 eC16eW5xbXAubyBjbGtjLm8NCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvenlucW1wL2Ns ay1nYXRlLXp5bnFtcC5jIGIvZHJpdmVycy9jbGsvenlucW1wL2Nsay0NCj4gZ2F0ZS16eW5xbXAu Yw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMC4uNDVlZWVkOA0K PiA+IC0tLSAvZGV2L251bGwNCj4gPiArKysgYi9kcml2ZXJzL2Nsay96eW5xbXAvY2xrLWdhdGUt enlucW1wLmMNCj4gPiBAQCAtMCwwICsxLDE1OCBAQA0KPiA+ICsvKg0KPiA+ICsgKiBaeW5xIFVs dHJhU2NhbGUrIE1QU29DIGNsb2NrIGNvbnRyb2xsZXINCj4gPiArICoNCj4gPiArICogIENvcHly aWdodCAoQykgMjAxNi0yMDE3IFhpbGlueA0KPiA+ICsgKg0KPiA+ICsgKiBTUERYLUxpY2Vuc2Ut SWRlbnRpZmllcjogICAgIEdQTC0yLjArDQo+IA0KPiBUaGlzIHRhZyBzaG91bGQgYmUgb24gdGhl IGZpc3QgbGluZSB0aGlzIHdheToNCj4gLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0y LjArDQo+IA0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92aWRlci5oPg0KPiA+ ICsjaW5jbHVkZSA8bGludXgvY2xrL3p5bnFtcC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvbW9k dWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51 eC9pby5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvZXJyLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51 eC9zdHJpbmcuaD4NCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiBzdHJ1Y3QgY2xrX2dhdGUgLSBn YXRpbmcgY2xvY2sNCj4gPiArICoNCj4gPiArICogQGh3OiAgICAgICAgaGFuZGxlIGJldHdlZW4g Y29tbW9uIGFuZCBoYXJkd2FyZS1zcGVjaWZpYyBpbnRlcmZhY2VzDQo+ID4gKyAqIEBmbGFnczog ICAgIGhhcmR3YXJlLXNwZWNpZmljIGZsYWdzDQo+ID4gKyAqIEBjbGtfaWQ6ICAgIElkIG9mIGNs b2NrDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgenlucW1wX2Nsa19nYXRlIHsNCj4gPiArICAgICAg IHN0cnVjdCBjbGtfaHcgaHc7DQo+ID4gKyAgICAgICB1OCBmbGFnczsNCj4gPiArICAgICAgIHUz MiBjbGtfaWQ7DQo+ID4gK307DQo+ID4gKw0KPiA+ICsjZGVmaW5lIHRvX3p5bnFtcF9jbGtfZ2F0 ZShfaHcpIGNvbnRhaW5lcl9vZihfaHcsIHN0cnVjdA0KPiB6eW5xbXBfY2xrX2dhdGUsIGh3KQ0K PiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9jbGtfZ2F0ZV9lbmFibGUgLSBFbmFibGUg Y2xvY2sNCj4gPiArICogQGh3OiBoYW5kbGUgYmV0d2VlbiBjb21tb24gYW5kIGhhcmR3YXJlLXNw ZWNpZmljIGludGVyZmFjZXMNCj4gPiArICoNCj4gPiArICogUmV0dXJuOiAwIGFsd2F5cw0KPiA+ ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBfY2xrX2dhdGVfZW5hYmxlKHN0cnVjdCBjbGtf aHcgKmh3KQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX2Nsa19nYXRlICpnYXRl ID0gdG9fenlucW1wX2Nsa19nYXRlKGh3KTsNCj4gPiArICAgICAgIGNvbnN0IGNoYXIgKmNsa19u YW1lID0gY2xrX2h3X2dldF9uYW1lKGh3KTsNCj4gPiArICAgICAgIHUzMiBjbGtfaWQgPSBnYXRl LT5jbGtfaWQ7DQo+ID4gKyAgICAgICBpbnQgcmV0ID0gMDsNCj4gPiArICAgICAgIGNvbnN0IHN0 cnVjdCB6eW5xbXBfZWVtaV9vcHMgKmVlbWlfb3BzID0gZ2V0X2VlbWlfb3BzKCk7DQo+ID4gKw0K PiA+ICsgICAgICAgaWYgKCFlZW1pX29wcyB8fCAhZWVtaV9vcHMtPmNsb2NrX2VuYWJsZSkNCj4g PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FTlhJTzsNCj4gPiArDQo+ID4gKyAgICAgICByZXQg PSBlZW1pX29wcy0+Y2xvY2tfZW5hYmxlKGNsa19pZCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYg KHJldCkNCj4gPiArICAgICAgICAgICAgICAgcHJfd2Fybl9vbmNlKCIlcygpIGNsb2NrIGVuYWJs ZWQgZmFpbGVkIGZvciAlcywgcmV0ID0gJWRcbiIsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICBfX2Z1bmNfXywgY2xrX25hbWUsIHJldCk7DQo+ID4gKw0KPiA+ICsgICAgICAgcmV0 dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qDQo+ID4gKyAqIHp5bnFtcF9jbGtfZ2F0ZV9k aXNhYmxlIC0gRGlzYWJsZSBjbG9jaw0KPiA+ICsgKiBAaHc6IGhhbmRsZSBiZXR3ZWVuIGNvbW1v biBhbmQgaGFyZHdhcmUtc3BlY2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKi8NCj4gPiArc3RhdGlj IHZvaWQgenlucW1wX2Nsa19nYXRlX2Rpc2FibGUoc3RydWN0IGNsa19odyAqaHcpDQo+ID4gK3sN Cj4gPiArICAgICAgIHN0cnVjdCB6eW5xbXBfY2xrX2dhdGUgKmdhdGUgPSB0b196eW5xbXBfY2xr X2dhdGUoaHcpOw0KPiA+ICsgICAgICAgY29uc3QgY2hhciAqY2xrX25hbWUgPSBjbGtfaHdfZ2V0 X25hbWUoaHcpOw0KPiA+ICsgICAgICAgdTMyIGNsa19pZCA9IGdhdGUtPmNsa19pZDsNCj4gPiAr ICAgICAgIGludCByZXQgPSAwOw0KPiA+ICsgICAgICAgY29uc3Qgc3RydWN0IHp5bnFtcF9lZW1p X29wcyAqZWVtaV9vcHMgPSBnZXRfZWVtaV9vcHMoKTsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAo IWVlbWlfb3BzIHx8ICFlZW1pX29wcy0+Y2xvY2tfZGlzYWJsZSkNCj4gPiArICAgICAgICAgICAg ICAgcmV0dXJuOw0KPiA+ICsNCj4gPiArICAgICAgIHJldCA9IGVlbWlfb3BzLT5jbG9ja19kaXNh YmxlKGNsa19pZCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKHJldCkNCj4gPiArICAgICAgICAg ICAgICAgcHJfd2Fybl9vbmNlKCIlcygpIGNsb2NrIGRpc2FibGUgZmFpbGVkIGZvciAlcywgcmV0 ID0gJWRcbiIsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgY2xr X25hbWUsIHJldCk7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiB6eW5xbXBfY2xr X2dhdGVfaXNfZW5hYmxlIC0gQ2hlY2sgY2xvY2sgc3RhdGUNCj4gPiArICogQGh3OiBoYW5kbGUg YmV0d2VlbiBjb21tb24gYW5kIGhhcmR3YXJlLXNwZWNpZmljIGludGVyZmFjZXMNCj4gPiArICoN Cj4gPiArICogUmV0dXJuOiAxIGlmIGVuYWJsZWQNCj4gPiArICogICAgICAgICAwIGlmIGRpc2Fi bGVkDQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgaW50IHp5bnFtcF9jbGtfZ2F0ZV9pc19lbmFibGVk KHN0cnVjdCBjbGtfaHcgKmh3KQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX2Ns a19nYXRlICpnYXRlID0gdG9fenlucW1wX2Nsa19nYXRlKGh3KTsNCj4gPiArICAgICAgIGNvbnN0 IGNoYXIgKmNsa19uYW1lID0gY2xrX2h3X2dldF9uYW1lKGh3KTsNCj4gPiArICAgICAgIHUzMiBj bGtfaWQgPSBnYXRlLT5jbGtfaWQ7DQo+ID4gKyAgICAgICBpbnQgc3RhdGUsIHJldDsNCj4gPiAr ICAgICAgIGNvbnN0IHN0cnVjdCB6eW5xbXBfZWVtaV9vcHMgKmVlbWlfb3BzID0gZ2V0X2VlbWlf b3BzKCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKCFlZW1pX29wcyB8fCAhZWVtaV9vcHMtPmNs b2NrX2dldHN0YXRlKQ0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsNCj4gPiArDQo+ID4g KyAgICAgICByZXQgPSBlZW1pX29wcy0+Y2xvY2tfZ2V0c3RhdGUoY2xrX2lkLCAmc3RhdGUpOw0K PiA+ICsgICAgICAgaWYgKHJldCkNCj4gPiArICAgICAgICAgICAgICAgcHJfd2Fybl9vbmNlKCIl cygpIGNsb2NrIGdldCBzdGF0ZSBmYWlsZWQgZm9yICVzLCByZXQgPSAlZFxuIiwNCj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBjbGtfbmFtZSwgcmV0KTsNCj4gPiAr DQo+ID4gKyAgICAgICByZXR1cm4gc3RhdGUgPyAxIDogMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiAr Y29uc3Qgc3RydWN0IGNsa19vcHMgenlucW1wX2Nsa19nYXRlX29wcyA9IHsNCj4gPiArICAgICAg IC5lbmFibGUgPSB6eW5xbXBfY2xrX2dhdGVfZW5hYmxlLA0KPiA+ICsgICAgICAgLmRpc2FibGUg PSB6eW5xbXBfY2xrX2dhdGVfZGlzYWJsZSwNCj4gPiArICAgICAgIC5pc19lbmFibGVkID0genlu cW1wX2Nsa19nYXRlX2lzX2VuYWJsZWQsDQo+ID4gK307DQo+ID4gK0VYUE9SVF9TWU1CT0xfR1BM KHp5bnFtcF9jbGtfZ2F0ZV9vcHMpOw0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9j bGtfcmVnaXN0ZXJfZ2F0ZSAtIHJlZ2lzdGVyIGEgZ2F0ZSBjbG9jayB3aXRoIHRoZSBjbG9jayBm cmFtZXdvcmsNCj4gPiArICogQGRldjogZGV2aWNlIHRoYXQgaXMgcmVnaXN0ZXJpbmcgdGhpcyBj bG9jaw0KPiA+ICsgKiBAbmFtZTogbmFtZSBvZiB0aGlzIGNsb2NrDQo+ID4gKyAqIEBjbGtfaWQ6 IElkIG9mIHRoaXMgY2xvY2sNCj4gPiArICogQHBhcmVudHM6IG5hbWUgb2YgdGhpcyBjbG9jaydz IHBhcmVudHMNCj4gPiArICogQG51bV9wYXJlbnRzOiBudW1iZXIgb2YgcGFyZW50cw0KPiA+ICsg KiBAZmxhZ3M6IGZyYW1ld29yay1zcGVjaWZpYyBmbGFncyBmb3IgdGhpcyBjbG9jaw0KPiA+ICsg KiBAY2xrX2dhdGVfZmxhZ3M6IGdhdGUtc3BlY2lmaWMgZmxhZ3MgZm9yIHRoaXMgY2xvY2sNCj4g PiArICoNCj4gPiArICogUmV0dXJuOiBjbG9jayBoYW5kbGUgb2YgdGhlIHJlZ2lzdGVyZWQgY2xv Y2sgZ2F0ZQ0KPiA+ICsgKi8NCj4gPiArc3RydWN0IGNsayAqenlucW1wX2Nsa19yZWdpc3Rlcl9n YXRlKHN0cnVjdCBkZXZpY2UgKmRldiwgY29uc3QgY2hhciAqbmFtZSwNCj4gPiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgdTMyIGNsa19pZCwgY29uc3QgY2hhciAqIGNvbnN0 ICpwYXJlbnRzLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1OCBu dW1fcGFyZW50cywgdW5zaWduZWQgbG9uZyBmbGFncywNCj4gPiArICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgdTggY2xrX2dhdGVfZmxhZ3MpDQo+ID4gK3sNCj4gPiArICAgICAg IHN0cnVjdCB6eW5xbXBfY2xrX2dhdGUgKmdhdGU7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xrICpj bGs7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0Ow0KPiA+ICsNCj4gPiAr ICAgICAgIC8qIGFsbG9jYXRlIHRoZSBnYXRlICovDQo+ID4gKyAgICAgICBnYXRlID0ga3phbGxv YyhzaXplb2YoKmdhdGUpLCBHRlBfS0VSTkVMKTsNCj4gPiArICAgICAgIGlmICghZ2F0ZSkNCj4g PiArICAgICAgICAgICAgICAgcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7DQo+ID4gKw0KPiA+ICsg ICAgICAgaW5pdC5uYW1lID0gbmFtZTsNCj4gPiArICAgICAgIGluaXQub3BzID0gJnp5bnFtcF9j bGtfZ2F0ZV9vcHM7DQo+ID4gKyAgICAgICBpbml0LmZsYWdzID0gZmxhZ3M7DQo+ID4gKyAgICAg ICBpbml0LnBhcmVudF9uYW1lcyA9IHBhcmVudHM7DQo+ID4gKyAgICAgICBpbml0Lm51bV9wYXJl bnRzID0gbnVtX3BhcmVudHM7DQo+ID4gKw0KPiA+ICsgICAgICAgLyogc3RydWN0IGNsa19nYXRl IGFzc2lnbm1lbnRzICovDQo+ID4gKyAgICAgICBnYXRlLT5mbGFncyA9IGNsa19nYXRlX2ZsYWdz Ow0KPiA+ICsgICAgICAgZ2F0ZS0+aHcuaW5pdCA9ICZpbml0Ow0KPiA+ICsgICAgICAgZ2F0ZS0+ Y2xrX2lkID0gY2xrX2lkOw0KPiA+ICsNCj4gPiArICAgICAgIGNsayA9IGNsa19yZWdpc3Rlcihk ZXYsICZnYXRlLT5odyk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKElTX0VSUihjbGspKQ0KPiA+ ICsgICAgICAgICAgICAgICBrZnJlZShnYXRlKTsNCj4gPiArDQo+ID4gKyAgICAgICByZXR1cm4g Y2xrOw0KPiA+ICt9DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY2xrL3p5bnFtcC9jbGstbXV4 LXp5bnFtcC5jIGIvZHJpdmVycy9jbGsvenlucW1wL2Nsay0NCj4gbXV4LXp5bnFtcC5jDQo+ID4g bmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gPiBpbmRleCAwMDAwMDAwLi5lZTM2MjQ0DQo+ID4gLS0t IC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZlcnMvY2xrL3p5bnFtcC9jbGstbXV4LXp5bnFtcC5j DQo+ID4gQEAgLTAsMCArMSwxOTAgQEANCj4gPiArLyoNCj4gPiArICogWnlucSBVbHRyYVNjYWxl KyBNUFNvQyBtdXgNCj4gPiArICoNCj4gPiArICogIENvcHlyaWdodCAoQykgMjAxNi0yMDE3IFhp bGlueA0KPiA+ICsgKg0KPiA+ICsgKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogICAgIEdQTC0y LjArDQo+IA0KPiBUaGlzIHRhZyBzaG91bGQgYmUgb24gdGhlIGZpc3QgbGluZSB0aGlzIHdheToN Cj4gLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjArDQo+IA0KPiA+ICsgKi8NCj4g PiArDQo+ID4gKyNpbmNsdWRlIDxsaW51eC9jbGstcHJvdmlkZXIuaD4NCj4gPiArI2luY2x1ZGUg PGxpbnV4L2Nsay96eW5xbXAuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiA+ ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaW8uaD4NCj4g PiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPg0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogRE9DOiBi YXNpYyBhZGp1c3RhYmxlIG11bHRpcGxleGVyIGNsb2NrIHRoYXQgY2Fubm90IGdhdGUNCj4gPiAr ICoNCj4gPiArICogVHJhaXRzIG9mIHRoaXMgY2xvY2s6DQo+ID4gKyAqIHByZXBhcmUgLSBjbGtf cHJlcGFyZSBvbmx5IGVuc3VyZXMgdGhhdCBwYXJlbnRzIGFyZSBwcmVwYXJlZA0KPiA+ICsgKiBl bmFibGUgLSBjbGtfZW5hYmxlIG9ubHkgZW5zdXJlcyB0aGF0IHBhcmVudHMgYXJlIGVuYWJsZWQN Cj4gPiArICogcmF0ZSAtIHJhdGUgaXMgb25seSBhZmZlY3RlZCBieSBwYXJlbnQgc3dpdGNoaW5n LiAgTm8gY2xrX3NldF9yYXRlIHN1cHBvcnQNCj4gPiArICogcGFyZW50IC0gcGFyZW50IGlzIGFk anVzdGFibGUgdGhyb3VnaCBjbGtfc2V0X3BhcmVudA0KPiA+ICsgKi8NCj4gPiArDQo+ID4gKy8q Kg0KPiA+ICsgKiBzdHJ1Y3QgenlucW1wX2Nsa19tdXggLSBtdWx0aXBsZXhlciBjbG9jaw0KPiA+ ICsgKg0KPiA+ICsgKiBAaHc6IGhhbmRsZSBiZXR3ZWVuIGNvbW1vbiBhbmQgaGFyZHdhcmUtc3Bl Y2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKiBAZmxhZ3M6IGhhcmR3YXJlLXNwZWNpZmljIGZsYWdz DQo+ID4gKyAqIEBjbGtfaWQ6IElkIG9mIGNsb2NrDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3Qgenlu cW1wX2Nsa19tdXggew0KPiA+ICsgICAgICAgc3RydWN0IGNsa19odyBodzsNCj4gPiArICAgICAg IHU4IGZsYWdzOw0KPiA+ICsgICAgICAgdTMyIGNsa19pZDsNCj4gPiArfTsNCj4gPiArDQo+ID4g KyNkZWZpbmUgdG9fenlucW1wX2Nsa19tdXgoX2h3KSBjb250YWluZXJfb2YoX2h3LCBzdHJ1Y3QN Cj4genlucW1wX2Nsa19tdXgsIGh3KQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9j bGtfbXV4X2dldF9wYXJlbnQgLSBHZXQgcGFyZW50IG9mIGNsb2NrDQo+ID4gKyAqIEBodzogaGFu ZGxlIGJldHdlZW4gY29tbW9uIGFuZCBoYXJkd2FyZS1zcGVjaWZpYyBpbnRlcmZhY2VzDQo+ID4g KyAqDQo+ID4gKyAqIFJldHVybjogUGFyZW50IGluZGV4DQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMg dTggenlucW1wX2Nsa19tdXhfZ2V0X3BhcmVudChzdHJ1Y3QgY2xrX2h3ICpodykNCj4gPiArew0K PiA+ICsgICAgICAgc3RydWN0IHp5bnFtcF9jbGtfbXV4ICptdXggPSB0b196eW5xbXBfY2xrX211 eChodyk7DQo+ID4gKyAgICAgICBjb25zdCBjaGFyICpjbGtfbmFtZSA9IGNsa19od19nZXRfbmFt ZShodyk7DQo+ID4gKyAgICAgICB1MzIgY2xrX2lkID0gbXV4LT5jbGtfaWQ7DQo+ID4gKyAgICAg ICB1MzIgdmFsOw0KPiA+ICsgICAgICAgaW50IHJldDsNCj4gPiArICAgICAgIGNvbnN0IHN0cnVj dCB6eW5xbXBfZWVtaV9vcHMgKmVlbWlfb3BzID0gZ2V0X2VlbWlfb3BzKCk7DQo+ID4gKw0KPiA+ ICsgICAgICAgaWYgKCFlZW1pX29wcyB8fCAhZWVtaV9vcHMtPmNsb2NrX2dldHBhcmVudCkNCj4g PiArICAgICAgICAgICAgICAgcmV0dXJuIC1FTlhJTzsNCj4gPiArDQo+ID4gKyAgICAgICByZXQg PSBlZW1pX29wcy0+Y2xvY2tfZ2V0cGFyZW50KGNsa19pZCwgJnZhbCk7DQo+ID4gKw0KPiA+ICsg ICAgICAgaWYgKHJldCkNCj4gPiArICAgICAgICAgICAgICAgcHJfd2Fybl9vbmNlKCIlcygpIGdl dHBhcmVudCBmYWlsZWQgZm9yIGNsb2NrOiAlcywgcmV0ID0gJWRcbiIsDQo+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgY2xrX25hbWUsIHJldCk7DQo+ID4gKw0KPiA+ ICsgICAgICAgaWYgKHZhbCAmJiAobXV4LT5mbGFncyAmIENMS19NVVhfSU5ERVhfQklUKSkNCj4g PiArICAgICAgICAgICAgICAgdmFsID0gZmZzKHZhbCkgLSAxOw0KPiA+ICsNCj4gPiArICAgICAg IGlmICh2YWwgJiYgKG11eC0+ZmxhZ3MgJiBDTEtfTVVYX0lOREVYX09ORSkpDQo+ID4gKyAgICAg ICAgICAgICAgIHZhbC0tOw0KPiA+ICsNCj4gPiArICAgICAgIHJldHVybiB2YWw7DQo+ID4gK30N Cj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiB6eW5xbXBfY2xrX211eF9zZXRfcGFyZW50IC0gU2V0 IHBhcmVudCBvZiBjbG9jaw0KPiA+ICsgKiBAaHc6IGhhbmRsZSBiZXR3ZWVuIGNvbW1vbiBhbmQg aGFyZHdhcmUtc3BlY2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKiBAaW5kZXg6IFBhcmVudCBpbmRl eA0KPiA+ICsgKg0KPiA+ICsgKiBSZXR1cm46IDAgYWx3YXlzDQo+ID4gKyAqLw0KPiA+ICtzdGF0 aWMgaW50IHp5bnFtcF9jbGtfbXV4X3NldF9wYXJlbnQoc3RydWN0IGNsa19odyAqaHcsIHU4IGlu ZGV4KQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX2Nsa19tdXggKm11eCA9IHRv X3p5bnFtcF9jbGtfbXV4KGh3KTsNCj4gPiArICAgICAgIGNvbnN0IGNoYXIgKmNsa19uYW1lID0g Y2xrX2h3X2dldF9uYW1lKGh3KTsNCj4gPiArICAgICAgIHUzMiBjbGtfaWQgPSBtdXgtPmNsa19p ZDsNCj4gPiArICAgICAgIGludCByZXQ7DQo+ID4gKyAgICAgICBjb25zdCBzdHJ1Y3QgenlucW1w X2VlbWlfb3BzICplZW1pX29wcyA9IGdldF9lZW1pX29wcygpOw0KPiA+ICsNCj4gPiArICAgICAg IGlmICghZWVtaV9vcHMgfHwgIWVlbWlfb3BzLT5jbG9ja19zZXRwYXJlbnQpDQo+ID4gKyAgICAg ICAgICAgICAgIHJldHVybiAtRU5YSU87DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKG11eC0+Zmxh Z3MgJiBDTEtfTVVYX0lOREVYX0JJVCkNCj4gPiArICAgICAgICAgICAgICAgaW5kZXggPSAxIDw8 IGluZGV4Ow0KPiA+ICsNCj4gPiArICAgICAgIGlmIChtdXgtPmZsYWdzICYgQ0xLX01VWF9JTkRF WF9PTkUpDQo+ID4gKyAgICAgICAgICAgICAgIGluZGV4Kys7DQo+ID4gKw0KPiA+ICsgICAgICAg cmV0ID0gZWVtaV9vcHMtPmNsb2NrX3NldHBhcmVudChjbGtfaWQsIGluZGV4KTsNCj4gPiArDQo+ ID4gKyAgICAgICBpZiAocmV0KQ0KPiA+ICsgICAgICAgICAgICAgICBwcl93YXJuX29uY2UoIiVz KCkgc2V0IHBhcmVudCBmYWlsZWQgZm9yIGNsb2NrOiAlcywgcmV0ID0gJWRcbiIsDQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgY2xrX25hbWUsIHJldCk7DQo+ID4g Kw0KPiA+ICsgICAgICAgcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK2NvbnN0IHN0cnVj dCBjbGtfb3BzIHp5bnFtcF9jbGtfbXV4X29wcyA9IHsNCj4gPiArICAgICAgIC5nZXRfcGFyZW50 ID0genlucW1wX2Nsa19tdXhfZ2V0X3BhcmVudCwNCj4gPiArICAgICAgIC5zZXRfcGFyZW50ID0g enlucW1wX2Nsa19tdXhfc2V0X3BhcmVudCwNCj4gPiArICAgICAgIC5kZXRlcm1pbmVfcmF0ZSA9 IF9fY2xrX211eF9kZXRlcm1pbmVfcmF0ZSwNCj4gPiArfTsNCj4gPiArRVhQT1JUX1NZTUJPTF9H UEwoenlucW1wX2Nsa19tdXhfb3BzKTsNCj4gPiArDQo+ID4gK2NvbnN0IHN0cnVjdCBjbGtfb3Bz IHp5bnFtcF9jbGtfbXV4X3JvX29wcyA9IHsNCj4gPiArICAgICAgIC5nZXRfcGFyZW50ID0genlu cW1wX2Nsa19tdXhfZ2V0X3BhcmVudCwNCj4gPiArfTsNCj4gPiArRVhQT1JUX1NZTUJPTF9HUEwo enlucW1wX2Nsa19tdXhfcm9fb3BzKTsNCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiB6eW5xbXBf Y2xrX3JlZ2lzdGVyX211eF90YWJsZSAtIHJlZ2lzdGVyIGEgbXV4IHRhYmxlIHdpdGggdGhlIGNs b2NrDQo+IGZyYW1ld29yaw0KPiA+ICsgKiBAZGV2OiBkZXZpY2UgdGhhdCBpcyByZWdpc3Rlcmlu ZyB0aGlzIGNsb2NrDQo+ID4gKyAqIEBuYW1lOiBuYW1lIG9mIHRoaXMgY2xvY2sNCj4gPiArICog QGNsa19pZDogSWQgb2YgdGhpcyBjbG9jaw0KPiA+ICsgKiBAcGFyZW50X25hbWVzOiBuYW1lIG9m IHRoaXMgY2xvY2sncyBwYXJlbnRzDQo+ID4gKyAqIEBudW1fcGFyZW50czogbnVtYmVyIG9mIHBh cmVudHMNCj4gPiArICogQGZsYWdzOiBmcmFtZXdvcmstc3BlY2lmaWMgZmxhZ3MgZm9yIHRoaXMg Y2xvY2sNCj4gPiArICogQGNsa19tdXhfZmxhZ3M6IG11eC1zcGVjaWZpYyBmbGFncyBmb3IgdGhp cyBjbG9jaw0KPiA+ICsgKg0KPiA+ICsgKiBSZXR1cm46IGNsb2NrIGhhbmRsZSBvZiB0aGUgcmVn aXN0ZXJlZCBjbG9jayBtdXgNCj4gPiArICovDQo+ID4gK3N0cnVjdCBjbGsgKnp5bnFtcF9jbGtf cmVnaXN0ZXJfbXV4X3RhYmxlKHN0cnVjdCBkZXZpY2UgKmRldiwgY29uc3QgY2hhcg0KPiAqbmFt ZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1MzIgY2xr X2lkLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0 IGNoYXIgKiBjb25zdCAqcGFyZW50X25hbWVzLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIHU4IG51bV9wYXJlbnRzLA0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3MsDQo+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTggY2xrX211eF9mbGFncykNCj4g PiArew0KPiA+ICsgICAgICAgc3RydWN0IHp5bnFtcF9jbGtfbXV4ICptdXg7DQo+ID4gKyAgICAg ICBzdHJ1Y3QgY2xrICpjbGs7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0 Ow0KPiA+ICsNCj4gPiArICAgICAgIC8qIGFsbG9jYXRlIHRoZSBtdXggKi8NCj4gPiArICAgICAg IG11eCA9IGt6YWxsb2Moc2l6ZW9mKCptdXgpLCBHRlBfS0VSTkVMKTsNCj4gPiArICAgICAgIGlm ICghbXV4KQ0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsNCj4g PiArDQo+ID4gKyAgICAgICBpbml0Lm5hbWUgPSBuYW1lOw0KPiA+ICsgICAgICAgaWYgKGNsa19t dXhfZmxhZ3MgJiBDTEtfTVVYX1JFQURfT05MWSkNCj4gPiArICAgICAgICAgICAgICAgaW5pdC5v cHMgPSAmenlucW1wX2Nsa19tdXhfcm9fb3BzOw0KPiA+ICsgICAgICAgZWxzZQ0KPiA+ICsgICAg ICAgICAgICAgICBpbml0Lm9wcyA9ICZ6eW5xbXBfY2xrX211eF9vcHM7DQo+ID4gKyAgICAgICBp bml0LmZsYWdzID0gZmxhZ3M7DQo+ID4gKyAgICAgICBpbml0LnBhcmVudF9uYW1lcyA9IHBhcmVu dF9uYW1lczsNCj4gPiArICAgICAgIGluaXQubnVtX3BhcmVudHMgPSBudW1fcGFyZW50czsNCj4g PiArDQo+ID4gKyAgICAgICAvKiBzdHJ1Y3QgY2xrX211eCBhc3NpZ25tZW50cyAqLw0KPiA+ICsg ICAgICAgbXV4LT5mbGFncyA9IGNsa19tdXhfZmxhZ3M7DQo+ID4gKyAgICAgICBtdXgtPmh3Lmlu aXQgPSAmaW5pdDsNCj4gPiArICAgICAgIG11eC0+Y2xrX2lkID0gY2xrX2lkOw0KPiA+ICsNCj4g PiArICAgICAgIGNsayA9IGNsa19yZWdpc3RlcihkZXYsICZtdXgtPmh3KTsNCj4gPiArDQo+ID4g KyAgICAgICBpZiAoSVNfRVJSKGNsaykpDQo+ID4gKyAgICAgICAgICAgICAgIGtmcmVlKG11eCk7 DQo+ID4gKw0KPiA+ICsgICAgICAgcmV0dXJuIGNsazsNCj4gPiArfQ0KPiA+ICtFWFBPUlRfU1lN Qk9MX0dQTCh6eW5xbXBfY2xrX3JlZ2lzdGVyX211eF90YWJsZSk7DQo+ID4gKw0KPiA+ICsvKioN Cj4gPiArICogenlucW1wX2Nsa19yZWdpc3Rlcl9tdXggLSByZWdpc3RlciBhIG11eCBjbG9jayB3 aXRoIHRoZSBjbG9jayBmcmFtZXdvcmsNCj4gPiArICogQGRldjogZGV2aWNlIHRoYXQgaXMgcmVn aXN0ZXJpbmcgdGhpcyBjbG9jaw0KPiA+ICsgKiBAbmFtZTogbmFtZSBvZiB0aGlzIGNsb2NrDQo+ ID4gKyAqIEBjbGtfaWQ6IElkIG9mIHRoaXMgY2xvY2sNCj4gPiArICogQHBhcmVudF9uYW1lczog bmFtZSBvZiB0aGlzIGNsb2NrJ3MgcGFyZW50cw0KPiA+ICsgKiBAbnVtX3BhcmVudHM6IG51bWJl ciBvZiBwYXJlbnRzDQo+ID4gKyAqIEBmbGFnczogZnJhbWV3b3JrLXNwZWNpZmljIGZsYWdzIGZv ciB0aGlzIGNsb2NrDQo+ID4gKyAqIEBjbGtfbXV4X2ZsYWdzOiBtdXgtc3BlY2lmaWMgZmxhZ3Mg Zm9yIHRoaXMgY2xvY2sNCj4gPiArICoNCj4gPiArICogUmV0dXJuOiBjbG9jayBoYW5kbGUgb2Yg dGhlIHJlZ2lzdGVyZWQgY2xvY2sgbXV4DQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgY2xrICp6eW5x bXBfY2xrX3JlZ2lzdGVyX211eChzdHJ1Y3QgZGV2aWNlICpkZXYsIGNvbnN0IGNoYXIgKm5hbWUs DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTMyIGNsa19pZCwgY29u c3QgY2hhciAqKnBhcmVudF9uYW1lcywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICB1OCBudW1fcGFyZW50cywgdW5zaWduZWQgbG9uZyBmbGFncywNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1OCBjbGtfbXV4X2ZsYWdzKQ0KPiA+ICt7DQo+ ID4gKyAgICAgICByZXR1cm4genlucW1wX2Nsa19yZWdpc3Rlcl9tdXhfdGFibGUoZGV2LCBuYW1l LCBjbGtfaWQsIHBhcmVudF9uYW1lcywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBudW1fcGFyZW50cywgZmxhZ3MsIGNsa19tdXhfZmxhZ3MpOw0KPiA+ ICt9DQo+ID4gK0VYUE9SVF9TWU1CT0xfR1BMKHp5bnFtcF9jbGtfcmVnaXN0ZXJfbXV4KTsNCj4g PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvenlucW1wL2Nsa2MuYyBiL2RyaXZlcnMvY2xrL3p5 bnFtcC9jbGtjLmMNCj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAu LjM2YmYxYzENCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9jbGsvenlucW1w L2Nsa2MuYw0KPiA+IEBAIC0wLDAgKzEsNzA3IEBADQo+ID4gKy8qDQo+ID4gKyAqIFp5bnEgVWx0 cmFTY2FsZSsgTVBTb0MgY2xvY2sgY29udHJvbGxlcg0KPiA+ICsgKg0KPiA+ICsgKiAgQ29weXJp Z2h0IChDKSAyMDE2LTIwMTcgWGlsaW54DQo+ID4gKyAqDQo+ID4gKyAqIFNQRFgtTGljZW5zZS1J ZGVudGlmaWVyOiAgICAgR1BMLTIuMCsNCj4gDQo+IFRoaXMgdGFnIHNob3VsZCBiZSBvbiB0aGUg ZmlzdCBsaW5lIHRoaXMgd2F5Og0KPiAvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIu MCsNCj4gDQo+ID4gKyAqDQo+ID4gKyAqIEJhc2VkIG9uIGRyaXZlcnMvY2xrL3p5bnEvY2xrYy5j DQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPg0KPiA+ICsjaW5j bHVkZSA8bGludXgvY2xrLXByb3ZpZGVyLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9jbGsvenlu cW1wLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9pby5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgv b2YuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L29mX2FkZHJlc3MuaD4NCj4gPiArI2luY2x1ZGUg PGxpbnV4L3NsYWIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPg0KPiA+ICsNCj4g PiArI2RlZmluZSBNQVhfUEFSRU5UICAgICAgICAgICAgICAgICAgICAgMTAwDQo+ID4gKyNkZWZp bmUgTUFYX05PREVTICAgICAgICAgICAgICAgICAgICAgIDYNCj4gPiArI2RlZmluZSBNQVhfTkFN RV9MRU4gICAgICAgICAgICAgICAgICAgNTANCj4gPiArI2RlZmluZSBNQVhfQ0xPQ0sgICAgICAg ICAgICAgICAgICAgICAgMzAwDQo+ID4gKw0KPiA+ICsjZGVmaW5lIENMS19JTklUX0VOQUJMRV9T SElGVCAgICAgICAgICAgMQ0KPiA+ICsjZGVmaW5lIENMS19UWVBFX1NISUZUICAgICAgICAgICAg ICAgICAgMg0KPiA+ICsNCj4gPiArI2RlZmluZSBQTV9BUElfUEFZTE9BRF9MRU4gICAgICAgICAg ICAgMw0KPiA+ICsNCj4gPiArI2RlZmluZSBOQV9QQVJFTlQgICAgICAgICAgICAgICAgICAgICAg LTENCj4gPiArI2RlZmluZSBEVU1NWV9QQVJFTlQgICAgICAgICAgICAgICAgICAgLTINCj4gPiAr DQo+ID4gKyNkZWZpbmUgQ0xLX1RZUEVfRklFTERfTEVOICAgICAgICAgICAgIDQNCj4gPiArI2Rl ZmluZSBDTEtfVE9QT0xPR1lfTk9ERV9PRkZTRVQgICAgICAgMTYNCj4gPiArI2RlZmluZSBOT0RF U19QRVJfUkVTUCAgICAgICAgICAgICAgICAgMw0KPiA+ICsNCj4gPiArI2RlZmluZSBDTEtfVFlQ RV9GSUVMRF9NQVNLICAgICAgICAgICAgMHhGDQo+ID4gKyNkZWZpbmUgQ0xLX0ZMQUdfRklFTERf U0hJRlQgICAgICAgICAgIDgNCj4gPiArI2RlZmluZSBDTEtfRkxBR19GSUVMRF9NQVNLICAgICAg ICAgICAgMHgzRkZGDQo+ID4gKyNkZWZpbmUgQ0xLX1RZUEVfRkxBR19GSUVMRF9TSElGVCAgICAg IDI0DQo+ID4gKyNkZWZpbmUgQ0xLX1RZUEVfRkxBR19GSUVMRF9NQVNLICAgICAgIDB4RkYNCj4g PiArDQo+ID4gKyNkZWZpbmUgQ0xLX1BBUkVOVFNfSURfTEVOICAgICAgICAgICAgICAxNg0KPiA+ ICsjZGVmaW5lIENMS19QQVJFTlRTX0lEX01BU0sgICAgICAgICAgICAweEZGRkYNCj4gPiArDQo+ ID4gKy8qIEZsYWdzIGZvciBwYXJlbnRzICovDQo+ID4gKyNkZWZpbmUgUEFSRU5UX0NMS19TRUxG ICAgICAgICAgICAgICAgICAgICAgICAgMA0KPiA+ICsjZGVmaW5lIFBBUkVOVF9DTEtfTk9ERTEg ICAgICAgICAgICAgICAxDQo+ID4gKyNkZWZpbmUgUEFSRU5UX0NMS19OT0RFMiAgICAgICAgICAg ICAgIDINCj4gPiArI2RlZmluZSBQQVJFTlRfQ0xLX05PREUzICAgICAgICAgICAgICAgMw0KPiA+ ICsjZGVmaW5lIFBBUkVOVF9DTEtfTk9ERTQgICAgICAgICAgICAgICA0DQo+ID4gKyNkZWZpbmUg UEFSRU5UX0NMS19FWFRFUk5BTCAgICAgICAgICAgIDUNCj4gPiArDQo+ID4gKyNkZWZpbmUgRU5E X09GX0NMS19OQU1FICAgICAgICAgICAgICAgICAgICAgICAgIkVORF9PRl9DTEsiDQo+ID4gKyNk ZWZpbmUgUkVTRVJWRURfQ0xLX05BTUUgICAgICAgICAgICAgICIiDQo+ID4gKw0KPiA+ICsjZGVm aW5lIENMS19WQUxJRF9NQVNLICAgICAgICAgICAgICAgICAweDENCj4gPiArI2RlZmluZSBDTEtf SU5JVF9FTkFCTEVfTUFTSyAgICAgICAgICAgKDB4MSA8PCBDTEtfSU5JVF9FTkFCTEVfU0hJRlQp DQo+ID4gKw0KPiA+ICtlbnVtIGNsa190eXBlIHsNCj4gPiArICAgICAgIENMS19UWVBFX09VVFBV VCwNCj4gPiArICAgICAgIENMS19UWVBFX0VYVEVSTkFMLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAr LyoqDQo+ID4gKyAqIHN0cnVjdCBjbG9ja19wYXJlbnQgLSBTdHJ1Y3R1cmUgZm9yIHBhcmVudCBv ZiBjbG9jaw0KPiA+ICsgKiBAaWQ6ICAgICAgICBQYXJlbnQgY2xvY2sgSUQNCj4gPiArICogQGZs YWc6IFBhcmVudCBmbGFncw0KPiA+ICsgKi8NCj4gPiArc3RydWN0IGNsb2NrX3BhcmVudCB7DQo+ ID4gKyAgICAgICBjaGFyIG5hbWVbTUFYX05BTUVfTEVOXTsNCj4gPiArICAgICAgIGludCBpZDsN Cj4gPiArICAgICAgIHUzMiBmbGFnOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAq IHN0cnVjdCBjbG9ja190b3BvbG9neSAtIFN0cnVjdHVyZSBmb3IgdG9wb2xvZ3kgb2YgY2xvY2sN Cj4gPiArICogQHR5cGU6IFR5cGUgb2YgdG9wb2xvZ3kNCj4gPiArICogQGZsYWc6IFRvcG9sb2d5 IGZsYWdzDQo+ID4gKyAqIEB0eXBlX2ZsYWc6IFRvcG9sb2d5IHR5cGUgc3BlY2lmaWMgZmxhZw0K PiA+ICsgKi8NCj4gPiArc3RydWN0IGNsb2NrX3RvcG9sb2d5IHsNCj4gPiArICAgICAgIHUzMiB0 eXBlOw0KPiA+ICsgICAgICAgdTMyIGZsYWc7DQo+ID4gKyAgICAgICB1MzIgdHlwZV9mbGFnOw0K PiA+ICt9Ow0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHN0cnVjdCB6eW5xbXBfY2xvY2sgLSBT dHJ1Y3R1cmUgZm9yIGNsb2NrDQo+ID4gKyAqIEBjbGtfbmFtZTogQ2xvY2sgbmFtZQ0KPiA+ICsg KiBAdmFsaWQ6IFZhbGlkaXR5IGZsYWcgb2YgY2xvY2sNCj4gPiArICogQGluaXRfZW5hYmxlOiBp bml0X2VuYWJsZSBmbGFnIG9mIGNsb2NrDQo+ID4gKyAqIEB0b3BvbG9neTogc3RydWN0dXJlIG9m IHRvcG9sb2d5IG9mIGNsb2NrDQo+ID4gKyAqIEBudW1fbm9kZTogTnVtYmVyIG9mIG5vZGVzIHBy ZXNlbnQgaW4gdG9wb2xvZ3kNCj4gPiArICogQHBhcmVudDogc3RydWN0dXJlIG9mIHBhcmVudCBv ZiBjbG9jaw0KPiA+ICsgKiBAbnVtX3BhcmVudHM6IE51bWJlciBvZiBwYXJlbnRzIG9mIGNsb2Nr DQo+ID4gKyAqIEB0eXBlOiBUeXBlIG9mIGNsb2NrDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3Qgenlu cW1wX2Nsb2NrIHsNCj4gPiArICAgICAgIGNoYXIgY2xrX25hbWVbTUFYX05BTUVfTEVOXTsNCj4g PiArICAgICAgIHUzMiB2YWxpZDsNCj4gPiArICAgICAgIHUzMiBpbml0X2VuYWJsZTsNCj4gPiAr ICAgICAgIGVudW0gY2xrX3R5cGUgdHlwZTsNCj4gPiArICAgICAgIHN0cnVjdCBjbG9ja190b3Bv bG9neSBub2RlW01BWF9OT0RFU107DQo+ID4gKyAgICAgICB1MzIgbnVtX25vZGVzOw0KPiA+ICsg ICAgICAgc3RydWN0IGNsb2NrX3BhcmVudCBwYXJlbnRbTUFYX1BBUkVOVF07DQo+ID4gKyAgICAg ICB1MzIgbnVtX3BhcmVudHM7DQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3QgY2hh ciBjbGtfdHlwZV9wb3N0Zml4W11bMTBdID0gew0KPiA+ICsgICAgICAgW1RZUEVfSU5WQUxJRF0g PSAiIiwNCj4gPiArICAgICAgIFtUWVBFX01VWF0gPSAiX211eCIsDQo+ID4gKyAgICAgICBbVFlQ RV9HQVRFXSA9ICIiLA0KPiA+ICsgICAgICAgW1RZUEVfRElWMV0gPSAiX2RpdjEiLA0KPiA+ICsg ICAgICAgW1RZUEVfRElWMl0gPSAiX2RpdjIiLA0KPiA+ICsgICAgICAgW1RZUEVfRklYRURGQUNU T1JdID0gIl9mZiIsDQo+ID4gKyAgICAgICBbVFlQRV9QTExdID0gIiINCj4gPiArfTsNCj4gPiAr DQo+ID4gK3N0YXRpYyBzdHJ1Y3QgenlucW1wX2Nsb2NrIGNsb2NrW01BWF9DTE9DS107DQo+ID4g K3N0YXRpYyBzdHJ1Y3QgY2xrX29uZWNlbGxfZGF0YSB6eW5xbXBfY2xrX2RhdGE7DQo+ID4gK3N0 YXRpYyBzdHJ1Y3QgY2xrICp6eW5xbXBfY2xrc1tNQVhfQ0xPQ0tdOw0KPiA+ICtzdGF0aWMgdW5z aWduZWQgaW50IGNsb2NrX21heF9pZHg7DQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgenlucW1w X2VlbWlfb3BzICplZW1pX29wczsNCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiBpc192YWxpZF9j bG9jayAtIENoZWNrIHdoZXRoZXIgY2xvY2sgaXMgdmFsaWQgb3Igbm90DQo+ID4gKyAqIEBjbGtf aWQ6IENsb2NrIEluZGV4DQo+ID4gKyAqIEB2YWxpZDogMTogaWYgY2xvY2sgaXMgdmFsaWQNCj4g PiArICogICAgICAgICAwOiBpbnZhbGlkIGNsb2NrDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjog MCBTdWNjZXNzDQo+ID4gKyAqICAgICAgICAgRXJyb3IgY29kZTogRmFpbHVyZQ0KPiA+ICsgKi8N Cj4gPiArc3RhdGljIGludCBpc192YWxpZF9jbG9jayh1MzIgY2xrX2lkLCB1MzIgKnZhbGlkKQ0K PiA+ICt7DQo+ID4gKyAgICAgICBpZiAoY2xrX2lkIDwgMCB8fCBjbGtfaWQgPiBjbG9ja19tYXhf aWR4KQ0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVOT0RFVjsNCj4gPiArDQo+ID4gKyAg ICAgICAqdmFsaWQgPSBjbG9ja1tjbGtfaWRdLnZhbGlkOw0KPiA+ICsNCj4gPiArICAgICAgIHJl dHVybiAqdmFsaWQgPyAwIDogLUVJTlZBTDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4g KyAqIHp5bnFtcF9nZXRfY2xvY2tfbmFtZSAtIEdldCBuYW1lIG9mIGNsb2NrIGZyb20gY2xvY2sg aW5kZXgNCj4gPiArICogQGNsa19pZDogQ2xvY2sgaW5kZXgNCj4gPiArICogQGNsa19uYW1lOiBO YW1lIG9mIGNsb2NrDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjogMDogU3VjY2Vzcw0KPiA+ICsg KiAgICAgICAgIEVycm9yIGNvZGU6IGZhaWx1cmUNCj4gPiArICovDQo+ID4gK3N0YXRpYyBpbnQg enlucW1wX2dldF9jbG9ja19uYW1lKHUzMiBjbGtfaWQsIGNoYXIgKmNsa19uYW1lKQ0KPiA+ICt7 DQo+ID4gKyAgICAgICBpbnQgcmV0Ow0KPiA+ICsgICAgICAgdTMyIHZhbGlkOw0KPiA+ICsNCj4g PiArICAgICAgIHJldCA9IGlzX3ZhbGlkX2Nsb2NrKGNsa19pZCwgJnZhbGlkKTsNCj4gPiArICAg ICAgIGlmICghcmV0ICYmIHZhbGlkKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHN0cm5jcHkoY2xr X25hbWUsIGNsb2NrW2Nsa19pZF0uY2xrX25hbWUsIE1BWF9OQU1FX0xFTik7DQo+ID4gKyAgICAg ICAgICAgICAgIHJldHVybiAwOw0KPiA+ICsgICAgICAgfSBlbHNlIHsNCj4gPiArICAgICAgICAg ICAgICAgcmV0dXJuIHJldDsNCj4gPiArICAgICAgIH0NCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoq DQo+ID4gKyAqIGdldF9jbG9ja190eXBlIC0gR2V0IHR5cGUgb2YgY2xvY2sNCj4gPiArICogQGNs a19pZDogQ2xvY2sgSW5kZXgNCj4gPiArICogQHR5cGU6IENsb2NrIHR5cGU6IENMS19UWVBFX09V VFBVVCBvciBDTEtfVFlQRV9FWFRFUk5BTA0KPiA+ICsgKg0KPiA+ICsgKiBSZXR1cm46IDA6IFN1 Y2Nlc3MNCj4gPiArICogICAgICAgICBFcnJvciBjb2RlOiBmYWlsdXJlDQo+ID4gKyAqLw0KPiA+ ICtzdGF0aWMgaW50IGdldF9jbG9ja190eXBlKHUzMiBjbGtfaWQsIHUzMiAqdHlwZSkNCj4gPiAr ew0KPiA+ICsgICAgICAgaW50IHJldDsNCj4gPiArICAgICAgIHUzMiB2YWxpZDsNCj4gPiArDQo+ ID4gKyAgICAgICByZXQgPSBpc192YWxpZF9jbG9jayhjbGtfaWQsICZ2YWxpZCk7DQo+ID4gKyAg ICAgICBpZiAoIXJldCAmJiB2YWxpZCkgew0KPiA+ICsgICAgICAgICAgICAgICAqdHlwZSA9IGNs b2NrW2Nsa19pZF0udHlwZTsNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIDA7DQo+ID4gKyAg ICAgICB9IGVsc2Ugew0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gcmV0Ow0KPiA+ICsgICAg ICAgfQ0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlucW1wX3BtX2Nsb2NrX2dl dF9uYW1lIC0gR2V0IHRoZSBuYW1lIG9mIGNsb2NrIGZvciBnaXZlbiBpZA0KPiA+ICsgKiBAY2xv Y2tfaWQ6IElEIG9mIHRoZSBjbG9jayB0byBiZSBxdWVyaWVkDQo+ID4gKyAqIEBuYW1lOiBOYW1l IG9mIGdpdmVuIGNsb2NrDQo+ID4gKyAqDQo+ID4gKyAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0 byBnZXQgbmFtZSBvZiBjbG9jayBzcGVjaWZpZWQgYnkgZ2l2ZW4NCj4gPiArICogY2xvY2sgSUQu DQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjogUmV0dXJucyBzdGF0dXMsIGluIGNhc2Ugb2YgZXJy b3IgbmFtZSB3b3VsZCBiZSAwLg0KPiA+ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBfcG1f Y2xvY2tfZ2V0X25hbWUodTMyIGNsb2NrX2lkLCBjaGFyICpuYW1lKQ0KPiA+ICt7DQo+ID4gKyAg ICAgICBzdHJ1Y3QgenlucW1wX3BtX3F1ZXJ5X2RhdGEgcWRhdGEgPSB7MH07DQo+ID4gKyAgICAg ICB1MzIgcmV0X3BheWxvYWRbUEFZTE9BRF9BUkdfQ05UXTsNCj4gPiArDQo+ID4gKyAgICAgICBx ZGF0YS5xaWQgPSBQTV9RSURfQ0xPQ0tfR0VUX05BTUU7DQo+ID4gKyAgICAgICBxZGF0YS5hcmcx ID0gY2xvY2tfaWQ7DQo+ID4gKw0KPiA+ICsgICAgICAgZWVtaV9vcHMtPnF1ZXJ5X2RhdGEocWRh dGEsIHJldF9wYXlsb2FkKTsNCj4gPiArICAgICAgIG1lbWNweShuYW1lLCByZXRfcGF5bG9hZCwg Q0xLX0dFVF9OQU1FX1JFU1BfTEVOKTsNCj4gPiArDQo+ID4gKyAgICAgICByZXR1cm4gMDsNCj4g PiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9wbV9jbG9ja19nZXRfdG9wb2xv Z3kgLSBHZXQgdGhlIHRvcG9sb2d5IG9mIGNsb2NrIGZvciBnaXZlbiBpZA0KPiA+ICsgKiBAY2xv Y2tfaWQ6IElEIG9mIHRoZSBjbG9jayB0byBiZSBxdWVyaWVkDQo+ID4gKyAqIEBpbmRleDogTm9k ZSBpbmRleCBvZiBjbG9jayB0b3BvbG9neQ0KPiA+ICsgKiBAdG9wb2xvZ3k6IEJ1ZmZlciB0byBz dG9yZSBub2RlcyBpbiB0b3BvbG9neSBhbmQgZmxhZ3MNCj4gPiArICoNCj4gPiArICogVGhpcyBm dW5jdGlvbiBpcyB1c2VkIHRvIGdldCB0b3BvbG9neSBpbmZvcm1hdGlvbiBmb3IgdGhlIGNsb2Nr DQo+ID4gKyAqIHNwZWNpZmllZCBieSBnaXZlbiBjbG9jayBJRC4NCj4gPiArICoNCj4gPiArICog VGhpcyBBUEkgd2lsbCByZXR1cm4gMyBub2RlIG9mIHRvcG9sb2d5IHdpdGggYSBzaW5nbGUgcmVz cG9uc2UuIFRvIGdldA0KPiA+ICsgKiBvdGhlciBub2RlcywgbWFzdGVyIHNob3VsZCBjYWxsIHNh bWUgQVBJIGluIGxvb3Agd2l0aCBuZXcNCj4gPiArICogaW5kZXggdGlsbCBlcnJvciBpcyByZXR1 cm5lZC4gRS5nIEZpcnN0IGNhbGwgc2hvdWxkIGhhdmUNCj4gPiArICogaW5kZXggMCB3aGljaCB3 aWxsIHJldHVybiBub2RlcyAwLDEgYW5kIDIuIE5leHQgY2FsbCwgaW5kZXgNCj4gPiArICogc2hv dWxkIGJlIDMgd2hpY2ggd2lsbCByZXR1cm4gbm9kZXMgMyw0IGFuZCA1IGFuZCBzbyBvbi4NCj4g PiArICoNCj4gPiArICogUmV0dXJuOiBSZXR1cm5zIHN0YXR1cywgZWl0aGVyIHN1Y2Nlc3Mgb3Ig ZXJyb3IrcmVhc29uLg0KPiA+ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBfcG1fY2xvY2tf Z2V0X3RvcG9sb2d5KHUzMiBjbG9ja19pZCwgdTMyIGluZGV4LCB1MzINCj4gKnRvcG9sb2d5KQ0K PiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX3BtX3F1ZXJ5X2RhdGEgcWRhdGEgPSB7 MH07DQo+ID4gKyAgICAgICB1MzIgcmV0X3BheWxvYWRbUEFZTE9BRF9BUkdfQ05UXTsNCj4gPiAr DQo+ID4gKyAgICAgICBxZGF0YS5xaWQgPSBQTV9RSURfQ0xPQ0tfR0VUX1RPUE9MT0dZOw0KPiA+ ICsgICAgICAgcWRhdGEuYXJnMSA9IGNsb2NrX2lkOw0KPiA+ICsgICAgICAgcWRhdGEuYXJnMiA9 IGluZGV4Ow0KPiA+ICsNCj4gPiArICAgICAgIGVlbWlfb3BzLT5xdWVyeV9kYXRhKHFkYXRhLCBy ZXRfcGF5bG9hZCk7DQo+ID4gKyAgICAgICBtZW1jcHkodG9wb2xvZ3ksICZyZXRfcGF5bG9hZFsx XSwNCj4gQ0xLX0dFVF9UT1BPTE9HWV9SRVNQX1dPUkRTICogNCk7DQo+ID4gKw0KPiA+ICsgICAg ICAgcmV0dXJuIHp5bnFtcF9wbV9yZXRfY29kZSgoZW51bSBwbV9yZXRfc3RhdHVzKXJldF9wYXls b2FkWzBdKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9wbV9jbG9j a19nZXRfZml4ZWRmYWN0b3JfcGFyYW1zIC0gR2V0IHRoZSBjbG9jaydzIGZpeGVkIGZhY3Rvcg0K PiA+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1ldGVy cyBmb3IgZml4ZWQgY2xvY2sNCj4gPiArICogQGNsb2NrX2lkOiBDbG9jayBJRA0KPiA+ICsgKiBA bXVsOiBNdWx0aXBsaWNhdGlvbiB2YWx1ZQ0KPiA+ICsgKiBAZGl2OiBEaXZpc29yIHZhbHVlDQo+ ID4gKyAqDQo+ID4gKyAqIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBnZXQgZml4ZWQgZmFjdG9y IHBhcmFtZWVycyBmb3IgdGhlIGZpeGVkDQo+ID4gKyAqIGNsb2NrLiBUaGlzIEFQSSBpcyBhcHBs aWNhdGlvbiBvbmx5IGZvciB0aGUgZml4ZWQgY2xvY2suDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVy bjogUmV0dXJucyBzdGF0dXMsIGVpdGhlciBzdWNjZXNzIG9yIGVycm9yK3JlYXNvbi4NCj4gPiAr ICovDQo+ID4gK3N0YXRpYyBpbnQgenlucW1wX3BtX2Nsb2NrX2dldF9maXhlZGZhY3Rvcl9wYXJh bXModTMyIGNsb2NrX2lkLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgdTMyICptdWwsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB1MzIgKmRpdikNCj4gPiArew0KPiA+ICsgICAgICAgc3Ry dWN0IHp5bnFtcF9wbV9xdWVyeV9kYXRhIHFkYXRhID0gezB9Ow0KPiA+ICsgICAgICAgdTMyIHJl dF9wYXlsb2FkW1BBWUxPQURfQVJHX0NOVF07DQo+ID4gKw0KPiA+ICsgICAgICAgcWRhdGEucWlk ID0gUE1fUUlEX0NMT0NLX0dFVF9GSVhFREZBQ1RPUl9QQVJBTVM7DQo+ID4gKyAgICAgICBxZGF0 YS5hcmcxID0gY2xvY2tfaWQ7DQo+ID4gKw0KPiA+ICsgICAgICAgZWVtaV9vcHMtPnF1ZXJ5X2Rh dGEocWRhdGEsIHJldF9wYXlsb2FkKTsNCj4gPiArICAgICAgICptdWwgPSByZXRfcGF5bG9hZFsx XTsNCj4gPiArICAgICAgICpkaXYgPSByZXRfcGF5bG9hZFsyXTsNCj4gPiArDQo+ID4gKyAgICAg ICByZXR1cm4genlucW1wX3BtX3JldF9jb2RlKChlbnVtIHBtX3JldF9zdGF0dXMpcmV0X3BheWxv YWRbMF0pOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlucW1wX3BtX2Nsb2Nr X2dldF9wYXJlbnRzIC0gR2V0IHRoZSBmaXJzdCAzIHBhcmVudHMgb2YgY2xvY2sgZm9yIGdpdmVu DQo+IGlkDQo+ID4gKyAqIEBjbG9ja19pZDogQ2xvY2sgSUQNCj4gPiArICogQGluZGV4OiBQYXJl bnQgaW5kZXgNCj4gPiArICogQHBhcmVudHM6IDMgcGFyZW50cyBvZiB0aGUgZ2l2ZW4gY2xvY2sN Cj4gPiArICoNCj4gPiArICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGdldCAzIHBhcmVudHMg Zm9yIHRoZSBjbG9jayBzcGVjaWZpZWQgYnkNCj4gPiArICogZ2l2ZW4gY2xvY2sgSUQuDQo+ID4g KyAqDQo+ID4gKyAqIFRoaXMgQVBJIHdpbGwgcmV0dXJuIDMgcGFyZW50cyB3aXRoIGEgc2luZ2xl IHJlc3BvbnNlLiBUbyBnZXQNCj4gPiArICogb3RoZXIgcGFyZW50cywgbWFzdGVyIHNob3VsZCBj YWxsIHNhbWUgQVBJIGluIGxvb3Agd2l0aCBuZXcNCj4gPiArICogcGFyZW50IGluZGV4IHRpbGwg ZXJyb3IgaXMgcmV0dXJuZWQuIEUuZyBGaXJzdCBjYWxsIHNob3VsZCBoYXZlDQo+ID4gKyAqIGlu ZGV4IDAgd2hpY2ggd2lsbCByZXR1cm4gcGFyZW50cyAwLDEgYW5kIDIuIE5leHQgY2FsbCwgaW5k ZXgNCj4gPiArICogc2hvdWxkIGJlIDMgd2hpY2ggd2lsbCByZXR1cm4gcGFyZW50IDMsNCBhbmQg NSBhbmQgc28gb24uDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjogUmV0dXJucyBzdGF0dXMsIGVp dGhlciBzdWNjZXNzIG9yIGVycm9yK3JlYXNvbi4NCj4gPiArICovDQo+ID4gK3N0YXRpYyBpbnQg enlucW1wX3BtX2Nsb2NrX2dldF9wYXJlbnRzKHUzMiBjbG9ja19pZCwgdTMyIGluZGV4LCB1MzIN Cj4gKnBhcmVudHMpDQo+ID4gK3sNCj4gPiArICAgICAgIHN0cnVjdCB6eW5xbXBfcG1fcXVlcnlf ZGF0YSBxZGF0YSA9IHswfTsNCj4gPiArICAgICAgIHUzMiByZXRfcGF5bG9hZFtQQVlMT0FEX0FS R19DTlRdOw0KPiA+ICsNCj4gPiArICAgICAgIHFkYXRhLnFpZCA9IFBNX1FJRF9DTE9DS19HRVRf UEFSRU5UUzsNCj4gPiArICAgICAgIHFkYXRhLmFyZzEgPSBjbG9ja19pZDsNCj4gPiArICAgICAg IHFkYXRhLmFyZzIgPSBpbmRleDsNCj4gPiArDQo+ID4gKyAgICAgICBlZW1pX29wcy0+cXVlcnlf ZGF0YShxZGF0YSwgcmV0X3BheWxvYWQpOw0KPiA+ICsgICAgICAgbWVtY3B5KHBhcmVudHMsICZy ZXRfcGF5bG9hZFsxXSwgQ0xLX0dFVF9QQVJFTlRTX1JFU1BfV09SRFMgKg0KPiA0KTsNCj4gPiAr DQo+ID4gKyAgICAgICByZXR1cm4genlucW1wX3BtX3JldF9jb2RlKChlbnVtIHBtX3JldF9zdGF0 dXMpcmV0X3BheWxvYWRbMF0pOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlu cW1wX3BtX2Nsb2NrX2dldF9hdHRyaWJ1dGVzIC0gR2V0IHRoZSBhdHRyaWJ1dGVzIG9mIGNsb2Nr IGZvciBnaXZlbiBpZA0KPiA+ICsgKiBAY2xvY2tfaWQ6IENsb2NrIElEDQo+ID4gKyAqIEBhdHRy aWJ1dGVzOiBDbG9jayBhdHRyaWJ1dGVzDQo+ID4gKyAqDQo+ID4gKyAqIFRoaXMgZnVuY3Rpb24g aXMgdXNlZCB0byBnZXQgY2xvY2sncyBhdHRyaWJ1dGVzKGUuZy4gdmFsaWQsIGNsb2NrIHR5cGUs IGV0YykuDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjogUmV0dXJucyBzdGF0dXMsIGVpdGhlciBz dWNjZXNzIG9yIGVycm9yK3JlYXNvbi4NCj4gPiArICovDQo+ID4gK3N0YXRpYyBpbnQgenlucW1w X3BtX2Nsb2NrX2dldF9hdHRyaWJ1dGVzKHUzMiBjbG9ja19pZCwgdTMyICphdHRyKQ0KPiA+ICt7 DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX3BtX3F1ZXJ5X2RhdGEgcWRhdGEgPSB7MH07DQo+ ID4gKyAgICAgICB1MzIgcmV0X3BheWxvYWRbUEFZTE9BRF9BUkdfQ05UXTsNCj4gPiArDQo+ID4g KyAgICAgICBxZGF0YS5xaWQgPSBQTV9RSURfQ0xPQ0tfR0VUX0FUVFJJQlVURVM7DQo+ID4gKyAg ICAgICBxZGF0YS5hcmcxID0gY2xvY2tfaWQ7DQo+ID4gKw0KPiA+ICsgICAgICAgZWVtaV9vcHMt PnF1ZXJ5X2RhdGEocWRhdGEsIHJldF9wYXlsb2FkKTsNCj4gPiArICAgICAgIG1lbWNweShhdHRy LCAmcmV0X3BheWxvYWRbMV0sIENMS19HRVRfQVRUUl9SRVNQX1dPUkRTICogNCk7DQo+ID4gKw0K PiA+ICsgICAgICAgcmV0dXJuIHp5bnFtcF9wbV9yZXRfY29kZSgoZW51bSBwbV9yZXRfc3RhdHVz KXJldF9wYXlsb2FkWzBdKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIGNsb2Nr X2dldF90b3BvbG9neTogR2V0IHRvcG9sb2d5IG9mIGNsb2NrIGZyb20gZmlybXdhcmUgdXNpbmcg UE1fQVBJDQo+ID4gKyAqIEBjbGtfaWQ6IENsb2NrIEluZGV4DQo+ID4gKyAqIEBjbGtfdG9wb2xv Z3k6IFN0cnVjdHVyZSBvZiBjbG9jayB0b3BvbG9neQ0KPiA+ICsgKiBAbnVtX25vZGVzOiBudW1i ZXIgb2Ygbm9kZXMNCj4gPiArICoNCj4gPiArICogUmV0dXJuOiAwOiBTdWNjZXNzDQo+ID4gKyAq ICAgICAgICAgRXJyb3IgQ29kZTogRmFpbHVyZQ0KPiA+ICsgKi8NCj4gPiArc3RhdGljIGludCBj bG9ja19nZXRfdG9wb2xvZ3kodTMyIGNsa19pZCwgc3RydWN0IGNsb2NrX3RvcG9sb2d5DQo+ICpj bGtfdG9wb2xvZ3ksDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTMyICpudW1f bm9kZXMpDQo+ID4gK3sNCj4gPiArICAgICAgIGludCBqLCBrID0gMCwgcmV0Ow0KPiA+ICsgICAg ICAgdTMyIHBtX3Jlc3BbUE1fQVBJX1BBWUxPQURfTEVOXSA9IHswfTsNCj4gPiArDQo+ID4gKyAg ICAgICAqbnVtX25vZGVzID0gMDsNCj4gPiArICAgICAgIGZvciAoaiA9IDA7IGogPD0gTUFYX05P REVTOyBqICs9IDMpIHsNCj4gPiArICAgICAgICAgICAgICAgcmV0ID0genlucW1wX3BtX2Nsb2Nr X2dldF90b3BvbG9neShjbGtfaWQsIGosIHBtX3Jlc3ApOw0KPiA+ICsgICAgICAgICAgICAgICBp ZiAocmV0KQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7DQo+ID4gKyAg ICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBQTV9BUElfUEFZTE9BRF9MRU47IGsrKykgew0K PiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGlmICghKHBtX3Jlc3Bba10gJiBDTEtfVFlQRV9G SUVMRF9NQVNLKSkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZG9u ZTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjbGtfdG9wb2xvZ3lbKm51bV9ub2Rlc10u dHlwZSA9IHBtX3Jlc3Bba10gJg0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgQ0xLX1RZUEVfRklFTERfTUFTSzsNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICBjbGtfdG9wb2xvZ3lbKm51bV9ub2Rlc10uZmxhZyA9DQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwbV9yZXNwW2tdID4+IENMS19G TEFHX0ZJRUxEX1NISUZUKSAmDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIENMS19GTEFHX0ZJRUxEX01BU0s7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg Y2xrX3RvcG9sb2d5WypudW1fbm9kZXNdLnR5cGVfZmxhZyA9DQo+ID4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAocG1fcmVzcFtrXSA+PiBDTEtfVFlQRV9GTEFHX0ZJRUxEX1NISUZU KSAmDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDTEtfVFlQRV9GTEFHX0ZJ RUxEX01BU0s7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgKCpudW1fbm9kZXMpKys7DQo+ ID4gKyAgICAgICAgICAgICAgIH0NCj4gPiArICAgICAgIH0NCj4gPiArZG9uZToNCj4gPiArICAg ICAgIHJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogY2xvY2tfZ2V0 X3BhcmVudHM6IEdldCBwYXJlbnRzIGluZm8gZnJvbSBmaXJtd2FyZSB1c2luZyBQTV9BUEkNCj4g PiArICogQGNsa19pZDogQ2xvY2sgSW5kZXgNCj4gPiArICogQHBhcmVudDogU3RydWN0dXJlIG9m IHBhcmVudCBpbmZvcm1hdGlvbg0KPiA+ICsgKiBAbnVtX3BhcmVudHM6IFRvdGFsIG51bWJlciBv ZiBwYXJlbnRzDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjogMDogU3VjY2Vzcw0KPiA+ICsgKiAg ICAgICAgIEVycm9yIGNvZGU6IEZhaWx1cmUNCj4gPiArICovDQo+ID4gK3N0YXRpYyBpbnQgY2xv Y2tfZ2V0X3BhcmVudHModTMyIGNsa19pZCwgc3RydWN0IGNsb2NrX3BhcmVudCAqcGFyZW50cywN Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgIHUzMiAqbnVtX3BhcmVudHMpDQo+ID4g K3sNCj4gPiArICAgICAgIGludCBqID0gMCwgaywgcmV0LCB0b3RhbF9wYXJlbnRzID0gMDsNCj4g PiArICAgICAgIHUzMiBwbV9yZXNwW1BNX0FQSV9QQVlMT0FEX0xFTl0gPSB7MH07DQo+ID4gKw0K PiA+ICsgICAgICAgZG8gew0KPiA+ICsgICAgICAgICAgICAgICAvKiBHZXQgcGFyZW50cyBmcm9t IGZpcm13YXJlICovDQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IHp5bnFtcF9wbV9jbG9ja19n ZXRfcGFyZW50cyhjbGtfaWQsIGosIHBtX3Jlc3ApOw0KPiA+ICsgICAgICAgICAgICAgICBpZiAo cmV0KQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQ7DQo+ID4gKw0KPiA+ ICsgICAgICAgICAgICAgICBmb3IgKGsgPSAwOyBrIDwgUE1fQVBJX1BBWUxPQURfTEVOOyBrKysp IHsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBpZiAocG1fcmVzcFtrXSA9PSAodTMyKU5B X1BBUkVOVCkgew0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm51bV9wYXJl bnRzID0gdG90YWxfcGFyZW50czsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHJldHVybiAwOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIH0NCj4gPiArDQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgcGFyZW50c1trICsgal0uaWQgPSBwbV9yZXNwW2tdICYgQ0xL X1BBUkVOVFNfSURfTUFTSzsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50 c1trICsgal0uaWQgPT0gRFVNTVlfUEFSRU5UKSB7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICBzdHJuY3B5KHBhcmVudHNbayArIGpdLm5hbWUsDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkdW1teV9uYW1lIiwgTUFYX05BTUVfTEVOKTsN Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudHNbayArIGpdLmZsYWcg PSAwOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQo+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRzW2sgKyBqXS5mbGFnID0gcG1fcmVzcFtrXSA+ Pg0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgQ0xLX1BBUkVOVFNfSURfTEVOOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgaWYgKHp5bnFtcF9nZXRfY2xvY2tfbmFtZShwYXJlbnRzW2sgKyBqXS5pZCwNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg cGFyZW50c1trICsgal0ubmFtZSkpDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGNvbnRpbnVlOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIH0NCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9wYXJlbnRzKys7DQo+ID4gKyAgICAgICAgICAg ICAgIH0NCj4gPiArICAgICAgICAgICAgICAgaiArPSBQTV9BUElfUEFZTE9BRF9MRU47DQo+ID4g KyAgICAgICB9IHdoaWxlICh0b3RhbF9wYXJlbnRzIDw9IE1BWF9QQVJFTlQpOw0KPiA+ICsgICAg ICAgcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiBnZXRfcGFyZW50 X2xpc3Q6IENyZWF0ZSBsaXN0IG9mIHBhcmVudHMgbmFtZQ0KPiA+ICsgKiBAbnA6ICAgICAgICAg ICAgICAgIERldmljZSBub2RlDQo+ID4gKyAqIEBjbGtfaWQ6IENsb2NrIEluZGV4DQo+ID4gKyAq IEBwYXJlbnRfbGlzdCBMaXN0IG9mIHBhcmVudCdzIG5hbWUNCj4gPiArICogQG51bV9wYXJlbnRz OiBUb3RhbCBudW1iZXIgb2YgcGFyZW50cw0KPiA+ICsgKg0KPiA+ICsgIyBSZXR1cm46IDA6IFN1 Y2Nlc3MNCj4gPiArICogICAgICAgICBFcnJvciBjb2RlOiBGYWlsdXJlDQo+ID4gKyAqLw0KPiA+ ICtzdGF0aWMgaW50IGdldF9wYXJlbnRfbGlzdChzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wLCB1MzIg Y2xrX2lkLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKipwYXJl bnRfbGlzdCwgdTMyICpudW1fcGFyZW50cykNCj4gPiArew0KPiA+ICsgICAgICAgaW50IGkgPSAw LCByZXQ7DQo+ID4gKyAgICAgICB1MzIgdG90YWxfcGFyZW50cyA9IGNsb2NrW2Nsa19pZF0ubnVt X3BhcmVudHM7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xvY2tfdG9wb2xvZ3kgKmNsa19ub2RlczsN Cj4gPiArICAgICAgIHN0cnVjdCBjbG9ja19wYXJlbnQgKnBhcmVudHM7DQo+ID4gKw0KPiA+ICsg ICAgICAgY2xrX25vZGVzID0gY2xvY2tbY2xrX2lkXS5ub2RlOw0KPiA+ICsgICAgICAgcGFyZW50 cyA9IGNsb2NrW2Nsa19pZF0ucGFyZW50Ow0KPiA+ICsNCj4gPiArICAgICAgIGZvciAoaSA9IDA7 IGkgPCB0b3RhbF9wYXJlbnRzOyBpKyspIHsNCj4gPiArICAgICAgICAgICAgICAgaWYgKCFwYXJl bnRzW2ldLmZsYWcpIHsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfbGlzdFtp XSA9IHBhcmVudHNbaV0ubmFtZTsNCj4gPiArICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJl bnRzW2ldLmZsYWcgPT0gUEFSRU5UX0NMS19FWFRFUk5BTCkgew0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgIHJldCA9IG9mX3Byb3BlcnR5X21hdGNoX3N0cmluZyhucCwgImNsb2NrLW5hbWVz IiwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgcGFyZW50c1tpXS5uYW1lKTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBpZiAo cmV0IDwgMCkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cm5jcHkocGFy ZW50c1tpXS5uYW1lLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAiZHVtbXlfbmFtZSIsIE1BWF9OQU1FX0xFTik7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgcGFyZW50X2xpc3RbaV0gPSBwYXJlbnRzW2ldLm5hbWU7DQo+ID4gKyAgICAgICAgICAgICAg IH0gZWxzZSB7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgc3RyY2F0KHBhcmVudHNbaV0u bmFtZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xrX3R5cGVfcG9zdGZp eFtjbGtfbm9kZXNbcGFyZW50c1tpXS5mbGFnIC0gMV0uDQo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHR5cGVdKTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRf bGlzdFtpXSA9IHBhcmVudHNbaV0ubmFtZTsNCj4gPiArICAgICAgICAgICAgICAgfQ0KPiA+ICsg ICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgICpudW1fcGFyZW50cyA9IHRvdGFsX3BhcmVudHM7 DQo+ID4gKyAgICAgICByZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAq IHp5bnFtcF9yZWdpc3Rlcl9jbGtfdG9wb2xvZ3k6IFJlZ2lzdGVyIGNsb2NrIHRvcG9sb2d5DQo+ ID4gKyAqIEBjbGtfaWQ6IENsb2NrIEluZGV4DQo+ID4gKyAqIEBjbGtfbmFtZTogQ2xvY2sgTmFt ZQ0KPiA+ICsgKiBAbnVtX3BhcmVudHM6IFRvdGFsIG51bWJlciBvZiBwYXJlbnRzDQo+ID4gKyAq IEBwYXJlbnRfbmFtZXM6IExpc3Qgb2YgcGFyZW50cyBuYW1lDQo+ID4gKyAqDQo+ID4gKyAqIFJl dHVybjogMDogU3VjY2Vzcw0KPiA+ICsgKiAgICAgICAgIEVycm9yIGNvZGU6IEZhaWx1cmUNCj4g PiArICovDQo+ID4gK3N0YXRpYyBzdHJ1Y3QgY2xrICp6eW5xbXBfcmVnaXN0ZXJfY2xrX3RvcG9s b2d5KGludCBjbGtfaWQsIGNoYXIgKmNsa19uYW1lLA0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1fcGFyZW50cywNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICoqcGFy ZW50X25hbWVzKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBpbnQgaiwgcmV0Ow0KPiA+ICsgICAgICAg dTMyIG51bV9ub2RlcywgbXVsdCwgZGl2Ow0KPiA+ICsgICAgICAgY2hhciAqY2xrX291dCA9IE5V TEw7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xvY2tfdG9wb2xvZ3kgKm5vZGVzOw0KPiA+ICsgICAg ICAgc3RydWN0IGNsayAqY2xrID0gTlVMTDsNCj4gPiArDQo+ID4gKyAgICAgICBub2RlcyA9IGNs b2NrW2Nsa19pZF0ubm9kZTsNCj4gPiArICAgICAgIG51bV9ub2RlcyA9IGNsb2NrW2Nsa19pZF0u bnVtX25vZGVzOw0KPiA+ICsNCj4gPiArICAgICAgIGZvciAoaiA9IDA7IGogPCBudW1fbm9kZXM7 IGorKykgew0KPiA+ICsgICAgICAgICAgICAgICBpZiAoaiAhPSAobnVtX25vZGVzIC0gMSkpIHsN Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjbGtfb3V0ID0ga2FzcHJpbnRmKEdGUF9LRVJO RUwsICIlcyVzIiwgY2xrX25hbWUsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBjbGtfdHlwZV9wb3N0Zml4W25vZGVzW2pdLnR5cGVdKTsNCj4gPiArICAg ICAgICAgICAgICAgfSBlbHNlIHsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjbGtfb3V0 ID0ga2FzcHJpbnRmKEdGUF9LRVJORUwsICIlcyIsIGNsa19uYW1lKTsNCj4gPiArICAgICAgICAg ICAgICAgfQ0KPiA+ICsNCj4gPiArICAgICAgICAgICAgICAgc3dpdGNoIChub2Rlc1tqXS50eXBl KSB7DQo+ID4gKyAgICAgICAgICAgICAgIGNhc2UgVFlQRV9NVVg6DQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgY2xrID0genlucW1wX2Nsa19yZWdpc3Rlcl9tdXgoTlVMTCwgY2xrX291dCwN Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBjbGtfaWQsIHBhcmVudF9uYW1lcywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBudW1fcGFyZW50cywNCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlc1tqXS5mbGFnLA0K PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IG5vZGVzW2pdLnR5cGVfZmxhZyk7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7 DQo+ID4gKyAgICAgICAgICAgICAgIGNhc2UgVFlQRV9QTEw6DQo+ID4gKyAgICAgICAgICAgICAg ICAgICAgICAgY2xrID0gY2xrX3JlZ2lzdGVyX3p5bnFtcF9wbGwoY2xrX291dCwgY2xrX2lkLA0K PiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHBhcmVudF9uYW1lcywgMSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBub2Rlc1tqXS5mbGFnKTsNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgICBicmVhazsNCj4gPiArICAgICAgICAgICAgICAgY2FzZSBUWVBFX0ZJWEVERkFDVE9S Og0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IHp5bnFtcF9wbV9jbG9ja19nZXRf Zml4ZWRmYWN0b3JfcGFyYW1zKGNsa19pZCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbXVsdCwNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAmZGl2KTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjbGsgPSBjbGtf cmVnaXN0ZXJfZml4ZWRfZmFjdG9yKE5VTEwsIGNsa19vdXQsDQo+ID4gKyAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfbmFtZXNbMF0s DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICBub2Rlc1tqXS5mbGFnLCBtdWx0LA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGl2KTsNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgICBicmVhazsNCj4gPiArICAgICAgICAgICAgICAgY2FzZSBUWVBFX0RJVjE6DQo+ID4g KyAgICAgICAgICAgICAgIGNhc2UgVFlQRV9ESVYyOg0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgIGNsayA9IHp5bnFtcF9jbGtfcmVnaXN0ZXJfZGl2aWRlcihOVUxMLCBjbGtfb3V0LCBjbGtf aWQsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIG5vZGVzW2pdLnR5cGUsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudF9uYW1lcywgMSwNCj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9k ZXNbal0uZmxhZywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgbm9kZXNbal0udHlwZV9mbGFnKTsNCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICBicmVhazsNCj4gPiArICAgICAgICAgICAgICAgY2FzZSBUWVBFX0dBVEU6DQo+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgY2xrID0genlucW1wX2Nsa19yZWdpc3Rlcl9nYXRl KE5VTEwsIGNsa19vdXQsIGNsa19pZCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50X25hbWVzLCAxLA0KPiA+ICsgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2Rlc1tqXS5m bGFnLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBub2Rlc1tqXS50eXBlX2ZsYWcpOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg IGJyZWFrOw0KPiA+ICsgICAgICAgICAgICAgICBkZWZhdWx0Og0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgIHByX2VycigiJXMoKSBVbmtub3duIHRvcG9sb2d5IGZvciAlc1xuIiwNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19mdW5jX18sIGNsa19vdXQpOw0KPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KPiA+ICsgICAgICAgICAgICAgICB9DQo+ID4g KyAgICAgICAgICAgICAgIGlmIChJU19FUlIoY2xrKSkNCj4gPiArICAgICAgICAgICAgICAgICAg ICAgICBwcl93YXJuX29uY2UoIiVzKCkgJXMgcmVnaXN0ZXIgZmFpbCB3aXRoICVsZFxuIiwNCj4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19mdW5jX18sIGNsa19uYW1l LCBQVFJfRVJSKGNsaykpOw0KPiA+ICsNCj4gPiArICAgICAgICAgICAgICAgcGFyZW50X25hbWVz WzBdID0gY2xrX291dDsNCj4gPiArICAgICAgIH0NCj4gPiArICAgICAgIGtmcmVlKGNsa19vdXQp Ow0KPiA+ICsgICAgICAgcmV0dXJuIGNsazsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4g KyAqIHp5bnFtcF9yZWdpc3Rlcl9jbG9ja3M6IFJlZ2lzdGVyIGNsb2Nrcw0KPiA+ICsgKiBAbnA6 IERldmljZSBub2RlDQo+ID4gKyAqDQo+ID4gKyAqIFJldHVybjogMDogU3VjY2Vzcw0KPiA+ICsg KiAgICAgICAgIEVycm9yIGNvZGU6IGZhaWx1cmUNCj4gPiArICovDQo+ID4gK3N0YXRpYyBpbnQg enlucW1wX3JlZ2lzdGVyX2Nsb2NrcyhzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wKQ0KPiA+ICt7DQo+ ID4gKyAgICAgICBpbnQgcmV0Ow0KPiA+ICsgICAgICAgdTMyIGksIHRvdGFsX3BhcmVudHMgPSAw LCB0eXBlID0gMDsNCj4gPiArICAgICAgIGNvbnN0IGNoYXIgKnBhcmVudF9uYW1lc1tNQVhfUEFS RU5UXTsNCj4gPiArDQo+ID4gKyAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2xvY2tfbWF4X2lkeDsg aSsrKSB7DQo+ID4gKyAgICAgICAgICAgICAgIGNoYXIgY2xrX25hbWVbTUFYX05BTUVfTEVOXTsN Cj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIC8qIGdldCBjbG9jayBuYW1lLCBjb250aW51ZSB0 byBuZXh0IGNsb2NrIGlmIG5hbWUgbm90IGZvdW5kICovDQo+ID4gKyAgICAgICAgICAgICAgIGlm ICh6eW5xbXBfZ2V0X2Nsb2NrX25hbWUoaSwgY2xrX25hbWUpKQ0KPiA+ICsgICAgICAgICAgICAg ICAgICAgICAgIGNvbnRpbnVlOw0KPiA+ICsNCj4gPiArICAgICAgICAgICAgICAgLyogQ2hlY2sg aWYgY2xvY2sgaXMgdmFsaWQgYW5kIG91dHB1dCBjbG9jay4NCj4gPiArICAgICAgICAgICAgICAg ICogRG8gbm90IHJlZ2l0ZXIgaW52YWxpZCBvciBleHRlcm5hbCBjbG9jay4NCj4gPiArICAgICAg ICAgICAgICAgICovDQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IGdldF9jbG9ja190eXBlKGks ICZ0eXBlKTsNCj4gPiArICAgICAgICAgICAgICAgaWYgKHJldCB8fCB0eXBlICE9IENMS19UWVBF X09VVFBVVCkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCj4gPiArDQo+ ID4gKyAgICAgICAgICAgICAgIC8qIEdldCBwYXJlbnRzIG9mIGNsb2NrKi8NCj4gPiArICAgICAg ICAgICAgICAgaWYgKGdldF9wYXJlbnRfbGlzdChucCwgaSwgcGFyZW50X25hbWVzLCAmdG90YWxf cGFyZW50cykpIHsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBXQVJOX09OQ0UoMSwgIk5v IHBhcmVudHMgZm91bmQgZm9yICVzXG4iLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBjbG9ja1tpXS5jbGtfbmFtZSk7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg Y29udGludWU7DQo+ID4gKyAgICAgICAgICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICAgICAg ICAgIHp5bnFtcF9jbGtzW2ldID0genlucW1wX3JlZ2lzdGVyX2Nsa190b3BvbG9neShpLCBjbGtf bmFtZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIHRvdGFsX3BhcmVudHMsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRfbmFtZXMpOw0K PiA+ICsNCj4gPiArICAgICAgICAgICAgICAgLyogRW5hYmxlIGNsb2NrIGlmIGluaXRfZW5hYmxl IGZsYWcgaXMgMSAqLw0KPiA+ICsgICAgICAgICAgICAgICBpZiAoY2xvY2tbaV0uaW5pdF9lbmFi bGUpDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgY2xrX3ByZXBhcmVfZW5hYmxlKHp5bnFt cF9jbGtzW2ldKTsNCj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICBmb3IgKGkgPSAw OyBpIDwgY2xvY2tfbWF4X2lkeDsgaSsrKSB7DQo+ID4gKyAgICAgICAgICAgICAgIGlmIChJU19F UlIoenlucW1wX2Nsa3NbaV0pKSB7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgcHJfZXJy KCJaeW5xIFVsdHJhc2NhbGUrIE1QU29DIGNsayAlczogcmVnaXN0ZXIgZmFpbGVkIHdpdGgNCj4g JWxkXG4iLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9ja1tpXS5jbGtf bmFtZSwgUFRSX0VSUih6eW5xbXBfY2xrc1tpXSkpOw0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgIFdBUk5fT04oMSk7DQo+ID4gKyAgICAgICAgICAgICAgIH0NCj4gPiArICAgICAgIH0NCj4g PiArICAgICAgIHJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlu cW1wX2dldF9jbG9ja19pbmZvIC0gR2V0IGNsb2NrIGluZm9ybWF0aW9uIGZyb20gZmlybXdhcmUg dXNpbmcNCj4gUE1fQVBJDQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgdm9pZCB6eW5xbXBfZ2V0X2Ns b2NrX2luZm8odm9pZCkNCj4gPiArew0KPiA+ICsgICAgICAgaW50IGksIHJldDsNCj4gPiArICAg ICAgIHUzMiBhdHRyLCB0eXBlID0gMDsNCj4gPiArDQo+ID4gKyAgICAgICBtZW1zZXQoY2xvY2ss IDAsIHNpemVvZihjbG9jaykpOw0KPiA+ICsgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DTE9D SzsgaSsrKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHp5bnFtcF9wbV9jbG9ja19nZXRfbmFtZShp LCBjbG9ja1tpXS5jbGtfbmFtZSk7DQo+ID4gKyAgICAgICAgICAgICAgIGlmICghc3RybmNtcChj bG9ja1tpXS5jbGtfbmFtZSwgRU5EX09GX0NMS19OQU1FLA0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgTUFYX05BTUVfTEVOKSkgew0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg IGNsb2NrX21heF9pZHggPSBpOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0K PiA+ICsgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFzdHJuY21wKGNsb2NrW2ldLmNsa19uYW1l LCBSRVNFUlZFRF9DTEtfTkFNRSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICBNQVhfTkFNRV9MRU4pKSB7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgY29udGlu dWU7DQo+ID4gKyAgICAgICAgICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIHJl dCA9IHp5bnFtcF9wbV9jbG9ja19nZXRfYXR0cmlidXRlcyhpLCAmYXR0cik7DQo+ID4gKyAgICAg ICAgICAgICAgIGlmIChyZXQpDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7 DQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAgICBjbG9ja1tpXS52YWxpZCA9IGF0dHIgJiBDTEtf VkFMSURfTUFTSzsNCj4gPiArICAgICAgICAgICAgICAgY2xvY2tbaV0uaW5pdF9lbmFibGUgPSAh IShhdHRyICYgQ0xLX0lOSVRfRU5BQkxFX01BU0spOw0KPiA+ICsgICAgICAgICAgICAgICBjbG9j a1tpXS50eXBlID0gYXR0ciA+PiBDTEtfVFlQRV9TSElGVCA/IENMS19UWVBFX0VYVEVSTkFMIDoN Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIENMS19UWVBFX09VVFBVVDsNCj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICAv KiBHZXQgdG9wb2xvZ3kgb2YgYWxsIGNsb2NrICovDQo+ID4gKyAgICAgICBmb3IgKGkgPSAwOyBp IDwgY2xvY2tfbWF4X2lkeDsgaSsrKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IGdldF9j bG9ja190eXBlKGksICZ0eXBlKTsNCj4gPiArICAgICAgICAgICAgICAgaWYgKHJldCB8fCB0eXBl ICE9IENMS19UWVBFX09VVFBVVCkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjb250aW51 ZTsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IGNsb2NrX2dldF90b3BvbG9neShp LCBjbG9ja1tpXS5ub2RlLCAmY2xvY2tbaV0ubnVtX25vZGVzKTsNCj4gPiArICAgICAgICAgICAg ICAgaWYgKHJldCkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCj4gPiAr DQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IGNsb2NrX2dldF9wYXJlbnRzKGksIGNsb2NrW2ld LnBhcmVudCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNs b2NrW2ldLm51bV9wYXJlbnRzKTsNCj4gPiArICAgICAgICAgICAgICAgaWYgKHJldCkNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsNCj4gPiArICAgICAgIH0NCj4gPiArfQ0K PiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9jbGtfc2V0dXAgLSAgU2V0dXAgdGhlIGNs b2NrIGZyYW1ld29yayBhbmQgcmVnaXN0ZXIgY2xvY2tzDQo+ID4gKyAqIEBucDogRGV2aWNlIG5v ZGUNCj4gPiArICovDQo+ID4gK3N0YXRpYyB2b2lkIF9faW5pdCB6eW5xbXBfY2xrX3NldHVwKHN0 cnVjdCBkZXZpY2Vfbm9kZSAqbnApDQo+ID4gK3sNCj4gPiArICAgICAgIGludCBpZHg7DQo+ID4g Kw0KPiA+ICsgICAgICAgaWR4ID0gb2ZfcHJvcGVydHlfbWF0Y2hfc3RyaW5nKG5wLCAiY2xvY2st bmFtZXMiLCAicHNzX3JlZl9jbGsiKTsNCj4gPiArICAgICAgIGlmIChpZHggPCAwKSB7DQo+ID4g KyAgICAgICAgICAgICAgIHByX2VycigicHNzX3JlZl9jbGsgbm90IHByb3ZpZGVkXG4iKTsNCj4g PiArICAgICAgICAgICAgICAgcmV0dXJuOw0KPiA+ICsgICAgICAgfQ0KPiA+ICsgICAgICAgaWR4 ID0gb2ZfcHJvcGVydHlfbWF0Y2hfc3RyaW5nKG5wLCAiY2xvY2stbmFtZXMiLCAidmlkZW9fY2xr Iik7DQo+ID4gKyAgICAgICBpZiAoaWR4IDwgMCkgew0KPiA+ICsgICAgICAgICAgICAgICBwcl9l cnIoInZpZGVvX2NsayBub3QgcHJvdmlkZWRcbiIpOw0KPiA+ICsgICAgICAgICAgICAgICByZXR1 cm47DQo+ID4gKyAgICAgICB9DQo+ID4gKyAgICAgICBpZHggPSBvZl9wcm9wZXJ0eV9tYXRjaF9z dHJpbmcobnAsICJjbG9jay1uYW1lcyIsICJwc3NfYWx0X3JlZl9jbGsiKTsNCj4gPiArICAgICAg IGlmIChpZHggPCAwKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHByX2VycigicHNzX2FsdF9yZWZf Y2xrIG5vdCBwcm92aWRlZFxuIik7DQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybjsNCj4gPiAr ICAgICAgIH0NCj4gPiArICAgICAgIGlkeCA9IG9mX3Byb3BlcnR5X21hdGNoX3N0cmluZyhucCwg ImNsb2NrLW5hbWVzIiwgImF1eF9yZWZfY2xrIik7DQo+ID4gKyAgICAgICBpZiAoaWR4IDwgMCkg ew0KPiA+ICsgICAgICAgICAgICAgICBwcl9lcnIoImF1eF9yZWZfY2xrIG5vdCBwcm92aWRlZFxu Iik7DQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybjsNCj4gPiArICAgICAgIH0NCj4gPiArICAg ICAgIGlkeCA9IG9mX3Byb3BlcnR5X21hdGNoX3N0cmluZyhucCwgImNsb2NrLW5hbWVzIiwgImd0 X2NyeF9yZWZfY2xrIik7DQo+ID4gKyAgICAgICBpZiAoaWR4IDwgMCkgew0KPiA+ICsgICAgICAg ICAgICAgICBwcl9lcnIoImF1eF9yZWZfY2xrIG5vdCBwcm92aWRlZFxuIik7DQo+ID4gKyAgICAg ICAgICAgICAgIHJldHVybjsNCj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICB6eW5x bXBfZ2V0X2Nsb2NrX2luZm8oKTsNCj4gPiArICAgICAgIHp5bnFtcF9yZWdpc3Rlcl9jbG9ja3Mo bnApOw0KPiA+ICsNCj4gPiArICAgICAgIHp5bnFtcF9jbGtfZGF0YS5jbGtzID0genlucW1wX2Ns a3M7DQo+ID4gKyAgICAgICB6eW5xbXBfY2xrX2RhdGEuY2xrX251bSA9IGNsb2NrX21heF9pZHg7 DQo+ID4gKyAgICAgICBvZl9jbGtfYWRkX3Byb3ZpZGVyKG5wLCBvZl9jbGtfc3JjX29uZWNlbGxf Z2V0LCAmenlucW1wX2Nsa19kYXRhKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAq IHp5bnFtcF9jbG9ja19pbml0IC0gIEluaXRpYWxpemUgenlucW1wIGNsb2Nrcw0KPiA+ICsgKg0K PiA+ICsgKiBSZXR1cm46IDAgYWx3YXlzDQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgaW50IF9faW5p dCB6eW5xbXBfY2xvY2tfaW5pdCh2b2lkKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgZGV2 aWNlX25vZGUgKm5wOw0KPiA+ICsNCj4gPiArICAgICAgIG5wID0gb2ZfZmluZF9jb21wYXRpYmxl X25vZGUoTlVMTCwgTlVMTCwgInhsbngsenlucW1wLWNsa2MiKTsNCj4gPiArICAgICAgIGlmICgh bnApIHsNCj4gPiArICAgICAgICAgICAgICAgcHJfZXJyKCIlczogY2xrYyBub2RlIG5vdCBmb3Vu ZFxuIiwgX19mdW5jX18pOw0KPiA+ICsgICAgICAgICAgICAgICBvZl9ub2RlX3B1dChucCk7DQo+ ID4gKyAgICAgICAgICAgICAgIHJldHVybiAwOw0KPiA+ICsgICAgICAgfQ0KPiA+ICsNCj4gPiAr ICAgICAgIGVlbWlfb3BzID0gZ2V0X2VlbWlfb3BzKCk7DQo+ID4gKyAgICAgICBpZiAoIWVlbWlf b3BzIHx8ICFlZW1pX29wcy0+cXVlcnlfZGF0YSkgew0KPiA+ICsgICAgICAgICAgICAgICBwcl9l cnIoIiVzOiBjbGsgZGF0YSBub3QgZm91bmRcbiIsIF9fZnVuY19fKTsNCj4gPiArICAgICAgICAg ICAgICAgb2Zfbm9kZV9wdXQobnApOw0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsNCj4g PiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICB6eW5xbXBfY2xrX3NldHVwKG5wKTsNCj4g PiArDQo+ID4gKyAgICAgICByZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICthcmNoX2luaXRjYWxsKHp5 bnFtcF9jbG9ja19pbml0KTsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jbGsvenlucW1wL2Rp dmlkZXIuYyBiL2RyaXZlcnMvY2xrL3p5bnFtcC9kaXZpZGVyLmMNCj4gPiBuZXcgZmlsZSBtb2Rl IDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjFhMTQ3M2MNCj4gPiAtLS0gL2Rldi9udWxsDQo+ ID4gKysrIGIvZHJpdmVycy9jbGsvenlucW1wL2RpdmlkZXIuYw0KPiA+IEBAIC0wLDAgKzEsMjM5 IEBADQo+ID4gKy8qDQo+ID4gKyAqIFp5bnEgVWx0cmFTY2FsZSsgTVBTb0MgRGl2aWRlciBzdXBw b3J0DQo+ID4gKyAqDQo+ID4gKyAqICBDb3B5cmlnaHQgKEMpIDIwMTYtMjAxNyBYaWxpbngNCj4g PiArICoNCj4gPiArICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6ICAgICBHUEwtMi4wKw0KPiAN Cj4gU2FtZSBhcyBhYm92ZTogVGhpcyB0YWcgc2hvdWxkIGJlIG9uIHRoZSBmaXN0IGxpbmUgdGhp cyB3YXk6DQo+IC8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wKw0KPiANCj4gPiAr ICoNCj4gPiArICogQWRqdXN0YWJsZSBkaXZpZGVyIGNsb2NrIGltcGxlbWVudGF0aW9uDQo+ID4g KyAqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4L2Nsay5oPg0KPiA+ICsjaW5jbHVkZSA8 bGludXgvY2xrLXByb3ZpZGVyLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9jbGsvenlucW1wLmg+ DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3Ns YWIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lvLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9l cnIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPg0KPiA+ICsjaW5jbHVkZSA8bGlu dXgvbG9nMi5oPg0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogRE9DOiBiYXNpYyBhZGp1c3RhYmxl IGRpdmlkZXIgY2xvY2sgdGhhdCBjYW5ub3QgZ2F0ZQ0KPiA+ICsgKg0KPiA+ICsgKiBUcmFpdHMg b2YgdGhpcyBjbG9jazoNCj4gPiArICogcHJlcGFyZSAtIGNsa19wcmVwYXJlIG9ubHkgZW5zdXJl cyB0aGF0IHBhcmVudHMgYXJlIHByZXBhcmVkDQo+ID4gKyAqIGVuYWJsZSAtIGNsa19lbmFibGUg b25seSBlbnN1cmVzIHRoYXQgcGFyZW50cyBhcmUgZW5hYmxlZA0KPiA+ICsgKiByYXRlIC0gcmF0 ZSBpcyBhZGp1c3RhYmxlLiAgY2xrLT5yYXRlID0gY2VpbGluZyhwYXJlbnQtPnJhdGUgLyBkaXZp c29yKQ0KPiA+ICsgKiBwYXJlbnQgLSBmaXhlZCBwYXJlbnQuICBObyBjbGtfc2V0X3BhcmVudCBz dXBwb3J0DQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2RlZmluZSB0b196eW5xbXBfY2xrX2Rpdmlk ZXIoX2h3KSAgICAgICAgICAgICBcDQo+ID4gKyAgICAgICBjb250YWluZXJfb2YoX2h3LCBzdHJ1 Y3QgenlucW1wX2Nsa19kaXZpZGVyLCBodykNCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiBzdHJ1 Y3QgenlucW1wX2Nsa19kaXZpZGVyIC0gYWRqdXN0YWJsZSBkaXZpZGVyIGNsb2NrDQo+ID4gKyAq DQo+ID4gKyAqIEBodzogICAgICAgIGhhbmRsZSBiZXR3ZWVuIGNvbW1vbiBhbmQgaGFyZHdhcmUt c3BlY2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKiBAZmxhZ3M6IEhhcmR3YXJlIHNwZWNpZmljIGZs YWdzDQo+ID4gKyAqIEBjbGtfaWQ6IElkIG9mIGNsb2NrDQo+ID4gKyAqIEBkaXZfdHlwZTogZGl2 aXNvciB0eXBlIChUWVBFX0RJVjEgb3IgVFlQRV9ESVYyKQ0KPiA+ICsgKi8NCj4gPiArc3RydWN0 IHp5bnFtcF9jbGtfZGl2aWRlciB7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xrX2h3IGh3Ow0KPiA+ ICsgICAgICAgdTggZmxhZ3M7DQo+ID4gKyAgICAgICB1MzIgY2xrX2lkOw0KPiA+ICsgICAgICAg dTMyIGRpdl90eXBlOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGljIGludCB6eW5xbXBfZGl2 aWRlcl9nZXRfdmFsKHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUsIHVuc2lnbmVkIGxvbmcNCj4g cmF0ZSkNCj4gPiArew0KPiA+ICsgICAgICAgcmV0dXJuIERJVl9ST1VORF9VUF9VTEwoKHU2NClw YXJlbnRfcmF0ZSwgcmF0ZSk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB1bnNpZ25lZCBs b25nIHp5bnFtcF9jbGtfZGl2aWRlcl9yZWNhbGNfcmF0ZShzdHJ1Y3QgY2xrX2h3ICpodywNCj4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5z aWduZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0IHp5bnFt cF9jbGtfZGl2aWRlciAqZGl2aWRlciA9IHRvX3p5bnFtcF9jbGtfZGl2aWRlcihodyk7DQo+ID4g KyAgICAgICBjb25zdCBjaGFyICpjbGtfbmFtZSA9IGNsa19od19nZXRfbmFtZShodyk7DQo+ID4g KyAgICAgICB1MzIgY2xrX2lkID0gZGl2aWRlci0+Y2xrX2lkOw0KPiA+ICsgICAgICAgdTMyIGRp dl90eXBlID0gZGl2aWRlci0+ZGl2X3R5cGU7DQo+ID4gKyAgICAgICB1MzIgZGl2LCB2YWx1ZTsN Cj4gPiArICAgICAgIGludCByZXQ7DQo+ID4gKyAgICAgICBjb25zdCBzdHJ1Y3QgenlucW1wX2Vl bWlfb3BzICplZW1pX29wcyA9IGdldF9lZW1pX29wcygpOw0KPiA+ICsNCj4gPiArICAgICAgIGlm ICghZWVtaV9vcHMgfHwgIWVlbWlfb3BzLT5jbG9ja19nZXRkaXZpZGVyKQ0KPiA+ICsgICAgICAg ICAgICAgICByZXR1cm4gLUVOWElPOw0KPiA+ICsNCj4gPiArICAgICAgIHJldCA9IGVlbWlfb3Bz LT5jbG9ja19nZXRkaXZpZGVyKGNsa19pZCwgJmRpdik7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYg KHJldCkNCj4gPiArICAgICAgICAgICAgICAgcHJfd2Fybl9vbmNlKCIlcygpIGdldCBkaXZpZGVy IGZhaWxlZCBmb3IgJXMsIHJldCA9ICVkXG4iLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgX19mdW5jX18sIGNsa19uYW1lLCByZXQpOw0KPiA+ICsNCj4gPiArICAgICAgIGlmIChk aXZfdHlwZSA9PSBUWVBFX0RJVjEpDQo+ID4gKyAgICAgICAgICAgICAgIHZhbHVlID0gZGl2ICYg MHhGRkZGOw0KPiA+ICsgICAgICAgZWxzZQ0KPiA+ICsgICAgICAgICAgICAgICB2YWx1ZSA9IChk aXYgPj4gMTYpICYgMHhGRkZGOw0KPiA+ICsNCj4gPiArICAgICAgIHJldHVybiB6eW5xbXBfZGl2 aWRlcl9nZXRfdmFsKCh1NjQpcGFyZW50X3JhdGUsIHZhbHVlKTsNCj4gPiArfQ0KPiA+ICsNCj4g PiArc3RhdGljIGxvbmcgenlucW1wX2Nsa19kaXZpZGVyX3JvdW5kX3JhdGUoc3RydWN0IGNsa19o dyAqaHcsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5z aWduZWQgbG9uZyByYXRlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHVuc2lnbmVkIGxvbmcgKnByYXRlKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3Qg enlucW1wX2Nsa19kaXZpZGVyICpkaXZpZGVyID0gdG9fenlucW1wX2Nsa19kaXZpZGVyKGh3KTsN Cj4gPiArICAgICAgIGNvbnN0IGNoYXIgKmNsa19uYW1lID0gY2xrX2h3X2dldF9uYW1lKGh3KTsN Cj4gPiArICAgICAgIHUzMiBjbGtfaWQgPSBkaXZpZGVyLT5jbGtfaWQ7DQo+ID4gKyAgICAgICB1 MzIgZGl2X3R5cGUgPSBkaXZpZGVyLT5kaXZfdHlwZTsNCj4gPiArICAgICAgIHUzMiBiZXN0ZGl2 Ow0KPiA+ICsgICAgICAgaW50IHJldDsNCj4gPiArICAgICAgIGNvbnN0IHN0cnVjdCB6eW5xbXBf ZWVtaV9vcHMgKmVlbWlfb3BzID0gZ2V0X2VlbWlfb3BzKCk7DQo+ID4gKw0KPiA+ICsgICAgICAg aWYgKCFlZW1pX29wcyB8fCAhZWVtaV9vcHMtPmNsb2NrX2dldGRpdmlkZXIpDQo+ID4gKyAgICAg ICAgICAgICAgIHJldHVybiAtRU5YSU87DQo+ID4gKw0KPiA+ICsgICAgICAgLyogaWYgcmVhZCBv bmx5LCBqdXN0IHJldHVybiBjdXJyZW50IHZhbHVlICovDQo+ID4gKyAgICAgICBpZiAoZGl2aWRl ci0+ZmxhZ3MgJiBDTEtfRElWSURFUl9SRUFEX09OTFkpIHsNCj4gPiArICAgICAgICAgICAgICAg cmV0ID0gZWVtaV9vcHMtPmNsb2NrX2dldGRpdmlkZXIoY2xrX2lkLCAmYmVzdGRpdik7DQo+ID4g Kw0KPiA+ICsgICAgICAgICAgICAgICBpZiAocmV0KQ0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgIHByX3dhcm5fb25jZSgiJXMoKSBnZXQgZGl2aWRlciBmYWlsZWQgZm9yICVzLCByZXQgPSAl ZFxuIiwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19mdW5jX18s IGNsa19uYW1lLCByZXQpOw0KPiA+ICsgICAgICAgICAgICAgICBpZiAoZGl2X3R5cGUgPT0gVFlQ RV9ESVYxKQ0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGJlc3RkaXYgPSBiZXN0ZGl2ICYg MHhGRkZGOw0KPiA+ICsgICAgICAgICAgICAgICBlbHNlDQo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgYmVzdGRpdiAgPSAoYmVzdGRpdiA+PiAxNikgJiAweEZGRkY7DQo+ID4gKw0KPiA+ICsg ICAgICAgICAgICAgICByZXR1cm4gRElWX1JPVU5EX1VQX1VMTCgodTY0KSpwcmF0ZSwgYmVzdGRp dik7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ICsgICAgICAgYmVzdGRpdiA9IHp5bnFtcF9k aXZpZGVyX2dldF92YWwoKnByYXRlLCByYXRlKTsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAoKGNs a19od19nZXRfZmxhZ3MoaHcpICYgQ0xLX1NFVF9SQVRFX1BBUkVOVCkgJiYNCj4gPiArICAgICAg ICAgICAoKGNsa19od19nZXRfZmxhZ3MoaHcpICYgQ0xLX0ZSQUMpKSkNCj4gPiArICAgICAgICAg ICAgICAgYmVzdGRpdiA9IHJhdGUgJSAqcHJhdGUgPyAxIDogYmVzdGRpdjsNCj4gPiArICAgICAg ICpwcmF0ZSA9IHJhdGUgKiBiZXN0ZGl2Ow0KPiA+ICsNCj4gPiArICAgICAgIHJldHVybiByYXRl Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlucW1wX2Nsa19kaXZpZGVyX3Nl dF9yYXRlIC0gU2V0IHJhdGUgb2YgZGl2aWRlciBjbG9jaw0KPiA+ICsgKiBAaHc6ICAgICAgICBo YW5kbGUgYmV0d2VlbiBjb21tb24gYW5kIGhhcmR3YXJlLXNwZWNpZmljIGludGVyZmFjZXMNCj4g PiArICogQHJhdGU6IHJhdGUgb2YgY2xvY2sgdG8gYmUgc2V0DQo+ID4gKyAqIEBwYXJlbnRfcmF0 ZTogcmF0ZSBvZiBwYXJlbnQgY2xvY2sNCj4gPiArICoNCj4gPiArICogUmV0dXJuOiAwIGFsd2F5 cw0KPiA+ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBfY2xrX2RpdmlkZXJfc2V0X3JhdGUo c3RydWN0IGNsa19odyAqaHcsIHVuc2lnbmVkIGxvbmcgcmF0ZSwNCj4gPiArICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIHBhcmVudF9yYXRlKQ0KPiA+ ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX2Nsa19kaXZpZGVyICpkaXZpZGVyID0gdG9f enlucW1wX2Nsa19kaXZpZGVyKGh3KTsNCj4gPiArICAgICAgIGNvbnN0IGNoYXIgKmNsa19uYW1l ID0gY2xrX2h3X2dldF9uYW1lKGh3KTsNCj4gPiArICAgICAgIHUzMiBjbGtfaWQgPSBkaXZpZGVy LT5jbGtfaWQ7DQo+ID4gKyAgICAgICB1MzIgZGl2X3R5cGUgPSBkaXZpZGVyLT5kaXZfdHlwZTsN Cj4gPiArICAgICAgIHUzMiB2YWx1ZSwgZGl2Ow0KPiA+ICsgICAgICAgaW50IHJldDsNCj4gPiAr ICAgICAgIGNvbnN0IHN0cnVjdCB6eW5xbXBfZWVtaV9vcHMgKmVlbWlfb3BzID0gZ2V0X2VlbWlf b3BzKCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKCFlZW1pX29wcyB8fCAhZWVtaV9vcHMtPmNs b2NrX3NldGRpdmlkZXIpDQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiAtRU5YSU87DQo+ID4g Kw0KPiA+ICsgICAgICAgdmFsdWUgPSB6eW5xbXBfZGl2aWRlcl9nZXRfdmFsKHBhcmVudF9yYXRl LCByYXRlKTsNCj4gPiArICAgICAgIGlmIChkaXZfdHlwZSA9PSBUWVBFX0RJVjEpIHsNCj4gPiAr ICAgICAgICAgICAgICAgZGl2ID0gdmFsdWUgJiAweEZGRkY7DQo+ID4gKyAgICAgICAgICAgICAg IGRpdiB8PSAoKHUxNiktMSkgPDwgMTY7DQo+ID4gKyAgICAgICB9IGVsc2Ugew0KPiA+ICsgICAg ICAgICAgICAgICBkaXYgPSAoKHUxNiktMSk7DQo+ID4gKyAgICAgICAgICAgICAgIGRpdiB8PSB2 YWx1ZSA8PCAxNjsNCj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICByZXQgPSBlZW1p X29wcy0+Y2xvY2tfc2V0ZGl2aWRlcihjbGtfaWQsIGRpdik7DQo+ID4gKw0KPiA+ICsgICAgICAg aWYgKHJldCkNCj4gPiArICAgICAgICAgICAgICAgcHJfd2Fybl9vbmNlKCIlcygpIHNldCBkaXZp ZGVyIGZhaWxlZCBmb3IgJXMsIHJldCA9ICVkXG4iLA0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgX19mdW5jX18sIGNsa19uYW1lLCByZXQpOw0KPiA+ICsNCj4gPiArICAgICAgIHJl dHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IGNsa19vcHMg enlucW1wX2Nsa19kaXZpZGVyX29wcyA9IHsNCj4gPiArICAgICAgIC5yZWNhbGNfcmF0ZSA9IHp5 bnFtcF9jbGtfZGl2aWRlcl9yZWNhbGNfcmF0ZSwNCj4gPiArICAgICAgIC5yb3VuZF9yYXRlID0g enlucW1wX2Nsa19kaXZpZGVyX3JvdW5kX3JhdGUsDQo+ID4gKyAgICAgICAuc2V0X3JhdGUgPSB6 eW5xbXBfY2xrX2RpdmlkZXJfc2V0X3JhdGUsDQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKioNCj4g PiArICogX3JlZ2lzdGVyX2RpdmlkZXIgLSByZWdpc3RlciBhIGRpdmlkZXIgY2xvY2sNCj4gPiAr ICogQGRldjogZGV2aWNlIHJlZ2lzdGVyaW5nIHRoaXMgY2xvY2sNCj4gPiArICogQG5hbWU6IG5h bWUgb2YgdGhpcyBjbG9jaw0KPiA+ICsgKiBAY2xrX2lkOiBJZCBvZiBjbG9jaw0KPiA+ICsgKiBA ZGl2X3R5cGU6IFR5cGUgb2YgZGl2aXNvcg0KPiA+ICsgKiBAcGFyZW50czogbmFtZSBvZiBjbG9j aydzIHBhcmVudHMNCj4gPiArICogQG51bV9wYXJlbnRzOiBudW1iZXIgb2YgcGFyZW50cw0KPiA+ ICsgKiBAZmxhZ3M6IGZyYW1ld29yay1zcGVjaWZpYyBmbGFncw0KPiA+ICsgKiBAY2xrX2Rpdmlk ZXJfZmxhZ3M6IGRpdmlkZXItc3BlY2lmaWMgZmxhZ3MgZm9yIHRoaXMgY2xvY2sNCj4gPiArICoN Cj4gPiArICogUmV0dXJuOiBoYW5kbGUgdG8gcmVnaXN0ZXJlZCBjbG9jayBkaXZpZGVyDQo+ID4g KyAqLw0KPiA+ICtzdGF0aWMgc3RydWN0IGNsayAqX3JlZ2lzdGVyX2RpdmlkZXIoc3RydWN0IGRl dmljZSAqZGV2LCBjb25zdCBjaGFyICpuYW1lLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICB1MzIgY2xrX2lkLCB1MzIgZGl2X3R5cGUsDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBjb25zdCAqcGFyZW50cywNCj4g PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTggbnVtX3BhcmVudHMsIHVu c2lnbmVkIGxvbmcgZmxhZ3MsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIHU4IGNsa19kaXZpZGVyX2ZsYWdzKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3Qgenlu cW1wX2Nsa19kaXZpZGVyICpkaXY7DQo+ID4gKyAgICAgICBzdHJ1Y3QgY2xrICpjbGs7DQo+ID4g KyAgICAgICBzdHJ1Y3QgY2xrX2luaXRfZGF0YSBpbml0Ow0KPiA+ICsNCj4gPiArICAgICAgIC8q IGFsbG9jYXRlIHRoZSBkaXZpZGVyICovDQo+ID4gKyAgICAgICBkaXYgPSBremFsbG9jKHNpemVv ZigqZGl2KSwgR0ZQX0tFUk5FTCk7DQo+ID4gKyAgICAgICBpZiAoIWRpdikNCj4gPiArICAgICAg ICAgICAgICAgcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7DQo+ID4gKw0KPiA+ICsgICAgICAgaW5p dC5uYW1lID0gbmFtZTsNCj4gPiArICAgICAgIGluaXQub3BzID0gJnp5bnFtcF9jbGtfZGl2aWRl cl9vcHM7DQo+ID4gKyAgICAgICBpbml0LmZsYWdzID0gZmxhZ3M7DQo+ID4gKyAgICAgICBpbml0 LnBhcmVudF9uYW1lcyA9IHBhcmVudHM7DQo+ID4gKyAgICAgICBpbml0Lm51bV9wYXJlbnRzID0g bnVtX3BhcmVudHM7DQo+ID4gKw0KPiA+ICsgICAgICAgLyogc3RydWN0IGNsa19kaXZpZGVyIGFz c2lnbm1lbnRzICovDQo+ID4gKyAgICAgICBkaXYtPmZsYWdzID0gY2xrX2RpdmlkZXJfZmxhZ3M7 DQo+ID4gKyAgICAgICBkaXYtPmh3LmluaXQgPSAmaW5pdDsNCj4gPiArICAgICAgIGRpdi0+Y2xr X2lkID0gY2xrX2lkOw0KPiA+ICsgICAgICAgZGl2LT5kaXZfdHlwZSA9IGRpdl90eXBlOw0KPiA+ ICsNCj4gPiArICAgICAgIC8qIHJlZ2lzdGVyIHRoZSBjbG9jayAqLw0KPiA+ICsgICAgICAgY2xr ID0gY2xrX3JlZ2lzdGVyKGRldiwgJmRpdi0+aHcpOw0KPiA+ICsNCj4gPiArICAgICAgIGlmIChJ U19FUlIoY2xrKSkNCj4gPiArICAgICAgICAgICAgICAga2ZyZWUoZGl2KTsNCj4gPiArDQo+ID4g KyAgICAgICByZXR1cm4gY2xrOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlu cW1wX2Nsa19yZWdpc3Rlcl9kaXZpZGVyIC0gcmVnaXN0ZXIgYSBkaXZpZGVyIGNsb2NrDQo+ID4g KyAqIEBkZXY6IGRldmljZSByZWdpc3RlcmluZyB0aGlzIGNsb2NrDQo+ID4gKyAqIEBuYW1lOiBu YW1lIG9mIHRoaXMgY2xvY2sNCj4gPiArICogQGNsa19pZDogSWQgb2YgY2xvY2sNCj4gPiArICog QGRpdl90eXBlOiBUeXBlIG9mIGRpdmlzb3INCj4gPiArICogQHBhcmVudHM6IG5hbWUgb2YgY2xv Y2sncyBwYXJlbnRzDQo+ID4gKyAqIEBudW1fcGFyZW50czogbnVtYmVyIG9mIHBhcmVudHMNCj4g PiArICogQGZsYWdzOiBmcmFtZXdvcmstc3BlY2lmaWMgZmxhZ3MNCj4gPiArICogQGNsa19kaXZp ZGVyX2ZsYWdzOiBkaXZpZGVyLXNwZWNpZmljIGZsYWdzIGZvciB0aGlzIGNsb2NrDQo+ID4gKyAq DQo+ID4gKyAqIFJldHVybjogaGFuZGxlIHRvIHJlZ2lzdGVyZWQgY2xvY2sgZGl2aWRlcg0KPiA+ ICsgKi8NCj4gPiArc3RydWN0IGNsayAqenlucW1wX2Nsa19yZWdpc3Rlcl9kaXZpZGVyKHN0cnVj dCBkZXZpY2UgKmRldiwgY29uc3QgY2hhcg0KPiAqbmFtZSwNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgdTMyIGNsa19pZCwgdTMyIGRpdl90eXBlLA0KPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogY29uc3Qg KnBhcmVudHMsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHU4 IG51bV9wYXJlbnRzLCB1bnNpZ25lZCBsb25nIGZsYWdzLA0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICB1OCBjbGtfZGl2aWRlcl9mbGFncykNCj4gPiArew0KPiA+ ICsgICAgICAgcmV0dXJuIF9yZWdpc3Rlcl9kaXZpZGVyKGRldiwgbmFtZSwgY2xrX2lkLCBkaXZf dHlwZSwgcGFyZW50cywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1f cGFyZW50cywgZmxhZ3MsIGNsa19kaXZpZGVyX2ZsYWdzKTsNCj4gPiArfQ0KPiA+ICtFWFBPUlRf U1lNQk9MX0dQTCh6eW5xbXBfY2xrX3JlZ2lzdGVyX2RpdmlkZXIpOw0KPiA+IGRpZmYgLS1naXQg YS9kcml2ZXJzL2Nsay96eW5xbXAvcGxsLmMgYi9kcml2ZXJzL2Nsay96eW5xbXAvcGxsLmMNCj4g PiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjc1ZGVmMjENCj4gPiAt LS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9jbGsvenlucW1wL3BsbC5jDQo+ID4gQEAg LTAsMCArMSwzODQgQEANCj4gPiArLyoNCj4gPiArICogWnlucSBVbHRyYVNjYWxlKyBNUFNvQyBQ TEwgZHJpdmVyDQo+ID4gKyAqDQo+ID4gKyAqICBDb3B5cmlnaHQgKEMpIDIwMTYtMjAxNyBYaWxp bngNCj4gPiArICoNCj4gPiArICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6ICAgICBHUEwtMi4w Kw0KPiANCj4gU2FtZSBhcyBhYm92ZTogVGhpcyB0YWcgc2hvdWxkIGJlIG9uIHRoZSBmaXN0IGxp bmUgdGhpcyB3YXk6DQo+IC8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wKw0KPiAN Cj4gPiArICovDQo+ID4gKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4NCj4gPiArI2luY2x1ZGUgPGxp bnV4L2Nsay96eW5xbXAuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2Nsay1wcm92aWRlci5oPg0K PiA+ICsjaW5jbHVkZSA8bGludXgvc2xhYi5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaW8uaD4N Cj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiBzdHJ1Y3QgenlucW1wX3BsbCAtIFN0cnVjdHVyZSBm b3IgUExMIGNsb2NrDQo+ID4gKyAqIEBodzogICAgICAgICAgICAgICAgSGFuZGxlIGJldHdlZW4g Y29tbW9uIGFuZCBoYXJkd2FyZS1zcGVjaWZpYyBpbnRlcmZhY2VzDQo+ID4gKyAqIEBjbGtfaWQ6 ICAgIFBMTCBjbG9jayBJRA0KPiA+ICsgKi8NCj4gPiArc3RydWN0IHp5bnFtcF9wbGwgew0KPiA+ ICsgICAgICAgc3RydWN0IGNsa19odyBodzsNCj4gPiArICAgICAgIHUzMiBjbGtfaWQ7DQo+ID4g K307DQo+ID4gKw0KPiA+ICsjZGVmaW5lIHRvX3p5bnFtcF9wbGwoX2h3KSAgICAgY29udGFpbmVy X29mKF9odywgc3RydWN0IHp5bnFtcF9wbGwsIGh3KQ0KPiA+ICsNCj4gPiArLyogUmVnaXN0ZXIg Yml0ZmllbGQgZGVmaW5lcyAqLw0KPiA+ICsjZGVmaW5lIFBMTENUUkxfRkJESVZfTUFTSyAgICAg MHg3ZjAwDQo+ID4gKyNkZWZpbmUgUExMQ1RSTF9GQkRJVl9TSElGVCAgICA4DQo+ID4gKyNkZWZp bmUgUExMQ1RSTF9CUF9NQVNLICAgICAgICAgICAgICAgIEJJVCgzKQ0KPiA+ICsjZGVmaW5lIFBM TENUUkxfRElWMl9NQVNLICAgICAgQklUKDE2KQ0KPiA+ICsjZGVmaW5lIFBMTENUUkxfUkVTRVRf TUFTSyAgICAgMQ0KPiA+ICsjZGVmaW5lIFBMTENUUkxfUkVTRVRfVkFMICAgICAgMQ0KPiA+ICsj ZGVmaW5lIFBMTF9TVEFUVVNfTE9DS0VEICAgICAgMQ0KPiA+ICsjZGVmaW5lIFBMTENUUkxfUkVT RVRfU0hJRlQgICAgMA0KPiA+ICsjZGVmaW5lIFBMTENUUkxfRElWMl9TSElGVCAgICAgMTYNCj4g PiArDQo+ID4gKyNkZWZpbmUgUExMX0ZCRElWX01JTiAgMjUNCj4gPiArI2RlZmluZSBQTExfRkJE SVZfTUFYICAxMjUNCj4gPiArDQo+ID4gKyNkZWZpbmUgUFNfUExMX1ZDT19NSU4gMTUwMDAwMDAw MA0KPiA+ICsjZGVmaW5lIFBTX1BMTF9WQ09fTUFYIDMwMDAwMDAwMDBVTA0KPiA+ICsNCj4gPiAr ZW51bSBwbGxfbW9kZSB7DQo+ID4gKyAgICAgICBQTExfTU9ERV9JTlQsDQo+ID4gKyAgICAgICBQ TExfTU9ERV9GUkFDLA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArI2RlZmluZSBGUkFDX09GRlNFVCAw eDgNCj4gPiArI2RlZmluZSBQTExGQ0ZHX0ZSQUNfRU4gICAgICAgIEJJVCgzMSkNCj4gPiArI2Rl ZmluZSBGUkFDX0RJViAgMHgxMDAwMCAgLyogMl4xNiAqLw0KPiA+ICsNCj4gPiArLyoqDQo+ID4g KyAqIHBsbF9nZXRfbW9kZSAtIEdldCBtb2RlIG9mIFBMTA0KPiA+ICsgKiBAaHc6IEhhbmRsZSBi ZXR3ZWVuIGNvbW1vbiBhbmQgaGFyZHdhcmUtc3BlY2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKg0K PiA+ICsgKiBSZXR1cm46IE1vZGUgb2YgUExMDQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgaW5saW5l IGVudW0gcGxsX21vZGUgcGxsX2dldF9tb2RlKHN0cnVjdCBjbGtfaHcgKmh3KQ0KPiA+ICt7DQo+ ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX3BsbCAqY2xrID0gdG9fenlucW1wX3BsbChodyk7DQo+ ID4gKyAgICAgICB1MzIgY2xrX2lkID0gY2xrLT5jbGtfaWQ7DQo+ID4gKyAgICAgICBjb25zdCBj aGFyICpjbGtfbmFtZSA9IGNsa19od19nZXRfbmFtZShodyk7DQo+ID4gKyAgICAgICB1MzIgcmV0 X3BheWxvYWRbUEFZTE9BRF9BUkdfQ05UXTsNCj4gPiArICAgICAgIGludCByZXQ7DQo+ID4gKyAg ICAgICBjb25zdCBzdHJ1Y3QgenlucW1wX2VlbWlfb3BzICplZW1pX29wcyA9IGdldF9lZW1pX29w cygpOw0KPiA+ICsNCj4gPiArICAgICAgIGlmICghZWVtaV9vcHMgfHwgIWVlbWlfb3BzLT5pb2N0 bCkNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIC1FTlhJTzsNCj4gPiArDQo+ID4gKyAgICAg ICByZXQgPSBlZW1pX29wcy0+aW9jdGwoMCwgSU9DVExfR0VUX1BMTF9GUkFDX01PREUsIGNsa19p ZCwgMCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRfcGF5bG9hZCk7DQo+ ID4gKyAgICAgICBpZiAocmV0KQ0KPiA+ICsgICAgICAgICAgICAgICBwcl93YXJuX29uY2UoIiVz KCkgUExMIGdldCBmcmFjIG1vZGUgZmFpbGVkIGZvciAlcywgcmV0ID0gJWRcbiIsDQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgY2xrX25hbWUsIHJldCk7DQo+ID4g Kw0KPiA+ICsgICAgICAgcmV0dXJuIHJldF9wYXlsb2FkWzFdOw0KPiA+ICt9DQo+ID4gKw0KPiA+ ICsvKioNCj4gPiArICogcGxsX3NldF9tb2RlIC0gU2V0IHRoZSBQTEwgbW9kZQ0KPiA+ICsgKiBA aHc6ICAgICAgICAgICAgICAgIEhhbmRsZSBiZXR3ZWVuIGNvbW1vbiBhbmQgaGFyZHdhcmUtc3Bl Y2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKiBAb246ICAgICAgICAgICAgICAgIEZsYWcgdG8gZGV0 ZXJtaW5lIHRoZSBtb2RlDQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgaW5saW5lIHZvaWQgcGxsX3Nl dF9tb2RlKHN0cnVjdCBjbGtfaHcgKmh3LCBib29sIG9uKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBz dHJ1Y3QgenlucW1wX3BsbCAqY2xrID0gdG9fenlucW1wX3BsbChodyk7DQo+ID4gKyAgICAgICB1 MzIgY2xrX2lkID0gY2xrLT5jbGtfaWQ7DQo+ID4gKyAgICAgICBjb25zdCBjaGFyICpjbGtfbmFt ZSA9IGNsa19od19nZXRfbmFtZShodyk7DQo+ID4gKyAgICAgICBpbnQgcmV0Ow0KPiA+ICsgICAg ICAgdTMyIG1vZGU7DQo+ID4gKyAgICAgICBjb25zdCBzdHJ1Y3QgenlucW1wX2VlbWlfb3BzICpl ZW1pX29wcyA9IGdldF9lZW1pX29wcygpOw0KPiA+ICsNCj4gPiArICAgICAgIGlmICghZWVtaV9v cHMgfHwgIWVlbWlfb3BzLT5pb2N0bCkgew0KPiA+ICsgICAgICAgICAgICAgICBwcl93YXJuX29u Y2UoImVlbWlfb3BzIG5vdCBmb3VuZFxuIik7DQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybjsN Cj4gPiArICAgICAgIH0NCj4gPiArDQo+ID4gKyAgICAgICBpZiAob24pDQo+ID4gKyAgICAgICAg ICAgICAgIG1vZGUgPSBQTExfTU9ERV9GUkFDOw0KPiA+ICsgICAgICAgZWxzZQ0KPiA+ICsgICAg ICAgICAgICAgICBtb2RlID0gUExMX01PREVfSU5UOw0KPiA+ICsNCj4gPiArICAgICAgIHJldCA9 IGVlbWlfb3BzLT5pb2N0bCgwLCBJT0NUTF9TRVRfUExMX0ZSQUNfTU9ERSwgY2xrX2lkLCBtb2Rl LA0KPiBOVUxMKTsNCj4gPiArICAgICAgIGlmIChyZXQpDQo+ID4gKyAgICAgICAgICAgICAgIHBy X3dhcm5fb25jZSgiJXMoKSBQTEwgc2V0IGZyYWMgbW9kZSBmYWlsZWQgZm9yICVzLCByZXQgPSAl ZFxuIiwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBjbGtfbmFt ZSwgcmV0KTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9wbGxfcm91 bmRfcmF0ZSAtIFJvdW5kIGEgY2xvY2sgZnJlcXVlbmN5DQo+ID4gKyAqIEBodzogICAgICAgICAg ICAgICAgSGFuZGxlIGJldHdlZW4gY29tbW9uIGFuZCBoYXJkd2FyZS1zcGVjaWZpYyBpbnRlcmZh Y2VzDQo+ID4gKyAqIEByYXRlOiAgICAgIERlc2lyZWQgY2xvY2sgZnJlcXVlbmN5DQo+ID4gKyAq IEBwcmF0ZTogICAgIENsb2NrIGZyZXF1ZW5jeSBvZiBwYXJlbnQgY2xvY2sNCj4gPiArICoNCj4g PiArICogUmV0dXJuOiAgICAgRnJlcXVlbmN5IGNsb3Nlc3QgdG8gQHJhdGUgdGhlIGhhcmR3YXJl IGNhbiBnZW5lcmF0ZQ0KPiA+ICsgKi8NCj4gPiArc3RhdGljIGxvbmcgenlucW1wX3BsbF9yb3Vu ZF9yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LCB1bnNpZ25lZCBsb25nIHJhdGUsDQo+ID4gKyAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgKnByYXRlKQ0KPiA+ICt7 DQo+ID4gKyAgICAgICB1MzIgZmJkaXY7DQo+ID4gKyAgICAgICBsb25nIHJhdGVfZGl2LCBmOw0K PiA+ICsNCj4gPiArICAgICAgIC8qIEVuYWJsZSB0aGUgZnJhY3Rpb25hbCBtb2RlIGlmIG5lZWRl ZCAqLw0KPiA+ICsgICAgICAgcmF0ZV9kaXYgPSAoKHJhdGUgKiBGUkFDX0RJVikgLyAqcHJhdGUp Ow0KPiA+ICsgICAgICAgZiA9IHJhdGVfZGl2ICUgRlJBQ19ESVY7DQo+ID4gKyAgICAgICBwbGxf c2V0X21vZGUoaHcsICEhZik7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKHBsbF9nZXRfbW9kZSho dykgPT0gUExMX01PREVfRlJBQykgew0KPiA+ICsgICAgICAgICAgICAgICBpZiAocmF0ZSA+IFBT X1BMTF9WQ09fTUFYKSB7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgZmJkaXYgPSByYXRl IC8gUFNfUExMX1ZDT19NQVg7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgcmF0ZSA9IHJh dGUgLyAoZmJkaXYgKyAxKTsNCj4gPiArICAgICAgICAgICAgICAgfQ0KPiA+ICsgICAgICAgICAg ICAgICBpZiAocmF0ZSA8IFBTX1BMTF9WQ09fTUlOKSB7DQo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgZmJkaXYgPSBESVZfUk9VTkRfVVAoUFNfUExMX1ZDT19NSU4sIHJhdGUpOw0KPiA+ICsg ICAgICAgICAgICAgICAgICAgICAgIHJhdGUgPSByYXRlICogZmJkaXY7DQo+ID4gKyAgICAgICAg ICAgICAgIH0NCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIHJhdGU7DQo+ID4gKyAgICAgICB9 DQo+ID4gKw0KPiA+ICsgICAgICAgZmJkaXYgPSBESVZfUk9VTkRfQ0xPU0VTVChyYXRlLCAqcHJh dGUpOw0KPiA+ICsgICAgICAgZmJkaXYgPSBjbGFtcF90KHUzMiwgZmJkaXYsIFBMTF9GQkRJVl9N SU4sIFBMTF9GQkRJVl9NQVgpOw0KPiA+ICsgICAgICAgcmV0dXJuICpwcmF0ZSAqIGZiZGl2Ow0K PiA+ICt9DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlucW1wX3BsbF9yZWNhbGNfcmF0ZSAt IFJlY2FsY3VsYXRlIGNsb2NrIGZyZXF1ZW5jeQ0KPiA+ICsgKiBAaHc6ICAgICAgICAgICAgICAg ICAgICAgICAgSGFuZGxlIGJldHdlZW4gY29tbW9uIGFuZCBoYXJkd2FyZS1zcGVjaWZpYw0KPiBp bnRlcmZhY2VzDQo+ID4gKyAqIEBwYXJlbnRfcmF0ZTogICAgICAgQ2xvY2sgZnJlcXVlbmN5IG9m IHBhcmVudCBjbG9jaw0KPiA+ICsgKiBSZXR1cm46ICAgICAgICAgICAgIEN1cnJlbnQgY2xvY2sg ZnJlcXVlbmN5DQo+ID4gKyAqLw0KPiA+ICtzdGF0aWMgdW5zaWduZWQgbG9uZyB6eW5xbXBfcGxs X3JlY2FsY19yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LA0KPiA+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBwYXJlbnRfcmF0ZSkNCj4gPiAr ew0KPiA+ICsgICAgICAgc3RydWN0IHp5bnFtcF9wbGwgKmNsayA9IHRvX3p5bnFtcF9wbGwoaHcp Ow0KPiA+ICsgICAgICAgdTMyIGNsa19pZCA9IGNsay0+Y2xrX2lkOw0KPiA+ICsgICAgICAgY29u c3QgY2hhciAqY2xrX25hbWUgPSBjbGtfaHdfZ2V0X25hbWUoaHcpOw0KPiA+ICsgICAgICAgdTMy IGZiZGl2LCBkYXRhOw0KPiA+ICsgICAgICAgdW5zaWduZWQgbG9uZyByYXRlLCBmcmFjOw0KPiA+ ICsgICAgICAgdTMyIHJldF9wYXlsb2FkW1BBWUxPQURfQVJHX0NOVF07DQo+ID4gKyAgICAgICBp bnQgcmV0Ow0KPiA+ICsgICAgICAgY29uc3Qgc3RydWN0IHp5bnFtcF9lZW1pX29wcyAqZWVtaV9v cHMgPSBnZXRfZWVtaV9vcHMoKTsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAoIWVlbWlfb3BzIHx8 ICFlZW1pX29wcy0+Y2xvY2tfZ2V0ZGl2aWRlcikNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJu IDA7DQo+ID4gKw0KPiA+ICsgICAgICAgLyoNCj4gPiArICAgICAgICAqIG1ha2VzIHByb2JhYmx5 IHNlbnNlIHRvIHJlZHVuZGFudGx5IHNhdmUgZmJkaXYgaW4gdGhlIHN0cnVjdA0KPiA+ICsgICAg ICAgICogenlucW1wX3BsbCB0byBzYXZlIHRoZSBJTyBhY2Nlc3MuDQo+ID4gKyAgICAgICAgKi8N Cj4gPiArICAgICAgIHJldCA9IGVlbWlfb3BzLT5jbG9ja19nZXRkaXZpZGVyKGNsa19pZCwgJmZi ZGl2KTsNCj4gPiArICAgICAgIGlmIChyZXQpDQo+ID4gKyAgICAgICAgICAgICAgIHByX3dhcm5f b25jZSgiJXMoKSBnZXQgZGl2aWRlciBmYWlsZWQgZm9yICVzLCByZXQgPSAlZFxuIiwNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBjbGtfbmFtZSwgcmV0KTsNCj4g PiArDQo+ID4gKyAgICAgICByYXRlID0gIHBhcmVudF9yYXRlICogZmJkaXY7DQo+ID4gKyAgICAg ICBpZiAocGxsX2dldF9tb2RlKGh3KSA9PSBQTExfTU9ERV9GUkFDKSB7DQo+ID4gKyAgICAgICAg ICAgICAgIGVlbWlfb3BzLT5pb2N0bCgwLCBJT0NUTF9HRVRfUExMX0ZSQUNfREFUQSwgY2xrX2lk LCAwLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0X3BheWxvYWQpOw0K PiA+ICsgICAgICAgICAgICAgICBkYXRhID0gcmV0X3BheWxvYWRbMV07DQo+ID4gKyAgICAgICAg ICAgICAgIGZyYWMgPSAocGFyZW50X3JhdGUgKiBkYXRhKSAvIEZSQUNfRElWOw0KPiA+ICsgICAg ICAgICAgICAgICByYXRlID0gcmF0ZSArIGZyYWM7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ ICsgICAgICAgcmV0dXJuIHJhdGU7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qKg0KPiA+ICsgKiB6 eW5xbXBfcGxsX3NldF9yYXRlIC0gU2V0IHJhdGUgb2YgUExMDQo+ID4gKyAqIEBodzogICAgICAg ICAgICAgICAgICAgICAgICBIYW5kbGUgYmV0d2VlbiBjb21tb24gYW5kIGhhcmR3YXJlLXNwZWNp ZmljDQo+IGludGVyZmFjZXMNCj4gPiArICogQHJhdGU6ICAgICAgICAgICAgICBGcmVxdWVuY3kg b2YgY2xvY2sgdG8gYmUgc2V0DQo+ID4gKyAqIEBwYXJlbnRfcmF0ZTogICAgICAgQ2xvY2sgZnJl cXVlbmN5IG9mIHBhcmVudCBjbG9jaw0KPiA+ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBf cGxsX3NldF9yYXRlKHN0cnVjdCBjbGtfaHcgKmh3LCB1bnNpZ25lZCBsb25nIHJhdGUsDQo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgcGFyZW50X3JhdGUp DQo+ID4gK3sNCj4gPiArICAgICAgIHN0cnVjdCB6eW5xbXBfcGxsICpjbGsgPSB0b196eW5xbXBf cGxsKGh3KTsNCj4gPiArICAgICAgIHUzMiBjbGtfaWQgPSBjbGstPmNsa19pZDsNCj4gPiArICAg ICAgIGNvbnN0IGNoYXIgKmNsa19uYW1lID0gY2xrX2h3X2dldF9uYW1lKGh3KTsNCj4gPiArICAg ICAgIHUzMiBmYmRpdiwgZGF0YTsNCj4gPiArICAgICAgIGxvbmcgcmF0ZV9kaXYsIGZyYWMsIG0s IGY7DQo+ID4gKyAgICAgICBpbnQgcmV0Ow0KPiA+ICsgICAgICAgY29uc3Qgc3RydWN0IHp5bnFt cF9lZW1pX29wcyAqZWVtaV9vcHMgPSBnZXRfZWVtaV9vcHMoKTsNCj4gPiArDQo+ID4gKyAgICAg ICBpZiAoIWVlbWlfb3BzIHx8ICFlZW1pX29wcy0+Y2xvY2tfc2V0ZGl2aWRlcikNCj4gPiArICAg ICAgICAgICAgICAgcmV0dXJuIC1FTlhJTzsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAocGxsX2dl dF9tb2RlKGh3KSA9PSBQTExfTU9ERV9GUkFDKSB7DQo+ID4gKyAgICAgICAgICAgICAgIHVuc2ln bmVkIGludCBjaGlsZHJlbjsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIC8qDQo+ID4gKyAg ICAgICAgICAgICAgICAqIFdlJ3JlIHJ1bm5pbmcgb24gYSBaeW5xTVAgY29tcGF0aWJsZSBtYWNo aW5lLCBtYWtlIHN1cmUgdGhlDQo+ID4gKyAgICAgICAgICAgICAgICAqIFZQTEwgb25seSBoYXMg b25lIGNoaWxkLg0KPiA+ICsgICAgICAgICAgICAgICAgKi8NCj4gPiArICAgICAgICAgICAgICAg Y2hpbGRyZW4gPSBjbGtfZ2V0X2NoaWxkcmVuKCJ2cGxsIik7DQo+ID4gKw0KPiA+ICsgICAgICAg ICAgICAgICAvKiBBY2NvdW50IGZvciB2cGxsX3RvX2xwZCBhbmQgZHBfdmlkZW9fcmVmICovDQo+ ID4gKyAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiA+IDIpDQo+ID4gKyAgICAgICAgICAgICAg ICAgICAgICAgV0FSTigxLCAiVHdvIGRldmljZXMgYXJlIHVzaW5nIHZwbGwgd2hpY2ggaXMgZm9y YmlkZGVuXG4iKTsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIHJhdGVfZGl2ID0gKChyYXRl ICogRlJBQ19ESVYpIC8gcGFyZW50X3JhdGUpOw0KPiA+ICsgICAgICAgICAgICAgICBtID0gcmF0 ZV9kaXYgLyBGUkFDX0RJVjsNCj4gPiArICAgICAgICAgICAgICAgZiA9IHJhdGVfZGl2ICUgRlJB Q19ESVY7DQo+ID4gKyAgICAgICAgICAgICAgIG0gPSBjbGFtcF90KHUzMiwgbSwgKFBMTF9GQkRJ Vl9NSU4pLCAoUExMX0ZCRElWX01BWCkpOw0KPiA+ICsgICAgICAgICAgICAgICByYXRlID0gcGFy ZW50X3JhdGUgKiBtOw0KPiA+ICsgICAgICAgICAgICAgICBmcmFjID0gKHBhcmVudF9yYXRlICog ZikgLyBGUkFDX0RJVjsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIHJldCA9IGVlbWlfb3Bz LT5jbG9ja19zZXRkaXZpZGVyKGNsa19pZCwgbSk7DQo+ID4gKyAgICAgICAgICAgICAgIGlmIChy ZXQpDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgcHJfd2Fybl9vbmNlKCIlcygpIHNldCBk aXZpZGVyIGZhaWxlZCBmb3IgJXMsIHJldCA9ICVkXG4iLA0KPiA+ICsgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgY2xrX25hbWUsIHJldCk7DQo+ID4gKw0KPiA+ ICsgICAgICAgICAgICAgICBkYXRhID0gKEZSQUNfRElWICogZikgLyBGUkFDX0RJVjsNCj4gPiAr ICAgICAgICAgICAgICAgZWVtaV9vcHMtPmlvY3RsKDAsIElPQ1RMX1NFVF9QTExfRlJBQ19EQVRB LCBjbGtfaWQsIGRhdGEsIE5VTEwpOw0KPiA+ICsNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJu IChyYXRlICsgZnJhYyk7DQo+ID4gKyAgICAgICB9DQo+ID4gKw0KPiA+ICsgICAgICAgZmJkaXYg PSBESVZfUk9VTkRfQ0xPU0VTVChyYXRlLCBwYXJlbnRfcmF0ZSk7DQo+ID4gKyAgICAgICBmYmRp diA9IGNsYW1wX3QodTMyLCBmYmRpdiwgUExMX0ZCRElWX01JTiwgUExMX0ZCRElWX01BWCk7DQo+ ID4gKyAgICAgICByZXQgPSBlZW1pX29wcy0+Y2xvY2tfc2V0ZGl2aWRlcihjbGtfaWQsIGZiZGl2 KTsNCj4gPiArICAgICAgIGlmIChyZXQpDQo+ID4gKyAgICAgICAgICAgICAgIHByX3dhcm5fb25j ZSgiJXMoKSBzZXQgZGl2aWRlciBmYWlsZWQgZm9yICVzLCByZXQgPSAlZFxuIiwNCj4gPiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBjbGtfbmFtZSwgcmV0KTsNCj4gPiAr DQo+ID4gKyAgICAgICByZXR1cm4gcGFyZW50X3JhdGUgKiBmYmRpdjsNCj4gPiArfQ0KPiA+ICsN Cj4gPiArLyoqDQo+ID4gKyAqIHp5bnFtcF9wbGxfaXNfZW5hYmxlZCAtIENoZWNrIGlmIGEgY2xv Y2sgaXMgZW5hYmxlZA0KPiA+ICsgKiBAaHc6ICAgICAgICAgICAgICAgIEhhbmRsZSBiZXR3ZWVu IGNvbW1vbiBhbmQgaGFyZHdhcmUtc3BlY2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKg0KPiA+ICsg KiBSZXR1cm46ICAgICAxIGlmIHRoZSBjbG9jayBpcyBlbmFibGVkLCAwIG90aGVyd2lzZQ0KPiA+ ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBfcGxsX2lzX2VuYWJsZWQoc3RydWN0IGNsa19o dyAqaHcpDQo+ID4gK3sNCj4gPiArICAgICAgIHN0cnVjdCB6eW5xbXBfcGxsICpjbGsgPSB0b196 eW5xbXBfcGxsKGh3KTsNCj4gPiArICAgICAgIGNvbnN0IGNoYXIgKmNsa19uYW1lID0gY2xrX2h3 X2dldF9uYW1lKGh3KTsNCj4gPiArICAgICAgIHUzMiBjbGtfaWQgPSBjbGstPmNsa19pZDsNCj4g PiArICAgICAgIHVuc2lnbmVkIGludCBzdGF0ZTsNCj4gPiArICAgICAgIGludCByZXQ7DQo+ID4g KyAgICAgICBjb25zdCBzdHJ1Y3QgenlucW1wX2VlbWlfb3BzICplZW1pX29wcyA9IGdldF9lZW1p X29wcygpOw0KPiA+ICsNCj4gPiArICAgICAgIGlmICghZWVtaV9vcHMgfHwgIWVlbWlfb3BzLT5j bG9ja19nZXRzdGF0ZSkNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIDA7DQo+ID4gKw0KPiA+ ICsgICAgICAgcmV0ID0gZWVtaV9vcHMtPmNsb2NrX2dldHN0YXRlKGNsa19pZCwgJnN0YXRlKTsN Cj4gPiArICAgICAgIGlmIChyZXQpDQo+ID4gKyAgICAgICAgICAgICAgIHByX3dhcm5fb25jZSgi JXMoKSBjbG9jayBnZXQgc3RhdGUgZmFpbGVkIGZvciAlcywgcmV0ID0gJWRcbiIsDQo+ID4gKyAg ICAgICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgY2xrX25hbWUsIHJldCk7DQo+ID4g Kw0KPiA+ICsgICAgICAgcmV0dXJuIHN0YXRlID8gMSA6IDA7DQo+ID4gK30NCj4gPiArDQo+ID4g Ky8qKg0KPiA+ICsgKiB6eW5xbXBfcGxsX2VuYWJsZSAtIEVuYWJsZSBjbG9jaw0KPiA+ICsgKiBA aHc6ICAgICAgICAgICAgICAgIEhhbmRsZSBiZXR3ZWVuIGNvbW1vbiBhbmQgaGFyZHdhcmUtc3Bl Y2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKg0KPiA+ICsgKiBSZXR1cm46ICAgICAwIGFsd2F5cw0K PiA+ICsgKi8NCj4gPiArc3RhdGljIGludCB6eW5xbXBfcGxsX2VuYWJsZShzdHJ1Y3QgY2xrX2h3 ICpodykNCj4gPiArew0KPiA+ICsgICAgICAgc3RydWN0IHp5bnFtcF9wbGwgKmNsayA9IHRvX3p5 bnFtcF9wbGwoaHcpOw0KPiA+ICsgICAgICAgY29uc3QgY2hhciAqY2xrX25hbWUgPSBjbGtfaHdf Z2V0X25hbWUoaHcpOw0KPiA+ICsgICAgICAgdTMyIGNsa19pZCA9IGNsay0+Y2xrX2lkOw0KPiA+ ICsgICAgICAgaW50IHJldDsNCj4gPiArICAgICAgIGNvbnN0IHN0cnVjdCB6eW5xbXBfZWVtaV9v cHMgKmVlbWlfb3BzID0gZ2V0X2VlbWlfb3BzKCk7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKCFl ZW1pX29wcyB8fCAhZWVtaV9vcHMtPmNsb2NrX2VuYWJsZSkNCj4gPiArICAgICAgICAgICAgICAg cmV0dXJuIDA7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKHp5bnFtcF9wbGxfaXNfZW5hYmxlZCho dykpDQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiAwOw0KPiA+ICsNCj4gPiArICAgICAgIHBy X2luZm8oIlBMTDogZW5hYmxlXG4iKTsNCj4gPiArDQo+ID4gKyAgICAgICByZXQgPSBlZW1pX29w cy0+Y2xvY2tfZW5hYmxlKGNsa19pZCk7DQo+ID4gKyAgICAgICBpZiAocmV0KQ0KPiA+ICsgICAg ICAgICAgICAgICBwcl93YXJuX29uY2UoIiVzKCkgY2xvY2sgZW5hYmxlIGZhaWxlZCBmb3IgJXMs IHJldCA9ICVkXG4iLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19mdW5jX18s IGNsa19uYW1lLCByZXQpOw0KPiA+ICsNCj4gPiArICAgICAgIHJldHVybiAwOw0KPiA+ICt9DQo+ ID4gKw0KPiA+ICsvKioNCj4gPiArICogenlucW1wX3BsbF9kaXNhYmxlIC0gRGlzYWJsZSBjbG9j aw0KPiA+ICsgKiBAaHc6ICAgICAgICAgICAgICAgIEhhbmRsZSBiZXR3ZWVuIGNvbW1vbiBhbmQg aGFyZHdhcmUtc3BlY2lmaWMgaW50ZXJmYWNlcw0KPiA+ICsgKg0KPiA+ICsgKi8NCj4gPiArc3Rh dGljIHZvaWQgenlucW1wX3BsbF9kaXNhYmxlKHN0cnVjdCBjbGtfaHcgKmh3KQ0KPiA+ICt7DQo+ ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX3BsbCAqY2xrID0gdG9fenlucW1wX3BsbChodyk7DQo+ ID4gKyAgICAgICBjb25zdCBjaGFyICpjbGtfbmFtZSA9IGNsa19od19nZXRfbmFtZShodyk7DQo+ ID4gKyAgICAgICB1MzIgY2xrX2lkID0gY2xrLT5jbGtfaWQ7DQo+ID4gKyAgICAgICBpbnQgcmV0 Ow0KPiA+ICsgICAgICAgY29uc3Qgc3RydWN0IHp5bnFtcF9lZW1pX29wcyAqZWVtaV9vcHMgPSBn ZXRfZWVtaV9vcHMoKTsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAoIWVlbWlfb3BzIHx8ICFlZW1p X29wcy0+Y2xvY2tfZGlzYWJsZSkNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuOw0KPiA+ICsN Cj4gPiArICAgICAgIGlmICghenlucW1wX3BsbF9pc19lbmFibGVkKGh3KSkNCj4gPiArICAgICAg ICAgICAgICAgcmV0dXJuOw0KPiA+ICsNCj4gPiArICAgICAgIHByX2luZm8oIlBMTDogc2h1dGRv d25cbiIpOw0KPiA+ICsNCj4gPiArICAgICAgIHJldCA9IGVlbWlfb3BzLT5jbG9ja19kaXNhYmxl KGNsa19pZCk7DQo+ID4gKyAgICAgICBpZiAocmV0KQ0KPiA+ICsgICAgICAgICAgICAgICBwcl93 YXJuX29uY2UoIiVzKCkgY2xvY2sgZGlzYWJsZSBmYWlsZWQgZm9yICVzLCByZXQgPSAlZFxuIiwN Cj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBjbGtfbmFtZSwgcmV0 KTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCBjbGtfb3BzIHp5bnFt cF9wbGxfb3BzID0gew0KPiA+ICsgICAgICAgLmVuYWJsZSA9IHp5bnFtcF9wbGxfZW5hYmxlLA0K PiA+ICsgICAgICAgLmRpc2FibGUgPSB6eW5xbXBfcGxsX2Rpc2FibGUsDQo+ID4gKyAgICAgICAu aXNfZW5hYmxlZCA9IHp5bnFtcF9wbGxfaXNfZW5hYmxlZCwNCj4gPiArICAgICAgIC5yb3VuZF9y YXRlID0genlucW1wX3BsbF9yb3VuZF9yYXRlLA0KPiA+ICsgICAgICAgLnJlY2FsY19yYXRlID0g enlucW1wX3BsbF9yZWNhbGNfcmF0ZSwNCj4gPiArICAgICAgIC5zZXRfcmF0ZSA9IHp5bnFtcF9w bGxfc2V0X3JhdGUsDQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKioNCj4gPiArICogY2xrX3JlZ2lz dGVyX3p5bnFtcF9wbGwgLSBSZWdpc3RlciBQTEwgd2l0aCB0aGUgY2xvY2sgZnJhbWV3b3JrDQo+ ID4gKyAqIEBuYW1lOiAgICAgIFBMTCBuYW1lDQo+ID4gKyAqIEBmbGFnOiAgICAgIFBMTCBmbGFn cw0KPiA+ICsgKiBAcGFyZW50czogICBQYXJlbnQgY2xvY2sgbmFtZXMNCj4gPiArICogQG51bV9w YXJlbnRzOk51bWJlciBvZiBwYXJlbnRzDQo+ID4gKyAqIEBwbGxfY3RybDogIFBvaW50ZXIgdG8g UExMIGNvbnRyb2wgcmVnaXN0ZXINCj4gPiArICogQHBsbF9zdGF0dXM6ICAgICAgICBQb2ludGVy IHRvIFBMTCBzdGF0dXMgcmVnaXN0ZXINCj4gPiArICogQGxvY2tfaW5kZXg6ICAgICAgICBCaXQg aW5kZXggdG8gdGhpcyBQTEwncyBsb2NrIHN0YXR1cyBiaXQgaW4gQHBsbF9zdGF0dXMNCj4gPiAr ICoNCj4gPiArICogUmV0dXJuOiAgICAgSGFuZGxlIHRvIHRoZSByZWdpc3RlcmVkIGNsb2NrDQo+ ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgY2xrICpjbGtfcmVnaXN0ZXJfenlucW1wX3BsbChjb25zdCBj aGFyICpuYW1lLCB1MzIgY2xrX2lkLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIGNvbnN0IGNoYXIgKiBjb25zdCAqcGFyZW50cywNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICB1OCBudW1fcGFyZW50cywgdW5zaWduZWQgbG9uZyBmbGFnKQ0K PiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgenlucW1wX3BsbCAqcGxsOw0KPiA+ICsgICAgICAg c3RydWN0IGNsayAqY2xrOw0KPiA+ICsgICAgICAgc3RydWN0IGNsa19pbml0X2RhdGEgaW5pdDsN Cj4gPiArICAgICAgIGludCBzdGF0dXM7DQo+ID4gKw0KPiA+ICsgICAgICAgaW5pdC5uYW1lID0g bmFtZTsNCj4gPiArICAgICAgIGluaXQub3BzID0gJnp5bnFtcF9wbGxfb3BzOw0KPiA+ICsgICAg ICAgaW5pdC5mbGFncyA9IGZsYWc7DQo+ID4gKyAgICAgICBpbml0LnBhcmVudF9uYW1lcyA9IHBh cmVudHM7DQo+ID4gKyAgICAgICBpbml0Lm51bV9wYXJlbnRzID0gbnVtX3BhcmVudHM7DQo+ID4g Kw0KPiA+ICsgICAgICAgcGxsID0ga21hbGxvYyhzaXplb2YoKnBsbCksIEdGUF9LRVJORUwpOw0K PiA+ICsgICAgICAgaWYgKCFwbGwpDQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiBFUlJfUFRS KC1FTk9NRU0pOw0KPiA+ICsNCj4gPiArICAgICAgIC8qIFBvcHVsYXRlIHRoZSBzdHJ1Y3QgKi8N Cj4gPiArICAgICAgIHBsbC0+aHcuaW5pdCA9ICZpbml0Ow0KPiA+ICsgICAgICAgcGxsLT5jbGtf aWQgPSBjbGtfaWQ7DQo+ID4gKw0KPiA+ICsgICAgICAgY2xrID0gY2xrX3JlZ2lzdGVyKE5VTEws ICZwbGwtPmh3KTsNCj4gPiArICAgICAgIGlmIChXQVJOX09OKElTX0VSUihjbGspKSkNCj4gPiAr ICAgICAgICAgICAgICAga2ZyZWUocGxsKTsNCj4gPiArDQo+ID4gKyAgICAgICBzdGF0dXMgPSBj bGtfc2V0X3JhdGVfcmFuZ2UoY2xrLCBQU19QTExfVkNPX01JTiwgUFNfUExMX1ZDT19NQVgpOw0K PiA+ICsgICAgICAgaWYgKHN0YXR1cyA8IDApDQo+ID4gKyAgICAgICAgICAgICAgIHByX2Vycigi JXM6RVJST1IgY2xrX3NldF9yYXRlX3JhbmdlIGZhaWxlZCAlZFxuIiwgbmFtZSwgc3RhdHVzKTsN Cj4gPiArDQo+ID4gKyAgICAgICByZXR1cm4gY2xrOw0KPiA+ICt9DQo+ID4gZGlmZiAtLWdpdCBh L2luY2x1ZGUvbGludXgvY2xrL3p5bnFtcC5oIGIvaW5jbHVkZS9saW51eC9jbGsvenlucW1wLmgN Cj4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjAyNGViZjgNCj4g PiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvaW5jbHVkZS9saW51eC9jbGsvenlucW1wLmgNCj4g PiBAQCAtMCwwICsxLDQ2IEBADQo+ID4gKy8qDQo+ID4gKyAqICBDb3B5cmlnaHQgKEMpIDIwMTYt MjAxNyBYaWxpbngNCj4gPiArICoNCj4gPiArICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6ICAg ICBHUEwtMi4wKw0KPiA+ICsgKi8NCj4gDQo+IFRoaXMgdGFnIHNob3VsZCBiZSBvbiB0aGUgZmlz dCBsaW5lIHRoaXMgd2F5Og0KPiAvKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMCsg Ki8NCj4gDQo+ID4gKw0KPiA+ICsjaWZuZGVmIF9fTElOVVhfQ0xLX1pZTlFNUF9IXw0KPiA+ICsj ZGVmaW5lIF9fTElOVVhfQ0xLX1pZTlFNUF9IXw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4 L3NwaW5sb2NrLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9maXJtd2FyZS94aWxpbngvenlucW1w L2Zpcm13YXJlLmg+DQo+ID4gKw0KPiA+ICsjZGVmaW5lIENMS19GUkFDICAgICAgIEJJVCgxMykg LyogaGFzIGEgZnJhY3Rpb25hbCBwYXJlbnQgKi8NCj4gPiArDQo+ID4gK3N0cnVjdCBkZXZpY2U7 DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgY2xrICpjbGtfcmVnaXN0ZXJfenlucW1wX3BsbChjb25zdCBj aGFyICpuYW1lLCB1MzIgY2xrX2lkLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIGNvbnN0IGNoYXIgKiBjb25zdCAqcGFyZW50LCB1OCBudW1fcGFyZW50cywNCj4gPiAr ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIGZsYWcpOw0K PiA+ICsNCj4gPiArc3RydWN0IGNsayAqenlucW1wX2Nsa19yZWdpc3Rlcl9nYXRlKHN0cnVjdCBk ZXZpY2UgKmRldiwgY29uc3QgY2hhciAqbmFtZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgdTMyIGNsa19pZCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgY29uc3QgY2hhciAqIGNvbnN0ICpwYXJlbnRfbmFtZSwNCj4gPiArICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTggbnVtX3BhcmVudHMsIHVuc2lnbmVkIGxv bmcgZmxhZ3MsDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHU4IGNs a19nYXRlX2ZsYWdzKTsNCj4gPiArDQo+ID4gK3N0cnVjdCBjbGsgKnp5bnFtcF9jbGtfcmVnaXN0 ZXJfZGl2aWRlcihzdHJ1Y3QgZGV2aWNlICpkZXYsIGNvbnN0IGNoYXINCj4gKm5hbWUsDQo+ID4g KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHUzMiBjbGtfaWQsIHUzMiBk aXZfdHlwZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29u c3QgY2hhciAqIGNvbnN0ICpwYXJlbnRfbmFtZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgdTggbnVtX3BhcmVudHMsDQo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgZmxhZ3MsDQo+ID4gKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHU4IGNsa19kaXZpZGVyX2ZsYWdzKTsNCj4g PiArDQo+ID4gK3N0cnVjdCBjbGsgKnp5bnFtcF9jbGtfcmVnaXN0ZXJfbXV4KHN0cnVjdCBkZXZp Y2UgKmRldiwgY29uc3QgY2hhciAqbmFtZSwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB1MzIgY2xrX2lkLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIGNvbnN0IGNoYXIgKipwYXJlbnRfbmFtZXMsDQo+ID4gKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgdTggbnVtX3BhcmVudHMsIHVuc2lnbmVkIGxvbmcgZmxhZ3MsDQo+ ID4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTggY2xrX211eF9mbGFncyk7 DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgY2xrICp6eW5xbXBfY2xrX3JlZ2lzdGVyX211eF90YWJsZShz dHJ1Y3QgZGV2aWNlICpkZXYsIGNvbnN0IGNoYXINCj4gKm5hbWUsDQo+ID4gKyAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdTMyIGNsa19pZCwNCj4gPiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogY29uc3QgKnBhcmVu dF9uYW1lcywNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1 OCBudW1fcGFyZW50cywgdW5zaWduZWQgbG9uZyBmbGFncywNCj4gPiArICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB1OCBjbGtfbXV4X2ZsYWdzKTsNCj4gPiArDQo+ID4g KyNlbmRpZg0KPiA+IC0tDQo+ID4gMi43LjQNCj4gPg0KPiANCj4gDQo+IC0tDQo+IENvcmRpYWxs eQ0KPiBQaGlsaXBwZSBPbWJyZWRhbm5lDQo= ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver 2018-01-09 12:52 ` Philippe Ombredanne 2018-01-10 20:06 ` Jolly Shah @ 2018-01-10 20:15 ` Jolly Shah 1 sibling, 0 replies; 10+ messages in thread From: Jolly Shah @ 2018-01-10 20:15 UTC (permalink / raw) To: Philippe Ombredanne Cc: Michael Turquette, Stephen Boyd, Michal Simek, linux-clk@vger.kernel.org, moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE, LKML, Rajan Vaja, Tejas Patel, Shubhrajyoti Datta SGkgUGhpbGlwcGUsDQpUaGFua3MgZm9yIHRoZSByZXZpZXcuDQpXaWxsIGZpeCBhbGwgU1BEWCB0 YWdzIGluIG5leHQgdmVyc2lvbi4NCg0KVGhhbmtzLA0KSm9sbHkgU2hhaA0KDQo+IC0tLS0tT3Jp Z2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IFBoaWxpcHBlIE9tYnJlZGFubmUgW21haWx0bzpw b21icmVkYW5uZUBuZXhiLmNvbV0NCj4gU2VudDogVHVlc2RheSwgSmFudWFyeSAwOSwgMjAxOCA0 OjUzIEFNDQo+IFRvOiBKb2xseSBTaGFoIDxKT0xMWVNAeGlsaW54LmNvbT4NCj4gQ2M6IE1pY2hh ZWwgVHVycXVldHRlIDxtdHVycXVldHRlQGJheWxpYnJlLmNvbT47IFN0ZXBoZW4gQm95ZA0KPiA8 c2JveWRAY29kZWF1cm9yYS5vcmc+OyBNaWNoYWwgU2ltZWsgPG1pY2hhbC5zaW1la0B4aWxpbngu Y29tPjsgbGludXgtDQo+IGNsa0B2Z2VyLmtlcm5lbC5vcmc7IG1vZGVyYXRlZCBsaXN0OkFSTS9G UkVFU0NBTEUgSU1YIC8gTVhDIEFSTQ0KPiBBUkNISVRFQ1RVUkUgPGxpbnV4LWFybS1rZXJuZWxA bGlzdHMuaW5mcmFkZWFkLm9yZz47IExLTUwgPGxpbnV4LQ0KPiBrZXJuZWxAdmdlci5rZXJuZWwu b3JnPjsgSm9sbHkgU2hhaCA8Sk9MTFlTQHhpbGlueC5jb20+OyBSYWphbiBWYWphDQo+IDxSQUpB TlZAeGlsaW54LmNvbT47IFRlamFzIFBhdGVsIDxURUpBU1BAeGlsaW54LmNvbT47IFNodWJocmFq eW90aSBEYXR0YQ0KPiA8c2h1YmhyYWpAeGlsaW54LmNvbT4NCj4gU3ViamVjdDogUmU6IFtSRkMg UEFUQ0ggMi8yXSBkcml2ZXJzOiBjbGs6IEFkZCBaeW5xTVAgY2xvY2sgZHJpdmVyDQo+IA0KPiBK b2xseSwNCj4gDQo+IE9uIE1vbiwgSmFuIDgsIDIwMTggYXQgMTE6MTYgUE0sIEpvbGx5IFNoYWgg PGpvbGx5LnNoYWhAeGlsaW54LmNvbT4gd3JvdGU6DQo+ID4gVGhpcyBwYXRjaCBhZGRzIENDRiBj b21wbGlhbnQgY2xvY2sgZHJpdmVyIGZvciBaeW5xTVAuDQo+ID4gQ2xvY2sgZHJpdmVyIHF1ZXJp ZXMgc3VwcG9ydGVkIGNsb2NrIGluZm9ybWF0aW9uIGZyb20NCj4gPiBmaXJtd2FyZSBhbmQgcmVn aXRlcnMgcGxsIGFuZCBvdXRwdXQgY2xvY2tzIHdpdGggQ0NGLg0KPiA+DQo+ID4gU2lnbmVkLW9m Zi1ieTogSm9sbHkgU2hhaCA8am9sbHlzQHhpbGlueC5jb20+DQo+ID4gU2lnbmVkLW9mZi1ieTog UmFqYW4gVmFqYSA8cmFqYW52QHhpbGlueC5jb20+DQo+ID4gU2lnbmVkLW9mZi1ieTogVGVqYXMg UGF0ZWwgPHRlamFzcEB4aWxpbnguY29tPg0KPiA+IFNpZ25lZC1vZmYtYnk6IFNodWJocmFqeW90 aSBEYXR0YSA8c2h1YmhyYWp5b3RpLmRhdHRhQHhpbGlueC5jb20+DQo+ID4gLS0tDQo+IA0KPiA8 c25pcD4NCj4gDQo+IA0KPiA+ICAuLi4vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay96eW5xX21w c29jLnR4dCAgICAgICB8IDE2MyArKysrKw0KPiA+ICBkcml2ZXJzL2Nsay9LY29uZmlnICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgMSArDQo+ID4gIGRyaXZlcnMvY2xrL01ha2Vm aWxlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAxICsNCj4gPiAgZHJpdmVycy9j bGsvenlucW1wL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDggKw0KPiA+ICBk cml2ZXJzL2Nsay96eW5xbXAvTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAgICB8ICAgMyAr DQo+ID4gIGRyaXZlcnMvY2xrL3p5bnFtcC9jbGstZ2F0ZS16eW5xbXAuYyAgICAgICAgICAgICAg IHwgMTU4ICsrKysrDQo+ID4gIGRyaXZlcnMvY2xrL3p5bnFtcC9jbGstbXV4LXp5bnFtcC5jICAg ICAgICAgICAgICAgIHwgMTkwICsrKysrKw0KPiA+ICBkcml2ZXJzL2Nsay96eW5xbXAvY2xrYy5j ICAgICAgICAgICAgICAgICAgICAgICAgICB8IDcwNyArKysrKysrKysrKysrKysrKysrKysNCj4g PiAgZHJpdmVycy9jbGsvenlucW1wL2RpdmlkZXIuYyAgICAgICAgICAgICAgICAgICAgICAgfCAy MzkgKysrKysrKw0KPiA+ICBkcml2ZXJzL2Nsay96eW5xbXAvcGxsLmMgICAgICAgICAgICAgICAg ICAgICAgICAgICB8IDM4NCArKysrKysrKysrKw0KPiA+ICBpbmNsdWRlL2xpbnV4L2Nsay96eW5x bXAuaCAgICAgICAgICAgICAgICAgICAgICAgICB8ICA0NiArKw0KPiA+ICAxMSBmaWxlcyBjaGFu Z2VkLCAxOTAwIGluc2VydGlvbnMoKykNCj4gPiAgY3JlYXRlIG1vZGUgMTAwNjQ0DQo+IERvY3Vt ZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9jbG9jay96eW5xX21wc29jLnR4dA0KPiA+ICBj cmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvenlucW1wL0tjb25maWcNCj4gPiAgY3JlYXRl IG1vZGUgMTAwNjQ0IGRyaXZlcnMvY2xrL3p5bnFtcC9NYWtlZmlsZQ0KPiA+ICBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9jbGsvenlucW1wL2Nsay1nYXRlLXp5bnFtcC5jDQo+ID4gIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2Nsay96eW5xbXAvY2xrLW11eC16eW5xbXAuYw0KPiA+ICBj cmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvenlucW1wL2Nsa2MuYw0KPiA+ICBjcmVhdGUg bW9kZSAxMDA2NDQgZHJpdmVycy9jbGsvenlucW1wL2RpdmlkZXIuYw0KPiA+ICBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9jbGsvenlucW1wL3BsbC5jDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0 NCBpbmNsdWRlL2xpbnV4L2Nsay96eW5xbXAuaA0KPiA+DQo= ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support 2018-01-08 22:16 [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Jolly Shah 2018-01-08 22:16 ` [RFC PATCH 1/2] drivers: clk: Add clk_get_children support Jolly Shah 2018-01-08 22:16 ` [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver Jolly Shah @ 2018-01-11 10:54 ` Sudeep Holla 2018-01-11 20:29 ` Jolly Shah 2 siblings, 1 reply; 10+ messages in thread From: Sudeep Holla @ 2018-01-11 10:54 UTC (permalink / raw) To: Jolly Shah, michal.simek, linux-clk Cc: mturquette, sboyd, Sudeep Holla, Jolly Shah, linux-kernel, linux-arm-kernel On 08/01/18 22:16, Jolly Shah wrote: > Add clock driver for ZynqMP > Can you post the complete series in one set for easy of review. It's currently broken into *6 - 8* different sets by different authors and it's extremely hard to get the full view of how these pieces are connected and extremely misleading. Can someone post them collectively as you would already have it if you are doing some testing building on each patch set. IIUC mailbox is used for all the communication, right ? If so, to start with just have 2 series one for mailbox/transport and another for the whole protocol(eemi?) and users of it. -- Regards, Sudeep ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support 2018-01-11 10:54 ` [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Sudeep Holla @ 2018-01-11 20:29 ` Jolly Shah 2018-01-12 11:47 ` Sudeep Holla 0 siblings, 1 reply; 10+ messages in thread From: Jolly Shah @ 2018-01-11 20:29 UTC (permalink / raw) To: Sudeep Holla, michal.simek@xilinx.com, linux-clk@vger.kernel.org Cc: mturquette@baylibre.com, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org SGkgU3VkZWVwLA0KDQpUaGVyZSBhcmUgMyB0aGluZ3M6DQoNCjE+IElQSSBtYWlsYm94IHRyYW5z cG9ydCAtIHNlcmllcyBpcyBhbHJlYWR5IHBvc3RlZA0KaHR0cHM6Ly9wYXRjaHdvcmsua2VybmVs Lm9yZy9wYXRjaC8xMDE0NTc5NS8NCjI+IEVFTUkgLSBQb3N0ZWQgYnkgbWUgYmVsb3cNCmh0dHBz Oi8vcGF0Y2h3b3JrLmtlcm5lbC5vcmcvcGF0Y2gvMTAxNTA2NjUvDQozPiBFRU1JIFVzZXJzDQpD dXJyZW50bHkgcG9zdGVkIGFzIFJGQyBhcyB0aGV5IGFyZSBkZXBlbmRlbnQgb24gIzIuDQoNCiMy IGRvZXNu4oCZdCB1c2UgbWFpbGJveCBzbyBpdCBpcyBhIHBvc3RlZCBhcyBhIHNlcGFyYXRlIHNl cmllcy4gDQoNClRoYW5rcywNCkpvbGx5IFNoYWgNCg0KDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNz YWdlLS0tLS0NCj4gRnJvbTogU3VkZWVwIEhvbGxhIFttYWlsdG86c3VkZWVwLmhvbGxhQGFybS5j b21dDQo+IFNlbnQ6IFRodXJzZGF5LCBKYW51YXJ5IDExLCAyMDE4IDI6NTUgQU0NCj4gVG86IEpv bGx5IFNoYWggPEpPTExZU0B4aWxpbnguY29tPjsgbWljaGFsLnNpbWVrQHhpbGlueC5jb207IGxp bnV4LQ0KPiBjbGtAdmdlci5rZXJuZWwub3JnDQo+IENjOiBtdHVycXVldHRlQGJheWxpYnJlLmNv bTsgc2JveWRAY29kZWF1cm9yYS5vcmc7IFN1ZGVlcCBIb2xsYQ0KPiA8c3VkZWVwLmhvbGxhQGFy bS5jb20+OyBKb2xseSBTaGFoIDxKT0xMWVNAeGlsaW54LmNvbT47IGxpbnV4LQ0KPiBrZXJuZWxA dmdlci5rZXJuZWwub3JnOyBsaW51eC1hcm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcNCj4g U3ViamVjdDogUmU6IFtSRkMgUEFUQ0ggMC8yXSBkcml2ZXJzOiBjbGs6IEFkZCBaeW5xTVAgY2xv Y2sgZHJpdmVyIHN1cHBvcnQNCj4gDQo+IA0KPiANCj4gT24gMDgvMDEvMTggMjI6MTYsIEpvbGx5 IFNoYWggd3JvdGU6DQo+ID4gQWRkIGNsb2NrIGRyaXZlciBmb3IgWnlucU1QDQo+ID4NCj4gDQo+ IENhbiB5b3UgcG9zdCB0aGUgY29tcGxldGUgc2VyaWVzIGluIG9uZSBzZXQgZm9yIGVhc3kgb2Yg cmV2aWV3LiBJdCdzIGN1cnJlbnRseQ0KPiBicm9rZW4gaW50byAqNiAtIDgqIGRpZmZlcmVudCBz ZXRzIGJ5IGRpZmZlcmVudCBhdXRob3JzIGFuZCBpdCdzIGV4dHJlbWVseSBoYXJkIHRvDQo+IGdl dCB0aGUgZnVsbCB2aWV3IG9mIGhvdyB0aGVzZSBwaWVjZXMgYXJlIGNvbm5lY3RlZCBhbmQgZXh0 cmVtZWx5IG1pc2xlYWRpbmcuDQo+IENhbiBzb21lb25lIHBvc3QgdGhlbSBjb2xsZWN0aXZlbHkg YXMgeW91IHdvdWxkIGFscmVhZHkgaGF2ZSBpdCBpZiB5b3UgYXJlDQo+IGRvaW5nIHNvbWUgdGVz dGluZyBidWlsZGluZyBvbiBlYWNoIHBhdGNoIHNldC4NCj4gDQo+IElJVUMgbWFpbGJveCBpcyB1 c2VkIGZvciBhbGwgdGhlIGNvbW11bmljYXRpb24sIHJpZ2h0ID8NCj4gSWYgc28sIHRvIHN0YXJ0 IHdpdGgganVzdCBoYXZlIDIgc2VyaWVzIG9uZSBmb3IgbWFpbGJveC90cmFuc3BvcnQgYW5kIGFu b3RoZXIgZm9yDQo+IHRoZSB3aG9sZSBwcm90b2NvbChlZW1pPykgYW5kIHVzZXJzIG9mIGl0Lg0K PiANCj4gLS0NCj4gUmVnYXJkcywNCj4gU3VkZWVwDQo= ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support 2018-01-11 20:29 ` Jolly Shah @ 2018-01-12 11:47 ` Sudeep Holla 2018-01-12 23:52 ` Jolly Shah 0 siblings, 1 reply; 10+ messages in thread From: Sudeep Holla @ 2018-01-12 11:47 UTC (permalink / raw) To: Jolly Shah, michal.simek@xilinx.com, linux-clk@vger.kernel.org Cc: Sudeep Holla, mturquette@baylibre.com, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org On 11/01/18 20:29, Jolly Shah wrote: > Hi Sudeep, > > There are 3 things: > > 1> IPI mailbox transport - series is already posted > https://patchwork.kernel.org/patch/10145795/ > 2> EEMI - Posted by me below > https://patchwork.kernel.org/patch/10150665/ > 3> EEMI Users > Currently posted as RFC as they are dependent on #2. > OK, can #2 and #3 can be put together until initial review ? > #2 doesn’t use mailbox so it is a posted as a separate series. OK, does it use smc ? If so, the point is treat it as smc mailbox so that smc is just a transport and EEMI can be still used with other transport technically. -- Regards, Sudeep ^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support 2018-01-12 11:47 ` Sudeep Holla @ 2018-01-12 23:52 ` Jolly Shah 0 siblings, 0 replies; 10+ messages in thread From: Jolly Shah @ 2018-01-12 23:52 UTC (permalink / raw) To: Sudeep Holla Cc: mturquette@baylibre.com, sboyd@codeaurora.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, michal.simek@xilinx.com, linux-clk@vger.kernel.org SGkgU3VkZWVwLA0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IFN1ZGVl cCBIb2xsYSBbbWFpbHRvOnN1ZGVlcC5ob2xsYUBhcm0uY29tXQ0KPiBTZW50OiBGcmlkYXksIEph bnVhcnkgMTIsIDIwMTggMzo0NyBBTQ0KPiBUbzogSm9sbHkgU2hhaCA8Sk9MTFlTQHhpbGlueC5j b20+OyBtaWNoYWwuc2ltZWtAeGlsaW54LmNvbTsgbGludXgtDQo+IGNsa0B2Z2VyLmtlcm5lbC5v cmcNCj4gQ2M6IFN1ZGVlcCBIb2xsYSA8c3VkZWVwLmhvbGxhQGFybS5jb20+OyBtdHVycXVldHRl QGJheWxpYnJlLmNvbTsNCj4gc2JveWRAY29kZWF1cm9yYS5vcmc7IGxpbnV4LWtlcm5lbEB2Z2Vy Lmtlcm5lbC5vcmc7IGxpbnV4LWFybS0NCj4ga2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcNCj4g U3ViamVjdDogUmU6IFtSRkMgUEFUQ0ggMC8yXSBkcml2ZXJzOiBjbGs6IEFkZCBaeW5xTVAgY2xv Y2sgZHJpdmVyIHN1cHBvcnQNCj4gDQo+IA0KPiANCj4gT24gMTEvMDEvMTggMjA6MjksIEpvbGx5 IFNoYWggd3JvdGU6DQo+ID4gSGkgU3VkZWVwLA0KPiA+DQo+ID4gVGhlcmUgYXJlIDMgdGhpbmdz Og0KPiA+DQo+ID4gMT4gSVBJIG1haWxib3ggdHJhbnNwb3J0IC0gc2VyaWVzIGlzIGFscmVhZHkg cG9zdGVkDQo+ID4gaHR0cHM6Ly9wYXRjaHdvcmsua2VybmVsLm9yZy9wYXRjaC8xMDE0NTc5NS8N Cj4gPiAyPiBFRU1JIC0gUG9zdGVkIGJ5IG1lIGJlbG93DQo+ID4gaHR0cHM6Ly9wYXRjaHdvcmsu a2VybmVsLm9yZy9wYXRjaC8xMDE1MDY2NS8NCj4gPiAzPiBFRU1JIFVzZXJzDQo+ID4gQ3VycmVu dGx5IHBvc3RlZCBhcyBSRkMgYXMgdGhleSBhcmUgZGVwZW5kZW50IG9uICMyLg0KPiA+IE9LLCBj YW4gIzIgYW5kICMzIGNhbiBiZSBwdXQgdG9nZXRoZXIgdW50aWwgaW5pdGlhbCByZXZpZXcgPw0K PiANCj4gPiAjMiBkb2VzbuKAmXQgdXNlIG1haWxib3ggc28gaXQgaXMgYSBwb3N0ZWQgYXMgYSBz ZXBhcmF0ZSBzZXJpZXMuDQo+IA0KPiBPSywgZG9lcyBpdCB1c2Ugc21jID8gSWYgc28sIHRoZSBw b2ludCBpcyB0cmVhdCBpdCBhcyBzbWMgbWFpbGJveCBzbyB0aGF0IHNtYyBpcyBqdXN0DQo+IGEg dHJhbnNwb3J0IGFuZCBFRU1JIGNhbiBiZSBzdGlsbCB1c2VkIHdpdGggb3RoZXIgdHJhbnNwb3J0 IHRlY2huaWNhbGx5Lg0KPiANCj4gLS0NCj4gUmVnYXJkcywNCj4gU3VkZWVwDQoNCg0KSSBhbSBu b3Qgc3VyZSBpZiBJIGdldCB5b3UgY29ycmVjdGx5LiANClllcywgRUVNSSB1c2VzIFNNQyBpbnRl cmZhY2UgdG8gY29tbXVuaWNhdGUgdG8gUE1VLiBEbyB5b3Ugc3VnZ2VzdCB0byB1c2UgQW5kcmUn cyBTTUMgbWFpbGJveCBkcml2ZXIgYXMgdHJhbnNwb3J0IGZvciBFRU1JPyANCg0KVGhhbmtzLA0K Sm9sbHkgU2hhaA0KIA0K ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2018-01-12 23:52 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-01-08 22:16 [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Jolly Shah 2018-01-08 22:16 ` [RFC PATCH 1/2] drivers: clk: Add clk_get_children support Jolly Shah 2018-01-08 22:16 ` [RFC PATCH 2/2] drivers: clk: Add ZynqMP clock driver Jolly Shah 2018-01-09 12:52 ` Philippe Ombredanne 2018-01-10 20:06 ` Jolly Shah 2018-01-10 20:15 ` Jolly Shah 2018-01-11 10:54 ` [RFC PATCH 0/2] drivers: clk: Add ZynqMP clock driver support Sudeep Holla 2018-01-11 20:29 ` Jolly Shah 2018-01-12 11:47 ` Sudeep Holla 2018-01-12 23:52 ` Jolly Shah
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox