From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from perceval.ideasonboard.com ([213.167.242.64]:40042 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725948AbeHTODK (ORCPT ); Mon, 20 Aug 2018 10:03:10 -0400 From: Laurent Pinchart To: Ulrich Hecht Cc: linux-renesas-soc@vger.kernel.org, dri-devel@lists.freedesktop.org, jacopo+renesas@jmondi.org, kieran.bingham+renesas@ideasonboard.com Subject: Re: [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support Date: Mon, 20 Aug 2018 13:48:56 +0300 Message-ID: <30096229.2ZlVbJNZoN@avalon> In-Reply-To: <1534254604-24204-5-git-send-email-uli+renesas@fpond.eu> References: <1534254604-24204-1-git-send-email-uli+renesas@fpond.eu> <1534254604-24204-5-git-send-email-uli+renesas@fpond.eu> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: Hi Ulrich, Thank you for the patch. On Tuesday, 14 August 2018 16:49:58 EEST Ulrich Hecht wrote: > In R-Car D3 and E3, the DU dot clock can be sourced from the LVDS PLL. > This patch enables that PLL if present. > > Based on patch by Koji Matsuoka . > > Signed-off-by: Ulrich Hecht > --- > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 3 + > drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 + > drivers/gpu/drm/rcar-du/rcar_du_drv.c | 3 +- > drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 + > drivers/gpu/drm/rcar-du/rcar_du_group.c | 11 +- > drivers/gpu/drm/rcar-du/rcar_lvds.c | 212 ++++++++++++++++++++++++++++ > drivers/gpu/drm/rcar-du/rcar_lvds_regs.h | 46 ++++++- The DU and LVDS encoder changes should be split in two patches. > 7 files changed, 274 insertions(+), 4 deletions(-) > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 9153e7a..a903456 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > @@ -275,6 +275,9 @@ static void rcar_du_crtc_set_display_timing(struct > rcar_du_crtc *rcrtc) mode_clock, extrate, rate, escr); > } > > + if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) > + escr = 0; > + > rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR, > escr); > rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0); > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index 7680cb2..65de551 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h > @@ -44,6 +44,7 @@ struct rcar_du_vsp; > * @group: CRTC group this CRTC belongs to > * @vsp: VSP feeding video to this CRTC > * @vsp_pipe: index of the VSP pipeline feeding video to this CRTC > + * @lvds_ch: index of LVDS > */ > struct rcar_du_crtc { > struct drm_crtc crtc; > @@ -67,6 +68,7 @@ struct rcar_du_crtc { > struct rcar_du_group *group; > struct rcar_du_vsp *vsp; > unsigned int vsp_pipe; > + int lvds_ch; This field is never set or used. > }; > > #define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc) > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c > b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index d930996..3338ef5 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c > @@ -299,7 +299,8 @@ static const struct rcar_du_device_info > rcar_du_r8a77995_info = { > .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK > | RCAR_DU_FEATURE_EXT_CTRL_REGS > | RCAR_DU_FEATURE_VSP1_SOURCE > - | RCAR_DU_FEATURE_R8A77995_REGS, > + | RCAR_DU_FEATURE_R8A77995_REGS > + | RCAR_DU_FEATURE_LVDS_PLL, > .quirks = RCAR_DU_QUIRK_TVM_MASTER_ONLY, > .channels_mask = BIT(1) | BIT(0), > .routes = { > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h > b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 9355b58..6009b7d 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h > +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h > @@ -32,6 +32,7 @@ struct rcar_du_device; > #define RCAR_DU_FEATURE_VSP1_SOURCE (1 << 2) /* Has inputs from VSP1 */ > #define RCAR_DU_FEATURE_R8A77965_REGS (1 << 3) /* Use R8A77965 registers */ > #define RCAR_DU_FEATURE_R8A77995_REGS (1 << 4) /* Use R8A77995 registers */ > +#define RCAR_DU_FEATURE_LVDS_PLL (1 << 5) /* Use PLL in LVDS */ The feature bit should tell if the LVDS encore has a PLL. Whether to use it or not should be a runtime decision. > #define RCAR_DU_QUIRK_ALIGN_128B (1 << 0) /* Align pitches to 128 bytes */ > #define RCAR_DU_QUIRK_TVM_MASTER_ONLY (1 << 1) /* Does not have TV > switch/sync modes */ diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c > b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 371d780..44681e3 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c > +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c > @@ -126,8 +126,15 @@ static void rcar_du_group_setup(struct rcar_du_group > *rgrp) * are setup through per-group registers, only available when > * the group has two channels. > */ > - if ((rcdu->info->gen < 3 && rgrp->index == 0) || > - (rcdu->info->gen == 3 && rgrp->num_crtcs > 1)) > + if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) > + rcar_du_group_write(rgrp, > + DIDSR, DIDSR_CODE | > + DIDSR_LCDS_LVDS0(1) | > + DIDSR_LCDS_LVDS0(0) | > + DIDSR_PDCS_CLK(1, 0) | > + DIDSR_PDCS_CLK(0, 0)); > + else if ((rcdu->info->gen < 3 && rgrp->index == 0) || > + (rcdu->info->gen == 3 && rgrp->num_crtcs > 1)) > rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE); > } > > diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c > b/drivers/gpu/drm/rcar-du/rcar_lvds.c index 4c39de3..cd55576 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c > +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c > @@ -23,6 +23,8 @@ > #include > > #include "rcar_lvds_regs.h" > +#include "rcar_du_crtc.h" > +#include "rcar_du_drv.h" That's a layering violation that I'd like to avoid. > /* Keep in sync with the LVDCR0.LVMD hardware register values. */ > enum rcar_lvds_mode { > @@ -65,6 +67,15 @@ struct rcar_lvds { > #define connector_to_rcar_lvds(connector) \ > container_of(connector, struct rcar_lvds, connector) > > +struct pll_info { > + unsigned int pllclk; > + unsigned int diff; > + unsigned int clk_n; > + unsigned int clk_m; > + unsigned int clk_e; > + unsigned int div; > +}; > + > static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data) > { > iowrite32(data, lvds->mmio + reg); > @@ -155,6 +166,198 @@ static u32 rcar_lvds_lvdpllcr_gen3(unsigned int freq) > return LVDPLLCR_PLLDIVCNT_148M; > } > > +static void rcar_lvds_pll_calc(struct rcar_du_crtc *rcrtc, > + struct pll_info *pll, unsigned int in_fre, > + unsigned int mode_freq, bool edivider) > +{ > + unsigned long diff = (unsigned long)-1; > + unsigned long fout, fpfd, fvco, n, m, e, div; > + bool clk_diff_set = true; > + > + if (in_fre < 12000000 || in_fre > 192000000) > + return; > + > + for (n = 0; n < 127; n++) { > + if (n + 1 < 60 || n + 1 > 120) > + continue; Seriously ? :-) > + for (m = 0; m < 7; m++) { > + for (e = 0; e < 1; e++) { > + if (edivider) > + fout = (((in_fre / 1000) * (n + 1)) / > + ((m + 1) * (e + 1) * 2)) * > + 1000; > + else > + fout = (((in_fre / 1000) * (n + 1)) / > + (m + 1)) * 1000; > + > + if (fout > 1039500000) > + continue; > + > + fpfd = (in_fre / (m + 1)); > + if (fpfd < 12000000 || fpfd > 24000000) > + continue; > + > + fvco = (((in_fre / 1000) * (n + 1)) / (m + 1)) > + * 1000; > + if (fvco < 900000000 || fvco > 1800000000) > + continue; > + > + fout = fout / 7; /* 7 divider */ > + > + for (div = 0; div < 64; div++) { That's a lot of iterations for the four nested loops, surely it can be simplified. > + diff = abs((long)(fout / (div + 1)) - > + (long)mode_freq); > + > + if (clk_diff_set || > + (diff == 0 || > + pll->diff > diff)) { > + pll->diff = diff; > + pll->clk_n = n; > + pll->clk_m = m; > + pll->clk_e = e; > + pll->pllclk = fout; > + pll->div = div; > + > + clk_diff_set = false; > + > + if (diff == 0) > + return; > + } > + } > + } > + } > + } > +} > + > +static void rcar_lvds_pll_pre_start(struct rcar_lvds *lvds, > + struct rcar_du_crtc *rcrtc) > +{ > + const struct drm_display_mode *mode = > + &rcrtc->crtc.state->adjusted_mode; > + unsigned int mode_freq = mode->clock * 1000; > + unsigned int ext_clk = 0; > + struct pll_info *lvds_pll[2]; > + u32 clksel, cksel; > + int i, ret; > + > + if (rcrtc->extclock) > + ext_clk = clk_get_rate(rcrtc->extclock); > + else > + dev_warn(lvds->dev, "external clock is not set\n"); > + > + dev_dbg(lvds->dev, "external clock %d Hz\n", ext_clk); > + > + if (lvds->enabled) > + return; > + > + for (i = 0; i < 2; i++) { > + lvds_pll[i] = kzalloc(sizeof(*lvds_pll), GFP_KERNEL); > + if (!lvds_pll[i]) > + return; Memory leak if kzalloc() fails in any but the first iteration. Why do you need dynamic allocation at all ? > + } > + > + /* software reset release */ > + reset_control_deassert(lvds->rst); > + > + ret = clk_prepare_enable(lvds->clock); > + if (ret < 0) > + goto end; > + > + for (i = 0; i < 2; i++) { > + bool edivider; > + > + if (i == 0) > + edivider = true; > + else > + edivider = false; > + > + rcar_lvds_pll_calc(rcrtc, lvds_pll[i], ext_clk, > + mode_freq, edivider); > + } > + > + dev_dbg(lvds->dev, "mode_frequency %d Hz\n", mode_freq); > + > + if (lvds_pll[1]->diff >= lvds_pll[0]->diff) { > + /* use E-edivider */ > + i = 0; > + clksel = LVDPLLCR_OUTCLKSEL_AFTER | > + LVDPLLCR_STP_CLKOUTE1_EN; > + } else { > + /* do not use E-divider */ > + i = 1; > + clksel = LVDPLLCR_OUTCLKSEL_BEFORE | > + LVDPLLCR_STP_CLKOUTE1_DIS; > + } > + dev_dbg(lvds->dev, > + "E-divider %s\n", (i == 0 ? "is used" : "is not used")); > + > + dev_dbg(lvds->dev, > + "pllclk:%u, n:%u, m:%u, e:%u, diff:%u, div:%u\n", > + lvds_pll[i]->pllclk, lvds_pll[i]->clk_n, lvds_pll[i]->clk_m, > + lvds_pll[i]->clk_e, lvds_pll[i]->diff, lvds_pll[i]->div); > + > + if (rcrtc->extal_use) > + cksel = LVDPLLCR_CKSEL_EXTAL; > + else > + cksel = LVDPLLCR_CKSEL_DU_DOTCLKIN(rcrtc->index); > + > + rcar_lvds_write(lvds, LVDPLLCR, LVDPLLCR_PLLON | > + LVDPLLCR_OCKSEL_7 | clksel | LVDPLLCR_CLKOUT_ENABLE | > + cksel | (lvds_pll[i]->clk_e << 10) | > + (lvds_pll[i]->clk_n << 3) | lvds_pll[i]->clk_m); > + > + if (lvds_pll[i]->div > 0) > + rcar_lvds_write(lvds, LVDDIV, LVDDIV_DIVSEL | > + LVDDIV_DIVRESET | lvds_pll[i]->div); > + else > + rcar_lvds_write(lvds, LVDDIV, 0); > + > + dev_dbg(lvds->dev, "LVDPLLCR: 0x%x\n", > + ioread32(lvds->mmio + LVDPLLCR)); > + dev_dbg(lvds->dev, "LVDDIV: 0x%x\n", > + ioread32(lvds->mmio + LVDDIV)); > + > +end: > + for (i = 0; i < 2; i++) > + kfree(lvds_pll[i]); > +} > + > +static void rcar_lvds_pll_start(struct rcar_lvds *lvds, > + struct rcar_du_crtc *rcrtc) > +{ > + u32 lvdhcr, lvdcr0; > + > + rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO | > + LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC | > + LVDCTRCR_CTR0SEL_HSYNC); > + > + lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1) | > + LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3); > + rcar_lvds_write(lvds, LVDCHCR, lvdhcr); > + > + rcar_lvds_write(lvds, LVDSTRIPE, 0); > + /* Turn all the channels on. */ > + rcar_lvds_write(lvds, LVDCR1, > + LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) | > + LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) | > + LVDCR1_CLKSTBY); > + /* > + * Turn the PLL on, set it to LVDS normal mode, wait for the startup > + * delay and turn the output on. > + */ > + lvdcr0 = (lvds->mode << LVDCR0_LVMD_SHIFT) | LVDCR0_PWD; > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > + > + lvdcr0 |= LVDCR0_LVEN; > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > + > + lvdcr0 |= LVDCR0_LVRES; > + rcar_lvds_write(lvds, LVDCR0, lvdcr0); > + > + lvds->enabled = true; > +} > + > static void rcar_lvds_enable(struct drm_bridge *bridge) > { > struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); > @@ -164,6 +367,7 @@ static void rcar_lvds_enable(struct drm_bridge *bridge) > * do we get a state pointer? > */ > struct drm_crtc *crtc = lvds->bridge.encoder->crtc; > + struct rcar_du_device *rcdu = to_rcar_crtc(crtc)->group->dev; > u32 lvdpllcr; > u32 lvdhcr; > u32 lvdcr0; > @@ -171,6 +375,12 @@ static void rcar_lvds_enable(struct drm_bridge *bridge) > > WARN_ON(lvds->enabled); > > + if (rcar_du_has(rcdu, RCAR_DU_FEATURE_LVDS_PLL)) { This should be turned into an LVDS encoder feature bit. > + rcar_lvds_pll_pre_start(lvds, to_rcar_crtc(crtc)); > + rcar_lvds_pll_start(lvds, to_rcar_crtc(crtc)); > + return; > + } > + > ret = clk_prepare_enable(lvds->clock); > if (ret < 0) > return; > @@ -264,6 +474,7 @@ static void rcar_lvds_disable(struct drm_bridge *bridge) > > rcar_lvds_write(lvds, LVDCR0, 0); > rcar_lvds_write(lvds, LVDCR1, 0); > + rcar_lvds_write(lvds, LVDPLLCR, 0); > > clk_disable_unprepare(lvds->clock); > > @@ -522,6 +733,7 @@ static const struct of_device_id rcar_lvds_of_table[] = > { { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info }, { > .compatible = "renesas,r8a7796-lvds", .data = &rcar_lvds_gen3_info }, { > .compatible = "renesas,r8a77970-lvds", .data = &rcar_lvds_r8a77970_info }, > + { .compatible = "renesas,r8a77995-lvds", .data = &rcar_lvds_gen3_info }, > { } > }; > > diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h > b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h index 2896835..e37db95 100644 > --- a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h > +++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h > @@ -21,7 +21,7 @@ > #define LVDCR0_PLLON (1 << 4) > #define LVDCR0_PWD (1 << 2) /* Gen3 only */ > #define LVDCR0_BEN (1 << 2) /* Gen2 only */ > -#define LVDCR0_LVEN (1 << 1) /* Gen2 only */ > +#define LVDCR0_LVEN (1 << 1) > #define LVDCR0_LVRES (1 << 0) > > #define LVDCR1 0x0004 > @@ -46,6 +46,24 @@ > #define LVDPLLCR_PLLDIVCNT_148M (0x046c1 << 0) > #define LVDPLLCR_PLLDIVCNT_MASK (0x7ffff << 0) > > +/* R-Car D3 */ > +#define LVDPLLCR_PLLON (1 << 22) > +#define LVDPLLCR_PLLSEL_PLL0 (0 << 20) > +#define LVDPLLCR_PLLSEL_LVX (1 << 20) > +#define LVDPLLCR_PLLSEL_PLL1 (2 << 20) > +#define LVDPLLCR_CKSEL_LVX (1 << 17) > +#define LVDPLLCR_CKSEL_EXTAL (3 << 17) > +#define LVDPLLCR_CKSEL_DU_DOTCLKIN0 (5 << 17) > +#define LVDPLLCR_CKSEL_DU_DOTCLKIN1 (7 << 17) > +#define LVDPLLCR_OCKSEL_7 (0 << 16) > +#define LVDPLLCR_OCKSEL_NOT_DIVIDED (1 << 16) > +#define LVDPLLCR_STP_CLKOUTE1_DIS (0 << 14) > +#define LVDPLLCR_STP_CLKOUTE1_EN (1 << 14) > +#define LVDPLLCR_OUTCLKSEL_BEFORE (0 << 12) > +#define LVDPLLCR_OUTCLKSEL_AFTER (1 << 12) > +#define LVDPLLCR_CLKOUT_DISABLE (0 << 11) > +#define LVDPLLCR_CLKOUT_ENABLE (1 << 11) > + > #define LVDCTRCR 0x000c > #define LVDCTRCR_CTR3SEL_ZERO (0 << 12) > #define LVDCTRCR_CTR3SEL_ODD (1 << 12) > @@ -74,4 +92,30 @@ > #define LVDCHCR_CHSEL_CH(n, c) ((((c) - (n)) & 3) << ((n) * 4)) > #define LVDCHCR_CHSEL_MASK(n) (3 << ((n) * 4)) > > +#define LVDSTRIPE 0x0014 > +#define LVDSTRIPE_ST_TRGSEL_DISP (0 << 2) > +#define LVDSTRIPE_ST_TRGSEL_HSYNC_R (1 << 2) > +#define LVDSTRIPE_ST_TRGSEL_HSYNC_F (2 << 2) > + > +#define LVDSTRIPE_ST_SWAP_NORMAL (0 << 1) > +#define LVDSTRIPE_ST_SWAP_SWAP (1 << 1) > +#define LVDSTRIPE_ST_ON (1 << 0) > + > +#define LVDSCR 0x0018 > +#define LVDSCR_DEPTH_DP1 (0 << 29) > +#define LVDSCR_DEPTH_DP2 (1 << 29) > +#define LVDSCR_DEPTH_DP3 (2 << 29) > +#define LVDSCR_BANDSET_10KHZ_LESS_THAN (1 << 28) > +#define LVDSCR_SDIV_SR1 (0 << 22) > +#define LVDSCR_SDIV_SR2 (1 << 22) > +#define LVDSCR_SDIV_SR4 (2 << 22) > +#define LVDSCR_SDIV_SR8 (3 << 22) > +#define LVDSCR_MODE_DOWN (1 << 21) > +#define LVDSCR_RSTN_ENABLE (1 << 20) > + > +#define LVDDIV 0x001c > +#define LVDDIV_DIVSEL (1 << 8) > +#define LVDDIV_DIVRESET (1 << 7) > +#define LVDDIV_DIVSTP (1 << 6) > + > #endif /* __RCAR_LVDS_REGS_H__ */ -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PROTO][PATCH 04/10] drm: rcar-du: lvds: LVDS PLL support Date: Mon, 20 Aug 2018 13:48:56 +0300 Message-ID: <30096229.2ZlVbJNZoN@avalon> References: <1534254604-24204-1-git-send-email-uli+renesas@fpond.eu> <1534254604-24204-5-git-send-email-uli+renesas@fpond.eu> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by gabe.freedesktop.org (Postfix) with ESMTPS id DE5566E058 for ; Mon, 20 Aug 2018 10:48:02 +0000 (UTC) In-Reply-To: <1534254604-24204-5-git-send-email-uli+renesas@fpond.eu> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Ulrich Hecht Cc: linux-renesas-soc@vger.kernel.org, kieran.bingham+renesas@ideasonboard.com, jacopo+renesas@jmondi.org, dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org SGkgVWxyaWNoLAoKVGhhbmsgeW91IGZvciB0aGUgcGF0Y2guCgpPbiBUdWVzZGF5LCAxNCBBdWd1 c3QgMjAxOCAxNjo0OTo1OCBFRVNUIFVscmljaCBIZWNodCB3cm90ZToKPiBJbiBSLUNhciBEMyBh bmQgRTMsIHRoZSBEVSBkb3QgY2xvY2sgY2FuIGJlIHNvdXJjZWQgZnJvbSB0aGUgTFZEUyBQTEwu Cj4gVGhpcyBwYXRjaCBlbmFibGVzIHRoYXQgUExMIGlmIHByZXNlbnQuCj4gCj4gQmFzZWQgb24g cGF0Y2ggYnkgS29qaSBNYXRzdW9rYSA8a29qaS5tYXRzdW9rYS54bUByZW5lc2FzLmNvbT4uCj4g Cj4gU2lnbmVkLW9mZi1ieTogVWxyaWNoIEhlY2h0IDx1bGkrcmVuZXNhc0BmcG9uZC5ldT4KPiAt LS0KPiAgZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9jcnRjLmMgICB8ICAgMyArCj4g IGRyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfY3J0Yy5oICAgfCAgIDIgKwo+ICBkcml2 ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2Rydi5jICAgIHwgICAzICstCj4gIGRyaXZlcnMv Z3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfZHJ2LmggICAgfCAgIDEgKwo+ICBkcml2ZXJzL2dwdS9k cm0vcmNhci1kdS9yY2FyX2R1X2dyb3VwLmMgIHwgIDExICstCj4gIGRyaXZlcnMvZ3B1L2RybS9y Y2FyLWR1L3JjYXJfbHZkcy5jICAgICAgfCAyMTIgKysrKysrKysrKysrKysrKysrKysrKysrKysr Kwo+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2x2ZHNfcmVncy5oIHwgIDQ2ICsrKysr Ky0KClRoZSBEVSBhbmQgTFZEUyBlbmNvZGVyIGNoYW5nZXMgc2hvdWxkIGJlIHNwbGl0IGluIHR3 byBwYXRjaGVzLgoKPiAgNyBmaWxlcyBjaGFuZ2VkLCAyNzQgaW5zZXJ0aW9ucygrKSwgNCBkZWxl dGlvbnMoLSkKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9k dV9jcnRjLmMKPiBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfY3J0Yy5jIGluZGV4 IDkxNTNlN2EuLmE5MDM0NTYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUv cmNhcl9kdV9jcnRjLmMKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2Ny dGMuYwo+IEBAIC0yNzUsNiArMjc1LDkgQEAgc3RhdGljIHZvaWQgcmNhcl9kdV9jcnRjX3NldF9k aXNwbGF5X3RpbWluZyhzdHJ1Y3QKPiByY2FyX2R1X2NydGMgKnJjcnRjKSBtb2RlX2Nsb2NrLCBl eHRyYXRlLCByYXRlLCBlc2NyKTsKPiAgCX0KPiAKPiArCWlmIChyY2FyX2R1X2hhcyhyY2R1LCBS Q0FSX0RVX0ZFQVRVUkVfTFZEU19QTEwpKQo+ICsJCWVzY3IgPSAwOwo+ICsKPiAgCXJjYXJfZHVf Z3JvdXBfd3JpdGUocmNydGMtPmdyb3VwLCByY3J0Yy0+aW5kZXggJSAyID8gRVNDUjIgOiBFU0NS LAo+ICAJCQkgICAgZXNjcik7Cj4gIAlyY2FyX2R1X2dyb3VwX3dyaXRlKHJjcnRjLT5ncm91cCwg cmNydGMtPmluZGV4ICUgMiA/IE9UQVIyIDogT1RBUiwgMCk7Cj4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfY3J0Yy5oCj4gYi9kcml2ZXJzL2dwdS9kcm0vcmNh ci1kdS9yY2FyX2R1X2NydGMuaCBpbmRleCA3NjgwY2IyLi42NWRlNTUxIDEwMDY0NAo+IC0tLSBh L2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfY3J0Yy5oCj4gKysrIGIvZHJpdmVycy9n cHUvZHJtL3JjYXItZHUvcmNhcl9kdV9jcnRjLmgKPiBAQCAtNDQsNiArNDQsNyBAQCBzdHJ1Y3Qg cmNhcl9kdV92c3A7Cj4gICAqIEBncm91cDogQ1JUQyBncm91cCB0aGlzIENSVEMgYmVsb25ncyB0 bwo+ICAgKiBAdnNwOiBWU1AgZmVlZGluZyB2aWRlbyB0byB0aGlzIENSVEMKPiAgICogQHZzcF9w aXBlOiBpbmRleCBvZiB0aGUgVlNQIHBpcGVsaW5lIGZlZWRpbmcgdmlkZW8gdG8gdGhpcyBDUlRD Cj4gKyAqIEBsdmRzX2NoOiBpbmRleCBvZiBMVkRTCj4gICAqLwo+ICBzdHJ1Y3QgcmNhcl9kdV9j cnRjIHsKPiAgCXN0cnVjdCBkcm1fY3J0YyBjcnRjOwo+IEBAIC02Nyw2ICs2OCw3IEBAIHN0cnVj dCByY2FyX2R1X2NydGMgewo+ICAJc3RydWN0IHJjYXJfZHVfZ3JvdXAgKmdyb3VwOwo+ICAJc3Ry dWN0IHJjYXJfZHVfdnNwICp2c3A7Cj4gIAl1bnNpZ25lZCBpbnQgdnNwX3BpcGU7Cj4gKwlpbnQg bHZkc19jaDsKClRoaXMgZmllbGQgaXMgbmV2ZXIgc2V0IG9yIHVzZWQuCgo+ICB9Owo+IAo+ICAj ZGVmaW5lIHRvX3JjYXJfY3J0YyhjKQljb250YWluZXJfb2YoYywgc3RydWN0IHJjYXJfZHVfY3J0 YywgY3J0YykKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9k cnYuYwo+IGIvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9kcnYuYyBpbmRleCBkOTMw OTk2Li4zMzM4ZWY1IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJf ZHVfZHJ2LmMKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2R1X2Rydi5jCj4g QEAgLTI5OSw3ICsyOTksOCBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHJjYXJfZHVfZGV2aWNlX2lu Zm8KPiByY2FyX2R1X3I4YTc3OTk1X2luZm8gPSB7Cj4gIAkuZmVhdHVyZXMgPSBSQ0FSX0RVX0ZF QVRVUkVfQ1JUQ19JUlFfQ0xPQ0sKPiAgCQkgIHwgUkNBUl9EVV9GRUFUVVJFX0VYVF9DVFJMX1JF R1MKPiAgCQkgIHwgUkNBUl9EVV9GRUFUVVJFX1ZTUDFfU09VUkNFCj4gLQkJICB8IFJDQVJfRFVf RkVBVFVSRV9SOEE3Nzk5NV9SRUdTLAo+ICsJCSAgfCBSQ0FSX0RVX0ZFQVRVUkVfUjhBNzc5OTVf UkVHUwo+ICsJCSAgfCBSQ0FSX0RVX0ZFQVRVUkVfTFZEU19QTEwsCj4gIAkucXVpcmtzID0gUkNB Ul9EVV9RVUlSS19UVk1fTUFTVEVSX09OTFksCj4gIAkuY2hhbm5lbHNfbWFzayA9IEJJVCgxKSB8 IEJJVCgwKSwKPiAgCS5yb3V0ZXMgPSB7Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9y Y2FyLWR1L3JjYXJfZHVfZHJ2LmgKPiBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVf ZHJ2LmggaW5kZXggOTM1NWI1OC4uNjAwOWI3ZCAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dwdS9k cm0vcmNhci1kdS9yY2FyX2R1X2Rydi5oCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUv cmNhcl9kdV9kcnYuaAo+IEBAIC0zMiw2ICszMiw3IEBAIHN0cnVjdCByY2FyX2R1X2RldmljZTsK PiAgI2RlZmluZSBSQ0FSX0RVX0ZFQVRVUkVfVlNQMV9TT1VSQ0UJKDEgPDwgMikJLyogSGFzIGlu cHV0cyBmcm9tIFZTUDEgKi8KPiAgI2RlZmluZSBSQ0FSX0RVX0ZFQVRVUkVfUjhBNzc5NjVfUkVH UwkoMSA8PCAzKQkvKiBVc2UgUjhBNzc5NjUgcmVnaXN0ZXJzIAoqLwo+ICNkZWZpbmUgUkNBUl9E VV9GRUFUVVJFX1I4QTc3OTk1X1JFR1MJKDEgPDwgNCkJLyogVXNlIFI4QTc3OTk1IHJlZ2lzdGVy cyAKKi8KPiArI2RlZmluZSBSQ0FSX0RVX0ZFQVRVUkVfTFZEU19QTEwJKDEgPDwgNSkJLyogVXNl IFBMTCBpbiBMVkRTICovCgpUaGUgZmVhdHVyZSBiaXQgc2hvdWxkIHRlbGwgaWYgdGhlIExWRFMg ZW5jb3JlIGhhcyBhIFBMTC4gV2hldGhlciB0byB1c2UgaXQgb3IgCm5vdCBzaG91bGQgYmUgYSBy dW50aW1lIGRlY2lzaW9uLgoKPiAgI2RlZmluZSBSQ0FSX0RVX1FVSVJLX0FMSUdOXzEyOEIJKDEg PDwgMCkJLyogQWxpZ24gcGl0Y2hlcyB0byAxMjggYnl0ZXMgCiovCj4gICNkZWZpbmUgUkNBUl9E VV9RVUlSS19UVk1fTUFTVEVSX09OTFkJKDEgPDwgMSkJLyogRG9lcyBub3QgaGF2ZSBUVgo+IHN3 aXRjaC9zeW5jIG1vZGVzICovIGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9y Y2FyX2R1X2dyb3VwLmMKPiBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVfZ3JvdXAu YyBpbmRleCAzNzFkNzgwLi40NDY4MWUzIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9y Y2FyLWR1L3JjYXJfZHVfZ3JvdXAuYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3Jj YXJfZHVfZ3JvdXAuYwo+IEBAIC0xMjYsOCArMTI2LDE1IEBAIHN0YXRpYyB2b2lkIHJjYXJfZHVf Z3JvdXBfc2V0dXAoc3RydWN0IHJjYXJfZHVfZ3JvdXAKPiAqcmdycCkgKiBhcmUgc2V0dXAgdGhy b3VnaCBwZXItZ3JvdXAgcmVnaXN0ZXJzLCBvbmx5IGF2YWlsYWJsZSB3aGVuCj4gIAkJICogdGhl IGdyb3VwIGhhcyB0d28gY2hhbm5lbHMuCj4gIAkJICovCj4gLQkJaWYgKChyY2R1LT5pbmZvLT5n ZW4gPCAzICYmIHJncnAtPmluZGV4ID09IDApIHx8Cj4gLQkJICAgIChyY2R1LT5pbmZvLT5nZW4g PT0gMyAmJiAgcmdycC0+bnVtX2NydGNzID4gMSkpCj4gKwkJaWYgKHJjYXJfZHVfaGFzKHJjZHUs IFJDQVJfRFVfRkVBVFVSRV9MVkRTX1BMTCkpCj4gKwkJCXJjYXJfZHVfZ3JvdXBfd3JpdGUocmdy cCwKPiArCQkJCQkgICAgRElEU1IsIERJRFNSX0NPREUgfAo+ICsJCQkJCSAgICBESURTUl9MQ0RT X0xWRFMwKDEpIHwKPiArCQkJCQkgICAgRElEU1JfTENEU19MVkRTMCgwKSB8Cj4gKwkJCQkJICAg IERJRFNSX1BEQ1NfQ0xLKDEsIDApIHwKPiArCQkJCQkgICAgRElEU1JfUERDU19DTEsoMCwgMCkp Owo+ICsJCWVsc2UgaWYgKChyY2R1LT5pbmZvLT5nZW4gPCAzICYmIHJncnAtPmluZGV4ID09IDAp IHx8Cj4gKwkJCSAocmNkdS0+aW5mby0+Z2VuID09IDMgJiYgIHJncnAtPm51bV9jcnRjcyA+IDEp KQo+ICAJCQlyY2FyX2R1X2dyb3VwX3dyaXRlKHJncnAsIERJRFNSLCBESURTUl9DT0RFKTsKPiAg CX0KPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9sdmRzLmMK PiBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfbHZkcy5jIGluZGV4IDRjMzlkZTMuLmNk NTU1NzYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9sdmRzLmMK PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2FyX2x2ZHMuYwo+IEBAIC0yMyw2ICsy Myw4IEBACj4gICNpbmNsdWRlIDxkcm0vZHJtX3BhbmVsLmg+Cj4gCj4gICNpbmNsdWRlICJyY2Fy X2x2ZHNfcmVncy5oIgo+ICsjaW5jbHVkZSAicmNhcl9kdV9jcnRjLmgiCj4gKyNpbmNsdWRlICJy Y2FyX2R1X2Rydi5oIgoKVGhhdCdzIGEgbGF5ZXJpbmcgdmlvbGF0aW9uIHRoYXQgSSdkIGxpa2Ug dG8gYXZvaWQuCgo+ICAvKiBLZWVwIGluIHN5bmMgd2l0aCB0aGUgTFZEQ1IwLkxWTUQgaGFyZHdh cmUgcmVnaXN0ZXIgdmFsdWVzLiAqLwo+ICBlbnVtIHJjYXJfbHZkc19tb2RlIHsKPiBAQCAtNjUs NiArNjcsMTUgQEAgc3RydWN0IHJjYXJfbHZkcyB7Cj4gICNkZWZpbmUgY29ubmVjdG9yX3RvX3Jj YXJfbHZkcyhjb25uZWN0b3IpIFwKPiAgCWNvbnRhaW5lcl9vZihjb25uZWN0b3IsIHN0cnVjdCBy Y2FyX2x2ZHMsIGNvbm5lY3RvcikKPiAKPiArc3RydWN0IHBsbF9pbmZvIHsKPiArCXVuc2lnbmVk IGludCBwbGxjbGs7Cj4gKwl1bnNpZ25lZCBpbnQgZGlmZjsKPiArCXVuc2lnbmVkIGludCBjbGtf bjsKPiArCXVuc2lnbmVkIGludCBjbGtfbTsKPiArCXVuc2lnbmVkIGludCBjbGtfZTsKPiArCXVu c2lnbmVkIGludCBkaXY7Cj4gK307Cj4gKwo+ICBzdGF0aWMgdm9pZCByY2FyX2x2ZHNfd3JpdGUo c3RydWN0IHJjYXJfbHZkcyAqbHZkcywgdTMyIHJlZywgdTMyIGRhdGEpCj4gIHsKPiAgCWlvd3Jp dGUzMihkYXRhLCBsdmRzLT5tbWlvICsgcmVnKTsKPiBAQCAtMTU1LDYgKzE2NiwxOTggQEAgc3Rh dGljIHUzMiByY2FyX2x2ZHNfbHZkcGxsY3JfZ2VuMyh1bnNpZ25lZCBpbnQgZnJlcSkKPiAgCQly ZXR1cm4gTFZEUExMQ1JfUExMRElWQ05UXzE0OE07Cj4gIH0KPiAKPiArc3RhdGljIHZvaWQgcmNh cl9sdmRzX3BsbF9jYWxjKHN0cnVjdCByY2FyX2R1X2NydGMgKnJjcnRjLAo+ICsJCQkJICAgICBz dHJ1Y3QgcGxsX2luZm8gKnBsbCwgdW5zaWduZWQgaW50IGluX2ZyZSwKPiArCQkJCSAgICAgdW5z aWduZWQgaW50IG1vZGVfZnJlcSwgYm9vbCBlZGl2aWRlcikKPiArewo+ICsJdW5zaWduZWQgbG9u ZyBkaWZmID0gKHVuc2lnbmVkIGxvbmcpLTE7Cj4gKwl1bnNpZ25lZCBsb25nIGZvdXQsIGZwZmQs IGZ2Y28sIG4sIG0sIGUsIGRpdjsKPiArCWJvb2wgY2xrX2RpZmZfc2V0ID0gdHJ1ZTsKPiArCj4g KwlpZiAoaW5fZnJlIDwgMTIwMDAwMDAgfHwgaW5fZnJlID4gMTkyMDAwMDAwKQo+ICsJCXJldHVy bjsKPiArCj4gKwlmb3IgKG4gPSAwOyBuIDwgMTI3OyBuKyspIHsKPiArCQlpZiAobiArIDEgPCA2 MCB8fCBuICsgMSA+IDEyMCkKPiArCQkJY29udGludWU7CgpTZXJpb3VzbHkgPyA6LSkKCj4gKwkJ Zm9yIChtID0gMDsgbSA8IDc7IG0rKykgewo+ICsJCQlmb3IgKGUgPSAwOyBlIDwgMTsgZSsrKSB7 Cj4gKwkJCQlpZiAoZWRpdmlkZXIpCj4gKwkJCQkJZm91dCA9ICgoKGluX2ZyZSAvIDEwMDApICog KG4gKyAxKSkgLwo+ICsJCQkJCQkoKG0gKyAxKSAqIChlICsgMSkgKiAyKSkgKgo+ICsJCQkJCQkx MDAwOwo+ICsJCQkJZWxzZQo+ICsJCQkJCWZvdXQgPSAoKChpbl9mcmUgLyAxMDAwKSAqIChuICsg MSkpIC8KPiArCQkJCQkJKG0gKyAxKSkgKiAxMDAwOwo+ICsKPiArCQkJCWlmIChmb3V0ID4gMTAz OTUwMDAwMCkKPiArCQkJCQljb250aW51ZTsKPiArCj4gKwkJCQlmcGZkICA9IChpbl9mcmUgLyAo bSArIDEpKTsKPiArCQkJCWlmIChmcGZkIDwgMTIwMDAwMDAgfHwgZnBmZCA+IDI0MDAwMDAwKQo+ ICsJCQkJCWNvbnRpbnVlOwo+ICsKPiArCQkJCWZ2Y28gID0gKCgoaW5fZnJlIC8gMTAwMCkgKiAo biArIDEpKSAvIChtICsgMSkpCj4gKwkJCQkJICogMTAwMDsKPiArCQkJCWlmIChmdmNvIDwgOTAw MDAwMDAwIHx8IGZ2Y28gPiAxODAwMDAwMDAwKQo+ICsJCQkJCWNvbnRpbnVlOwo+ICsKPiArCQkJ CWZvdXQgPSBmb3V0IC8gNzsgLyogNyBkaXZpZGVyICovCj4gKwo+ICsJCQkJZm9yIChkaXYgPSAw OyBkaXYgPCA2NDsgZGl2KyspIHsKClRoYXQncyBhIGxvdCBvZiBpdGVyYXRpb25zIGZvciB0aGUg Zm91ciBuZXN0ZWQgbG9vcHMsIHN1cmVseSBpdCBjYW4gYmUgCnNpbXBsaWZpZWQuCgo+ICsJCQkJ CWRpZmYgPSBhYnMoKGxvbmcpKGZvdXQgLyAoZGl2ICsgMSkpIC0KPiArCQkJCQkgICAgICAgKGxv bmcpbW9kZV9mcmVxKTsKPiArCj4gKwkJCQkJaWYgKGNsa19kaWZmX3NldCB8fAo+ICsJCQkJCSAg ICAoZGlmZiA9PSAwIHx8Cj4gKwkJCQkJICAgIHBsbC0+ZGlmZiA+IGRpZmYpKSB7Cj4gKwkJCQkJ CXBsbC0+ZGlmZiA9IGRpZmY7Cj4gKwkJCQkJCXBsbC0+Y2xrX24gPSBuOwo+ICsJCQkJCQlwbGwt PmNsa19tID0gbTsKPiArCQkJCQkJcGxsLT5jbGtfZSA9IGU7Cj4gKwkJCQkJCXBsbC0+cGxsY2xr ID0gZm91dDsKPiArCQkJCQkJcGxsLT5kaXYgPSBkaXY7Cj4gKwo+ICsJCQkJCQljbGtfZGlmZl9z ZXQgPSBmYWxzZTsKPiArCj4gKwkJCQkJCWlmIChkaWZmID09IDApCj4gKwkJCQkJCQlyZXR1cm47 Cj4gKwkJCQkJfQo+ICsJCQkJfQo+ICsJCQl9Cj4gKwkJfQo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0 aWMgdm9pZCByY2FyX2x2ZHNfcGxsX3ByZV9zdGFydChzdHJ1Y3QgcmNhcl9sdmRzICpsdmRzLAo+ ICsJCQkJICAgIHN0cnVjdCByY2FyX2R1X2NydGMgKnJjcnRjKQo+ICt7Cj4gKwljb25zdCBzdHJ1 Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSA9Cj4gKwkJCQkmcmNydGMtPmNydGMuc3RhdGUtPmFk anVzdGVkX21vZGU7Cj4gKwl1bnNpZ25lZCBpbnQgbW9kZV9mcmVxID0gbW9kZS0+Y2xvY2sgKiAx MDAwOwo+ICsJdW5zaWduZWQgaW50IGV4dF9jbGsgPSAwOwo+ICsJc3RydWN0IHBsbF9pbmZvICps dmRzX3BsbFsyXTsKPiArCXUzMiBjbGtzZWwsIGNrc2VsOwo+ICsJaW50IGksIHJldDsKPiArCj4g KwlpZiAocmNydGMtPmV4dGNsb2NrKQo+ICsJCWV4dF9jbGsgPSBjbGtfZ2V0X3JhdGUocmNydGMt PmV4dGNsb2NrKTsKPiArCWVsc2UKPiArCQlkZXZfd2FybihsdmRzLT5kZXYsICJleHRlcm5hbCBj bG9jayBpcyBub3Qgc2V0XG4iKTsKPiArCj4gKwlkZXZfZGJnKGx2ZHMtPmRldiwgImV4dGVybmFs IGNsb2NrICVkIEh6XG4iLCBleHRfY2xrKTsKPiArCj4gKwlpZiAobHZkcy0+ZW5hYmxlZCkKPiAr CQlyZXR1cm47Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewo+ICsJCWx2ZHNfcGxs W2ldID0ga3phbGxvYyhzaXplb2YoKmx2ZHNfcGxsKSwgR0ZQX0tFUk5FTCk7Cj4gKwkJaWYgKCFs dmRzX3BsbFtpXSkKPiArCQkJcmV0dXJuOwoKTWVtb3J5IGxlYWsgaWYga3phbGxvYygpIGZhaWxz IGluIGFueSBidXQgdGhlIGZpcnN0IGl0ZXJhdGlvbi4KCldoeSBkbyB5b3UgbmVlZCBkeW5hbWlj IGFsbG9jYXRpb24gYXQgYWxsID8KCj4gKwl9Cj4gKwo+ICsJLyogc29mdHdhcmUgcmVzZXQgcmVs ZWFzZSAqLwo+ICsJcmVzZXRfY29udHJvbF9kZWFzc2VydChsdmRzLT5yc3QpOwo+ICsKPiArCXJl dCA9IGNsa19wcmVwYXJlX2VuYWJsZShsdmRzLT5jbG9jayk7Cj4gKwlpZiAocmV0IDwgMCkKPiAr CQlnb3RvIGVuZDsKPiArCj4gKwlmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7Cj4gKwkJYm9vbCBl ZGl2aWRlcjsKPiArCj4gKwkJaWYgKGkgPT0gMCkKPiArCQkJZWRpdmlkZXIgPSB0cnVlOwo+ICsJ CWVsc2UKPiArCQkJZWRpdmlkZXIgPSBmYWxzZTsKPiArCj4gKwkJcmNhcl9sdmRzX3BsbF9jYWxj KHJjcnRjLCBsdmRzX3BsbFtpXSwgZXh0X2NsaywKPiArCQkJCQkgbW9kZV9mcmVxLCBlZGl2aWRl cik7Cj4gKwl9Cj4gKwo+ICsJZGV2X2RiZyhsdmRzLT5kZXYsICJtb2RlX2ZyZXF1ZW5jeSAlZCBI elxuIiwgbW9kZV9mcmVxKTsKPiArCj4gKwlpZiAobHZkc19wbGxbMV0tPmRpZmYgPj0gbHZkc19w bGxbMF0tPmRpZmYpIHsKPiArCQkvKiB1c2UgRS1lZGl2aWRlciAqLwo+ICsJCWkgPSAwOwo+ICsJ CWNsa3NlbCA9IExWRFBMTENSX09VVENMS1NFTF9BRlRFUiB8Cj4gKwkJCSBMVkRQTExDUl9TVFBf Q0xLT1VURTFfRU47Cj4gKwl9IGVsc2Ugewo+ICsJCS8qIGRvIG5vdCB1c2UgRS1kaXZpZGVyICov Cj4gKwkJaSA9IDE7Cj4gKwkJY2xrc2VsID0gTFZEUExMQ1JfT1VUQ0xLU0VMX0JFRk9SRSB8Cj4g KwkJCSBMVkRQTExDUl9TVFBfQ0xLT1VURTFfRElTOwo+ICsJfQo+ICsJZGV2X2RiZyhsdmRzLT5k ZXYsCj4gKwkJIkUtZGl2aWRlciAlc1xuIiwgKGkgPT0gMCA/ICJpcyB1c2VkIiA6ICJpcyBub3Qg dXNlZCIpKTsKPiArCj4gKwlkZXZfZGJnKGx2ZHMtPmRldiwKPiArCQkicGxsY2xrOiV1LCBuOiV1 LCBtOiV1LCBlOiV1LCBkaWZmOiV1LCBkaXY6JXVcbiIsCj4gKwkJIGx2ZHNfcGxsW2ldLT5wbGxj bGssIGx2ZHNfcGxsW2ldLT5jbGtfbiwgbHZkc19wbGxbaV0tPmNsa19tLAo+ICsJCSBsdmRzX3Bs bFtpXS0+Y2xrX2UsIGx2ZHNfcGxsW2ldLT5kaWZmLCBsdmRzX3BsbFtpXS0+ZGl2KTsKPiArCj4g KwlpZiAocmNydGMtPmV4dGFsX3VzZSkKPiArCQlja3NlbCA9IExWRFBMTENSX0NLU0VMX0VYVEFM Owo+ICsJZWxzZQo+ICsJCWNrc2VsID0gTFZEUExMQ1JfQ0tTRUxfRFVfRE9UQ0xLSU4ocmNydGMt PmluZGV4KTsKPiArCj4gKwlyY2FyX2x2ZHNfd3JpdGUobHZkcywgTFZEUExMQ1IsIExWRFBMTENS X1BMTE9OIHwKPiArCQkJTFZEUExMQ1JfT0NLU0VMXzcgfCBjbGtzZWwgfCBMVkRQTExDUl9DTEtP VVRfRU5BQkxFIHwKPiArCQkJY2tzZWwgfCAobHZkc19wbGxbaV0tPmNsa19lIDw8IDEwKSB8Cj4g KwkJCShsdmRzX3BsbFtpXS0+Y2xrX24gPDwgMykgfCBsdmRzX3BsbFtpXS0+Y2xrX20pOwo+ICsK PiArCWlmIChsdmRzX3BsbFtpXS0+ZGl2ID4gMCkKPiArCQlyY2FyX2x2ZHNfd3JpdGUobHZkcywg TFZERElWLCBMVkRESVZfRElWU0VMIHwKPiArCQkJCUxWRERJVl9ESVZSRVNFVCB8IGx2ZHNfcGxs W2ldLT5kaXYpOwo+ICsJZWxzZQo+ICsJCXJjYXJfbHZkc193cml0ZShsdmRzLCBMVkRESVYsIDAp Owo+ICsKPiArCWRldl9kYmcobHZkcy0+ZGV2LCAiTFZEUExMQ1I6IDB4JXhcbiIsCj4gKwkJaW9y ZWFkMzIobHZkcy0+bW1pbyArIExWRFBMTENSKSk7Cj4gKwlkZXZfZGJnKGx2ZHMtPmRldiwgIkxW RERJVjogMHgleFxuIiwKPiArCQlpb3JlYWQzMihsdmRzLT5tbWlvICsgTFZERElWKSk7Cj4gKwo+ ICtlbmQ6Cj4gKwlmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKQo+ICsJCWtmcmVlKGx2ZHNfcGxsW2ld KTsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgcmNhcl9sdmRzX3BsbF9zdGFydChzdHJ1Y3QgcmNh cl9sdmRzICpsdmRzLAo+ICsJCQkgICAgICAgc3RydWN0IHJjYXJfZHVfY3J0YyAqcmNydGMpCj4g K3sKPiArCXUzMiBsdmRoY3IsIGx2ZGNyMDsKPiArCj4gKwlyY2FyX2x2ZHNfd3JpdGUobHZkcywg TFZEQ1RSQ1IsIExWRENUUkNSX0NUUjNTRUxfWkVSTyB8Cj4gKwkJCUxWRENUUkNSX0NUUjJTRUxf RElTUCB8IExWRENUUkNSX0NUUjFTRUxfVlNZTkMgfAo+ICsJCQlMVkRDVFJDUl9DVFIwU0VMX0hT WU5DKTsKPiArCj4gKwlsdmRoY3IgPSBMVkRDSENSX0NIU0VMX0NIKDAsIDApIHwgTFZEQ0hDUl9D SFNFTF9DSCgxLCAxKSB8Cj4gKwkJIExWRENIQ1JfQ0hTRUxfQ0goMiwgMikgfCBMVkRDSENSX0NI U0VMX0NIKDMsIDMpOwo+ICsJcmNhcl9sdmRzX3dyaXRlKGx2ZHMsIExWRENIQ1IsIGx2ZGhjcik7 Cj4gKwo+ICsJcmNhcl9sdmRzX3dyaXRlKGx2ZHMsIExWRFNUUklQRSwgMCk7Cj4gKwkvKiBUdXJu IGFsbCB0aGUgY2hhbm5lbHMgb24uICovCj4gKwlyY2FyX2x2ZHNfd3JpdGUobHZkcywgTFZEQ1Ix LAo+ICsJCQlMVkRDUjFfQ0hTVEJZKDMpIHwgTFZEQ1IxX0NIU1RCWSgyKSB8Cj4gKwkJCUxWRENS MV9DSFNUQlkoMSkgfCBMVkRDUjFfQ0hTVEJZKDApIHwKPiArCQkJTFZEQ1IxX0NMS1NUQlkpOwo+ ICsJLyoKPiArCSAqIFR1cm4gdGhlIFBMTCBvbiwgc2V0IGl0IHRvIExWRFMgbm9ybWFsIG1vZGUs IHdhaXQgZm9yIHRoZSBzdGFydHVwCj4gKwkgKiBkZWxheSBhbmQgdHVybiB0aGUgb3V0cHV0IG9u Lgo+ICsJICovCj4gKwlsdmRjcjAgPSAobHZkcy0+bW9kZSA8PCBMVkRDUjBfTFZNRF9TSElGVCkg fCBMVkRDUjBfUFdEOwo+ICsJcmNhcl9sdmRzX3dyaXRlKGx2ZHMsIExWRENSMCwgbHZkY3IwKTsK PiArCj4gKwlsdmRjcjAgfD0gTFZEQ1IwX0xWRU47Cj4gKwlyY2FyX2x2ZHNfd3JpdGUobHZkcywg TFZEQ1IwLCBsdmRjcjApOwo+ICsKPiArCWx2ZGNyMCB8PSBMVkRDUjBfTFZSRVM7Cj4gKwlyY2Fy X2x2ZHNfd3JpdGUobHZkcywgTFZEQ1IwLCBsdmRjcjApOwo+ICsKPiArCWx2ZHMtPmVuYWJsZWQg PSB0cnVlOwo+ICt9Cj4gKwo+ICBzdGF0aWMgdm9pZCByY2FyX2x2ZHNfZW5hYmxlKHN0cnVjdCBk cm1fYnJpZGdlICpicmlkZ2UpCj4gIHsKPiAgCXN0cnVjdCByY2FyX2x2ZHMgKmx2ZHMgPSBicmlk Z2VfdG9fcmNhcl9sdmRzKGJyaWRnZSk7Cj4gQEAgLTE2NCw2ICszNjcsNyBAQCBzdGF0aWMgdm9p ZCByY2FyX2x2ZHNfZW5hYmxlKHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UpCj4gIAkgKiBkbyB3 ZSBnZXQgYSBzdGF0ZSBwb2ludGVyPwo+ICAJICovCj4gIAlzdHJ1Y3QgZHJtX2NydGMgKmNydGMg PSBsdmRzLT5icmlkZ2UuZW5jb2Rlci0+Y3J0YzsKPiArCXN0cnVjdCByY2FyX2R1X2RldmljZSAq cmNkdSA9IHRvX3JjYXJfY3J0YyhjcnRjKS0+Z3JvdXAtPmRldjsKPiAgCXUzMiBsdmRwbGxjcjsK PiAgCXUzMiBsdmRoY3I7Cj4gIAl1MzIgbHZkY3IwOwo+IEBAIC0xNzEsNiArMzc1LDEyIEBAIHN0 YXRpYyB2b2lkIHJjYXJfbHZkc19lbmFibGUoc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZSkKPiAK PiAgCVdBUk5fT04obHZkcy0+ZW5hYmxlZCk7Cj4gCj4gKwlpZiAocmNhcl9kdV9oYXMocmNkdSwg UkNBUl9EVV9GRUFUVVJFX0xWRFNfUExMKSkgewoKVGhpcyBzaG91bGQgYmUgdHVybmVkIGludG8g YW4gTFZEUyBlbmNvZGVyIGZlYXR1cmUgYml0LgoKPiArCQlyY2FyX2x2ZHNfcGxsX3ByZV9zdGFy dChsdmRzLCB0b19yY2FyX2NydGMoY3J0YykpOwo+ICsJCXJjYXJfbHZkc19wbGxfc3RhcnQobHZk cywgdG9fcmNhcl9jcnRjKGNydGMpKTsKPiArCQlyZXR1cm47Cj4gKwl9Cj4gKwo+ICAJcmV0ID0g Y2xrX3ByZXBhcmVfZW5hYmxlKGx2ZHMtPmNsb2NrKTsKPiAgCWlmIChyZXQgPCAwKQo+ICAJCXJl dHVybjsKPiBAQCAtMjY0LDYgKzQ3NCw3IEBAIHN0YXRpYyB2b2lkIHJjYXJfbHZkc19kaXNhYmxl KHN0cnVjdCBkcm1fYnJpZGdlICpicmlkZ2UpCj4gCj4gIAlyY2FyX2x2ZHNfd3JpdGUobHZkcywg TFZEQ1IwLCAwKTsKPiAgCXJjYXJfbHZkc193cml0ZShsdmRzLCBMVkRDUjEsIDApOwo+ICsJcmNh cl9sdmRzX3dyaXRlKGx2ZHMsIExWRFBMTENSLCAwKTsKPiAKPiAgCWNsa19kaXNhYmxlX3VucHJl cGFyZShsdmRzLT5jbG9jayk7Cj4gCj4gQEAgLTUyMiw2ICs3MzMsNyBAQCBzdGF0aWMgY29uc3Qg c3RydWN0IG9mX2RldmljZV9pZCByY2FyX2x2ZHNfb2ZfdGFibGVbXSA9Cj4geyB7IC5jb21wYXRp YmxlID0gInJlbmVzYXMscjhhNzc5NS1sdmRzIiwgLmRhdGEgPSAmcmNhcl9sdmRzX2dlbjNfaW5m byB9LCB7Cj4gLmNvbXBhdGlibGUgPSAicmVuZXNhcyxyOGE3Nzk2LWx2ZHMiLCAuZGF0YSA9ICZy Y2FyX2x2ZHNfZ2VuM19pbmZvIH0sIHsKPiAuY29tcGF0aWJsZSA9ICJyZW5lc2FzLHI4YTc3OTcw LWx2ZHMiLCAuZGF0YSA9ICZyY2FyX2x2ZHNfcjhhNzc5NzBfaW5mbyB9LAo+ICsJeyAuY29tcGF0 aWJsZSA9ICJyZW5lc2FzLHI4YTc3OTk1LWx2ZHMiLCAuZGF0YSA9ICZyY2FyX2x2ZHNfZ2VuM19p bmZvIH0sCj4geyB9Cj4gIH07Cj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9yY2Fy LWR1L3JjYXJfbHZkc19yZWdzLmgKPiBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfbHZk c19yZWdzLmggaW5kZXggMjg5NjgzNS4uZTM3ZGI5NSAxMDA2NDQKPiAtLS0gYS9kcml2ZXJzL2dw dS9kcm0vcmNhci1kdS9yY2FyX2x2ZHNfcmVncy5oCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL3Jj YXItZHUvcmNhcl9sdmRzX3JlZ3MuaAo+IEBAIC0yMSw3ICsyMSw3IEBACj4gICNkZWZpbmUgTFZE Q1IwX1BMTE9OCQkJKDEgPDwgNCkKPiAgI2RlZmluZSBMVkRDUjBfUFdECQkJKDEgPDwgMikJCS8q IEdlbjMgb25seSAqLwo+ICAjZGVmaW5lIExWRENSMF9CRU4JCQkoMSA8PCAyKQkJLyogR2VuMiBv bmx5ICovCj4gLSNkZWZpbmUgTFZEQ1IwX0xWRU4JCQkoMSA8PCAxKQkJLyogR2VuMiBvbmx5ICov Cj4gKyNkZWZpbmUgTFZEQ1IwX0xWRU4JCQkoMSA8PCAxKQo+ICAjZGVmaW5lIExWRENSMF9MVlJF UwkJCSgxIDw8IDApCj4gCj4gICNkZWZpbmUgTFZEQ1IxCQkJCTB4MDAwNAo+IEBAIC00Niw2ICs0 NiwyNCBAQAo+ICAjZGVmaW5lIExWRFBMTENSX1BMTERJVkNOVF8xNDhNCQkoMHgwNDZjMSA8PCAw KQo+ICAjZGVmaW5lIExWRFBMTENSX1BMTERJVkNOVF9NQVNLCQkoMHg3ZmZmZiA8PCAwKQo+IAo+ ICsvKiBSLUNhciBEMyAqLwo+ICsjZGVmaW5lIExWRFBMTENSX1BMTE9OCQkJKDEgPDwgMjIpCj4g KyNkZWZpbmUgTFZEUExMQ1JfUExMU0VMX1BMTDAJCSgwIDw8IDIwKQo+ICsjZGVmaW5lIExWRFBM TENSX1BMTFNFTF9MVlgJCSgxIDw8IDIwKQo+ICsjZGVmaW5lIExWRFBMTENSX1BMTFNFTF9QTEwx CQkoMiA8PCAyMCkKPiArI2RlZmluZSBMVkRQTExDUl9DS1NFTF9MVlgJCSgxIDw8IDE3KQo+ICsj ZGVmaW5lIExWRFBMTENSX0NLU0VMX0VYVEFMCQkoMyA8PCAxNykKPiArI2RlZmluZSBMVkRQTExD Ul9DS1NFTF9EVV9ET1RDTEtJTjAJKDUgPDwgMTcpCj4gKyNkZWZpbmUgTFZEUExMQ1JfQ0tTRUxf RFVfRE9UQ0xLSU4xCSg3IDw8IDE3KQo+ICsjZGVmaW5lIExWRFBMTENSX09DS1NFTF83CQkoMCA8 PCAxNikKPiArI2RlZmluZSBMVkRQTExDUl9PQ0tTRUxfTk9UX0RJVklERUQJKDEgPDwgMTYpCj4g KyNkZWZpbmUgTFZEUExMQ1JfU1RQX0NMS09VVEUxX0RJUwkoMCA8PCAxNCkKPiArI2RlZmluZSBM VkRQTExDUl9TVFBfQ0xLT1VURTFfRU4JKDEgPDwgMTQpCj4gKyNkZWZpbmUgTFZEUExMQ1JfT1VU Q0xLU0VMX0JFRk9SRQkoMCA8PCAxMikKPiArI2RlZmluZSBMVkRQTExDUl9PVVRDTEtTRUxfQUZU RVIJKDEgPDwgMTIpCj4gKyNkZWZpbmUgTFZEUExMQ1JfQ0xLT1VUX0RJU0FCTEUJCSgwIDw8IDEx KQo+ICsjZGVmaW5lIExWRFBMTENSX0NMS09VVF9FTkFCTEUJCSgxIDw8IDExKQo+ICsKPiAgI2Rl ZmluZSBMVkRDVFJDUgkJCTB4MDAwYwo+ICAjZGVmaW5lIExWRENUUkNSX0NUUjNTRUxfWkVSTwkJ KDAgPDwgMTIpCj4gICNkZWZpbmUgTFZEQ1RSQ1JfQ1RSM1NFTF9PREQJCSgxIDw8IDEyKQo+IEBA IC03NCw0ICs5MiwzMCBAQAo+ICAjZGVmaW5lIExWRENIQ1JfQ0hTRUxfQ0gobiwgYykJCSgoKChj KSAtIChuKSkgJiAzKSA8PCAoKG4pICogNCkpCj4gICNkZWZpbmUgTFZEQ0hDUl9DSFNFTF9NQVNL KG4pCQkoMyA8PCAoKG4pICogNCkpCj4gCj4gKyNkZWZpbmUgTFZEU1RSSVBFCQkJMHgwMDE0Cj4g KyNkZWZpbmUgTFZEU1RSSVBFX1NUX1RSR1NFTF9ESVNQCSgwIDw8IDIpCj4gKyNkZWZpbmUgTFZE U1RSSVBFX1NUX1RSR1NFTF9IU1lOQ19SCSgxIDw8IDIpCj4gKyNkZWZpbmUgTFZEU1RSSVBFX1NU X1RSR1NFTF9IU1lOQ19GCSgyIDw8IDIpCj4gKwo+ICsjZGVmaW5lIExWRFNUUklQRV9TVF9TV0FQ X05PUk1BTAkoMCA8PCAxKQo+ICsjZGVmaW5lIExWRFNUUklQRV9TVF9TV0FQX1NXQVAJCSgxIDw8 IDEpCj4gKyNkZWZpbmUgTFZEU1RSSVBFX1NUX09OCQkJKDEgPDwgMCkKPiArCj4gKyNkZWZpbmUg TFZEU0NSCQkJCTB4MDAxOAo+ICsjZGVmaW5lIExWRFNDUl9ERVBUSF9EUDEJCSgwIDw8IDI5KQo+ ICsjZGVmaW5lIExWRFNDUl9ERVBUSF9EUDIJCSgxIDw8IDI5KQo+ICsjZGVmaW5lIExWRFNDUl9E RVBUSF9EUDMJCSgyIDw8IDI5KQo+ICsjZGVmaW5lIExWRFNDUl9CQU5EU0VUXzEwS0haX0xFU1Nf VEhBTgkoMSA8PCAyOCkKPiArI2RlZmluZSBMVkRTQ1JfU0RJVl9TUjEJCQkoMCA8PCAyMikKPiAr I2RlZmluZSBMVkRTQ1JfU0RJVl9TUjIJCQkoMSA8PCAyMikKPiArI2RlZmluZSBMVkRTQ1JfU0RJ Vl9TUjQJCQkoMiA8PCAyMikKPiArI2RlZmluZSBMVkRTQ1JfU0RJVl9TUjgJCQkoMyA8PCAyMikK PiArI2RlZmluZSBMVkRTQ1JfTU9ERV9ET1dOCQkoMSA8PCAyMSkKPiArI2RlZmluZSBMVkRTQ1Jf UlNUTl9FTkFCTEUJCSgxIDw8IDIwKQo+ICsKPiArI2RlZmluZSBMVkRESVYJCQkJMHgwMDFjCj4g KyNkZWZpbmUgTFZERElWX0RJVlNFTAkJCSgxIDw8IDgpCj4gKyNkZWZpbmUgTFZERElWX0RJVlJF U0VUCQkJKDEgPDwgNykKPiArI2RlZmluZSBMVkRESVZfRElWU1RQCQkJKDEgPDwgNikKPiArCj4g ICNlbmRpZiAvKiBfX1JDQVJfTFZEU19SRUdTX0hfXyAqLwoKLS0gClJlZ2FyZHMsCgpMYXVyZW50 IFBpbmNoYXJ0CgoKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9y ZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZl bAo=