From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.3 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2FF3C32751 for ; Sat, 10 Aug 2019 05:17:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 73039217F4 for ; Sat, 10 Aug 2019 05:17:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=jaseg.net header.i=@jaseg.net header.b="tFXYp5+D"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="mkYbFRki" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726132AbfHJFRP (ORCPT ); Sat, 10 Aug 2019 01:17:15 -0400 Received: from wout5-smtp.messagingengine.com ([64.147.123.21]:44133 "EHLO wout5-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725372AbfHJFRO (ORCPT ); Sat, 10 Aug 2019 01:17:14 -0400 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.west.internal (Postfix) with ESMTP id 02CCD558; Sat, 10 Aug 2019 01:17:10 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Sat, 10 Aug 2019 01:17:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jaseg.net; h= subject:to:cc:references:from:message-id:date:mime-version :in-reply-to:content-type:content-transfer-encoding; s=fm3; bh=T LKyPNFTsFZjFD5Cr/7Cre9egz8NoqCwoZLt4puyBJE=; b=tFXYp5+DPG8iNQeyE BBRQZZxMl+6qafobzbg/5E1c/C/jKA3xW0LBN1RKPIWbByAEwlfmXAs1k0vei4rV 6t4mZ8Zd8sv5kG7S04c52vczT/aHj6xhrgC8cIsu2Smdrrd2qovtL4vQvOfuU2GB eG7/ZOde6VfKHp6YZYtAuY47m89JyyCk+wLmvDFhPubRK8OeP4xWE3pxQvD+5Fhp Id/8afpIEAjClRSO4ZOFE+8K8xM7qj6YrXGKMoGVdD6fg8qDxGhjTAVlyvL8K2XD z6TqfI1bJ+SOVfGoCYwhJNG6S1PqV39E8PEVuFcRhlfwnUyEuma2gJiFPKB2GM+C OSx7w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; bh=TLKyPNFTsFZjFD5Cr/7Cre9egz8NoqCwoZLt4puyB JE=; b=mkYbFRkiHlbE3Aedt/y7fbg5aAahol580ZkKuqQE5juraz24gPeTsnASU L9KjzfRCAb7UVbAuLEkMyl2yYhcTC/p3wGJt0q5/uw/TLinoOtcIYHOJ6bBcbLyR j608EB7pfRkK0t6UE95G5NLJ+qm3EsYati4hMxCmueAO1XTvMPBYBKtzbAp1/cT2 bUw4b8rtdloWy1k+5DweyqpxlE+QNb/4gaZT2ijmnt1EgbPdKh56iughZF6e8hrh 0h5OZtDxUQmckZVvSNVCi4GwrP9GshEnXmzzJZqWI06j3+294OW4extnDldSAaXK a6zcPHqvRixR6YUnkfyPHtpH5ZIGg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduvddruddukedgleeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepuffvfhfhkffffgggjggtgfesthekredttdefjeenucfhrhhomheplfgrnhgp ufgvsggrshhtihgrnhgpifpnthhtvgcuoehlihhnuhigsehjrghsvghgrdhnvghtqeenuc ffohhmrghinhepfhhrvggvuggvshhkthhophdrohhrghenucfkphepiedtrdejuddrieef rdejheenucfrrghrrghmpehmrghilhhfrhhomheplhhinhhugiesjhgrshgvghdrnhgvth enucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from [10.137.0.16] (softbank060071063075.bbtec.net [60.71.63.75]) by mail.messagingengine.com (Postfix) with ESMTPA id 3738880059; Sat, 10 Aug 2019 01:17:08 -0400 (EDT) Subject: Re: [PATCH 6/6] drm: tiny: gdepaper: add driver for 2/3 color epaper displays To: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , dri-devel@lists.freedesktop.org Cc: David Airlie , Daniel Vetter , linux-kernel@vger.kernel.org References: <95b64347-fbc8-ba3d-79da-9de2557ff95e@jaseg.net> <604c82ee-af16-5f34-b229-5e919c4adfdc@tronnes.org> From: =?UTF-8?Q?Jan_Sebastian_G=c3=b6tte?= Message-ID: <7ebf06e2-fe24-a4fb-25ff-77ce1ee3ae16@jaseg.net> Date: Sat, 10 Aug 2019 14:17:06 +0900 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.2 MIME-Version: 1.0 In-Reply-To: <604c82ee-af16-5f34-b229-5e919c4adfdc@tronnes.org> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Noralf, thank you for your comments. I've incorporated your suggestions into my draft. On 8/7/19 1:06 AM, Noralf Trønnes wrote: [...] >> +static int gdepaper_probe(struct spi_device *spi) >> +{ >> + struct device *dev = &spi->dev; >> + struct device_node *np = dev->of_node; >> + const struct of_device_id *of_id; >> + struct drm_device *drm; >> + struct drm_display_mode *mode; >> + struct gdepaper *epap; >> + const struct gdepaper_type_descriptor *type_desc; >> + int ret; >> + size_t bufsize; >> + >> + of_id = of_match_node(gdepaper_of_match, np); >> + if (WARN_ON(of_id == NULL)) { >> + dev_warn(dev, "dt node didn't match, aborting probe\n"); >> + return -EINVAL; >> + } >> + type_desc = of_id->data; >> + >> + dev_dbg(dev, "Probing gdepaper module\n"); >> + epap = kzalloc(sizeof(*epap), GFP_KERNEL); >> + if (!epap) >> + return -ENOMEM; >> + >> + epap->enabled = false; >> + mutex_init(&epap->cmdlock); >> + epap->tx_buf = NULL; >> + epap->spi = spi; >> + >> + drm = &epap->drm; >> + ret = devm_drm_dev_init(dev, drm, &gdepaper_driver); >> + if (ret) { >> + dev_warn(dev, "failed to init drm dev\n"); >> + goto err_free; >> + } >> + >> + drm_mode_config_init(drm); >> + >> + epap->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); >> + if (IS_ERR(epap->reset)) { >> + dev_err(dev, "Failed to get reset GPIO\n"); >> + ret = PTR_ERR(epap->reset); >> + goto err_free; >> + } >> + >> + epap->busy = devm_gpiod_get(dev, "busy", GPIOD_IN); >> + if (IS_ERR(epap->busy)) { >> + dev_err(dev, "Failed to get busy GPIO\n"); >> + ret = PTR_ERR(epap->busy); >> + goto err_free; >> + } >> + >> + epap->dc = devm_gpiod_get(dev, "dc", GPIOD_OUT_LOW); >> + if (IS_ERR(epap->dc)) { >> + dev_err(dev, "Failed to get dc GPIO\n"); >> + ret = PTR_ERR(epap->dc); >> + goto err_free; >> + } >> + >> + epap->spi_speed_hz = 2000000; >> + epap->pll_div = 1; >> + epap->framerate_mHz = 81850; >> + epap->rfp.vg_lv = GDEP_PWR_VGHL_16V; >> + epap->rfp.vcom_sel = 0; >> + epap->rfp.vdh_bw_mv = 11000; /* drive high level, b/w pixel */ >> + epap->rfp.vdh_col_mv = 4200; /* drive high level, red/yellow pixel */ >> + epap->rfp.vdl_mv = -11000; /* drive low level */ >> + epap->rfp.border_data_sel = 2; /* "vbd" */ >> + epap->rfp.data_polarity = 0; /* "ddx" */ >> + epap->rfp.vcom_dc_mv = -1000; >> + epap->rfp.vcom_data_ivl_hsync = 10; /* hsync periods */ >> + epap->rfp.use_otp_luts_flag = 1; >> + epap->ss_param[0] = 0x07; >> + epap->ss_param[1] = 0x07; >> + epap->ss_param[2] = 0x17; >> + epap->controller_res = GDEP_CTRL_RES_320X300; >> + >> + ret = gdepaper_of_read_luts(epap, np, dev); >> + if (ret) { >> + dev_warn(dev, "can't read LUTs from dt\n"); >> + goto err_free; >> + } >> + >> + of_property_read_u32(np, "controller-resolution", >> + &epap->controller_res); >> + of_property_read_u32(np, "spi-speed-hz", &epap->spi_speed_hz); >> + epap->partial_update_en = of_property_read_bool(np, "partial-update"); >> + ret = of_property_read_u32(np, "colors", &epap->display_colors); >> + if (ret == -EINVAL) { >> + if (type_desc) { >> + epap->display_colors = type_desc->colors; >> + >> + } else { >> + dev_err(dev, "colors must be set in dt\n"); >> + ret = -EINVAL; >> + goto err_free; >> + } >> + } else if (ret) { >> + dev_err(dev, "Invalid dt colors property\n"); >> + goto err_free; >> + } >> + if (epap->display_colors < 0 || >> + epap->display_colors >= GDEPAPER_COL_END) { >> + dev_err(dev, "invalid colors value\n"); >> + ret = -EINVAL; >> + goto err_free; >> + } >> + epap->mirror_x = of_property_read_bool(np, "mirror-x"); >> + epap->mirror_y = of_property_read_bool(np, "mirror-y"); >> + of_property_read_u32(np, "pll-div", &epap->pll_div); >> + of_property_read_u32(np, "fps-millihertz", &epap->framerate_mHz); >> + of_property_read_u32(np, "vghl-level", &epap->rfp.vg_lv); >> + epap->vds_en = !of_property_read_bool(np, "vds-external"); >> + epap->vdg_en = !of_property_read_bool(np, "vdg-external"); >> + of_property_read_u32(np, "vcom", &epap->rfp.vcom_sel); >> + of_property_read_u32(np, "vdh-bw-millivolts", &epap->rfp.vdh_bw_mv); >> + of_property_read_u32(np, "vdh-color-millivolts", &epap->rfp.vdh_col_mv); >> + of_property_read_u32(np, "vdl-millivolts", &epap->rfp.vdl_mv); >> + of_property_read_u32(np, "border-data", &epap->rfp.border_data_sel); >> + of_property_read_u32(np, "data-polarity", &epap->rfp.data_polarity); >> + ret = of_property_read_u8_array(np, "boost-soft-start", >> + (u8 *)&epap->ss_param, sizeof(epap->ss_param)); >> + if (ret && ret != -EINVAL) >> + dev_err(dev, "invalid boost-soft-start value, ignoring\n"); >> + of_property_read_u32(np, "vcom-data-interval-periods", >> + &epap->rfp.vcom_data_ivl_hsync); > > Why do you need these DT properties when you define compatibles for all > the panels, can't you include these settings in the type descriptor? I allowed for these to be overridden in case there is some panel that's not listed on the mfg's (quite chaotic) website. Looking at this some more I think I'll remove some of these though. I'll leave vds-external/vgs-external since they depend on circuitry around the panel and thus should be in DT. boost-soft-start is largely undocumented and I don't know what they might be useful for, but I feel it could depend on the booster inductors and voltage regulator connected to the panel, so it should be in DT. Those ending up in the refresh params struct are refresh-related and thus application-specific. Most of these come with probably sane defaults, so to initialize a display at a minimum you only need either the type (compatible=gdew...) or the dimensions (px, mm) and color scheme. >> + >> + /* Accept both positive and negative notation */ >> + if (epap->rfp.vdl_mv < 0) >> + epap->rfp.vdl_mv = -epap->rfp.vdl_mv; >> + if (epap->rfp.vcom_dc_mv < 0) >> + epap->rfp.vcom_dc_mv = -epap->rfp.vcom_dc_mv; >> + >> + /* (from mipi-dbi.c:) >> + * Even though it's not the SPI device that does DMA (the master does), >> + * the dma mask is necessary for the dma_alloc_wc() in >> + * drm_gem_cma_create(). The dma_addr returned will be a physical >> + * address which might be different from the bus address, but this is >> + * not a problem since the address will not be used. >> + * The virtual address is used in the transfer and the SPI core >> + * re-maps it on the SPI master device using the DMA streaming API >> + * (spi_map_buf()). >> + */ >> + if (!dev->coherent_dma_mask) { >> + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); >> + if (ret) { >> + dev_warn(dev, "Failed to set dma mask %d\n", ret); >> + goto err_free; >> + } >> + } >> + >> + mode = gdepaper_of_read_mode(type_desc, np, dev); >> + if (IS_ERR(mode)) { >> + dev_warn(dev, "Failed to read mode: %ld\n", PTR_ERR(mode)); >> + ret = PTR_ERR(mode); >> + goto err_free; >> + } >> + >> + /* 8 pixels per byte, bit-packed */ >> + bufsize = (mode->vdisplay * mode->hdisplay + 7)/8; > > DIV_ROUND_UP(mode->vdisplay * mode->hdisplay, 8) > >> + epap->tx_buf = devm_kmalloc(drm->dev, bufsize, GFP_KERNEL); >> + if (!epap->tx_buf) { >> + ret = -ENOMEM; >> + goto err_free; >> + } >> + >> + /* TODO rotation support? */ >> + ret = tinydrm_display_pipe_init(drm, &epap->pipe, &gdepaper_pipe_funcs, >> + DRM_MODE_CONNECTOR_VIRTUAL, >> + gdepaper_formats, >> + ARRAY_SIZE(gdepaper_formats), mode, 0); > > tinydrm_display_pipe_init() is gone now, here's how I replaced it in the > other e-ink driver: > > drm/tinydrm/repaper: Don't use tinydrm_display_pipe_init() > https://cgit.freedesktop.org/drm/drm-misc/commit?id=1321db837549a0ff9dc2c95ff76c46770f7f02a1 Thank you. I found an almost identical solution. - Jan From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?Q?Jan_Sebastian_G=c3=b6tte?= Subject: Re: [PATCH 6/6] drm: tiny: gdepaper: add driver for 2/3 color epaper displays Date: Sat, 10 Aug 2019 14:17:06 +0900 Message-ID: <7ebf06e2-fe24-a4fb-25ff-77ce1ee3ae16@jaseg.net> References: <95b64347-fbc8-ba3d-79da-9de2557ff95e@jaseg.net> <604c82ee-af16-5f34-b229-5e919c4adfdc@tronnes.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from wout5-smtp.messagingengine.com (wout5-smtp.messagingengine.com [64.147.123.21]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6826E6EF3D for ; Sat, 10 Aug 2019 05:17:13 +0000 (UTC) In-Reply-To: <604c82ee-af16-5f34-b229-5e919c4adfdc@tronnes.org> Content-Language: en-US List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , dri-devel@lists.freedesktop.org Cc: David Airlie , linux-kernel@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org SGkgTm9yYWxmLAoKdGhhbmsgeW91IGZvciB5b3VyIGNvbW1lbnRzLiBJJ3ZlIGluY29ycG9yYXRl ZCB5b3VyIHN1Z2dlc3Rpb25zIGludG8gbXkgZHJhZnQuCgpPbiA4LzcvMTkgMTowNiBBTSwgTm9y YWxmIFRyw7hubmVzIHdyb3RlOgpbLi4uXQoKPj4gK3N0YXRpYyBpbnQgZ2RlcGFwZXJfcHJvYmUo c3RydWN0IHNwaV9kZXZpY2UgKnNwaSkKPj4gK3sKPj4gKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAm c3BpLT5kZXY7Cj4+ICsJc3RydWN0IGRldmljZV9ub2RlICpucCA9IGRldi0+b2Zfbm9kZTsKPj4g Kwljb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkICpvZl9pZDsKPj4gKwlzdHJ1Y3QgZHJtX2Rldmlj ZSAqZHJtOwo+PiArCXN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlOwo+PiArCXN0cnVjdCBn ZGVwYXBlciAqZXBhcDsKPj4gKwljb25zdCBzdHJ1Y3QgZ2RlcGFwZXJfdHlwZV9kZXNjcmlwdG9y ICp0eXBlX2Rlc2M7Cj4+ICsJaW50IHJldDsKPj4gKwlzaXplX3QgYnVmc2l6ZTsKPj4gKwo+PiAr CW9mX2lkID0gb2ZfbWF0Y2hfbm9kZShnZGVwYXBlcl9vZl9tYXRjaCwgbnApOwo+PiArCWlmIChX QVJOX09OKG9mX2lkID09IE5VTEwpKSB7Cj4+ICsJCWRldl93YXJuKGRldiwgImR0IG5vZGUgZGlk bid0IG1hdGNoLCBhYm9ydGluZyBwcm9iZVxuIik7Cj4+ICsJCXJldHVybiAtRUlOVkFMOwo+PiAr CX0KPj4gKwl0eXBlX2Rlc2MgPSBvZl9pZC0+ZGF0YTsKPj4gKwo+PiArCWRldl9kYmcoZGV2LCAi UHJvYmluZyBnZGVwYXBlciBtb2R1bGVcbiIpOwo+PiArCWVwYXAgPSBremFsbG9jKHNpemVvZigq ZXBhcCksIEdGUF9LRVJORUwpOwo+PiArCWlmICghZXBhcCkKPj4gKwkJcmV0dXJuIC1FTk9NRU07 Cj4+ICsKPj4gKwllcGFwLT5lbmFibGVkID0gZmFsc2U7Cj4+ICsJbXV0ZXhfaW5pdCgmZXBhcC0+ Y21kbG9jayk7Cj4+ICsJZXBhcC0+dHhfYnVmID0gTlVMTDsKPj4gKwllcGFwLT5zcGkgPSBzcGk7 Cj4+ICsKPj4gKwlkcm0gPSAmZXBhcC0+ZHJtOwo+PiArCXJldCA9IGRldm1fZHJtX2Rldl9pbml0 KGRldiwgZHJtLCAmZ2RlcGFwZXJfZHJpdmVyKTsKPj4gKwlpZiAocmV0KSB7Cj4+ICsJCWRldl93 YXJuKGRldiwgImZhaWxlZCB0byBpbml0IGRybSBkZXZcbiIpOwo+PiArCQlnb3RvIGVycl9mcmVl Owo+PiArCX0KPj4gKwo+PiArCWRybV9tb2RlX2NvbmZpZ19pbml0KGRybSk7Cj4+ICsKPj4gKwll cGFwLT5yZXNldCA9IGRldm1fZ3Bpb2RfZ2V0KGRldiwgInJlc2V0IiwgR1BJT0RfT1VUX0hJR0gp Owo+PiArCWlmIChJU19FUlIoZXBhcC0+cmVzZXQpKSB7Cj4+ICsJCWRldl9lcnIoZGV2LCAiRmFp bGVkIHRvIGdldCByZXNldCBHUElPXG4iKTsKPj4gKwkJcmV0ID0gUFRSX0VSUihlcGFwLT5yZXNl dCk7Cj4+ICsJCWdvdG8gZXJyX2ZyZWU7Cj4+ICsJfQo+PiArCj4+ICsJZXBhcC0+YnVzeSA9IGRl dm1fZ3Bpb2RfZ2V0KGRldiwgImJ1c3kiLCBHUElPRF9JTik7Cj4+ICsJaWYgKElTX0VSUihlcGFw LT5idXN5KSkgewo+PiArCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0byBnZXQgYnVzeSBHUElPXG4i KTsKPj4gKwkJcmV0ID0gUFRSX0VSUihlcGFwLT5idXN5KTsKPj4gKwkJZ290byBlcnJfZnJlZTsK Pj4gKwl9Cj4+ICsKPj4gKwllcGFwLT5kYyA9IGRldm1fZ3Bpb2RfZ2V0KGRldiwgImRjIiwgR1BJ T0RfT1VUX0xPVyk7Cj4+ICsJaWYgKElTX0VSUihlcGFwLT5kYykpIHsKPj4gKwkJZGV2X2Vycihk ZXYsICJGYWlsZWQgdG8gZ2V0IGRjIEdQSU9cbiIpOwo+PiArCQlyZXQgPSBQVFJfRVJSKGVwYXAt PmRjKTsKPj4gKwkJZ290byBlcnJfZnJlZTsKPj4gKwl9Cj4+ICsKPj4gKwllcGFwLT5zcGlfc3Bl ZWRfaHogPSAyMDAwMDAwOwo+PiArCWVwYXAtPnBsbF9kaXYgPSAxOwo+PiArCWVwYXAtPmZyYW1l cmF0ZV9tSHogPSA4MTg1MDsKPj4gKwllcGFwLT5yZnAudmdfbHYgPSBHREVQX1BXUl9WR0hMXzE2 VjsKPj4gKwllcGFwLT5yZnAudmNvbV9zZWwgPSAwOwo+PiArCWVwYXAtPnJmcC52ZGhfYndfbXYg PSAxMTAwMDsgLyogZHJpdmUgaGlnaCBsZXZlbCwgYi93IHBpeGVsICovCj4+ICsJZXBhcC0+cmZw LnZkaF9jb2xfbXYgPSA0MjAwOyAvKiBkcml2ZSBoaWdoIGxldmVsLCByZWQveWVsbG93IHBpeGVs ICovCj4+ICsJZXBhcC0+cmZwLnZkbF9tdiA9IC0xMTAwMDsgLyogZHJpdmUgbG93IGxldmVsICov Cj4+ICsJZXBhcC0+cmZwLmJvcmRlcl9kYXRhX3NlbCA9IDI7IC8qICJ2YmQiICovCj4+ICsJZXBh cC0+cmZwLmRhdGFfcG9sYXJpdHkgPSAwOyAvKiAiZGR4IiAqLwo+PiArCWVwYXAtPnJmcC52Y29t X2RjX212ID0gLTEwMDA7Cj4+ICsJZXBhcC0+cmZwLnZjb21fZGF0YV9pdmxfaHN5bmMgPSAxMDsg LyogaHN5bmMgcGVyaW9kcyAqLwo+PiArCWVwYXAtPnJmcC51c2Vfb3RwX2x1dHNfZmxhZyA9IDE7 Cj4+ICsJZXBhcC0+c3NfcGFyYW1bMF0gPSAweDA3Owo+PiArCWVwYXAtPnNzX3BhcmFtWzFdID0g MHgwNzsKPj4gKwllcGFwLT5zc19wYXJhbVsyXSA9IDB4MTc7Cj4+ICsJZXBhcC0+Y29udHJvbGxl cl9yZXMgPSBHREVQX0NUUkxfUkVTXzMyMFgzMDA7Cj4+ICsKPj4gKwlyZXQgPSBnZGVwYXBlcl9v Zl9yZWFkX2x1dHMoZXBhcCwgbnAsIGRldik7Cj4+ICsJaWYgKHJldCkgewo+PiArCQlkZXZfd2Fy bihkZXYsICJjYW4ndCByZWFkIExVVHMgZnJvbSBkdFxuIik7Cj4+ICsJCWdvdG8gZXJyX2ZyZWU7 Cj4+ICsJfQo+PiArCj4+ICsJb2ZfcHJvcGVydHlfcmVhZF91MzIobnAsICJjb250cm9sbGVyLXJl c29sdXRpb24iLAo+PiArCQkJJmVwYXAtPmNvbnRyb2xsZXJfcmVzKTsKPj4gKwlvZl9wcm9wZXJ0 eV9yZWFkX3UzMihucCwgInNwaS1zcGVlZC1oeiIsICZlcGFwLT5zcGlfc3BlZWRfaHopOwo+PiAr CWVwYXAtPnBhcnRpYWxfdXBkYXRlX2VuID0gb2ZfcHJvcGVydHlfcmVhZF9ib29sKG5wLCAicGFy dGlhbC11cGRhdGUiKTsKPj4gKwlyZXQgPSBvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgImNvbG9y cyIsICZlcGFwLT5kaXNwbGF5X2NvbG9ycyk7Cj4+ICsJaWYgKHJldCA9PSAtRUlOVkFMKSB7Cj4+ ICsJCWlmICh0eXBlX2Rlc2MpIHsKPj4gKwkJCWVwYXAtPmRpc3BsYXlfY29sb3JzID0gdHlwZV9k ZXNjLT5jb2xvcnM7Cj4+ICsKPj4gKwkJfSBlbHNlIHsKPj4gKwkJCWRldl9lcnIoZGV2LCAiY29s b3JzIG11c3QgYmUgc2V0IGluIGR0XG4iKTsKPj4gKwkJCXJldCA9IC1FSU5WQUw7Cj4+ICsJCQln b3RvIGVycl9mcmVlOwo+PiArCQl9Cj4+ICsJfSBlbHNlIGlmIChyZXQpIHsKPj4gKwkJZGV2X2Vy cihkZXYsICJJbnZhbGlkIGR0IGNvbG9ycyBwcm9wZXJ0eVxuIik7Cj4+ICsJCWdvdG8gZXJyX2Zy ZWU7Cj4+ICsJfQo+PiArCWlmIChlcGFwLT5kaXNwbGF5X2NvbG9ycyA8IDAgfHwKPj4gKwkJCWVw YXAtPmRpc3BsYXlfY29sb3JzID49IEdERVBBUEVSX0NPTF9FTkQpIHsKPj4gKwkJZGV2X2Vycihk ZXYsICJpbnZhbGlkIGNvbG9ycyB2YWx1ZVxuIik7Cj4+ICsJCXJldCA9IC1FSU5WQUw7Cj4+ICsJ CWdvdG8gZXJyX2ZyZWU7Cj4+ICsJfQo+PiArCWVwYXAtPm1pcnJvcl94ID0gb2ZfcHJvcGVydHlf cmVhZF9ib29sKG5wLCAibWlycm9yLXgiKTsKPj4gKwllcGFwLT5taXJyb3JfeSA9IG9mX3Byb3Bl cnR5X3JlYWRfYm9vbChucCwgIm1pcnJvci15Iik7Cj4+ICsJb2ZfcHJvcGVydHlfcmVhZF91MzIo bnAsICJwbGwtZGl2IiwgJmVwYXAtPnBsbF9kaXYpOwo+PiArCW9mX3Byb3BlcnR5X3JlYWRfdTMy KG5wLCAiZnBzLW1pbGxpaGVydHoiLCAmZXBhcC0+ZnJhbWVyYXRlX21Ieik7Cj4+ICsJb2ZfcHJv cGVydHlfcmVhZF91MzIobnAsICJ2Z2hsLWxldmVsIiwgJmVwYXAtPnJmcC52Z19sdik7Cj4+ICsJ ZXBhcC0+dmRzX2VuID0gIW9mX3Byb3BlcnR5X3JlYWRfYm9vbChucCwgInZkcy1leHRlcm5hbCIp Owo+PiArCWVwYXAtPnZkZ19lbiA9ICFvZl9wcm9wZXJ0eV9yZWFkX2Jvb2wobnAsICJ2ZGctZXh0 ZXJuYWwiKTsKPj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgInZjb20iLCAmZXBhcC0+cmZw LnZjb21fc2VsKTsKPj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgInZkaC1idy1taWxsaXZv bHRzIiwgJmVwYXAtPnJmcC52ZGhfYndfbXYpOwo+PiArCW9mX3Byb3BlcnR5X3JlYWRfdTMyKG5w LCAidmRoLWNvbG9yLW1pbGxpdm9sdHMiLCAmZXBhcC0+cmZwLnZkaF9jb2xfbXYpOwo+PiArCW9m X3Byb3BlcnR5X3JlYWRfdTMyKG5wLCAidmRsLW1pbGxpdm9sdHMiLCAmZXBhcC0+cmZwLnZkbF9t dik7Cj4+ICsJb2ZfcHJvcGVydHlfcmVhZF91MzIobnAsICJib3JkZXItZGF0YSIsICZlcGFwLT5y ZnAuYm9yZGVyX2RhdGFfc2VsKTsKPj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgImRhdGEt cG9sYXJpdHkiLCAmZXBhcC0+cmZwLmRhdGFfcG9sYXJpdHkpOwo+PiArCXJldCA9IG9mX3Byb3Bl cnR5X3JlYWRfdThfYXJyYXkobnAsICJib29zdC1zb2Z0LXN0YXJ0IiwKPj4gKwkJCSh1OCAqKSZl cGFwLT5zc19wYXJhbSwgc2l6ZW9mKGVwYXAtPnNzX3BhcmFtKSk7Cj4+ICsJaWYgKHJldCAmJiBy ZXQgIT0gLUVJTlZBTCkKPj4gKwkJZGV2X2VycihkZXYsICJpbnZhbGlkIGJvb3N0LXNvZnQtc3Rh cnQgdmFsdWUsIGlnbm9yaW5nXG4iKTsKPj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgInZj b20tZGF0YS1pbnRlcnZhbC1wZXJpb2RzIiwKPj4gKwkJCSZlcGFwLT5yZnAudmNvbV9kYXRhX2l2 bF9oc3luYyk7Cj4gCj4gV2h5IGRvIHlvdSBuZWVkIHRoZXNlIERUIHByb3BlcnRpZXMgd2hlbiB5 b3UgZGVmaW5lIGNvbXBhdGlibGVzIGZvciBhbGwKPiB0aGUgcGFuZWxzLCBjYW4ndCB5b3UgaW5j bHVkZSB0aGVzZSBzZXR0aW5ncyBpbiB0aGUgdHlwZSBkZXNjcmlwdG9yPwoJSSBhbGxvd2VkIGZv ciB0aGVzZSB0byBiZSBvdmVycmlkZGVuIGluIGNhc2UgdGhlcmUgaXMgc29tZSBwYW5lbCB0aGF0 J3Mgbm90IGxpc3RlZCBvbiB0aGUgbWZnJ3MgKHF1aXRlIGNoYW90aWMpIHdlYnNpdGUuIExvb2tp bmcgYXQgdGhpcyBzb21lIG1vcmUgSSB0aGluayBJJ2xsIHJlbW92ZSBzb21lIG9mIHRoZXNlIHRo b3VnaC4KCkknbGwgbGVhdmUgdmRzLWV4dGVybmFsL3Zncy1leHRlcm5hbCBzaW5jZSB0aGV5IGRl cGVuZCBvbiBjaXJjdWl0cnkgYXJvdW5kIHRoZSBwYW5lbCBhbmQgdGh1cyBzaG91bGQgYmUgaW4g RFQuIGJvb3N0LXNvZnQtc3RhcnQgaXMgbGFyZ2VseSB1bmRvY3VtZW50ZWQgYW5kIEkgZG9uJ3Qg a25vdyB3aGF0IHRoZXkgbWlnaHQgYmUgdXNlZnVsIGZvciwgYnV0IEkgZmVlbCBpdCBjb3VsZCBk ZXBlbmQgb24gdGhlIGJvb3N0ZXIgaW5kdWN0b3JzIGFuZCB2b2x0YWdlIHJlZ3VsYXRvciBjb25u ZWN0ZWQgdG8gdGhlIHBhbmVsLCBzbyBpdCBzaG91bGQgYmUgaW4gRFQuCgpUaG9zZSBlbmRpbmcg dXAgaW4gdGhlIHJlZnJlc2ggcGFyYW1zIHN0cnVjdCBhcmUgcmVmcmVzaC1yZWxhdGVkIGFuZCB0 aHVzIGFwcGxpY2F0aW9uLXNwZWNpZmljLiBNb3N0IG9mIHRoZXNlIGNvbWUgd2l0aCBwcm9iYWJs eSBzYW5lIGRlZmF1bHRzLCBzbyB0byBpbml0aWFsaXplIGEgZGlzcGxheSBhdCBhIG1pbmltdW0g eW91IG9ubHkgbmVlZCBlaXRoZXIgdGhlIHR5cGUgKGNvbXBhdGlibGU9Z2Rldy4uLikgb3IgdGhl IGRpbWVuc2lvbnMgKHB4LCBtbSkgYW5kIGNvbG9yIHNjaGVtZS4KCj4+ICsKPj4gKwkvKiBBY2Nl cHQgYm90aCBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgbm90YXRpb24gKi8KPj4gKwlpZiAoZXBhcC0+ cmZwLnZkbF9tdiA8IDApCj4+ICsJCWVwYXAtPnJmcC52ZGxfbXYgPSAtZXBhcC0+cmZwLnZkbF9t djsKPj4gKwlpZiAoZXBhcC0+cmZwLnZjb21fZGNfbXYgPCAwKQo+PiArCQllcGFwLT5yZnAudmNv bV9kY19tdiA9IC1lcGFwLT5yZnAudmNvbV9kY19tdjsKPj4gKwo+PiArCS8qIChmcm9tIG1pcGkt ZGJpLmM6KQo+PiArCSAqIEV2ZW4gdGhvdWdoIGl0J3Mgbm90IHRoZSBTUEkgZGV2aWNlIHRoYXQg ZG9lcyBETUEgKHRoZSBtYXN0ZXIgZG9lcyksCj4+ICsJICogdGhlIGRtYSBtYXNrIGlzIG5lY2Vz c2FyeSBmb3IgdGhlIGRtYV9hbGxvY193YygpIGluCj4+ICsJICogZHJtX2dlbV9jbWFfY3JlYXRl KCkuIFRoZSBkbWFfYWRkciByZXR1cm5lZCB3aWxsIGJlIGEgcGh5c2ljYWwKPj4gKwkgKiBhZGRy ZXNzIHdoaWNoIG1pZ2h0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBidXMgYWRkcmVzcywgYnV0IHRo aXMgaXMKPj4gKwkgKiBub3QgYSBwcm9ibGVtIHNpbmNlIHRoZSBhZGRyZXNzIHdpbGwgbm90IGJl IHVzZWQuCj4+ICsJICogVGhlIHZpcnR1YWwgYWRkcmVzcyBpcyB1c2VkIGluIHRoZSB0cmFuc2Zl ciBhbmQgdGhlIFNQSSBjb3JlCj4+ICsJICogcmUtbWFwcyBpdCBvbiB0aGUgU1BJIG1hc3RlciBk ZXZpY2UgdXNpbmcgdGhlIERNQSBzdHJlYW1pbmcgQVBJCj4+ICsJICogKHNwaV9tYXBfYnVmKCkp Lgo+PiArCSAqLwo+PiArCWlmICghZGV2LT5jb2hlcmVudF9kbWFfbWFzaykgewo+PiArCQlyZXQg PSBkbWFfY29lcmNlX21hc2tfYW5kX2NvaGVyZW50KGRldiwgRE1BX0JJVF9NQVNLKDMyKSk7Cj4+ ICsJCWlmIChyZXQpIHsKPj4gKwkJCWRldl93YXJuKGRldiwgIkZhaWxlZCB0byBzZXQgZG1hIG1h c2sgJWRcbiIsIHJldCk7Cj4+ICsJCQlnb3RvIGVycl9mcmVlOwo+PiArCQl9Cj4+ICsJfQo+PiAr Cj4+ICsJbW9kZSA9IGdkZXBhcGVyX29mX3JlYWRfbW9kZSh0eXBlX2Rlc2MsIG5wLCBkZXYpOwo+ PiArCWlmIChJU19FUlIobW9kZSkpIHsKPj4gKwkJZGV2X3dhcm4oZGV2LCAiRmFpbGVkIHRvIHJl YWQgbW9kZTogJWxkXG4iLCBQVFJfRVJSKG1vZGUpKTsKPj4gKwkJcmV0ID0gUFRSX0VSUihtb2Rl KTsKPj4gKwkJZ290byBlcnJfZnJlZTsKPj4gKwl9Cj4+ICsKPj4gKwkvKiA4IHBpeGVscyBwZXIg Ynl0ZSwgYml0LXBhY2tlZCAqLwo+PiArCWJ1ZnNpemUgPSAobW9kZS0+dmRpc3BsYXkgKiBtb2Rl LT5oZGlzcGxheSArIDcpLzg7Cj4gCj4gRElWX1JPVU5EX1VQKG1vZGUtPnZkaXNwbGF5ICogbW9k ZS0+aGRpc3BsYXksIDgpCj4gCj4+ICsJZXBhcC0+dHhfYnVmID0gZGV2bV9rbWFsbG9jKGRybS0+ ZGV2LCBidWZzaXplLCBHRlBfS0VSTkVMKTsKPj4gKwlpZiAoIWVwYXAtPnR4X2J1Zikgewo+PiAr CQlyZXQgPSAtRU5PTUVNOwo+PiArCQlnb3RvIGVycl9mcmVlOwo+PiArCX0KPj4gKwo+PiArCS8q IFRPRE8gcm90YXRpb24gc3VwcG9ydD8gKi8KPj4gKwlyZXQgPSB0aW55ZHJtX2Rpc3BsYXlfcGlw ZV9pbml0KGRybSwgJmVwYXAtPnBpcGUsICZnZGVwYXBlcl9waXBlX2Z1bmNzLAo+PiArCQkJCQlE Uk1fTU9ERV9DT05ORUNUT1JfVklSVFVBTCwKPj4gKwkJCQkJZ2RlcGFwZXJfZm9ybWF0cywKPj4g KwkJCQkJQVJSQVlfU0laRShnZGVwYXBlcl9mb3JtYXRzKSwgbW9kZSwgMCk7Cj4gCj4gdGlueWRy bV9kaXNwbGF5X3BpcGVfaW5pdCgpIGlzIGdvbmUgbm93LCBoZXJlJ3MgaG93IEkgcmVwbGFjZWQg aXQgaW4gdGhlCj4gb3RoZXIgZS1pbmsgZHJpdmVyOgo+IAo+IGRybS90aW55ZHJtL3JlcGFwZXI6 IERvbid0IHVzZSB0aW55ZHJtX2Rpc3BsYXlfcGlwZV9pbml0KCkKPiBodHRwczovL2NnaXQuZnJl ZWRlc2t0b3Aub3JnL2RybS9kcm0tbWlzYy9jb21taXQ/aWQ9MTMyMWRiODM3NTQ5YTBmZjlkYzJj OTVmZjc2YzQ2NzcwZjdmMDJhMQpUaGFuayB5b3UuIEkgZm91bmQgYW4gYWxtb3N0IGlkZW50aWNh bCBzb2x1dGlvbi4KCi0gSmFuCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNr dG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2Ry aS1kZXZlbA==