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=-1.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_PASS 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 8266DC28CF6 for ; Wed, 1 Aug 2018 10:01:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1D2E420844 for ; Wed, 1 Aug 2018 10:01:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=agner.ch header.i=@agner.ch header.b="ETejsza0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1D2E420844 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389148AbeHALqS (ORCPT ); Wed, 1 Aug 2018 07:46:18 -0400 Received: from mail.kmu-office.ch ([178.209.48.109]:37912 "EHLO mail.kmu-office.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388876AbeHALqR (ORCPT ); Wed, 1 Aug 2018 07:46:17 -0400 Received: from webmail.kmu-office.ch (unknown [IPv6:2a02:418:6a02::a3]) by mail.kmu-office.ch (Postfix) with ESMTPSA id 8D4F85C0548; Wed, 1 Aug 2018 12:00:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=agner.ch; s=dkim; t=1533117659; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2o9vRgBUyJ5JGVgcFGNnnnXqbhL3w3mJqvKIHU62Zmg=; b=ETejsza0RlN2gM/DaNiLTAbP1X059/BNgfWkipz2+pqxn5TVLuMKj4/PKd+CIOZQA/+xSV jTZcZ/+LSi5cH9U1Q1uNdEqidLrGv1sfOXa1WrnlyBuU2aISC1I5iR9tCPKb4xOstDC98Q SZt9oqm9uJchS8plrMAa9ZYZhIWsTfw= MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Date: Wed, 01 Aug 2018 12:00:58 +0200 From: Stefan Agner To: Leonard Crestez Cc: Marek Vasut , Shawn Guo , Lucas Stach , Fabio Estevam , Robert Chiras , Anson Huang , David Airlie , dri-devel@lists.freedesktop.org, kernel@pengutronix.de, linux-imx@nxp.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] drm/mxsfb: Fix runtime PM for unpowering lcdif block In-Reply-To: References: Message-ID: <053a788e297c5b54baa80d03586da53d@agner.ch> X-Sender: stefan@agner.ch User-Agent: Roundcube Webmail/1.3.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 17.07.2018 12:48, Leonard Crestez wrote: > Adding lcdif nodes to a power domain currently does work, it results in > black/corrupted screens or hangs. While the driver does enable runtime > pm it does not deal correctly with the block being unpowered. > > Ensure power is on when required by adding pm_runtime_get/put_sync to > mxsfb_pipe_enable/disable. > > Since power is lost on suspend implement PM_SLEEP_OPS using > drm_mode_config_helper_suspend/resume. > > The mxsfb_plane_atomic_update function can get called before > mxsfb_pipe_enable while the block is not yet powered. When this happens > the write to LCDIF_NEXT_BUF is lost causing corrupt display on unblank > until a refresh. > > Fix this by not writing gem->paddr if the block is not enabled and > instead delaying the write until the next mxsfb_crtc_mode_set_nofb call. > At that point also update cur_buf to avoid an initial corrupt frame > after resume. You seem to do two things in a single patch. I know they are related, but it still seems better if you split it up: 1. Introduce mxsfb_get_fb_paddr and set framebuffer pointers properly (this seems to have a positive effect even without PM as reported by Philipp) 2. Add PM callbacks I think in a follow up patch we can also use runtime pm to enable/disable the AXI clock. Add driver level runtime pm functions which enable disable the clocks. > > Signed-off-by: Leonard Crestez > > --- > > The purpose of this patch is to prepare for enabling power gating on > DISPLAY power domains. > > Changes since v1: > * Drop mxsfb_runtime_suspend/mxsfb_runtime_resume, calling > pm_runtime_get/put in pipe enable/disable is enough. > * Use drm_mode_config_helper_suspend/resume instead of attempting to > track state manually. > * Don't touch NEXT_BUF if atomic_update called with crtc disabled > * Also update CUR_BUF on enable, this avoids initial corrupt frames. > > Previous discussion: https://lkml.org/lkml/2018/7/17/329 > --- > drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 51 +++++++++++++++++++++++------- > drivers/gpu/drm/mxsfb/mxsfb_drv.c | 25 +++++++++++++++ > drivers/gpu/drm/mxsfb/mxsfb_drv.h | 2 ++ > 3 files changed, 67 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c > b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c > index 0abe77675b76..10153da77c40 100644 > --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c > +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c > @@ -194,15 +194,31 @@ static int mxsfb_reset_block(void __iomem *reset_addr) > return ret; > > return clear_poll_bit(reset_addr, MODULE_CLKGATE); > } > > +static dma_addr_t mxsfb_get_fb_paddr(struct mxsfb_drm_private *mxsfb) > +{ > + struct drm_framebuffer *fb = mxsfb->pipe.plane.state->fb; > + struct drm_gem_cma_object *gem; > + > + if (!fb) > + return 0; > + > + gem = drm_fb_cma_get_gem_obj(fb, 0); > + if (!gem) > + return 0; > + > + return gem->paddr; > +} > + > static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) > { > struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode; > const u32 bus_flags = mxsfb->connector.display_info.bus_flags; > u32 vdctrl0, vsync_pulse_len, hsync_pulse_len; > + dma_addr_t paddr; > int err; > > /* > * It seems, you can't re-program the controller if it is still > * running. This may lead to shifted pictures (FIFO issue?), so > @@ -268,35 +284,47 @@ static void mxsfb_crtc_mode_set_nofb(struct > mxsfb_drm_private *mxsfb) > mxsfb->base + LCDC_VDCTRL3); > > writel(SET_DOTCLK_H_VALID_DATA_CNT(m->hdisplay), > mxsfb->base + LCDC_VDCTRL4); > > + /* Update cur_buf as well to avoid an initial corrupt frame */ > + paddr = mxsfb_get_fb_paddr(mxsfb); > + if (paddr) { > + writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf); > + writel(paddr, mxsfb->base + mxsfb->devdata->next_buf); > + } > mxsfb_disable_axi_clk(mxsfb); > } > > void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb) > { > + if (mxsfb->enabled) > + return; > + > mxsfb_crtc_mode_set_nofb(mxsfb); > mxsfb_enable_controller(mxsfb); > + > + mxsfb->enabled = true; > } > > void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb) > { > + if (!mxsfb->enabled) > + return; > + > mxsfb_disable_controller(mxsfb); > + > + mxsfb->enabled = false; > } > > void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb, > struct drm_plane_state *state) > { > struct drm_simple_display_pipe *pipe = &mxsfb->pipe; > struct drm_crtc *crtc = &pipe->crtc; > - struct drm_framebuffer *fb = pipe->plane.state->fb; > struct drm_pending_vblank_event *event; > - struct drm_gem_cma_object *gem; > - > - if (!crtc) > - return; > + dma_addr_t paddr; > > spin_lock_irq(&crtc->dev->event_lock); > event = crtc->state->event; > if (event) { > crtc->state->event = NULL; > @@ -307,14 +335,15 @@ void mxsfb_plane_atomic_update(struct > mxsfb_drm_private *mxsfb, > drm_crtc_send_vblank_event(crtc, event); > } > } > spin_unlock_irq(&crtc->dev->event_lock); > > - if (!fb) > + if (!mxsfb->enabled) > return; > I think this is the wrong thing to do. The simple KMS helper callback ->update() is called by the ->atomic_update() callback of drm_plane_helper_funcs. And the documentation of atomic_update() states: https://01.org/linuxgraphics/gfx-docs/drm/gpu/drm-kms-helpers.html#c.drm_plane_helper_funcs "Note that the power state of the display pipe when this function is called depends upon the exact helpers and calling sequence the driver has picked. See drm_atomic_helper_commit_planes() for a discussion of the tradeoffs and variants of plane commit helpers." The documentation of drm_atomic_helper_commit_planes() then has more information: https://01.org/linuxgraphics/gfx-docs/drm/gpu/drm-kms-helpers.html#c.drm_atomic_helper_commit_planes Bottom line, we should be using drm_atomic_helper_commit_tail_rpm() for runtime pm... So adding something like: static const struct drm_mode_config_helper_funcs mxsfb_drm_mode_config_helpers = { .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, }; And add something like this in mxsfb_load: drm->mode_config.funcs = &mxsfb_mode_config_funcs; + dev->mode_config.helper_private = &mxsfb_drm_mode_config_helpers; ... Should make the stack not calling update while the pipe is disabled. With that you do not have to keep state locally and can always apply the new state in ->enable(). > - gem = drm_fb_cma_get_gem_obj(fb, 0); > - > - mxsfb_enable_axi_clk(mxsfb); > - writel(gem->paddr, mxsfb->base + mxsfb->devdata->next_buf); > - mxsfb_disable_axi_clk(mxsfb); > + paddr = mxsfb_get_fb_paddr(mxsfb); > + if (paddr) { > + mxsfb_enable_axi_clk(mxsfb); > + writel(paddr, mxsfb->base + mxsfb->devdata->next_buf); > + mxsfb_disable_axi_clk(mxsfb); > + } > } > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c > b/drivers/gpu/drm/mxsfb/mxsfb_drv.c > index dd1dd58e4956..a5269fccbed9 100644 > --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c > +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c > @@ -101,23 +101,27 @@ static const struct drm_mode_config_funcs > mxsfb_mode_config_funcs = { > static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe, > struct drm_crtc_state *crtc_state, > struct drm_plane_state *plane_state) > { > struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe); > + struct drm_device *drm = pipe->plane.dev; > > + pm_runtime_get_sync(drm->dev); > drm_panel_prepare(mxsfb->panel); > mxsfb_crtc_enable(mxsfb); > drm_panel_enable(mxsfb->panel); > } > > static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe) > { > struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe); > + struct drm_device *drm = pipe->plane.dev; > > drm_panel_disable(mxsfb->panel); > mxsfb_crtc_disable(mxsfb); > drm_panel_unprepare(mxsfb->panel); > + pm_runtime_put_sync(drm->dev); > } > > static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe, > struct drm_plane_state *plane_state) > { > @@ -412,17 +416,38 @@ static int mxsfb_remove(struct platform_device *pdev) > drm_dev_unref(drm); > > return 0; > } > > +#ifdef CONFIG_PM This should be CONFIG_PM_SLEEP afaict. -- Stefan > +static int mxsfb_suspend(struct device *dev) > +{ > + struct drm_device *drm = dev_get_drvdata(dev); > + > + return drm_mode_config_helper_suspend(drm); > +} > + > +static int mxsfb_resume(struct device *dev) > +{ > + struct drm_device *drm = dev_get_drvdata(dev); > + > + return drm_mode_config_helper_resume(drm); > +} > +#endif > + > +static const struct dev_pm_ops mxsfb_pm_ops = { > + SET_SYSTEM_SLEEP_PM_OPS(mxsfb_suspend, mxsfb_resume) > +}; > + > static struct platform_driver mxsfb_platform_driver = { > .probe = mxsfb_probe, > .remove = mxsfb_remove, > .id_table = mxsfb_devtype, > .driver = { > .name = "mxsfb-drm", > .of_match_table = mxsfb_dt_ids, > + .pm = &mxsfb_pm_ops, > }, > }; > > module_platform_driver(mxsfb_platform_driver); > > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h > b/drivers/gpu/drm/mxsfb/mxsfb_drv.h > index 5d0883fc805b..e539d4b05c48 100644 > --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h > +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h > @@ -36,10 +36,12 @@ struct mxsfb_drm_private { > > struct drm_simple_display_pipe pipe; > struct drm_connector connector; > struct drm_panel *panel; > struct drm_fbdev_cma *fbdev; > + > + bool enabled; > }; > > int mxsfb_setup_crtc(struct drm_device *dev); > int mxsfb_create_output(struct drm_device *dev); From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stefan Agner Subject: Re: [PATCH v2] drm/mxsfb: Fix runtime PM for unpowering lcdif block Date: Wed, 01 Aug 2018 12:00:58 +0200 Message-ID: <053a788e297c5b54baa80d03586da53d@agner.ch> References: Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail.kmu-office.ch (mail.kmu-office.ch [IPv6:2a02:418:6a02::a2]) by gabe.freedesktop.org (Postfix) with ESMTPS id 44F2F89C98 for ; Wed, 1 Aug 2018 10:01:03 +0000 (UTC) In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Leonard Crestez Cc: Marek Vasut , Anson Huang , David Airlie , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Robert Chiras , linux-imx@nxp.com, kernel@pengutronix.de, Fabio Estevam , Shawn Guo List-Id: dri-devel@lists.freedesktop.org T24gMTcuMDcuMjAxOCAxMjo0OCwgTGVvbmFyZCBDcmVzdGV6IHdyb3RlOgo+IEFkZGluZyBsY2Rp ZiBub2RlcyB0byBhIHBvd2VyIGRvbWFpbiBjdXJyZW50bHkgZG9lcyB3b3JrLCBpdCByZXN1bHRz IGluCj4gYmxhY2svY29ycnVwdGVkIHNjcmVlbnMgb3IgaGFuZ3MuIFdoaWxlIHRoZSBkcml2ZXIg ZG9lcyBlbmFibGUgcnVudGltZQo+IHBtIGl0IGRvZXMgbm90IGRlYWwgY29ycmVjdGx5IHdpdGgg dGhlIGJsb2NrIGJlaW5nIHVucG93ZXJlZC4KPiAKPiBFbnN1cmUgcG93ZXIgaXMgb24gd2hlbiBy ZXF1aXJlZCBieSBhZGRpbmcgcG1fcnVudGltZV9nZXQvcHV0X3N5bmMgdG8KPiBteHNmYl9waXBl X2VuYWJsZS9kaXNhYmxlLgo+IAo+IFNpbmNlIHBvd2VyIGlzIGxvc3Qgb24gc3VzcGVuZCBpbXBs ZW1lbnQgUE1fU0xFRVBfT1BTIHVzaW5nCj4gZHJtX21vZGVfY29uZmlnX2hlbHBlcl9zdXNwZW5k L3Jlc3VtZS4KPiAKPiBUaGUgbXhzZmJfcGxhbmVfYXRvbWljX3VwZGF0ZSBmdW5jdGlvbiBjYW4g Z2V0IGNhbGxlZCBiZWZvcmUKPiBteHNmYl9waXBlX2VuYWJsZSB3aGlsZSB0aGUgYmxvY2sgaXMg bm90IHlldCBwb3dlcmVkLiBXaGVuIHRoaXMgaGFwcGVucwo+IHRoZSB3cml0ZSB0byBMQ0RJRl9O RVhUX0JVRiBpcyBsb3N0IGNhdXNpbmcgY29ycnVwdCBkaXNwbGF5IG9uIHVuYmxhbmsKPiB1bnRp bCBhIHJlZnJlc2guCj4gCj4gRml4IHRoaXMgYnkgbm90IHdyaXRpbmcgZ2VtLT5wYWRkciBpZiB0 aGUgYmxvY2sgaXMgbm90IGVuYWJsZWQgYW5kCj4gaW5zdGVhZCBkZWxheWluZyB0aGUgd3JpdGUg dW50aWwgdGhlIG5leHQgbXhzZmJfY3J0Y19tb2RlX3NldF9ub2ZiIGNhbGwuCj4gQXQgdGhhdCBw b2ludCBhbHNvIHVwZGF0ZSBjdXJfYnVmIHRvIGF2b2lkIGFuIGluaXRpYWwgY29ycnVwdCBmcmFt ZQo+IGFmdGVyIHJlc3VtZS4KCllvdSBzZWVtIHRvIGRvIHR3byB0aGluZ3MgaW4gYSBzaW5nbGUg cGF0Y2guIEkga25vdyB0aGV5IGFyZSByZWxhdGVkLApidXQgaXQgc3RpbGwgc2VlbXMgYmV0dGVy IGlmIHlvdSBzcGxpdCBpdCB1cDoKCjEuIEludHJvZHVjZSBteHNmYl9nZXRfZmJfcGFkZHIgYW5k IHNldCBmcmFtZWJ1ZmZlciBwb2ludGVycyBwcm9wZXJseQoodGhpcyBzZWVtcyB0byBoYXZlIGEg cG9zaXRpdmUgZWZmZWN0IGV2ZW4gd2l0aG91dCBQTSBhcyByZXBvcnRlZCBieQpQaGlsaXBwKQoy LiBBZGQgUE0gY2FsbGJhY2tzCgpJIHRoaW5rIGluIGEgZm9sbG93IHVwIHBhdGNoIHdlIGNhbiBh bHNvIHVzZSBydW50aW1lIHBtIHRvCmVuYWJsZS9kaXNhYmxlIHRoZSBBWEkgY2xvY2suIEFkZCBk cml2ZXIgbGV2ZWwgcnVudGltZSBwbSBmdW5jdGlvbnMKd2hpY2ggZW5hYmxlIGRpc2FibGUgdGhl IGNsb2Nrcy4KCj4gCj4gU2lnbmVkLW9mZi1ieTogTGVvbmFyZCBDcmVzdGV6IDxsZW9uYXJkLmNy ZXN0ZXpAbnhwLmNvbT4KPiAKPiAtLS0KPiAKPiBUaGUgcHVycG9zZSBvZiB0aGlzIHBhdGNoIGlz IHRvIHByZXBhcmUgZm9yIGVuYWJsaW5nIHBvd2VyIGdhdGluZyBvbgo+IERJU1BMQVkgcG93ZXIg ZG9tYWlucy4KPiAKPiBDaGFuZ2VzIHNpbmNlIHYxOgo+ICogRHJvcCBteHNmYl9ydW50aW1lX3N1 c3BlbmQvbXhzZmJfcnVudGltZV9yZXN1bWUsIGNhbGxpbmcKPiBwbV9ydW50aW1lX2dldC9wdXQg aW4gcGlwZSBlbmFibGUvZGlzYWJsZSBpcyBlbm91Z2guCj4gKiBVc2UgZHJtX21vZGVfY29uZmln X2hlbHBlcl9zdXNwZW5kL3Jlc3VtZSBpbnN0ZWFkIG9mIGF0dGVtcHRpbmcgdG8KPiB0cmFjayBz dGF0ZSBtYW51YWxseS4KPiAqIERvbid0IHRvdWNoIE5FWFRfQlVGIGlmIGF0b21pY191cGRhdGUg Y2FsbGVkIHdpdGggY3J0YyBkaXNhYmxlZAo+ICogQWxzbyB1cGRhdGUgQ1VSX0JVRiBvbiBlbmFi bGUsIHRoaXMgYXZvaWRzIGluaXRpYWwgY29ycnVwdCBmcmFtZXMuCj4gCj4gUHJldmlvdXMgZGlz Y3Vzc2lvbjogaHR0cHM6Ly9sa21sLm9yZy9sa21sLzIwMTgvNy8xNy8zMjkKPiAtLS0KPiAgZHJp dmVycy9ncHUvZHJtL214c2ZiL214c2ZiX2NydGMuYyB8IDUxICsrKysrKysrKysrKysrKysrKysr KysrLS0tLS0tLQo+ICBkcml2ZXJzL2dwdS9kcm0vbXhzZmIvbXhzZmJfZHJ2LmMgIHwgMjUgKysr KysrKysrKysrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS9teHNmYi9teHNmYl9kcnYuaCAgfCAgMiAr Kwo+ICAzIGZpbGVzIGNoYW5nZWQsIDY3IGluc2VydGlvbnMoKyksIDExIGRlbGV0aW9ucygtKQo+ IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vbXhzZmIvbXhzZmJfY3J0Yy5jCj4gYi9k cml2ZXJzL2dwdS9kcm0vbXhzZmIvbXhzZmJfY3J0Yy5jCj4gaW5kZXggMGFiZTc3Njc1Yjc2Li4x MDE1M2RhNzdjNDAgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL214c2ZiL214c2ZiX2Ny dGMuYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9teHNmYi9teHNmYl9jcnRjLmMKPiBAQCAtMTk0 LDE1ICsxOTQsMzEgQEAgc3RhdGljIGludCBteHNmYl9yZXNldF9ibG9jayh2b2lkIF9faW9tZW0g KnJlc2V0X2FkZHIpCj4gIAkJcmV0dXJuIHJldDsKPiAgCj4gIAlyZXR1cm4gY2xlYXJfcG9sbF9i aXQocmVzZXRfYWRkciwgTU9EVUxFX0NMS0dBVEUpOwo+ICB9Cj4gIAo+ICtzdGF0aWMgZG1hX2Fk ZHJfdCBteHNmYl9nZXRfZmJfcGFkZHIoc3RydWN0IG14c2ZiX2RybV9wcml2YXRlICpteHNmYikK PiArewo+ICsJc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIgPSBteHNmYi0+cGlwZS5wbGFuZS5z dGF0ZS0+ZmI7Cj4gKwlzdHJ1Y3QgZHJtX2dlbV9jbWFfb2JqZWN0ICpnZW07Cj4gKwo+ICsJaWYg KCFmYikKPiArCQlyZXR1cm4gMDsKPiArCj4gKwlnZW0gPSBkcm1fZmJfY21hX2dldF9nZW1fb2Jq KGZiLCAwKTsKPiArCWlmICghZ2VtKQo+ICsJCXJldHVybiAwOwo+ICsKPiArCXJldHVybiBnZW0t PnBhZGRyOwo+ICt9Cj4gKwo+ICBzdGF0aWMgdm9pZCBteHNmYl9jcnRjX21vZGVfc2V0X25vZmIo c3RydWN0IG14c2ZiX2RybV9wcml2YXRlICpteHNmYikKPiAgewo+ICAJc3RydWN0IGRybV9kaXNw bGF5X21vZGUgKm0gPSAmbXhzZmItPnBpcGUuY3J0Yy5zdGF0ZS0+YWRqdXN0ZWRfbW9kZTsKPiAg CWNvbnN0IHUzMiBidXNfZmxhZ3MgPSBteHNmYi0+Y29ubmVjdG9yLmRpc3BsYXlfaW5mby5idXNf ZmxhZ3M7Cj4gIAl1MzIgdmRjdHJsMCwgdnN5bmNfcHVsc2VfbGVuLCBoc3luY19wdWxzZV9sZW47 Cj4gKwlkbWFfYWRkcl90IHBhZGRyOwo+ICAJaW50IGVycjsKPiAgCj4gIAkvKgo+ICAJICogSXQg c2VlbXMsIHlvdSBjYW4ndCByZS1wcm9ncmFtIHRoZSBjb250cm9sbGVyIGlmIGl0IGlzIHN0aWxs Cj4gIAkgKiBydW5uaW5nLiBUaGlzIG1heSBsZWFkIHRvIHNoaWZ0ZWQgcGljdHVyZXMgKEZJRk8g aXNzdWU/KSwgc28KPiBAQCAtMjY4LDM1ICsyODQsNDcgQEAgc3RhdGljIHZvaWQgbXhzZmJfY3J0 Y19tb2RlX3NldF9ub2ZiKHN0cnVjdAo+IG14c2ZiX2RybV9wcml2YXRlICpteHNmYikKPiAgCSAg ICAgICBteHNmYi0+YmFzZSArIExDRENfVkRDVFJMMyk7Cj4gIAo+ICAJd3JpdGVsKFNFVF9ET1RD TEtfSF9WQUxJRF9EQVRBX0NOVChtLT5oZGlzcGxheSksCj4gIAkgICAgICAgbXhzZmItPmJhc2Ug KyBMQ0RDX1ZEQ1RSTDQpOwo+ICAKPiArCS8qIFVwZGF0ZSBjdXJfYnVmIGFzIHdlbGwgdG8gYXZv aWQgYW4gaW5pdGlhbCBjb3JydXB0IGZyYW1lICovCj4gKwlwYWRkciA9IG14c2ZiX2dldF9mYl9w YWRkcihteHNmYik7Cj4gKwlpZiAocGFkZHIpIHsKPiArCQl3cml0ZWwocGFkZHIsIG14c2ZiLT5i YXNlICsgbXhzZmItPmRldmRhdGEtPmN1cl9idWYpOwo+ICsJCXdyaXRlbChwYWRkciwgbXhzZmIt PmJhc2UgKyBteHNmYi0+ZGV2ZGF0YS0+bmV4dF9idWYpOwo+ICsJfQo+ICAJbXhzZmJfZGlzYWJs ZV9heGlfY2xrKG14c2ZiKTsKPiAgfQo+ICAKPiAgdm9pZCBteHNmYl9jcnRjX2VuYWJsZShzdHJ1 Y3QgbXhzZmJfZHJtX3ByaXZhdGUgKm14c2ZiKQo+ICB7Cj4gKwlpZiAobXhzZmItPmVuYWJsZWQp Cj4gKwkJcmV0dXJuOwo+ICsKPiAgCW14c2ZiX2NydGNfbW9kZV9zZXRfbm9mYihteHNmYik7Cj4g IAlteHNmYl9lbmFibGVfY29udHJvbGxlcihteHNmYik7Cj4gKwo+ICsJbXhzZmItPmVuYWJsZWQg PSB0cnVlOwo+ICB9Cj4gIAo+ICB2b2lkIG14c2ZiX2NydGNfZGlzYWJsZShzdHJ1Y3QgbXhzZmJf ZHJtX3ByaXZhdGUgKm14c2ZiKQo+ICB7Cj4gKwlpZiAoIW14c2ZiLT5lbmFibGVkKQo+ICsJCXJl dHVybjsKPiArCj4gIAlteHNmYl9kaXNhYmxlX2NvbnRyb2xsZXIobXhzZmIpOwo+ICsKPiArCW14 c2ZiLT5lbmFibGVkID0gZmFsc2U7Cj4gIH0KPiAgCj4gIHZvaWQgbXhzZmJfcGxhbmVfYXRvbWlj X3VwZGF0ZShzdHJ1Y3QgbXhzZmJfZHJtX3ByaXZhdGUgKm14c2ZiLAo+ICAJCQkgICAgICAgc3Ry dWN0IGRybV9wbGFuZV9zdGF0ZSAqc3RhdGUpCj4gIHsKPiAgCXN0cnVjdCBkcm1fc2ltcGxlX2Rp c3BsYXlfcGlwZSAqcGlwZSA9ICZteHNmYi0+cGlwZTsKPiAgCXN0cnVjdCBkcm1fY3J0YyAqY3J0 YyA9ICZwaXBlLT5jcnRjOwo+IC0Jc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIgPSBwaXBlLT5w bGFuZS5zdGF0ZS0+ZmI7Cj4gIAlzdHJ1Y3QgZHJtX3BlbmRpbmdfdmJsYW5rX2V2ZW50ICpldmVu dDsKPiAtCXN0cnVjdCBkcm1fZ2VtX2NtYV9vYmplY3QgKmdlbTsKPiAtCj4gLQlpZiAoIWNydGMp Cj4gLQkJcmV0dXJuOwo+ICsJZG1hX2FkZHJfdCBwYWRkcjsKPiAgCj4gIAlzcGluX2xvY2tfaXJx KCZjcnRjLT5kZXYtPmV2ZW50X2xvY2spOwo+ICAJZXZlbnQgPSBjcnRjLT5zdGF0ZS0+ZXZlbnQ7 Cj4gIAlpZiAoZXZlbnQpIHsKPiAgCQljcnRjLT5zdGF0ZS0+ZXZlbnQgPSBOVUxMOwo+IEBAIC0z MDcsMTQgKzMzNSwxNSBAQCB2b2lkIG14c2ZiX3BsYW5lX2F0b21pY191cGRhdGUoc3RydWN0Cj4g bXhzZmJfZHJtX3ByaXZhdGUgKm14c2ZiLAo+ICAJCQlkcm1fY3J0Y19zZW5kX3ZibGFua19ldmVu dChjcnRjLCBldmVudCk7Cj4gIAkJfQo+ICAJfQo+ICAJc3Bpbl91bmxvY2tfaXJxKCZjcnRjLT5k ZXYtPmV2ZW50X2xvY2spOwo+ICAKPiAtCWlmICghZmIpCj4gKwlpZiAoIW14c2ZiLT5lbmFibGVk KQo+ICAJCXJldHVybjsKPiAgCgpJIHRoaW5rIHRoaXMgaXMgdGhlIHdyb25nIHRoaW5nIHRvIGRv LgoKVGhlIHNpbXBsZSBLTVMgaGVscGVyIGNhbGxiYWNrIC0+dXBkYXRlKCkgaXMgY2FsbGVkIGJ5 IHRoZQotPmF0b21pY191cGRhdGUoKSBjYWxsYmFjayBvZiBkcm1fcGxhbmVfaGVscGVyX2Z1bmNz LgoKQW5kIHRoZSBkb2N1bWVudGF0aW9uIG9mIGF0b21pY191cGRhdGUoKSBzdGF0ZXM6Cmh0dHBz Oi8vMDEub3JnL2xpbnV4Z3JhcGhpY3MvZ2Z4LWRvY3MvZHJtL2dwdS9kcm0ta21zLWhlbHBlcnMu aHRtbCNjLmRybV9wbGFuZV9oZWxwZXJfZnVuY3MKCiJOb3RlIHRoYXQgdGhlIHBvd2VyIHN0YXRl IG9mIHRoZSBkaXNwbGF5IHBpcGUgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzCmNhbGxlZCBkZXBlbmRz IHVwb24gdGhlIGV4YWN0IGhlbHBlcnMgYW5kIGNhbGxpbmcgc2VxdWVuY2UgdGhlIGRyaXZlcgpo YXMgcGlja2VkLiBTZWUgZHJtX2F0b21pY19oZWxwZXJfY29tbWl0X3BsYW5lcygpIGZvciBhIGRp c2N1c3Npb24gb2YKdGhlIHRyYWRlb2ZmcyBhbmQgdmFyaWFudHMgb2YgcGxhbmUgY29tbWl0IGhl bHBlcnMuIgoKVGhlIGRvY3VtZW50YXRpb24gb2YgZHJtX2F0b21pY19oZWxwZXJfY29tbWl0X3Bs YW5lcygpIHRoZW4gaGFzIG1vcmUKaW5mb3JtYXRpb246Cmh0dHBzOi8vMDEub3JnL2xpbnV4Z3Jh cGhpY3MvZ2Z4LWRvY3MvZHJtL2dwdS9kcm0ta21zLWhlbHBlcnMuaHRtbCNjLmRybV9hdG9taWNf aGVscGVyX2NvbW1pdF9wbGFuZXMKCkJvdHRvbSBsaW5lLCB3ZSBzaG91bGQgYmUgdXNpbmcgZHJt X2F0b21pY19oZWxwZXJfY29tbWl0X3RhaWxfcnBtKCkgZm9yCnJ1bnRpbWUgcG0uLi4KClNvIGFk ZGluZyBzb21ldGhpbmcgbGlrZToKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX21vZGVfY29uZmln X2hlbHBlcl9mdW5jcwpteHNmYl9kcm1fbW9kZV9jb25maWdfaGVscGVycyA9IHsKCS5hdG9taWNf Y29tbWl0X3RhaWwgPSBkcm1fYXRvbWljX2hlbHBlcl9jb21taXRfdGFpbF9ycG0sCn07CgpBbmQg YWRkIHNvbWV0aGluZyBsaWtlIHRoaXMgaW4gbXhzZmJfbG9hZDoKCglkcm0tPm1vZGVfY29uZmln LmZ1bmNzCQk9ICZteHNmYl9tb2RlX2NvbmZpZ19mdW5jczsKKwlkZXYtPm1vZGVfY29uZmlnLmhl bHBlcl9wcml2YXRlID0gJm14c2ZiX2RybV9tb2RlX2NvbmZpZ19oZWxwZXJzOwouLi4KClNob3Vs ZCBtYWtlIHRoZSBzdGFjayBub3QgY2FsbGluZyB1cGRhdGUgd2hpbGUgdGhlIHBpcGUgaXMgZGlz YWJsZWQuCgpXaXRoIHRoYXQgeW91IGRvIG5vdCBoYXZlIHRvIGtlZXAgc3RhdGUgbG9jYWxseSBh bmQgY2FuIGFsd2F5cyBhcHBseSB0aGUKbmV3IHN0YXRlIGluIC0+ZW5hYmxlKCkuCgo+IC0JZ2Vt ID0gZHJtX2ZiX2NtYV9nZXRfZ2VtX29iaihmYiwgMCk7Cj4gLQo+IC0JbXhzZmJfZW5hYmxlX2F4 aV9jbGsobXhzZmIpOwo+IC0Jd3JpdGVsKGdlbS0+cGFkZHIsIG14c2ZiLT5iYXNlICsgbXhzZmIt PmRldmRhdGEtPm5leHRfYnVmKTsKPiAtCW14c2ZiX2Rpc2FibGVfYXhpX2NsayhteHNmYik7Cj4g KwlwYWRkciA9IG14c2ZiX2dldF9mYl9wYWRkcihteHNmYik7Cj4gKwlpZiAocGFkZHIpIHsKPiAr CQlteHNmYl9lbmFibGVfYXhpX2NsayhteHNmYik7Cj4gKwkJd3JpdGVsKHBhZGRyLCBteHNmYi0+ YmFzZSArIG14c2ZiLT5kZXZkYXRhLT5uZXh0X2J1Zik7Cj4gKwkJbXhzZmJfZGlzYWJsZV9heGlf Y2xrKG14c2ZiKTsKPiArCX0KPiAgfQo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vbXhz ZmIvbXhzZmJfZHJ2LmMKPiBiL2RyaXZlcnMvZ3B1L2RybS9teHNmYi9teHNmYl9kcnYuYwo+IGlu ZGV4IGRkMWRkNThlNDk1Ni4uYTUyNjlmY2NiZWQ5IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1 L2RybS9teHNmYi9teHNmYl9kcnYuYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9teHNmYi9teHNm Yl9kcnYuYwo+IEBAIC0xMDEsMjMgKzEwMSwyNyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9t b2RlX2NvbmZpZ19mdW5jcwo+IG14c2ZiX21vZGVfY29uZmlnX2Z1bmNzID0gewo+ICBzdGF0aWMg dm9pZCBteHNmYl9waXBlX2VuYWJsZShzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBp cGUsCj4gIAkJCSAgICAgIHN0cnVjdCBkcm1fY3J0Y19zdGF0ZSAqY3J0Y19zdGF0ZSwKPiAgCQkJ ICAgICAgc3RydWN0IGRybV9wbGFuZV9zdGF0ZSAqcGxhbmVfc3RhdGUpCj4gIHsKPiAgCXN0cnVj dCBteHNmYl9kcm1fcHJpdmF0ZSAqbXhzZmIgPSBkcm1fcGlwZV90b19teHNmYl9kcm1fcHJpdmF0 ZShwaXBlKTsKPiArCXN0cnVjdCBkcm1fZGV2aWNlICpkcm0gPSBwaXBlLT5wbGFuZS5kZXY7Cj4g IAo+ICsJcG1fcnVudGltZV9nZXRfc3luYyhkcm0tPmRldik7Cj4gIAlkcm1fcGFuZWxfcHJlcGFy ZShteHNmYi0+cGFuZWwpOwo+ICAJbXhzZmJfY3J0Y19lbmFibGUobXhzZmIpOwo+ICAJZHJtX3Bh bmVsX2VuYWJsZShteHNmYi0+cGFuZWwpOwo+ICB9Cj4gIAo+ICBzdGF0aWMgdm9pZCBteHNmYl9w aXBlX2Rpc2FibGUoc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9waXBlICpwaXBlKQo+ICB7Cj4g IAlzdHJ1Y3QgbXhzZmJfZHJtX3ByaXZhdGUgKm14c2ZiID0gZHJtX3BpcGVfdG9fbXhzZmJfZHJt X3ByaXZhdGUocGlwZSk7Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZHJtID0gcGlwZS0+cGxhbmUu ZGV2Owo+ICAKPiAgCWRybV9wYW5lbF9kaXNhYmxlKG14c2ZiLT5wYW5lbCk7Cj4gIAlteHNmYl9j cnRjX2Rpc2FibGUobXhzZmIpOwo+ICAJZHJtX3BhbmVsX3VucHJlcGFyZShteHNmYi0+cGFuZWwp Owo+ICsJcG1fcnVudGltZV9wdXRfc3luYyhkcm0tPmRldik7Cj4gIH0KPiAgCj4gIHN0YXRpYyB2 b2lkIG14c2ZiX3BpcGVfdXBkYXRlKHN0cnVjdCBkcm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlw ZSwKPiAgCQkJICAgICAgc3RydWN0IGRybV9wbGFuZV9zdGF0ZSAqcGxhbmVfc3RhdGUpCj4gIHsK PiBAQCAtNDEyLDE3ICs0MTYsMzggQEAgc3RhdGljIGludCBteHNmYl9yZW1vdmUoc3RydWN0IHBs YXRmb3JtX2RldmljZSAqcGRldikKPiAgCWRybV9kZXZfdW5yZWYoZHJtKTsKPiAgCj4gIAlyZXR1 cm4gMDsKPiAgfQo+ICAKPiArI2lmZGVmIENPTkZJR19QTQoKVGhpcyBzaG91bGQgYmUgQ09ORklH X1BNX1NMRUVQIGFmYWljdC4KCi0tClN0ZWZhbgoKPiArc3RhdGljIGludCBteHNmYl9zdXNwZW5k KHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsgICAgICAgc3RydWN0IGRybV9kZXZpY2UgKmRy bSA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwo+ICsKPiArICAgICAgIHJldHVybiBkcm1fbW9kZV9j b25maWdfaGVscGVyX3N1c3BlbmQoZHJtKTsKPiArfQo+ICsKPiArc3RhdGljIGludCBteHNmYl9y ZXN1bWUoc3RydWN0IGRldmljZSAqZGV2KQo+ICt7Cj4gKyAgICAgICBzdHJ1Y3QgZHJtX2Rldmlj ZSAqZHJtID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwo+ICsgICAgICAgcmV0dXJuIGRybV9t b2RlX2NvbmZpZ19oZWxwZXJfcmVzdW1lKGRybSk7Cj4gK30KPiArI2VuZGlmCj4gKwo+ICtzdGF0 aWMgY29uc3Qgc3RydWN0IGRldl9wbV9vcHMgbXhzZmJfcG1fb3BzID0gewo+ICsgICAgICAgU0VU X1NZU1RFTV9TTEVFUF9QTV9PUFMobXhzZmJfc3VzcGVuZCwgbXhzZmJfcmVzdW1lKQo+ICt9Owo+ ICsKPiAgc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbXhzZmJfcGxhdGZvcm1fZHJpdmVy ID0gewo+ICAJLnByb2JlCQk9IG14c2ZiX3Byb2JlLAo+ICAJLnJlbW92ZQkJPSBteHNmYl9yZW1v dmUsCj4gIAkuaWRfdGFibGUJPSBteHNmYl9kZXZ0eXBlLAo+ICAJLmRyaXZlcgk9IHsKPiAgCQku bmFtZQkJPSAibXhzZmItZHJtIiwKPiAgCQkub2ZfbWF0Y2hfdGFibGUJPSBteHNmYl9kdF9pZHMs Cj4gKwkJLnBtCQk9ICZteHNmYl9wbV9vcHMsCj4gIAl9LAo+ICB9Owo+ICAKPiAgbW9kdWxlX3Bs YXRmb3JtX2RyaXZlcihteHNmYl9wbGF0Zm9ybV9kcml2ZXIpOwo+ICAKPiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy9ncHUvZHJtL214c2ZiL214c2ZiX2Rydi5oCj4gYi9kcml2ZXJzL2dwdS9kcm0vbXhz ZmIvbXhzZmJfZHJ2LmgKPiBpbmRleCA1ZDA4ODNmYzgwNWIuLmU1MzlkNGIwNWM0OCAxMDA2NDQK PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vbXhzZmIvbXhzZmJfZHJ2LmgKPiArKysgYi9kcml2ZXJz L2dwdS9kcm0vbXhzZmIvbXhzZmJfZHJ2LmgKPiBAQCAtMzYsMTAgKzM2LDEyIEBAIHN0cnVjdCBt eHNmYl9kcm1fcHJpdmF0ZSB7Cj4gIAo+ICAJc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9waXBl CXBpcGU7Cj4gIAlzdHJ1Y3QgZHJtX2Nvbm5lY3RvcgkJY29ubmVjdG9yOwo+ICAJc3RydWN0IGRy bV9wYW5lbAkJKnBhbmVsOwo+ICAJc3RydWN0IGRybV9mYmRldl9jbWEJCSpmYmRldjsKPiArCj4g Kwlib29sIGVuYWJsZWQ7Cj4gIH07Cj4gIAo+ICBpbnQgbXhzZmJfc2V0dXBfY3J0YyhzdHJ1Y3Qg ZHJtX2RldmljZSAqZGV2KTsKPiAgaW50IG14c2ZiX2NyZWF0ZV9vdXRwdXQoc3RydWN0IGRybV9k ZXZpY2UgKmRldik7Cl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9y ZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZl bAo=