From mboxrd@z Thu Jan 1 00:00:00 1970 From: laurent.pinchart@ideasonboard.com (Laurent Pinchart) Date: Sun, 18 Sep 2016 13:01:16 +0300 Subject: [PATCH v3 1/4] drm/bridge: Add RGB to VGA bridge support In-Reply-To: <20160908121751.16911-2-maxime.ripard@free-electrons.com> References: <20160908121751.16911-1-maxime.ripard@free-electrons.com> <20160908121751.16911-2-maxime.ripard@free-electrons.com> Message-ID: <2115773.yQojqqIjGI@avalon> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Maxime, Thank you for the patch. On Thursday 08 Sep 2016 14:17:48 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 | 52 +++++ > drivers/gpu/drm/bridge/Kconfig | 6 + > drivers/gpu/drm/bridge/Makefile | 1 + > drivers/gpu/drm/bridge/rgb-to-vga.c | 232 ++++++++++++++++++ > 4 files changed, 291 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..83a053fb51a0 > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/bridge/rgb-to-vga-bridge.txt > @@ -0,0 +1,52 @@ > +Passive RGB to VGA bridge > +------------------------- > + > +This binding is aimed for entirely passive RGB to VGA bridges that do not > +require any configuration. Couldn't it also support active RGB to VGA bridges that don't require any configuration ? It would seem a bit pointless to define a separate DT binding for them. > +Required properties: > + > +- compatible: Must be "rgb-to-vga-bridge" > + > +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 { > + #address-cells = <1>; > + #size-cells = <0>; > + reg = <0>; > + > + vga_bridge_in: endpoint { > + remote-endpoint = <&tcon0_out_vga>; > + }; > + }; > + > + port at 1 { > + #address-cells = <1>; > + #size-cells = <0>; > + 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..42b95adf5091 100644 > --- a/drivers/gpu/drm/bridge/Kconfig > +++ b/drivers/gpu/drm/bridge/Kconfig > @@ -17,6 +17,12 @@ 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" > + 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..84b1b10198a4 > --- /dev/null > +++ b/drivers/gpu/drm/bridge/rgb-to-vga.c > @@ -0,0 +1,232 @@ > + > +#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 struct drm_encoder * > +dumb_vga_best_encoder(struct drm_connector *connector) > +{ > + struct dumb_vga *vga = drm_connector_to_dumb_vga(connector); > + > + return vga->bridge.encoder; > +} > + > +static struct drm_connector_helper_funcs dumb_vga_con_helper_funcs = { > + .get_modes = dumb_vga_get_modes, > + .best_encoder = dumb_vga_best_encoder, > +}; > + > +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. Some cables don't wire > + * the DDC pins, or the I2C bus might be disfunctional. > + */ > + 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 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); Bridges should really not create connectors. Fixing this problem is a bit out of scope for your patch, but I'm concerned that the growing number of bridge drivers will make it difficult to fix it later. > + if (ret) { > + DRM_ERROR("Failed to initialize connector\n"); > + return ret; > + } > + > + drm_mode_connector_attach_encoder(&vga->connector, > + bridge->encoder); > + > + return 0; > +} > + > +static void dumb_vga_nop(struct drm_bridge *bridge) {}; > + > +static struct drm_bridge_funcs dumb_vga_bridge_funcs = { > + .attach = dumb_vga_attach, > + .enable = dumb_vga_nop, > + .disable = dumb_vga_nop, > + .pre_enable = dumb_vga_nop, > + .post_disable = dumb_vga_nop, Those four operations are optional, you don't need dumb_vga_nop(). > +}; > + > +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"); -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: Re: [PATCH v3 1/4] drm/bridge: Add RGB to VGA bridge support Date: Sun, 18 Sep 2016 13:01:16 +0300 Message-ID: <2115773.yQojqqIjGI@avalon> References: <20160908121751.16911-1-maxime.ripard@free-electrons.com> <20160908121751.16911-2-maxime.ripard@free-electrons.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <20160908121751.16911-2-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: dri-devel@lists.freedesktop.org Cc: devicetree@vger.kernel.org, Chen-Yu Tsai , Rob Herring , Daniel Vetter , Maxime Ripard , linux-arm-kernel@lists.infradead.org List-Id: devicetree@vger.kernel.org SGkgTWF4aW1lLAoKVGhhbmsgeW91IGZvciB0aGUgcGF0Y2guCgpPbiBUaHVyc2RheSAwOCBTZXAg MjAxNiAxNDoxNzo0OCBNYXhpbWUgUmlwYXJkIHdyb3RlOgo+IFNvbWUgYm9hcmRzIGhhdmUgYW4g ZW50aXJlbHkgcGFzc2l2ZSBSR0IgdG8gVkdBIGJyaWRnZSwgYmFzZWQgb24gZWl0aGVyCj4gREFD cyBvciByZXNpc3RvciBsYWRkZXJzLgo+IAo+IFRob3NlIG1pZ2h0IG9yIG1pZ2h0IG5vdCBoYXZl IGFuIGkyYyBidXMgcm91dGVkIHRvIHRoZSBWR0EgY29ubmVjdG9yIGluCj4gb3JkZXIgdG8gYWNj ZXNzIHRoZSBzY3JlZW4gRURJRHMuCj4gCj4gQWRkIGEgYnJpZGdlIHRoYXQgZG9lc24ndCBkbyBh bnl0aGluZyBidXQgZXhwb3NlIHRoZSBtb2RlcyBhdmFpbGFibGUgb24gdGhlCj4gc2NyZWVuLCBl aXRoZXIgYmFzZWQgb24gdGhlIEVESURzIGlmIGF2YWlsYWJsZSwgb3IgYmFzZWQgb24gdGhlIFhH QQo+IHN0YW5kYXJkcy4KPiAKPiBBY2tlZC1ieTogUm9iIEhlcnJpbmcgPHJvYmhAa2VybmVsLm9y Zz4KPiBTaWduZWQtb2ZmLWJ5OiBNYXhpbWUgUmlwYXJkIDxtYXhpbWUucmlwYXJkQGZyZWUtZWxl Y3Ryb25zLmNvbT4KPiAtLS0KPiAgLi4uL2JpbmRpbmdzL2Rpc3BsYXkvYnJpZGdlL3JnYi10by12 Z2EtYnJpZGdlLnR4dCAgfCAgNTIgKysrKysKPiAgZHJpdmVycy9ncHUvZHJtL2JyaWRnZS9LY29u ZmlnICAgICAgICAgICAgICAgICAgICAgfCAgIDYgKwo+ICBkcml2ZXJzL2dwdS9kcm0vYnJpZGdl L01ha2VmaWxlICAgICAgICAgICAgICAgICAgICB8ICAgMSArCj4gIGRyaXZlcnMvZ3B1L2RybS9i cmlkZ2UvcmdiLXRvLXZnYS5jICAgICAgICAgICAgICAgIHwgMjMyICsrKysrKysrKysrKysrKysr Kwo+ICA0IGZpbGVzIGNoYW5nZWQsIDI5MSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEw MDY0NAo+IERvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9kaXNwbGF5L2JyaWRnZS9y Z2ItdG8tdmdhLWJyaWRnZS50eHQKPiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJt L2JyaWRnZS9yZ2ItdG8tdmdhLmMKPiAKPiBkaWZmIC0tZ2l0Cj4gYS9Eb2N1bWVudGF0aW9uL2Rl dmljZXRyZWUvYmluZGluZ3MvZGlzcGxheS9icmlkZ2UvcmdiLXRvLXZnYS1icmlkZ2UudHh0Cj4g Yi9Eb2N1bWVudGF0aW9uL2RldmljZXRyZWUvYmluZGluZ3MvZGlzcGxheS9icmlkZ2UvcmdiLXRv LXZnYS1icmlkZ2UudHh0Cj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAw MDAuLjgzYTA1M2ZiNTFhMAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9Eb2N1bWVudGF0aW9uL2Rl dmljZXRyZWUvYmluZGluZ3MvZGlzcGxheS9icmlkZ2UvcmdiLXRvLXZnYS1icmlkZ2UudHh0Cj4g QEAgLTAsMCArMSw1MiBAQAo+ICtQYXNzaXZlIFJHQiB0byBWR0EgYnJpZGdlCj4gKy0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0KPiArCj4gK1RoaXMgYmluZGluZyBpcyBhaW1lZCBmb3IgZW50aXJl bHkgcGFzc2l2ZSBSR0IgdG8gVkdBIGJyaWRnZXMgdGhhdCBkbyBub3QKPiArcmVxdWlyZSBhbnkg Y29uZmlndXJhdGlvbi4KCkNvdWxkbid0IGl0IGFsc28gc3VwcG9ydCBhY3RpdmUgUkdCIHRvIFZH QSBicmlkZ2VzIHRoYXQgZG9uJ3QgcmVxdWlyZSBhbnkgCmNvbmZpZ3VyYXRpb24gPyBJdCB3b3Vs ZCBzZWVtIGEgYml0IHBvaW50bGVzcyB0byBkZWZpbmUgYSBzZXBhcmF0ZSBEVCBiaW5kaW5nIApm b3IgdGhlbS4KCj4gK1JlcXVpcmVkIHByb3BlcnRpZXM6Cj4gKwo+ICstIGNvbXBhdGlibGU6IE11 c3QgYmUgInJnYi10by12Z2EtYnJpZGdlIgo+ICsKPiArUmVxdWlyZWQgbm9kZXM6Cj4gKwo+ICtU aGlzIGRldmljZSBoYXMgdHdvIHZpZGVvIHBvcnRzLiBUaGVpciBjb25uZWN0aW9ucyBhcmUgbW9k ZWxlZCB1c2luZyB0aGUgT0YKPiArZ3JhcGggYmluZGluZ3Mgc3BlY2lmaWVkIGluIERvY3VtZW50 YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9ncmFwaC50eHQuCj4gKwo+ICstIFZpZGVvIHBvcnQg MCBmb3IgUkdCIGlucHV0Cj4gKy0gVmlkZW8gcG9ydCAxIGZvciBWR0Egb3V0cHV0Cj4gKwo+ICsK PiArRXhhbXBsZQo+ICstLS0tLS0tCj4gKwo+ICticmlkZ2Ugewo+ICsJY29tcGF0aWJsZSA9ICJy Z2ItdG8tdmdhLWJyaWRnZSI7Cj4gKwkjYWRkcmVzcy1jZWxscyA9IDwxPjsKPiArCSNzaXplLWNl bGxzID0gPDA+Owo+ICsKPiArCXBvcnRzIHsKPiArCQkjYWRkcmVzcy1jZWxscyA9IDwxPjsKPiAr CQkjc2l6ZS1jZWxscyA9IDwwPjsKPiArCj4gKwkJcG9ydEAwIHsKPiArCQkJI2FkZHJlc3MtY2Vs bHMgPSA8MT47Cj4gKwkJCSNzaXplLWNlbGxzID0gPDA+Owo+ICsJCQlyZWcgPSA8MD47Cj4gKwo+ ICsJCQl2Z2FfYnJpZGdlX2luOiBlbmRwb2ludCB7Cj4gKwkJCQlyZW1vdGUtZW5kcG9pbnQgPSA8 JnRjb24wX291dF92Z2E+Owo+ICsJCQl9Owo+ICsJCX07Cj4gKwo+ICsJCXBvcnRAMSB7Cj4gKwkJ CSNhZGRyZXNzLWNlbGxzID0gPDE+Owo+ICsJCQkjc2l6ZS1jZWxscyA9IDwwPjsKPiArCQkJcmVn ID0gPDE+Owo+ICsKPiArCQkJdmdhX2JyaWRnZV9vdXQ6IGVuZHBvaW50IHsKPiArCQkJCXJlbW90 ZS1lbmRwb2ludCA9IDwmdmdhX2Nvbl9pbj47Cj4gKwkJCX07Cj4gKwkJfTsKPiArCX07Cj4gK307 Cj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZpZyBiL2RyaXZlcnMv Z3B1L2RybS9icmlkZ2UvS2NvbmZpZwo+IGluZGV4IGI1OTBlNjc4MDUyZC4uNDJiOTVhZGY1MDkx IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZpZwo+ICsrKyBiL2Ry aXZlcnMvZ3B1L2RybS9icmlkZ2UvS2NvbmZpZwo+IEBAIC0xNyw2ICsxNywxMiBAQCBjb25maWcg RFJNX0FOQUxPR0lYX0FOWDc4WFgKPiAgCSAgdGhlIEhETUkgb3V0cHV0IG9mIGFuIGFwcGxpY2F0 aW9uIHByb2Nlc3NvciB0byBNeURQCj4gIAkgIG9yIERpc3BsYXlQb3J0Lgo+IAo+ICtjb25maWcg RFJNX1JHQl9UT19WR0EKPiArCXRyaXN0YXRlICJEdW1iIFJHQiB0byBWR0EgQnJpZGdlIHN1cHBv cnQiCj4gKwlzZWxlY3QgRFJNX0tNU19IRUxQRVIKPiArCWhlbHAKPiArCSAgU3VwcG9ydCBmb3Ig cGFzc2l2ZSBSR0IgdG8gVkdBIGJyaWRnZXMKPiArCj4gIGNvbmZpZyBEUk1fRFdfSERNSQo+ICAJ dHJpc3RhdGUKPiAgCXNlbGVjdCBEUk1fS01TX0hFTFBFUgo+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vYnJpZGdlL01ha2VmaWxlCj4gYi9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL01ha2Vm aWxlIGluZGV4IGVmZGIwN2U4NzhmNS4uM2JiOGNiZTA5ZmU5IDEwMDY0NAo+IC0tLSBhL2RyaXZl cnMvZ3B1L2RybS9icmlkZ2UvTWFrZWZpbGUKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYnJpZGdl L01ha2VmaWxlCj4gQEAgLTEsNiArMSw3IEBACj4gIGNjZmxhZ3MteSA6PSAtSWluY2x1ZGUvZHJt Cj4gCj4gIG9iai0kKENPTkZJR19EUk1fQU5BTE9HSVhfQU5YNzhYWCkgKz0gYW5hbG9naXgtYW54 Nzh4eC5vCj4gK29iai0kKENPTkZJR19EUk1fUkdCX1RPX1ZHQSkgKz0gcmdiLXRvLXZnYS5vCj4g IG9iai0kKENPTkZJR19EUk1fRFdfSERNSSkgKz0gZHctaGRtaS5vCj4gIG9iai0kKENPTkZJR19E Uk1fRFdfSERNSV9BSEJfQVVESU8pICs9IGR3LWhkbWktYWhiLWF1ZGlvLm8KPiAgb2JqLSQoQ09O RklHX0RSTV9OWFBfUFROMzQ2MCkgKz0gbnhwLXB0bjM0NjAubwo+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vYnJpZGdlL3JnYi10by12Z2EuYwo+IGIvZHJpdmVycy9ncHUvZHJtL2JyaWRn ZS9yZ2ItdG8tdmdhLmMgbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAu Ljg0YjFiMTAxOThhNAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYnJp ZGdlL3JnYi10by12Z2EuYwo+IEBAIC0wLDAgKzEsMjMyIEBACj4gKwo+ICsjaW5jbHVkZSA8bGlu dXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZl9ncmFwaC5oPgo+ICsKPiArI2luY2x1 ZGUgPGRybS9kcm1QLmg+Cj4gKyNpbmNsdWRlIDxkcm0vZHJtX2F0b21pY19oZWxwZXIuaD4KPiAr I2luY2x1ZGUgPGRybS9kcm1fY3J0Yy5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBl ci5oPgo+ICsKPiArc3RydWN0IGR1bWJfdmdhIHsKPiArCXN0cnVjdCBkcm1fYnJpZGdlCWJyaWRn ZTsKPiArCXN0cnVjdCBkcm1fY29ubmVjdG9yCWNvbm5lY3RvcjsKPiArCj4gKwlzdHJ1Y3QgaTJj X2FkYXB0ZXIJKmRkYzsKPiArfTsKPiArCj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGR1bWJfdmdh ICoKPiArZHJtX2JyaWRnZV90b19kdW1iX3ZnYShzdHJ1Y3QgZHJtX2JyaWRnZSAqYnJpZGdlKQo+ ICt7Cj4gKwlyZXR1cm4gY29udGFpbmVyX29mKGJyaWRnZSwgc3RydWN0IGR1bWJfdmdhLCBicmlk Z2UpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW5saW5lIHN0cnVjdCBkdW1iX3ZnYSAqCj4gK2RybV9j b25uZWN0b3JfdG9fZHVtYl92Z2Eoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcikKPiAr ewo+ICsJcmV0dXJuIGNvbnRhaW5lcl9vZihjb25uZWN0b3IsIHN0cnVjdCBkdW1iX3ZnYSwgY29u bmVjdG9yKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBkdW1iX3ZnYV9nZXRfbW9kZXMoc3RydWN0 IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcikKPiArewo+ICsJc3RydWN0IGR1bWJfdmdhICp2Z2Eg PSBkcm1fY29ubmVjdG9yX3RvX2R1bWJfdmdhKGNvbm5lY3Rvcik7Cj4gKwlzdHJ1Y3QgZWRpZCAq ZWRpZDsKPiArCWludCByZXQ7Cj4gKwo+ICsJaWYgKElTX0VSUih2Z2EtPmRkYykpCj4gKwkJZ290 byBmYWxsYmFjazsKPiArCj4gKwllZGlkID0gZHJtX2dldF9lZGlkKGNvbm5lY3RvciwgdmdhLT5k ZGMpOwo+ICsJaWYgKCFlZGlkKSB7Cj4gKwkJRFJNX0lORk8oIkVESUQgcmVhZG91dCBmYWlsZWQs IGZhbGxpbmcgYmFjayB0byBzdGFuZGFyZCAKbW9kZXNcbiIpOwo+ICsJCWdvdG8gZmFsbGJhY2s7 Cj4gKwl9Cj4gKwo+ICsJZHJtX21vZGVfY29ubmVjdG9yX3VwZGF0ZV9lZGlkX3Byb3BlcnR5KGNv bm5lY3RvciwgZWRpZCk7Cj4gKwlyZXR1cm4gZHJtX2FkZF9lZGlkX21vZGVzKGNvbm5lY3Rvciwg ZWRpZCk7Cj4gKwo+ICtmYWxsYmFjazoKPiArCS8qCj4gKwkgKiBJbiBjYXNlIHdlIGNhbm5vdCBy ZXRyaWV2ZSB0aGUgRURJRHMgKGJyb2tlbiBvciBtaXNzaW5nIGkyYwo+ICsJICogYnVzKSwgZmFs bGJhY2sgb24gdGhlIFhHQSBzdGFuZGFyZHMKPiArCSAqLwo+ICsJcmV0ID0gZHJtX2FkZF9tb2Rl c19ub2VkaWQoY29ubmVjdG9yLCAxOTIwLCAxMjAwKTsKPiArCj4gKwkvKiBBbmQgcHJlZmVyIGEg bW9kZSBwcmV0dHkgbXVjaCBhbnlvbmUgY2FuIGhhbmRsZSAqLwo+ICsJZHJtX3NldF9wcmVmZXJy ZWRfbW9kZShjb25uZWN0b3IsIDEwMjQsIDc2OCk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ ICsKPiArc3RhdGljIHN0cnVjdCBkcm1fZW5jb2RlciAqCj4gK2R1bWJfdmdhX2Jlc3RfZW5jb2Rl cihzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKQo+ICt7Cj4gKwlzdHJ1Y3QgZHVtYl92 Z2EgKnZnYSA9IGRybV9jb25uZWN0b3JfdG9fZHVtYl92Z2EoY29ubmVjdG9yKTsKPiArCj4gKwly ZXR1cm4gdmdhLT5icmlkZ2UuZW5jb2RlcjsKPiArfQo+ICsKPiArc3RhdGljIHN0cnVjdCBkcm1f Y29ubmVjdG9yX2hlbHBlcl9mdW5jcyBkdW1iX3ZnYV9jb25faGVscGVyX2Z1bmNzID0gewo+ICsJ LmdldF9tb2Rlcwk9IGR1bWJfdmdhX2dldF9tb2RlcywKPiArCS5iZXN0X2VuY29kZXIJPSBkdW1i X3ZnYV9iZXN0X2VuY29kZXIsCj4gK307Cj4gKwo+ICtzdGF0aWMgZW51bSBkcm1fY29ubmVjdG9y X3N0YXR1cwo+ICtkdW1iX3ZnYV9jb25uZWN0b3JfZGV0ZWN0KHN0cnVjdCBkcm1fY29ubmVjdG9y ICpjb25uZWN0b3IsIGJvb2wgZm9yY2UpCj4gK3sKPiArCXN0cnVjdCBkdW1iX3ZnYSAqdmdhID0g ZHJtX2Nvbm5lY3Rvcl90b19kdW1iX3ZnYShjb25uZWN0b3IpOwo+ICsKPiArCS8qCj4gKwkgKiBF dmVuIGlmIHdlIGhhdmUgYW4gSTJDIGJ1cywgd2UgY2FuJ3QgYXNzdW1lIHRoYXQgdGhlIGNhYmxl Cj4gKwkgKiBpcyBkaXNjb25uZWN0ZWQgaWYgZHJtX3Byb2JlX2RkYy4gU29tZSBjYWJsZXMgZG9u J3Qgd2lyZQo+ICsJICogdGhlIEREQyBwaW5zLCBvciB0aGUgSTJDIGJ1cyBtaWdodCBiZSBkaXNm dW5jdGlvbmFsLgo+ICsJICovCj4gKwlpZiAoIUlTX0VSUih2Z2EtPmRkYykgJiYgZHJtX3Byb2Jl X2RkYyh2Z2EtPmRkYykpCj4gKwkJcmV0dXJuIGNvbm5lY3Rvcl9zdGF0dXNfY29ubmVjdGVkOwo+ ICsKPiArCXJldHVybiBjb25uZWN0b3Jfc3RhdHVzX3Vua25vd247Cj4gK30KPiArCj4gK3N0YXRp YyB2b2lkCj4gK2R1bWJfdmdhX2Nvbm5lY3Rvcl9kZXN0cm95KHN0cnVjdCBkcm1fY29ubmVjdG9y ICpjb25uZWN0b3IpCj4gK3sKPiArCWRybV9jb25uZWN0b3JfY2xlYW51cChjb25uZWN0b3IpOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGRybV9jb25uZWN0b3JfZnVuY3MgZHVtYl92Z2FfY29u X2Z1bmNzID0gewo+ICsJLmRwbXMJCQk9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kcG1z LAo+ICsJLmRldGVjdAkJCT0gZHVtYl92Z2FfY29ubmVjdG9yX2RldGVjdCwKPiArCS5maWxsX21v ZGVzCQk9IGRybV9oZWxwZXJfcHJvYmVfc2luZ2xlX2Nvbm5lY3Rvcl9tb2RlcywKPiArCS5kZXN0 cm95CQk9IGR1bWJfdmdhX2Nvbm5lY3Rvcl9kZXN0cm95LAo+ICsJLnJlc2V0CQkJPSBkcm1fYXRv bWljX2hlbHBlcl9jb25uZWN0b3JfcmVzZXQsCj4gKwkuYXRvbWljX2R1cGxpY2F0ZV9zdGF0ZQk9 IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kdXBsaWNhdGVfc3RhdGUsCj4gKwkuYXRvbWlj X2Rlc3Ryb3lfc3RhdGUJPSBkcm1fYXRvbWljX2hlbHBlcl9jb25uZWN0b3JfZGVzdHJveV9zdGF0 ZSwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgZHVtYl92Z2FfYXR0YWNoKHN0cnVjdCBkcm1fYnJp ZGdlICpicmlkZ2UpCj4gK3sKPiArCXN0cnVjdCBkdW1iX3ZnYSAqdmdhID0gZHJtX2JyaWRnZV90 b19kdW1iX3ZnYShicmlkZ2UpOwo+ICsJaW50IHJldDsKPiArCj4gKwlpZiAoIWJyaWRnZS0+ZW5j b2Rlcikgewo+ICsJCURSTV9FUlJPUigiTWlzc2luZyBlbmNvZGVyXG4iKTsKPiArCQlyZXR1cm4g LUVOT0RFVjsKPiArCX0KPiArCj4gKwlkcm1fY29ubmVjdG9yX2hlbHBlcl9hZGQoJnZnYS0+Y29u bmVjdG9yLAo+ICsJCQkJICZkdW1iX3ZnYV9jb25faGVscGVyX2Z1bmNzKTsKPiArCXJldCA9IGRy bV9jb25uZWN0b3JfaW5pdChicmlkZ2UtPmRldiwgJnZnYS0+Y29ubmVjdG9yLAo+ICsJCQkJICZk dW1iX3ZnYV9jb25fZnVuY3MsIERSTV9NT0RFX0NPTk5FQ1RPUl9WR0EpOwoKQnJpZGdlcyBzaG91 bGQgcmVhbGx5IG5vdCBjcmVhdGUgY29ubmVjdG9ycy4gRml4aW5nIHRoaXMgcHJvYmxlbSBpcyBh IGJpdCBvdXQgCm9mIHNjb3BlIGZvciB5b3VyIHBhdGNoLCBidXQgSSdtIGNvbmNlcm5lZCB0aGF0 IHRoZSBncm93aW5nIG51bWJlciBvZiBicmlkZ2UgCmRyaXZlcnMgd2lsbCBtYWtlIGl0IGRpZmZp Y3VsdCB0byBmaXggaXQgbGF0ZXIuCgo+ICsJaWYgKHJldCkgewo+ICsJCURSTV9FUlJPUigiRmFp bGVkIHRvIGluaXRpYWxpemUgY29ubmVjdG9yXG4iKTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ ICsKPiArCWRybV9tb2RlX2Nvbm5lY3Rvcl9hdHRhY2hfZW5jb2RlcigmdmdhLT5jb25uZWN0b3Is Cj4gKwkJCQkJICBicmlkZ2UtPmVuY29kZXIpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ ICtzdGF0aWMgdm9pZCBkdW1iX3ZnYV9ub3Aoc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZSkge307 Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGRybV9icmlkZ2VfZnVuY3MgZHVtYl92Z2FfYnJpZGdlX2Z1 bmNzID0gewo+ICsJLmF0dGFjaAkJPSBkdW1iX3ZnYV9hdHRhY2gsCj4gKwkuZW5hYmxlCQk9IGR1 bWJfdmdhX25vcCwKPiArCS5kaXNhYmxlCT0gZHVtYl92Z2Ffbm9wLAo+ICsJLnByZV9lbmFibGUJ PSBkdW1iX3ZnYV9ub3AsCj4gKwkucG9zdF9kaXNhYmxlCT0gZHVtYl92Z2Ffbm9wLAoKVGhvc2Ug Zm91ciBvcGVyYXRpb25zIGFyZSBvcHRpb25hbCwgeW91IGRvbid0IG5lZWQgZHVtYl92Z2Ffbm9w KCkuCgo+ICt9Owo+ICsKPiArc3RhdGljIHN0cnVjdCBpMmNfYWRhcHRlciAqZHVtYl92Z2FfcmV0 cmlldmVfZGRjKHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsJc3RydWN0IGRldmljZV9ub2Rl ICplbmRfbm9kZSwgKnBoYW5kbGUsICpyZW1vdGU7Cj4gKwlzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmRk YzsKPiArCj4gKwllbmRfbm9kZSA9IG9mX2dyYXBoX2dldF9lbmRwb2ludF9ieV9yZWdzKGRldi0+ b2Zfbm9kZSwgMSwgLTEpOwo+ICsJaWYgKCFlbmRfbm9kZSkgewo+ICsJCWRldl9lcnIoZGV2LCAi TWlzc2luZyBjb25uZWN0b3IgZW5kcG9pbnRcbiIpOwo+ICsJCXJldHVybiBFUlJfUFRSKC1FTk9E RVYpOwo+ICsJfQo+ICsKPiArCXJlbW90ZSA9IG9mX2dyYXBoX2dldF9yZW1vdGVfcG9ydF9wYXJl bnQoZW5kX25vZGUpOwo+ICsJb2Zfbm9kZV9wdXQoZW5kX25vZGUpOwo+ICsJaWYgKCFyZW1vdGUp IHsKPiArCQlkZXZfZXJyKGRldiwgIkVuYWJsZSB0byBwYXJzZSByZW1vdGUgbm9kZVxuIik7Cj4g KwkJcmV0dXJuIEVSUl9QVFIoLUVJTlZBTCk7Cj4gKwl9Cj4gKwo+ICsJcGhhbmRsZSA9IG9mX3Bh cnNlX3BoYW5kbGUocmVtb3RlLCAiZGRjLWkyYy1idXMiLCAwKTsKPiArCW9mX25vZGVfcHV0KHJl bW90ZSk7Cj4gKwlpZiAoIXBoYW5kbGUpCj4gKwkJcmV0dXJuIEVSUl9QVFIoLUVOT0RFVik7Cj4g Kwo+ICsJZGRjID0gb2ZfZ2V0X2kyY19hZGFwdGVyX2J5X25vZGUocGhhbmRsZSk7Cj4gKwlvZl9u b2RlX3B1dChwaGFuZGxlKTsKPiArCWlmICghZGRjKQo+ICsJCXJldHVybiBFUlJfUFRSKC1FUFJP QkVfREVGRVIpOwo+ICsKPiArCXJldHVybiBkZGM7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgZHVt Yl92Z2FfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3RydWN0 IGR1bWJfdmdhICp2Z2E7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCXZnYSA9IGRldm1fa3phbGxvYygm cGRldi0+ZGV2LCBzaXplb2YoKnZnYSksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCF2Z2EpCj4gKwkJ cmV0dXJuIC1FTk9NRU07Cj4gKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCB2Z2EpOwo+ICsK PiArCXZnYS0+ZGRjID0gZHVtYl92Z2FfcmV0cmlldmVfZGRjKCZwZGV2LT5kZXYpOwo+ICsJaWYg KElTX0VSUih2Z2EtPmRkYykpIHsKPiArCQlpZiAoUFRSX0VSUih2Z2EtPmRkYykgPT0gLUVOT0RF Vikgewo+ICsJCQlkZXZfaW5mbygmcGRldi0+ZGV2LAo+ICsJCQkJICJObyBpMmMgYnVzIHNwZWNp ZmllZC4uLiBEaXNhYmxpbmcgRURJRCAKcmVhZG91dFxuIik7Cj4gKwkJfSBlbHNlIHsKPiArCQkJ ZGV2X2VycigmcGRldi0+ZGV2LCAiQ291bGRuJ3QgcmV0cmlldmUgaTJjIGJ1c1xuIik7Cj4gKwkJ CXJldHVybiBQVFJfRVJSKHZnYS0+ZGRjKTsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJdmdhLT5icmlk Z2UuZnVuY3MgPSAmZHVtYl92Z2FfYnJpZGdlX2Z1bmNzOwo+ICsJdmdhLT5icmlkZ2Uub2Zfbm9k ZSA9IHBkZXYtPmRldi5vZl9ub2RlOwo+ICsKPiArCXJldCA9IGRybV9icmlkZ2VfYWRkKCZ2Z2Et PmJyaWRnZSk7Cj4gKwlpZiAocmV0ICYmICFJU19FUlIodmdhLT5kZGMpKQo+ICsJCWkyY19wdXRf YWRhcHRlcih2Z2EtPmRkYyk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGlj IGludCBkdW1iX3ZnYV9yZW1vdmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ ICsJc3RydWN0IGR1bWJfdmdhICp2Z2EgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKPiAr Cj4gKwlkcm1fYnJpZGdlX3JlbW92ZSgmdmdhLT5icmlkZ2UpOwo+ICsKPiArCWlmICghSVNfRVJS KHZnYS0+ZGRjKSkKPiArCQlpMmNfcHV0X2FkYXB0ZXIodmdhLT5kZGMpOwo+ICsKPiArCXJldHVy biAwOwo+ICt9Cj4gKwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBkdW1iX3Zn YV9tYXRjaFtdID0gewo+ICsJeyAuY29tcGF0aWJsZSA9ICJyZ2ItdG8tdmdhLWJyaWRnZSIgfSwK PiArCXt9LAo+ICt9Owo+ICtNT0RVTEVfREVWSUNFX1RBQkxFKG9mLCBkdW1iX3ZnYV9tYXRjaCk7 Cj4gKwo+ICtzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIGR1bWJfdmdhX2RyaXZlciA9IHsKPiArCS5w cm9iZQk9IGR1bWJfdmdhX3Byb2JlLAo+ICsJLnJlbW92ZQk9IGR1bWJfdmdhX3JlbW92ZSwKPiAr CS5kcml2ZXIJCT0gewo+ICsJCS5uYW1lCQk9ICJyZ2ItdG8tdmdhLWJyaWRnZSIsCj4gKwkJLm9m X21hdGNoX3RhYmxlCT0gZHVtYl92Z2FfbWF0Y2gsCj4gKwl9LAo+ICt9Owo+ICttb2R1bGVfcGxh dGZvcm1fZHJpdmVyKGR1bWJfdmdhX2RyaXZlcik7Cj4gKwo+ICtNT0RVTEVfQVVUSE9SKCJNYXhp bWUgUmlwYXJkIDxtYXhpbWUucmlwYXJkQGZyZWUtZWxlY3Ryb25zLmNvbT4iKTsKPiArTU9EVUxF X0RFU0NSSVBUSU9OKCJEdW1iIFJHQiB0byBWR0EgYnJpZGdlIGRyaXZlciIpOwo+ICtNT0RVTEVf TElDRU5TRSgiR1BMIik7CgotLSAKUmVnYXJkcywKCkxhdXJlbnQgUGluY2hhcnQKCl9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5n IGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVk ZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=