From mboxrd@z Thu Jan 1 00:00:00 1970 From: laurent.pinchart@ideasonboard.com (Laurent Pinchart) Date: Thu, 26 Feb 2015 20:33:33 +0200 Subject: [PATCH 03/11] drm: add driver for simple vga encoders In-Reply-To: <1422721984-27782-4-git-send-email-heiko@sntech.de> References: <1422721984-27782-1-git-send-email-heiko@sntech.de> <1422721984-27782-4-git-send-email-heiko@sntech.de> Message-ID: <10479896.3hQzemuBRM@avalon> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Heiko, Thank you for the patch. On Saturday 31 January 2015 17:32:56 Heiko Stuebner wrote: > There exist simple vga encoders without any type of management interface > and just maybe a simple gpio for turning it on or off. Examples for these > are the Analog Devices ADV7123, Chipsea CS7123 or Micronas SDA7123. > > Add a generic encoder driver for those that can be used by drm drivers > using the component framework. The rcar-du driver already handles the adi,adv7123 compatible string used by this driver. A generic driver is in my opinion a very good idea, but we can't break the existing support. Porting the rcar-du driver to the component model is needed. > Signed-off-by: Heiko Stuebner > --- > drivers/gpu/drm/i2c/Kconfig | 6 + > drivers/gpu/drm/i2c/Makefile | 2 + > drivers/gpu/drm/i2c/vga-simple.c | 325 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i2c/ feels wrong for a platform device. > 3 files changed, 333 insertions(+) > create mode 100644 drivers/gpu/drm/i2c/vga-simple.c > > diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig > index 22c7ed6..319f2cb 100644 > --- a/drivers/gpu/drm/i2c/Kconfig > +++ b/drivers/gpu/drm/i2c/Kconfig > @@ -31,4 +31,10 @@ config DRM_I2C_NXP_TDA998X > help > Support for NXP Semiconductors TDA998X HDMI encoders. > > +config DRM_VGA_SIMPLE > + tristate "Generic simple vga encoder" > + help > + Support for vga encoder chips without any special settings > + and at most a power-control gpio. > + > endmenu > diff --git a/drivers/gpu/drm/i2c/Makefile b/drivers/gpu/drm/i2c/Makefile > index 2c72eb5..858961f 100644 > --- a/drivers/gpu/drm/i2c/Makefile > +++ b/drivers/gpu/drm/i2c/Makefile > @@ -10,3 +10,5 @@ obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o > > tda998x-y := tda998x_drv.o > obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o > + > +obj-$(CONFIG_DRM_VGA_SIMPLE) += vga-simple.o > diff --git a/drivers/gpu/drm/i2c/vga-simple.c > b/drivers/gpu/drm/i2c/vga-simple.c new file mode 100644 > index 0000000..bb9d19c > --- /dev/null > +++ b/drivers/gpu/drm/i2c/vga-simple.c > @@ -0,0 +1,325 @@ > +/* > + * Simple vga encoder driver > + * > + * Copyright (C) 2014 Heiko Stuebner > + * > + * This software is licensed under the terms of the GNU General Public > + * License version 2, as published by the Free Software Foundation, and > + * may be copied, distributed, and modified under those terms. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define connector_to_vga_simple(x) container_of(x, struct vga_simple, > connector) +#define encoder_to_vga_simple(x) container_of(x, struct > vga_simple, encoder) + > +struct vga_simple { > + struct drm_connector connector; > + struct drm_encoder encoder; > + > + struct device *dev; > + struct i2c_adapter *ddc; > + > + struct regulator *vaa_reg; > + struct gpio_desc *enable_gpio; > + > + struct mutex enable_lock; > + bool enabled; > +}; > + > +/* > + * Connector functions > + */ > + > +enum drm_connector_status vga_simple_detect(struct drm_connector > *connector, + bool force) > +{ > + struct vga_simple *vga = connector_to_vga_simple(connector); > + > + if (!vga->ddc) > + return connector_status_unknown; > + > + if (drm_probe_ddc(vga->ddc)) > + return connector_status_connected; > + > + return connector_status_disconnected; > +} > + > +void vga_simple_connector_destroy(struct drm_connector *connector) > +{ > + drm_connector_unregister(connector); > + drm_connector_cleanup(connector); > +} > + > +struct drm_connector_funcs vga_simple_connector_funcs = { > + .dpms = drm_helper_connector_dpms, > + .fill_modes = drm_helper_probe_single_connector_modes, > + .detect = vga_simple_detect, > + .destroy = vga_simple_connector_destroy, > +}; > + > +/* > + * Connector helper functions > + */ > + > +static int vga_simple_connector_get_modes(struct drm_connector *connector) > +{ > + struct vga_simple *vga = connector_to_vga_simple(connector); > + struct edid *edid; > + int ret = 0; > + > + if (!vga->ddc) > + return 0; > + > + edid = drm_get_edid(connector, vga->ddc); > + if (edid) { > + drm_mode_connector_update_edid_property(connector, edid); > + ret = drm_add_edid_modes(connector, edid); > + kfree(edid); > + } > + > + return ret; > +} > + > +static int vga_simple_connector_mode_valid(struct drm_connector *connector, > + struct drm_display_mode *mode) > +{ > + return MODE_OK; > +} > + > +static struct drm_encoder > +*vga_simple_connector_best_encoder(struct drm_connector *connector) > +{ > + struct vga_simple *vga = connector_to_vga_simple(connector); > + > + return &vga->encoder; > +} > + > +static struct drm_connector_helper_funcs vga_simple_connector_helper_funcs > = { + .get_modes = vga_simple_connector_get_modes, > + .best_encoder = vga_simple_connector_best_encoder, > + .mode_valid = vga_simple_connector_mode_valid, > +}; > + > +/* > + * Encoder functions > + */ > + > +static void vga_simple_encoder_destroy(struct drm_encoder *encoder) > +{ > + drm_encoder_cleanup(encoder); > +} > + > +static const struct drm_encoder_funcs vga_simple_encoder_funcs = { > + .destroy = vga_simple_encoder_destroy, > +}; > + > +/* > + * Encoder helper functions > + */ > + > +static void vga_simple_encoder_dpms(struct drm_encoder *encoder, int mode) > +{ > + struct vga_simple *vga = encoder_to_vga_simple(encoder); > + > + mutex_lock(&vga->enable_lock); > + > + switch (mode) { > + case DRM_MODE_DPMS_ON: > + if (vga->enabled) > + goto out; > + > + if (!IS_ERR(vga->vaa_reg)) > + regulator_enable(vga->vaa_reg); > + > + if (vga->enable_gpio) > + gpiod_set_value(vga->enable_gpio, 1); > + > + vga->enabled = true; > + break; > + case DRM_MODE_DPMS_STANDBY: > + case DRM_MODE_DPMS_SUSPEND: > + case DRM_MODE_DPMS_OFF: > + if (!vga->enabled) > + goto out; > + > + if (vga->enable_gpio) > + gpiod_set_value(vga->enable_gpio, 0); > + > + if (!IS_ERR(vga->vaa_reg)) > + regulator_enable(vga->vaa_reg); > + > + vga->enabled = false; > + break; > + default: > + break; > + } > + > +out: > + mutex_unlock(&vga->enable_lock); > +} > + > +static bool vga_simple_mode_fixup(struct drm_encoder *encoder, > + const struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > + return true; > +} > + > +static void vga_simple_encoder_prepare(struct drm_encoder *encoder) > +{ > +} > + > +static void vga_simple_encoder_mode_set(struct drm_encoder *encoder, > + struct drm_display_mode *mode, > + struct drm_display_mode *adjusted_mode) > +{ > +} > + > +static void vga_simple_encoder_commit(struct drm_encoder *encoder) > +{ > + vga_simple_encoder_dpms(encoder, DRM_MODE_DPMS_ON); > +} > + > +static void vga_simple_encoder_disable(struct drm_encoder *encoder) > +{ > + vga_simple_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > +} > + > +static const struct drm_encoder_helper_funcs > vga_simple_encoder_helper_funcs = { > + .dpms = vga_simple_encoder_dpms, > + .mode_fixup = vga_simple_mode_fixup, > + .prepare = vga_simple_encoder_prepare, > + .mode_set = vga_simple_encoder_mode_set, > + .commit = vga_simple_encoder_commit, > + .disable = vga_simple_encoder_disable, this is interesting. Some users of this encoder (I'm thinking about rcar-du, for which I've just posted the patches) are already ported to atomic updates, while others are not. How can we support both ? > +}; > + > +/* > + * Component helper functions > + */ > + > +static int vga_simple_bind(struct device *dev, struct device *master, > + void *data) > +{ > + struct platform_device *pdev = to_platform_device(dev); > + struct drm_device *drm = data; > + > + struct device_node *ddc_node, *np = pdev->dev.of_node; > + struct vga_simple *vga; > + int ret; > + > + if (!np) > + return -ENODEV; > + > + vga = devm_kzalloc(dev, sizeof(*vga), GFP_KERNEL); > + if (!vga) > + return -ENOMEM; > + > + vga->dev = dev; > + dev_set_drvdata(dev, vga); > + mutex_init(&vga->enable_lock); > + > + vga->enable_gpio = devm_gpiod_get_optional(dev, "enable", > + GPIOD_OUT_LOW); > + if (IS_ERR(vga->enable_gpio)) { > + ret = PTR_ERR(vga->enable_gpio); > + dev_err(dev, "failed to request GPIO: %d\n", ret); > + return ret; > + } > + > + vga->enabled = false; > + > + ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); > + if (ddc_node) { > + vga->ddc = of_find_i2c_adapter_by_node(ddc_node); > + of_node_put(ddc_node); > + if (!vga->ddc) { > + dev_dbg(vga->dev, "failed to read ddc node\n"); > + return -EPROBE_DEFER; > + } > + } else { > + dev_dbg(vga->dev, "no ddc property found\n"); > + } > + > + vga->vaa_reg = devm_regulator_get_optional(dev, "vaa"); > + > + vga->encoder.possible_crtcs = drm_of_find_possible_crtcs(drm, np); > + vga->encoder.of_node = np; > + vga->connector.polled = DRM_CONNECTOR_POLL_CONNECT | > + DRM_CONNECTOR_POLL_DISCONNECT; > + > + drm_encoder_helper_add(&vga->encoder, &vga_simple_encoder_helper_funcs); > + drm_encoder_init(drm, &vga->encoder, &vga_simple_encoder_funcs, > + DRM_MODE_ENCODER_DAC); > + > + drm_connector_helper_add(&vga->connector, > + &vga_simple_connector_helper_funcs); I really dislike this, this is an encoder driver, not a connector driver. It shouldn't be responsible for creating the connector. For all it knows, there might not even be a VGA connector connected to the encoder, VGA signals could be sent to a chained encoder. That might be a bit far-fetched in the VGA case, but in the generic case encoder drivers shouldn't create connectors. > + drm_connector_init(drm, &vga->connector, &vga_simple_connector_funcs, > + DRM_MODE_CONNECTOR_VGA); > + > + drm_mode_connector_attach_encoder(&vga->connector, &vga->encoder); > + > + return 0; > +} > + > +static void vga_simple_unbind(struct device *dev, struct device *master, > + void *data) > +{ > + struct vga_simple *vga = dev_get_drvdata(dev); > + > + vga->connector.funcs->destroy(&vga->connector); > + vga->encoder.funcs->destroy(&vga->encoder); > +} > + > +static const struct component_ops vga_simple_ops = { > + .bind = vga_simple_bind, > + .unbind = vga_simple_unbind, > +}; > + > +static int vga_simple_probe(struct platform_device *pdev) > +{ > + return component_add(&pdev->dev, &vga_simple_ops); > +} > + > +static int vga_simple_remove(struct platform_device *pdev) > +{ > + component_del(&pdev->dev, &vga_simple_ops); > + > + return 0; > +} > + > +static const struct of_device_id vga_simple_ids[] = { > + { .compatible = "adi,adv7123", }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, vga_simple_ids); > + > +static struct platform_driver vga_simple_driver = { > + .probe = vga_simple_probe, > + .remove = vga_simple_remove, > + .driver = { > + .name = "vga-simple", > + .of_match_table = vga_simple_ids, > + }, > +}; > +module_platform_driver(vga_simple_driver); > + > +MODULE_AUTHOR("Heiko Stuebner "); > +MODULE_DESCRIPTION("Simple vga converter"); > +MODULE_LICENSE("GPL"); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH 03/11] drm: add driver for simple vga encoders Date: Thu, 26 Feb 2015 20:33:33 +0200 Message-ID: <10479896.3hQzemuBRM@avalon> References: <1422721984-27782-1-git-send-email-heiko@sntech.de> <1422721984-27782-4-git-send-email-heiko@sntech.de> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1422721984-27782-4-git-send-email-heiko@sntech.de> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: dri-devel@lists.freedesktop.org Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, pawel.moll@arm.com, ijc+devicetree@hellion.org.uk, linux-rockchip@lists.infradead.org, robh+dt@kernel.org, galak@codeaurora.org, linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org SGkgSGVpa28sCgpUaGFuayB5b3UgZm9yIHRoZSBwYXRjaC4KCk9uIFNhdHVyZGF5IDMxIEphbnVh cnkgMjAxNSAxNzozMjo1NiBIZWlrbyBTdHVlYm5lciB3cm90ZToKPiBUaGVyZSBleGlzdCBzaW1w bGUgdmdhIGVuY29kZXJzIHdpdGhvdXQgYW55IHR5cGUgb2YgbWFuYWdlbWVudCBpbnRlcmZhY2UK PiBhbmQganVzdCBtYXliZSBhIHNpbXBsZSBncGlvIGZvciB0dXJuaW5nIGl0IG9uIG9yIG9mZi4g RXhhbXBsZXMgZm9yIHRoZXNlCj4gYXJlIHRoZSBBbmFsb2cgRGV2aWNlcyBBRFY3MTIzLCBDaGlw c2VhIENTNzEyMyBvciBNaWNyb25hcyBTREE3MTIzLgo+IAo+IEFkZCBhIGdlbmVyaWMgZW5jb2Rl ciBkcml2ZXIgZm9yIHRob3NlIHRoYXQgY2FuIGJlIHVzZWQgYnkgZHJtIGRyaXZlcnMKPiB1c2lu ZyB0aGUgY29tcG9uZW50IGZyYW1ld29yay4KClRoZSByY2FyLWR1IGRyaXZlciBhbHJlYWR5IGhh bmRsZXMgdGhlIGFkaSxhZHY3MTIzIGNvbXBhdGlibGUgc3RyaW5nIHVzZWQgYnkgCnRoaXMgZHJp dmVyLiBBIGdlbmVyaWMgZHJpdmVyIGlzIGluIG15IG9waW5pb24gYSB2ZXJ5IGdvb2QgaWRlYSwg YnV0IHdlIGNhbid0IApicmVhayB0aGUgZXhpc3Rpbmcgc3VwcG9ydC4gUG9ydGluZyB0aGUgcmNh ci1kdSBkcml2ZXIgdG8gdGhlIGNvbXBvbmVudCBtb2RlbCAKaXMgbmVlZGVkLgoKPiBTaWduZWQt b2ZmLWJ5OiBIZWlrbyBTdHVlYm5lciA8aGVpa29Ac250ZWNoLmRlPgo+IC0tLQo+ICBkcml2ZXJz L2dwdS9kcm0vaTJjL0tjb25maWcgICAgICB8ICAgNiArCj4gIGRyaXZlcnMvZ3B1L2RybS9pMmMv TWFrZWZpbGUgICAgIHwgICAyICsKPiAgZHJpdmVycy9ncHUvZHJtL2kyYy92Z2Etc2ltcGxlLmMg fCAzMjUgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCgpkcml2ZXJzL2dwdS9k cm0vaTJjLyBmZWVscyB3cm9uZyBmb3IgYSBwbGF0Zm9ybSBkZXZpY2UuCgo+ICAzIGZpbGVzIGNo YW5nZWQsIDMzMyBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dw dS9kcm0vaTJjL3ZnYS1zaW1wbGUuYwo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0v aTJjL0tjb25maWcgYi9kcml2ZXJzL2dwdS9kcm0vaTJjL0tjb25maWcKPiBpbmRleCAyMmM3ZWQ2 Li4zMTlmMmNiIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pMmMvS2NvbmZpZwo+ICsr KyBiL2RyaXZlcnMvZ3B1L2RybS9pMmMvS2NvbmZpZwo+IEBAIC0zMSw0ICszMSwxMCBAQCBjb25m aWcgRFJNX0kyQ19OWFBfVERBOTk4WAo+ICAJaGVscAo+ICAJICBTdXBwb3J0IGZvciBOWFAgU2Vt aWNvbmR1Y3RvcnMgVERBOTk4WCBIRE1JIGVuY29kZXJzLgo+IAo+ICtjb25maWcgRFJNX1ZHQV9T SU1QTEUKPiArCXRyaXN0YXRlICJHZW5lcmljIHNpbXBsZSB2Z2EgZW5jb2RlciIKPiArCWhlbHAK PiArCSAgU3VwcG9ydCBmb3IgdmdhIGVuY29kZXIgY2hpcHMgd2l0aG91dCBhbnkgc3BlY2lhbCBz ZXR0aW5ncwo+ICsJICBhbmQgYXQgbW9zdCBhIHBvd2VyLWNvbnRyb2wgZ3Bpby4KPiArCj4gIGVu ZG1lbnUKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2kyYy9NYWtlZmlsZSBiL2RyaXZl cnMvZ3B1L2RybS9pMmMvTWFrZWZpbGUKPiBpbmRleCAyYzcyZWI1Li44NTg5NjFmIDEwMDY0NAo+ IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pMmMvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL2dwdS9k cm0vaTJjL01ha2VmaWxlCj4gQEAgLTEwLDMgKzEwLDUgQEAgb2JqLSQoQ09ORklHX0RSTV9JMkNf U0lMMTY0KSArPSBzaWwxNjQubwo+IAo+ICB0ZGE5OTh4LXkgOj0gdGRhOTk4eF9kcnYubwo+ICBv YmotJChDT05GSUdfRFJNX0kyQ19OWFBfVERBOTk4WCkgKz0gdGRhOTk4eC5vCj4gKwo+ICtvYmot JChDT05GSUdfRFJNX1ZHQV9TSU1QTEUpICs9IHZnYS1zaW1wbGUubwo+IGRpZmYgLS1naXQgYS9k cml2ZXJzL2dwdS9kcm0vaTJjL3ZnYS1zaW1wbGUuYwo+IGIvZHJpdmVycy9ncHUvZHJtL2kyYy92 Z2Etc2ltcGxlLmMgbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwLi5iYjlkMTlj Cj4gLS0tIC9kZXYvbnVsbAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9pMmMvdmdhLXNpbXBsZS5j Cj4gQEAgLTAsMCArMSwzMjUgQEAKPiArLyoKPiArICogU2ltcGxlIHZnYSBlbmNvZGVyIGRyaXZl cgo+ICsgKgo+ICsgKiBDb3B5cmlnaHQgKEMpIDIwMTQgSGVpa28gU3R1ZWJuZXIgPGhlaWtvQHNu dGVjaC5kZT4KPiArICoKPiArICogVGhpcyBzb2Z0d2FyZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUg dGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwo+ICsgKiBMaWNlbnNlIHZlcnNpb24gMiwg YXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGFuZAo+ICsgKiBt YXkgYmUgY29waWVkLCBkaXN0cmlidXRlZCwgYW5kIG1vZGlmaWVkIHVuZGVyIHRob3NlIHRlcm1z Lgo+ICsgKgo+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhh dCBpdCB3aWxsIGJlIHVzZWZ1bCwKPiArICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRo b3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKPiArICogTUVSQ0hBTlRBQklMSVRZIG9y IEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQo+ICsgKiBHTlUgR2Vu ZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgo+ICsgKi8KPiArCj4gKyNpbmNs dWRlIDxsaW51eC9tb2R1bGUuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2NvbXBvbmVudC5oPgo+ICsj aW5jbHVkZSA8bGludXgvZ3Bpby5oPgo+ICsjaW5jbHVkZSA8bGludXgvZ3Bpby9jb25zdW1lci5o Pgo+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yZWd1bGF0b3Iv Y29uc3VtZXIuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1fb2YuaD4KPiArI2luY2x1ZGUgPGRybS9k cm1QLmg+Cj4gKyNpbmNsdWRlIDxkcm0vZHJtX2NydGMuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1f Y3J0Y19oZWxwZXIuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1fZWRpZC5oPgo+ICsKPiArI2RlZmlu ZSBjb25uZWN0b3JfdG9fdmdhX3NpbXBsZSh4KSBjb250YWluZXJfb2YoeCwgc3RydWN0IHZnYV9z aW1wbGUsCj4gY29ubmVjdG9yKSArI2RlZmluZSBlbmNvZGVyX3RvX3ZnYV9zaW1wbGUoeCkgY29u dGFpbmVyX29mKHgsIHN0cnVjdAo+IHZnYV9zaW1wbGUsIGVuY29kZXIpICsKPiArc3RydWN0IHZn YV9zaW1wbGUgewo+ICsJc3RydWN0IGRybV9jb25uZWN0b3IgY29ubmVjdG9yOwo+ICsJc3RydWN0 IGRybV9lbmNvZGVyIGVuY29kZXI7Cj4gKwo+ICsJc3RydWN0IGRldmljZSAqZGV2Owo+ICsJc3Ry dWN0IGkyY19hZGFwdGVyICpkZGM7Cj4gKwo+ICsJc3RydWN0IHJlZ3VsYXRvciAqdmFhX3JlZzsK PiArCXN0cnVjdCBncGlvX2Rlc2MgKmVuYWJsZV9ncGlvOwo+ICsKPiArCXN0cnVjdCBtdXRleCBl bmFibGVfbG9jazsKPiArCWJvb2wgZW5hYmxlZDsKPiArfTsKPiArCj4gKy8qCj4gKyAqIENvbm5l Y3RvciBmdW5jdGlvbnMKPiArICovCj4gKwo+ICtlbnVtIGRybV9jb25uZWN0b3Jfc3RhdHVzIHZn YV9zaW1wbGVfZGV0ZWN0KHN0cnVjdCBkcm1fY29ubmVjdG9yCj4gKmNvbm5lY3RvciwgKwkJCQkJ ICAgIGJvb2wgZm9yY2UpCj4gK3sKPiArCXN0cnVjdCB2Z2Ffc2ltcGxlICp2Z2EgPSBjb25uZWN0 b3JfdG9fdmdhX3NpbXBsZShjb25uZWN0b3IpOwo+ICsKPiArCWlmICghdmdhLT5kZGMpCj4gKwkJ cmV0dXJuIGNvbm5lY3Rvcl9zdGF0dXNfdW5rbm93bjsKPiArCj4gKwlpZiAoZHJtX3Byb2JlX2Rk Yyh2Z2EtPmRkYykpCj4gKwkJcmV0dXJuIGNvbm5lY3Rvcl9zdGF0dXNfY29ubmVjdGVkOwo+ICsK PiArCXJldHVybiBjb25uZWN0b3Jfc3RhdHVzX2Rpc2Nvbm5lY3RlZDsKPiArfQo+ICsKPiArdm9p ZCB2Z2Ffc2ltcGxlX2Nvbm5lY3Rvcl9kZXN0cm95KHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25u ZWN0b3IpCj4gK3sKPiArCWRybV9jb25uZWN0b3JfdW5yZWdpc3Rlcihjb25uZWN0b3IpOwo+ICsJ ZHJtX2Nvbm5lY3Rvcl9jbGVhbnVwKGNvbm5lY3Rvcik7Cj4gK30KPiArCj4gK3N0cnVjdCBkcm1f Y29ubmVjdG9yX2Z1bmNzIHZnYV9zaW1wbGVfY29ubmVjdG9yX2Z1bmNzID0gewo+ICsJLmRwbXMg PSBkcm1faGVscGVyX2Nvbm5lY3Rvcl9kcG1zLAo+ICsJLmZpbGxfbW9kZXMgPSBkcm1faGVscGVy X3Byb2JlX3NpbmdsZV9jb25uZWN0b3JfbW9kZXMsCj4gKwkuZGV0ZWN0ID0gdmdhX3NpbXBsZV9k ZXRlY3QsCj4gKwkuZGVzdHJveSA9IHZnYV9zaW1wbGVfY29ubmVjdG9yX2Rlc3Ryb3ksCj4gK307 Cj4gKwo+ICsvKgo+ICsgKiBDb25uZWN0b3IgaGVscGVyIGZ1bmN0aW9ucwo+ICsgKi8KPiArCj4g K3N0YXRpYyBpbnQgdmdhX3NpbXBsZV9jb25uZWN0b3JfZ2V0X21vZGVzKHN0cnVjdCBkcm1fY29u bmVjdG9yICpjb25uZWN0b3IpCj4gK3sKPiArCXN0cnVjdCB2Z2Ffc2ltcGxlICp2Z2EgPSBjb25u ZWN0b3JfdG9fdmdhX3NpbXBsZShjb25uZWN0b3IpOwo+ICsJc3RydWN0IGVkaWQgKmVkaWQ7Cj4g KwlpbnQgcmV0ID0gMDsKPiArCj4gKwlpZiAoIXZnYS0+ZGRjKQo+ICsJCXJldHVybiAwOwo+ICsK PiArCWVkaWQgPSBkcm1fZ2V0X2VkaWQoY29ubmVjdG9yLCB2Z2EtPmRkYyk7Cj4gKwlpZiAoZWRp ZCkgewo+ICsJCWRybV9tb2RlX2Nvbm5lY3Rvcl91cGRhdGVfZWRpZF9wcm9wZXJ0eShjb25uZWN0 b3IsIGVkaWQpOwo+ICsJCXJldCA9IGRybV9hZGRfZWRpZF9tb2Rlcyhjb25uZWN0b3IsIGVkaWQp Owo+ICsJCWtmcmVlKGVkaWQpOwo+ICsJfQo+ICsKPiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4g K3N0YXRpYyBpbnQgdmdhX3NpbXBsZV9jb25uZWN0b3JfbW9kZV92YWxpZChzdHJ1Y3QgZHJtX2Nv bm5lY3RvciAqY29ubmVjdG9yLAo+ICsJCQkJCXN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2Rl KQo+ICt7Cj4gKwlyZXR1cm4gTU9ERV9PSzsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBkcm1f ZW5jb2Rlcgo+ICsqdmdhX3NpbXBsZV9jb25uZWN0b3JfYmVzdF9lbmNvZGVyKHN0cnVjdCBkcm1f Y29ubmVjdG9yICpjb25uZWN0b3IpCj4gK3sKPiArCXN0cnVjdCB2Z2Ffc2ltcGxlICp2Z2EgPSBj b25uZWN0b3JfdG9fdmdhX3NpbXBsZShjb25uZWN0b3IpOwo+ICsKPiArCXJldHVybiAmdmdhLT5l bmNvZGVyOwo+ICt9Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGRybV9jb25uZWN0b3JfaGVscGVyX2Z1 bmNzIHZnYV9zaW1wbGVfY29ubmVjdG9yX2hlbHBlcl9mdW5jcwo+ID0geyArCS5nZXRfbW9kZXMg PSB2Z2Ffc2ltcGxlX2Nvbm5lY3Rvcl9nZXRfbW9kZXMsCj4gKwkuYmVzdF9lbmNvZGVyID0gdmdh X3NpbXBsZV9jb25uZWN0b3JfYmVzdF9lbmNvZGVyLAo+ICsJLm1vZGVfdmFsaWQgPSB2Z2Ffc2lt cGxlX2Nvbm5lY3Rvcl9tb2RlX3ZhbGlkLAo+ICt9Owo+ICsKPiArLyoKPiArICogRW5jb2RlciBm dW5jdGlvbnMKPiArICovCj4gKwo+ICtzdGF0aWMgdm9pZCB2Z2Ffc2ltcGxlX2VuY29kZXJfZGVz dHJveShzdHJ1Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4gK3sKPiArCWRybV9lbmNvZGVyX2Ns ZWFudXAoZW5jb2Rlcik7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2VuY29k ZXJfZnVuY3MgdmdhX3NpbXBsZV9lbmNvZGVyX2Z1bmNzID0gewo+ICsJLmRlc3Ryb3kgPSB2Z2Ff c2ltcGxlX2VuY29kZXJfZGVzdHJveSwKPiArfTsKPiArCj4gKy8qCj4gKyAqIEVuY29kZXIgaGVs cGVyIGZ1bmN0aW9ucwo+ICsgKi8KPiArCj4gK3N0YXRpYyB2b2lkIHZnYV9zaW1wbGVfZW5jb2Rl cl9kcG1zKHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwgaW50IG1vZGUpCj4gK3sKPiArCXN0 cnVjdCB2Z2Ffc2ltcGxlICp2Z2EgPSBlbmNvZGVyX3RvX3ZnYV9zaW1wbGUoZW5jb2Rlcik7Cj4g Kwo+ICsJbXV0ZXhfbG9jaygmdmdhLT5lbmFibGVfbG9jayk7Cj4gKwo+ICsJc3dpdGNoIChtb2Rl KSB7Cj4gKwljYXNlIERSTV9NT0RFX0RQTVNfT046Cj4gKwkJaWYgKHZnYS0+ZW5hYmxlZCkKPiAr CQkJZ290byBvdXQ7Cj4gKwo+ICsJCWlmICghSVNfRVJSKHZnYS0+dmFhX3JlZykpCj4gKwkJCXJl Z3VsYXRvcl9lbmFibGUodmdhLT52YWFfcmVnKTsKPiArCj4gKwkJaWYgKHZnYS0+ZW5hYmxlX2dw aW8pCj4gKwkJCWdwaW9kX3NldF92YWx1ZSh2Z2EtPmVuYWJsZV9ncGlvLCAxKTsKPiArCj4gKwkJ dmdhLT5lbmFibGVkID0gdHJ1ZTsKPiArCQlicmVhazsKPiArCWNhc2UgRFJNX01PREVfRFBNU19T VEFOREJZOgo+ICsJY2FzZSBEUk1fTU9ERV9EUE1TX1NVU1BFTkQ6Cj4gKwljYXNlIERSTV9NT0RF X0RQTVNfT0ZGOgo+ICsJCWlmICghdmdhLT5lbmFibGVkKQo+ICsJCQlnb3RvIG91dDsKPiArCj4g KwkJaWYgKHZnYS0+ZW5hYmxlX2dwaW8pCj4gKwkJCWdwaW9kX3NldF92YWx1ZSh2Z2EtPmVuYWJs ZV9ncGlvLCAwKTsKPiArCj4gKwkJaWYgKCFJU19FUlIodmdhLT52YWFfcmVnKSkKPiArCQkJcmVn dWxhdG9yX2VuYWJsZSh2Z2EtPnZhYV9yZWcpOwo+ICsKPiArCQl2Z2EtPmVuYWJsZWQgPSBmYWxz ZTsKPiArCQlicmVhazsKPiArCWRlZmF1bHQ6Cj4gKwkJYnJlYWs7Cj4gKwl9Cj4gKwo+ICtvdXQ6 Cj4gKwltdXRleF91bmxvY2soJnZnYS0+ZW5hYmxlX2xvY2spOwo+ICt9Cj4gKwo+ICtzdGF0aWMg Ym9vbCB2Z2Ffc2ltcGxlX21vZGVfZml4dXAoc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyLAo+ ICsJCQkJICBjb25zdCBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSwKPiArCQkJCSAgc3Ry dWN0IGRybV9kaXNwbGF5X21vZGUgKmFkanVzdGVkX21vZGUpCj4gK3sKPiArCXJldHVybiB0cnVl Owo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2Z2Ffc2ltcGxlX2VuY29kZXJfcHJlcGFyZShzdHJ1 Y3QgZHJtX2VuY29kZXIgKmVuY29kZXIpCj4gK3sKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgdmdh X3NpbXBsZV9lbmNvZGVyX21vZGVfc2V0KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlciwKPiAr CQkJCQlzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSwKPiArCQkJCQlzdHJ1Y3QgZHJtX2Rp c3BsYXlfbW9kZSAqYWRqdXN0ZWRfbW9kZSkKPiArewo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2 Z2Ffc2ltcGxlX2VuY29kZXJfY29tbWl0KHN0cnVjdCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPiAr ewo+ICsJdmdhX3NpbXBsZV9lbmNvZGVyX2RwbXMoZW5jb2RlciwgRFJNX01PREVfRFBNU19PTik7 Cj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHZnYV9zaW1wbGVfZW5jb2Rlcl9kaXNhYmxlKHN0cnVj dCBkcm1fZW5jb2RlciAqZW5jb2RlcikKPiArewo+ICsJdmdhX3NpbXBsZV9lbmNvZGVyX2RwbXMo ZW5jb2RlciwgRFJNX01PREVfRFBNU19PRkYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3Ry dWN0IGRybV9lbmNvZGVyX2hlbHBlcl9mdW5jcwo+IHZnYV9zaW1wbGVfZW5jb2Rlcl9oZWxwZXJf ZnVuY3MgPSB7Cj4gKwkuZHBtcyA9IHZnYV9zaW1wbGVfZW5jb2Rlcl9kcG1zLAo+ICsJLm1vZGVf Zml4dXAgPSB2Z2Ffc2ltcGxlX21vZGVfZml4dXAsCj4gKwkucHJlcGFyZSA9IHZnYV9zaW1wbGVf ZW5jb2Rlcl9wcmVwYXJlLAo+ICsJLm1vZGVfc2V0ID0gdmdhX3NpbXBsZV9lbmNvZGVyX21vZGVf c2V0LAo+ICsJLmNvbW1pdCA9IHZnYV9zaW1wbGVfZW5jb2Rlcl9jb21taXQsCj4gKwkuZGlzYWJs ZSA9IHZnYV9zaW1wbGVfZW5jb2Rlcl9kaXNhYmxlLAoKdGhpcyBpcyBpbnRlcmVzdGluZy4gU29t ZSB1c2VycyBvZiB0aGlzIGVuY29kZXIgKEknbSB0aGlua2luZyBhYm91dCByY2FyLWR1LCAKZm9y IHdoaWNoIEkndmUganVzdCBwb3N0ZWQgdGhlIHBhdGNoZXMpIGFyZSBhbHJlYWR5IHBvcnRlZCB0 byBhdG9taWMgdXBkYXRlcywgCndoaWxlIG90aGVycyBhcmUgbm90LiBIb3cgY2FuIHdlIHN1cHBv cnQgYm90aCA/Cgo+ICt9Owo+ICsKPiArLyoKPiArICogQ29tcG9uZW50IGhlbHBlciBmdW5jdGlv bnMKPiArICovCj4gKwo+ICtzdGF0aWMgaW50IHZnYV9zaW1wbGVfYmluZChzdHJ1Y3QgZGV2aWNl ICpkZXYsIHN0cnVjdCBkZXZpY2UgKm1hc3RlciwKPiArCQkJCSB2b2lkICpkYXRhKQo+ICt7Cj4g KwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2ID0gdG9fcGxhdGZvcm1fZGV2aWNlKGRldik7 Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZHJtID0gZGF0YTsKPiArCj4gKwlzdHJ1Y3QgZGV2aWNl X25vZGUgKmRkY19ub2RlLCAqbnAgPSBwZGV2LT5kZXYub2Zfbm9kZTsKPiArCXN0cnVjdCB2Z2Ff c2ltcGxlICp2Z2E7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCWlmICghbnApCj4gKwkJcmV0dXJuIC1F Tk9ERVY7Cj4gKwo+ICsJdmdhID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCp2Z2EpLCBHRlBf S0VSTkVMKTsKPiArCWlmICghdmdhKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCXZnYS0+ ZGV2ID0gZGV2Owo+ICsJZGV2X3NldF9kcnZkYXRhKGRldiwgdmdhKTsKPiArCW11dGV4X2luaXQo JnZnYS0+ZW5hYmxlX2xvY2spOwo+ICsKPiArCXZnYS0+ZW5hYmxlX2dwaW8gPSBkZXZtX2dwaW9k X2dldF9vcHRpb25hbChkZXYsICJlbmFibGUiLAo+ICsJCQkJCQkgICBHUElPRF9PVVRfTE9XKTsK PiArCWlmIChJU19FUlIodmdhLT5lbmFibGVfZ3BpbykpIHsKPiArCQlyZXQgPSBQVFJfRVJSKHZn YS0+ZW5hYmxlX2dwaW8pOwo+ICsJCWRldl9lcnIoZGV2LCAiZmFpbGVkIHRvIHJlcXVlc3QgR1BJ TzogJWRcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwl2Z2EtPmVuYWJs ZWQgPSBmYWxzZTsKPiArCj4gKwlkZGNfbm9kZSA9IG9mX3BhcnNlX3BoYW5kbGUobnAsICJkZGMt aTJjLWJ1cyIsIDApOwo+ICsJaWYgKGRkY19ub2RlKSB7Cj4gKwkJdmdhLT5kZGMgPSBvZl9maW5k X2kyY19hZGFwdGVyX2J5X25vZGUoZGRjX25vZGUpOwo+ICsJCW9mX25vZGVfcHV0KGRkY19ub2Rl KTsKPiArCQlpZiAoIXZnYS0+ZGRjKSB7Cj4gKwkJCWRldl9kYmcodmdhLT5kZXYsICJmYWlsZWQg dG8gcmVhZCBkZGMgbm9kZVxuIik7Cj4gKwkJCXJldHVybiAtRVBST0JFX0RFRkVSOwo+ICsJCX0K PiArCX0gZWxzZSB7Cj4gKwkJZGV2X2RiZyh2Z2EtPmRldiwgIm5vIGRkYyBwcm9wZXJ0eSBmb3Vu ZFxuIik7Cj4gKwl9Cj4gKwo+ICsJdmdhLT52YWFfcmVnID0gZGV2bV9yZWd1bGF0b3JfZ2V0X29w dGlvbmFsKGRldiwgInZhYSIpOwo+ICsKPiArCXZnYS0+ZW5jb2Rlci5wb3NzaWJsZV9jcnRjcyA9 IGRybV9vZl9maW5kX3Bvc3NpYmxlX2NydGNzKGRybSwgbnApOwo+ICsJdmdhLT5lbmNvZGVyLm9m X25vZGUgPSBucDsKPiArCXZnYS0+Y29ubmVjdG9yLnBvbGxlZCA9IERSTV9DT05ORUNUT1JfUE9M TF9DT05ORUNUIHwKPiArCQkJCURSTV9DT05ORUNUT1JfUE9MTF9ESVNDT05ORUNUOwo+ICsKPiAr CWRybV9lbmNvZGVyX2hlbHBlcl9hZGQoJnZnYS0+ZW5jb2RlciwgJnZnYV9zaW1wbGVfZW5jb2Rl cl9oZWxwZXJfZnVuY3MpOwo+ICsJZHJtX2VuY29kZXJfaW5pdChkcm0sICZ2Z2EtPmVuY29kZXIs ICZ2Z2Ffc2ltcGxlX2VuY29kZXJfZnVuY3MsCj4gKwkJCSBEUk1fTU9ERV9FTkNPREVSX0RBQyk7 Cj4gKwo+ICsJZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfYWRkKCZ2Z2EtPmNvbm5lY3RvciwKPiArCQkJ CSAmdmdhX3NpbXBsZV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzKTsKCkkgcmVhbGx5IGRpc2xpa2Ug dGhpcywgdGhpcyBpcyBhbiBlbmNvZGVyIGRyaXZlciwgbm90IGEgY29ubmVjdG9yIGRyaXZlci4g SXQgCnNob3VsZG4ndCBiZSByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgdGhlIGNvbm5lY3Rvci4g Rm9yIGFsbCBpdCBrbm93cywgdGhlcmUgCm1pZ2h0IG5vdCBldmVuIGJlIGEgVkdBIGNvbm5lY3Rv ciBjb25uZWN0ZWQgdG8gdGhlIGVuY29kZXIsIFZHQSBzaWduYWxzIGNvdWxkIApiZSBzZW50IHRv IGEgY2hhaW5lZCBlbmNvZGVyLiBUaGF0IG1pZ2h0IGJlIGEgYml0IGZhci1mZXRjaGVkIGluIHRo ZSBWR0EgY2FzZSwgCmJ1dCBpbiB0aGUgZ2VuZXJpYyBjYXNlIGVuY29kZXIgZHJpdmVycyBzaG91 bGRuJ3QgY3JlYXRlIGNvbm5lY3RvcnMuCgo+ICsJZHJtX2Nvbm5lY3Rvcl9pbml0KGRybSwgJnZn YS0+Y29ubmVjdG9yLCAmdmdhX3NpbXBsZV9jb25uZWN0b3JfZnVuY3MsCj4gKwkJCSAgIERSTV9N T0RFX0NPTk5FQ1RPUl9WR0EpOwo+ICsKPiArCWRybV9tb2RlX2Nvbm5lY3Rvcl9hdHRhY2hfZW5j b2RlcigmdmdhLT5jb25uZWN0b3IsICZ2Z2EtPmVuY29kZXIpOwo+ICsKPiArCXJldHVybiAwOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCB2Z2Ffc2ltcGxlX3VuYmluZChzdHJ1Y3QgZGV2aWNlICpk ZXYsIHN0cnVjdCBkZXZpY2UgKm1hc3RlciwKPiArCQkJCSAgICB2b2lkICpkYXRhKQo+ICt7Cj4g KwlzdHJ1Y3QgdmdhX3NpbXBsZSAqdmdhID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwo+ICsJ dmdhLT5jb25uZWN0b3IuZnVuY3MtPmRlc3Ryb3koJnZnYS0+Y29ubmVjdG9yKTsKPiArCXZnYS0+ ZW5jb2Rlci5mdW5jcy0+ZGVzdHJveSgmdmdhLT5lbmNvZGVyKTsKPiArfQo+ICsKPiArc3RhdGlj IGNvbnN0IHN0cnVjdCBjb21wb25lbnRfb3BzIHZnYV9zaW1wbGVfb3BzID0gewo+ICsJLmJpbmQg PSB2Z2Ffc2ltcGxlX2JpbmQsCj4gKwkudW5iaW5kID0gdmdhX3NpbXBsZV91bmJpbmQsCj4gK307 Cj4gKwo+ICtzdGF0aWMgaW50IHZnYV9zaW1wbGVfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2Rldmlj ZSAqcGRldikKPiArewo+ICsJcmV0dXJuIGNvbXBvbmVudF9hZGQoJnBkZXYtPmRldiwgJnZnYV9z aW1wbGVfb3BzKTsKPiArfQo+ICsKPiArc3RhdGljIGludCB2Z2Ffc2ltcGxlX3JlbW92ZShzdHJ1 Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwljb21wb25lbnRfZGVsKCZwZGV2LT5k ZXYsICZ2Z2Ffc2ltcGxlX29wcyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRp YyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIHZnYV9zaW1wbGVfaWRzW10gPSB7Cj4gKwl7IC5j b21wYXRpYmxlID0gImFkaSxhZHY3MTIzIiwgfSwKPiArCXt9LAo+ICt9Owo+ICtNT0RVTEVfREVW SUNFX1RBQkxFKG9mLCB2Z2Ffc2ltcGxlX2lkcyk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRm b3JtX2RyaXZlciB2Z2Ffc2ltcGxlX2RyaXZlciA9IHsKPiArCS5wcm9iZSAgPSB2Z2Ffc2ltcGxl X3Byb2JlLAo+ICsJLnJlbW92ZSA9IHZnYV9zaW1wbGVfcmVtb3ZlLAo+ICsJLmRyaXZlciA9IHsK PiArCQkubmFtZSA9ICJ2Z2Etc2ltcGxlIiwKPiArCQkub2ZfbWF0Y2hfdGFibGUgPSB2Z2Ffc2lt cGxlX2lkcywKPiArCX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIodmdhX3NpbXBs ZV9kcml2ZXIpOwo+ICsKPiArTU9EVUxFX0FVVEhPUigiSGVpa28gU3R1ZWJuZXIgPGhlaWtvQHNu dGVjaC5kZT4iKTsKPiArTU9EVUxFX0RFU0NSSVBUSU9OKCJTaW1wbGUgdmdhIGNvbnZlcnRlciIp Owo+ICtNT0RVTEVfTElDRU5TRSgiR1BMIik7CgotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hh cnQKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1k ZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwOi8v bGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJpLWRldmVsCg==