* [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