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 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA22BC433F5 for ; Fri, 28 Jan 2022 10:59:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B94F410F00A; Fri, 28 Jan 2022 10:59:13 +0000 (UTC) Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de [IPv6:2001:67c:670:201:290:27ff:fe1d:cc33]) by gabe.freedesktop.org (Postfix) with ESMTPS id 953FC10F00A for ; Fri, 28 Jan 2022 10:59:12 +0000 (UTC) Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nDOyC-0006q5-Lu; Fri, 28 Jan 2022 11:59:08 +0100 Received: from [2a0a:edc0:0:900:1d::77] (helo=ptz.office.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1nDOyA-00CxGs-6h; Fri, 28 Jan 2022 11:59:05 +0100 Received: from ukl by ptz.office.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1nDOy8-001vPv-NL; Fri, 28 Jan 2022 11:59:04 +0100 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= To: Philipp Zabel Subject: [PATCH 2/2] drm/imx/lcdc: Implement DRM driver for imx21 Date: Fri, 28 Jan 2022 11:58:49 +0100 Message-Id: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de> References: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Developer-Signature: v=1; a=openpgp-sha256; l=22490; i=u.kleine-koenig@pengutronix.de; h=from:subject; bh=68F8YE1H89sNovamSKJdUhBglBIYByhtEyQgstqIeRA=; b=owEBbQGS/pANAwAKAcH8FHityuwJAcsmYgBh88xifvszg2evwXEL6/GTOvchWOsYOqeIY/rykwx3 IH8LOaeJATMEAAEKAB0WIQR+cioWkBis/z50pAvB/BR4rcrsCQUCYfPMYgAKCRDB/BR4rcrsCQPZB/ 4jIeF/BsDDn61GQ79R37zjw6mi8AwMmdAi3lBzJwdRjUBQMe5bX0UVDI6GuYOUMv75ckV50O7zSd9o 1NEtNJl3Tx4qFYCd2MvboOj4trbdHXJ1kjJdO3oyr5pSv48INnEz+6+oDPkc8PGZoEw63PjUaXiJsM ABCaNlJhhN3EXqKy2Rh7q2ds195Dv4BFVsjR0MosnpB5wv+tAN3tqaqz4ZxnTj5d3LcWwCKMnpa2S6 7z8izeIkCVE6ysmnzqNR/gm7ruTOG/drZa7TGG/JqHDMqTqlP5l4qgsZ8Dyiva90sAtbgaRkXRLKYJ XIp5iPtNW6eW8NBcQ1OeQcMnmBZtVR X-Developer-Key: i=u.kleine-koenig@pengutronix.de; a=openpgp; fpr=0D2511F322BFAB1C1580266BE2DCDD9132669BD6 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Airlie , Shawn Guo , dri-devel@lists.freedesktop.org, NXP Linux Team , Pengutronix Kernel Team , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Marian Cichy Add support for the LCD Controller found on i.MX21, i.MX25 and i.MX27 Note there is already a fb driver for this hardware in the tree that is supposed to be superseded by this one. Signed-off-by: Uwe Kleine-König --- drivers/gpu/drm/imx/Kconfig | 9 + drivers/gpu/drm/imx/Makefile | 2 + drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c | 631 ++++++++++++++++++++ 3 files changed, 642 insertions(+) create mode 100644 drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig index bb9738c7c825..62b24ea1bbe0 100644 --- a/drivers/gpu/drm/imx/Kconfig +++ b/drivers/gpu/drm/imx/Kconfig @@ -42,3 +42,12 @@ config DRM_IMX_HDMI Choose this if you want to use HDMI on i.MX6. source "drivers/gpu/drm/imx/dcss/Kconfig" + +config DRM_IMX21_LCDC + tristate "Freescale i.MX LCDC displays" + depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM || COMPILE_TEST) + select DRM_GEM_CMA_HELPER + select DRM_KMS_HELPER + help + This driver is for the Liquid Crystal Display Controller (LCDC) found + on Freescale i.MX21, i.MX25 and i.MX27. diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile index b644deffe948..25685230f4f7 100644 --- a/drivers/gpu/drm/imx/Makefile +++ b/drivers/gpu/drm/imx/Makefile @@ -10,3 +10,5 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o obj-$(CONFIG_DRM_IMX_DCSS) += dcss/ + +obj-$(CONFIG_DRM_IMX21_LCDC) += imx21-lcdc/ diff --git a/drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c b/drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c new file mode 100644 index 000000000000..37e75f728293 --- /dev/null +++ b/drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c @@ -0,0 +1,631 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: 2020 Marian Cichy + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* LCDC Screen Start Address Register */ +#define IMX21LCDC_LSSAR 0x0000 + +/* LCDC Size Register */ +#define IMX21LCDC_LSR 0x0004 +#define IMX21LCDC_LSR_XMAX GENMASK(25, 20) /* Screen width (in pixels) divided by 16. */ +#define IMX21LCDC_LSR_YMAX GENMASK(9, 0) + +/* LCDC Virtual Page Width Register */ +#define IMX21LCDC_LVPWR 0x0008 + +/* LCDC Cursor Position Register */ +#define IMX21LCDC_LCPR 0x000c +#define IMX21LCDC_LCPR_CC GENMASK(31, 30) /* Cursor Control */ + +/* LCDC Cursor Width Height and Blink Register*/ +#define IMX21LCDC_LCWHB 0x0010 + +/* LCDC Color Cursor Mapping Register */ +#define IMX21LCDC_LCCMR 0x0014 + +/* LCDC Panel Configuration Register */ +#define IMX21LCDC_LPCR 0x0018 +#define IMX21LCDC_LPCR_PCD GENMASK(5, 0) +#define IMX21LCDC_LPCR_SHARP BIT(6) +#define IMX21LCDC_LPCR_SCLKSEL BIT(7) +#define IMX21LCDC_LPCR_ACD GENMASK(14, 8) +#define IMX21LCDC_LPCR_ACDSEL BIT(15) +#define IMX21LCDC_LPCR_REV_VS BIT(16) +#define IMX21LCDC_LPCR_SWAP_SEL BIT(17) +#define IMX21LCDC_LPCR_END_SEL BIT(18) +#define IMX21LCDC_LPCR_SCLKIDLE BIT(19) +#define IMX21LCDC_LPCR_OEPOL BIT(20) +#define IMX21LCDC_LPCR_CLKPOL BIT(21) +#define IMX21LCDC_LPCR_LPPOL BIT(22) +#define IMX21LCDC_LPCR_FLMPOL BIT(23) +#define IMX21LCDC_LPCR_PIXPOL BIT(24) +#define IMX21LCDC_LPCR_BPIX GENMASK(27, 25) +#define IMX21LCDC_LPCR_PBSIZ GENMASK(29, 28) +#define IMX21LCDC_LPCR_COLOR BIT(30) +#define IMX21LCDC_LPCR_TFT BIT(31) + +/* LCDC Horizontal Configuration Register */ +#define IMX21LCDC_LHCR 0x001c +#define IMX21LCDC_LHCR_H_WIDTH GENMASK(31, 26) +#define IMX21LCDC_LHCR_H_BPORCH GENMASK(7, 0) +#define IMX21LCDC_LHCR_H_FPORCH GENMASK(15, 8) + +/* LCDC Vertical Configuration Register */ +#define IMX21LCDC_LVCR 0x0020 +#define IMX21LCDC_LVCR_V_WIDTH GENMASK(31, 26) +#define IMX21LCDC_LVCR_V_BPORCH GENMASK(7, 0) +#define IMX21LCDC_LVCR_V_FPORCH GENMASK(15, 8) + +/* LCDC Panning Offset Register */ +#define IMX21LCDC_LPOR 0x0024 + +/* LCDC Sharp Configuration Register */ +#define IMX21LCDC_LSCR 0x0028 + +/* LCDC PWM Contrast Control Register */ +#define IMX21LCDC_LPCCR 0x002c + +/* LCDC DMA Control Register */ +#define IMX21LCDC_LDCR 0x0030 + +/* LCDC Refresh Mode Control Register */ +#define IMX21LCDC_LRMCR 0x0034 + +/* LCDC Interrupt Configuration Register */ +#define IMX21LCDC_LICR 0x0038 + +/* LCDC Interrupt Enable Register */ +#define IMX21LCDC_LIER 0x003c +#define IMX21LCDC_LIER_EOF BIT(1) + +/* LCDC Interrupt Status Register */ +#define IMX21LCDC_LISR 0x0040 +#define IMX21LCDC_LISR_EOF BIT(1) + +/* LCDC Graphic Window Start Address Register */ +#define IMX21LCDC_LGWSAR 0x0050 + +/* LCDC Graph Window Size Register */ +#define IMX21LCDC_LGWSR 0x0054 + +/* LCDC Graphic Window Virtual Page Width Register */ +#define IMX21LCDC_LGWVPWR 0x0058 + +/* LCDC Graphic Window Panning Offset Register */ +#define IMX21LCDC_LGWPOR 0x005c + +/* LCDC Graphic Window Position Register */ +#define IMX21LCDC_LGWPR 0x0060 + +/* LCDC Graphic Window Control Register */ +#define IMX21LCDC_LGWCR 0x0064 + +/* LCDC Graphic Window DMA Control Register */ +#define IMX21LCDC_LGWDCR 0x0068 + +/* LCDC AUS Mode Control Register */ +#define IMX21LCDC_LAUSCR 0x0080 + +/* LCDC AUS Mode Cursor Control Register */ +#define IMX21LCDC_LAUSCCR 0x0084 + +/* Background Lookup Table */ +#define IMX21LCDC_BGLUT 0x0800 + +/* Graphic Window Lookup Table */ +#define IMX21LCDC_GWLUT 0x0c00 + +#define BPP_RGB565 0x05 + +#define LCDC_MIN_XRES 64 +#define LCDC_MIN_YRES 64 + +#define LCDC_MAX_XRES 1024 +#define LCDC_MAX_YRES 1024 + +struct imx_lcdc { + struct drm_device drm; + struct drm_simple_display_pipe pipe; + const struct drm_display_mode *mode; + struct drm_connector connector; + struct drm_panel *panel; + struct drm_bridge *bridge; + void __iomem *base; + + struct clk *clk_ipg; + struct clk *clk_ahb; + struct clk *clk_per; +}; + +static const u32 imx_lcdc_formats[] = { + DRM_FORMAT_RGB565, +}; + +static inline struct imx_lcdc *drm_to_lcdc(struct drm_device *drm) +{ + return container_of(drm, struct imx_lcdc, drm); +} + +static unsigned int imx_lcdc_get_format(unsigned int drm_format) +{ + unsigned int bpp; + + switch (drm_format) { + default: + DRM_WARN("Format not supported - fallback to RGB565\n"); + fallthrough; + case DRM_FORMAT_RGB565: + bpp = BPP_RGB565; + break; + } + + return bpp; +} + +static int imx_lcdc_connector_get_modes(struct drm_connector *connector) +{ + struct imx_lcdc *lcdc = drm_to_lcdc(connector->dev); + + if (lcdc->panel) + return drm_panel_get_modes(lcdc->panel, connector); + + return 0; +} + +static const struct drm_connector_helper_funcs imx_lcdc_connector_hfuncs = { + .get_modes = imx_lcdc_connector_get_modes, +}; + +static const struct drm_connector_funcs imx_lcdc_connector_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static void imx_lcdc_update_hw_registers(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *old_state, + bool mode_set) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct drm_plane_state *new_state = pipe->plane.state; + struct drm_framebuffer *fb = new_state->fb; + struct imx_lcdc *lcdc = drm_to_lcdc(pipe->crtc.dev); + unsigned int bpp = imx_lcdc_get_format(fb->format->format); + unsigned int lvcr; /* LVCR-Register value */ + unsigned int lhcr; /* LHCR-Register value */ + unsigned int framesize; + dma_addr_t addr = drm_fb_cma_get_gem_addr(fb, new_state, 0); + + /* The LSSAR register specifies the LCD screen start address (SSA). */ + writel(addr, lcdc->base + IMX21LCDC_LSSAR); + + if (!mode_set) + return; + + /* Disable PER clock to make register write possible */ + if (old_state && old_state->crtc && old_state->crtc->enabled) + clk_disable_unprepare(lcdc->clk_per); + + /* Framesize */ + framesize = FIELD_PREP(IMX21LCDC_LSR_XMAX, crtc->mode.hdisplay / 16); + framesize |= FIELD_PREP(IMX21LCDC_LSR_YMAX, crtc->mode.vdisplay); + writel(framesize, lcdc->base + IMX21LCDC_LSR); + + /* HSYNC */ + lhcr = FIELD_PREP(IMX21LCDC_LHCR_H_FPORCH, crtc->mode.hsync_start - crtc->mode.hdisplay - 1); + lhcr |= FIELD_PREP(IMX21LCDC_LHCR_H_WIDTH, crtc->mode.hsync_end - crtc->mode.hsync_start - 1); + lhcr |= FIELD_PREP(IMX21LCDC_LHCR_H_BPORCH, crtc->mode.htotal - crtc->mode.hsync_end - 3); + writel(lhcr, lcdc->base + IMX21LCDC_LHCR); + + /* VSYNC */ + lvcr = FIELD_PREP(IMX21LCDC_LVCR_V_FPORCH, crtc->mode.vsync_start - crtc->mode.vdisplay); + lvcr |= FIELD_PREP(IMX21LCDC_LVCR_V_WIDTH, crtc->mode.vsync_end - crtc->mode.vsync_start); + lvcr |= FIELD_PREP(IMX21LCDC_LVCR_V_BPORCH, crtc->mode.vtotal - crtc->mode.vsync_end); + writel(lvcr, lcdc->base + IMX21LCDC_LVCR); + + writel(readl(lcdc->base + IMX21LCDC_LPCR) | FIELD_PREP(IMX21LCDC_LPCR_BPIX, bpp), + lcdc->base + IMX21LCDC_LPCR); + + /* Virtual Page Width */ + writel(new_state->fb->pitches[0] / 4, lcdc->base + IMX21LCDC_LVPWR); + + /* Enable PER clock */ + if (new_state->crtc->enabled) + clk_prepare_enable(lcdc->clk_per); +} + +static void imx_lcdc_pipe_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) +{ + int ret; + int clk_div; + int bpp; + struct imx_lcdc *lcdc = drm_to_lcdc(pipe->crtc.dev); + struct drm_display_mode *mode = &pipe->crtc.mode; + struct drm_display_info *disp_info = &pipe->connector->display_info; + const int hsync_pol = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : 1; + const int vsync_pol = (mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : 1; + const int data_enable_pol = + (disp_info->bus_flags & DRM_BUS_FLAG_DE_HIGH) ? 0 : 1; + const int clk_pol = + (disp_info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) ? 0 : 1; + + drm_panel_prepare(lcdc->panel); + + clk_div = DIV_ROUND_CLOSEST_ULL(clk_get_rate(lcdc->clk_per), + mode->clock * 1000); + bpp = imx_lcdc_get_format(plane_state->fb->format->format); + + writel(FIELD_PREP(IMX21LCDC_LPCR_PCD, clk_div - 1) | + FIELD_PREP(IMX21LCDC_LPCR_LPPOL, hsync_pol) | + FIELD_PREP(IMX21LCDC_LPCR_FLMPOL, vsync_pol) | + FIELD_PREP(IMX21LCDC_LPCR_OEPOL, data_enable_pol) | + FIELD_PREP(IMX21LCDC_LPCR_TFT, 1) | + FIELD_PREP(IMX21LCDC_LPCR_COLOR, 1) | + FIELD_PREP(IMX21LCDC_LPCR_PBSIZ, 3) | + FIELD_PREP(IMX21LCDC_LPCR_BPIX, bpp) | + FIELD_PREP(IMX21LCDC_LPCR_SCLKSEL, 1) | + FIELD_PREP(IMX21LCDC_LPCR_PIXPOL, 0) | + FIELD_PREP(IMX21LCDC_LPCR_CLKPOL, clk_pol), + lcdc->base + IMX21LCDC_LPCR); + + /* 0px panning offset */ + writel(0x0, lcdc->base + IMX21LCDC_LPOR); + + /* disable hardware cursor */ + writel(readl(lcdc->base + IMX21LCDC_LCPR) & ~IMX21LCDC_LCPR_CC, + lcdc->base + IMX21LCDC_LCPR); + + ret = clk_prepare_enable(lcdc->clk_ipg); + if (ret) { + dev_err(pipe->crtc.dev->dev, "Cannot enable ipg clock: %pe\n", ERR_PTR(ret)); + return; + } + ret = clk_prepare_enable(lcdc->clk_ahb); + if (ret) { + dev_err(pipe->crtc.dev->dev, "Cannot enable ahb clock: %pe\n", ERR_PTR(ret)); + clk_disable_unprepare(lcdc->clk_ipg); + return; + } + + imx_lcdc_update_hw_registers(pipe, NULL, true); + drm_panel_enable(lcdc->panel); + + /* Enable VBLANK Interrupt */ + writel(IMX21LCDC_LIER_EOF, lcdc->base + IMX21LCDC_LIER); +} + +static void imx_lcdc_pipe_disable(struct drm_simple_display_pipe *pipe) +{ + struct imx_lcdc *lcdc = drm_to_lcdc(pipe->crtc.dev); + struct drm_panel *panel = lcdc->panel; + struct drm_crtc *crtc = &lcdc->pipe.crtc; + struct drm_pending_vblank_event *event; + + drm_panel_disable(panel); + + clk_disable_unprepare(lcdc->clk_ahb); + clk_disable_unprepare(lcdc->clk_ipg); + + if (pipe->crtc.enabled) + clk_disable_unprepare(lcdc->clk_per); + + drm_panel_unprepare(panel); + + spin_lock_irq(&lcdc->drm.event_lock); + event = crtc->state->event; + if (event) { + crtc->state->event = NULL; + drm_crtc_send_vblank_event(crtc, event); + } + spin_unlock_irq(&lcdc->drm.event_lock); + + /* Disable VBLANK Interrupt */ + writel(0, lcdc->base + IMX21LCDC_LIER); +} + +static int imx_lcdc_pipe_check(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state, + struct drm_crtc_state *crtc_state) +{ + const struct drm_display_mode *mode = &crtc_state->mode; + + if ((mode->hdisplay < LCDC_MIN_XRES || mode->hdisplay > LCDC_MAX_XRES) || + (mode->vdisplay < LCDC_MIN_YRES || mode->vdisplay > LCDC_MAX_YRES) || + (mode->hdisplay % 16)) { + DRM_ERROR("unsupported display mode (%u x %u)\n", + mode->hdisplay, mode->vdisplay); + return -EINVAL; + } + + if (!FIELD_FIT(IMX21LCDC_LHCR_H_FPORCH, mode->hsync_start - mode->hdisplay - 1) || + !FIELD_FIT(IMX21LCDC_LHCR_H_WIDTH, mode->hsync_end - mode->hsync_start - 1) || + !FIELD_FIT(IMX21LCDC_LHCR_H_BPORCH, mode->htotal - mode->hsync_end - 3)) { + DRM_ERROR("invalid HSYNC setting (htotal = %hu, hsync_start = %hu, hsync_end = %hu, hdisplay = %hu)\n", + mode->htotal, mode->hsync_start, mode->hsync_end, mode->hdisplay); + return -EINVAL; + } + if (!FIELD_FIT(IMX21LCDC_LVCR_V_FPORCH, mode->vsync_start - mode->vdisplay) || + !FIELD_FIT(IMX21LCDC_LVCR_V_WIDTH, mode->vsync_end - mode->vsync_start) || + !FIELD_FIT(IMX21LCDC_LVCR_V_BPORCH, mode->vtotal - mode->vsync_end)) { + DRM_ERROR("invalid VSYNC setting (vtotal = %hu, vsync_start = %hu, vsync_end = %hu, vdisplay = %hu)\n", + mode->vtotal, mode->vsync_start, mode->vsync_end, mode->vdisplay); + return -EINVAL; + + } + + if (plane_state->fb->pitches[0] % 4) { + DRM_ERROR("invalid pitches setting (%hu)\n", plane_state->fb->pitches[0]); + return -EINVAL; + } + + crtc_state->mode_changed = + crtc_state->mode.hdisplay != pipe->crtc.state->mode.hdisplay || + crtc_state->mode.vdisplay != pipe->crtc.state->mode.vdisplay || + plane_state->fb->pitches[0] != pipe->plane.state->fb->pitches[0]; + + return 0; +} + +static void imx_lcdc_pipe_update(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *old_state) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct drm_pending_vblank_event *event = crtc->state->event; + struct drm_plane_state *new_state = pipe->plane.state; + struct drm_framebuffer *fb = new_state->fb; + struct drm_framebuffer *old_fb = old_state->fb; + struct drm_crtc *old_crtc = old_state->crtc; + bool mode_changed = false; + + if (old_fb && old_fb->format != fb->format) + mode_changed = true; + else if (old_crtc != crtc) + mode_changed = true; + else if (crtc->state->mode_changed) + mode_changed = true; + + imx_lcdc_update_hw_registers(pipe, old_state, mode_changed); + + if (event) { + crtc->state->event = NULL; + + spin_lock_irq(&crtc->dev->event_lock); + + if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0) + drm_crtc_arm_vblank_event(crtc, event); + else + drm_crtc_send_vblank_event(crtc, event); + + spin_unlock_irq(&crtc->dev->event_lock); + } +} + +static const struct drm_simple_display_pipe_funcs imx_lcdc_pipe_funcs = { + .enable = imx_lcdc_pipe_enable, + .disable = imx_lcdc_pipe_disable, + .check = imx_lcdc_pipe_check, + .update = imx_lcdc_pipe_update, + .prepare_fb = drm_gem_simple_display_pipe_prepare_fb, +}; + +static const struct drm_mode_config_funcs imx_lcdc_mode_config_funcs = { + .fb_create = drm_gem_fb_create_with_dirty, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static const struct drm_mode_config_helper_funcs imx_lcdc_mode_config_helpers = { + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, +}; + +DEFINE_DRM_GEM_CMA_FOPS(imx_lcdc_drm_fops); + +static struct drm_driver imx_lcdc_drm_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .fops = &imx_lcdc_drm_fops, + DRM_GEM_CMA_DRIVER_OPS_VMAP, + .name = "imx-lcdc", + .desc = "i.MX LCDC driver", + .date = "20200716", +}; + +static const struct of_device_id imx_lcdc_of_dev_id[] = { + { .compatible = "fsl,imx21-lcdc", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_lcdc_of_dev_id); + +static irqreturn_t irq_handler(int irq, void *arg) +{ + struct imx_lcdc *lcdc = (struct imx_lcdc *)arg; + struct drm_crtc *crtc = &lcdc->pipe.crtc; + unsigned int status; + + status = readl(lcdc->base + IMX21LCDC_LISR); + + if (status & IMX21LCDC_LISR_EOF) { + drm_crtc_handle_vblank(crtc); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int imx_lcdc_probe(struct platform_device *pdev) +{ + struct imx_lcdc *lcdc; + struct drm_device *drm; + int irq; + int ret; + struct device *dev = &pdev->dev; + + lcdc = devm_drm_dev_alloc(&pdev->dev, &imx_lcdc_drm_driver, + struct imx_lcdc, drm); + if (!lcdc) + return -ENOMEM; + + drm = &lcdc->drm; + + lcdc->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(lcdc->base)) + return PTR_ERR(lcdc->base); + + /* Panel */ + ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &lcdc->panel, &lcdc->bridge); + if (ret) + return dev_err_probe(dev, ret, "Failed to find panel or bridge\n"); + + /* Get Clocks */ + lcdc->clk_ipg = devm_clk_get(dev, "ipg"); + if (IS_ERR(lcdc->clk_ipg)) + return dev_err_probe(dev, PTR_ERR(lcdc->clk_ipg), "Failed to get ipg clk\n"); + + lcdc->clk_ahb = devm_clk_get(dev, "ahb"); + if (IS_ERR(lcdc->clk_ahb)) + return dev_err_probe(dev, PTR_ERR(lcdc->clk_ipg), "Failed to get ahb clk\n"); + + lcdc->clk_per = devm_clk_get(dev, "per"); + if (IS_ERR(lcdc->clk_per)) + return dev_err_probe(dev, PTR_ERR(lcdc->clk_ipg), "Failed to get ahb clk\n"); + + ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)); + if (ret) + return dev_err_probe(drm->dev, ret, "Failed to set DMA Mask.\n"); + + /* Modeset init */ + ret = drmm_mode_config_init(drm); + if (ret) + return dev_err_probe(drm->dev, ret, "Failed to initialized mode setting.\n"); + + /* CRTC, Plane, Encoder */ + ret = drm_simple_display_pipe_init(drm, &lcdc->pipe, &imx_lcdc_pipe_funcs, imx_lcdc_formats, + ARRAY_SIZE(imx_lcdc_formats), NULL, &lcdc->connector); + if (ret < 0) + return dev_err_probe(drm->dev, ret, "Cannot setup simple display pipe\n"); + + ret = drm_vblank_init(drm, drm->mode_config.num_crtc); + if (ret < 0) + return dev_err_probe(drm->dev, ret, "Failed to initialize vblank\n"); + + if (lcdc->bridge) { + ret = drm_simple_display_pipe_attach_bridge(&lcdc->pipe, + lcdc->bridge); + if (ret) + return dev_err_probe(drm->dev, ret, "Cannot connect bridge\n"); + } + + /* Connector */ + drm_connector_helper_add(&lcdc->connector, &imx_lcdc_connector_hfuncs); + drm_connector_init(drm, &lcdc->connector, &imx_lcdc_connector_funcs, + DRM_MODE_CONNECTOR_DPI); + + /* + * The LCDC controller does not have an enable bit. The + * controller starts directly when the clocks are enabled. + * If the clocks are enabled when the controller is not yet + * programmed with proper register values (enabled at the + * bootloader, for example) then it just goes into some undefined + * state. + * To avoid this issue, let's enable and disable LCDC IPG, + * PER and AHB clock so that we force some kind of 'reset' + * to the LCDC block. + */ + + ret = clk_prepare_enable(lcdc->clk_ipg); + if (ret) + return dev_err_probe(dev, ret, "Cannot enable ipg clock\n"); + clk_disable_unprepare(lcdc->clk_ipg); + + ret = clk_prepare_enable(lcdc->clk_per); + if (ret) + return dev_err_probe(dev, ret, "Cannot enable per clock\n"); + clk_disable_unprepare(lcdc->clk_per); + + ret = clk_prepare_enable(lcdc->clk_ahb); + if (ret) + return dev_err_probe(dev, ret, "Cannot enable ahb clock\n"); + clk_disable_unprepare(lcdc->clk_ahb); + + drm->mode_config.min_width = LCDC_MIN_XRES; + drm->mode_config.max_width = LCDC_MAX_XRES; + drm->mode_config.min_height = LCDC_MIN_YRES; + drm->mode_config.max_height = LCDC_MAX_YRES; + drm->mode_config.preferred_depth = 16; + drm->mode_config.funcs = &imx_lcdc_mode_config_funcs; + drm->mode_config.helper_private = &imx_lcdc_mode_config_helpers; + + drm_mode_config_reset(drm); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + return ret; + } + + ret = devm_request_irq(dev, irq, irq_handler, 0, "imx-lcdc", lcdc); + if (ret < 0) + return dev_err_probe(drm->dev, ret, "Failed to install IRQ handler\n"); + + platform_set_drvdata(pdev, drm); + + ret = drm_dev_register(&lcdc->drm, 0); + if (ret) + return dev_err_probe(dev, ret, "Cannot register device\n"); + + drm_fbdev_generic_setup(drm, 0); + + return 0; +} + +static int imx_lcdc_remove(struct platform_device *pdev) +{ + struct imx_lcdc *lcdc = drm_to_lcdc(platform_get_drvdata(pdev)); + + drm_dev_unregister(&lcdc->drm); + drm_atomic_helper_shutdown(&lcdc->drm); + + return 0; +} + +static void imx_lcdc_shutdown(struct platform_device *pdev) +{ + drm_atomic_helper_shutdown(platform_get_drvdata(pdev)); +} + +static struct platform_driver imx_lcdc_driver = { + .driver = { + .name = "imx-lcdc", + .of_match_table = imx_lcdc_of_dev_id, + }, + .probe = imx_lcdc_probe, + .remove = imx_lcdc_remove, + .shutdown = imx_lcdc_shutdown, +}; +module_platform_driver(imx_lcdc_driver); + +MODULE_AUTHOR("Marian Cichy "); +MODULE_DESCRIPTION("Freescale i.MX LCDC driver"); +MODULE_LICENSE("GPL"); -- 2.34.1 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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D11A4C433F5 for ; Fri, 28 Jan 2022 11:01:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=s+hjyQXNlsqMKF0Vk60ubVROjWJepGbOInXq12dGqPE=; b=vGd6UHPKV+xh8O oltbcHHJkDK9CZIx09Ts/QiUn0Njz+VCdkNWK53XF4lgjf8ui/Jhgv/eH8es34bV2NiH/dwctiCWz W6Q2CIdUqM9QZrxX40GOqubY9SAdeUB1K8jLIfScnaxuzoV8xhM+f1qdeeKHOXwEvqWtlpMMoFko6 fK7kGChs3jK22Mv1glX1g2BqW3/Uz3+DLyJzgSFOb+T+bHeL2NLjrOI10R+l6CxpI/O6U1ZiwvJ4L ye8+IebYeBTdhVKkwFcy6z80LlF/KpL47VQDuxbdla2eNhOz75fN22nF4gYurU6AlloN4ENRi28IW iljxfay+jig4gxJK22zw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nDOyb-001Zk8-5B; Fri, 28 Jan 2022 10:59:33 +0000 Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nDOyK-001Zcy-H8 for linux-arm-kernel@lists.infradead.org; Fri, 28 Jan 2022 10:59:21 +0000 Received: from drehscheibe.grey.stw.pengutronix.de ([2a0a:edc0:0:c01:1d::a2]) by metis.ext.pengutronix.de with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nDOyC-0006q5-Lu; Fri, 28 Jan 2022 11:59:08 +0100 Received: from [2a0a:edc0:0:900:1d::77] (helo=ptz.office.stw.pengutronix.de) by drehscheibe.grey.stw.pengutronix.de with esmtp (Exim 4.94.2) (envelope-from ) id 1nDOyA-00CxGs-6h; Fri, 28 Jan 2022 11:59:05 +0100 Received: from ukl by ptz.office.stw.pengutronix.de with local (Exim 4.94.2) (envelope-from ) id 1nDOy8-001vPv-NL; Fri, 28 Jan 2022 11:59:04 +0100 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= To: Philipp Zabel Cc: David Airlie , Daniel Vetter , Shawn Guo , Pengutronix Kernel Team , Fabio Estevam , NXP Linux Team , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/2] drm/imx/lcdc: Implement DRM driver for imx21 Date: Fri, 28 Jan 2022 11:58:49 +0100 Message-Id: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de> References: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=22490; i=u.kleine-koenig@pengutronix.de; h=from:subject; bh=68F8YE1H89sNovamSKJdUhBglBIYByhtEyQgstqIeRA=; b=owEBbQGS/pANAwAKAcH8FHityuwJAcsmYgBh88xifvszg2evwXEL6/GTOvchWOsYOqeIY/rykwx3 IH8LOaeJATMEAAEKAB0WIQR+cioWkBis/z50pAvB/BR4rcrsCQUCYfPMYgAKCRDB/BR4rcrsCQPZB/ 4jIeF/BsDDn61GQ79R37zjw6mi8AwMmdAi3lBzJwdRjUBQMe5bX0UVDI6GuYOUMv75ckV50O7zSd9o 1NEtNJl3Tx4qFYCd2MvboOj4trbdHXJ1kjJdO3oyr5pSv48INnEz+6+oDPkc8PGZoEw63PjUaXiJsM ABCaNlJhhN3EXqKy2Rh7q2ds195Dv4BFVsjR0MosnpB5wv+tAN3tqaqz4ZxnTj5d3LcWwCKMnpa2S6 7z8izeIkCVE6ysmnzqNR/gm7ruTOG/drZa7TGG/JqHDMqTqlP5l4qgsZ8Dyiva90sAtbgaRkXRLKYJ XIp5iPtNW6eW8NBcQ1OeQcMnmBZtVR X-Developer-Key: i=u.kleine-koenig@pengutronix.de; a=openpgp; fpr=0D2511F322BFAB1C1580266BE2DCDD9132669BD6 X-SA-Exim-Connect-IP: 2a0a:edc0:0:c01:1d::a2 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220128_025916_920024_9631B4E4 X-CRM114-Status: GOOD ( 25.35 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org RnJvbTogTWFyaWFuIENpY2h5IDxtLmNpY2h5QHBlbmd1dHJvbml4LmRlPgoKQWRkIHN1cHBvcnQg Zm9yIHRoZSBMQ0QgQ29udHJvbGxlciBmb3VuZCBvbiBpLk1YMjEsIGkuTVgyNSBhbmQgaS5NWDI3 CgpOb3RlIHRoZXJlIGlzIGFscmVhZHkgYSBmYiBkcml2ZXIgZm9yIHRoaXMgaGFyZHdhcmUgaW4g dGhlIHRyZWUgdGhhdCBpcwpzdXBwb3NlZCB0byBiZSBzdXBlcnNlZGVkIGJ5IHRoaXMgb25lLgoK U2lnbmVkLW9mZi1ieTogVXdlIEtsZWluZS1Lw7ZuaWcgPHUua2xlaW5lLWtvZW5pZ0BwZW5ndXRy b25peC5kZT4KLS0tCiBkcml2ZXJzL2dwdS9kcm0vaW14L0tjb25maWcgICAgICAgICAgICAgICAg IHwgICA5ICsKIGRyaXZlcnMvZ3B1L2RybS9pbXgvTWFrZWZpbGUgICAgICAgICAgICAgICAgfCAg IDIgKwogZHJpdmVycy9ncHUvZHJtL2lteC9pbXgyMS1sY2RjL2lteDIxLWxjZGMuYyB8IDYzMSAr KysrKysrKysrKysrKysrKysrKwogMyBmaWxlcyBjaGFuZ2VkLCA2NDIgaW5zZXJ0aW9ucygrKQog Y3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS9pbXgvaW14MjEtbGNkYy9pbXgyMS1s Y2RjLmMKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaW14L0tjb25maWcgYi9kcml2ZXJz L2dwdS9kcm0vaW14L0tjb25maWcKaW5kZXggYmI5NzM4YzdjODI1Li42MmIyNGVhMWJiZTAgMTAw NjQ0Ci0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pbXgvS2NvbmZpZworKysgYi9kcml2ZXJzL2dwdS9k cm0vaW14L0tjb25maWcKQEAgLTQyLDMgKzQyLDEyIEBAIGNvbmZpZyBEUk1fSU1YX0hETUkKIAkg IENob29zZSB0aGlzIGlmIHlvdSB3YW50IHRvIHVzZSBIRE1JIG9uIGkuTVg2LgogCiBzb3VyY2Ug ImRyaXZlcnMvZ3B1L2RybS9pbXgvZGNzcy9LY29uZmlnIgorCitjb25maWcgRFJNX0lNWDIxX0xD REMKKwl0cmlzdGF0ZSAiRnJlZXNjYWxlIGkuTVggTENEQyBkaXNwbGF5cyIKKwlkZXBlbmRzIG9u IERSTSAmJiAoQVJDSF9NWEMgfHwgQVJDSF9NVUxUSVBMQVRGT1JNIHx8IENPTVBJTEVfVEVTVCkK KwlzZWxlY3QgRFJNX0dFTV9DTUFfSEVMUEVSCisJc2VsZWN0IERSTV9LTVNfSEVMUEVSCisJaGVs cAorCSAgVGhpcyBkcml2ZXIgaXMgZm9yIHRoZSBMaXF1aWQgQ3J5c3RhbCBEaXNwbGF5IENvbnRy b2xsZXIgKExDREMpIGZvdW5kCisJICBvbiBGcmVlc2NhbGUgaS5NWDIxLCBpLk1YMjUgYW5kIGku TVgyNy4KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pbXgvTWFrZWZpbGUgYi9kcml2ZXJz L2dwdS9kcm0vaW14L01ha2VmaWxlCmluZGV4IGI2NDRkZWZmZTk0OC4uMjU2ODUyMzBmNGY3IDEw MDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vaW14L01ha2VmaWxlCisrKyBiL2RyaXZlcnMvZ3B1 L2RybS9pbXgvTWFrZWZpbGUKQEAgLTEwLDMgKzEwLDUgQEAgb2JqLSQoQ09ORklHX0RSTV9JTVhf TERCKSArPSBpbXgtbGRiLm8KIAogb2JqLSQoQ09ORklHX0RSTV9JTVhfSERNSSkgKz0gZHdfaGRt aS1pbXgubwogb2JqLSQoQ09ORklHX0RSTV9JTVhfRENTUykgKz0gZGNzcy8KKworb2JqLSQoQ09O RklHX0RSTV9JTVgyMV9MQ0RDKSArPSBpbXgyMS1sY2RjLwpkaWZmIC0tZ2l0IGEvZHJpdmVycy9n cHUvZHJtL2lteC9pbXgyMS1sY2RjL2lteDIxLWxjZGMuYyBiL2RyaXZlcnMvZ3B1L2RybS9pbXgv aW14MjEtbGNkYy9pbXgyMS1sY2RjLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw MDAwMDAwLi4zN2U3NWY3MjgyOTMKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL2dwdS9kcm0v aW14L2lteDIxLWxjZGMvaW14MjEtbGNkYy5jCkBAIC0wLDAgKzEsNjMxIEBACisvLyBTUERYLUxp Y2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5CisvLyBTUERYLUZpbGVDb3B5cmlnaHRUZXh0 OiAyMDIwIE1hcmlhbiBDaWNoeSA8a2VybmVsQHBlbmd1dHJvbml4LmRlPgorCisjaW5jbHVkZSA8 ZHJtL2RybV9hdG9taWNfaGVscGVyLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9kcnYuaD4KKyNpbmNs dWRlIDxkcm0vZHJtX2ZiX2NtYV9oZWxwZXIuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX2ZiX2hlbHBl ci5oPgorI2luY2x1ZGUgPGRybS9kcm1fZm91cmNjLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9nZW1f YXRvbWljX2hlbHBlci5oPgorI2luY2x1ZGUgPGRybS9kcm1fZ2VtX2NtYV9oZWxwZXIuaD4KKyNp bmNsdWRlIDxkcm0vZHJtX2dlbV9mcmFtZWJ1ZmZlcl9oZWxwZXIuaD4KKyNpbmNsdWRlIDxkcm0v ZHJtX29mLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9wYW5lbC5oPgorI2luY2x1ZGUgPGRybS9kcm1f cHJvYmVfaGVscGVyLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9zaW1wbGVfa21zX2hlbHBlci5oPgor I2luY2x1ZGUgPGRybS9kcm1fdmJsYW5rLmg+CisjaW5jbHVkZSA8bGludXgvYml0ZmllbGQuaD4K KyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KKyNpbmNsdWRlIDxsaW51eC9kbWEtbWFwcGluZy5oPgor I2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgorI2luY2x1ZGUgPGxpbnV4L29mX2RldmljZS5oPgor I2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgorCisvKiBMQ0RDIFNjcmVlbiBTdGFy dCBBZGRyZXNzIFJlZ2lzdGVyICovCisjZGVmaW5lIElNWDIxTENEQ19MU1NBUgkJMHgwMDAwCisK Ky8qIExDREMgU2l6ZSBSZWdpc3RlciAqLworI2RlZmluZSBJTVgyMUxDRENfTFNSCQkweDAwMDQK KyNkZWZpbmUgICBJTVgyMUxDRENfTFNSX1hNQVgJCUdFTk1BU0soMjUsIDIwKSAvKiBTY3JlZW4g d2lkdGggKGluIHBpeGVscykgZGl2aWRlZCBieSAxNi4gKi8KKyNkZWZpbmUgICBJTVgyMUxDRENf TFNSX1lNQVgJCUdFTk1BU0soOSwgMCkKKworLyogTENEQyBWaXJ0dWFsIFBhZ2UgV2lkdGggUmVn aXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xWUFdSCQkweDAwMDgKKworLyogTENEQyBDdXJz b3IgUG9zaXRpb24gUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xDUFIJCTB4MDAwYwor I2RlZmluZSAgIElNWDIxTENEQ19MQ1BSX0NDCQlHRU5NQVNLKDMxLCAzMCkgLyogQ3Vyc29yIENv bnRyb2wgKi8KKworLyogTENEQyBDdXJzb3IgV2lkdGggSGVpZ2h0IGFuZCBCbGluayBSZWdpc3Rl ciovCisjZGVmaW5lIElNWDIxTENEQ19MQ1dIQgkJMHgwMDEwCisKKy8qIExDREMgQ29sb3IgQ3Vy c29yIE1hcHBpbmcgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xDQ01SCQkweDAwMTQK KworLyogTENEQyBQYW5lbCBDb25maWd1cmF0aW9uIFJlZ2lzdGVyICovCisjZGVmaW5lIElNWDIx TENEQ19MUENSCQkweDAwMTgKKyNkZWZpbmUgICBJTVgyMUxDRENfTFBDUl9QQ0QJCUdFTk1BU0so NSwgMCkKKyNkZWZpbmUgICBJTVgyMUxDRENfTFBDUl9TSEFSUAkJQklUKDYpCisjZGVmaW5lICAg SU1YMjFMQ0RDX0xQQ1JfU0NMS1NFTAlCSVQoNykKKyNkZWZpbmUgICBJTVgyMUxDRENfTFBDUl9B Q0QJCUdFTk1BU0soMTQsIDgpCisjZGVmaW5lICAgSU1YMjFMQ0RDX0xQQ1JfQUNEU0VMCQlCSVQo MTUpCisjZGVmaW5lICAgSU1YMjFMQ0RDX0xQQ1JfUkVWX1ZTCQlCSVQoMTYpCisjZGVmaW5lICAg SU1YMjFMQ0RDX0xQQ1JfU1dBUF9TRUwJQklUKDE3KQorI2RlZmluZSAgIElNWDIxTENEQ19MUENS X0VORF9TRUwJQklUKDE4KQorI2RlZmluZSAgIElNWDIxTENEQ19MUENSX1NDTEtJRExFCUJJVCgx OSkKKyNkZWZpbmUgICBJTVgyMUxDRENfTFBDUl9PRVBPTAkJQklUKDIwKQorI2RlZmluZSAgIElN WDIxTENEQ19MUENSX0NMS1BPTAkJQklUKDIxKQorI2RlZmluZSAgIElNWDIxTENEQ19MUENSX0xQ UE9MCQlCSVQoMjIpCisjZGVmaW5lICAgSU1YMjFMQ0RDX0xQQ1JfRkxNUE9MCQlCSVQoMjMpCisj ZGVmaW5lICAgSU1YMjFMQ0RDX0xQQ1JfUElYUE9MCQlCSVQoMjQpCisjZGVmaW5lICAgSU1YMjFM Q0RDX0xQQ1JfQlBJWAkJR0VOTUFTSygyNywgMjUpCisjZGVmaW5lICAgSU1YMjFMQ0RDX0xQQ1Jf UEJTSVoJCUdFTk1BU0soMjksIDI4KQorI2RlZmluZSAgIElNWDIxTENEQ19MUENSX0NPTE9SCQlC SVQoMzApCisjZGVmaW5lICAgSU1YMjFMQ0RDX0xQQ1JfVEZUCQlCSVQoMzEpCisKKy8qIExDREMg SG9yaXpvbnRhbCBDb25maWd1cmF0aW9uIFJlZ2lzdGVyICovCisjZGVmaW5lIElNWDIxTENEQ19M SENSCQkweDAwMWMKKyNkZWZpbmUgICBJTVgyMUxDRENfTEhDUl9IX1dJRFRICUdFTk1BU0soMzEs IDI2KQorI2RlZmluZSAgIElNWDIxTENEQ19MSENSX0hfQlBPUkNICUdFTk1BU0soNywgMCkKKyNk ZWZpbmUgICBJTVgyMUxDRENfTEhDUl9IX0ZQT1JDSAlHRU5NQVNLKDE1LCA4KQorCisvKiBMQ0RD IFZlcnRpY2FsIENvbmZpZ3VyYXRpb24gUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xW Q1IJCTB4MDAyMAorI2RlZmluZSAgIElNWDIxTENEQ19MVkNSX1ZfV0lEVEgJR0VOTUFTSygzMSwg MjYpCisjZGVmaW5lICAgSU1YMjFMQ0RDX0xWQ1JfVl9CUE9SQ0gJR0VOTUFTSyg3LCAwKQorI2Rl ZmluZSAgIElNWDIxTENEQ19MVkNSX1ZfRlBPUkNICUdFTk1BU0soMTUsIDgpCisKKy8qIExDREMg UGFubmluZyBPZmZzZXQgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xQT1IJCTB4MDAy NAorCisvKiBMQ0RDIFNoYXJwIENvbmZpZ3VyYXRpb24gUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1Y MjFMQ0RDX0xTQ1IJCTB4MDAyOAorCisvKiBMQ0RDIFBXTSBDb250cmFzdCBDb250cm9sIFJlZ2lz dGVyICovCisjZGVmaW5lIElNWDIxTENEQ19MUENDUgkJMHgwMDJjCisKKy8qIExDREMgRE1BIENv bnRyb2wgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xEQ1IJCTB4MDAzMAorCisvKiBM Q0RDIFJlZnJlc2ggTW9kZSBDb250cm9sIFJlZ2lzdGVyICovCisjZGVmaW5lIElNWDIxTENEQ19M Uk1DUgkJMHgwMDM0CisKKy8qIExDREMgSW50ZXJydXB0IENvbmZpZ3VyYXRpb24gUmVnaXN0ZXIg Ki8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xJQ1IJCTB4MDAzOAorCisvKiBMQ0RDIEludGVycnVwdCBF bmFibGUgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xJRVIJCTB4MDAzYworI2RlZmlu ZSAgIElNWDIxTENEQ19MSUVSX0VPRgkJQklUKDEpCisKKy8qIExDREMgSW50ZXJydXB0IFN0YXR1 cyBSZWdpc3RlciAqLworI2RlZmluZSBJTVgyMUxDRENfTElTUgkJMHgwMDQwCisjZGVmaW5lICAg SU1YMjFMQ0RDX0xJU1JfRU9GCQlCSVQoMSkKKworLyogTENEQyBHcmFwaGljIFdpbmRvdyBTdGFy dCBBZGRyZXNzIFJlZ2lzdGVyICovCisjZGVmaW5lIElNWDIxTENEQ19MR1dTQVIJMHgwMDUwCisK Ky8qIExDREMgR3JhcGggV2luZG93IFNpemUgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RD X0xHV1NSCQkweDAwNTQKKworLyogTENEQyBHcmFwaGljIFdpbmRvdyBWaXJ0dWFsIFBhZ2UgV2lk dGggUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xHV1ZQV1IJMHgwMDU4CisKKy8qIExD REMgR3JhcGhpYyBXaW5kb3cgUGFubmluZyBPZmZzZXQgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1Y MjFMQ0RDX0xHV1BPUgkweDAwNWMKKworLyogTENEQyBHcmFwaGljIFdpbmRvdyBQb3NpdGlvbiBS ZWdpc3RlciAqLworI2RlZmluZSBJTVgyMUxDRENfTEdXUFIJCTB4MDA2MAorCisvKiBMQ0RDIEdy YXBoaWMgV2luZG93IENvbnRyb2wgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xHV0NS CQkweDAwNjQKKworLyogTENEQyBHcmFwaGljIFdpbmRvdyBETUEgQ29udHJvbCBSZWdpc3RlciAq LworI2RlZmluZSBJTVgyMUxDRENfTEdXRENSCTB4MDA2OAorCisvKiBMQ0RDIEFVUyBNb2RlIENv bnRyb2wgUmVnaXN0ZXIgKi8KKyNkZWZpbmUgSU1YMjFMQ0RDX0xBVVNDUgkweDAwODAKKworLyog TENEQyBBVVMgTW9kZSBDdXJzb3IgQ29udHJvbCBSZWdpc3RlciAqLworI2RlZmluZSBJTVgyMUxD RENfTEFVU0NDUgkweDAwODQKKworLyogQmFja2dyb3VuZCBMb29rdXAgVGFibGUgKi8KKyNkZWZp bmUgSU1YMjFMQ0RDX0JHTFVUCQkweDA4MDAKKworLyogR3JhcGhpYyBXaW5kb3cgTG9va3VwIFRh YmxlICovCisjZGVmaW5lIElNWDIxTENEQ19HV0xVVAkJMHgwYzAwCisKKyNkZWZpbmUgQlBQX1JH QjU2NSAweDA1CisKKyNkZWZpbmUgTENEQ19NSU5fWFJFUyA2NAorI2RlZmluZSBMQ0RDX01JTl9Z UkVTIDY0CisKKyNkZWZpbmUgTENEQ19NQVhfWFJFUyAxMDI0CisjZGVmaW5lIExDRENfTUFYX1lS RVMgMTAyNAorCitzdHJ1Y3QgaW14X2xjZGMgeworCXN0cnVjdCBkcm1fZGV2aWNlIGRybTsKKwlz dHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgcGlwZTsKKwljb25zdCBzdHJ1Y3QgZHJtX2Rp c3BsYXlfbW9kZSAqbW9kZTsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciBjb25uZWN0b3I7CisJc3Ry dWN0IGRybV9wYW5lbCAqcGFuZWw7CisJc3RydWN0IGRybV9icmlkZ2UgKmJyaWRnZTsKKwl2b2lk IF9faW9tZW0gKmJhc2U7CisKKwlzdHJ1Y3QgY2xrICpjbGtfaXBnOworCXN0cnVjdCBjbGsgKmNs a19haGI7CisJc3RydWN0IGNsayAqY2xrX3BlcjsKK307CisKK3N0YXRpYyBjb25zdCB1MzIgaW14 X2xjZGNfZm9ybWF0c1tdID0geworCURSTV9GT1JNQVRfUkdCNTY1LAorfTsKKworc3RhdGljIGlu bGluZSBzdHJ1Y3QgaW14X2xjZGMgKmRybV90b19sY2RjKHN0cnVjdCBkcm1fZGV2aWNlICpkcm0p Cit7CisJcmV0dXJuIGNvbnRhaW5lcl9vZihkcm0sIHN0cnVjdCBpbXhfbGNkYywgZHJtKTsKK30K Kworc3RhdGljIHVuc2lnbmVkIGludCBpbXhfbGNkY19nZXRfZm9ybWF0KHVuc2lnbmVkIGludCBk cm1fZm9ybWF0KQoreworCXVuc2lnbmVkIGludCBicHA7CisKKwlzd2l0Y2ggKGRybV9mb3JtYXQp IHsKKwlkZWZhdWx0OgorCQlEUk1fV0FSTigiRm9ybWF0IG5vdCBzdXBwb3J0ZWQgLSBmYWxsYmFj ayB0byBSR0I1NjVcbiIpOworCQlmYWxsdGhyb3VnaDsKKwljYXNlIERSTV9GT1JNQVRfUkdCNTY1 OgorCQlicHAgPSBCUFBfUkdCNTY1OworCQlicmVhazsKKwl9CisKKwlyZXR1cm4gYnBwOworfQor CitzdGF0aWMgaW50IGlteF9sY2RjX2Nvbm5lY3Rvcl9nZXRfbW9kZXMoc3RydWN0IGRybV9jb25u ZWN0b3IgKmNvbm5lY3RvcikKK3sKKwlzdHJ1Y3QgaW14X2xjZGMgKmxjZGMgPSBkcm1fdG9fbGNk Yyhjb25uZWN0b3ItPmRldik7CisKKwlpZiAobGNkYy0+cGFuZWwpCisJCXJldHVybiBkcm1fcGFu ZWxfZ2V0X21vZGVzKGxjZGMtPnBhbmVsLCBjb25uZWN0b3IpOworCisJcmV0dXJuIDA7Cit9CisK K3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfZnVuY3MgaW14X2xjZGNf Y29ubmVjdG9yX2hmdW5jcyA9IHsKKwkuZ2V0X21vZGVzID0gaW14X2xjZGNfY29ubmVjdG9yX2dl dF9tb2RlcywKK307CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9mdW5jcyBp bXhfbGNkY19jb25uZWN0b3JfZnVuY3MgPSB7CisJLnJlc2V0ID0gZHJtX2F0b21pY19oZWxwZXJf Y29ubmVjdG9yX3Jlc2V0LAorCS5maWxsX21vZGVzID0gZHJtX2hlbHBlcl9wcm9iZV9zaW5nbGVf Y29ubmVjdG9yX21vZGVzLAorCS5kZXN0cm95ID0gZHJtX2Nvbm5lY3Rvcl9jbGVhbnVwLAorCS5h dG9taWNfZHVwbGljYXRlX3N0YXRlID0gZHJtX2F0b21pY19oZWxwZXJfY29ubmVjdG9yX2R1cGxp Y2F0ZV9zdGF0ZSwKKwkuYXRvbWljX2Rlc3Ryb3lfc3RhdGUgPSBkcm1fYXRvbWljX2hlbHBlcl9j b25uZWN0b3JfZGVzdHJveV9zdGF0ZSwKK307CisKK3N0YXRpYyB2b2lkIGlteF9sY2RjX3VwZGF0 ZV9od19yZWdpc3RlcnMoc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9waXBlICpwaXBlLAorCQkJ CQkgc3RydWN0IGRybV9wbGFuZV9zdGF0ZSAqb2xkX3N0YXRlLAorCQkJCQkgYm9vbCBtb2RlX3Nl dCkKK3sKKwlzdHJ1Y3QgZHJtX2NydGMgKmNydGMgPSAmcGlwZS0+Y3J0YzsKKwlzdHJ1Y3QgZHJt X3BsYW5lX3N0YXRlICpuZXdfc3RhdGUgPSBwaXBlLT5wbGFuZS5zdGF0ZTsKKwlzdHJ1Y3QgZHJt X2ZyYW1lYnVmZmVyICpmYiA9IG5ld19zdGF0ZS0+ZmI7CisJc3RydWN0IGlteF9sY2RjICpsY2Rj ID0gZHJtX3RvX2xjZGMocGlwZS0+Y3J0Yy5kZXYpOworCXVuc2lnbmVkIGludCBicHAgPSBpbXhf bGNkY19nZXRfZm9ybWF0KGZiLT5mb3JtYXQtPmZvcm1hdCk7CisJdW5zaWduZWQgaW50IGx2Y3I7 IC8qIExWQ1ItUmVnaXN0ZXIgdmFsdWUgKi8KKwl1bnNpZ25lZCBpbnQgbGhjcjsgLyogTEhDUi1S ZWdpc3RlciB2YWx1ZSAqLworCXVuc2lnbmVkIGludCBmcmFtZXNpemU7CisJZG1hX2FkZHJfdCBh ZGRyID0gZHJtX2ZiX2NtYV9nZXRfZ2VtX2FkZHIoZmIsIG5ld19zdGF0ZSwgMCk7CisKKwkvKiBU aGUgTFNTQVIgcmVnaXN0ZXIgc3BlY2lmaWVzIHRoZSBMQ0Qgc2NyZWVuIHN0YXJ0IGFkZHJlc3Mg KFNTQSkuICovCisJd3JpdGVsKGFkZHIsIGxjZGMtPmJhc2UgKyBJTVgyMUxDRENfTFNTQVIpOwor CisJaWYgKCFtb2RlX3NldCkKKwkJcmV0dXJuOworCisJLyogRGlzYWJsZSBQRVIgY2xvY2sgdG8g bWFrZSByZWdpc3RlciB3cml0ZSBwb3NzaWJsZSAqLworCWlmIChvbGRfc3RhdGUgJiYgb2xkX3N0 YXRlLT5jcnRjICYmIG9sZF9zdGF0ZS0+Y3J0Yy0+ZW5hYmxlZCkKKwkJY2xrX2Rpc2FibGVfdW5w cmVwYXJlKGxjZGMtPmNsa19wZXIpOworCisJLyogRnJhbWVzaXplICovCisJZnJhbWVzaXplID0g RklFTERfUFJFUChJTVgyMUxDRENfTFNSX1hNQVgsIGNydGMtPm1vZGUuaGRpc3BsYXkgLyAxNik7 CisJZnJhbWVzaXplIHw9IEZJRUxEX1BSRVAoSU1YMjFMQ0RDX0xTUl9ZTUFYLCBjcnRjLT5tb2Rl LnZkaXNwbGF5KTsKKwl3cml0ZWwoZnJhbWVzaXplLCBsY2RjLT5iYXNlICsgSU1YMjFMQ0RDX0xT Uik7CisKKwkvKiBIU1lOQyAqLworCWxoY3IgPSBGSUVMRF9QUkVQKElNWDIxTENEQ19MSENSX0hf RlBPUkNILCBjcnRjLT5tb2RlLmhzeW5jX3N0YXJ0IC0gY3J0Yy0+bW9kZS5oZGlzcGxheSAtIDEp OworCWxoY3IgfD0gRklFTERfUFJFUChJTVgyMUxDRENfTEhDUl9IX1dJRFRILCBjcnRjLT5tb2Rl LmhzeW5jX2VuZCAtIGNydGMtPm1vZGUuaHN5bmNfc3RhcnQgLSAxKTsKKwlsaGNyIHw9IEZJRUxE X1BSRVAoSU1YMjFMQ0RDX0xIQ1JfSF9CUE9SQ0gsIGNydGMtPm1vZGUuaHRvdGFsIC0gY3J0Yy0+ bW9kZS5oc3luY19lbmQgLSAzKTsKKwl3cml0ZWwobGhjciwgbGNkYy0+YmFzZSArIElNWDIxTENE Q19MSENSKTsKKworCS8qIFZTWU5DICovCisJbHZjciA9IEZJRUxEX1BSRVAoSU1YMjFMQ0RDX0xW Q1JfVl9GUE9SQ0gsIGNydGMtPm1vZGUudnN5bmNfc3RhcnQgLSBjcnRjLT5tb2RlLnZkaXNwbGF5 KTsKKwlsdmNyIHw9IEZJRUxEX1BSRVAoSU1YMjFMQ0RDX0xWQ1JfVl9XSURUSCwgY3J0Yy0+bW9k ZS52c3luY19lbmQgLSBjcnRjLT5tb2RlLnZzeW5jX3N0YXJ0KTsKKwlsdmNyIHw9IEZJRUxEX1BS RVAoSU1YMjFMQ0RDX0xWQ1JfVl9CUE9SQ0gsIGNydGMtPm1vZGUudnRvdGFsIC0gY3J0Yy0+bW9k ZS52c3luY19lbmQpOworCXdyaXRlbChsdmNyLCBsY2RjLT5iYXNlICsgSU1YMjFMQ0RDX0xWQ1Ip OworCisJd3JpdGVsKHJlYWRsKGxjZGMtPmJhc2UgKyBJTVgyMUxDRENfTFBDUikgfCBGSUVMRF9Q UkVQKElNWDIxTENEQ19MUENSX0JQSVgsIGJwcCksCisJICAgICAgIGxjZGMtPmJhc2UgKyBJTVgy MUxDRENfTFBDUik7CisKKwkvKiBWaXJ0dWFsIFBhZ2UgV2lkdGggKi8KKwl3cml0ZWwobmV3X3N0 YXRlLT5mYi0+cGl0Y2hlc1swXSAvIDQsIGxjZGMtPmJhc2UgKyBJTVgyMUxDRENfTFZQV1IpOwor CisJLyogRW5hYmxlIFBFUiBjbG9jayAqLworCWlmIChuZXdfc3RhdGUtPmNydGMtPmVuYWJsZWQp CisJCWNsa19wcmVwYXJlX2VuYWJsZShsY2RjLT5jbGtfcGVyKTsKK30KKworc3RhdGljIHZvaWQg aW14X2xjZGNfcGlwZV9lbmFibGUoc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9waXBlICpwaXBl LAorCQkJCSBzdHJ1Y3QgZHJtX2NydGNfc3RhdGUgKmNydGNfc3RhdGUsCisJCQkJIHN0cnVjdCBk cm1fcGxhbmVfc3RhdGUgKnBsYW5lX3N0YXRlKQoreworCWludCByZXQ7CisJaW50IGNsa19kaXY7 CisJaW50IGJwcDsKKwlzdHJ1Y3QgaW14X2xjZGMgKmxjZGMgPSBkcm1fdG9fbGNkYyhwaXBlLT5j cnRjLmRldik7CisJc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1vZGUgPSAmcGlwZS0+Y3J0Yy5t b2RlOworCXN0cnVjdCBkcm1fZGlzcGxheV9pbmZvICpkaXNwX2luZm8gPSAmcGlwZS0+Y29ubmVj dG9yLT5kaXNwbGF5X2luZm87CisJY29uc3QgaW50IGhzeW5jX3BvbCA9IChtb2RlLT5mbGFncyAm IERSTV9NT0RFX0ZMQUdfUEhTWU5DKSA/IDAgOiAxOworCWNvbnN0IGludCB2c3luY19wb2wgPSAo bW9kZS0+ZmxhZ3MgJiBEUk1fTU9ERV9GTEFHX1BWU1lOQykgPyAwIDogMTsKKwljb25zdCBpbnQg ZGF0YV9lbmFibGVfcG9sID0KKwkJKGRpc3BfaW5mby0+YnVzX2ZsYWdzICYgRFJNX0JVU19GTEFH X0RFX0hJR0gpID8gMCA6IDE7CisJY29uc3QgaW50IGNsa19wb2wgPQorCQkoZGlzcF9pbmZvLT5i dXNfZmxhZ3MgJiBEUk1fQlVTX0ZMQUdfUElYREFUQV9EUklWRV9QT1NFREdFKSA/IDAgOiAxOwor CisJZHJtX3BhbmVsX3ByZXBhcmUobGNkYy0+cGFuZWwpOworCisJY2xrX2RpdiA9IERJVl9ST1VO RF9DTE9TRVNUX1VMTChjbGtfZ2V0X3JhdGUobGNkYy0+Y2xrX3BlciksCisJCQkJCW1vZGUtPmNs b2NrICogMTAwMCk7CisJYnBwID0gaW14X2xjZGNfZ2V0X2Zvcm1hdChwbGFuZV9zdGF0ZS0+ZmIt PmZvcm1hdC0+Zm9ybWF0KTsKKworCXdyaXRlbChGSUVMRF9QUkVQKElNWDIxTENEQ19MUENSX1BD RCwgY2xrX2RpdiAtIDEpIHwKKwkgICAgICAgRklFTERfUFJFUChJTVgyMUxDRENfTFBDUl9MUFBP TCwgaHN5bmNfcG9sKSB8CisJICAgICAgIEZJRUxEX1BSRVAoSU1YMjFMQ0RDX0xQQ1JfRkxNUE9M LCB2c3luY19wb2wpIHwKKwkgICAgICAgRklFTERfUFJFUChJTVgyMUxDRENfTFBDUl9PRVBPTCwg ZGF0YV9lbmFibGVfcG9sKSB8CisJICAgICAgIEZJRUxEX1BSRVAoSU1YMjFMQ0RDX0xQQ1JfVEZU LCAxKSB8CisJICAgICAgIEZJRUxEX1BSRVAoSU1YMjFMQ0RDX0xQQ1JfQ09MT1IsIDEpIHwKKwkg ICAgICAgRklFTERfUFJFUChJTVgyMUxDRENfTFBDUl9QQlNJWiwgMykgfAorCSAgICAgICBGSUVM RF9QUkVQKElNWDIxTENEQ19MUENSX0JQSVgsIGJwcCkgfAorCSAgICAgICBGSUVMRF9QUkVQKElN WDIxTENEQ19MUENSX1NDTEtTRUwsIDEpIHwKKwkgICAgICAgRklFTERfUFJFUChJTVgyMUxDRENf TFBDUl9QSVhQT0wsIDApIHwKKwkgICAgICAgRklFTERfUFJFUChJTVgyMUxDRENfTFBDUl9DTEtQ T0wsIGNsa19wb2wpLAorCSAgICAgICBsY2RjLT5iYXNlICsgSU1YMjFMQ0RDX0xQQ1IpOworCisJ LyogMHB4IHBhbm5pbmcgb2Zmc2V0ICovCisJd3JpdGVsKDB4MCwgbGNkYy0+YmFzZSArIElNWDIx TENEQ19MUE9SKTsKKworCS8qIGRpc2FibGUgaGFyZHdhcmUgY3Vyc29yICovCisJd3JpdGVsKHJl YWRsKGxjZGMtPmJhc2UgKyBJTVgyMUxDRENfTENQUikgJiB+SU1YMjFMQ0RDX0xDUFJfQ0MsCisJ ICAgICAgIGxjZGMtPmJhc2UgKyBJTVgyMUxDRENfTENQUik7CisKKwlyZXQgPSBjbGtfcHJlcGFy ZV9lbmFibGUobGNkYy0+Y2xrX2lwZyk7CisJaWYgKHJldCkgeworCQlkZXZfZXJyKHBpcGUtPmNy dGMuZGV2LT5kZXYsICJDYW5ub3QgZW5hYmxlIGlwZyBjbG9jazogJXBlXG4iLCBFUlJfUFRSKHJl dCkpOworCQlyZXR1cm47CisJfQorCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShsY2RjLT5jbGtf YWhiKTsKKwlpZiAocmV0KSB7CisJCWRldl9lcnIocGlwZS0+Y3J0Yy5kZXYtPmRldiwgIkNhbm5v dCBlbmFibGUgYWhiIGNsb2NrOiAlcGVcbiIsIEVSUl9QVFIocmV0KSk7CisJCWNsa19kaXNhYmxl X3VucHJlcGFyZShsY2RjLT5jbGtfaXBnKTsKKwkJcmV0dXJuOworCX0KKworCWlteF9sY2RjX3Vw ZGF0ZV9od19yZWdpc3RlcnMocGlwZSwgTlVMTCwgdHJ1ZSk7CisJZHJtX3BhbmVsX2VuYWJsZShs Y2RjLT5wYW5lbCk7CisKKwkvKiBFbmFibGUgVkJMQU5LIEludGVycnVwdCAqLworCXdyaXRlbChJ TVgyMUxDRENfTElFUl9FT0YsIGxjZGMtPmJhc2UgKyBJTVgyMUxDRENfTElFUik7Cit9CisKK3N0 YXRpYyB2b2lkIGlteF9sY2RjX3BpcGVfZGlzYWJsZShzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5 X3BpcGUgKnBpcGUpCit7CisJc3RydWN0IGlteF9sY2RjICpsY2RjID0gZHJtX3RvX2xjZGMocGlw ZS0+Y3J0Yy5kZXYpOworCXN0cnVjdCBkcm1fcGFuZWwgKnBhbmVsID0gbGNkYy0+cGFuZWw7CisJ c3RydWN0IGRybV9jcnRjICpjcnRjID0gJmxjZGMtPnBpcGUuY3J0YzsKKwlzdHJ1Y3QgZHJtX3Bl bmRpbmdfdmJsYW5rX2V2ZW50ICpldmVudDsKKworCWRybV9wYW5lbF9kaXNhYmxlKHBhbmVsKTsK KworCWNsa19kaXNhYmxlX3VucHJlcGFyZShsY2RjLT5jbGtfYWhiKTsKKwljbGtfZGlzYWJsZV91 bnByZXBhcmUobGNkYy0+Y2xrX2lwZyk7CisKKwlpZiAocGlwZS0+Y3J0Yy5lbmFibGVkKQorCQlj bGtfZGlzYWJsZV91bnByZXBhcmUobGNkYy0+Y2xrX3Blcik7CisKKwlkcm1fcGFuZWxfdW5wcmVw YXJlKHBhbmVsKTsKKworCXNwaW5fbG9ja19pcnEoJmxjZGMtPmRybS5ldmVudF9sb2NrKTsKKwll dmVudCA9IGNydGMtPnN0YXRlLT5ldmVudDsKKwlpZiAoZXZlbnQpIHsKKwkJY3J0Yy0+c3RhdGUt PmV2ZW50ID0gTlVMTDsKKwkJZHJtX2NydGNfc2VuZF92YmxhbmtfZXZlbnQoY3J0YywgZXZlbnQp OworCX0KKwlzcGluX3VubG9ja19pcnEoJmxjZGMtPmRybS5ldmVudF9sb2NrKTsKKworCS8qIERp c2FibGUgVkJMQU5LIEludGVycnVwdCAqLworCXdyaXRlbCgwLCBsY2RjLT5iYXNlICsgSU1YMjFM Q0RDX0xJRVIpOworfQorCitzdGF0aWMgaW50IGlteF9sY2RjX3BpcGVfY2hlY2soc3RydWN0IGRy bV9zaW1wbGVfZGlzcGxheV9waXBlICpwaXBlLAorCQkJICAgICAgIHN0cnVjdCBkcm1fcGxhbmVf c3RhdGUgKnBsYW5lX3N0YXRlLAorCQkJICAgICAgIHN0cnVjdCBkcm1fY3J0Y19zdGF0ZSAqY3J0 Y19zdGF0ZSkKK3sKKwljb25zdCBzdHJ1Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqbW9kZSA9ICZjcnRj X3N0YXRlLT5tb2RlOworCisJaWYgKChtb2RlLT5oZGlzcGxheSA8IExDRENfTUlOX1hSRVMgfHwg bW9kZS0+aGRpc3BsYXkgPiBMQ0RDX01BWF9YUkVTKSB8fAorCSAgICAobW9kZS0+dmRpc3BsYXkg PCBMQ0RDX01JTl9ZUkVTIHx8IG1vZGUtPnZkaXNwbGF5ID4gTENEQ19NQVhfWVJFUykgfHwKKwkg ICAgKG1vZGUtPmhkaXNwbGF5ICUgMTYpKSB7CisJCURSTV9FUlJPUigidW5zdXBwb3J0ZWQgZGlz cGxheSBtb2RlICgldSB4ICV1KVxuIiwKKwkJCSAgbW9kZS0+aGRpc3BsYXksIG1vZGUtPnZkaXNw bGF5KTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJaWYgKCFGSUVMRF9GSVQoSU1YMjFMQ0RD X0xIQ1JfSF9GUE9SQ0gsIG1vZGUtPmhzeW5jX3N0YXJ0IC0gbW9kZS0+aGRpc3BsYXkgLSAxKSB8 fAorCSAgICAhRklFTERfRklUKElNWDIxTENEQ19MSENSX0hfV0lEVEgsIG1vZGUtPmhzeW5jX2Vu ZCAtIG1vZGUtPmhzeW5jX3N0YXJ0IC0gMSkgfHwKKwkgICAgIUZJRUxEX0ZJVChJTVgyMUxDRENf TEhDUl9IX0JQT1JDSCwgbW9kZS0+aHRvdGFsIC0gbW9kZS0+aHN5bmNfZW5kIC0gMykpIHsKKwkJ RFJNX0VSUk9SKCJpbnZhbGlkIEhTWU5DIHNldHRpbmcgKGh0b3RhbCA9ICVodSwgaHN5bmNfc3Rh cnQgPSAlaHUsIGhzeW5jX2VuZCA9ICVodSwgaGRpc3BsYXkgPSAlaHUpXG4iLAorCQkJICBtb2Rl LT5odG90YWwsIG1vZGUtPmhzeW5jX3N0YXJ0LCBtb2RlLT5oc3luY19lbmQsIG1vZGUtPmhkaXNw bGF5KTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCWlmICghRklFTERfRklUKElNWDIxTENEQ19M VkNSX1ZfRlBPUkNILCBtb2RlLT52c3luY19zdGFydCAtIG1vZGUtPnZkaXNwbGF5KSB8fAorCSAg ICAhRklFTERfRklUKElNWDIxTENEQ19MVkNSX1ZfV0lEVEgsIG1vZGUtPnZzeW5jX2VuZCAtIG1v ZGUtPnZzeW5jX3N0YXJ0KSB8fAorCSAgICAhRklFTERfRklUKElNWDIxTENEQ19MVkNSX1ZfQlBP UkNILCBtb2RlLT52dG90YWwgLSBtb2RlLT52c3luY19lbmQpKSB7CisJCURSTV9FUlJPUigiaW52 YWxpZCBWU1lOQyBzZXR0aW5nICh2dG90YWwgPSAlaHUsIHZzeW5jX3N0YXJ0ID0gJWh1LCB2c3lu Y19lbmQgPSAlaHUsIHZkaXNwbGF5ID0gJWh1KVxuIiwKKwkJCSAgbW9kZS0+dnRvdGFsLCBtb2Rl LT52c3luY19zdGFydCwgbW9kZS0+dnN5bmNfZW5kLCBtb2RlLT52ZGlzcGxheSk7CisJCXJldHVy biAtRUlOVkFMOworCisJfQorCisJaWYgKHBsYW5lX3N0YXRlLT5mYi0+cGl0Y2hlc1swXSAlIDQp IHsKKwkJRFJNX0VSUk9SKCJpbnZhbGlkIHBpdGNoZXMgc2V0dGluZyAoJWh1KVxuIiwgcGxhbmVf c3RhdGUtPmZiLT5waXRjaGVzWzBdKTsKKwkJcmV0dXJuIC1FSU5WQUw7CisJfQorCisJY3J0Y19z dGF0ZS0+bW9kZV9jaGFuZ2VkID0KKwkJY3J0Y19zdGF0ZS0+bW9kZS5oZGlzcGxheSAhPSBwaXBl LT5jcnRjLnN0YXRlLT5tb2RlLmhkaXNwbGF5IHx8CisJCWNydGNfc3RhdGUtPm1vZGUudmRpc3Bs YXkgIT0gcGlwZS0+Y3J0Yy5zdGF0ZS0+bW9kZS52ZGlzcGxheSB8fAorCQlwbGFuZV9zdGF0ZS0+ ZmItPnBpdGNoZXNbMF0gIT0gcGlwZS0+cGxhbmUuc3RhdGUtPmZiLT5waXRjaGVzWzBdOworCisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIGlteF9sY2RjX3BpcGVfdXBkYXRlKHN0cnVjdCBk cm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSwKKwkJCQkgc3RydWN0IGRybV9wbGFuZV9zdGF0 ZSAqb2xkX3N0YXRlKQoreworCXN0cnVjdCBkcm1fY3J0YyAqY3J0YyA9ICZwaXBlLT5jcnRjOwor CXN0cnVjdCBkcm1fcGVuZGluZ192YmxhbmtfZXZlbnQgKmV2ZW50ID0gY3J0Yy0+c3RhdGUtPmV2 ZW50OworCXN0cnVjdCBkcm1fcGxhbmVfc3RhdGUgKm5ld19zdGF0ZSA9IHBpcGUtPnBsYW5lLnN0 YXRlOworCXN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiID0gbmV3X3N0YXRlLT5mYjsKKwlzdHJ1 Y3QgZHJtX2ZyYW1lYnVmZmVyICpvbGRfZmIgPSBvbGRfc3RhdGUtPmZiOworCXN0cnVjdCBkcm1f Y3J0YyAqb2xkX2NydGMgPSBvbGRfc3RhdGUtPmNydGM7CisJYm9vbCBtb2RlX2NoYW5nZWQgPSBm YWxzZTsKKworCWlmIChvbGRfZmIgJiYgb2xkX2ZiLT5mb3JtYXQgIT0gZmItPmZvcm1hdCkKKwkJ bW9kZV9jaGFuZ2VkID0gdHJ1ZTsKKwllbHNlIGlmIChvbGRfY3J0YyAhPSBjcnRjKQorCQltb2Rl X2NoYW5nZWQgPSB0cnVlOworCWVsc2UgaWYgKGNydGMtPnN0YXRlLT5tb2RlX2NoYW5nZWQpCisJ CW1vZGVfY2hhbmdlZCA9IHRydWU7CisKKwlpbXhfbGNkY191cGRhdGVfaHdfcmVnaXN0ZXJzKHBp cGUsIG9sZF9zdGF0ZSwgbW9kZV9jaGFuZ2VkKTsKKworCWlmIChldmVudCkgeworCQljcnRjLT5z dGF0ZS0+ZXZlbnQgPSBOVUxMOworCisJCXNwaW5fbG9ja19pcnEoJmNydGMtPmRldi0+ZXZlbnRf bG9jayk7CisKKwkJaWYgKGNydGMtPnN0YXRlLT5hY3RpdmUgJiYgZHJtX2NydGNfdmJsYW5rX2dl dChjcnRjKSA9PSAwKQorCQkJZHJtX2NydGNfYXJtX3ZibGFua19ldmVudChjcnRjLCBldmVudCk7 CisJCWVsc2UKKwkJCWRybV9jcnRjX3NlbmRfdmJsYW5rX2V2ZW50KGNydGMsIGV2ZW50KTsKKwor CQlzcGluX3VubG9ja19pcnEoJmNydGMtPmRldi0+ZXZlbnRfbG9jayk7CisJfQorfQorCitzdGF0 aWMgY29uc3Qgc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9waXBlX2Z1bmNzIGlteF9sY2RjX3Bp cGVfZnVuY3MgPSB7CisJLmVuYWJsZSA9IGlteF9sY2RjX3BpcGVfZW5hYmxlLAorCS5kaXNhYmxl ID0gaW14X2xjZGNfcGlwZV9kaXNhYmxlLAorCS5jaGVjayA9IGlteF9sY2RjX3BpcGVfY2hlY2ss CisJLnVwZGF0ZSA9IGlteF9sY2RjX3BpcGVfdXBkYXRlLAorCS5wcmVwYXJlX2ZiID0gZHJtX2dl bV9zaW1wbGVfZGlzcGxheV9waXBlX3ByZXBhcmVfZmIsCit9OworCitzdGF0aWMgY29uc3Qgc3Ry dWN0IGRybV9tb2RlX2NvbmZpZ19mdW5jcyBpbXhfbGNkY19tb2RlX2NvbmZpZ19mdW5jcyA9IHsK KwkuZmJfY3JlYXRlID0gZHJtX2dlbV9mYl9jcmVhdGVfd2l0aF9kaXJ0eSwKKwkuYXRvbWljX2No ZWNrID0gZHJtX2F0b21pY19oZWxwZXJfY2hlY2ssCisJLmF0b21pY19jb21taXQgPSBkcm1fYXRv bWljX2hlbHBlcl9jb21taXQsCit9OworCitzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9tb2RlX2Nv bmZpZ19oZWxwZXJfZnVuY3MgaW14X2xjZGNfbW9kZV9jb25maWdfaGVscGVycyA9IHsKKwkuYXRv bWljX2NvbW1pdF90YWlsID0gZHJtX2F0b21pY19oZWxwZXJfY29tbWl0X3RhaWxfcnBtLAorfTsK KworREVGSU5FX0RSTV9HRU1fQ01BX0ZPUFMoaW14X2xjZGNfZHJtX2ZvcHMpOworCitzdGF0aWMg c3RydWN0IGRybV9kcml2ZXIgaW14X2xjZGNfZHJtX2RyaXZlciA9IHsKKwkuZHJpdmVyX2ZlYXR1 cmVzID0gRFJJVkVSX0dFTSB8IERSSVZFUl9NT0RFU0VUIHwgRFJJVkVSX0FUT01JQywKKwkuZm9w cyA9ICZpbXhfbGNkY19kcm1fZm9wcywKKwlEUk1fR0VNX0NNQV9EUklWRVJfT1BTX1ZNQVAsCisJ Lm5hbWUgPSAiaW14LWxjZGMiLAorCS5kZXNjID0gImkuTVggTENEQyBkcml2ZXIiLAorCS5kYXRl ID0gIjIwMjAwNzE2IiwKK307CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIGlt eF9sY2RjX29mX2Rldl9pZFtdID0geworCXsgLmNvbXBhdGlibGUgPSAiZnNsLGlteDIxLWxjZGMi LCB9LAorCXsgLyogc2VudGluZWwgKi8gfQorfTsKK01PRFVMRV9ERVZJQ0VfVEFCTEUob2YsIGlt eF9sY2RjX29mX2Rldl9pZCk7CisKK3N0YXRpYyBpcnFyZXR1cm5fdCBpcnFfaGFuZGxlcihpbnQg aXJxLCB2b2lkICphcmcpCit7CisJc3RydWN0IGlteF9sY2RjICpsY2RjID0gKHN0cnVjdCBpbXhf bGNkYyAqKWFyZzsKKwlzdHJ1Y3QgZHJtX2NydGMgKmNydGMgPSAmbGNkYy0+cGlwZS5jcnRjOwor CXVuc2lnbmVkIGludCBzdGF0dXM7CisKKwlzdGF0dXMgPSByZWFkbChsY2RjLT5iYXNlICsgSU1Y MjFMQ0RDX0xJU1IpOworCisJaWYgKHN0YXR1cyAmIElNWDIxTENEQ19MSVNSX0VPRikgeworCQlk cm1fY3J0Y19oYW5kbGVfdmJsYW5rKGNydGMpOworCQlyZXR1cm4gSVJRX0hBTkRMRUQ7CisJfQor CisJcmV0dXJuIElSUV9OT05FOworfQorCitzdGF0aWMgaW50IGlteF9sY2RjX3Byb2JlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3RydWN0IGlteF9sY2RjICpsY2RjOworCXN0 cnVjdCBkcm1fZGV2aWNlICpkcm07CisJaW50IGlycTsKKwlpbnQgcmV0OworCXN0cnVjdCBkZXZp Y2UgKmRldiA9ICZwZGV2LT5kZXY7CisKKwlsY2RjID0gZGV2bV9kcm1fZGV2X2FsbG9jKCZwZGV2 LT5kZXYsICZpbXhfbGNkY19kcm1fZHJpdmVyLAorCQkJCSAgc3RydWN0IGlteF9sY2RjLCBkcm0p OworCWlmICghbGNkYykKKwkJcmV0dXJuIC1FTk9NRU07CisKKwlkcm0gPSAmbGNkYy0+ZHJtOwor CisJbGNkYy0+YmFzZSA9IGRldm1fcGxhdGZvcm1faW9yZW1hcF9yZXNvdXJjZShwZGV2LCAwKTsK KwlpZiAoSVNfRVJSKGxjZGMtPmJhc2UpKQorCQlyZXR1cm4gUFRSX0VSUihsY2RjLT5iYXNlKTsK KworCS8qIFBhbmVsICovCisJcmV0ID0gZHJtX29mX2ZpbmRfcGFuZWxfb3JfYnJpZGdlKGRldi0+ b2Zfbm9kZSwgMCwgMCwgJmxjZGMtPnBhbmVsLCAmbGNkYy0+YnJpZGdlKTsKKwlpZiAocmV0KQor CQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgIkZhaWxlZCB0byBmaW5kIHBhbmVsIG9y IGJyaWRnZVxuIik7CisKKwkvKiBHZXQgQ2xvY2tzICovCisJbGNkYy0+Y2xrX2lwZyA9IGRldm1f Y2xrX2dldChkZXYsICJpcGciKTsKKwlpZiAoSVNfRVJSKGxjZGMtPmNsa19pcGcpKQorCQlyZXR1 cm4gZGV2X2Vycl9wcm9iZShkZXYsIFBUUl9FUlIobGNkYy0+Y2xrX2lwZyksICJGYWlsZWQgdG8g Z2V0IGlwZyBjbGtcbiIpOworCisJbGNkYy0+Y2xrX2FoYiA9IGRldm1fY2xrX2dldChkZXYsICJh aGIiKTsKKwlpZiAoSVNfRVJSKGxjZGMtPmNsa19haGIpKQorCQlyZXR1cm4gZGV2X2Vycl9wcm9i ZShkZXYsIFBUUl9FUlIobGNkYy0+Y2xrX2lwZyksICJGYWlsZWQgdG8gZ2V0IGFoYiBjbGtcbiIp OworCisJbGNkYy0+Y2xrX3BlciA9IGRldm1fY2xrX2dldChkZXYsICJwZXIiKTsKKwlpZiAoSVNf RVJSKGxjZGMtPmNsa19wZXIpKQorCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIFBUUl9FUlIo bGNkYy0+Y2xrX2lwZyksICJGYWlsZWQgdG8gZ2V0IGFoYiBjbGtcbiIpOworCisJcmV0ID0gZG1h X3NldF9tYXNrX2FuZF9jb2hlcmVudChkcm0tPmRldiwgRE1BX0JJVF9NQVNLKDMyKSk7CisJaWYg KHJldCkKKwkJcmV0dXJuIGRldl9lcnJfcHJvYmUoZHJtLT5kZXYsIHJldCwgIkZhaWxlZCB0byBz ZXQgRE1BIE1hc2suXG4iKTsKKworCS8qIE1vZGVzZXQgaW5pdCAqLworCXJldCA9IGRybW1fbW9k ZV9jb25maWdfaW5pdChkcm0pOworCWlmIChyZXQpCisJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRy bS0+ZGV2LCByZXQsICJGYWlsZWQgdG8gaW5pdGlhbGl6ZWQgbW9kZSBzZXR0aW5nLlxuIik7CisK KwkvKiBDUlRDLCBQbGFuZSwgRW5jb2RlciAqLworCXJldCA9IGRybV9zaW1wbGVfZGlzcGxheV9w aXBlX2luaXQoZHJtLCAmbGNkYy0+cGlwZSwgJmlteF9sY2RjX3BpcGVfZnVuY3MsIGlteF9sY2Rj X2Zvcm1hdHMsCisJCQkJCSAgIEFSUkFZX1NJWkUoaW14X2xjZGNfZm9ybWF0cyksIE5VTEwsICZs Y2RjLT5jb25uZWN0b3IpOworCWlmIChyZXQgPCAwKQorCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShk cm0tPmRldiwgcmV0LCAiQ2Fubm90IHNldHVwIHNpbXBsZSBkaXNwbGF5IHBpcGVcbiIpOworCisJ cmV0ID0gZHJtX3ZibGFua19pbml0KGRybSwgZHJtLT5tb2RlX2NvbmZpZy5udW1fY3J0Yyk7CisJ aWYgKHJldCA8IDApCisJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRybS0+ZGV2LCByZXQsICJGYWls ZWQgdG8gaW5pdGlhbGl6ZSB2YmxhbmtcbiIpOworCisJaWYgKGxjZGMtPmJyaWRnZSkgeworCQly ZXQgPSBkcm1fc2ltcGxlX2Rpc3BsYXlfcGlwZV9hdHRhY2hfYnJpZGdlKCZsY2RjLT5waXBlLAor CQkJCQkJCSAgICBsY2RjLT5icmlkZ2UpOworCQlpZiAocmV0KQorCQkJcmV0dXJuIGRldl9lcnJf cHJvYmUoZHJtLT5kZXYsIHJldCwgIkNhbm5vdCBjb25uZWN0IGJyaWRnZVxuIik7CisJfQorCisJ LyogQ29ubmVjdG9yICovCisJZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfYWRkKCZsY2RjLT5jb25uZWN0 b3IsICZpbXhfbGNkY19jb25uZWN0b3JfaGZ1bmNzKTsKKwlkcm1fY29ubmVjdG9yX2luaXQoZHJt LCAmbGNkYy0+Y29ubmVjdG9yLCAmaW14X2xjZGNfY29ubmVjdG9yX2Z1bmNzLAorCQkJICAgRFJN X01PREVfQ09OTkVDVE9SX0RQSSk7CisKKwkvKgorCSAqIFRoZSBMQ0RDIGNvbnRyb2xsZXIgZG9l cyBub3QgaGF2ZSBhbiBlbmFibGUgYml0LiBUaGUKKwkgKiBjb250cm9sbGVyIHN0YXJ0cyBkaXJl Y3RseSB3aGVuIHRoZSBjbG9ja3MgYXJlIGVuYWJsZWQuCisJICogSWYgdGhlIGNsb2NrcyBhcmUg ZW5hYmxlZCB3aGVuIHRoZSBjb250cm9sbGVyIGlzIG5vdCB5ZXQKKwkgKiBwcm9ncmFtbWVkIHdp dGggcHJvcGVyIHJlZ2lzdGVyIHZhbHVlcyAoZW5hYmxlZCBhdCB0aGUKKwkgKiBib290bG9hZGVy LCBmb3IgZXhhbXBsZSkgdGhlbiBpdCBqdXN0IGdvZXMgaW50byBzb21lIHVuZGVmaW5lZAorCSAq IHN0YXRlLgorCSAqIFRvIGF2b2lkIHRoaXMgaXNzdWUsIGxldCdzIGVuYWJsZSBhbmQgZGlzYWJs ZSBMQ0RDIElQRywKKwkgKiBQRVIgYW5kIEFIQiBjbG9jayBzbyB0aGF0IHdlIGZvcmNlIHNvbWUg a2luZCBvZiAncmVzZXQnCisJICogdG8gdGhlIExDREMgYmxvY2suCisJICovCisKKwlyZXQgPSBj bGtfcHJlcGFyZV9lbmFibGUobGNkYy0+Y2xrX2lwZyk7CisJaWYgKHJldCkKKwkJcmV0dXJuIGRl dl9lcnJfcHJvYmUoZGV2LCByZXQsICJDYW5ub3QgZW5hYmxlIGlwZyBjbG9ja1xuIik7CisJY2xr X2Rpc2FibGVfdW5wcmVwYXJlKGxjZGMtPmNsa19pcGcpOworCisJcmV0ID0gY2xrX3ByZXBhcmVf ZW5hYmxlKGxjZGMtPmNsa19wZXIpOworCWlmIChyZXQpCisJCXJldHVybiBkZXZfZXJyX3Byb2Jl KGRldiwgcmV0LCAiQ2Fubm90IGVuYWJsZSBwZXIgY2xvY2tcbiIpOworCWNsa19kaXNhYmxlX3Vu cHJlcGFyZShsY2RjLT5jbGtfcGVyKTsKKworCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShsY2Rj LT5jbGtfYWhiKTsKKwlpZiAocmV0KQorCQlyZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwg IkNhbm5vdCBlbmFibGUgYWhiIGNsb2NrXG4iKTsKKwljbGtfZGlzYWJsZV91bnByZXBhcmUobGNk Yy0+Y2xrX2FoYik7CisKKwlkcm0tPm1vZGVfY29uZmlnLm1pbl93aWR0aCA9IExDRENfTUlOX1hS RVM7CisJZHJtLT5tb2RlX2NvbmZpZy5tYXhfd2lkdGggPSBMQ0RDX01BWF9YUkVTOworCWRybS0+ bW9kZV9jb25maWcubWluX2hlaWdodCA9IExDRENfTUlOX1lSRVM7CisJZHJtLT5tb2RlX2NvbmZp Zy5tYXhfaGVpZ2h0ID0gTENEQ19NQVhfWVJFUzsKKwlkcm0tPm1vZGVfY29uZmlnLnByZWZlcnJl ZF9kZXB0aCA9IDE2OworCWRybS0+bW9kZV9jb25maWcuZnVuY3MgPSAmaW14X2xjZGNfbW9kZV9j b25maWdfZnVuY3M7CisJZHJtLT5tb2RlX2NvbmZpZy5oZWxwZXJfcHJpdmF0ZSA9ICZpbXhfbGNk Y19tb2RlX2NvbmZpZ19oZWxwZXJzOworCisJZHJtX21vZGVfY29uZmlnX3Jlc2V0KGRybSk7CisK KwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOworCWlmIChpcnEgPCAwKSB7CisJCXJl dCA9IGlycTsKKwkJcmV0dXJuIHJldDsKKwl9CisKKwlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKGRl diwgaXJxLCBpcnFfaGFuZGxlciwgMCwgImlteC1sY2RjIiwgbGNkYyk7CisJaWYgKHJldCA8IDAp CisJCXJldHVybiBkZXZfZXJyX3Byb2JlKGRybS0+ZGV2LCByZXQsICJGYWlsZWQgdG8gaW5zdGFs bCBJUlEgaGFuZGxlclxuIik7CisKKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBkcm0pOwor CisJcmV0ID0gZHJtX2Rldl9yZWdpc3RlcigmbGNkYy0+ZHJtLCAwKTsKKwlpZiAocmV0KQorCQly ZXR1cm4gZGV2X2Vycl9wcm9iZShkZXYsIHJldCwgIkNhbm5vdCByZWdpc3RlciBkZXZpY2VcbiIp OworCisJZHJtX2ZiZGV2X2dlbmVyaWNfc2V0dXAoZHJtLCAwKTsKKworCXJldHVybiAwOworfQor CitzdGF0aWMgaW50IGlteF9sY2RjX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2 KQoreworCXN0cnVjdCBpbXhfbGNkYyAqbGNkYyA9IGRybV90b19sY2RjKHBsYXRmb3JtX2dldF9k cnZkYXRhKHBkZXYpKTsKKworCWRybV9kZXZfdW5yZWdpc3RlcigmbGNkYy0+ZHJtKTsKKwlkcm1f YXRvbWljX2hlbHBlcl9zaHV0ZG93bigmbGNkYy0+ZHJtKTsKKworCXJldHVybiAwOworfQorCitz dGF0aWMgdm9pZCBpbXhfbGNkY19zaHV0ZG93bihzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2 KQoreworCWRybV9hdG9taWNfaGVscGVyX3NodXRkb3duKHBsYXRmb3JtX2dldF9kcnZkYXRhKHBk ZXYpKTsKK30KKworc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgaW14X2xjZGNfZHJpdmVy ID0geworCS5kcml2ZXIgPSB7CisJCS5uYW1lID0gImlteC1sY2RjIiwKKwkJLm9mX21hdGNoX3Rh YmxlID0gaW14X2xjZGNfb2ZfZGV2X2lkLAorCX0sCisJLnByb2JlID0gaW14X2xjZGNfcHJvYmUs CisJLnJlbW92ZSA9IGlteF9sY2RjX3JlbW92ZSwKKwkuc2h1dGRvd24gPSBpbXhfbGNkY19zaHV0 ZG93biwKK307Cittb2R1bGVfcGxhdGZvcm1fZHJpdmVyKGlteF9sY2RjX2RyaXZlcik7CisKK01P RFVMRV9BVVRIT1IoIk1hcmlhbiBDaWNoeSA8a2VybmVsQHBlbmd1dHJvbml4LmRlPiIpOworTU9E VUxFX0RFU0NSSVBUSU9OKCJGcmVlc2NhbGUgaS5NWCBMQ0RDIGRyaXZlciIpOworTU9EVUxFX0xJ Q0VOU0UoIkdQTCIpOwotLSAKMi4zNC4xCgoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJt LWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21h aWxtYW4vbGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=