From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from perceval.ideasonboard.com ([213.167.242.64]:44306 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726634AbeIIVee (ORCPT ); Sun, 9 Sep 2018 17:34:34 -0400 From: Laurent Pinchart To: jacopo mondi Cc: Laurent Pinchart , dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org Subject: Re: [PATCH 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Date: Sun, 09 Sep 2018 19:44:27 +0300 Message-ID: <12914706.DMgRscQiTK@avalon> In-Reply-To: <20180907181938.GM20333@w540> References: <20180904121027.24031-1-laurent.pinchart+renesas@ideasonboard.com> <20180904121027.24031-7-laurent.pinchart+renesas@ideasonboard.com> <20180907181938.GM20333@w540> 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 Jacopo, On Friday, 7 September 2018 21:19:38 EEST jacopo mondi wrote: > On Tue, Sep 04, 2018 at 03:10:17PM +0300, Laurent Pinchart wrote: > > The rcar_du_crtc_get() function is always immediately followed by a call > > to rcar_du_crtc_setup(). Call the later from the former to simplify the > > code, and add a comment to explain how the get and put calls are > > balanced. > > > > Signed-off-by: Laurent Pinchart > > > > --- > > > > drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 107 +++++++++++++++------------- > > 1 file changed, 56 insertions(+), 51 deletions(-) > > > > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > > b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 4c9572d7ea89..1d81eb244441 > > 100644 > > --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > > +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c > > @@ -66,39 +66,6 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc > > *rcrtc, u32 reg, > > rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set); > > } > > > > -static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc) > > -{ > > - int ret; > > - > > - ret = clk_prepare_enable(rcrtc->clock); > > - if (ret < 0) > > - return ret; > > - > > - ret = clk_prepare_enable(rcrtc->extclock); > > - if (ret < 0) > > - goto error_clock; > > - > > - ret = rcar_du_group_get(rcrtc->group); > > - if (ret < 0) > > - goto error_group; > > - > > - return 0; > > - > > -error_group: > > - clk_disable_unprepare(rcrtc->extclock); > > -error_clock: > > - clk_disable_unprepare(rcrtc->clock); > > - return ret; > > -} > > - > > -static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) > > For what I see, rcar_du_crtc_stop() is also called once just before > _put(). Have you considered doing with them what you've done with > _get() and _setup() ? I have, but given that we have an explicit get(); start(); sequence in rcar_du_crtc_atomic_enable(), I'd rather keep the stop(); put(); sequence in rcar_du_crtc_atomic_disable(). > > -{ > > - rcar_du_group_put(rcrtc->group); > > - > > - clk_disable_unprepare(rcrtc->extclock); > > - clk_disable_unprepare(rcrtc->clock); > > -} > > - > > > > /* > > ------------------------------------------------------------------------ > > -----> > > * Hardware Setup > > */ > > > > @@ -546,6 +513,51 @@ static void rcar_du_crtc_setup(struct rcar_du_crtc > > *rcrtc)> > > drm_crtc_vblank_on(&rcrtc->crtc); > > > > } > > > > +static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc) > > +{ > > + int ret; > > + > > + /* > > + * Guard against double-get, as the function is called from both the > > + * .atomic_enable() and .atomic_begin() handlers. > > + */ > > + if (rcrtc->initialized) > > + return 0; > > + > > + ret = clk_prepare_enable(rcrtc->clock); > > + if (ret < 0) > > + return ret; > > + > > + ret = clk_prepare_enable(rcrtc->extclock); > > + if (ret < 0) > > + goto error_clock; > > + > > + ret = rcar_du_group_get(rcrtc->group); > > + if (ret < 0) > > + goto error_group; > > + > > + rcar_du_crtc_setup(rcrtc); > > + rcrtc->initialized = true; > > + > > + return 0; > > + > > +error_group: > > + clk_disable_unprepare(rcrtc->extclock); > > +error_clock: > > + clk_disable_unprepare(rcrtc->clock); > > + return ret; > > +} > > + > > +static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) > > +{ > > + rcar_du_group_put(rcrtc->group); > > + > > + clk_disable_unprepare(rcrtc->extclock); > > + clk_disable_unprepare(rcrtc->clock); > > + > > + rcrtc->initialized = false; > > +} > > + > > > > static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) > > { > > > > bool interlaced; > > > > @@ -639,16 +651,7 @@ static void rcar_du_crtc_atomic_enable(struct > > drm_crtc *crtc,> > > { > > > > struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); > > > > - /* > > - * If the CRTC has already been setup by the .atomic_begin() handler we > > - * can skip the setup stage. > > - */ > > - if (!rcrtc->initialized) { > > - rcar_du_crtc_get(rcrtc); > > - rcar_du_crtc_setup(rcrtc); > > - rcrtc->initialized = true; > > - } > > - > > + rcar_du_crtc_get(rcrtc); > > > > rcar_du_crtc_start(rcrtc); > > > > } > > > > @@ -667,7 +670,6 @@ static void rcar_du_crtc_atomic_disable(struct > > drm_crtc *crtc,> > > } > > spin_unlock_irq(&crtc->dev->event_lock); > > > > - rcrtc->initialized = false; > > > > rcrtc->outputs = 0; > > > > } > > > > @@ -680,14 +682,17 @@ static void rcar_du_crtc_atomic_begin(struct > > drm_crtc *crtc,> > > /* > > > > * If a mode set is in progress we can be called with the CRTC disabled. > > > > - * We then need to first setup the CRTC in order to configure planes. > > - * The .atomic_enable() handler will notice and skip the CRTC setup. > > + * We thus need to first get and setup the CRTC in order to configure > > + * planes. We must *not* put the CRTC in .atomic_flush(), as it must be > > + * kept awake until the .atomic_enable() call that will follow. The get > > + * operation in .atomic_enable() will in that case be a no-op, and the > > + * CRTC will be put later in .atomic_disable(). > > + * > > + * If a mode set is not in progress the CRTC is enabled, and the > > + * following get call will be a no-op. There is thus no need to belance > > + * it in .atomic_flush() either. > > > > */ > > > > - if (!rcrtc->initialized) { > > - rcar_du_crtc_get(rcrtc); > > - rcar_du_crtc_setup(rcrtc); > > - rcrtc->initialized = true; > > - } > > + rcar_du_crtc_get(rcrtc); > > > > if (rcar_du_has(rcrtc->group->dev, RCAR_DU_FEATURE_VSP1_SOURCE)) > > > > rcar_du_vsp_atomic_begin(rcrtc); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH 06/16] drm: rcar-du: Perform the initial CRTC setup from rcar_du_crtc_get() Date: Sun, 09 Sep 2018 19:44:27 +0300 Message-ID: <12914706.DMgRscQiTK@avalon> References: <20180904121027.24031-1-laurent.pinchart+renesas@ideasonboard.com> <20180904121027.24031-7-laurent.pinchart+renesas@ideasonboard.com> <20180907181938.GM20333@w540> 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 [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by gabe.freedesktop.org (Postfix) with ESMTPS id DCF7F6E021 for ; Sun, 9 Sep 2018 16:44:20 +0000 (UTC) In-Reply-To: <20180907181938.GM20333@w540> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: jacopo mondi Cc: linux-renesas-soc@vger.kernel.org, Laurent Pinchart , dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org SGkgSmFjb3BvLAoKT24gRnJpZGF5LCA3IFNlcHRlbWJlciAyMDE4IDIxOjE5OjM4IEVFU1QgamFj b3BvIG1vbmRpIHdyb3RlOgo+IE9uIFR1ZSwgU2VwIDA0LCAyMDE4IGF0IDAzOjEwOjE3UE0gKzAz MDAsIExhdXJlbnQgUGluY2hhcnQgd3JvdGU6Cj4gPiBUaGUgcmNhcl9kdV9jcnRjX2dldCgpIGZ1 bmN0aW9uIGlzIGFsd2F5cyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBhIGNhbGwKPiA+IHRvIHJj YXJfZHVfY3J0Y19zZXR1cCgpLiBDYWxsIHRoZSBsYXRlciBmcm9tIHRoZSBmb3JtZXIgdG8gc2lt cGxpZnkgdGhlCj4gPiBjb2RlLCBhbmQgYWRkIGEgY29tbWVudCB0byBleHBsYWluIGhvdyB0aGUg Z2V0IGFuZCBwdXQgY2FsbHMgYXJlCj4gPiBiYWxhbmNlZC4KPiA+IAo+ID4gU2lnbmVkLW9mZi1i eTogTGF1cmVudCBQaW5jaGFydAo+ID4gPGxhdXJlbnQucGluY2hhcnQrcmVuZXNhc0BpZGVhc29u Ym9hcmQuY29tPgo+ID4gLS0tCj4gPiAKPiA+ICBkcml2ZXJzL2dwdS9kcm0vcmNhci1kdS9yY2Fy X2R1X2NydGMuYyB8IDEwNyArKysrKysrKysrKysrKystLS0tLS0tLS0tLS0tCj4gPiAgMSBmaWxl IGNoYW5nZWQsIDU2IGluc2VydGlvbnMoKyksIDUxIGRlbGV0aW9ucygtKQo+ID4gCj4gPiBkaWZm IC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9jcnRjLmMKPiA+IGIvZHJp dmVycy9ncHUvZHJtL3JjYXItZHUvcmNhcl9kdV9jcnRjLmMgaW5kZXggNGM5NTcyZDdlYTg5Li4x ZDgxZWIyNDQ0NDEKPiA+IDEwMDY0NAo+ID4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL3JjYXItZHUv cmNhcl9kdV9jcnRjLmMKPiA+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9yY2FyLWR1L3JjYXJfZHVf Y3J0Yy5jCj4gPiBAQCAtNjYsMzkgKzY2LDYgQEAgc3RhdGljIHZvaWQgcmNhcl9kdV9jcnRjX2Ns cl9zZXQoc3RydWN0IHJjYXJfZHVfY3J0Ywo+ID4gKnJjcnRjLCB1MzIgcmVnLAo+ID4gIAlyY2Fy X2R1X3dyaXRlKHJjZHUsIHJjcnRjLT5tbWlvX29mZnNldCArIHJlZywgKHZhbHVlICYgfmNscikg fCBzZXQpOwo+ID4gIH0KPiA+IAo+ID4gLXN0YXRpYyBpbnQgcmNhcl9kdV9jcnRjX2dldChzdHJ1 Y3QgcmNhcl9kdV9jcnRjICpyY3J0YykKPiA+IC17Cj4gPiAtCWludCByZXQ7Cj4gPiAtCj4gPiAt CXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShyY3J0Yy0+Y2xvY2spOwo+ID4gLQlpZiAocmV0IDwg MCkKPiA+IC0JCXJldHVybiByZXQ7Cj4gPiAtCj4gPiAtCXJldCA9IGNsa19wcmVwYXJlX2VuYWJs ZShyY3J0Yy0+ZXh0Y2xvY2spOwo+ID4gLQlpZiAocmV0IDwgMCkKPiA+IC0JCWdvdG8gZXJyb3Jf Y2xvY2s7Cj4gPiAtCj4gPiAtCXJldCA9IHJjYXJfZHVfZ3JvdXBfZ2V0KHJjcnRjLT5ncm91cCk7 Cj4gPiAtCWlmIChyZXQgPCAwKQo+ID4gLQkJZ290byBlcnJvcl9ncm91cDsKPiA+IC0KPiA+IC0J cmV0dXJuIDA7Cj4gPiAtCj4gPiAtZXJyb3JfZ3JvdXA6Cj4gPiAtCWNsa19kaXNhYmxlX3VucHJl cGFyZShyY3J0Yy0+ZXh0Y2xvY2spOwo+ID4gLWVycm9yX2Nsb2NrOgo+ID4gLQljbGtfZGlzYWJs ZV91bnByZXBhcmUocmNydGMtPmNsb2NrKTsKPiA+IC0JcmV0dXJuIHJldDsKPiA+IC19Cj4gPiAt Cj4gPiAtc3RhdGljIHZvaWQgcmNhcl9kdV9jcnRjX3B1dChzdHJ1Y3QgcmNhcl9kdV9jcnRjICpy Y3J0YykKPiAKPiBGb3Igd2hhdCBJIHNlZSwgcmNhcl9kdV9jcnRjX3N0b3AoKSBpcyBhbHNvIGNh bGxlZCBvbmNlIGp1c3QgYmVmb3JlCj4gX3B1dCgpLiBIYXZlIHlvdSBjb25zaWRlcmVkIGRvaW5n IHdpdGggdGhlbSB3aGF0IHlvdSd2ZSBkb25lIHdpdGgKPiBfZ2V0KCkgYW5kIF9zZXR1cCgpID8K CkkgaGF2ZSwgYnV0IGdpdmVuIHRoYXQgd2UgaGF2ZSBhbiBleHBsaWNpdCBnZXQoKTsgc3RhcnQo KTsgc2VxdWVuY2UgaW4gCnJjYXJfZHVfY3J0Y19hdG9taWNfZW5hYmxlKCksIEknZCByYXRoZXIg a2VlcCB0aGUgc3RvcCgpOyBwdXQoKTsgc2VxdWVuY2UgaW4gCnJjYXJfZHVfY3J0Y19hdG9taWNf ZGlzYWJsZSgpLgoKPiA+IC17Cj4gPiAtCXJjYXJfZHVfZ3JvdXBfcHV0KHJjcnRjLT5ncm91cCk7 Cj4gPiAtCj4gPiAtCWNsa19kaXNhYmxlX3VucHJlcGFyZShyY3J0Yy0+ZXh0Y2xvY2spOwo+ID4g LQljbGtfZGlzYWJsZV91bnByZXBhcmUocmNydGMtPmNsb2NrKTsKPiA+IC19Cj4gPiAtCj4gPiAK PiA+ICAvKgo+ID4gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+ID4gIC0tLS0tPiAgCj4gPiAgICogSGFyZHdh cmUgU2V0dXAKPiA+ICAgKi8KPiA+IAo+ID4gQEAgLTU0Niw2ICs1MTMsNTEgQEAgc3RhdGljIHZv aWQgcmNhcl9kdV9jcnRjX3NldHVwKHN0cnVjdCByY2FyX2R1X2NydGMKPiA+ICpyY3J0Yyk+IAo+ ID4gIAlkcm1fY3J0Y192Ymxhbmtfb24oJnJjcnRjLT5jcnRjKTsKPiA+ICAKPiA+ICB9Cj4gPiAK PiA+ICtzdGF0aWMgaW50IHJjYXJfZHVfY3J0Y19nZXQoc3RydWN0IHJjYXJfZHVfY3J0YyAqcmNy dGMpCj4gPiArewo+ID4gKwlpbnQgcmV0Owo+ID4gKwo+ID4gKwkvKgo+ID4gKwkgKiBHdWFyZCBh Z2FpbnN0IGRvdWJsZS1nZXQsIGFzIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgZnJvbSBib3RoIHRo ZQo+ID4gKwkgKiAuYXRvbWljX2VuYWJsZSgpIGFuZCAuYXRvbWljX2JlZ2luKCkgaGFuZGxlcnMu Cj4gPiArCSAqLwo+ID4gKwlpZiAocmNydGMtPmluaXRpYWxpemVkKQo+ID4gKwkJcmV0dXJuIDA7 Cj4gPiArCj4gPiArCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShyY3J0Yy0+Y2xvY2spOwo+ID4g KwlpZiAocmV0IDwgMCkKPiA+ICsJCXJldHVybiByZXQ7Cj4gPiArCj4gPiArCXJldCA9IGNsa19w cmVwYXJlX2VuYWJsZShyY3J0Yy0+ZXh0Y2xvY2spOwo+ID4gKwlpZiAocmV0IDwgMCkKPiA+ICsJ CWdvdG8gZXJyb3JfY2xvY2s7Cj4gPiArCj4gPiArCXJldCA9IHJjYXJfZHVfZ3JvdXBfZ2V0KHJj cnRjLT5ncm91cCk7Cj4gPiArCWlmIChyZXQgPCAwKQo+ID4gKwkJZ290byBlcnJvcl9ncm91cDsK PiA+ICsKPiA+ICsJcmNhcl9kdV9jcnRjX3NldHVwKHJjcnRjKTsKPiA+ICsJcmNydGMtPmluaXRp YWxpemVkID0gdHJ1ZTsKPiA+ICsKPiA+ICsJcmV0dXJuIDA7Cj4gPiArCj4gPiArZXJyb3JfZ3Jv dXA6Cj4gPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShyY3J0Yy0+ZXh0Y2xvY2spOwo+ID4gK2Vy cm9yX2Nsb2NrOgo+ID4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUocmNydGMtPmNsb2NrKTsKPiA+ ICsJcmV0dXJuIHJldDsKPiA+ICt9Cj4gPiArCj4gPiArc3RhdGljIHZvaWQgcmNhcl9kdV9jcnRj X3B1dChzdHJ1Y3QgcmNhcl9kdV9jcnRjICpyY3J0YykKPiA+ICt7Cj4gPiArCXJjYXJfZHVfZ3Jv dXBfcHV0KHJjcnRjLT5ncm91cCk7Cj4gPiArCj4gPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShy Y3J0Yy0+ZXh0Y2xvY2spOwo+ID4gKwljbGtfZGlzYWJsZV91bnByZXBhcmUocmNydGMtPmNsb2Nr KTsKPiA+ICsKPiA+ICsJcmNydGMtPmluaXRpYWxpemVkID0gZmFsc2U7Cj4gPiArfQo+ID4gKwo+ ID4gCj4gPiAgc3RhdGljIHZvaWQgcmNhcl9kdV9jcnRjX3N0YXJ0KHN0cnVjdCByY2FyX2R1X2Ny dGMgKnJjcnRjKQo+ID4gIHsKPiA+ICAKPiA+ICAJYm9vbCBpbnRlcmxhY2VkOwo+ID4gCj4gPiBA QCAtNjM5LDE2ICs2NTEsNyBAQCBzdGF0aWMgdm9pZCByY2FyX2R1X2NydGNfYXRvbWljX2VuYWJs ZShzdHJ1Y3QKPiA+IGRybV9jcnRjICpjcnRjLD4gCj4gPiAgewo+ID4gIAo+ID4gIAlzdHJ1Y3Qg cmNhcl9kdV9jcnRjICpyY3J0YyA9IHRvX3JjYXJfY3J0YyhjcnRjKTsKPiA+IAo+ID4gLQkvKgo+ ID4gLQkgKiBJZiB0aGUgQ1JUQyBoYXMgYWxyZWFkeSBiZWVuIHNldHVwIGJ5IHRoZSAuYXRvbWlj X2JlZ2luKCkgaGFuZGxlciB3ZQo+ID4gLQkgKiBjYW4gc2tpcCB0aGUgc2V0dXAgc3RhZ2UuCj4g PiAtCSAqLwo+ID4gLQlpZiAoIXJjcnRjLT5pbml0aWFsaXplZCkgewo+ID4gLQkJcmNhcl9kdV9j cnRjX2dldChyY3J0Yyk7Cj4gPiAtCQlyY2FyX2R1X2NydGNfc2V0dXAocmNydGMpOwo+ID4gLQkJ cmNydGMtPmluaXRpYWxpemVkID0gdHJ1ZTsKPiA+IC0JfQo+ID4gLQo+ID4gKwlyY2FyX2R1X2Ny dGNfZ2V0KHJjcnRjKTsKPiA+IAo+ID4gIAlyY2FyX2R1X2NydGNfc3RhcnQocmNydGMpOwo+ID4g IAo+ID4gIH0KPiA+IAo+ID4gQEAgLTY2Nyw3ICs2NzAsNiBAQCBzdGF0aWMgdm9pZCByY2FyX2R1 X2NydGNfYXRvbWljX2Rpc2FibGUoc3RydWN0Cj4gPiBkcm1fY3J0YyAqY3J0Yyw+IAo+ID4gIAl9 Cj4gPiAgCXNwaW5fdW5sb2NrX2lycSgmY3J0Yy0+ZGV2LT5ldmVudF9sb2NrKTsKPiA+IAo+ID4g LQlyY3J0Yy0+aW5pdGlhbGl6ZWQgPSBmYWxzZTsKPiA+IAo+ID4gIAlyY3J0Yy0+b3V0cHV0cyA9 IDA7Cj4gPiAgCj4gPiAgfQo+ID4gCj4gPiBAQCAtNjgwLDE0ICs2ODIsMTcgQEAgc3RhdGljIHZv aWQgcmNhcl9kdV9jcnRjX2F0b21pY19iZWdpbihzdHJ1Y3QKPiA+IGRybV9jcnRjICpjcnRjLD4g Cj4gPiAgCS8qCj4gPiAgCQo+ID4gIAkgKiBJZiBhIG1vZGUgc2V0IGlzIGluIHByb2dyZXNzIHdl IGNhbiBiZSBjYWxsZWQgd2l0aCB0aGUgQ1JUQyAKZGlzYWJsZWQuCj4gPiAKPiA+IC0JICogV2Ug dGhlbiBuZWVkIHRvIGZpcnN0IHNldHVwIHRoZSBDUlRDIGluIG9yZGVyIHRvIGNvbmZpZ3VyZSBw bGFuZXMuCj4gPiAtCSAqIFRoZSAuYXRvbWljX2VuYWJsZSgpIGhhbmRsZXIgd2lsbCBub3RpY2Ug YW5kIHNraXAgdGhlIENSVEMgc2V0dXAuCj4gPiArCSAqIFdlIHRodXMgbmVlZCB0byBmaXJzdCBn ZXQgYW5kIHNldHVwIHRoZSBDUlRDIGluIG9yZGVyIHRvIGNvbmZpZ3VyZQo+ID4gKwkgKiBwbGFu ZXMuIFdlIG11c3QgKm5vdCogcHV0IHRoZSBDUlRDIGluIC5hdG9taWNfZmx1c2goKSwgYXMgaXQg bXVzdCBiZQo+ID4gKwkgKiBrZXB0IGF3YWtlIHVudGlsIHRoZSAuYXRvbWljX2VuYWJsZSgpIGNh bGwgdGhhdCB3aWxsIGZvbGxvdy4gVGhlIGdldAo+ID4gKwkgKiBvcGVyYXRpb24gaW4gLmF0b21p Y19lbmFibGUoKSB3aWxsIGluIHRoYXQgY2FzZSBiZSBhIG5vLW9wLCBhbmQgdGhlCj4gPiArCSAq IENSVEMgd2lsbCBiZSBwdXQgbGF0ZXIgaW4gLmF0b21pY19kaXNhYmxlKCkuCj4gPiArCSAqCj4g PiArCSAqIElmIGEgbW9kZSBzZXQgaXMgbm90IGluIHByb2dyZXNzIHRoZSBDUlRDIGlzIGVuYWJs ZWQsIGFuZCB0aGUKPiA+ICsJICogZm9sbG93aW5nIGdldCBjYWxsIHdpbGwgYmUgYSBuby1vcC4g VGhlcmUgaXMgdGh1cyBubyBuZWVkIHRvIGJlbGFuY2UKPiA+ICsJICogaXQgaW4gLmF0b21pY19m bHVzaCgpIGVpdGhlci4KPiA+IAo+ID4gIAkgKi8KPiA+IAo+ID4gLQlpZiAoIXJjcnRjLT5pbml0 aWFsaXplZCkgewo+ID4gLQkJcmNhcl9kdV9jcnRjX2dldChyY3J0Yyk7Cj4gPiAtCQlyY2FyX2R1 X2NydGNfc2V0dXAocmNydGMpOwo+ID4gLQkJcmNydGMtPmluaXRpYWxpemVkID0gdHJ1ZTsKPiA+ IC0JfQo+ID4gKwlyY2FyX2R1X2NydGNfZ2V0KHJjcnRjKTsKPiA+IAo+ID4gIAlpZiAocmNhcl9k dV9oYXMocmNydGMtPmdyb3VwLT5kZXYsIFJDQVJfRFVfRkVBVFVSRV9WU1AxX1NPVVJDRSkpCj4g PiAgCQo+ID4gIAkJcmNhcl9kdV92c3BfYXRvbWljX2JlZ2luKHJjcnRjKTsKCgotLSAKUmVnYXJk cywKCkxhdXJlbnQgUGluY2hhcnQKCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJl ZWRlc2t0b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGlu Zm8vZHJpLWRldmVsCg==