From mboxrd@z Thu Jan 1 00:00:00 1970 From: linus.walleij@linaro.org (Linus Walleij) Date: Sun, 13 Aug 2017 17:11:30 +0200 Subject: [PATCH 2/4] drm/tve200: Add new driver for TVE200 In-Reply-To: <20170813151132.24736-1-linus.walleij@linaro.org> References: <20170813151132.24736-1-linus.walleij@linaro.org> Message-ID: <20170813151132.24736-3-linus.walleij@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org This adds a new DRM driver for the Faraday Technology TVE200 block. This "TV Encoder" encodes a ITU-T BT.656 stream and can be found in the StorLink SL3516 (later Cortina Systems CS3516) as well as the Grain Media GM8180. I do not have definitive word from anyone at Faraday that this IP block is theirs, but it bears the hallmark of their 3-digit version code (200) and is used in two SoCs from completely different companies. (Grain Media was fully owned by Faraday until it was transferred to NovoTek this january, and Faraday did lots of work on the StorLink SoCs.) The D-Link DIR-685 uses this in connection with the Ilitek ILI9322 panel driver that supports BT.656 input, while the GM8180 apparently has been used with the Cirrus Logic CS4954 digital video encoder. The oldest user seems to be something called Techwall 2835. This driver is heavily inspired by Eric Anholt's PL111 driver and therefore I have mentioned all the ancestor authors in the header file. Signed-off-by: Linus Walleij --- Documentation/gpu/index.rst | 1 + Documentation/gpu/tve200.rst | 6 + MAINTAINERS | 6 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/tve200/Kconfig | 15 ++ drivers/gpu/drm/tve200/Makefile | 5 + drivers/gpu/drm/tve200/tve200_connector.c | 126 +++++++++++ drivers/gpu/drm/tve200/tve200_display.c | 346 ++++++++++++++++++++++++++++++ drivers/gpu/drm/tve200/tve200_drm.h | 129 +++++++++++ drivers/gpu/drm/tve200/tve200_drv.c | 277 ++++++++++++++++++++++++ 11 files changed, 914 insertions(+) create mode 100644 Documentation/gpu/tve200.rst create mode 100644 drivers/gpu/drm/tve200/Kconfig create mode 100644 drivers/gpu/drm/tve200/Makefile create mode 100644 drivers/gpu/drm/tve200/tve200_connector.c create mode 100644 drivers/gpu/drm/tve200/tve200_display.c create mode 100644 drivers/gpu/drm/tve200/tve200_drm.h create mode 100644 drivers/gpu/drm/tve200/tve200_drv.c diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index 35d673bf9b56..c36586dad29d 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -15,6 +15,7 @@ Linux GPU Driver Developer's Guide pl111 tegra tinydrm + tve200 vc4 vga-switcheroo vgaarbiter diff --git a/Documentation/gpu/tve200.rst b/Documentation/gpu/tve200.rst new file mode 100644 index 000000000000..69b17b324e12 --- /dev/null +++ b/Documentation/gpu/tve200.rst @@ -0,0 +1,6 @@ +================================== + drm/tve200 Faraday TV Encoder 200 +================================== + +.. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c + :doc: Faraday TV Encoder 200 diff --git a/MAINTAINERS b/MAINTAINERS index e87cba115ea4..c3d42d68253a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4305,6 +4305,12 @@ T: git git://anongit.freedesktop.org/drm/drm-misc S: Maintained F: drivers/gpu/drm/bochs/ +DRM DRIVER FOR FARADAY TVE200 TV ENCODER +M: Linus Walleij +T: git git://anongit.freedesktop.org/drm/drm-misc +S: Maintained +F: drivers/gpu/drm/tve200/ + DRM DRIVER FOR INTEL I810 VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/i810/ diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 83cb2a88c204..c5e1a8409285 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -278,6 +278,8 @@ source "drivers/gpu/drm/tinydrm/Kconfig" source "drivers/gpu/drm/pl111/Kconfig" +source "drivers/gpu/drm/tve200/Kconfig" + # Keep legacy drivers last menuconfig DRM_LEGACY diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 24a066e1841c..cc81813e2238 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -100,3 +100,4 @@ obj-$(CONFIG_DRM_ZTE) += zte/ obj-$(CONFIG_DRM_MXSFB) += mxsfb/ obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ obj-$(CONFIG_DRM_PL111) += pl111/ +obj-$(CONFIG_DRM_TVE200) += tve200/ diff --git a/drivers/gpu/drm/tve200/Kconfig b/drivers/gpu/drm/tve200/Kconfig new file mode 100644 index 000000000000..21d9841ddb88 --- /dev/null +++ b/drivers/gpu/drm/tve200/Kconfig @@ -0,0 +1,15 @@ +config DRM_TVE200 + tristate "DRM Support for Faraday TV Encoder TVE200" + depends on DRM + depends on CMA + depends on ARM || COMPILE_TEST + depends on OF + select DRM_PANEL + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_GEM_CMA_HELPER + select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE + help + Choose this option for DRM support for the Faraday TV Encoder + TVE200 Controller. + If M is selected the module will be called tve200_drm. diff --git a/drivers/gpu/drm/tve200/Makefile b/drivers/gpu/drm/tve200/Makefile new file mode 100644 index 000000000000..a9dba54f7ee5 --- /dev/null +++ b/drivers/gpu/drm/tve200/Makefile @@ -0,0 +1,5 @@ +tve200_drm-y += tve200_connector.o \ + tve200_display.o \ + tve200_drv.o + +obj-$(CONFIG_DRM_TVE200) += tve200_drm.o diff --git a/drivers/gpu/drm/tve200/tve200_connector.c b/drivers/gpu/drm/tve200/tve200_connector.c new file mode 100644 index 000000000000..93e99156d375 --- /dev/null +++ b/drivers/gpu/drm/tve200/tve200_connector.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2017 Linus Walleij + * Parts of this file were based on sources as follows: + * + * Copyright (C) 2006-2008 Intel Corporation + * Copyright (C) 2007 Amos Lee + * Copyright (C) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * Copyright (C) 2017 Eric Anholt + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + */ + +/** + * tve200_drm_connector.c + * Implementation of the connector functions for the Faraday TV Encoder + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "tve200_drm.h" + +static void tve200_connector_destroy(struct drm_connector *connector) +{ + struct tve200_drm_connector *tve200con = + to_tve200_connector(connector); + + if (tve200con->panel) + drm_panel_detach(tve200con->panel); + + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static enum drm_connector_status tve200_connector_detect(struct drm_connector + *connector, bool force) +{ + struct tve200_drm_connector *tve200con = + to_tve200_connector(connector); + + return (tve200con->panel ? + connector_status_connected : + connector_status_disconnected); +} + +static int tve200_connector_helper_get_modes(struct drm_connector *connector) +{ + struct tve200_drm_connector *tve200con = + to_tve200_connector(connector); + + if (!tve200con->panel) + return 0; + + return drm_panel_get_modes(tve200con->panel); +} + +static const struct drm_connector_funcs connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = tve200_connector_destroy, + .detect = tve200_connector_detect, + .dpms = drm_atomic_helper_connector_dpms, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static const struct drm_connector_helper_funcs connector_helper_funcs = { + .get_modes = tve200_connector_helper_get_modes, +}; + +/* + * Walks the OF graph to find the panel node and then asks DRM to look + * up the panel. + */ +static struct drm_panel *tve200_get_panel(struct device *dev) +{ + struct device_node *endpoint, *panel_node; + struct device_node *np = dev->of_node; + struct drm_panel *panel; + + endpoint = of_graph_get_next_endpoint(np, NULL); + if (!endpoint) { + dev_err(dev, "no endpoint to fetch panel\n"); + return NULL; + } + + /* Don't proceed if we have an endpoint but no panel_node tied to it */ + panel_node = of_graph_get_remote_port_parent(endpoint); + of_node_put(endpoint); + if (!panel_node) { + dev_err(dev, "no valid panel node\n"); + return NULL; + } + + panel = of_drm_find_panel(panel_node); + of_node_put(panel_node); + + return panel; +} + +int tve200_connector_init(struct drm_device *dev) +{ + struct tve200_drm_dev_private *priv = dev->dev_private; + struct tve200_drm_connector *tve200con = &priv->connector; + struct drm_connector *connector = &tve200con->connector; + + drm_connector_init(dev, connector, &connector_funcs, + DRM_MODE_CONNECTOR_DPI); + drm_connector_helper_add(connector, &connector_helper_funcs); + + tve200con->panel = tve200_get_panel(dev->dev); + if (tve200con->panel) + drm_panel_attach(tve200con->panel, connector); + + return 0; +} diff --git a/drivers/gpu/drm/tve200/tve200_display.c b/drivers/gpu/drm/tve200/tve200_display.c new file mode 100644 index 000000000000..027553aacb33 --- /dev/null +++ b/drivers/gpu/drm/tve200/tve200_display.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2017 Linus Walleij + * Parts of this file were based on sources as follows: + * + * Copyright (C) 2006-2008 Intel Corporation + * Copyright (C) 2007 Amos Lee + * Copyright (C) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * Copyright (C) 2017 Eric Anholt + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "tve200_drm.h" + +irqreturn_t tve200_irq(int irq, void *data) +{ + struct tve200_drm_dev_private *priv = data; + u32 stat; + u32 val; + + stat = readl(priv->regs + TVE200_INT_STAT); + + if (!stat) + return IRQ_NONE; + + /* + * Vblank IRQ + * + * The hardware is a bit tilted: the line stays high after clearing + * the vblank IRQ, fireing many more interrupts. We counter this + * by toggling the IRQ back and forth from fireing at vblank and + * fireing at start of active image, which works around the problem + * since those occur strictly in sequence, and we get two IRQs for each + * frame, one at start of Vblank (that we make call into the CRTC) and + * another one at the start of the image (that we discard). + */ + if (stat & TVE200_INT_V_STATUS) { + val = readl(priv->regs + TVE200_CTRL); + /* We have an actual start of vsync */ + if (!(val & TVE200_VSTSTYPE_BITS)) { + drm_crtc_handle_vblank(&priv->pipe.crtc); + /* Toggle trigger to start of active image */ + val |= TVE200_VSTSTYPE_VAI; + } else { + /* Toggle trigger back to start of vsync */ + val &= ~TVE200_VSTSTYPE_BITS; + } + writel(val, priv->regs + TVE200_CTRL); + } else + dev_err(priv->drm->dev, "stray IRQ %08x\n", stat); + + /* Clear the interrupt once done */ + writel(stat, priv->regs + TVE200_INT_CLR); + + return IRQ_HANDLED; +} + +static int tve200_display_check(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *pstate, + struct drm_crtc_state *cstate) +{ + const struct drm_display_mode *mode = &cstate->mode; + struct drm_framebuffer *old_fb = pipe->plane.state->fb; + struct drm_framebuffer *fb = pstate->fb; + struct drm_connector *connector = pipe->connector; + struct drm_device *drm = connector->dev; + + /* + * We support these specific resolutions and nothing else. + */ + if (!(mode->hdisplay == 352 && mode->vdisplay == 240) && /* SIF(525) */ + !(mode->hdisplay == 352 && mode->vdisplay == 288) && /* CIF(625) */ + !(mode->hdisplay == 640 && mode->vdisplay == 480) && /* VGA */ + !(mode->hdisplay == 720 && mode->vdisplay == 480) && /* D1 */ + !(mode->hdisplay == 720 && mode->vdisplay == 576)) { /* D1 */ + dev_err(drm->dev, "unsupported display mode (%u x %u)\n", + mode->hdisplay, mode->vdisplay); + return -EINVAL; + } + + if (fb) { + u32 offset = drm_fb_cma_get_gem_addr(fb, pstate, 0); + + /* FB base address must be dword aligned. */ + if (offset & 3) { + dev_err(drm->dev, "FB not 32-bit aligned\n"); + return -EINVAL; + } + + /* + * There's no pitch register, the mode's hdisplay + * controls this. + */ + if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) { + dev_err(drm->dev, "can't handle pitches\n"); + return -EINVAL; + } + + /* + * We can't change the FB format in a flicker-free + * manner (and only update it during CRTC enable). + */ + if (old_fb && old_fb->format != fb->format) + cstate->mode_changed = true; + } + + return 0; +} + +static void tve200_display_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *cstate) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct drm_plane *plane = &pipe->plane; + struct drm_device *drm = crtc->dev; + struct tve200_drm_dev_private *priv = drm->dev_private; + const struct drm_display_mode *mode = &cstate->mode; + struct drm_framebuffer *fb = plane->state->fb; + struct drm_connector *connector = &priv->connector.connector; + u32 format = fb->format->format; + u32 ctrl1 = 0; + + clk_prepare_enable(priv->clk); + + /* Function 1 */ + ctrl1 |= TVE200_CTRL_CSMODE; + /* Interlace mode for CCIR656: parameterize? */ + ctrl1 |= TVE200_CTRL_NONINTERLACE; + /* 32 words per burst */ + ctrl1 |= TVE200_CTRL_BURST_32_WORDS; + /* 16 retries */ + ctrl1 |= TVE200_CTRL_RETRYCNT_16; + /* NTSC mode: parametrize? */ + ctrl1 |= TVE200_CTRL_NTSC; + + /* Vsync IRQ at start of Vsync at first */ + ctrl1 |= TVE200_VSTSTYPE_VSYNC; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_NEGEDGE) + ctrl1 |= TVE200_CTRL_TVCLKP; + + if ((mode->hdisplay == 352 && mode->vdisplay == 240) || /* SIF(525) */ + (mode->hdisplay == 352 && mode->vdisplay == 288)) { /* CIF(625) */ + ctrl1 |= TVE200_CTRL_IPRESOL_CIF; + dev_info(drm->dev, "CIF mode\n"); + } else if (mode->hdisplay == 640 && mode->vdisplay == 480) { + ctrl1 |= TVE200_CTRL_IPRESOL_VGA; + dev_info(drm->dev, "VGA mode\n"); + } else if ((mode->hdisplay == 720 && mode->vdisplay == 480) || + (mode->hdisplay == 720 && mode->vdisplay == 576)) { + ctrl1 |= TVE200_CTRL_IPRESOL_D1; + dev_info(drm->dev, "D1 mode\n"); + } + + if (format & DRM_FORMAT_BIG_ENDIAN) { + ctrl1 |= TVE200_CTRL_BBBP; + format &= ~DRM_FORMAT_BIG_ENDIAN; + } + + switch (format) { + case DRM_FORMAT_XRGB8888: + ctrl1 |= TVE200_IPDMOD_RGB888; + break; + case DRM_FORMAT_RGB565: + ctrl1 |= TVE200_IPDMOD_RGB565; + break; + case DRM_FORMAT_XRGB1555: + ctrl1 |= TVE200_IPDMOD_RGB555; + break; + case DRM_FORMAT_XBGR8888: + ctrl1 |= TVE200_IPDMOD_RGB888 | TVE200_BGR; + break; + case DRM_FORMAT_BGR565: + ctrl1 |= TVE200_IPDMOD_RGB565 | TVE200_BGR; + break; + case DRM_FORMAT_XBGR1555: + ctrl1 |= TVE200_IPDMOD_RGB555 | TVE200_BGR; + break; + case DRM_FORMAT_YUYV: + ctrl1 |= TVE200_IPDMOD_YUV422; + ctrl1 |= TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0; + break; + case DRM_FORMAT_YVYU: + ctrl1 |= TVE200_IPDMOD_YUV422; + ctrl1 |= TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0; + break; + case DRM_FORMAT_UYVY: + ctrl1 |= TVE200_IPDMOD_YUV422; + ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0; + break; + case DRM_FORMAT_VYUY: + ctrl1 |= TVE200_IPDMOD_YUV422; + ctrl1 |= TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0; + break; + case DRM_FORMAT_YUV420: + ctrl1 |= TVE200_CTRL_YUV420; + ctrl1 |= TVE200_IPDMOD_YUV420; + break; + default: + dev_err(drm->dev, "Unknown FB format 0x%08x\n", + fb->format->format); + break; + } + + ctrl1 |= TVE200_TVEEN; + + drm_panel_prepare(priv->connector.panel); + + /* Turn it on */ + writel(ctrl1, priv->regs + TVE200_CTRL); + + drm_panel_enable(priv->connector.panel); + + drm_crtc_vblank_on(crtc); +} + +void tve200_display_disable(struct drm_simple_display_pipe *pipe) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct drm_device *drm = crtc->dev; + struct tve200_drm_dev_private *priv = drm->dev_private; + + drm_crtc_vblank_off(crtc); + + drm_panel_disable(priv->connector.panel); + + /* Disable and Power Down */ + writel(0, priv->regs + TVE200_CTRL); + + drm_panel_unprepare(priv->connector.panel); + + clk_disable_unprepare(priv->clk); +} + +static void tve200_display_update(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *old_pstate) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct drm_device *drm = crtc->dev; + struct tve200_drm_dev_private *priv = drm->dev_private; + struct drm_pending_vblank_event *event = crtc->state->event; + struct drm_plane *plane = &pipe->plane; + struct drm_plane_state *pstate = plane->state; + struct drm_framebuffer *fb = pstate->fb; + + if (fb) { + /* For RGB, the Y component is used as base address */ + writel(drm_fb_cma_get_gem_addr(fb, pstate, 0), + priv->regs + TVE200_Y_FRAME_BASE_ADDR); + + /* For three plane YUV we need two more addresses */ + if (fb->format->format == DRM_FORMAT_YUV420) { + writel(drm_fb_cma_get_gem_addr(fb, pstate, 1), + priv->regs + TVE200_U_FRAME_BASE_ADDR); + writel(drm_fb_cma_get_gem_addr(fb, pstate, 2), + priv->regs + TVE200_V_FRAME_BASE_ADDR); + } + } + + 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); + } +} + +int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc) +{ + struct tve200_drm_dev_private *priv = drm->dev_private; + + writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN); + return 0; +} + +void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc) +{ + struct tve200_drm_dev_private *priv = drm->dev_private; + + writel(0, priv->regs + TVE200_INT_EN); +} + +static int tve200_display_prepare_fb(struct drm_simple_display_pipe *pipe, + struct drm_plane_state *plane_state) +{ + return drm_fb_cma_prepare_fb(&pipe->plane, plane_state); +} + +const struct drm_simple_display_pipe_funcs tve200_display_funcs = { + .check = tve200_display_check, + .enable = tve200_display_enable, + .disable = tve200_display_disable, + .update = tve200_display_update, + .prepare_fb = tve200_display_prepare_fb, +}; + +int tve200_display_init(struct drm_device *drm) +{ + struct tve200_drm_dev_private *priv = drm->dev_private; + int ret; + static const u32 formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_XBGR1555, + /* + * The controller actually supports any YCbCr ordering, + * for packed YCbCr. This just lists the orderings that + * DRM supports. + */ + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_UYVY, + DRM_FORMAT_VYUY, + /* This uses three planes */ + DRM_FORMAT_YUV420, + }; + + ret = drm_simple_display_pipe_init(drm, &priv->pipe, + &tve200_display_funcs, + formats, ARRAY_SIZE(formats), + &priv->connector.connector); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/gpu/drm/tve200/tve200_drm.h b/drivers/gpu/drm/tve200/tve200_drm.h new file mode 100644 index 000000000000..f00fc47a6bd1 --- /dev/null +++ b/drivers/gpu/drm/tve200/tve200_drm.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2017 Linus Walleij + * Parts of this file were based on sources as follows: + * + * Copyright (C) 2006-2008 Intel Corporation + * Copyright (C) 2007 Amos Lee + * Copyright (C) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * Copyright (C) 2017 Eric Anholt + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + */ + +#ifndef _TVE200_DRM_H_ +#define _TVE200_DRM_H_ + +/* Bits 2-31 are valid physical base addresses */ +#define TVE200_Y_FRAME_BASE_ADDR 0x00 +#define TVE200_U_FRAME_BASE_ADDR 0x04 +#define TVE200_V_FRAME_BASE_ADDR 0x08 + +#define TVE200_INT_EN 0x0C +#define TVE200_INT_CLR 0x10 +#define TVE200_INT_STAT 0x14 +#define TVE200_INT_BUS_ERR BIT(7) +#define TVE200_INT_V_STATUS BIT(6) /* vertical blank */ +#define TVE200_INT_V_NEXT_FRAME BIT(5) +#define TVE200_INT_U_NEXT_FRAME BIT(4) +#define TVE200_INT_Y_NEXT_FRAME BIT(3) +#define TVE200_INT_V_FIFO_UNDERRUN BIT(2) +#define TVE200_INT_U_FIFO_UNDERRUN BIT(1) +#define TVE200_INT_Y_FIFO_UNDERRUN BIT(0) +#define TVE200_FIFO_UNDERRUNS (TVE200_INT_V_FIFO_UNDERRUN | \ + TVE200_INT_U_FIFO_UNDERRUN | \ + TVE200_INT_Y_FIFO_UNDERRUN) + +#define TVE200_CTRL 0x18 +#define TVE200_CTRL_YUV420 BIT(31) +#define TVE200_CTRL_CSMODE BIT(30) +#define TVE200_CTRL_NONINTERLACE BIT(28) /* 0 = non-interlace CCIR656 */ +#define TVE200_CTRL_TVCLKP BIT(27) /* Inverted clock phase */ +/* Bits 24..26 define the burst size after arbitration on the bus */ +#define TVE200_CTRL_BURST_4_WORDS (0 << 24) +#define TVE200_CTRL_BURST_8_WORDS (1 << 24) +#define TVE200_CTRL_BURST_16_WORDS (2 << 24) +#define TVE200_CTRL_BURST_32_WORDS (3 << 24) +#define TVE200_CTRL_BURST_64_WORDS (4 << 24) +#define TVE200_CTRL_BURST_128_WORDS (5 << 24) +#define TVE200_CTRL_BURST_256_WORDS (6 << 24) +#define TVE200_CTRL_BURST_0_WORDS (7 << 24) /* ? */ +/* + * Bits 16..23 is the retry count*16 before issueing a new AHB transfer + * on the AHB bus. + */ +#define TVE200_CTRL_RETRYCNT_MASK GENMASK(23, 16) +#define TVE200_CTRL_RETRYCNT_16 (1 << 16) +#define TVE200_CTRL_BBBP BIT(15) /* 0 = little-endian */ +/* Bits 12..14 define the YCbCr ordering */ +#define TVE200_CTRL_YCBCRODR_CB0Y0CR0Y1 (0 << 12) +#define TVE200_CTRL_YCBCRODR_Y0CB0Y1CR0 (1 << 12) +#define TVE200_CTRL_YCBCRODR_CR0Y0CB0Y1 (2 << 12) +#define TVE200_CTRL_YCBCRODR_Y1CB0Y0CR0 (3 << 12) +#define TVE200_CTRL_YCBCRODR_CR0Y1CB0Y0 (4 << 12) +#define TVE200_CTRL_YCBCRODR_Y1CR0Y0CB0 (5 << 12) +#define TVE200_CTRL_YCBCRODR_CB0Y1CR0Y0 (6 << 12) +#define TVE200_CTRL_YCBCRODR_Y0CR0Y1CB0 (7 << 12) +/* Bits 10..11 define the input resolution (framebuffer size) */ +#define TVE200_CTRL_IPRESOL_CIF (0 << 10) +#define TVE200_CTRL_IPRESOL_VGA (1 << 10) +#define TVE200_CTRL_IPRESOL_D1 (2 << 10) +#define TVE200_CTRL_NTSC BIT(9) /* 0 = PAL, 1 = NTSC */ +#define TVE200_CTRL_INTERLACE BIT(8) /* 1 = interlace, only for D1 */ +#define TVE200_IPDMOD_RGB555 (0 << 6) /* TVE200_CTRL_YUV420 = 0 */ +#define TVE200_IPDMOD_RGB565 (1 << 6) +#define TVE200_IPDMOD_RGB888 (2 << 6) +#define TVE200_IPDMOD_YUV420 (2 << 6) /* TVE200_CTRL_YUV420 = 1 */ +#define TVE200_IPDMOD_YUV422 (3 << 6) +/* Bits 4 & 5 define when to fire the vblank IRQ */ +#define TVE200_VSTSTYPE_VSYNC (0 << 4) /* start of vsync */ +#define TVE200_VSTSTYPE_VBP (1 << 4) /* start of v back porch */ +#define TVE200_VSTSTYPE_VAI (2 << 4) /* start of v active image */ +#define TVE200_VSTSTYPE_VFP (3 << 4) /* start of v front porch */ +#define TVE200_VSTSTYPE_BITS (BIT(4) | BIT(5)) +#define TVE200_BGR BIT(1) /* 0 = RGB, 1 = BGR */ +#define TVE200_TVEEN BIT(0) /* Enable TVE block */ + +#define TVE200_CTRL_2 0x1c +#define TVE200_CTRL_3 0x20 + +#define TVE200_CTRL_4 0x24 +#define TVE200_CTRL_4_RESET BIT(0) /* triggers reset of TVE200 */ + +#include +#include + +struct tve200_drm_connector { + struct drm_connector connector; + struct drm_panel *panel; +}; + +struct tve200_drm_dev_private { + struct drm_device *drm; + + struct tve200_drm_connector connector; + struct drm_simple_display_pipe pipe; + struct drm_fbdev_cma *fbdev; + + void *regs; + struct clk *pclk; + struct clk *clk; +}; + +#define to_tve200_connector(x) \ + container_of(x, struct tve200_drm_connector, connector) + +int tve200_display_init(struct drm_device *dev); +int tve200_enable_vblank(struct drm_device *drm, unsigned int crtc); +void tve200_disable_vblank(struct drm_device *drm, unsigned int crtc); +irqreturn_t tve200_irq(int irq, void *data); +int tve200_connector_init(struct drm_device *dev); +int tve200_encoder_init(struct drm_device *dev); +int tve200_dumb_create(struct drm_file *file_priv, + struct drm_device *dev, + struct drm_mode_create_dumb *args); + +#endif /* _TVE200_DRM_H_ */ diff --git a/drivers/gpu/drm/tve200/tve200_drv.c b/drivers/gpu/drm/tve200/tve200_drv.c new file mode 100644 index 000000000000..9e34147e2617 --- /dev/null +++ b/drivers/gpu/drm/tve200/tve200_drv.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2017 Linus Walleij + * Parts of this file were based on sources as follows: + * + * Copyright (C) 2006-2008 Intel Corporation + * Copyright (C) 2007 Amos Lee + * Copyright (C) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * Copyright (C) 2017 Eric Anholt + * + * This program is free software and is provided to you under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation, and any use by you of this program is subject to the terms of + * such GNU licence. + */ + +/** + * DOC: Faraday TV Encoder TVE200 DRM Driver + * + * The Faraday TV Encoder TVE200 is also known as the Gemini TV Interface + * Controller (TVC) and is found in the Gemini Chipset from Storlink + * Semiconductor (later Storm Semiconductor, later Cortina Systems) + * but also in the Grain Media GM8180 chipset. On the Gemini the module + * is connected to 8 data lines and a single clock line, comprising an + * 8-bit BT.656 interface. + * + * This is a very basic YUV display driver. The datasheet specifies that + * it supports the ITU BT.656 standard. It requires a 27 MHz clock which is + * the hallmark of any TV encoder supporting both PAL and NTSC. + * + * This driver exposes a standard KMS interface for this TV encoder. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "tve200_drm.h" + +#define DRIVER_DESC "DRM module for Faraday TVE200" + +struct drm_mode_config_funcs mode_config_funcs = { + .fb_create = drm_fb_cma_create, + .atomic_check = drm_atomic_helper_check, + .atomic_commit = drm_atomic_helper_commit, +}; + +static int tve200_modeset_init(struct drm_device *dev) +{ + struct drm_mode_config *mode_config; + struct tve200_drm_dev_private *priv = dev->dev_private; + int ret = 0; + + drm_mode_config_init(dev); + mode_config = &dev->mode_config; + mode_config->funcs = &mode_config_funcs; + mode_config->min_width = 352; + mode_config->max_width = 720; + mode_config->min_height = 240; + mode_config->max_height = 576; + + ret = tve200_connector_init(dev); + if (ret) { + dev_err(dev->dev, "Failed to create tve200_drm_connector\n"); + goto out_config; + } + + /* + * Don't actually attach if we didn't find a drm_panel + * attached to us. + */ + if (!priv->connector.panel) { + dev_info(dev->dev, + "deferring due to lack of DRM panel device\n"); + ret = -EPROBE_DEFER; + goto out_config; + } + dev_info(dev->dev, "attached to panel %s\n", + dev_name(priv->connector.panel->dev)); + + ret = tve200_display_init(dev); + if (ret) { + dev_err(dev->dev, "failed to init display\n"); + goto out_config; + } + + ret = drm_vblank_init(dev, 1); + if (ret) { + dev_err(dev->dev, "failed to init vblank\n"); + goto out_config; + } + + drm_mode_config_reset(dev); + + /* + * Passing in 16 here will make the RGB656 mode the default + * Passing in 32 will use XRGB8888 mode + */ + priv->fbdev = drm_fbdev_cma_init(dev, 16, + dev->mode_config.num_connector); + drm_kms_helper_poll_init(dev); + + goto finish; + +out_config: + drm_mode_config_cleanup(dev); +finish: + return ret; +} + +DEFINE_DRM_GEM_CMA_FOPS(drm_fops); + +static void tve200_lastclose(struct drm_device *dev) +{ + struct tve200_drm_dev_private *priv = dev->dev_private; + + drm_fbdev_cma_restore_mode(priv->fbdev); +} + +static struct drm_driver tve200_drm_driver = { + .driver_features = + DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, + .lastclose = tve200_lastclose, + .ioctls = NULL, + .fops = &drm_fops, + .name = "tve200", + .desc = DRIVER_DESC, + .date = "20170703", + .major = 1, + .minor = 0, + .patchlevel = 0, + .dumb_create = drm_gem_cma_dumb_create, + .dumb_destroy = drm_gem_dumb_destroy, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .gem_free_object = drm_gem_cma_free_object, + .gem_vm_ops = &drm_gem_cma_vm_ops, + + .enable_vblank = tve200_enable_vblank, + .disable_vblank = tve200_disable_vblank, + + .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import = drm_gem_prime_import, + .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, + .gem_prime_export = drm_gem_prime_export, + .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, +}; + +static int tve200_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tve200_drm_dev_private *priv; + struct drm_device *drm; + struct resource *res; + int irq; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + drm = drm_dev_alloc(&tve200_drm_driver, dev); + if (IS_ERR(drm)) + return PTR_ERR(drm); + platform_set_drvdata(pdev, drm); + priv->drm = drm; + drm->dev_private = priv; + + /* Clock the silicon so we can access the registers */ + priv->pclk = devm_clk_get(dev, "PCLK"); + if (IS_ERR(priv->pclk)) { + dev_err(dev, "unable to get PCLK\n"); + ret = PTR_ERR(priv->pclk); + goto dev_unref; + } + ret = clk_prepare_enable(priv->pclk); + if (ret) { + dev_err(dev, "failed to enable PCLK\n"); + goto dev_unref; + } + + /* This clock is for the pixels (27MHz) */ + priv->clk = devm_clk_get(dev, "TVE"); + if (IS_ERR(priv->clk)) { + dev_err(dev, "unable to get TVE clock\n"); + ret = PTR_ERR(priv->clk); + goto clk_disable; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + priv->regs = devm_ioremap_resource(dev, res); + if (!priv->regs) { + dev_err(dev, "%s failed mmio\n", __func__); + ret = -EINVAL; + goto dev_unref; + } + + irq = platform_get_irq(pdev, 0); + if (!irq) { + ret = -EINVAL; + goto dev_unref; + } + + /* turn off interrupts before requesting the irq */ + writel(0, priv->regs + TVE200_INT_EN); + + ret = devm_request_irq(dev, irq, tve200_irq, 0, "tve200", priv); + if (ret) { + dev_err(dev, "failed to request irq %d\n", ret); + return ret; + } + + ret = tve200_modeset_init(drm); + if (ret) + goto dev_unref; + + ret = drm_dev_register(drm, 0); + if (ret < 0) + goto dev_unref; + + return 0; + +clk_disable: + clk_disable_unprepare(priv->pclk); +dev_unref: + drm_dev_unref(drm); + return ret; +} + +static int tve200_remove(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + struct tve200_drm_dev_private *priv = drm->dev_private; + + drm_dev_unregister(drm); + if (priv->fbdev) + drm_fbdev_cma_fini(priv->fbdev); + drm_mode_config_cleanup(drm); + clk_disable_unprepare(priv->pclk); + drm_dev_unref(drm); + + return 0; +} + +static const struct of_device_id tve200_of_match[] = { + { + .compatible = "faraday,tve200", + }, + {}, +}; + +static struct platform_driver tve200_driver = { + .driver = { + .name = "tve200", + .of_match_table = of_match_ptr(tve200_of_match), + }, + .probe = tve200_probe, + .remove = tve200_remove, +}; +module_platform_driver(tve200_driver); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Linus Walleij "); +MODULE_LICENSE("GPL"); -- 2.13.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Linus Walleij Subject: [PATCH 2/4] drm/tve200: Add new driver for TVE200 Date: Sun, 13 Aug 2017 17:11:30 +0200 Message-ID: <20170813151132.24736-3-linus.walleij@linaro.org> References: <20170813151132.24736-1-linus.walleij@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-lf0-x229.google.com (mail-lf0-x229.google.com [IPv6:2a00:1450:4010:c07::229]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4DD5B6E058 for ; Sun, 13 Aug 2017 15:12:00 +0000 (UTC) Received: by mail-lf0-x229.google.com with SMTP id y15so31328910lfd.5 for ; Sun, 13 Aug 2017 08:12:00 -0700 (PDT) In-Reply-To: <20170813151132.24736-1-linus.walleij@linaro.org> 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, Eric Anholt , Daniel Vetter , Jani Nikula , Sean Paul Cc: linux-arm-kernel@lists.infradead.org List-Id: dri-devel@lists.freedesktop.org VGhpcyBhZGRzIGEgbmV3IERSTSBkcml2ZXIgZm9yIHRoZSBGYXJhZGF5IFRlY2hub2xvZ3kgVFZF MjAwCmJsb2NrLiBUaGlzICJUViBFbmNvZGVyIiBlbmNvZGVzIGEgSVRVLVQgQlQuNjU2IHN0cmVh bSBhbmQgY2FuCmJlIGZvdW5kIGluIHRoZSBTdG9yTGluayBTTDM1MTYgKGxhdGVyIENvcnRpbmEg U3lzdGVtcyBDUzM1MTYpCmFzIHdlbGwgYXMgdGhlIEdyYWluIE1lZGlhIEdNODE4MC4KCkkgZG8g bm90IGhhdmUgZGVmaW5pdGl2ZSB3b3JkIGZyb20gYW55b25lIGF0IEZhcmFkYXkgdGhhdCB0aGlz CklQIGJsb2NrIGlzIHRoZWlycywgYnV0IGl0IGJlYXJzIHRoZSBoYWxsbWFyayBvZiB0aGVpciAz LWRpZ2l0CnZlcnNpb24gY29kZSAoMjAwKSBhbmQgaXMgdXNlZCBpbiB0d28gU29DcyBmcm9tIGNv bXBsZXRlbHkKZGlmZmVyZW50IGNvbXBhbmllcy4gKEdyYWluIE1lZGlhIHdhcyBmdWxseSBvd25l ZCBieSBGYXJhZGF5CnVudGlsIGl0IHdhcyB0cmFuc2ZlcnJlZCB0byBOb3ZvVGVrIHRoaXMgamFu dWFyeSwgYW5kCkZhcmFkYXkgZGlkIGxvdHMgb2Ygd29yayBvbiB0aGUgU3RvckxpbmsgU29Dcy4p CgpUaGUgRC1MaW5rIERJUi02ODUgdXNlcyB0aGlzIGluIGNvbm5lY3Rpb24gd2l0aCB0aGUgSWxp dGVrCklMSTkzMjIgcGFuZWwgZHJpdmVyIHRoYXQgc3VwcG9ydHMgQlQuNjU2IGlucHV0LCB3aGls ZSB0aGUKR004MTgwIGFwcGFyZW50bHkgaGFzIGJlZW4gdXNlZCB3aXRoIHRoZSBDaXJydXMgTG9n aWMgQ1M0OTU0CmRpZ2l0YWwgdmlkZW8gZW5jb2Rlci4gVGhlIG9sZGVzdCB1c2VyIHNlZW1zIHRv IGJlCnNvbWV0aGluZyBjYWxsZWQgVGVjaHdhbGwgMjgzNS4KClRoaXMgZHJpdmVyIGlzIGhlYXZp bHkgaW5zcGlyZWQgYnkgRXJpYyBBbmhvbHQncyBQTDExMQpkcml2ZXIgYW5kIHRoZXJlZm9yZSBJ IGhhdmUgbWVudGlvbmVkIGFsbCB0aGUgYW5jZXN0b3IgYXV0aG9ycwppbiB0aGUgaGVhZGVyIGZp bGUuCgpTaWduZWQtb2ZmLWJ5OiBMaW51cyBXYWxsZWlqIDxsaW51cy53YWxsZWlqQGxpbmFyby5v cmc+Ci0tLQogRG9jdW1lbnRhdGlvbi9ncHUvaW5kZXgucnN0ICAgICAgICAgICAgICAgfCAgIDEg KwogRG9jdW1lbnRhdGlvbi9ncHUvdHZlMjAwLnJzdCAgICAgICAgICAgICAgfCAgIDYgKwogTUFJ TlRBSU5FUlMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDYgKwogZHJpdmVycy9n cHUvZHJtL0tjb25maWcgICAgICAgICAgICAgICAgICAgfCAgIDIgKwogZHJpdmVycy9ncHUvZHJt L01ha2VmaWxlICAgICAgICAgICAgICAgICAgfCAgIDEgKwogZHJpdmVycy9ncHUvZHJtL3R2ZTIw MC9LY29uZmlnICAgICAgICAgICAgfCAgMTUgKysKIGRyaXZlcnMvZ3B1L2RybS90dmUyMDAvTWFr ZWZpbGUgICAgICAgICAgIHwgICA1ICsKIGRyaXZlcnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2Nv bm5lY3Rvci5jIHwgMTI2ICsrKysrKysrKysrCiBkcml2ZXJzL2dwdS9kcm0vdHZlMjAwL3R2ZTIw MF9kaXNwbGF5LmMgICB8IDM0NiArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysKIGRyaXZl cnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2RybS5oICAgICAgIHwgMTI5ICsrKysrKysrKysrCiBk cml2ZXJzL2dwdS9kcm0vdHZlMjAwL3R2ZTIwMF9kcnYuYyAgICAgICB8IDI3NyArKysrKysrKysr KysrKysrKysrKysrKysKIDExIGZpbGVzIGNoYW5nZWQsIDkxNCBpbnNlcnRpb25zKCspCiBjcmVh dGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9ncHUvdHZlMjAwLnJzdAogY3JlYXRlIG1vZGUg MTAwNjQ0IGRyaXZlcnMvZ3B1L2RybS90dmUyMDAvS2NvbmZpZwogY3JlYXRlIG1vZGUgMTAwNjQ0 IGRyaXZlcnMvZ3B1L2RybS90dmUyMDAvTWFrZWZpbGUKIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2 ZXJzL2dwdS9kcm0vdHZlMjAwL3R2ZTIwMF9jb25uZWN0b3IuYwogY3JlYXRlIG1vZGUgMTAwNjQ0 IGRyaXZlcnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2Rpc3BsYXkuYwogY3JlYXRlIG1vZGUgMTAw NjQ0IGRyaXZlcnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2RybS5oCiBjcmVhdGUgbW9kZSAxMDA2 NDQgZHJpdmVycy9ncHUvZHJtL3R2ZTIwMC90dmUyMDBfZHJ2LmMKCmRpZmYgLS1naXQgYS9Eb2N1 bWVudGF0aW9uL2dwdS9pbmRleC5yc3QgYi9Eb2N1bWVudGF0aW9uL2dwdS9pbmRleC5yc3QKaW5k ZXggMzVkNjczYmY5YjU2Li5jMzY1ODZkYWQyOWQgMTAwNjQ0Ci0tLSBhL0RvY3VtZW50YXRpb24v Z3B1L2luZGV4LnJzdAorKysgYi9Eb2N1bWVudGF0aW9uL2dwdS9pbmRleC5yc3QKQEAgLTE1LDYg KzE1LDcgQEAgTGludXggR1BVIERyaXZlciBEZXZlbG9wZXIncyBHdWlkZQogICAgcGwxMTEKICAg IHRlZ3JhCiAgICB0aW55ZHJtCisgICB0dmUyMDAKICAgIHZjNAogICAgdmdhLXN3aXRjaGVyb28K ICAgIHZnYWFyYml0ZXIKZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vZ3B1L3R2ZTIwMC5yc3Qg Yi9Eb2N1bWVudGF0aW9uL2dwdS90dmUyMDAucnN0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAwMDAwMC4uNjliMTdiMzI0ZTEyCi0tLSAvZGV2L251bGwKKysrIGIvRG9jdW1lbnRh dGlvbi9ncHUvdHZlMjAwLnJzdApAQCAtMCwwICsxLDYgQEAKKz09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT0KKyBkcm0vdHZlMjAwIEZhcmFkYXkgVFYgRW5jb2RlciAyMDAKKz09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLi4ga2VybmVsLWRvYzo6IGRyaXZlcnMv Z3B1L2RybS90dmUyMDAvdHZlMjAwX2Rydi5jCisgICA6ZG9jOiBGYXJhZGF5IFRWIEVuY29kZXIg MjAwCmRpZmYgLS1naXQgYS9NQUlOVEFJTkVSUyBiL01BSU5UQUlORVJTCmluZGV4IGU4N2NiYTEx NWVhNC4uYzNkNDJkNjgyNTNhIDEwMDY0NAotLS0gYS9NQUlOVEFJTkVSUworKysgYi9NQUlOVEFJ TkVSUwpAQCAtNDMwNSw2ICs0MzA1LDEyIEBAIFQ6CWdpdCBnaXQ6Ly9hbm9uZ2l0LmZyZWVkZXNr dG9wLm9yZy9kcm0vZHJtLW1pc2MKIFM6CU1haW50YWluZWQKIEY6CWRyaXZlcnMvZ3B1L2RybS9i b2Nocy8KIAorRFJNIERSSVZFUiBGT1IgRkFSQURBWSBUVkUyMDAgVFYgRU5DT0RFUgorTToJTGlu dXMgV2FsbGVpaiA8bGludXMud2FsbGVpakBsaW5hcm8ub3JnPgorVDoJZ2l0IGdpdDovL2Fub25n aXQuZnJlZWRlc2t0b3Aub3JnL2RybS9kcm0tbWlzYworUzoJTWFpbnRhaW5lZAorRjoJZHJpdmVy cy9ncHUvZHJtL3R2ZTIwMC8KKwogRFJNIERSSVZFUiBGT1IgSU5URUwgSTgxMCBWSURFTyBDQVJE UwogUzoJT3JwaGFuIC8gT2Jzb2xldGUKIEY6CWRyaXZlcnMvZ3B1L2RybS9pODEwLwpkaWZmIC0t Z2l0IGEvZHJpdmVycy9ncHUvZHJtL0tjb25maWcgYi9kcml2ZXJzL2dwdS9kcm0vS2NvbmZpZwpp bmRleCA4M2NiMmE4OGMyMDQuLmM1ZTFhODQwOTI4NSAxMDA2NDQKLS0tIGEvZHJpdmVycy9ncHUv ZHJtL0tjb25maWcKKysrIGIvZHJpdmVycy9ncHUvZHJtL0tjb25maWcKQEAgLTI3OCw2ICsyNzgs OCBAQCBzb3VyY2UgImRyaXZlcnMvZ3B1L2RybS90aW55ZHJtL0tjb25maWciCiAKIHNvdXJjZSAi ZHJpdmVycy9ncHUvZHJtL3BsMTExL0tjb25maWciCiAKK3NvdXJjZSAiZHJpdmVycy9ncHUvZHJt L3R2ZTIwMC9LY29uZmlnIgorCiAjIEtlZXAgbGVnYWN5IGRyaXZlcnMgbGFzdAogCiBtZW51Y29u ZmlnIERSTV9MRUdBQ1kKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9NYWtlZmlsZSBiL2Ry aXZlcnMvZ3B1L2RybS9NYWtlZmlsZQppbmRleCAyNGEwNjZlMTg0MWMuLmNjODE4MTNlMjIzOCAx MDA2NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL01ha2VmaWxlCisrKyBiL2RyaXZlcnMvZ3B1L2Ry bS9NYWtlZmlsZQpAQCAtMTAwLDMgKzEwMCw0IEBAIG9iai0kKENPTkZJR19EUk1fWlRFKQkrPSB6 dGUvCiBvYmotJChDT05GSUdfRFJNX01YU0ZCKQkrPSBteHNmYi8KIG9iai0kKENPTkZJR19EUk1f VElOWURSTSkgKz0gdGlueWRybS8KIG9iai0kKENPTkZJR19EUk1fUEwxMTEpICs9IHBsMTExLwor b2JqLSQoQ09ORklHX0RSTV9UVkUyMDApICs9IHR2ZTIwMC8KZGlmZiAtLWdpdCBhL2RyaXZlcnMv Z3B1L2RybS90dmUyMDAvS2NvbmZpZyBiL2RyaXZlcnMvZ3B1L2RybS90dmUyMDAvS2NvbmZpZwpu ZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLjIxZDk4NDFkZGI4OAotLS0g L2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZ3B1L2RybS90dmUyMDAvS2NvbmZpZwpAQCAtMCwwICsx LDE1IEBACitjb25maWcgRFJNX1RWRTIwMAorCXRyaXN0YXRlICJEUk0gU3VwcG9ydCBmb3IgRmFy YWRheSBUViBFbmNvZGVyIFRWRTIwMCIKKwlkZXBlbmRzIG9uIERSTQorCWRlcGVuZHMgb24gQ01B CisJZGVwZW5kcyBvbiBBUk0gfHwgQ09NUElMRV9URVNUCisJZGVwZW5kcyBvbiBPRgorCXNlbGVj dCBEUk1fUEFORUwKKwlzZWxlY3QgRFJNX0tNU19IRUxQRVIKKwlzZWxlY3QgRFJNX0tNU19DTUFf SEVMUEVSCisJc2VsZWN0IERSTV9HRU1fQ01BX0hFTFBFUgorCXNlbGVjdCBWVF9IV19DT05TT0xF X0JJTkRJTkcgaWYgRlJBTUVCVUZGRVJfQ09OU09MRQorCWhlbHAKKwkgIENob29zZSB0aGlzIG9w dGlvbiBmb3IgRFJNIHN1cHBvcnQgZm9yIHRoZSBGYXJhZGF5IFRWIEVuY29kZXIKKwkgIFRWRTIw MCBDb250cm9sbGVyLgorCSAgSWYgTSBpcyBzZWxlY3RlZCB0aGUgbW9kdWxlIHdpbGwgYmUgY2Fs bGVkIHR2ZTIwMF9kcm0uCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdHZlMjAwL01ha2Vm aWxlIGIvZHJpdmVycy9ncHUvZHJtL3R2ZTIwMC9NYWtlZmlsZQpuZXcgZmlsZSBtb2RlIDEwMDY0 NAppbmRleCAwMDAwMDAwMDAwMDAuLmE5ZGJhNTRmN2VlNQotLS0gL2Rldi9udWxsCisrKyBiL2Ry aXZlcnMvZ3B1L2RybS90dmUyMDAvTWFrZWZpbGUKQEAgLTAsMCArMSw1IEBACit0dmUyMDBfZHJt LXkgKz0JdHZlMjAwX2Nvbm5lY3Rvci5vIFwKKwkJdHZlMjAwX2Rpc3BsYXkubyBcCisJCXR2ZTIw MF9kcnYubworCitvYmotJChDT05GSUdfRFJNX1RWRTIwMCkgKz0gdHZlMjAwX2RybS5vCmRpZmYg LS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vdHZlMjAwL3R2ZTIwMF9jb25uZWN0b3IuYyBiL2RyaXZl cnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2Nvbm5lY3Rvci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0 CmluZGV4IDAwMDAwMDAwMDAwMC4uOTNlOTkxNTZkMzc1Ci0tLSAvZGV2L251bGwKKysrIGIvZHJp dmVycy9ncHUvZHJtL3R2ZTIwMC90dmUyMDBfY29ubmVjdG9yLmMKQEAgLTAsMCArMSwxMjYgQEAK Ky8qCisgKiBDb3B5cmlnaHQgKEMpIDIwMTcgTGludXMgV2FsbGVpaiA8bGludXMud2FsbGVpakBs aW5hcm8ub3JnPgorICogUGFydHMgb2YgdGhpcyBmaWxlIHdlcmUgYmFzZWQgb24gc291cmNlcyBh cyBmb2xsb3dzOgorICoKKyAqIENvcHlyaWdodCAoQykgMjAwNi0yMDA4IEludGVsIENvcnBvcmF0 aW9uCisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgQW1vcyBMZWUgPGFtb3NfbGVlQHN0b3JsaW5rc2Vt aS5jb20+CisgKiBDb3B5cmlnaHQgKEMpIDIwMDcgRGF2ZSBBaXJsaWUgPGFpcmxpZWRAbGludXgu aWU+CisgKiBDb3B5cmlnaHQgKEMpIDIwMTEgVGV4YXMgSW5zdHJ1bWVudHMKKyAqIENvcHlyaWdo dCAoQykgMjAxNyBFcmljIEFuaG9sdAorICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3 YXJlIGFuZCBpcyBwcm92aWRlZCB0byB5b3UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZQorICogR05V IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJl ZSBTb2Z0d2FyZQorICogRm91bmRhdGlvbiwgYW5kIGFueSB1c2UgYnkgeW91IG9mIHRoaXMgcHJv Z3JhbSBpcyBzdWJqZWN0IHRvIHRoZSB0ZXJtcyBvZgorICogc3VjaCBHTlUgbGljZW5jZS4KKyAq LworCisvKioKKyAqIHR2ZTIwMF9kcm1fY29ubmVjdG9yLmMKKyAqIEltcGxlbWVudGF0aW9uIG9m IHRoZSBjb25uZWN0b3IgZnVuY3Rpb25zIGZvciB0aGUgRmFyYWRheSBUViBFbmNvZGVyCisgKi8K KyNpbmNsdWRlIDxsaW51eC92ZXJzaW9uLmg+CisjaW5jbHVkZSA8bGludXgvc2htZW1fZnMuaD4K KyNpbmNsdWRlIDxsaW51eC9kbWEtYnVmLmg+CisKKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgorI2lu Y2x1ZGUgPGRybS9kcm1fYXRvbWljX2hlbHBlci5oPgorI2luY2x1ZGUgPGRybS9kcm1fY3J0Y19o ZWxwZXIuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX29mLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9wYW5l bC5oPgorCisjaW5jbHVkZSAidHZlMjAwX2RybS5oIgorCitzdGF0aWMgdm9pZCB0dmUyMDBfY29u bmVjdG9yX2Rlc3Ryb3koc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvcikKK3sKKwlzdHJ1 Y3QgdHZlMjAwX2RybV9jb25uZWN0b3IgKnR2ZTIwMGNvbiA9CisJCXRvX3R2ZTIwMF9jb25uZWN0 b3IoY29ubmVjdG9yKTsKKworCWlmICh0dmUyMDBjb24tPnBhbmVsKQorCQlkcm1fcGFuZWxfZGV0 YWNoKHR2ZTIwMGNvbi0+cGFuZWwpOworCisJZHJtX2Nvbm5lY3Rvcl91bnJlZ2lzdGVyKGNvbm5l Y3Rvcik7CisJZHJtX2Nvbm5lY3Rvcl9jbGVhbnVwKGNvbm5lY3Rvcik7Cit9CisKK3N0YXRpYyBl bnVtIGRybV9jb25uZWN0b3Jfc3RhdHVzIHR2ZTIwMF9jb25uZWN0b3JfZGV0ZWN0KHN0cnVjdCBk cm1fY29ubmVjdG9yCisJCQkJCQkJKmNvbm5lY3RvciwgYm9vbCBmb3JjZSkKK3sKKwlzdHJ1Y3Qg dHZlMjAwX2RybV9jb25uZWN0b3IgKnR2ZTIwMGNvbiA9CisJCXRvX3R2ZTIwMF9jb25uZWN0b3Io Y29ubmVjdG9yKTsKKworCXJldHVybiAodHZlMjAwY29uLT5wYW5lbCA/CisJCWNvbm5lY3Rvcl9z dGF0dXNfY29ubmVjdGVkIDoKKwkJY29ubmVjdG9yX3N0YXR1c19kaXNjb25uZWN0ZWQpOworfQor CitzdGF0aWMgaW50IHR2ZTIwMF9jb25uZWN0b3JfaGVscGVyX2dldF9tb2RlcyhzdHJ1Y3QgZHJt X2Nvbm5lY3RvciAqY29ubmVjdG9yKQoreworCXN0cnVjdCB0dmUyMDBfZHJtX2Nvbm5lY3RvciAq dHZlMjAwY29uID0KKwkJdG9fdHZlMjAwX2Nvbm5lY3Rvcihjb25uZWN0b3IpOworCisJaWYgKCF0 dmUyMDBjb24tPnBhbmVsKQorCQlyZXR1cm4gMDsKKworCXJldHVybiBkcm1fcGFuZWxfZ2V0X21v ZGVzKHR2ZTIwMGNvbi0+cGFuZWwpOworfQorCitzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9jb25u ZWN0b3JfZnVuY3MgY29ubmVjdG9yX2Z1bmNzID0geworCS5maWxsX21vZGVzID0gZHJtX2hlbHBl cl9wcm9iZV9zaW5nbGVfY29ubmVjdG9yX21vZGVzLAorCS5kZXN0cm95ID0gdHZlMjAwX2Nvbm5l Y3Rvcl9kZXN0cm95LAorCS5kZXRlY3QgPSB0dmUyMDBfY29ubmVjdG9yX2RldGVjdCwKKwkuZHBt cyA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kcG1zLAorCS5yZXNldCA9IGRybV9hdG9t aWNfaGVscGVyX2Nvbm5lY3Rvcl9yZXNldCwKKwkuYXRvbWljX2R1cGxpY2F0ZV9zdGF0ZSA9IGRy bV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kdXBsaWNhdGVfc3RhdGUsCisJLmF0b21pY19kZXN0 cm95X3N0YXRlID0gZHJtX2F0b21pY19oZWxwZXJfY29ubmVjdG9yX2Rlc3Ryb3lfc3RhdGUsCit9 OworCitzdGF0aWMgY29uc3Qgc3RydWN0IGRybV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzIGNvbm5l Y3Rvcl9oZWxwZXJfZnVuY3MgPSB7CisJLmdldF9tb2RlcyA9IHR2ZTIwMF9jb25uZWN0b3JfaGVs cGVyX2dldF9tb2RlcywKK307CisKKy8qCisgKiBXYWxrcyB0aGUgT0YgZ3JhcGggdG8gZmluZCB0 aGUgcGFuZWwgbm9kZSBhbmQgdGhlbiBhc2tzIERSTSB0byBsb29rCisgKiB1cCB0aGUgcGFuZWwu CisgKi8KK3N0YXRpYyBzdHJ1Y3QgZHJtX3BhbmVsICp0dmUyMDBfZ2V0X3BhbmVsKHN0cnVjdCBk ZXZpY2UgKmRldikKK3sKKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKmVuZHBvaW50LCAqcGFuZWxfbm9k ZTsKKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wID0gZGV2LT5vZl9ub2RlOworCXN0cnVjdCBkcm1f cGFuZWwgKnBhbmVsOworCisJZW5kcG9pbnQgPSBvZl9ncmFwaF9nZXRfbmV4dF9lbmRwb2ludChu cCwgTlVMTCk7CisJaWYgKCFlbmRwb2ludCkgeworCQlkZXZfZXJyKGRldiwgIm5vIGVuZHBvaW50 IHRvIGZldGNoIHBhbmVsXG4iKTsKKwkJcmV0dXJuIE5VTEw7CisJfQorCisJLyogRG9uJ3QgcHJv Y2VlZCBpZiB3ZSBoYXZlIGFuIGVuZHBvaW50IGJ1dCBubyBwYW5lbF9ub2RlIHRpZWQgdG8gaXQg Ki8KKwlwYW5lbF9ub2RlID0gb2ZfZ3JhcGhfZ2V0X3JlbW90ZV9wb3J0X3BhcmVudChlbmRwb2lu dCk7CisJb2Zfbm9kZV9wdXQoZW5kcG9pbnQpOworCWlmICghcGFuZWxfbm9kZSkgeworCQlkZXZf ZXJyKGRldiwgIm5vIHZhbGlkIHBhbmVsIG5vZGVcbiIpOworCQlyZXR1cm4gTlVMTDsKKwl9CisK KwlwYW5lbCA9IG9mX2RybV9maW5kX3BhbmVsKHBhbmVsX25vZGUpOworCW9mX25vZGVfcHV0KHBh bmVsX25vZGUpOworCisJcmV0dXJuIHBhbmVsOworfQorCitpbnQgdHZlMjAwX2Nvbm5lY3Rvcl9p bml0KHN0cnVjdCBkcm1fZGV2aWNlICpkZXYpCit7CisJc3RydWN0IHR2ZTIwMF9kcm1fZGV2X3By aXZhdGUgKnByaXYgPSBkZXYtPmRldl9wcml2YXRlOworCXN0cnVjdCB0dmUyMDBfZHJtX2Nvbm5l Y3RvciAqdHZlMjAwY29uID0gJnByaXYtPmNvbm5lY3RvcjsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3Rv ciAqY29ubmVjdG9yID0gJnR2ZTIwMGNvbi0+Y29ubmVjdG9yOworCisJZHJtX2Nvbm5lY3Rvcl9p bml0KGRldiwgY29ubmVjdG9yLCAmY29ubmVjdG9yX2Z1bmNzLAorCQkJICAgRFJNX01PREVfQ09O TkVDVE9SX0RQSSk7CisJZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfYWRkKGNvbm5lY3RvciwgJmNvbm5l Y3Rvcl9oZWxwZXJfZnVuY3MpOworCisJdHZlMjAwY29uLT5wYW5lbCA9IHR2ZTIwMF9nZXRfcGFu ZWwoZGV2LT5kZXYpOworCWlmICh0dmUyMDBjb24tPnBhbmVsKQorCQlkcm1fcGFuZWxfYXR0YWNo KHR2ZTIwMGNvbi0+cGFuZWwsIGNvbm5lY3Rvcik7CisKKwlyZXR1cm4gMDsKK30KZGlmZiAtLWdp dCBhL2RyaXZlcnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2Rpc3BsYXkuYyBiL2RyaXZlcnMvZ3B1 L2RybS90dmUyMDAvdHZlMjAwX2Rpc3BsYXkuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAw MDAwMDAwMDAwMDAuLjAyNzU1M2FhY2IzMwotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZ3B1 L2RybS90dmUyMDAvdHZlMjAwX2Rpc3BsYXkuYwpAQCAtMCwwICsxLDM0NiBAQAorLyoKKyAqIENv cHlyaWdodCAoQykgMjAxNyBMaW51cyBXYWxsZWlqIDxsaW51cy53YWxsZWlqQGxpbmFyby5vcmc+ CisgKiBQYXJ0cyBvZiB0aGlzIGZpbGUgd2VyZSBiYXNlZCBvbiBzb3VyY2VzIGFzIGZvbGxvd3M6 CisgKgorICogQ29weXJpZ2h0IChDKSAyMDA2LTIwMDggSW50ZWwgQ29ycG9yYXRpb24KKyAqIENv cHlyaWdodCAoQykgMjAwNyBBbW9zIExlZSA8YW1vc19sZWVAc3RvcmxpbmtzZW1pLmNvbT4KKyAq IENvcHlyaWdodCAoQykgMjAwNyBEYXZlIEFpcmxpZSA8YWlybGllZEBsaW51eC5pZT4KKyAqIENv cHlyaWdodCAoQykgMjAxMSBUZXhhcyBJbnN0cnVtZW50cworICogQ29weXJpZ2h0IChDKSAyMDE3 IEVyaWMgQW5ob2x0CisgKgorICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmUgYW5kIGlz IHByb3ZpZGVkIHRvIHlvdSB1bmRlciB0aGUgdGVybXMgb2YgdGhlCisgKiBHTlUgR2VuZXJhbCBQ dWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJl CisgKiBGb3VuZGF0aW9uLCBhbmQgYW55IHVzZSBieSB5b3Ugb2YgdGhpcyBwcm9ncmFtIGlzIHN1 YmplY3QgdG8gdGhlIHRlcm1zIG9mCisgKiBzdWNoIEdOVSBsaWNlbmNlLgorICovCisjaW5jbHVk ZSA8bGludXgvY2xrLmg+CisjaW5jbHVkZSA8bGludXgvdmVyc2lvbi5oPgorI2luY2x1ZGUgPGxp bnV4L2RtYS1idWYuaD4KKyNpbmNsdWRlIDxsaW51eC9vZl9ncmFwaC5oPgorCisjaW5jbHVkZSA8 ZHJtL2RybVAuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX3BhbmVsLmg+CisjaW5jbHVkZSA8ZHJtL2Ry bV9nZW1fY21hX2hlbHBlci5oPgorI2luY2x1ZGUgPGRybS9kcm1fZmJfY21hX2hlbHBlci5oPgor CisjaW5jbHVkZSAidHZlMjAwX2RybS5oIgorCitpcnFyZXR1cm5fdCB0dmUyMDBfaXJxKGludCBp cnEsIHZvaWQgKmRhdGEpCit7CisJc3RydWN0IHR2ZTIwMF9kcm1fZGV2X3ByaXZhdGUgKnByaXYg PSBkYXRhOworCXUzMiBzdGF0OworCXUzMiB2YWw7CisKKwlzdGF0ID0gcmVhZGwocHJpdi0+cmVn cyArIFRWRTIwMF9JTlRfU1RBVCk7CisKKwlpZiAoIXN0YXQpCisJCXJldHVybiBJUlFfTk9ORTsK KworCS8qCisJICogVmJsYW5rIElSUQorCSAqCisJICogVGhlIGhhcmR3YXJlIGlzIGEgYml0IHRp bHRlZDogdGhlIGxpbmUgc3RheXMgaGlnaCBhZnRlciBjbGVhcmluZworCSAqIHRoZSB2Ymxhbmsg SVJRLCBmaXJlaW5nIG1hbnkgbW9yZSBpbnRlcnJ1cHRzLiBXZSBjb3VudGVyIHRoaXMKKwkgKiBi eSB0b2dnbGluZyB0aGUgSVJRIGJhY2sgYW5kIGZvcnRoIGZyb20gZmlyZWluZyBhdCB2Ymxhbmsg YW5kCisJICogZmlyZWluZyBhdCBzdGFydCBvZiBhY3RpdmUgaW1hZ2UsIHdoaWNoIHdvcmtzIGFy b3VuZCB0aGUgcHJvYmxlbQorCSAqIHNpbmNlIHRob3NlIG9jY3VyIHN0cmljdGx5IGluIHNlcXVl bmNlLCBhbmQgd2UgZ2V0IHR3byBJUlFzIGZvciBlYWNoCisJICogZnJhbWUsIG9uZSBhdCBzdGFy dCBvZiBWYmxhbmsgKHRoYXQgd2UgbWFrZSBjYWxsIGludG8gdGhlIENSVEMpIGFuZAorCSAqIGFu b3RoZXIgb25lIGF0IHRoZSBzdGFydCBvZiB0aGUgaW1hZ2UgKHRoYXQgd2UgZGlzY2FyZCkuCisJ ICovCisJaWYgKHN0YXQgJiBUVkUyMDBfSU5UX1ZfU1RBVFVTKSB7CisJCXZhbCA9IHJlYWRsKHBy aXYtPnJlZ3MgKyBUVkUyMDBfQ1RSTCk7CisJCS8qIFdlIGhhdmUgYW4gYWN0dWFsIHN0YXJ0IG9m IHZzeW5jICovCisJCWlmICghKHZhbCAmIFRWRTIwMF9WU1RTVFlQRV9CSVRTKSkgeworCQkJZHJt X2NydGNfaGFuZGxlX3ZibGFuaygmcHJpdi0+cGlwZS5jcnRjKTsKKwkJCS8qIFRvZ2dsZSB0cmln Z2VyIHRvIHN0YXJ0IG9mIGFjdGl2ZSBpbWFnZSAqLworCQkJdmFsIHw9IFRWRTIwMF9WU1RTVFlQ RV9WQUk7CisJCX0gZWxzZSB7CisJCQkvKiBUb2dnbGUgdHJpZ2dlciBiYWNrIHRvIHN0YXJ0IG9m IHZzeW5jICovCisJCQl2YWwgJj0gflRWRTIwMF9WU1RTVFlQRV9CSVRTOworCQl9CisJCXdyaXRl bCh2YWwsIHByaXYtPnJlZ3MgKyBUVkUyMDBfQ1RSTCk7CisJfSBlbHNlCisJCWRldl9lcnIocHJp di0+ZHJtLT5kZXYsICJzdHJheSBJUlEgJTA4eFxuIiwgc3RhdCk7CisKKwkvKiBDbGVhciB0aGUg aW50ZXJydXB0IG9uY2UgZG9uZSAqLworCXdyaXRlbChzdGF0LCBwcml2LT5yZWdzICsgVFZFMjAw X0lOVF9DTFIpOworCisJcmV0dXJuIElSUV9IQU5ETEVEOworfQorCitzdGF0aWMgaW50IHR2ZTIw MF9kaXNwbGF5X2NoZWNrKHN0cnVjdCBkcm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSwKKwkJ CSAgICAgICBzdHJ1Y3QgZHJtX3BsYW5lX3N0YXRlICpwc3RhdGUsCisJCQkgICAgICAgc3RydWN0 IGRybV9jcnRjX3N0YXRlICpjc3RhdGUpCit7CisJY29uc3Qgc3RydWN0IGRybV9kaXNwbGF5X21v ZGUgKm1vZGUgPSAmY3N0YXRlLT5tb2RlOworCXN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKm9sZF9m YiA9IHBpcGUtPnBsYW5lLnN0YXRlLT5mYjsKKwlzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYiA9 IHBzdGF0ZS0+ZmI7CisJc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciA9IHBpcGUtPmNv bm5lY3RvcjsKKwlzdHJ1Y3QgZHJtX2RldmljZSAqZHJtID0gY29ubmVjdG9yLT5kZXY7CisKKwkv KgorCSAqIFdlIHN1cHBvcnQgdGhlc2Ugc3BlY2lmaWMgcmVzb2x1dGlvbnMgYW5kIG5vdGhpbmcg ZWxzZS4KKwkgKi8KKwlpZiAoIShtb2RlLT5oZGlzcGxheSA9PSAzNTIgJiYgbW9kZS0+dmRpc3Bs YXkgPT0gMjQwKSAmJiAvKiBTSUYoNTI1KSAqLworCSAgICAhKG1vZGUtPmhkaXNwbGF5ID09IDM1 MiAmJiBtb2RlLT52ZGlzcGxheSA9PSAyODgpICYmIC8qIENJRig2MjUpICovCisJICAgICEobW9k ZS0+aGRpc3BsYXkgPT0gNjQwICYmIG1vZGUtPnZkaXNwbGF5ID09IDQ4MCkgJiYgLyogVkdBICov CisJICAgICEobW9kZS0+aGRpc3BsYXkgPT0gNzIwICYmIG1vZGUtPnZkaXNwbGF5ID09IDQ4MCkg JiYgLyogRDEgKi8KKwkgICAgIShtb2RlLT5oZGlzcGxheSA9PSA3MjAgJiYgbW9kZS0+dmRpc3Bs YXkgPT0gNTc2KSkgeyAvKiBEMSAqLworCQlkZXZfZXJyKGRybS0+ZGV2LCAidW5zdXBwb3J0ZWQg ZGlzcGxheSBtb2RlICgldSB4ICV1KVxuIiwKKwkJCW1vZGUtPmhkaXNwbGF5LCBtb2RlLT52ZGlz cGxheSk7CisJCXJldHVybiAtRUlOVkFMOworCX0KKworCWlmIChmYikgeworCQl1MzIgb2Zmc2V0 ID0gZHJtX2ZiX2NtYV9nZXRfZ2VtX2FkZHIoZmIsIHBzdGF0ZSwgMCk7CisKKwkJLyogRkIgYmFz ZSBhZGRyZXNzIG11c3QgYmUgZHdvcmQgYWxpZ25lZC4gKi8KKwkJaWYgKG9mZnNldCAmIDMpIHsK KwkJCWRldl9lcnIoZHJtLT5kZXYsICJGQiBub3QgMzItYml0IGFsaWduZWRcbiIpOworCQkJcmV0 dXJuIC1FSU5WQUw7CisJCX0KKworCQkvKgorCQkgKiBUaGVyZSdzIG5vIHBpdGNoIHJlZ2lzdGVy LCB0aGUgbW9kZSdzIGhkaXNwbGF5CisJCSAqIGNvbnRyb2xzIHRoaXMuCisJCSAqLworCQlpZiAo ZmItPnBpdGNoZXNbMF0gIT0gbW9kZS0+aGRpc3BsYXkgKiBmYi0+Zm9ybWF0LT5jcHBbMF0pIHsK KwkJCWRldl9lcnIoZHJtLT5kZXYsICJjYW4ndCBoYW5kbGUgcGl0Y2hlc1xuIik7CisJCQlyZXR1 cm4gLUVJTlZBTDsKKwkJfQorCisJCS8qCisJCSAqIFdlIGNhbid0IGNoYW5nZSB0aGUgRkIgZm9y bWF0IGluIGEgZmxpY2tlci1mcmVlCisJCSAqIG1hbm5lciAoYW5kIG9ubHkgdXBkYXRlIGl0IGR1 cmluZyBDUlRDIGVuYWJsZSkuCisJCSAqLworCQlpZiAob2xkX2ZiICYmIG9sZF9mYi0+Zm9ybWF0 ICE9IGZiLT5mb3JtYXQpCisJCQljc3RhdGUtPm1vZGVfY2hhbmdlZCA9IHRydWU7CisJfQorCisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIHR2ZTIwMF9kaXNwbGF5X2VuYWJsZShzdHJ1Y3Qg ZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUsCisJCQkJIHN0cnVjdCBkcm1fY3J0Y19zdGF0 ZSAqY3N0YXRlKQoreworCXN0cnVjdCBkcm1fY3J0YyAqY3J0YyA9ICZwaXBlLT5jcnRjOworCXN0 cnVjdCBkcm1fcGxhbmUgKnBsYW5lID0gJnBpcGUtPnBsYW5lOworCXN0cnVjdCBkcm1fZGV2aWNl ICpkcm0gPSBjcnRjLT5kZXY7CisJc3RydWN0IHR2ZTIwMF9kcm1fZGV2X3ByaXZhdGUgKnByaXYg PSBkcm0tPmRldl9wcml2YXRlOworCWNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2Rl ID0gJmNzdGF0ZS0+bW9kZTsKKwlzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpmYiA9IHBsYW5lLT5z dGF0ZS0+ZmI7CisJc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciA9ICZwcml2LT5jb25u ZWN0b3IuY29ubmVjdG9yOworCXUzMiBmb3JtYXQgPSBmYi0+Zm9ybWF0LT5mb3JtYXQ7CisJdTMy IGN0cmwxID0gMDsKKworCWNsa19wcmVwYXJlX2VuYWJsZShwcml2LT5jbGspOworCisJLyogRnVu Y3Rpb24gMSAqLworCWN0cmwxIHw9IFRWRTIwMF9DVFJMX0NTTU9ERTsKKwkvKiBJbnRlcmxhY2Ug bW9kZSBmb3IgQ0NJUjY1NjogcGFyYW1ldGVyaXplPyAqLworCWN0cmwxIHw9IFRWRTIwMF9DVFJM X05PTklOVEVSTEFDRTsKKwkvKiAzMiB3b3JkcyBwZXIgYnVyc3QgKi8KKwljdHJsMSB8PSBUVkUy MDBfQ1RSTF9CVVJTVF8zMl9XT1JEUzsKKwkvKiAxNiByZXRyaWVzICovCisJY3RybDEgfD0gVFZF MjAwX0NUUkxfUkVUUllDTlRfMTY7CisJLyogTlRTQyBtb2RlOiBwYXJhbWV0cml6ZT8gKi8KKwlj dHJsMSB8PSBUVkUyMDBfQ1RSTF9OVFNDOworCisJLyogVnN5bmMgSVJRIGF0IHN0YXJ0IG9mIFZz eW5jIGF0IGZpcnN0ICovCisJY3RybDEgfD0gVFZFMjAwX1ZTVFNUWVBFX1ZTWU5DOworCisJaWYg KGNvbm5lY3Rvci0+ZGlzcGxheV9pbmZvLmJ1c19mbGFncyAmIERSTV9CVVNfRkxBR19QSVhEQVRB X05FR0VER0UpCisJCWN0cmwxIHw9IFRWRTIwMF9DVFJMX1RWQ0xLUDsKKworCWlmICgobW9kZS0+ aGRpc3BsYXkgPT0gMzUyICYmIG1vZGUtPnZkaXNwbGF5ID09IDI0MCkgfHwgLyogU0lGKDUyNSkg Ki8KKwkgICAgKG1vZGUtPmhkaXNwbGF5ID09IDM1MiAmJiBtb2RlLT52ZGlzcGxheSA9PSAyODgp KSB7IC8qIENJRig2MjUpICovCisJCWN0cmwxIHw9IFRWRTIwMF9DVFJMX0lQUkVTT0xfQ0lGOwor CQlkZXZfaW5mbyhkcm0tPmRldiwgIkNJRiBtb2RlXG4iKTsKKwl9IGVsc2UgaWYgKG1vZGUtPmhk aXNwbGF5ID09IDY0MCAmJiBtb2RlLT52ZGlzcGxheSA9PSA0ODApIHsKKwkJY3RybDEgfD0gVFZF MjAwX0NUUkxfSVBSRVNPTF9WR0E7CisJCWRldl9pbmZvKGRybS0+ZGV2LCAiVkdBIG1vZGVcbiIp OworCX0gZWxzZSBpZiAoKG1vZGUtPmhkaXNwbGF5ID09IDcyMCAmJiBtb2RlLT52ZGlzcGxheSA9 PSA0ODApIHx8CisJCSAgIChtb2RlLT5oZGlzcGxheSA9PSA3MjAgJiYgbW9kZS0+dmRpc3BsYXkg PT0gNTc2KSkgeworCQljdHJsMSB8PSBUVkUyMDBfQ1RSTF9JUFJFU09MX0QxOworCQlkZXZfaW5m byhkcm0tPmRldiwgIkQxIG1vZGVcbiIpOworCX0KKworCWlmIChmb3JtYXQgJiBEUk1fRk9STUFU X0JJR19FTkRJQU4pIHsKKwkJY3RybDEgfD0gVFZFMjAwX0NUUkxfQkJCUDsKKwkJZm9ybWF0ICY9 IH5EUk1fRk9STUFUX0JJR19FTkRJQU47CisJfQorCisJc3dpdGNoIChmb3JtYXQpIHsKKwljYXNl IERSTV9GT1JNQVRfWFJHQjg4ODg6CisJCWN0cmwxIHw9IFRWRTIwMF9JUERNT0RfUkdCODg4Owor CQlicmVhazsKKwljYXNlIERSTV9GT1JNQVRfUkdCNTY1OgorCQljdHJsMSB8PSBUVkUyMDBfSVBE TU9EX1JHQjU2NTsKKwkJYnJlYWs7CisJY2FzZSBEUk1fRk9STUFUX1hSR0IxNTU1OgorCQljdHJs MSB8PSBUVkUyMDBfSVBETU9EX1JHQjU1NTsKKwkJYnJlYWs7CisJY2FzZSBEUk1fRk9STUFUX1hC R1I4ODg4OgorCQljdHJsMSB8PSBUVkUyMDBfSVBETU9EX1JHQjg4OCB8IFRWRTIwMF9CR1I7CisJ CWJyZWFrOworCWNhc2UgRFJNX0ZPUk1BVF9CR1I1NjU6CisJCWN0cmwxIHw9IFRWRTIwMF9JUERN T0RfUkdCNTY1IHwgVFZFMjAwX0JHUjsKKwkJYnJlYWs7CisJY2FzZSBEUk1fRk9STUFUX1hCR1Ix NTU1OgorCQljdHJsMSB8PSBUVkUyMDBfSVBETU9EX1JHQjU1NSB8IFRWRTIwMF9CR1I7CisJCWJy ZWFrOworCWNhc2UgRFJNX0ZPUk1BVF9ZVVlWOgorCQljdHJsMSB8PSBUVkUyMDBfSVBETU9EX1lV VjQyMjsKKwkJY3RybDEgfD0gVFZFMjAwX0NUUkxfWUNCQ1JPRFJfQ1IwWTFDQjBZMDsKKwkJYnJl YWs7CisJY2FzZSBEUk1fRk9STUFUX1lWWVU6CisJCWN0cmwxIHw9IFRWRTIwMF9JUERNT0RfWVVW NDIyOworCQljdHJsMSB8PSBUVkUyMDBfQ1RSTF9ZQ0JDUk9EUl9DQjBZMUNSMFkwOworCQlicmVh azsKKwljYXNlIERSTV9GT1JNQVRfVVlWWToKKwkJY3RybDEgfD0gVFZFMjAwX0lQRE1PRF9ZVVY0 MjI7CisJCWN0cmwxIHw9IFRWRTIwMF9DVFJMX1lDQkNST0RSX1kxQ1IwWTBDQjA7CisJCWJyZWFr OworCWNhc2UgRFJNX0ZPUk1BVF9WWVVZOgorCQljdHJsMSB8PSBUVkUyMDBfSVBETU9EX1lVVjQy MjsKKwkJY3RybDEgfD0gVFZFMjAwX0NUUkxfWUNCQ1JPRFJfWTFDQjBZMENSMDsKKwkJYnJlYWs7 CisJY2FzZSBEUk1fRk9STUFUX1lVVjQyMDoKKwkJY3RybDEgfD0gVFZFMjAwX0NUUkxfWVVWNDIw OworCQljdHJsMSB8PSBUVkUyMDBfSVBETU9EX1lVVjQyMDsKKwkJYnJlYWs7CisJZGVmYXVsdDoK KwkJZGV2X2Vycihkcm0tPmRldiwgIlVua25vd24gRkIgZm9ybWF0IDB4JTA4eFxuIiwKKwkJCWZi LT5mb3JtYXQtPmZvcm1hdCk7CisJCWJyZWFrOworCX0KKworCWN0cmwxIHw9IFRWRTIwMF9UVkVF TjsKKworCWRybV9wYW5lbF9wcmVwYXJlKHByaXYtPmNvbm5lY3Rvci5wYW5lbCk7CisKKwkvKiBU dXJuIGl0IG9uICovCisJd3JpdGVsKGN0cmwxLCBwcml2LT5yZWdzICsgVFZFMjAwX0NUUkwpOwor CisJZHJtX3BhbmVsX2VuYWJsZShwcml2LT5jb25uZWN0b3IucGFuZWwpOworCisJZHJtX2NydGNf dmJsYW5rX29uKGNydGMpOworfQorCit2b2lkIHR2ZTIwMF9kaXNwbGF5X2Rpc2FibGUoc3RydWN0 IGRybV9zaW1wbGVfZGlzcGxheV9waXBlICpwaXBlKQoreworCXN0cnVjdCBkcm1fY3J0YyAqY3J0 YyA9ICZwaXBlLT5jcnRjOworCXN0cnVjdCBkcm1fZGV2aWNlICpkcm0gPSBjcnRjLT5kZXY7CisJ c3RydWN0IHR2ZTIwMF9kcm1fZGV2X3ByaXZhdGUgKnByaXYgPSBkcm0tPmRldl9wcml2YXRlOwor CisJZHJtX2NydGNfdmJsYW5rX29mZihjcnRjKTsKKworCWRybV9wYW5lbF9kaXNhYmxlKHByaXYt PmNvbm5lY3Rvci5wYW5lbCk7CisKKwkvKiBEaXNhYmxlIGFuZCBQb3dlciBEb3duICovCisJd3Jp dGVsKDAsIHByaXYtPnJlZ3MgKyBUVkUyMDBfQ1RSTCk7CisKKwlkcm1fcGFuZWxfdW5wcmVwYXJl KHByaXYtPmNvbm5lY3Rvci5wYW5lbCk7CisKKwljbGtfZGlzYWJsZV91bnByZXBhcmUocHJpdi0+ Y2xrKTsKK30KKworc3RhdGljIHZvaWQgdHZlMjAwX2Rpc3BsYXlfdXBkYXRlKHN0cnVjdCBkcm1f c2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSwKKwkJCQkgc3RydWN0IGRybV9wbGFuZV9zdGF0ZSAq b2xkX3BzdGF0ZSkKK3sKKwlzdHJ1Y3QgZHJtX2NydGMgKmNydGMgPSAmcGlwZS0+Y3J0YzsKKwlz dHJ1Y3QgZHJtX2RldmljZSAqZHJtID0gY3J0Yy0+ZGV2OworCXN0cnVjdCB0dmUyMDBfZHJtX2Rl dl9wcml2YXRlICpwcml2ID0gZHJtLT5kZXZfcHJpdmF0ZTsKKwlzdHJ1Y3QgZHJtX3BlbmRpbmdf dmJsYW5rX2V2ZW50ICpldmVudCA9IGNydGMtPnN0YXRlLT5ldmVudDsKKwlzdHJ1Y3QgZHJtX3Bs YW5lICpwbGFuZSA9ICZwaXBlLT5wbGFuZTsKKwlzdHJ1Y3QgZHJtX3BsYW5lX3N0YXRlICpwc3Rh dGUgPSBwbGFuZS0+c3RhdGU7CisJc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIgPSBwc3RhdGUt PmZiOworCisJaWYgKGZiKSB7CisJCS8qIEZvciBSR0IsIHRoZSBZIGNvbXBvbmVudCBpcyB1c2Vk IGFzIGJhc2UgYWRkcmVzcyAqLworCQl3cml0ZWwoZHJtX2ZiX2NtYV9nZXRfZ2VtX2FkZHIoZmIs IHBzdGF0ZSwgMCksCisJCSAgICAgICBwcml2LT5yZWdzICsgVFZFMjAwX1lfRlJBTUVfQkFTRV9B RERSKTsKKworCQkvKiBGb3IgdGhyZWUgcGxhbmUgWVVWIHdlIG5lZWQgdHdvIG1vcmUgYWRkcmVz c2VzICovCisJCWlmIChmYi0+Zm9ybWF0LT5mb3JtYXQgPT0gRFJNX0ZPUk1BVF9ZVVY0MjApIHsK KwkJCXdyaXRlbChkcm1fZmJfY21hX2dldF9nZW1fYWRkcihmYiwgcHN0YXRlLCAxKSwKKwkJCSAg ICAgICBwcml2LT5yZWdzICsgVFZFMjAwX1VfRlJBTUVfQkFTRV9BRERSKTsKKwkJCXdyaXRlbChk cm1fZmJfY21hX2dldF9nZW1fYWRkcihmYiwgcHN0YXRlLCAyKSwKKwkJCSAgICAgICBwcml2LT5y ZWdzICsgVFZFMjAwX1ZfRlJBTUVfQkFTRV9BRERSKTsKKwkJfQorCX0KKworCWlmIChldmVudCkg eworCQljcnRjLT5zdGF0ZS0+ZXZlbnQgPSBOVUxMOworCisJCXNwaW5fbG9ja19pcnEoJmNydGMt PmRldi0+ZXZlbnRfbG9jayk7CisJCWlmIChjcnRjLT5zdGF0ZS0+YWN0aXZlICYmIGRybV9jcnRj X3ZibGFua19nZXQoY3J0YykgPT0gMCkKKwkJCWRybV9jcnRjX2FybV92YmxhbmtfZXZlbnQoY3J0 YywgZXZlbnQpOworCQllbHNlCisJCQlkcm1fY3J0Y19zZW5kX3ZibGFua19ldmVudChjcnRjLCBl dmVudCk7CisJCXNwaW5fdW5sb2NrX2lycSgmY3J0Yy0+ZGV2LT5ldmVudF9sb2NrKTsKKwl9Cit9 CisKK2ludCB0dmUyMDBfZW5hYmxlX3ZibGFuayhzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLCB1bnNp Z25lZCBpbnQgY3J0YykKK3sKKwlzdHJ1Y3QgdHZlMjAwX2RybV9kZXZfcHJpdmF0ZSAqcHJpdiA9 IGRybS0+ZGV2X3ByaXZhdGU7CisKKwl3cml0ZWwoVFZFMjAwX0lOVF9WX1NUQVRVUywgcHJpdi0+ cmVncyArIFRWRTIwMF9JTlRfRU4pOworCXJldHVybiAwOworfQorCit2b2lkIHR2ZTIwMF9kaXNh YmxlX3ZibGFuayhzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLCB1bnNpZ25lZCBpbnQgY3J0YykKK3sK KwlzdHJ1Y3QgdHZlMjAwX2RybV9kZXZfcHJpdmF0ZSAqcHJpdiA9IGRybS0+ZGV2X3ByaXZhdGU7 CisKKwl3cml0ZWwoMCwgcHJpdi0+cmVncyArIFRWRTIwMF9JTlRfRU4pOworfQorCitzdGF0aWMg aW50IHR2ZTIwMF9kaXNwbGF5X3ByZXBhcmVfZmIoc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9w aXBlICpwaXBlLAorCQkJCSAgICBzdHJ1Y3QgZHJtX3BsYW5lX3N0YXRlICpwbGFuZV9zdGF0ZSkK K3sKKwlyZXR1cm4gZHJtX2ZiX2NtYV9wcmVwYXJlX2ZiKCZwaXBlLT5wbGFuZSwgcGxhbmVfc3Rh dGUpOworfQorCitjb25zdCBzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGVfZnVuY3MgdHZl MjAwX2Rpc3BsYXlfZnVuY3MgPSB7CisJLmNoZWNrID0gdHZlMjAwX2Rpc3BsYXlfY2hlY2ssCisJ LmVuYWJsZSA9IHR2ZTIwMF9kaXNwbGF5X2VuYWJsZSwKKwkuZGlzYWJsZSA9IHR2ZTIwMF9kaXNw bGF5X2Rpc2FibGUsCisJLnVwZGF0ZSA9IHR2ZTIwMF9kaXNwbGF5X3VwZGF0ZSwKKwkucHJlcGFy ZV9mYiA9IHR2ZTIwMF9kaXNwbGF5X3ByZXBhcmVfZmIsCit9OworCitpbnQgdHZlMjAwX2Rpc3Bs YXlfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAqZHJtKQoreworCXN0cnVjdCB0dmUyMDBfZHJtX2Rl dl9wcml2YXRlICpwcml2ID0gZHJtLT5kZXZfcHJpdmF0ZTsKKwlpbnQgcmV0OworCXN0YXRpYyBj b25zdCB1MzIgZm9ybWF0c1tdID0geworCQlEUk1fRk9STUFUX1hSR0I4ODg4LAorCQlEUk1fRk9S TUFUX1hCR1I4ODg4LAorCQlEUk1fRk9STUFUX1JHQjU2NSwKKwkJRFJNX0ZPUk1BVF9CR1I1NjUs CisJCURSTV9GT1JNQVRfWFJHQjE1NTUsCisJCURSTV9GT1JNQVRfWEJHUjE1NTUsCisJCS8qCisJ CSAqIFRoZSBjb250cm9sbGVyIGFjdHVhbGx5IHN1cHBvcnRzIGFueSBZQ2JDciBvcmRlcmluZywK KwkJICogZm9yIHBhY2tlZCBZQ2JDci4gVGhpcyBqdXN0IGxpc3RzIHRoZSBvcmRlcmluZ3MgdGhh dAorCQkgKiBEUk0gc3VwcG9ydHMuCisJCSAqLworCQlEUk1fRk9STUFUX1lVWVYsCisJCURSTV9G T1JNQVRfWVZZVSwKKwkJRFJNX0ZPUk1BVF9VWVZZLAorCQlEUk1fRk9STUFUX1ZZVVksCisJCS8q IFRoaXMgdXNlcyB0aHJlZSBwbGFuZXMgKi8KKwkJRFJNX0ZPUk1BVF9ZVVY0MjAsCisJfTsKKwor CXJldCA9IGRybV9zaW1wbGVfZGlzcGxheV9waXBlX2luaXQoZHJtLCAmcHJpdi0+cGlwZSwKKwkJ CQkJICAgJnR2ZTIwMF9kaXNwbGF5X2Z1bmNzLAorCQkJCQkgICBmb3JtYXRzLCBBUlJBWV9TSVpF KGZvcm1hdHMpLAorCQkJCQkgICAmcHJpdi0+Y29ubmVjdG9yLmNvbm5lY3Rvcik7CisJaWYgKHJl dCkKKwkJcmV0dXJuIHJldDsKKworCXJldHVybiAwOworfQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9n cHUvZHJtL3R2ZTIwMC90dmUyMDBfZHJtLmggYi9kcml2ZXJzL2dwdS9kcm0vdHZlMjAwL3R2ZTIw MF9kcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwMDAwMDAuLmYwMGZjNDdh NmJkMQotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZ3B1L2RybS90dmUyMDAvdHZlMjAwX2Ry bS5oCkBAIC0wLDAgKzEsMTI5IEBACisvKgorICogQ29weXJpZ2h0IChDKSAyMDE3IExpbnVzIFdh bGxlaWogPGxpbnVzLndhbGxlaWpAbGluYXJvLm9yZz4KKyAqIFBhcnRzIG9mIHRoaXMgZmlsZSB3 ZXJlIGJhc2VkIG9uIHNvdXJjZXMgYXMgZm9sbG93czoKKyAqCisgKiBDb3B5cmlnaHQgKEMpIDIw MDYtMjAwOCBJbnRlbCBDb3Jwb3JhdGlvbgorICogQ29weXJpZ2h0IChDKSAyMDA3IEFtb3MgTGVl IDxhbW9zX2xlZUBzdG9ybGlua3NlbWkuY29tPgorICogQ29weXJpZ2h0IChDKSAyMDA3IERhdmUg QWlybGllIDxhaXJsaWVkQGxpbnV4LmllPgorICogQ29weXJpZ2h0IChDKSAyMDExIFRleGFzIElu c3RydW1lbnRzCisgKiBDb3B5cmlnaHQgKEMpIDIwMTcgRXJpYyBBbmhvbHQKKyAqCisgKiBUaGlz IHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZSBhbmQgaXMgcHJvdmlkZWQgdG8geW91IHVuZGVyIHRo ZSB0ZXJtcyBvZiB0aGUKKyAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBh cyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKKyAqIEZvdW5kYXRpb24sIGFuZCBhbnkg dXNlIGJ5IHlvdSBvZiB0aGlzIHByb2dyYW0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YKKyAq IHN1Y2ggR05VIGxpY2VuY2UuCisgKi8KKworI2lmbmRlZiBfVFZFMjAwX0RSTV9IXworI2RlZmlu ZSBfVFZFMjAwX0RSTV9IXworCisvKiBCaXRzIDItMzEgYXJlIHZhbGlkIHBoeXNpY2FsIGJhc2Ug YWRkcmVzc2VzICovCisjZGVmaW5lIFRWRTIwMF9ZX0ZSQU1FX0JBU0VfQUREUgkweDAwCisjZGVm aW5lIFRWRTIwMF9VX0ZSQU1FX0JBU0VfQUREUgkweDA0CisjZGVmaW5lIFRWRTIwMF9WX0ZSQU1F X0JBU0VfQUREUgkweDA4CisKKyNkZWZpbmUgVFZFMjAwX0lOVF9FTgkJCTB4MEMKKyNkZWZpbmUg VFZFMjAwX0lOVF9DTFIJCQkweDEwCisjZGVmaW5lIFRWRTIwMF9JTlRfU1RBVAkJCTB4MTQKKyNk ZWZpbmUgVFZFMjAwX0lOVF9CVVNfRVJSCQlCSVQoNykKKyNkZWZpbmUgVFZFMjAwX0lOVF9WX1NU QVRVUwkJQklUKDYpIC8qIHZlcnRpY2FsIGJsYW5rICovCisjZGVmaW5lIFRWRTIwMF9JTlRfVl9O RVhUX0ZSQU1FCQlCSVQoNSkKKyNkZWZpbmUgVFZFMjAwX0lOVF9VX05FWFRfRlJBTUUJCUJJVCg0 KQorI2RlZmluZSBUVkUyMDBfSU5UX1lfTkVYVF9GUkFNRQkJQklUKDMpCisjZGVmaW5lIFRWRTIw MF9JTlRfVl9GSUZPX1VOREVSUlVOCUJJVCgyKQorI2RlZmluZSBUVkUyMDBfSU5UX1VfRklGT19V TkRFUlJVTglCSVQoMSkKKyNkZWZpbmUgVFZFMjAwX0lOVF9ZX0ZJRk9fVU5ERVJSVU4JQklUKDAp CisjZGVmaW5lIFRWRTIwMF9GSUZPX1VOREVSUlVOUwkJKFRWRTIwMF9JTlRfVl9GSUZPX1VOREVS UlVOIHwgXAorCQkJCQkgVFZFMjAwX0lOVF9VX0ZJRk9fVU5ERVJSVU4gfCBcCisJCQkJCSBUVkUy MDBfSU5UX1lfRklGT19VTkRFUlJVTikKKworI2RlZmluZSBUVkUyMDBfQ1RSTAkJCTB4MTgKKyNk ZWZpbmUgVFZFMjAwX0NUUkxfWVVWNDIwCQlCSVQoMzEpCisjZGVmaW5lIFRWRTIwMF9DVFJMX0NT TU9ERQkJQklUKDMwKQorI2RlZmluZSBUVkUyMDBfQ1RSTF9OT05JTlRFUkxBQ0UJQklUKDI4KSAv KiAwID0gbm9uLWludGVybGFjZSBDQ0lSNjU2ICovCisjZGVmaW5lIFRWRTIwMF9DVFJMX1RWQ0xL UAkJQklUKDI3KSAvKiBJbnZlcnRlZCBjbG9jayBwaGFzZSAqLworLyogQml0cyAyNC4uMjYgZGVm aW5lIHRoZSBidXJzdCBzaXplIGFmdGVyIGFyYml0cmF0aW9uIG9uIHRoZSBidXMgKi8KKyNkZWZp bmUgVFZFMjAwX0NUUkxfQlVSU1RfNF9XT1JEUwkoMCA8PCAyNCkKKyNkZWZpbmUgVFZFMjAwX0NU UkxfQlVSU1RfOF9XT1JEUwkoMSA8PCAyNCkKKyNkZWZpbmUgVFZFMjAwX0NUUkxfQlVSU1RfMTZf V09SRFMJKDIgPDwgMjQpCisjZGVmaW5lIFRWRTIwMF9DVFJMX0JVUlNUXzMyX1dPUkRTCSgzIDw8 IDI0KQorI2RlZmluZSBUVkUyMDBfQ1RSTF9CVVJTVF82NF9XT1JEUwkoNCA8PCAyNCkKKyNkZWZp bmUgVFZFMjAwX0NUUkxfQlVSU1RfMTI4X1dPUkRTCSg1IDw8IDI0KQorI2RlZmluZSBUVkUyMDBf Q1RSTF9CVVJTVF8yNTZfV09SRFMJKDYgPDwgMjQpCisjZGVmaW5lIFRWRTIwMF9DVFJMX0JVUlNU XzBfV09SRFMJKDcgPDwgMjQpIC8qID8gKi8KKy8qCisgKiBCaXRzIDE2Li4yMyBpcyB0aGUgcmV0 cnkgY291bnQqMTYgYmVmb3JlIGlzc3VlaW5nIGEgbmV3IEFIQiB0cmFuc2ZlcgorICogb24gdGhl IEFIQiBidXMuCisgKi8KKyNkZWZpbmUgVFZFMjAwX0NUUkxfUkVUUllDTlRfTUFTSwlHRU5NQVNL KDIzLCAxNikKKyNkZWZpbmUgVFZFMjAwX0NUUkxfUkVUUllDTlRfMTYJCSgxIDw8IDE2KQorI2Rl ZmluZSBUVkUyMDBfQ1RSTF9CQkJQCQlCSVQoMTUpIC8qIDAgPSBsaXR0bGUtZW5kaWFuICovCisv KiBCaXRzIDEyLi4xNCBkZWZpbmUgdGhlIFlDYkNyIG9yZGVyaW5nICovCisjZGVmaW5lIFRWRTIw MF9DVFJMX1lDQkNST0RSX0NCMFkwQ1IwWTEJKDAgPDwgMTIpCisjZGVmaW5lIFRWRTIwMF9DVFJM X1lDQkNST0RSX1kwQ0IwWTFDUjAJKDEgPDwgMTIpCisjZGVmaW5lIFRWRTIwMF9DVFJMX1lDQkNS T0RSX0NSMFkwQ0IwWTEJKDIgPDwgMTIpCisjZGVmaW5lIFRWRTIwMF9DVFJMX1lDQkNST0RSX1kx Q0IwWTBDUjAJKDMgPDwgMTIpCisjZGVmaW5lIFRWRTIwMF9DVFJMX1lDQkNST0RSX0NSMFkxQ0Iw WTAJKDQgPDwgMTIpCisjZGVmaW5lIFRWRTIwMF9DVFJMX1lDQkNST0RSX1kxQ1IwWTBDQjAJKDUg PDwgMTIpCisjZGVmaW5lIFRWRTIwMF9DVFJMX1lDQkNST0RSX0NCMFkxQ1IwWTAJKDYgPDwgMTIp CisjZGVmaW5lIFRWRTIwMF9DVFJMX1lDQkNST0RSX1kwQ1IwWTFDQjAJKDcgPDwgMTIpCisvKiBC aXRzIDEwLi4xMSBkZWZpbmUgdGhlIGlucHV0IHJlc29sdXRpb24gKGZyYW1lYnVmZmVyIHNpemUp ICovCisjZGVmaW5lIFRWRTIwMF9DVFJMX0lQUkVTT0xfQ0lGCQkoMCA8PCAxMCkKKyNkZWZpbmUg VFZFMjAwX0NUUkxfSVBSRVNPTF9WR0EJCSgxIDw8IDEwKQorI2RlZmluZSBUVkUyMDBfQ1RSTF9J UFJFU09MX0QxCQkoMiA8PCAxMCkKKyNkZWZpbmUgVFZFMjAwX0NUUkxfTlRTQwkJQklUKDkpIC8q IDAgPSBQQUwsIDEgPSBOVFNDICovCisjZGVmaW5lIFRWRTIwMF9DVFJMX0lOVEVSTEFDRQkJQklU KDgpIC8qIDEgPSBpbnRlcmxhY2UsIG9ubHkgZm9yIEQxICovCisjZGVmaW5lIFRWRTIwMF9JUERN T0RfUkdCNTU1CQkoMCA8PCA2KSAvKiBUVkUyMDBfQ1RSTF9ZVVY0MjAgPSAwICovCisjZGVmaW5l IFRWRTIwMF9JUERNT0RfUkdCNTY1CQkoMSA8PCA2KQorI2RlZmluZSBUVkUyMDBfSVBETU9EX1JH Qjg4OAkJKDIgPDwgNikKKyNkZWZpbmUgVFZFMjAwX0lQRE1PRF9ZVVY0MjAJCSgyIDw8IDYpIC8q IFRWRTIwMF9DVFJMX1lVVjQyMCA9IDEgKi8KKyNkZWZpbmUgVFZFMjAwX0lQRE1PRF9ZVVY0MjIJ CSgzIDw8IDYpCisvKiBCaXRzIDQgJiA1IGRlZmluZSB3aGVuIHRvIGZpcmUgdGhlIHZibGFuayBJ UlEgKi8KKyNkZWZpbmUgVFZFMjAwX1ZTVFNUWVBFX1ZTWU5DCQkoMCA8PCA0KSAvKiBzdGFydCBv ZiB2c3luYyAqLworI2RlZmluZSBUVkUyMDBfVlNUU1RZUEVfVkJQCQkoMSA8PCA0KSAvKiBzdGFy dCBvZiB2IGJhY2sgcG9yY2ggKi8KKyNkZWZpbmUgVFZFMjAwX1ZTVFNUWVBFX1ZBSQkJKDIgPDwg NCkgLyogc3RhcnQgb2YgdiBhY3RpdmUgaW1hZ2UgKi8KKyNkZWZpbmUgVFZFMjAwX1ZTVFNUWVBF X1ZGUAkJKDMgPDwgNCkgLyogc3RhcnQgb2YgdiBmcm9udCBwb3JjaCAqLworI2RlZmluZSBUVkUy MDBfVlNUU1RZUEVfQklUUwkJKEJJVCg0KSB8IEJJVCg1KSkKKyNkZWZpbmUgVFZFMjAwX0JHUgkJ CUJJVCgxKSAvKiAwID0gUkdCLCAxID0gQkdSICovCisjZGVmaW5lIFRWRTIwMF9UVkVFTgkJCUJJ VCgwKSAvKiBFbmFibGUgVFZFIGJsb2NrICovCisKKyNkZWZpbmUgVFZFMjAwX0NUUkxfMgkJCTB4 MWMKKyNkZWZpbmUgVFZFMjAwX0NUUkxfMwkJCTB4MjAKKworI2RlZmluZSBUVkUyMDBfQ1RSTF80 CQkJMHgyNAorI2RlZmluZSBUVkUyMDBfQ1RSTF80X1JFU0VUCQlCSVQoMCkgLyogdHJpZ2dlcnMg cmVzZXQgb2YgVFZFMjAwICovCisKKyNpbmNsdWRlIDxkcm0vZHJtX2dlbS5oPgorI2luY2x1ZGUg PGRybS9kcm1fc2ltcGxlX2ttc19oZWxwZXIuaD4KKworc3RydWN0IHR2ZTIwMF9kcm1fY29ubmVj dG9yIHsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciBjb25uZWN0b3I7CisJc3RydWN0IGRybV9wYW5l bCAqcGFuZWw7Cit9OworCitzdHJ1Y3QgdHZlMjAwX2RybV9kZXZfcHJpdmF0ZSB7CisJc3RydWN0 IGRybV9kZXZpY2UgKmRybTsKKworCXN0cnVjdCB0dmUyMDBfZHJtX2Nvbm5lY3RvciBjb25uZWN0 b3I7CisJc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9waXBlIHBpcGU7CisJc3RydWN0IGRybV9m YmRldl9jbWEgKmZiZGV2OworCisJdm9pZCAqcmVnczsKKwlzdHJ1Y3QgY2xrICpwY2xrOworCXN0 cnVjdCBjbGsgKmNsazsKK307CisKKyNkZWZpbmUgdG9fdHZlMjAwX2Nvbm5lY3Rvcih4KSBcCisJ Y29udGFpbmVyX29mKHgsIHN0cnVjdCB0dmUyMDBfZHJtX2Nvbm5lY3RvciwgY29ubmVjdG9yKQor CitpbnQgdHZlMjAwX2Rpc3BsYXlfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KTsKK2ludCB0 dmUyMDBfZW5hYmxlX3ZibGFuayhzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLCB1bnNpZ25lZCBpbnQg Y3J0Yyk7Cit2b2lkIHR2ZTIwMF9kaXNhYmxlX3ZibGFuayhzdHJ1Y3QgZHJtX2RldmljZSAqZHJt LCB1bnNpZ25lZCBpbnQgY3J0Yyk7CitpcnFyZXR1cm5fdCB0dmUyMDBfaXJxKGludCBpcnEsIHZv aWQgKmRhdGEpOworaW50IHR2ZTIwMF9jb25uZWN0b3JfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAq ZGV2KTsKK2ludCB0dmUyMDBfZW5jb2Rlcl9pbml0KHN0cnVjdCBkcm1fZGV2aWNlICpkZXYpOwor aW50IHR2ZTIwMF9kdW1iX2NyZWF0ZShzdHJ1Y3QgZHJtX2ZpbGUgKmZpbGVfcHJpdiwKKwkJICAg ICAgc3RydWN0IGRybV9kZXZpY2UgKmRldiwKKwkJICAgICAgc3RydWN0IGRybV9tb2RlX2NyZWF0 ZV9kdW1iICphcmdzKTsKKworI2VuZGlmIC8qIF9UVkUyMDBfRFJNX0hfICovCmRpZmYgLS1naXQg YS9kcml2ZXJzL2dwdS9kcm0vdHZlMjAwL3R2ZTIwMF9kcnYuYyBiL2RyaXZlcnMvZ3B1L2RybS90 dmUyMDAvdHZlMjAwX2Rydi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAw MC4uOWUzNDE0N2UyNjE3Ci0tLSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9ncHUvZHJtL3R2ZTIw MC90dmUyMDBfZHJ2LmMKQEAgLTAsMCArMSwyNzcgQEAKKy8qCisgKiBDb3B5cmlnaHQgKEMpIDIw MTcgTGludXMgV2FsbGVpaiA8bGludXMud2FsbGVpakBsaW5hcm8ub3JnPgorICogUGFydHMgb2Yg dGhpcyBmaWxlIHdlcmUgYmFzZWQgb24gc291cmNlcyBhcyBmb2xsb3dzOgorICoKKyAqIENvcHly aWdodCAoQykgMjAwNi0yMDA4IEludGVsIENvcnBvcmF0aW9uCisgKiBDb3B5cmlnaHQgKEMpIDIw MDcgQW1vcyBMZWUgPGFtb3NfbGVlQHN0b3JsaW5rc2VtaS5jb20+CisgKiBDb3B5cmlnaHQgKEMp IDIwMDcgRGF2ZSBBaXJsaWUgPGFpcmxpZWRAbGludXguaWU+CisgKiBDb3B5cmlnaHQgKEMpIDIw MTEgVGV4YXMgSW5zdHJ1bWVudHMKKyAqIENvcHlyaWdodCAoQykgMjAxNyBFcmljIEFuaG9sdAor ICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlIGFuZCBpcyBwcm92aWRlZCB0byB5 b3UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZQorICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2Ug dmVyc2lvbiAyIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQorICogRm91bmRhdGlv biwgYW5kIGFueSB1c2UgYnkgeW91IG9mIHRoaXMgcHJvZ3JhbSBpcyBzdWJqZWN0IHRvIHRoZSB0 ZXJtcyBvZgorICogc3VjaCBHTlUgbGljZW5jZS4KKyAqLworCisvKioKKyAqIERPQzogRmFyYWRh eSBUViBFbmNvZGVyIFRWRTIwMCBEUk0gRHJpdmVyCisgKgorICogVGhlIEZhcmFkYXkgVFYgRW5j b2RlciBUVkUyMDAgaXMgYWxzbyBrbm93biBhcyB0aGUgR2VtaW5pIFRWIEludGVyZmFjZQorICog Q29udHJvbGxlciAoVFZDKSBhbmQgaXMgZm91bmQgaW4gdGhlIEdlbWluaSBDaGlwc2V0IGZyb20g U3RvcmxpbmsKKyAqIFNlbWljb25kdWN0b3IgKGxhdGVyIFN0b3JtIFNlbWljb25kdWN0b3IsIGxh dGVyIENvcnRpbmEgU3lzdGVtcykKKyAqIGJ1dCBhbHNvIGluIHRoZSBHcmFpbiBNZWRpYSBHTTgx ODAgY2hpcHNldC4gT24gdGhlIEdlbWluaSB0aGUgbW9kdWxlCisgKiBpcyBjb25uZWN0ZWQgdG8g OCBkYXRhIGxpbmVzIGFuZCBhIHNpbmdsZSBjbG9jayBsaW5lLCBjb21wcmlzaW5nIGFuCisgKiA4 LWJpdCBCVC42NTYgaW50ZXJmYWNlLgorICoKKyAqIFRoaXMgaXMgYSB2ZXJ5IGJhc2ljIFlVViBk aXNwbGF5IGRyaXZlci4gVGhlIGRhdGFzaGVldCBzcGVjaWZpZXMgdGhhdAorICogaXQgc3VwcG9y dHMgdGhlIElUVSBCVC42NTYgc3RhbmRhcmQuIEl0IHJlcXVpcmVzIGEgMjcgTUh6IGNsb2NrIHdo aWNoIGlzCisgKiB0aGUgaGFsbG1hcmsgb2YgYW55IFRWIGVuY29kZXIgc3VwcG9ydGluZyBib3Ro IFBBTCBhbmQgTlRTQy4KKyAqCisgKiBUaGlzIGRyaXZlciBleHBvc2VzIGEgc3RhbmRhcmQgS01T IGludGVyZmFjZSBmb3IgdGhpcyBUViBlbmNvZGVyLgorICovCisKKyNpbmNsdWRlIDxsaW51eC9j bGsuaD4KKyNpbmNsdWRlIDxsaW51eC9kbWEtYnVmLmg+CisjaW5jbHVkZSA8bGludXgvaXJxLmg+ CisjaW5jbHVkZSA8bGludXgvaW8uaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KKyNpbmNs dWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4KKyNpbmNsdWRlIDxsaW51eC9zaG1lbV9mcy5o PgorI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KKyNpbmNsdWRlIDxsaW51eC92ZXJzaW9uLmg+CisK KyNpbmNsdWRlIDxkcm0vZHJtUC5oPgorI2luY2x1ZGUgPGRybS9kcm1fYXRvbWljX2hlbHBlci5o PgorI2luY2x1ZGUgPGRybS9kcm1fY3J0Y19oZWxwZXIuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX2dl bV9jbWFfaGVscGVyLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9mYl9jbWFfaGVscGVyLmg+CisjaW5j bHVkZSA8ZHJtL2RybV9wYW5lbC5oPgorCisjaW5jbHVkZSAidHZlMjAwX2RybS5oIgorCisjZGVm aW5lIERSSVZFUl9ERVNDICAgICAgIkRSTSBtb2R1bGUgZm9yIEZhcmFkYXkgVFZFMjAwIgorCitz dHJ1Y3QgZHJtX21vZGVfY29uZmlnX2Z1bmNzIG1vZGVfY29uZmlnX2Z1bmNzID0geworCS5mYl9j cmVhdGUgPSBkcm1fZmJfY21hX2NyZWF0ZSwKKwkuYXRvbWljX2NoZWNrID0gZHJtX2F0b21pY19o ZWxwZXJfY2hlY2ssCisJLmF0b21pY19jb21taXQgPSBkcm1fYXRvbWljX2hlbHBlcl9jb21taXQs Cit9OworCitzdGF0aWMgaW50IHR2ZTIwMF9tb2Rlc2V0X2luaXQoc3RydWN0IGRybV9kZXZpY2Ug KmRldikKK3sKKwlzdHJ1Y3QgZHJtX21vZGVfY29uZmlnICptb2RlX2NvbmZpZzsKKwlzdHJ1Y3Qg dHZlMjAwX2RybV9kZXZfcHJpdmF0ZSAqcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CisJaW50IHJl dCA9IDA7CisKKwlkcm1fbW9kZV9jb25maWdfaW5pdChkZXYpOworCW1vZGVfY29uZmlnID0gJmRl di0+bW9kZV9jb25maWc7CisJbW9kZV9jb25maWctPmZ1bmNzID0gJm1vZGVfY29uZmlnX2Z1bmNz OworCW1vZGVfY29uZmlnLT5taW5fd2lkdGggPSAzNTI7CisJbW9kZV9jb25maWctPm1heF93aWR0 aCA9IDcyMDsKKwltb2RlX2NvbmZpZy0+bWluX2hlaWdodCA9IDI0MDsKKwltb2RlX2NvbmZpZy0+ bWF4X2hlaWdodCA9IDU3NjsKKworCXJldCA9IHR2ZTIwMF9jb25uZWN0b3JfaW5pdChkZXYpOwor CWlmIChyZXQpIHsKKwkJZGV2X2VycihkZXYtPmRldiwgIkZhaWxlZCB0byBjcmVhdGUgdHZlMjAw X2RybV9jb25uZWN0b3JcbiIpOworCQlnb3RvIG91dF9jb25maWc7CisJfQorCisJLyoKKwkgKiBE b24ndCBhY3R1YWxseSBhdHRhY2ggaWYgd2UgZGlkbid0IGZpbmQgYSBkcm1fcGFuZWwKKwkgKiBh dHRhY2hlZCB0byB1cy4KKwkgKi8KKwlpZiAoIXByaXYtPmNvbm5lY3Rvci5wYW5lbCkgeworCQlk ZXZfaW5mbyhkZXYtPmRldiwKKwkJCSAiZGVmZXJyaW5nIGR1ZSB0byBsYWNrIG9mIERSTSBwYW5l bCBkZXZpY2VcbiIpOworCQlyZXQgPSAtRVBST0JFX0RFRkVSOworCQlnb3RvIG91dF9jb25maWc7 CisJfQorCWRldl9pbmZvKGRldi0+ZGV2LCAiYXR0YWNoZWQgdG8gcGFuZWwgJXNcbiIsCisJCSBk ZXZfbmFtZShwcml2LT5jb25uZWN0b3IucGFuZWwtPmRldikpOworCisJcmV0ID0gdHZlMjAwX2Rp c3BsYXlfaW5pdChkZXYpOworCWlmIChyZXQpIHsKKwkJZGV2X2VycihkZXYtPmRldiwgImZhaWxl ZCB0byBpbml0IGRpc3BsYXlcbiIpOworCQlnb3RvIG91dF9jb25maWc7CisJfQorCisJcmV0ID0g ZHJtX3ZibGFua19pbml0KGRldiwgMSk7CisJaWYgKHJldCkgeworCQlkZXZfZXJyKGRldi0+ZGV2 LCAiZmFpbGVkIHRvIGluaXQgdmJsYW5rXG4iKTsKKwkJZ290byBvdXRfY29uZmlnOworCX0KKwor CWRybV9tb2RlX2NvbmZpZ19yZXNldChkZXYpOworCisJLyoKKwkgKiBQYXNzaW5nIGluIDE2IGhl cmUgd2lsbCBtYWtlIHRoZSBSR0I2NTYgbW9kZSB0aGUgZGVmYXVsdAorCSAqIFBhc3NpbmcgaW4g MzIgd2lsbCB1c2UgWFJHQjg4ODggbW9kZQorCSAqLworCXByaXYtPmZiZGV2ID0gZHJtX2ZiZGV2 X2NtYV9pbml0KGRldiwgMTYsCisJCQkJCSBkZXYtPm1vZGVfY29uZmlnLm51bV9jb25uZWN0b3Ip OworCWRybV9rbXNfaGVscGVyX3BvbGxfaW5pdChkZXYpOworCisJZ290byBmaW5pc2g7CisKK291 dF9jb25maWc6CisJZHJtX21vZGVfY29uZmlnX2NsZWFudXAoZGV2KTsKK2ZpbmlzaDoKKwlyZXR1 cm4gcmV0OworfQorCitERUZJTkVfRFJNX0dFTV9DTUFfRk9QUyhkcm1fZm9wcyk7CisKK3N0YXRp YyB2b2lkIHR2ZTIwMF9sYXN0Y2xvc2Uoc3RydWN0IGRybV9kZXZpY2UgKmRldikKK3sKKwlzdHJ1 Y3QgdHZlMjAwX2RybV9kZXZfcHJpdmF0ZSAqcHJpdiA9IGRldi0+ZGV2X3ByaXZhdGU7CisKKwlk cm1fZmJkZXZfY21hX3Jlc3RvcmVfbW9kZShwcml2LT5mYmRldik7Cit9CisKK3N0YXRpYyBzdHJ1 Y3QgZHJtX2RyaXZlciB0dmUyMDBfZHJtX2RyaXZlciA9IHsKKwkuZHJpdmVyX2ZlYXR1cmVzID0K KwkJRFJJVkVSX01PREVTRVQgfCBEUklWRVJfR0VNIHwgRFJJVkVSX1BSSU1FIHwgRFJJVkVSX0FU T01JQywKKwkubGFzdGNsb3NlID0gdHZlMjAwX2xhc3RjbG9zZSwKKwkuaW9jdGxzID0gTlVMTCwK KwkuZm9wcyA9ICZkcm1fZm9wcywKKwkubmFtZSA9ICJ0dmUyMDAiLAorCS5kZXNjID0gRFJJVkVS X0RFU0MsCisJLmRhdGUgPSAiMjAxNzA3MDMiLAorCS5tYWpvciA9IDEsCisJLm1pbm9yID0gMCwK KwkucGF0Y2hsZXZlbCA9IDAsCisJLmR1bWJfY3JlYXRlID0gZHJtX2dlbV9jbWFfZHVtYl9jcmVh dGUsCisJLmR1bWJfZGVzdHJveSA9IGRybV9nZW1fZHVtYl9kZXN0cm95LAorCS5kdW1iX21hcF9v ZmZzZXQgPSBkcm1fZ2VtX2NtYV9kdW1iX21hcF9vZmZzZXQsCisJLmdlbV9mcmVlX29iamVjdCA9 IGRybV9nZW1fY21hX2ZyZWVfb2JqZWN0LAorCS5nZW1fdm1fb3BzID0gJmRybV9nZW1fY21hX3Zt X29wcywKKworCS5lbmFibGVfdmJsYW5rID0gdHZlMjAwX2VuYWJsZV92YmxhbmssCisJLmRpc2Fi bGVfdmJsYW5rID0gdHZlMjAwX2Rpc2FibGVfdmJsYW5rLAorCisJLnByaW1lX2hhbmRsZV90b19m ZCA9IGRybV9nZW1fcHJpbWVfaGFuZGxlX3RvX2ZkLAorCS5wcmltZV9mZF90b19oYW5kbGUgPSBk cm1fZ2VtX3ByaW1lX2ZkX3RvX2hhbmRsZSwKKwkuZ2VtX3ByaW1lX2ltcG9ydCA9IGRybV9nZW1f cHJpbWVfaW1wb3J0LAorCS5nZW1fcHJpbWVfaW1wb3J0X3NnX3RhYmxlID0gZHJtX2dlbV9jbWFf cHJpbWVfaW1wb3J0X3NnX3RhYmxlLAorCS5nZW1fcHJpbWVfZXhwb3J0ID0gZHJtX2dlbV9wcmlt ZV9leHBvcnQsCisJLmdlbV9wcmltZV9nZXRfc2dfdGFibGUJPSBkcm1fZ2VtX2NtYV9wcmltZV9n ZXRfc2dfdGFibGUsCit9OworCitzdGF0aWMgaW50IHR2ZTIwMF9wcm9iZShzdHJ1Y3QgcGxhdGZv cm1fZGV2aWNlICpwZGV2KQoreworCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZwZGV2LT5kZXY7CisJ c3RydWN0IHR2ZTIwMF9kcm1fZGV2X3ByaXZhdGUgKnByaXY7CisJc3RydWN0IGRybV9kZXZpY2Ug KmRybTsKKwlzdHJ1Y3QgcmVzb3VyY2UgKnJlczsKKwlpbnQgaXJxOworCWludCByZXQ7CisKKwlw cml2ID0gZGV2bV9remFsbG9jKGRldiwgc2l6ZW9mKCpwcml2KSwgR0ZQX0tFUk5FTCk7CisJaWYg KCFwcml2KQorCQlyZXR1cm4gLUVOT01FTTsKKworCWRybSA9IGRybV9kZXZfYWxsb2MoJnR2ZTIw MF9kcm1fZHJpdmVyLCBkZXYpOworCWlmIChJU19FUlIoZHJtKSkKKwkJcmV0dXJuIFBUUl9FUlIo ZHJtKTsKKwlwbGF0Zm9ybV9zZXRfZHJ2ZGF0YShwZGV2LCBkcm0pOworCXByaXYtPmRybSA9IGRy bTsKKwlkcm0tPmRldl9wcml2YXRlID0gcHJpdjsKKworCS8qIENsb2NrIHRoZSBzaWxpY29uIHNv IHdlIGNhbiBhY2Nlc3MgdGhlIHJlZ2lzdGVycyAqLworCXByaXYtPnBjbGsgPSBkZXZtX2Nsa19n ZXQoZGV2LCAiUENMSyIpOworCWlmIChJU19FUlIocHJpdi0+cGNsaykpIHsKKwkJZGV2X2Vycihk ZXYsICJ1bmFibGUgdG8gZ2V0IFBDTEtcbiIpOworCQlyZXQgPSBQVFJfRVJSKHByaXYtPnBjbGsp OworCQlnb3RvIGRldl91bnJlZjsKKwl9CisJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKHByaXYt PnBjbGspOworCWlmIChyZXQpIHsKKwkJZGV2X2VycihkZXYsICJmYWlsZWQgdG8gZW5hYmxlIFBD TEtcbiIpOworCQlnb3RvIGRldl91bnJlZjsKKwl9CisKKwkvKiBUaGlzIGNsb2NrIGlzIGZvciB0 aGUgcGl4ZWxzICgyN01IeikgKi8KKwlwcml2LT5jbGsgPSBkZXZtX2Nsa19nZXQoZGV2LCAiVFZF Iik7CisJaWYgKElTX0VSUihwcml2LT5jbGspKSB7CisJCWRldl9lcnIoZGV2LCAidW5hYmxlIHRv IGdldCBUVkUgY2xvY2tcbiIpOworCQlyZXQgPSBQVFJfRVJSKHByaXYtPmNsayk7CisJCWdvdG8g Y2xrX2Rpc2FibGU7CisJfQorCisJcmVzID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElP UkVTT1VSQ0VfTUVNLCAwKTsKKwlwcml2LT5yZWdzID0gZGV2bV9pb3JlbWFwX3Jlc291cmNlKGRl diwgcmVzKTsKKwlpZiAoIXByaXYtPnJlZ3MpIHsKKwkJZGV2X2VycihkZXYsICIlcyBmYWlsZWQg bW1pb1xuIiwgX19mdW5jX18pOworCQlyZXQgPSAtRUlOVkFMOworCQlnb3RvIGRldl91bnJlZjsK Kwl9CisKKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYsIDApOworCWlmICghaXJxKSB7CisJ CXJldCA9IC1FSU5WQUw7CisJCWdvdG8gZGV2X3VucmVmOworCX0KKworCS8qIHR1cm4gb2ZmIGlu dGVycnVwdHMgYmVmb3JlIHJlcXVlc3RpbmcgdGhlIGlycSAqLworCXdyaXRlbCgwLCBwcml2LT5y ZWdzICsgVFZFMjAwX0lOVF9FTik7CisKKwlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKGRldiwgaXJx LCB0dmUyMDBfaXJxLCAwLCAidHZlMjAwIiwgcHJpdik7CisJaWYgKHJldCkgeworCQlkZXZfZXJy KGRldiwgImZhaWxlZCB0byByZXF1ZXN0IGlycSAlZFxuIiwgcmV0KTsKKwkJcmV0dXJuIHJldDsK Kwl9CisKKwlyZXQgPSB0dmUyMDBfbW9kZXNldF9pbml0KGRybSk7CisJaWYgKHJldCkKKwkJZ290 byBkZXZfdW5yZWY7CisKKwlyZXQgPSBkcm1fZGV2X3JlZ2lzdGVyKGRybSwgMCk7CisJaWYgKHJl dCA8IDApCisJCWdvdG8gZGV2X3VucmVmOworCisJcmV0dXJuIDA7CisKK2Nsa19kaXNhYmxlOgor CWNsa19kaXNhYmxlX3VucHJlcGFyZShwcml2LT5wY2xrKTsKK2Rldl91bnJlZjoKKwlkcm1fZGV2 X3VucmVmKGRybSk7CisJcmV0dXJuIHJldDsKK30KKworc3RhdGljIGludCB0dmUyMDBfcmVtb3Zl KHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCit7CisJc3RydWN0IGRybV9kZXZpY2UgKmRy bSA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOworCXN0cnVjdCB0dmUyMDBfZHJtX2Rldl9w cml2YXRlICpwcml2ID0gZHJtLT5kZXZfcHJpdmF0ZTsKKworCWRybV9kZXZfdW5yZWdpc3Rlcihk cm0pOworCWlmIChwcml2LT5mYmRldikKKwkJZHJtX2ZiZGV2X2NtYV9maW5pKHByaXYtPmZiZGV2 KTsKKwlkcm1fbW9kZV9jb25maWdfY2xlYW51cChkcm0pOworCWNsa19kaXNhYmxlX3VucHJlcGFy ZShwcml2LT5wY2xrKTsKKwlkcm1fZGV2X3VucmVmKGRybSk7CisKKwlyZXR1cm4gMDsKK30KKwor c3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgdHZlMjAwX29mX21hdGNoW10gPSB7CisJ eworCQkuY29tcGF0aWJsZSA9ICJmYXJhZGF5LHR2ZTIwMCIsCisJfSwKKwl7fSwKK307CisKK3N0 YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIHR2ZTIwMF9kcml2ZXIgPSB7CisJLmRyaXZlciA9 IHsKKwkJLm5hbWUgICAgICAgICAgID0gInR2ZTIwMCIsCisJCS5vZl9tYXRjaF90YWJsZSA9IG9m X21hdGNoX3B0cih0dmUyMDBfb2ZfbWF0Y2gpLAorCX0sCisJLnByb2JlID0gdHZlMjAwX3Byb2Jl LAorCS5yZW1vdmUgPSB0dmUyMDBfcmVtb3ZlLAorfTsKK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIo dHZlMjAwX2RyaXZlcik7CisKK01PRFVMRV9ERVNDUklQVElPTihEUklWRVJfREVTQyk7CitNT0RV TEVfQVVUSE9SKCJMaW51cyBXYWxsZWlqIDxsaW51cy53YWxsZWlqQGxpbmFyby5vcmc+Iik7CitN T0RVTEVfTElDRU5TRSgiR1BMIik7Ci0tIAoyLjEzLjQKCl9fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVs QGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWls bWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=