From mboxrd@z Thu Jan 1 00:00:00 1970 From: architt@codeaurora.org (Archit Taneja) Date: Mon, 3 Oct 2016 16:40:57 +0530 Subject: [PATCH v5 2/5] drm/bridge: Add RGB to VGA bridge support In-Reply-To: <20160930143709.1388-3-maxime.ripard@free-electrons.com> References: <20160930143709.1388-1-maxime.ripard@free-electrons.com> <20160930143709.1388-3-maxime.ripard@free-electrons.com> Message-ID: <8795dc49-26f9-0505-f442-2ca74b51872f@codeaurora.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Maxime, On 09/30/2016 08:07 PM, Maxime Ripard wrote: > Some boards have an entirely passive RGB to VGA bridge, based on either > DACs or resistor ladders. > > Those might or might not have an i2c bus routed to the VGA connector in > order to access the screen EDIDs. > > Add a bridge that doesn't do anything but expose the modes available on the > screen, either based on the EDIDs if available, or based on the XGA > standards. > > Acked-by: Rob Herring > Signed-off-by: Maxime Ripard > --- > .../bindings/display/bridge/rgb-to-vga-bridge.txt | 48 +++++ > drivers/gpu/drm/bridge/Kconfig | 7 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/rgb-to-vga.c | 229 +++++++++++++++++++++ > 4 files changed, 285 insertions(+) > create mode 100644 Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt > create mode 100644 drivers/gpu/drm/bridge/rgb-to-vga.c > > diff --git a/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt > new file mode 100644 > index 000000000000..a8375bc1f9cb > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt > @@ -0,0 +1,48 @@ > +Dumb RGB to VGA bridge > +---------------------- > + > +This binding is aimed for dumb RGB to VGA bridges that do not require > +any configuration. > + > +Required properties: > + > +- compatible: Must be "rgb-to-vga-bridge" I'd talked to Laurent on IRC if he's okay with this. And I guess you to had discussed it during XDC too. He's suggested that it'd be better to have the compatible string as "simple-vga-dac". Some of the reasons behind having this: - We don't need to specify "rgb" in the compatible string since most simple VGA DACs can only work with an RGB input. - Also, with "dac" specified in the string, we don't need to specifically mention "bridge" in the string. Also, bridge is a drm specific term. - "simple" is considered because it's an unconfigurable bridge, and it might be misleading for other VGA DACs to not use "vga-dac". What do you think about this? If you think it's good, would it be possible for you to change this? I guess it's okay for the rest of the patch to stay the same. Sorry about the churn. Thanks, Archit > + > +Required nodes: > + > +This device has two video ports. Their connections are modeled using the OF > +graph bindings specified in Documentation/devicetree/bindings/graph.txt. > + > +- Video port 0 for RGB input > +- Video port 1 for VGA output > + > + > +Example > +------- > + > +bridge { > + compatible = "rgb-to-vga-bridge"; > + #address-cells = <1>; > + #size-cells = <0>; > + > + ports { > + #address-cells = <1>; > + #size-cells = <0>; > + > + port at 0 { > + reg = <0>; > + > + vga_bridge_in: endpoint { > + remote-endpoint = <&tcon0_out_vga>; > + }; > + }; > + > + port at 1 { > + reg = <1>; > + > + vga_bridge_out: endpoint { > + remote-endpoint = <&vga_con_in>; > + }; > + }; > + }; > +}; > diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig > index b590e678052d..d690398c541c 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -17,6 +17,13 @@ config DRM_ANALOGIX_ANX78XX > the HDMI output of an application processor to MyDP > or DisplayPort. > > +config DRM_RGB_TO_VGA > + tristate "Dumb RGB to VGA Bridge support" > + depends on OF > + select DRM_KMS_HELPER > + help > + Support for passive RGB to VGA bridges > + > config DRM_DW_HDMI > tristate > select DRM_KMS_HELPER > diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile > index efdb07e878f5..3bb8cbe09fe9 100644 > --- a/drivers/gpu/drm/bridge/Makefile > +++ b/drivers/gpu/drm/bridge/Makefile > @@ -1,6 +1,7 @@ > ccflags-y := -Iinclude/drm > > obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o > +obj-$(CONFIG_DRM_RGB_TO_VGA) += rgb-to-vga.o > obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o > obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o > obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o > diff --git a/drivers/gpu/drm/bridge/rgb-to-vga.c b/drivers/gpu/drm/bridge/rgb-to-vga.c > new file mode 100644 > index 000000000000..5ff4d4f3598f > --- /dev/null > +++ b/drivers/gpu/drm/bridge/rgb-to-vga.c > @@ -0,0 +1,229 @@ > +/* > + * Copyright (C) 2015-2016 Free Electrons > + * Copyright (C) 2015-2016 NextThing Co > + * > + * Maxime Ripard > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of > + * the License, or (at your option) any later version. > + */ > + > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +struct dumb_vga { > + struct drm_bridge bridge; > + struct drm_connector connector; > + > + struct i2c_adapter *ddc; > +}; > + > +static inline struct dumb_vga * > +drm_bridge_to_dumb_vga(struct drm_bridge *bridge) > +{ > + return container_of(bridge, struct dumb_vga, bridge); > +} > + > +static inline struct dumb_vga * > +drm_connector_to_dumb_vga(struct drm_connector *connector) > +{ > + return container_of(connector, struct dumb_vga, connector); > +} > + > +static int dumb_vga_get_modes(struct drm_connector *connector) > +{ > + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); > + struct edid *edid; > + int ret; > + > + if (IS_ERR(vga->ddc)) > + goto fallback; > + > + edid = drm_get_edid(connector, vga->ddc); > + if (!edid) { > + DRM_INFO("EDID readout failed, falling back to standard modes\n"); > + goto fallback; > + } > + > + drm_mode_connector_update_edid_property(connector, edid); > + return drm_add_edid_modes(connector, edid); > + > +fallback: > + /* > + * In case we cannot retrieve the EDIDs (broken or missing i2c > + * bus), fallback on the XGA standards > + */ > + ret = drm_add_modes_noedid(connector, 1920, 1200); > + > + /* And prefer a mode pretty much anyone can handle */ > + drm_set_preferred_mode(connector, 1024, 768); > + > + return ret; > +} > + > +static const struct drm_connector_helper_funcs dumb_vga_con_helper_funcs = { > + .get_modes = dumb_vga_get_modes, > +}; > + > +static enum drm_connector_status > +dumb_vga_connector_detect(struct drm_connector *connector, bool force) > +{ > + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); > + > + /* > + * Even if we have an I2C bus, we can't assume that the cable > + * is disconnected if drm_probe_ddc fails. Some cables don't > + * wire the DDC pins, or the I2C bus might not be working at > + * all. > + */ > + if (!IS_ERR(vga->ddc) && drm_probe_ddc(vga->ddc)) > + return connector_status_connected; > + > + return connector_status_unknown; > +} > + > +static void > +dumb_vga_connector_destroy(struct drm_connector *connector) > +{ > + drm_connector_cleanup(connector); > +} > + > +static const struct drm_connector_funcs dumb_vga_con_funcs = { > + .dpms = drm_atomic_helper_connector_dpms, > + .detect = dumb_vga_connector_detect, > + .fill_modes = drm_helper_probe_single_connector_modes, > + .destroy = dumb_vga_connector_destroy, > + .reset = drm_atomic_helper_connector_reset, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > +}; > + > +static int dumb_vga_attach(struct drm_bridge *bridge) > +{ > + struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge); > + int ret; > + > + if (!bridge->encoder) { > + DRM_ERROR("Missing encoder\n"); > + return -ENODEV; > + } > + > + drm_connector_helper_add(&vga->connector, > + &dumb_vga_con_helper_funcs); > + ret = drm_connector_init(bridge->dev, &vga->connector, > + &dumb_vga_con_funcs, DRM_MODE_CONNECTOR_VGA); > + if (ret) { > + DRM_ERROR("Failed to initialize connector\n"); > + return ret; > + } > + > + drm_mode_connector_attach_encoder(&vga->connector, > + bridge->encoder); > + > + return 0; > +} > + > +static const struct drm_bridge_funcs dumb_vga_bridge_funcs = { > + .attach = dumb_vga_attach, > +}; > + > +static struct i2c_adapter *dumb_vga_retrieve_ddc(struct device *dev) > +{ > + struct device_node *end_node, *phandle, *remote; > + struct i2c_adapter *ddc; > + > + end_node = of_graph_get_endpoint_by_regs(dev->of_node, 1, -1); > + if (!end_node) { > + dev_err(dev, "Missing connector endpoint\n"); > + return ERR_PTR(-ENODEV); > + } > + > + remote = of_graph_get_remote_port_parent(end_node); > + of_node_put(end_node); > + if (!remote) { > + dev_err(dev, "Enable to parse remote node\n"); > + return ERR_PTR(-EINVAL); > + } > + > + phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0); > + of_node_put(remote); > + if (!phandle) > + return ERR_PTR(-ENODEV); > + > + ddc = of_get_i2c_adapter_by_node(phandle); > + of_node_put(phandle); > + if (!ddc) > + return ERR_PTR(-EPROBE_DEFER); > + > + return ddc; > +} > + > +static int dumb_vga_probe(struct platform_device *pdev) > +{ > + struct dumb_vga *vga; > + int ret; > + > + vga = devm_kzalloc(&pdev->dev, sizeof(*vga), GFP_KERNEL); > + if (!vga) > + return -ENOMEM; > + platform_set_drvdata(pdev, vga); > + > + vga->ddc = dumb_vga_retrieve_ddc(&pdev->dev); > + if (IS_ERR(vga->ddc)) { > + if (PTR_ERR(vga->ddc) == -ENODEV) { > + dev_info(&pdev->dev, > + "No i2c bus specified... Disabling EDID readout\n"); > + } else { > + dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n"); > + return PTR_ERR(vga->ddc); > + } > + } > + > + vga->bridge.funcs = &dumb_vga_bridge_funcs; > + vga->bridge.of_node = pdev->dev.of_node; > + > + ret = drm_bridge_add(&vga->bridge); > + if (ret && !IS_ERR(vga->ddc)) > + i2c_put_adapter(vga->ddc); > + > + return ret; > +} > + > +static int dumb_vga_remove(struct platform_device *pdev) > +{ > + struct dumb_vga *vga = platform_get_drvdata(pdev); > + > + drm_bridge_remove(&vga->bridge); > + > + if (!IS_ERR(vga->ddc)) > + i2c_put_adapter(vga->ddc); > + > + return 0; > +} > + > +static const struct of_device_id dumb_vga_match[] = { > + { .compatible = "rgb-to-vga-bridge" }, > + {}, > +}; > +MODULE_DEVICE_TABLE(of, dumb_vga_match); > + > +struct platform_driver dumb_vga_driver = { > + .probe = dumb_vga_probe, > + .remove = dumb_vga_remove, > + .driver = { > + .name = "rgb-to-vga-bridge", > + .of_match_table = dumb_vga_match, > + }, > +}; > +module_platform_driver(dumb_vga_driver); > + > +MODULE_AUTHOR("Maxime Ripard "); > +MODULE_DESCRIPTION("Dumb RGB to VGA bridge driver"); > +MODULE_LICENSE("GPL"); > -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project From mboxrd@z Thu Jan 1 00:00:00 1970 From: Archit Taneja Subject: Re: [PATCH v5 2/5] drm/bridge: Add RGB to VGA bridge support Date: Mon, 3 Oct 2016 16:40:57 +0530 Message-ID: <8795dc49-26f9-0505-f442-2ca74b51872f@codeaurora.org> References: <20160930143709.1388-1-maxime.ripard@free-electrons.com> <20160930143709.1388-3-maxime.ripard@free-electrons.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20160930143709.1388-3-maxime.ripard@free-electrons.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Maxime Ripard , Rob Herring , Daniel Vetter , David Airlie Cc: devicetree@vger.kernel.org, Chen-Yu Tsai , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org SGkgTWF4aW1lLAoKT24gMDkvMzAvMjAxNiAwODowNyBQTSwgTWF4aW1lIFJpcGFyZCB3cm90ZToK PiBTb21lIGJvYXJkcyBoYXZlIGFuIGVudGlyZWx5IHBhc3NpdmUgUkdCIHRvIFZHQSBicmlkZ2Us IGJhc2VkIG9uIGVpdGhlcgo+IERBQ3Mgb3IgcmVzaXN0b3IgbGFkZGVycy4KPgo+IFRob3NlIG1p Z2h0IG9yIG1pZ2h0IG5vdCBoYXZlIGFuIGkyYyBidXMgcm91dGVkIHRvIHRoZSBWR0EgY29ubmVj dG9yIGluCj4gb3JkZXIgdG8gYWNjZXNzIHRoZSBzY3JlZW4gRURJRHMuCj4KPiBBZGQgYSBicmlk Z2UgdGhhdCBkb2Vzbid0IGRvIGFueXRoaW5nIGJ1dCBleHBvc2UgdGhlIG1vZGVzIGF2YWlsYWJs ZSBvbiB0aGUKPiBzY3JlZW4sIGVpdGhlciBiYXNlZCBvbiB0aGUgRURJRHMgaWYgYXZhaWxhYmxl LCBvciBiYXNlZCBvbiB0aGUgWEdBCj4gc3RhbmRhcmRzLgo+Cj4gQWNrZWQtYnk6IFJvYiBIZXJy aW5nIDxyb2JoQGtlcm5lbC5vcmc+Cj4gU2lnbmVkLW9mZi1ieTogTWF4aW1lIFJpcGFyZCA8bWF4 aW1lLnJpcGFyZEBmcmVlLWVsZWN0cm9ucy5jb20+Cj4gLS0tCj4gIC4uLi9iaW5kaW5ncy9kaXNw bGF5L2JyaWRnZS9yZ2ItdG8tdmdhLWJyaWRnZS50eHQgIHwgIDQ4ICsrKysrCj4gIGRyaXZlcnMv Z3B1L2RybS9icmlkZ2UvS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgIHwgICA3ICsKPiAgZHJp dmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZSAgICAgICAgICAgICAgICAgICAgfCAgIDEgKwo+ ICBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL3JnYi10by12Z2EuYyAgICAgICAgICAgICAgICB8IDIy OSArKysrKysrKysrKysrKysrKysrKysKPiAgNCBmaWxlcyBjaGFuZ2VkLCAyODUgaW5zZXJ0aW9u cygrKQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRp bmdzL2Rpc3BsYXkvYnJpZGdlL3JnYi10by12Z2EtYnJpZGdlLnR4dAo+ICBjcmVhdGUgbW9kZSAx MDA2NDQgZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9yZ2ItdG8tdmdhLmMKPgo+IGRpZmYgLS1naXQg YS9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGlzcGxheS9icmlkZ2UvcmdiLXRv LXZnYS1icmlkZ2UudHh0IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Rpc3Bs YXkvYnJpZGdlL3JnYi10by12Z2EtYnJpZGdlLnR4dAo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4g aW5kZXggMDAwMDAwMDAwMDAwLi5hODM3NWJjMWY5Y2IKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIv RG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL2Rpc3BsYXkvYnJpZGdlL3JnYi10by12 Z2EtYnJpZGdlLnR4dAo+IEBAIC0wLDAgKzEsNDggQEAKPiArRHVtYiBSR0IgdG8gVkdBIGJyaWRn ZQo+ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tCj4gKwo+ICtUaGlzIGJpbmRpbmcgaXMgYWltZWQg Zm9yIGR1bWIgUkdCIHRvIFZHQSBicmlkZ2VzIHRoYXQgZG8gbm90IHJlcXVpcmUKPiArYW55IGNv bmZpZ3VyYXRpb24uCj4gKwo+ICtSZXF1aXJlZCBwcm9wZXJ0aWVzOgo+ICsKPiArLSBjb21wYXRp YmxlOiBNdXN0IGJlICJyZ2ItdG8tdmdhLWJyaWRnZSIKCkknZCB0YWxrZWQgdG8gTGF1cmVudCBv biBJUkMgaWYgaGUncyBva2F5IHdpdGggdGhpcy4gQW5kIEkgZ3Vlc3MgeW91IHRvCmhhZCBkaXNj dXNzZWQgaXQgZHVyaW5nIFhEQyB0b28uIEhlJ3Mgc3VnZ2VzdGVkIHRoYXQgaXQnZCBiZSBiZXR0 ZXIgdG8KaGF2ZSB0aGUgY29tcGF0aWJsZSBzdHJpbmcgYXMgInNpbXBsZS12Z2EtZGFjIi4KClNv bWUgb2YgdGhlIHJlYXNvbnMgYmVoaW5kIGhhdmluZyB0aGlzOgoKLSBXZSBkb24ndCBuZWVkIHRv IHNwZWNpZnkgInJnYiIgaW4gdGhlIGNvbXBhdGlibGUgc3RyaW5nIHNpbmNlIG1vc3QKc2ltcGxl IFZHQSBEQUNzIGNhbiBvbmx5IHdvcmsgd2l0aCBhbiBSR0IgaW5wdXQuCi0gQWxzbywgd2l0aCAi ZGFjIiBzcGVjaWZpZWQgaW4gdGhlIHN0cmluZywgd2UgZG9uJ3QgbmVlZCB0bwpzcGVjaWZpY2Fs bHkgbWVudGlvbiAiYnJpZGdlIiBpbiB0aGUgc3RyaW5nLiBBbHNvLCBicmlkZ2UgaXMgYSBkcm0K c3BlY2lmaWMgdGVybS4KLSAic2ltcGxlIiBpcyBjb25zaWRlcmVkIGJlY2F1c2UgaXQncyBhbiB1 bmNvbmZpZ3VyYWJsZSBicmlkZ2UsIGFuZCBpdAptaWdodCBiZSBtaXNsZWFkaW5nIGZvciBvdGhl ciBWR0EgREFDcyB0byBub3QgdXNlICJ2Z2EtZGFjIi4KCldoYXQgZG8geW91IHRoaW5rIGFib3V0 IHRoaXM/IElmIHlvdSB0aGluayBpdCdzIGdvb2QsIHdvdWxkIGl0IGJlCnBvc3NpYmxlIGZvciB5 b3UgdG8gY2hhbmdlIHRoaXM/IEkgZ3Vlc3MgaXQncyBva2F5IGZvciB0aGUgcmVzdCBvZgp0aGUg cGF0Y2ggdG8gc3RheSB0aGUgc2FtZS4KClNvcnJ5IGFib3V0IHRoZSBjaHVybi4KClRoYW5rcywK QXJjaGl0Cgo+ICsKPiArUmVxdWlyZWQgbm9kZXM6Cj4gKwo+ICtUaGlzIGRldmljZSBoYXMgdHdv IHZpZGVvIHBvcnRzLiBUaGVpciBjb25uZWN0aW9ucyBhcmUgbW9kZWxlZCB1c2luZyB0aGUgT0YK PiArZ3JhcGggYmluZGluZ3Mgc3BlY2lmaWVkIGluIERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9i aW5kaW5ncy9ncmFwaC50eHQuCj4gKwo+ICstIFZpZGVvIHBvcnQgMCBmb3IgUkdCIGlucHV0Cj4g Ky0gVmlkZW8gcG9ydCAxIGZvciBWR0Egb3V0cHV0Cj4gKwo+ICsKPiArRXhhbXBsZQo+ICstLS0t LS0tCj4gKwo+ICticmlkZ2Ugewo+ICsJY29tcGF0aWJsZSA9ICJyZ2ItdG8tdmdhLWJyaWRnZSI7 Cj4gKwkjYWRkcmVzcy1jZWxscyA9IDwxPjsKPiArCSNzaXplLWNlbGxzID0gPDA+Owo+ICsKPiAr CXBvcnRzIHsKPiArCQkjYWRkcmVzcy1jZWxscyA9IDwxPjsKPiArCQkjc2l6ZS1jZWxscyA9IDww PjsKPiArCj4gKwkJcG9ydEAwIHsKPiArCQkJcmVnID0gPDA+Owo+ICsKPiArCQkJdmdhX2JyaWRn ZV9pbjogZW5kcG9pbnQgewo+ICsJCQkJcmVtb3RlLWVuZHBvaW50ID0gPCZ0Y29uMF9vdXRfdmdh PjsKPiArCQkJfTsKPiArCQl9Owo+ICsKPiArCQlwb3J0QDEgewo+ICsJCQlyZWcgPSA8MT47Cj4g Kwo+ICsJCQl2Z2FfYnJpZGdlX291dDogZW5kcG9pbnQgewo+ICsJCQkJcmVtb3RlLWVuZHBvaW50 ID0gPCZ2Z2FfY29uX2luPjsKPiArCQkJfTsKPiArCQl9Owo+ICsJfTsKPiArfTsKPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29uZmlnIGIvZHJpdmVycy9ncHUvZHJtL2Jy aWRnZS9LY29uZmlnCj4gaW5kZXggYjU5MGU2NzgwNTJkLi5kNjkwMzk4YzU0MWMgMTAwNjQ0Cj4g LS0tIGEvZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29uZmlnCj4gKysrIGIvZHJpdmVycy9ncHUv ZHJtL2JyaWRnZS9LY29uZmlnCj4gQEAgLTE3LDYgKzE3LDEzIEBAIGNvbmZpZyBEUk1fQU5BTE9H SVhfQU5YNzhYWAo+ICAJICB0aGUgSERNSSBvdXRwdXQgb2YgYW4gYXBwbGljYXRpb24gcHJvY2Vz c29yIHRvIE15RFAKPiAgCSAgb3IgRGlzcGxheVBvcnQuCj4KPiArY29uZmlnIERSTV9SR0JfVE9f VkdBCj4gKwl0cmlzdGF0ZSAiRHVtYiBSR0IgdG8gVkdBIEJyaWRnZSBzdXBwb3J0Igo+ICsJZGVw ZW5kcyBvbiBPRgo+ICsJc2VsZWN0IERSTV9LTVNfSEVMUEVSCj4gKwloZWxwCj4gKwkgIFN1cHBv cnQgZm9yIHBhc3NpdmUgUkdCIHRvIFZHQSBicmlkZ2VzCj4gKwo+ICBjb25maWcgRFJNX0RXX0hE TUkKPiAgCXRyaXN0YXRlCj4gIAlzZWxlY3QgRFJNX0tNU19IRUxQRVIKPiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9NYWtlZmlsZSBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2Uv TWFrZWZpbGUKPiBpbmRleCBlZmRiMDdlODc4ZjUuLjNiYjhjYmUwOWZlOSAxMDA2NDQKPiAtLS0g YS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL01ha2VmaWxlCj4gKysrIGIvZHJpdmVycy9ncHUvZHJt L2JyaWRnZS9NYWtlZmlsZQo+IEBAIC0xLDYgKzEsNyBAQAo+ICBjY2ZsYWdzLXkgOj0gLUlpbmNs dWRlL2RybQo+Cj4gIG9iai0kKENPTkZJR19EUk1fQU5BTE9HSVhfQU5YNzhYWCkgKz0gYW5hbG9n aXgtYW54Nzh4eC5vCj4gK29iai0kKENPTkZJR19EUk1fUkdCX1RPX1ZHQSkgKz0gcmdiLXRvLXZn YS5vCj4gIG9iai0kKENPTkZJR19EUk1fRFdfSERNSSkgKz0gZHctaGRtaS5vCj4gIG9iai0kKENP TkZJR19EUk1fRFdfSERNSV9BSEJfQVVESU8pICs9IGR3LWhkbWktYWhiLWF1ZGlvLm8KPiAgb2Jq LSQoQ09ORklHX0RSTV9OWFBfUFROMzQ2MCkgKz0gbnhwLXB0bjM0NjAubwo+IGRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL3JnYi10by12Z2EuYyBiL2RyaXZlcnMvZ3B1L2RybS9i cmlkZ2UvcmdiLXRvLXZnYS5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAw MDAwMDAuLjVmZjRkNGYzNTk4Zgo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9k cm0vYnJpZGdlL3JnYi10by12Z2EuYwo+IEBAIC0wLDAgKzEsMjI5IEBACj4gKy8qCj4gKyAqIENv cHlyaWdodCAoQykgMjAxNS0yMDE2IEZyZWUgRWxlY3Ryb25zCj4gKyAqIENvcHlyaWdodCAoQykg MjAxNS0yMDE2IE5leHRUaGluZyBDbwo+ICsgKgo+ICsgKiBNYXhpbWUgUmlwYXJkIDxtYXhpbWUu cmlwYXJkQGZyZWUtZWxlY3Ryb25zLmNvbT4KPiArICoKPiArICogVGhpcyBwcm9ncmFtIGlzIGZy ZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgo+ICsgKiBtb2RpZnkg aXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwo+ ICsgKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZl cnNpb24gMiBvZgo+ICsgKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0 ZXIgdmVyc2lvbi4KPiArICovCj4gKwo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNp bmNsdWRlIDxsaW51eC9vZl9ncmFwaC5oPgo+ICsKPiArI2luY2x1ZGUgPGRybS9kcm1QLmg+Cj4g KyNpbmNsdWRlIDxkcm0vZHJtX2F0b21pY19oZWxwZXIuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1f Y3J0Yy5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBlci5oPgo+ICsKPiArc3RydWN0 IGR1bWJfdmdhIHsKPiArCXN0cnVjdCBkcm1fYnJpZGdlCWJyaWRnZTsKPiArCXN0cnVjdCBkcm1f Y29ubmVjdG9yCWNvbm5lY3RvcjsKPiArCj4gKwlzdHJ1Y3QgaTJjX2FkYXB0ZXIJKmRkYzsKPiAr fTsKPiArCj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGR1bWJfdmdhICoKPiArZHJtX2JyaWRnZV90 b19kdW1iX3ZnYShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ICt7Cj4gKwlyZXR1cm4gY29u dGFpbmVyX29mKGJyaWRnZSwgc3RydWN0IGR1bWJfdmdhLCBicmlkZ2UpOwo+ICt9Cj4gKwo+ICtz dGF0aWMgaW5saW5lIHN0cnVjdCBkdW1iX3ZnYSAqCj4gK2RybV9jb25uZWN0b3JfdG9fZHVtYl92 Z2Eoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcikKPiArewo+ICsJcmV0dXJuIGNvbnRh aW5lcl9vZihjb25uZWN0b3IsIHN0cnVjdCBkdW1iX3ZnYSwgY29ubmVjdG9yKTsKPiArfQo+ICsK PiArc3RhdGljIGludCBkdW1iX3ZnYV9nZXRfbW9kZXMoc3RydWN0IGRybV9jb25uZWN0b3IgKmNv bm5lY3RvcikKPiArewo+ICsJc3RydWN0IGR1bWJfdmdhICp2Z2EgPSBkcm1fY29ubmVjdG9yX3Rv X2R1bWJfdmdhKGNvbm5lY3Rvcik7Cj4gKwlzdHJ1Y3QgZWRpZCAqZWRpZDsKPiArCWludCByZXQ7 Cj4gKwo+ICsJaWYgKElTX0VSUih2Z2EtPmRkYykpCj4gKwkJZ290byBmYWxsYmFjazsKPiArCj4g KwllZGlkID0gZHJtX2dldF9lZGlkKGNvbm5lY3RvciwgdmdhLT5kZGMpOwo+ICsJaWYgKCFlZGlk KSB7Cj4gKwkJRFJNX0lORk8oIkVESUQgcmVhZG91dCBmYWlsZWQsIGZhbGxpbmcgYmFjayB0byBz dGFuZGFyZCBtb2Rlc1xuIik7Cj4gKwkJZ290byBmYWxsYmFjazsKPiArCX0KPiArCj4gKwlkcm1f bW9kZV9jb25uZWN0b3JfdXBkYXRlX2VkaWRfcHJvcGVydHkoY29ubmVjdG9yLCBlZGlkKTsKPiAr CXJldHVybiBkcm1fYWRkX2VkaWRfbW9kZXMoY29ubmVjdG9yLCBlZGlkKTsKPiArCj4gK2ZhbGxi YWNrOgo+ICsJLyoKPiArCSAqIEluIGNhc2Ugd2UgY2Fubm90IHJldHJpZXZlIHRoZSBFRElEcyAo YnJva2VuIG9yIG1pc3NpbmcgaTJjCj4gKwkgKiBidXMpLCBmYWxsYmFjayBvbiB0aGUgWEdBIHN0 YW5kYXJkcwo+ICsJICovCj4gKwlyZXQgPSBkcm1fYWRkX21vZGVzX25vZWRpZChjb25uZWN0b3Is IDE5MjAsIDEyMDApOwo+ICsKPiArCS8qIEFuZCBwcmVmZXIgYSBtb2RlIHByZXR0eSBtdWNoIGFu eW9uZSBjYW4gaGFuZGxlICovCj4gKwlkcm1fc2V0X3ByZWZlcnJlZF9tb2RlKGNvbm5lY3Rvciwg MTAyNCwgNzY4KTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qg c3RydWN0IGRybV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzIGR1bWJfdmdhX2Nvbl9oZWxwZXJfZnVu Y3MgPSB7Cj4gKwkuZ2V0X21vZGVzCT0gZHVtYl92Z2FfZ2V0X21vZGVzLAo+ICt9Owo+ICsKPiAr c3RhdGljIGVudW0gZHJtX2Nvbm5lY3Rvcl9zdGF0dXMKPiArZHVtYl92Z2FfY29ubmVjdG9yX2Rl dGVjdChzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yLCBib29sIGZvcmNlKQo+ICt7Cj4g KwlzdHJ1Y3QgZHVtYl92Z2EgKnZnYSA9IGRybV9jb25uZWN0b3JfdG9fZHVtYl92Z2EoY29ubmVj dG9yKTsKPiArCj4gKwkvKgo+ICsJICogRXZlbiBpZiB3ZSBoYXZlIGFuIEkyQyBidXMsIHdlIGNh bid0IGFzc3VtZSB0aGF0IHRoZSBjYWJsZQo+ICsJICogaXMgZGlzY29ubmVjdGVkIGlmIGRybV9w cm9iZV9kZGMgZmFpbHMuIFNvbWUgY2FibGVzIGRvbid0Cj4gKwkgKiB3aXJlIHRoZSBEREMgcGlu cywgb3IgdGhlIEkyQyBidXMgbWlnaHQgbm90IGJlIHdvcmtpbmcgYXQKPiArCSAqIGFsbC4KPiAr CSAqLwo+ICsJaWYgKCFJU19FUlIodmdhLT5kZGMpICYmIGRybV9wcm9iZV9kZGModmdhLT5kZGMp KQo+ICsJCXJldHVybiBjb25uZWN0b3Jfc3RhdHVzX2Nvbm5lY3RlZDsKPiArCj4gKwlyZXR1cm4g Y29ubmVjdG9yX3N0YXR1c191bmtub3duOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZAo+ICtkdW1i X3ZnYV9jb25uZWN0b3JfZGVzdHJveShzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKQo+ ICt7Cj4gKwlkcm1fY29ubmVjdG9yX2NsZWFudXAoY29ubmVjdG9yKTsKPiArfQo+ICsKPiArc3Rh dGljIGNvbnN0IHN0cnVjdCBkcm1fY29ubmVjdG9yX2Z1bmNzIGR1bWJfdmdhX2Nvbl9mdW5jcyA9 IHsKPiArCS5kcG1zCQkJPSBkcm1fYXRvbWljX2hlbHBlcl9jb25uZWN0b3JfZHBtcywKPiArCS5k ZXRlY3QJCQk9IGR1bWJfdmdhX2Nvbm5lY3Rvcl9kZXRlY3QsCj4gKwkuZmlsbF9tb2RlcwkJPSBk cm1faGVscGVyX3Byb2JlX3NpbmdsZV9jb25uZWN0b3JfbW9kZXMsCj4gKwkuZGVzdHJveQkJPSBk dW1iX3ZnYV9jb25uZWN0b3JfZGVzdHJveSwKPiArCS5yZXNldAkJCT0gZHJtX2F0b21pY19oZWxw ZXJfY29ubmVjdG9yX3Jlc2V0LAo+ICsJLmF0b21pY19kdXBsaWNhdGVfc3RhdGUJPSBkcm1fYXRv bWljX2hlbHBlcl9jb25uZWN0b3JfZHVwbGljYXRlX3N0YXRlLAo+ICsJLmF0b21pY19kZXN0cm95 X3N0YXRlCT0gZHJtX2F0b21pY19oZWxwZXJfY29ubmVjdG9yX2Rlc3Ryb3lfc3RhdGUsCj4gK307 Cj4gKwo+ICtzdGF0aWMgaW50IGR1bWJfdmdhX2F0dGFjaChzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJp ZGdlKQo+ICt7Cj4gKwlzdHJ1Y3QgZHVtYl92Z2EgKnZnYSA9IGRybV9icmlkZ2VfdG9fZHVtYl92 Z2EoYnJpZGdlKTsKPiArCWludCByZXQ7Cj4gKwo+ICsJaWYgKCFicmlkZ2UtPmVuY29kZXIpIHsK PiArCQlEUk1fRVJST1IoIk1pc3NpbmcgZW5jb2RlclxuIik7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7 Cj4gKwl9Cj4gKwo+ICsJZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfYWRkKCZ2Z2EtPmNvbm5lY3RvciwK PiArCQkJCSAmZHVtYl92Z2FfY29uX2hlbHBlcl9mdW5jcyk7Cj4gKwlyZXQgPSBkcm1fY29ubmVj dG9yX2luaXQoYnJpZGdlLT5kZXYsICZ2Z2EtPmNvbm5lY3RvciwKPiArCQkJCSAmZHVtYl92Z2Ff Y29uX2Z1bmNzLCBEUk1fTU9ERV9DT05ORUNUT1JfVkdBKTsKPiArCWlmIChyZXQpIHsKPiArCQlE Uk1fRVJST1IoIkZhaWxlZCB0byBpbml0aWFsaXplIGNvbm5lY3RvclxuIik7Cj4gKwkJcmV0dXJu IHJldDsKPiArCX0KPiArCj4gKwlkcm1fbW9kZV9jb25uZWN0b3JfYXR0YWNoX2VuY29kZXIoJnZn YS0+Y29ubmVjdG9yLAo+ICsJCQkJCSAgYnJpZGdlLT5lbmNvZGVyKTsKPiArCj4gKwlyZXR1cm4g MDsKPiArfQo+ICsKPiArc3RhdGljIGNvbnN0IHN0cnVjdCBkcm1fYnJpZGdlX2Z1bmNzIGR1bWJf dmdhX2JyaWRnZV9mdW5jcyA9IHsKPiArCS5hdHRhY2gJCT0gZHVtYl92Z2FfYXR0YWNoLAo+ICt9 Owo+ICsKPiArc3RhdGljIHN0cnVjdCBpMmNfYWRhcHRlciAqZHVtYl92Z2FfcmV0cmlldmVfZGRj KHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsJc3RydWN0IGRldmljZV9ub2RlICplbmRfbm9k ZSwgKnBoYW5kbGUsICpyZW1vdGU7Cj4gKwlzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmRkYzsKPiArCj4g KwllbmRfbm9kZSA9IG9mX2dyYXBoX2dldF9lbmRwb2ludF9ieV9yZWdzKGRldi0+b2Zfbm9kZSwg MSwgLTEpOwo+ICsJaWYgKCFlbmRfbm9kZSkgewo+ICsJCWRldl9lcnIoZGV2LCAiTWlzc2luZyBj b25uZWN0b3IgZW5kcG9pbnRcbiIpOwo+ICsJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwo+ICsJ fQo+ICsKPiArCXJlbW90ZSA9IG9mX2dyYXBoX2dldF9yZW1vdGVfcG9ydF9wYXJlbnQoZW5kX25v ZGUpOwo+ICsJb2Zfbm9kZV9wdXQoZW5kX25vZGUpOwo+ICsJaWYgKCFyZW1vdGUpIHsKPiArCQlk ZXZfZXJyKGRldiwgIkVuYWJsZSB0byBwYXJzZSByZW1vdGUgbm9kZVxuIik7Cj4gKwkJcmV0dXJu IEVSUl9QVFIoLUVJTlZBTCk7Cj4gKwl9Cj4gKwo+ICsJcGhhbmRsZSA9IG9mX3BhcnNlX3BoYW5k bGUocmVtb3RlLCAiZGRjLWkyYy1idXMiLCAwKTsKPiArCW9mX25vZGVfcHV0KHJlbW90ZSk7Cj4g KwlpZiAoIXBoYW5kbGUpCj4gKwkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7Cj4gKwo+ICsJZGRj ID0gb2ZfZ2V0X2kyY19hZGFwdGVyX2J5X25vZGUocGhhbmRsZSk7Cj4gKwlvZl9ub2RlX3B1dChw aGFuZGxlKTsKPiArCWlmICghZGRjKQo+ICsJCXJldHVybiBFUlJfUFRSKC1FUFJPQkVfREVGRVIp Owo+ICsKPiArCXJldHVybiBkZGM7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZHVtYl92Z2FfcHJv YmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0IGR1bWJfdmdh ICp2Z2E7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXZnYSA9IGRldm1fa3phbGxvYygmcGRldi0+ZGV2 LCBzaXplb2YoKnZnYSksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCF2Z2EpCj4gKwkJcmV0dXJuIC1F Tk9NRU07Cj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCB2Z2EpOwo+ICsKPiArCXZnYS0+ ZGRjID0gZHVtYl92Z2FfcmV0cmlldmVfZGRjKCZwZGV2LT5kZXYpOwo+ICsJaWYgKElTX0VSUih2 Z2EtPmRkYykpIHsKPiArCQlpZiAoUFRSX0VSUih2Z2EtPmRkYykgPT0gLUVOT0RFVikgewo+ICsJ CQlkZXZfaW5mbygmcGRldi0+ZGV2LAo+ICsJCQkJICJObyBpMmMgYnVzIHNwZWNpZmllZC4uLiBE aXNhYmxpbmcgRURJRCByZWFkb3V0XG4iKTsKPiArCQl9IGVsc2Ugewo+ICsJCQlkZXZfZXJyKCZw ZGV2LT5kZXYsICJDb3VsZG4ndCByZXRyaWV2ZSBpMmMgYnVzXG4iKTsKPiArCQkJcmV0dXJuIFBU Ul9FUlIodmdhLT5kZGMpOwo+ICsJCX0KPiArCX0KPiArCj4gKwl2Z2EtPmJyaWRnZS5mdW5jcyA9 ICZkdW1iX3ZnYV9icmlkZ2VfZnVuY3M7Cj4gKwl2Z2EtPmJyaWRnZS5vZl9ub2RlID0gcGRldi0+ ZGV2Lm9mX25vZGU7Cj4gKwo+ICsJcmV0ID0gZHJtX2JyaWRnZV9hZGQoJnZnYS0+YnJpZGdlKTsK PiArCWlmIChyZXQgJiYgIUlTX0VSUih2Z2EtPmRkYykpCj4gKwkJaTJjX3B1dF9hZGFwdGVyKHZn YS0+ZGRjKTsKPiArCj4gKwlyZXR1cm4gcmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IGR1bWJf dmdhX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQo+ICt7Cj4gKwlzdHJ1Y3Qg ZHVtYl92Z2EgKnZnYSA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwo+ICsKPiArCWRybV9i cmlkZ2VfcmVtb3ZlKCZ2Z2EtPmJyaWRnZSk7Cj4gKwo+ICsJaWYgKCFJU19FUlIodmdhLT5kZGMp KQo+ICsJCWkyY19wdXRfYWRhcHRlcih2Z2EtPmRkYyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30K PiArCj4gK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIGR1bWJfdmdhX21hdGNoW10g PSB7Cj4gKwl7IC5jb21wYXRpYmxlID0gInJnYi10by12Z2EtYnJpZGdlIiB9LAo+ICsJe30sCj4g K307Cj4gK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGR1bWJfdmdhX21hdGNoKTsKPiArCj4gK3N0 cnVjdCBwbGF0Zm9ybV9kcml2ZXIgZHVtYl92Z2FfZHJpdmVyID0gewo+ICsJLnByb2JlCT0gZHVt Yl92Z2FfcHJvYmUsCj4gKwkucmVtb3ZlCT0gZHVtYl92Z2FfcmVtb3ZlLAo+ICsJLmRyaXZlcgkJ PSB7Cj4gKwkJLm5hbWUJCT0gInJnYi10by12Z2EtYnJpZGdlIiwKPiArCQkub2ZfbWF0Y2hfdGFi bGUJPSBkdW1iX3ZnYV9tYXRjaCwKPiArCX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2 ZXIoZHVtYl92Z2FfZHJpdmVyKTsKPiArCj4gK01PRFVMRV9BVVRIT1IoIk1heGltZSBSaXBhcmQg PG1heGltZS5yaXBhcmRAZnJlZS1lbGVjdHJvbnMuY29tPiIpOwo+ICtNT0RVTEVfREVTQ1JJUFRJ T04oIkR1bWIgUkdCIHRvIFZHQSBicmlkZ2UgZHJpdmVyIik7Cj4gK01PRFVMRV9MSUNFTlNFKCJH UEwiKTsKPgoKLS0gClF1YWxjb21tIElubm92YXRpb24gQ2VudGVyLCBJbmMuIGlzIGEgbWVtYmVy IG9mIENvZGUgQXVyb3JhIEZvcnVtLAphIExpbnV4IEZvdW5kYXRpb24gQ29sbGFib3JhdGl2ZSBQ cm9qZWN0Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRy aS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRw czovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=