From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from galahad.ideasonboard.com ([185.26.127.97]:40901 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751847AbdCCRXc (ORCPT ); Fri, 3 Mar 2017 12:23:32 -0500 From: Laurent Pinchart To: dri-devel@lists.freedesktop.org Cc: Andy Yan , Archit Taneja , Fabio Estevam , Jose Abreu , Kieran Bingham , Neil Armstrong , Nickey Yang , Russell King , Vladimir Zapolskiy , linux-renesas-soc@vger.kernel.org, Kieran Bingham Subject: [PATCH v5 07/10] drm: bridge: dw-hdmi: Add support for custom PHY configuration Date: Fri, 3 Mar 2017 19:20:04 +0200 Message-Id: <20170303172007.26541-8-laurent.pinchart+renesas@ideasonboard.com> In-Reply-To: <20170303172007.26541-1-laurent.pinchart+renesas@ideasonboard.com> References: <20170303172007.26541-1-laurent.pinchart+renesas@ideasonboard.com> Sender: linux-renesas-soc-owner@vger.kernel.org List-ID: From: Kieran Bingham The DWC HDMI TX controller interfaces with a companion PHY. While Synopsys provides multiple standard PHYs, SoC vendors can also integrate a custom PHY. Modularize PHY configuration to support vendor PHYs through platform data. The existing PHY configuration code was originally written to support the DWC HDMI 3D TX PHY, and seems to be compatible with the DWC MLP PHY. The HDMI 2.0 PHY will require a separate configuration function. Signed-off-by: Kieran Bingham Signed-off-by: Laurent Pinchart Tested-by: Neil Armstrong Reviewed-by: Jose Abreu --- Changes since v1: - Check pdata->phy_configure in hdmi_phy_configure() to avoid dereferencing NULL pointer. --- drivers/gpu/drm/bridge/dw-hdmi.c | 109 ++++++++++++++++++++++++++------------- include/drm/bridge/dw_hdmi.h | 7 +++ 2 files changed, 81 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index cb2703862be2..b835d81bb471 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -118,6 +118,9 @@ struct dw_hdmi_phy_data { const char *name; unsigned int gen; bool has_svsret; + int (*configure)(struct dw_hdmi *hdmi, + const struct dw_hdmi_plat_data *pdata, + unsigned long mpixelclock); }; struct dw_hdmi { @@ -860,8 +863,8 @@ static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) return true; } -static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, - unsigned char addr) +void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, + unsigned char addr) { hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); @@ -873,6 +876,7 @@ static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, HDMI_PHY_I2CM_OPERATION_ADDR); hdmi_phy_wait_i2c_done(hdmi, 1000); } +EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write); static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) { @@ -993,37 +997,67 @@ static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) return 0; } -static int hdmi_phy_configure(struct dw_hdmi *hdmi) +/* + * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available + * information the DWC MHL PHY has the same register layout and is thus also + * supported by this function. + */ +static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, + const struct dw_hdmi_plat_data *pdata, + unsigned long mpixelclock) { - const struct dw_hdmi_phy_data *phy = hdmi->phy.data; - const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; /* PLL/MPLL Cfg - always match on final entry */ for (; mpll_config->mpixelclock != ~0UL; mpll_config++) - if (hdmi->hdmi_data.video_mode.mpixelclock <= - mpll_config->mpixelclock) + if (mpixelclock <= mpll_config->mpixelclock) break; for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) - if (hdmi->hdmi_data.video_mode.mpixelclock <= - curr_ctrl->mpixelclock) + if (mpixelclock <= curr_ctrl->mpixelclock) break; for (; phy_config->mpixelclock != ~0UL; phy_config++) - if (hdmi->hdmi_data.video_mode.mpixelclock <= - phy_config->mpixelclock) + if (mpixelclock <= phy_config->mpixelclock) break; if (mpll_config->mpixelclock == ~0UL || curr_ctrl->mpixelclock == ~0UL || - phy_config->mpixelclock == ~0UL) { - dev_err(hdmi->dev, "Pixel clock %d - unsupported by HDMI\n", - hdmi->hdmi_data.video_mode.mpixelclock); + phy_config->mpixelclock == ~0UL) return -EINVAL; - } + + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, + HDMI_3D_TX_PHY_CPCE_CTRL); + dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, + HDMI_3D_TX_PHY_GMPCTRL); + dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], + HDMI_3D_TX_PHY_CURRCTRL); + + dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); + dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, + HDMI_3D_TX_PHY_MSM_CTRL); + + dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); + dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, + HDMI_3D_TX_PHY_CKSYMTXCTRL); + dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, + HDMI_3D_TX_PHY_VLEVCTRL); + + /* Override and disable clock termination. */ + dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, + HDMI_3D_TX_PHY_CKCALCTRL); + + return 0; +} + +static int hdmi_phy_configure(struct dw_hdmi *hdmi) +{ + const struct dw_hdmi_phy_data *phy = hdmi->phy.data; + const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; + unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock; + int ret; dw_hdmi_phy_power_off(hdmi); @@ -1042,26 +1076,16 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi) HDMI_PHY_I2CM_SLAVE_ADDR); hdmi_phy_test_clear(hdmi, 0); - hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, - HDMI_3D_TX_PHY_CPCE_CTRL); - hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, - HDMI_3D_TX_PHY_GMPCTRL); - hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], - HDMI_3D_TX_PHY_CURRCTRL); - - hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); - hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, - HDMI_3D_TX_PHY_MSM_CTRL); - - hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM); - hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr, - HDMI_3D_TX_PHY_CKSYMTXCTRL); - hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr, - HDMI_3D_TX_PHY_VLEVCTRL); - - /* Override and disable clock termination. */ - hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, - HDMI_3D_TX_PHY_CKCALCTRL); + /* Write to the PHY as configured by the platform */ + if (pdata->configure_phy) + ret = pdata->configure_phy(hdmi, pdata, mpixelclock); + else + ret = phy->configure(hdmi, pdata, mpixelclock); + if (ret) { + dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n", + mpixelclock); + return ret; + } return dw_hdmi_phy_power_on(hdmi); } @@ -1895,24 +1919,31 @@ static const struct dw_hdmi_phy_data dw_hdmi_phys[] = { .name = "DWC MHL PHY + HEAC PHY", .gen = 2, .has_svsret = true, + .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, }, { .type = DW_HDMI_PHY_DWC_MHL_PHY, .name = "DWC MHL PHY", .gen = 2, .has_svsret = true, + .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, }, { .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, .name = "DWC HDMI 3D TX PHY + HEAC PHY", .gen = 2, + .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, }, { .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, .name = "DWC HDMI 3D TX PHY", .gen = 2, + .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, }, { .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, .name = "DWC HDMI 2.0 TX PHY", .gen = 2, .has_svsret = true, + }, { + .type = DW_HDMI_PHY_VENDOR_PHY, + .name = "Vendor PHY", } }; @@ -1943,6 +1974,14 @@ static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; hdmi->phy.name = dw_hdmi_phys[i].name; hdmi->phy.data = (void *)&dw_hdmi_phys[i]; + + if (!dw_hdmi_phys[i].configure && + !hdmi->plat_data->configure_phy) { + dev_err(hdmi->dev, "%s requires platform support\n", + hdmi->phy.name); + return -ENODEV; + } + return 0; } } diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 0f583ca7e66e..dd330259a3dc 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -78,6 +78,9 @@ struct dw_hdmi_plat_data { const struct dw_hdmi_mpll_config *mpll_cfg; const struct dw_hdmi_curr_ctrl *cur_ctr; const struct dw_hdmi_phy_config *phy_config; + int (*configure_phy)(struct dw_hdmi *hdmi, + const struct dw_hdmi_plat_data *pdata, + unsigned long mpixelclock); }; int dw_hdmi_probe(struct platform_device *pdev, @@ -91,4 +94,8 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate); void dw_hdmi_audio_enable(struct dw_hdmi *hdmi); void dw_hdmi_audio_disable(struct dw_hdmi *hdmi); +/* PHY configuration */ +void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, + unsigned char addr); + #endif /* __IMX_HDMI_H__ */ -- Regards, Laurent Pinchart From mboxrd@z Thu Jan 1 00:00:00 1970 From: Laurent Pinchart Subject: [PATCH v5 07/10] drm: bridge: dw-hdmi: Add support for custom PHY configuration Date: Fri, 3 Mar 2017 19:20:04 +0200 Message-ID: <20170303172007.26541-8-laurent.pinchart+renesas@ideasonboard.com> References: <20170303172007.26541-1-laurent.pinchart+renesas@ideasonboard.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from galahad.ideasonboard.com (galahad.ideasonboard.com [IPv6:2001:4b98:dc2:45:216:3eff:febb:480d]) by gabe.freedesktop.org (Postfix) with ESMTPS id 134776EDAC for ; Fri, 3 Mar 2017 17:19:43 +0000 (UTC) In-Reply-To: <20170303172007.26541-1-laurent.pinchart+renesas@ideasonboard.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: Fabio Estevam , Jose Abreu , Neil Armstrong , Kieran Bingham , linux-renesas-soc@vger.kernel.org, Nickey Yang , Kieran Bingham , Russell King , Andy Yan , Vladimir Zapolskiy List-Id: dri-devel@lists.freedesktop.org RnJvbTogS2llcmFuIEJpbmdoYW0gPGtpZXJhbi5iaW5naGFtK3JlbmVzYXNAaWRlYXNvbmJvYXJk LmNvbT4KClRoZSBEV0MgSERNSSBUWCBjb250cm9sbGVyIGludGVyZmFjZXMgd2l0aCBhIGNvbXBh bmlvbiBQSFkuIFdoaWxlClN5bm9wc3lzIHByb3ZpZGVzIG11bHRpcGxlIHN0YW5kYXJkIFBIWXMs IFNvQyB2ZW5kb3JzIGNhbiBhbHNvIGludGVncmF0ZQphIGN1c3RvbSBQSFkuCgpNb2R1bGFyaXpl IFBIWSBjb25maWd1cmF0aW9uIHRvIHN1cHBvcnQgdmVuZG9yIFBIWXMgdGhyb3VnaCBwbGF0Zm9y bQpkYXRhLiBUaGUgZXhpc3RpbmcgUEhZIGNvbmZpZ3VyYXRpb24gY29kZSB3YXMgb3JpZ2luYWxs eSB3cml0dGVuIHRvCnN1cHBvcnQgdGhlIERXQyBIRE1JIDNEIFRYIFBIWSwgYW5kIHNlZW1zIHRv IGJlIGNvbXBhdGlibGUgd2l0aCB0aGUgRFdDCk1MUCBQSFkuIFRoZSBIRE1JIDIuMCBQSFkgd2ls bCByZXF1aXJlIGEgc2VwYXJhdGUgY29uZmlndXJhdGlvbgpmdW5jdGlvbi4KClNpZ25lZC1vZmYt Ynk6IEtpZXJhbiBCaW5naGFtIDxraWVyYW4uYmluZ2hhbStyZW5lc2FzQGlkZWFzb25ib2FyZC5j b20+ClNpZ25lZC1vZmYtYnk6IExhdXJlbnQgUGluY2hhcnQgPGxhdXJlbnQucGluY2hhcnQrcmVu ZXNhc0BpZGVhc29uYm9hcmQuY29tPgpUZXN0ZWQtYnk6IE5laWwgQXJtc3Ryb25nIDxuYXJtc3Ry b25nQGJheWxpYnJlLmNvbT4KUmV2aWV3ZWQtYnk6IEpvc2UgQWJyZXUgPEpvc2UuQWJyZXVAc3lu b3BzeXMuY29tPgotLS0KQ2hhbmdlcyBzaW5jZSB2MToKCi0gQ2hlY2sgcGRhdGEtPnBoeV9jb25m aWd1cmUgaW4gaGRtaV9waHlfY29uZmlndXJlKCkgdG8gYXZvaWQKICBkZXJlZmVyZW5jaW5nIE5V TEwgcG9pbnRlci4KLS0tCiBkcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2R3LWhkbWkuYyB8IDEwOSAr KysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0KIGluY2x1ZGUvZHJtL2JyaWRn ZS9kd19oZG1pLmggICAgIHwgICA3ICsrKwogMiBmaWxlcyBjaGFuZ2VkLCA4MSBpbnNlcnRpb25z KCspLCAzNSBkZWxldGlvbnMoLSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdl L2R3LWhkbWkuYyBiL2RyaXZlcnMvZ3B1L2RybS9icmlkZ2UvZHctaGRtaS5jCmluZGV4IGNiMjcw Mzg2MmJlMi4uYjgzNWQ4MWJiNDcxIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vYnJpZGdl L2R3LWhkbWkuYworKysgYi9kcml2ZXJzL2dwdS9kcm0vYnJpZGdlL2R3LWhkbWkuYwpAQCAtMTE4 LDYgKzExOCw5IEBAIHN0cnVjdCBkd19oZG1pX3BoeV9kYXRhIHsKIAljb25zdCBjaGFyICpuYW1l OwogCXVuc2lnbmVkIGludCBnZW47CiAJYm9vbCBoYXNfc3ZzcmV0OworCWludCAoKmNvbmZpZ3Vy ZSkoc3RydWN0IGR3X2hkbWkgKmhkbWksCisJCQkgY29uc3Qgc3RydWN0IGR3X2hkbWlfcGxhdF9k YXRhICpwZGF0YSwKKwkJCSB1bnNpZ25lZCBsb25nIG1waXhlbGNsb2NrKTsKIH07CiAKIHN0cnVj dCBkd19oZG1pIHsKQEAgLTg2MCw4ICs4NjMsOCBAQCBzdGF0aWMgYm9vbCBoZG1pX3BoeV93YWl0 X2kyY19kb25lKHN0cnVjdCBkd19oZG1pICpoZG1pLCBpbnQgbXNlYykKIAlyZXR1cm4gdHJ1ZTsK IH0KIAotc3RhdGljIHZvaWQgaGRtaV9waHlfaTJjX3dyaXRlKHN0cnVjdCBkd19oZG1pICpoZG1p LCB1bnNpZ25lZCBzaG9ydCBkYXRhLAotCQkJCSB1bnNpZ25lZCBjaGFyIGFkZHIpCit2b2lkIGR3 X2hkbWlfcGh5X2kyY193cml0ZShzdHJ1Y3QgZHdfaGRtaSAqaGRtaSwgdW5zaWduZWQgc2hvcnQg ZGF0YSwKKwkJCSAgIHVuc2lnbmVkIGNoYXIgYWRkcikKIHsKIAloZG1pX3dyaXRlYihoZG1pLCAw eEZGLCBIRE1JX0lIX0kyQ01QSFlfU1RBVDApOwogCWhkbWlfd3JpdGViKGhkbWksIGFkZHIsIEhE TUlfUEhZX0kyQ01fQUREUkVTU19BRERSKTsKQEAgLTg3Myw2ICs4NzYsNyBAQCBzdGF0aWMgdm9p ZCBoZG1pX3BoeV9pMmNfd3JpdGUoc3RydWN0IGR3X2hkbWkgKmhkbWksIHVuc2lnbmVkIHNob3J0 IGRhdGEsCiAJCSAgICBIRE1JX1BIWV9JMkNNX09QRVJBVElPTl9BRERSKTsKIAloZG1pX3BoeV93 YWl0X2kyY19kb25lKGhkbWksIDEwMDApOwogfQorRVhQT1JUX1NZTUJPTF9HUEwoZHdfaGRtaV9w aHlfaTJjX3dyaXRlKTsKIAogc3RhdGljIHZvaWQgZHdfaGRtaV9waHlfZW5hYmxlX3Bvd2VyZG93 bihzdHJ1Y3QgZHdfaGRtaSAqaGRtaSwgYm9vbCBlbmFibGUpCiB7CkBAIC05OTMsMzcgKzk5Nyw2 NyBAQCBzdGF0aWMgaW50IGR3X2hkbWlfcGh5X3Bvd2VyX29uKHN0cnVjdCBkd19oZG1pICpoZG1p KQogCXJldHVybiAwOwogfQogCi1zdGF0aWMgaW50IGhkbWlfcGh5X2NvbmZpZ3VyZShzdHJ1Y3Qg ZHdfaGRtaSAqaGRtaSkKKy8qCisgKiBQSFkgY29uZmlndXJhdGlvbiBmdW5jdGlvbiBmb3IgdGhl IERXQyBIRE1JIDNEIFRYIFBIWS4gQmFzZWQgb24gdGhlIGF2YWlsYWJsZQorICogaW5mb3JtYXRp b24gdGhlIERXQyBNSEwgUEhZIGhhcyB0aGUgc2FtZSByZWdpc3RlciBsYXlvdXQgYW5kIGlzIHRo dXMgYWxzbworICogc3VwcG9ydGVkIGJ5IHRoaXMgZnVuY3Rpb24uCisgKi8KK3N0YXRpYyBpbnQg aGRtaV9waHlfY29uZmlndXJlX2R3Y19oZG1pXzNkX3R4KHN0cnVjdCBkd19oZG1pICpoZG1pLAor CQljb25zdCBzdHJ1Y3QgZHdfaGRtaV9wbGF0X2RhdGEgKnBkYXRhLAorCQl1bnNpZ25lZCBsb25n IG1waXhlbGNsb2NrKQogewotCWNvbnN0IHN0cnVjdCBkd19oZG1pX3BoeV9kYXRhICpwaHkgPSBo ZG1pLT5waHkuZGF0YTsKLQljb25zdCBzdHJ1Y3QgZHdfaGRtaV9wbGF0X2RhdGEgKnBkYXRhID0g aGRtaS0+cGxhdF9kYXRhOwogCWNvbnN0IHN0cnVjdCBkd19oZG1pX21wbGxfY29uZmlnICptcGxs X2NvbmZpZyA9IHBkYXRhLT5tcGxsX2NmZzsKIAljb25zdCBzdHJ1Y3QgZHdfaGRtaV9jdXJyX2N0 cmwgKmN1cnJfY3RybCA9IHBkYXRhLT5jdXJfY3RyOwogCWNvbnN0IHN0cnVjdCBkd19oZG1pX3Bo eV9jb25maWcgKnBoeV9jb25maWcgPSBwZGF0YS0+cGh5X2NvbmZpZzsKIAogCS8qIFBMTC9NUExM IENmZyAtIGFsd2F5cyBtYXRjaCBvbiBmaW5hbCBlbnRyeSAqLwogCWZvciAoOyBtcGxsX2NvbmZp Zy0+bXBpeGVsY2xvY2sgIT0gfjBVTDsgbXBsbF9jb25maWcrKykKLQkJaWYgKGhkbWktPmhkbWlf ZGF0YS52aWRlb19tb2RlLm1waXhlbGNsb2NrIDw9Ci0JCSAgICBtcGxsX2NvbmZpZy0+bXBpeGVs Y2xvY2spCisJCWlmIChtcGl4ZWxjbG9jayA8PSBtcGxsX2NvbmZpZy0+bXBpeGVsY2xvY2spCiAJ CQlicmVhazsKIAogCWZvciAoOyBjdXJyX2N0cmwtPm1waXhlbGNsb2NrICE9IH4wVUw7IGN1cnJf Y3RybCsrKQotCQlpZiAoaGRtaS0+aGRtaV9kYXRhLnZpZGVvX21vZGUubXBpeGVsY2xvY2sgPD0K LQkJICAgIGN1cnJfY3RybC0+bXBpeGVsY2xvY2spCisJCWlmIChtcGl4ZWxjbG9jayA8PSBjdXJy X2N0cmwtPm1waXhlbGNsb2NrKQogCQkJYnJlYWs7CiAKIAlmb3IgKDsgcGh5X2NvbmZpZy0+bXBp eGVsY2xvY2sgIT0gfjBVTDsgcGh5X2NvbmZpZysrKQotCQlpZiAoaGRtaS0+aGRtaV9kYXRhLnZp ZGVvX21vZGUubXBpeGVsY2xvY2sgPD0KLQkJICAgIHBoeV9jb25maWctPm1waXhlbGNsb2NrKQor CQlpZiAobXBpeGVsY2xvY2sgPD0gcGh5X2NvbmZpZy0+bXBpeGVsY2xvY2spCiAJCQlicmVhazsK IAogCWlmIChtcGxsX2NvbmZpZy0+bXBpeGVsY2xvY2sgPT0gfjBVTCB8fAogCSAgICBjdXJyX2N0 cmwtPm1waXhlbGNsb2NrID09IH4wVUwgfHwKLQkgICAgcGh5X2NvbmZpZy0+bXBpeGVsY2xvY2sg PT0gfjBVTCkgewotCQlkZXZfZXJyKGhkbWktPmRldiwgIlBpeGVsIGNsb2NrICVkIC0gdW5zdXBw b3J0ZWQgYnkgSERNSVxuIiwKLQkJCWhkbWktPmhkbWlfZGF0YS52aWRlb19tb2RlLm1waXhlbGNs b2NrKTsKKwkgICAgcGh5X2NvbmZpZy0+bXBpeGVsY2xvY2sgPT0gfjBVTCkKIAkJcmV0dXJuIC1F SU5WQUw7Ci0JfQorCisJZHdfaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIG1wbGxfY29uZmlnLT5y ZXNbMF0uY3BjZSwKKwkJCSAgICAgIEhETUlfM0RfVFhfUEhZX0NQQ0VfQ1RSTCk7CisJZHdfaGRt aV9waHlfaTJjX3dyaXRlKGhkbWksIG1wbGxfY29uZmlnLT5yZXNbMF0uZ21wLAorCQkJICAgICAg SERNSV8zRF9UWF9QSFlfR01QQ1RSTCk7CisJZHdfaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIGN1 cnJfY3RybC0+Y3VyclswXSwKKwkJCSAgICAgIEhETUlfM0RfVFhfUEhZX0NVUlJDVFJMKTsKKwor CWR3X2hkbWlfcGh5X2kyY193cml0ZShoZG1pLCAwLCBIRE1JXzNEX1RYX1BIWV9QTExQSEJZQ1RS TCk7CisJZHdfaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIEhETUlfM0RfVFhfUEhZX01TTV9DVFJM X0NLT19TRUxfRkJfQ0xLLAorCQkJICAgICAgSERNSV8zRF9UWF9QSFlfTVNNX0NUUkwpOworCisJ ZHdfaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIHBoeV9jb25maWctPnRlcm0sIEhETUlfM0RfVFhf UEhZX1RYVEVSTSk7CisJZHdfaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIHBoeV9jb25maWctPnN5 bV9jdHIsCisJCQkgICAgICBIRE1JXzNEX1RYX1BIWV9DS1NZTVRYQ1RSTCk7CisJZHdfaGRtaV9w aHlfaTJjX3dyaXRlKGhkbWksIHBoeV9jb25maWctPnZsZXZfY3RyLAorCQkJICAgICAgSERNSV8z RF9UWF9QSFlfVkxFVkNUUkwpOworCisJLyogT3ZlcnJpZGUgYW5kIGRpc2FibGUgY2xvY2sgdGVy bWluYXRpb24uICovCisJZHdfaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIEhETUlfM0RfVFhfUEhZ X0NLQ0FMQ1RSTF9PVkVSUklERSwKKwkJCSAgICAgIEhETUlfM0RfVFhfUEhZX0NLQ0FMQ1RSTCk7 CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBoZG1pX3BoeV9jb25maWd1cmUoc3RydWN0 IGR3X2hkbWkgKmhkbWkpCit7CisJY29uc3Qgc3RydWN0IGR3X2hkbWlfcGh5X2RhdGEgKnBoeSA9 IGhkbWktPnBoeS5kYXRhOworCWNvbnN0IHN0cnVjdCBkd19oZG1pX3BsYXRfZGF0YSAqcGRhdGEg PSBoZG1pLT5wbGF0X2RhdGE7CisJdW5zaWduZWQgbG9uZyBtcGl4ZWxjbG9jayA9IGhkbWktPmhk bWlfZGF0YS52aWRlb19tb2RlLm1waXhlbGNsb2NrOworCWludCByZXQ7CiAKIAlkd19oZG1pX3Bo eV9wb3dlcl9vZmYoaGRtaSk7CiAKQEAgLTEwNDIsMjYgKzEwNzYsMTYgQEAgc3RhdGljIGludCBo ZG1pX3BoeV9jb25maWd1cmUoc3RydWN0IGR3X2hkbWkgKmhkbWkpCiAJCSAgICBIRE1JX1BIWV9J MkNNX1NMQVZFX0FERFIpOwogCWhkbWlfcGh5X3Rlc3RfY2xlYXIoaGRtaSwgMCk7CiAKLQloZG1p X3BoeV9pMmNfd3JpdGUoaGRtaSwgbXBsbF9jb25maWctPnJlc1swXS5jcGNlLAotCQkJICAgSERN SV8zRF9UWF9QSFlfQ1BDRV9DVFJMKTsKLQloZG1pX3BoeV9pMmNfd3JpdGUoaGRtaSwgbXBsbF9j b25maWctPnJlc1swXS5nbXAsCi0JCQkgICBIRE1JXzNEX1RYX1BIWV9HTVBDVFJMKTsKLQloZG1p X3BoeV9pMmNfd3JpdGUoaGRtaSwgY3Vycl9jdHJsLT5jdXJyWzBdLAotCQkJICAgSERNSV8zRF9U WF9QSFlfQ1VSUkNUUkwpOwotCi0JaGRtaV9waHlfaTJjX3dyaXRlKGhkbWksIDAsIEhETUlfM0Rf VFhfUEhZX1BMTFBIQllDVFJMKTsKLQloZG1pX3BoeV9pMmNfd3JpdGUoaGRtaSwgSERNSV8zRF9U WF9QSFlfTVNNX0NUUkxfQ0tPX1NFTF9GQl9DTEssCi0JCQkgICBIRE1JXzNEX1RYX1BIWV9NU01f Q1RSTCk7Ci0KLQloZG1pX3BoeV9pMmNfd3JpdGUoaGRtaSwgcGh5X2NvbmZpZy0+dGVybSwgSERN SV8zRF9UWF9QSFlfVFhURVJNKTsKLQloZG1pX3BoeV9pMmNfd3JpdGUoaGRtaSwgcGh5X2NvbmZp Zy0+c3ltX2N0ciwKLQkJCSAgIEhETUlfM0RfVFhfUEhZX0NLU1lNVFhDVFJMKTsKLQloZG1pX3Bo eV9pMmNfd3JpdGUoaGRtaSwgcGh5X2NvbmZpZy0+dmxldl9jdHIsCi0JCQkgICBIRE1JXzNEX1RY X1BIWV9WTEVWQ1RSTCk7Ci0KLQkvKiBPdmVycmlkZSBhbmQgZGlzYWJsZSBjbG9jayB0ZXJtaW5h dGlvbi4gKi8KLQloZG1pX3BoeV9pMmNfd3JpdGUoaGRtaSwgSERNSV8zRF9UWF9QSFlfQ0tDQUxD VFJMX09WRVJSSURFLAotCQkJICAgSERNSV8zRF9UWF9QSFlfQ0tDQUxDVFJMKTsKKwkvKiBXcml0 ZSB0byB0aGUgUEhZIGFzIGNvbmZpZ3VyZWQgYnkgdGhlIHBsYXRmb3JtICovCisJaWYgKHBkYXRh LT5jb25maWd1cmVfcGh5KQorCQlyZXQgPSBwZGF0YS0+Y29uZmlndXJlX3BoeShoZG1pLCBwZGF0 YSwgbXBpeGVsY2xvY2spOworCWVsc2UKKwkJcmV0ID0gcGh5LT5jb25maWd1cmUoaGRtaSwgcGRh dGEsIG1waXhlbGNsb2NrKTsKKwlpZiAocmV0KSB7CisJCWRldl9lcnIoaGRtaS0+ZGV2LCAiUEhZ IGNvbmZpZ3VyYXRpb24gZmFpbGVkIChjbG9jayAlbHUpXG4iLAorCQkJbXBpeGVsY2xvY2spOwor CQlyZXR1cm4gcmV0OworCX0KIAogCXJldHVybiBkd19oZG1pX3BoeV9wb3dlcl9vbihoZG1pKTsK IH0KQEAgLTE4OTUsMjQgKzE5MTksMzEgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBkd19oZG1pX3Bo eV9kYXRhIGR3X2hkbWlfcGh5c1tdID0gewogCQkubmFtZSA9ICJEV0MgTUhMIFBIWSArIEhFQUMg UEhZIiwKIAkJLmdlbiA9IDIsCiAJCS5oYXNfc3ZzcmV0ID0gdHJ1ZSwKKwkJLmNvbmZpZ3VyZSA9 IGhkbWlfcGh5X2NvbmZpZ3VyZV9kd2NfaGRtaV8zZF90eCwKIAl9LCB7CiAJCS50eXBlID0gRFdf SERNSV9QSFlfRFdDX01ITF9QSFksCiAJCS5uYW1lID0gIkRXQyBNSEwgUEhZIiwKIAkJLmdlbiA9 IDIsCiAJCS5oYXNfc3ZzcmV0ID0gdHJ1ZSwKKwkJLmNvbmZpZ3VyZSA9IGhkbWlfcGh5X2NvbmZp Z3VyZV9kd2NfaGRtaV8zZF90eCwKIAl9LCB7CiAJCS50eXBlID0gRFdfSERNSV9QSFlfRFdDX0hE TUlfM0RfVFhfUEhZX0hFQUMsCiAJCS5uYW1lID0gIkRXQyBIRE1JIDNEIFRYIFBIWSArIEhFQUMg UEhZIiwKIAkJLmdlbiA9IDIsCisJCS5jb25maWd1cmUgPSBoZG1pX3BoeV9jb25maWd1cmVfZHdj X2hkbWlfM2RfdHgsCiAJfSwgewogCQkudHlwZSA9IERXX0hETUlfUEhZX0RXQ19IRE1JXzNEX1RY X1BIWSwKIAkJLm5hbWUgPSAiRFdDIEhETUkgM0QgVFggUEhZIiwKIAkJLmdlbiA9IDIsCisJCS5j b25maWd1cmUgPSBoZG1pX3BoeV9jb25maWd1cmVfZHdjX2hkbWlfM2RfdHgsCiAJfSwgewogCQku dHlwZSA9IERXX0hETUlfUEhZX0RXQ19IRE1JMjBfVFhfUEhZLAogCQkubmFtZSA9ICJEV0MgSERN SSAyLjAgVFggUEhZIiwKIAkJLmdlbiA9IDIsCiAJCS5oYXNfc3ZzcmV0ID0gdHJ1ZSwKKwl9LCB7 CisJCS50eXBlID0gRFdfSERNSV9QSFlfVkVORE9SX1BIWSwKKwkJLm5hbWUgPSAiVmVuZG9yIFBI WSIsCiAJfQogfTsKIApAQCAtMTk0Myw2ICsxOTc0LDE0IEBAIHN0YXRpYyBpbnQgZHdfaGRtaV9k ZXRlY3RfcGh5KHN0cnVjdCBkd19oZG1pICpoZG1pKQogCQkJaGRtaS0+cGh5Lm9wcyA9ICZkd19o ZG1pX3N5bm9wc3lzX3BoeV9vcHM7CiAJCQloZG1pLT5waHkubmFtZSA9IGR3X2hkbWlfcGh5c1tp XS5uYW1lOwogCQkJaGRtaS0+cGh5LmRhdGEgPSAodm9pZCAqKSZkd19oZG1pX3BoeXNbaV07CisK KwkJCWlmICghZHdfaGRtaV9waHlzW2ldLmNvbmZpZ3VyZSAmJgorCQkJICAgICFoZG1pLT5wbGF0 X2RhdGEtPmNvbmZpZ3VyZV9waHkpIHsKKwkJCQlkZXZfZXJyKGhkbWktPmRldiwgIiVzIHJlcXVp cmVzIHBsYXRmb3JtIHN1cHBvcnRcbiIsCisJCQkJCWhkbWktPnBoeS5uYW1lKTsKKwkJCQlyZXR1 cm4gLUVOT0RFVjsKKwkJCX0KKwogCQkJcmV0dXJuIDA7CiAJCX0KIAl9CmRpZmYgLS1naXQgYS9p bmNsdWRlL2RybS9icmlkZ2UvZHdfaGRtaS5oIGIvaW5jbHVkZS9kcm0vYnJpZGdlL2R3X2hkbWku aAppbmRleCAwZjU4M2NhN2U2NmUuLmRkMzMwMjU5YTNkYyAxMDA2NDQKLS0tIGEvaW5jbHVkZS9k cm0vYnJpZGdlL2R3X2hkbWkuaAorKysgYi9pbmNsdWRlL2RybS9icmlkZ2UvZHdfaGRtaS5oCkBA IC03OCw2ICs3OCw5IEBAIHN0cnVjdCBkd19oZG1pX3BsYXRfZGF0YSB7CiAJY29uc3Qgc3RydWN0 IGR3X2hkbWlfbXBsbF9jb25maWcgKm1wbGxfY2ZnOwogCWNvbnN0IHN0cnVjdCBkd19oZG1pX2N1 cnJfY3RybCAqY3VyX2N0cjsKIAljb25zdCBzdHJ1Y3QgZHdfaGRtaV9waHlfY29uZmlnICpwaHlf Y29uZmlnOworCWludCAoKmNvbmZpZ3VyZV9waHkpKHN0cnVjdCBkd19oZG1pICpoZG1pLAorCQkJ ICAgICBjb25zdCBzdHJ1Y3QgZHdfaGRtaV9wbGF0X2RhdGEgKnBkYXRhLAorCQkJICAgICB1bnNp Z25lZCBsb25nIG1waXhlbGNsb2NrKTsKIH07CiAKIGludCBkd19oZG1pX3Byb2JlKHN0cnVjdCBw bGF0Zm9ybV9kZXZpY2UgKnBkZXYsCkBAIC05MSw0ICs5NCw4IEBAIHZvaWQgZHdfaGRtaV9zZXRf c2FtcGxlX3JhdGUoc3RydWN0IGR3X2hkbWkgKmhkbWksIHVuc2lnbmVkIGludCByYXRlKTsKIHZv aWQgZHdfaGRtaV9hdWRpb19lbmFibGUoc3RydWN0IGR3X2hkbWkgKmhkbWkpOwogdm9pZCBkd19o ZG1pX2F1ZGlvX2Rpc2FibGUoc3RydWN0IGR3X2hkbWkgKmhkbWkpOwogCisvKiBQSFkgY29uZmln dXJhdGlvbiAqLwordm9pZCBkd19oZG1pX3BoeV9pMmNfd3JpdGUoc3RydWN0IGR3X2hkbWkgKmhk bWksIHVuc2lnbmVkIHNob3J0IGRhdGEsCisJCQkgICB1bnNpZ25lZCBjaGFyIGFkZHIpOworCiAj ZW5kaWYgLyogX19JTVhfSERNSV9IX18gKi8KLS0gClJlZ2FyZHMsCgpMYXVyZW50IFBpbmNoYXJ0 CgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpkcmktZGV2 ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9s aXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0aW5mby9kcmktZGV2ZWwK