From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756060AbdDMDR6 (ORCPT ); Wed, 12 Apr 2017 23:17:58 -0400 Received: from anholt.net ([50.246.234.109]:60728 "EHLO anholt.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755528AbdDMDRy (ORCPT ); Wed, 12 Apr 2017 23:17:54 -0400 From: Eric Anholt To: dri-devel@lists.freedesktop.org, tom.cooksey@arm.com, Russell King , linus.walleij@linaro.org Cc: linux-kernel@vger.kernel.org, Eric Anholt Subject: [PATCH v6 2/2] drm/pl111: Initial drm/kms driver for pl111 Date: Wed, 12 Apr 2017 20:17:46 -0700 Message-Id: <20170413031746.12921-2-eric@anholt.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170413031746.12921-1-eric@anholt.net> References: <20170413031746.12921-1-eric@anholt.net> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Tom Cooksey This is a modesetting driver for the pl111 CLCD display controller found on various ARM platforms such as the Versatile Express. The driver has only been tested on the bcm911360_entphn platform so far, with PRIME-based buffer sharing between vc4 and clcd. It reuses the existing devicetree binding, while not using quite as many of its properties as the fbdev driver does (those are left for future work). v2: Nearly complete rewrite by anholt, cutting 2/3 of the code thanks to DRM core's excellent new helpers. v3: Don't match pl110 any more, don't attach if we don't have a DRM panel, use DRM_GEM_CMA_FOPS, update MAINTAINERS, use the simple display helper, use drm_gem_cma_dumb_create (same as our wrapper). v4: Change the driver's .name to not clash with fbdev in sysfs, drop platform alias, drop redundant "drm" in DRM driver name, hook up .prepare_fb to the CMA helper so that DMA fences should work. v5: Move register definitions inside the driver directory, fix build in COMPILE_TEST and !AMBA mode. v6: Drop TIM2_CLKSEL for now to be consistent with existing DT bindings, switch back to external register definitions. Signed-off-by: Tom Cooksey Signed-off-by: Eric Anholt Reviewed-by: Linus Walleij (v5) --- Documentation/gpu/index.rst | 1 + Documentation/gpu/pl111.rst | 6 + MAINTAINERS | 6 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/pl111/Kconfig | 12 ++ drivers/gpu/drm/pl111/Makefile | 5 + drivers/gpu/drm/pl111/pl111_connector.c | 127 ++++++++++++ drivers/gpu/drm/pl111/pl111_display.c | 344 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/pl111/pl111_drm.h | 56 ++++++ drivers/gpu/drm/pl111/pl111_drv.c | 272 +++++++++++++++++++++++++ 11 files changed, 832 insertions(+) create mode 100644 Documentation/gpu/pl111.rst create mode 100644 drivers/gpu/drm/pl111/Kconfig create mode 100644 drivers/gpu/drm/pl111/Makefile create mode 100644 drivers/gpu/drm/pl111/pl111_connector.c create mode 100644 drivers/gpu/drm/pl111/pl111_display.c create mode 100644 drivers/gpu/drm/pl111/pl111_drm.h create mode 100644 drivers/gpu/drm/pl111/pl111_drv.c diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index c572f092739e..037a39ac1807 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -12,6 +12,7 @@ Linux GPU Driver Developer's Guide drm-uapi i915 meson + pl111 tinydrm vc4 vga-switcheroo diff --git a/Documentation/gpu/pl111.rst b/Documentation/gpu/pl111.rst new file mode 100644 index 000000000000..9b03736d33dd --- /dev/null +++ b/Documentation/gpu/pl111.rst @@ -0,0 +1,6 @@ +========================================== + drm/pl111 ARM PrimeCell PL111 CLCD Driver +========================================== + +.. kernel-doc:: drivers/gpu/drm/pl111/pl111_drv.c + :doc: ARM PrimeCell PL111 CLCD Driver diff --git a/MAINTAINERS b/MAINTAINERS index c36dfaeef26b..780630e2055b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4161,6 +4161,12 @@ F: include/drm/drm* F: include/uapi/drm/drm* F: include/linux/vga* +DRM DRIVER FOR ARM PL111 CLCD +M: Eric Anholt +T: git git://anongit.freedesktop.org/drm/drm-misc +S: Supported +F: drivers/gpu/drm/pl111/ + DRM DRIVER FOR AST SERVER GRAPHICS CHIPS M: Dave Airlie S: Odd Fixes diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 78d7fc0ebb57..d1c6c12199b7 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -274,6 +274,8 @@ source "drivers/gpu/drm/meson/Kconfig" source "drivers/gpu/drm/tinydrm/Kconfig" +source "drivers/gpu/drm/pl111/Kconfig" + # Keep legacy drivers last menuconfig DRM_LEGACY diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 59f0f9b696eb..28dcf93e1d8f 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -96,3 +96,4 @@ obj-y += hisilicon/ obj-$(CONFIG_DRM_ZTE) += zte/ obj-$(CONFIG_DRM_MXSFB) += mxsfb/ obj-$(CONFIG_DRM_TINYDRM) += tinydrm/ +obj-$(CONFIG_DRM_PL111) += pl111/ diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig new file mode 100644 index 000000000000..ede49efd531f --- /dev/null +++ b/drivers/gpu/drm/pl111/Kconfig @@ -0,0 +1,12 @@ +config DRM_PL111 + tristate "DRM Support for PL111 CLCD Controller" + depends on DRM + depends on ARM || ARM64 || COMPILE_TEST + 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 PL111 CLCD controller. + If M is selected the module will be called pl111_drm. + diff --git a/drivers/gpu/drm/pl111/Makefile b/drivers/gpu/drm/pl111/Makefile new file mode 100644 index 000000000000..01caee727c13 --- /dev/null +++ b/drivers/gpu/drm/pl111/Makefile @@ -0,0 +1,5 @@ +pl111_drm-y += pl111_connector.o \ + pl111_display.o \ + pl111_drv.o + +obj-$(CONFIG_DRM_PL111) += pl111_drm.o diff --git a/drivers/gpu/drm/pl111/pl111_connector.c b/drivers/gpu/drm/pl111/pl111_connector.c new file mode 100644 index 000000000000..3f213d7e7692 --- /dev/null +++ b/drivers/gpu/drm/pl111/pl111_connector.c @@ -0,0 +1,127 @@ +/* + * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved. + * + * Parts of this file were based on sources as follows: + * + * Copyright (c) 2006-2008 Intel Corporation + * Copyright (c) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * + * 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. + * + */ + +/** + * pl111_drm_connector.c + * Implementation of the connector functions for PL111 DRM + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pl111_drm.h" + +static void pl111_connector_destroy(struct drm_connector *connector) +{ + struct pl111_drm_connector *pl111_connector = + to_pl111_connector(connector); + + if (pl111_connector->panel) + drm_panel_detach(pl111_connector->panel); + + drm_connector_unregister(connector); + drm_connector_cleanup(connector); +} + +static enum drm_connector_status pl111_connector_detect(struct drm_connector + *connector, bool force) +{ + struct pl111_drm_connector *pl111_connector = + to_pl111_connector(connector); + + return (pl111_connector->panel ? + connector_status_connected : + connector_status_disconnected); +} + +static int pl111_connector_helper_get_modes(struct drm_connector *connector) +{ + struct pl111_drm_connector *pl111_connector = + to_pl111_connector(connector); + + if (!pl111_connector->panel) + return 0; + + return drm_panel_get_modes(pl111_connector->panel); +} + +const struct drm_connector_funcs connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = pl111_connector_destroy, + .detect = pl111_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, +}; + +const struct drm_connector_helper_funcs connector_helper_funcs = { + .get_modes = pl111_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 *pl111_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 pl111_connector_init(struct drm_device *dev) +{ + struct pl111_drm_dev_private *priv = dev->dev_private; + struct pl111_drm_connector *pl111_connector = &priv->connector; + struct drm_connector *connector = &pl111_connector->connector; + + drm_connector_init(dev, connector, &connector_funcs, + DRM_MODE_CONNECTOR_DPI); + drm_connector_helper_add(connector, &connector_helper_funcs); + + pl111_connector->panel = pl111_get_panel(dev->dev); + if (pl111_connector->panel) + drm_panel_attach(pl111_connector->panel, connector); + + return 0; +} + diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c new file mode 100644 index 000000000000..cb0170533346 --- /dev/null +++ b/drivers/gpu/drm/pl111/pl111_display.c @@ -0,0 +1,344 @@ +/* + * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved. + * + * Parts of this file were based on sources as follows: + * + * Copyright (c) 2006-2008 Intel Corporation + * Copyright (c) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * + * 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 + +#include "pl111_drm.h" + +irqreturn_t pl111_irq(int irq, void *data) +{ + struct pl111_drm_dev_private *priv = data; + u32 irq_stat; + irqreturn_t status = IRQ_NONE; + + irq_stat = readl(priv->regs + CLCD_PL111_MIS); + + if (!irq_stat) + return IRQ_NONE; + + if (irq_stat & CLCD_IRQ_NEXTBASE_UPDATE) { + drm_crtc_handle_vblank(&priv->pipe.crtc); + + status = IRQ_HANDLED; + } + + /* Clear the interrupt once done */ + writel(irq_stat, priv->regs + CLCD_PL111_ICR); + + return status; +} + +static u32 pl111_get_fb_offset(struct drm_plane_state *pstate) +{ + struct drm_framebuffer *fb = pstate->fb; + struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, 0); + + return (obj->paddr + + fb->offsets[0] + + fb->format->cpp[0] * pstate->src_x + + fb->pitches[0] * pstate->src_y); +} + +static int pl111_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; + + if (mode->hdisplay % 16) + return -EINVAL; + + if (fb) { + u32 offset = pl111_get_fb_offset(pstate); + + /* FB base address must be dword aligned. */ + if (offset & 3) + return -EINVAL; + + /* There's no pitch register -- the mode's hdisplay + * controls it. + */ + if (fb->pitches[0] != mode->hdisplay * fb->format->cpp[0]) + 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 pl111_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 pl111_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 cntl; + u32 ppl, hsw, hfp, hbp; + u32 lpp, vsw, vfp, vbp; + u32 cpl; + int ret; + + ret = clk_set_rate(priv->clk, mode->clock * 1000); + if (ret) { + dev_err(drm->dev, + "Failed to set pixel clock rate to %d: %d\n", + mode->clock * 1000, ret); + } + + clk_prepare_enable(priv->clk); + + ppl = (mode->hdisplay / 16) - 1; + hsw = mode->hsync_end - mode->hsync_start - 1; + hfp = mode->hsync_start - mode->hdisplay - 1; + hbp = mode->htotal - mode->hsync_end - 1; + + lpp = mode->vdisplay - 1; + vsw = mode->vsync_end - mode->vsync_start - 1; + vfp = mode->vsync_start - mode->vdisplay; + vbp = mode->vtotal - mode->vsync_end; + + cpl = mode->hdisplay - 1; + + writel((ppl << 2) | + (hsw << 8) | + (hfp << 16) | + (hbp << 24), + priv->regs + CLCD_TIM0); + writel(lpp | + (vsw << 10) | + (vfp << 16) | + (vbp << 24), + priv->regs + CLCD_TIM1); + /* XXX: We currently always use CLCDCLK with no divisor. We + * could probably reduce power consumption by using HCLK + * (apb_pclk) with a divisor when it gets us near our target + * pixel clock. + */ + writel(((mode->flags & DRM_MODE_FLAG_NHSYNC) ? TIM2_IHS : 0) | + ((mode->flags & DRM_MODE_FLAG_NVSYNC) ? TIM2_IVS : 0) | + ((connector->display_info.bus_flags & + DRM_BUS_FLAG_DE_LOW) ? TIM2_IOE : 0) | + ((connector->display_info.bus_flags & + DRM_BUS_FLAG_PIXDATA_NEGEDGE) ? TIM2_IPC : 0) | + TIM2_BCD | + (cpl << 16) | + priv->regs + CLCD_TIM2); + writel(0, priv->regs + CLCD_TIM3); + + drm_panel_prepare(priv->connector.panel); + + /* Enable and Power Up */ + cntl = CNTL_LCDEN | CNTL_LCDTFT | CNTL_LCDPWR | CNTL_LCDVCOMP(1); + + /* Note that the the hardware's format reader takes 'r' from + * the low bit, while DRM formats list channels from high bit + * to low bit as you read left to right. + */ + switch (fb->format->format) { + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XBGR8888: + cntl |= CNTL_LCDBPP24; + break; + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB8888: + cntl |= CNTL_LCDBPP24 | CNTL_BGR; + break; + case DRM_FORMAT_BGR565: + cntl |= CNTL_LCDBPP16_565; + break; + case DRM_FORMAT_RGB565: + cntl |= CNTL_LCDBPP16_565 | CNTL_BGR; + break; + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_XBGR1555: + cntl |= CNTL_LCDBPP16; + break; + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_XRGB1555: + cntl |= CNTL_LCDBPP16 | CNTL_BGR; + break; + case DRM_FORMAT_ABGR4444: + case DRM_FORMAT_XBGR4444: + cntl |= CNTL_LCDBPP16_444; + break; + case DRM_FORMAT_ARGB4444: + case DRM_FORMAT_XRGB4444: + cntl |= CNTL_LCDBPP16_444 | CNTL_BGR; + break; + default: + WARN_ONCE(true, "Unknown FB format 0x%08x\n", + fb->format->format); + break; + } + + writel(cntl, priv->regs + CLCD_PL111_CNTL); + + drm_panel_enable(priv->connector.panel); + + drm_crtc_vblank_on(crtc); +} + +void pl111_display_disable(struct drm_simple_display_pipe *pipe) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct drm_device *drm = crtc->dev; + struct pl111_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 + CLCD_PL111_CNTL); + + drm_panel_unprepare(priv->connector.panel); + + clk_disable_unprepare(priv->clk); +} + +static void pl111_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 pl111_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) { + u32 addr = pl111_get_fb_offset(pstate); + + writel(addr, priv->regs + CLCD_UBAS); + } + + 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 pl111_enable_vblank(struct drm_device *drm, unsigned int crtc) +{ + struct pl111_drm_dev_private *priv = drm->dev_private; + + writel(CLCD_IRQ_NEXTBASE_UPDATE, priv->regs + CLCD_PL111_IENB); + + return 0; +} + +void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc) +{ + struct pl111_drm_dev_private *priv = drm->dev_private; + + writel(0, priv->regs + CLCD_PL111_IENB); +} + +static int pl111_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 pl111_display_funcs = { + .check = pl111_display_check, + .enable = pl111_display_enable, + .disable = pl111_display_disable, + .update = pl111_display_update, + .prepare_fb = pl111_display_prepare_fb, +}; + +int pl111_display_init(struct drm_device *drm) +{ + struct pl111_drm_dev_private *priv = drm->dev_private; + struct device *dev = drm->dev; + struct device_node *endpoint; + u32 tft_r0b0g0[3]; + int ret; + static const u32 formats[] = { + DRM_FORMAT_ABGR8888, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB8888, + DRM_FORMAT_BGR565, + DRM_FORMAT_RGB565, + DRM_FORMAT_ABGR1555, + DRM_FORMAT_XBGR1555, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_ABGR4444, + DRM_FORMAT_XBGR4444, + DRM_FORMAT_ARGB4444, + DRM_FORMAT_XRGB4444, + }; + + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); + if (!endpoint) + return -ENODEV; + + if (of_property_read_u32_array(endpoint, + "arm,pl11x,tft-r0g0b0-pads", + tft_r0b0g0, + ARRAY_SIZE(tft_r0b0g0)) != 0) { + dev_err(dev, "arm,pl11x,tft-r0g0b0-pads should be 3 ints\n"); + of_node_put(endpoint); + return -ENOENT; + } + of_node_put(endpoint); + + if (tft_r0b0g0[0] != 0 || + tft_r0b0g0[1] != 8 || + tft_r0b0g0[2] != 16) { + dev_err(dev, "arm,pl11x,tft-r0g0b0-pads != [0,8,16] not yet supported\n"); + return -EINVAL; + } + + ret = drm_simple_display_pipe_init(drm, &priv->pipe, + &pl111_display_funcs, + formats, ARRAY_SIZE(formats), + &priv->connector.connector); + if (ret) + return ret; + + return 0; +} diff --git a/drivers/gpu/drm/pl111/pl111_drm.h b/drivers/gpu/drm/pl111/pl111_drm.h new file mode 100644 index 000000000000..f381593921b7 --- /dev/null +++ b/drivers/gpu/drm/pl111/pl111_drm.h @@ -0,0 +1,56 @@ +/* + * + * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved. + * + * + * Parts of this file were based on sources as follows: + * + * Copyright (c) 2006-2008 Intel Corporation + * Copyright (c) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * + * 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 _PL111_DRM_H_ +#define _PL111_DRM_H_ + +#include +#include + +#define CLCD_IRQ_NEXTBASE_UPDATE BIT(2) + +struct pl111_drm_connector { + struct drm_connector connector; + struct drm_panel *panel; +}; + +struct pl111_drm_dev_private { + struct drm_device *drm; + + struct pl111_drm_connector connector; + struct drm_simple_display_pipe pipe; + struct drm_fbdev_cma *fbdev; + + void *regs; + struct clk *clk; +}; + +#define to_pl111_connector(x) \ + container_of(x, struct pl111_drm_connector, connector) + +int pl111_display_init(struct drm_device *dev); +int pl111_enable_vblank(struct drm_device *drm, unsigned int crtc); +void pl111_disable_vblank(struct drm_device *drm, unsigned int crtc); +irqreturn_t pl111_irq(int irq, void *data); +int pl111_connector_init(struct drm_device *dev); +int pl111_encoder_init(struct drm_device *dev); +int pl111_dumb_create(struct drm_file *file_priv, + struct drm_device *dev, + struct drm_mode_create_dumb *args); + +#endif /* _PL111_DRM_H_ */ diff --git a/drivers/gpu/drm/pl111/pl111_drv.c b/drivers/gpu/drm/pl111/pl111_drv.c new file mode 100644 index 000000000000..936403f65508 --- /dev/null +++ b/drivers/gpu/drm/pl111/pl111_drv.c @@ -0,0 +1,272 @@ +/* + * (C) COPYRIGHT 2012-2013 ARM Limited. All rights reserved. + * + * Parts of this file were based on sources as follows: + * + * Copyright (c) 2006-2008 Intel Corporation + * Copyright (c) 2007 Dave Airlie + * Copyright (C) 2011 Texas Instruments + * + * 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: ARM PrimeCell PL111 CLCD Driver + * + * The PL111 is a simple LCD controller that can support TFT and STN + * displays. This driver exposes a standard KMS interface for them. + * + * This driver uses the same Device Tree binding as the fbdev CLCD + * driver. While the fbdev driver supports panels that may be + * connected to the CLCD internally to the CLCD driver, in DRM the + * panels get split out to drivers/gpu/drm/panels/. This means that, + * in converting from using fbdev to using DRM, you also need to write + * a panel driver (which may be as simple as an entry in + * panel-simple.c). + * + * The driver currently doesn't expose the cursor. The DRM API for + * cursors requires support for 64x64 ARGB8888 cursor images, while + * the hardware can only support 64x64 monochrome with masking + * cursors. While one could imagine trying to hack something together + * to look at the ARGB8888 and program reasonable in monochrome, we + * just don't expose the cursor at all instead, and leave cursor + * support to the X11 software cursor layer. + * + * TODO: + * + * - Fix race between setting plane base address and getting IRQ for + * vsync firing the pageflip completion. + * + * - Expose the correct set of formats we can support based on the + * "arm,pl11x,tft-r0g0b0-pads" DT property. + * + * - Use the "max-memory-bandwidth" DT property to filter the + * supported formats. + * + * - Read back hardware state at boot to skip reprogramming the + * hardware when doing a no-op modeset. + * + * - Use the internal clock divisor to reduce power consumption by + * using HCLK (apb_pclk) when appropriate. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pl111_drm.h" + +#define DRIVER_DESC "DRM module for PL111" + +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 pl111_modeset_init(struct drm_device *dev) +{ + struct drm_mode_config *mode_config; + struct pl111_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 = 1; + mode_config->max_width = 1024; + mode_config->min_height = 1; + mode_config->max_height = 768; + + ret = pl111_connector_init(dev); + if (ret) { + dev_err(dev->dev, "Failed to create pl111_drm_connector\n"); + goto out_config; + } + + /* Don't actually attach if we didn't find a drm_panel + * attached to us. This will allow a kernel to include both + * the fbdev pl111 driver and this one, and choose between + * them based on which subsystem has support for the panel. + */ + if (!priv->connector.panel) { + dev_info(dev->dev, + "Disabling due to lack of DRM panel device.\n"); + ret = -ENODEV; + goto out_config; + } + + ret = pl111_display_init(dev); + if (ret != 0) { + dev_err(dev->dev, "Failed to init display\n"); + goto out_config; + } + + ret = drm_vblank_init(dev, 1); + if (ret != 0) { + dev_err(dev->dev, "Failed to init vblank\n"); + goto out_config; + } + + drm_mode_config_reset(dev); + + priv->fbdev = drm_fbdev_cma_init(dev, 32, + 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 pl111_lastclose(struct drm_device *dev) +{ + struct pl111_drm_dev_private *priv = dev->dev_private; + + drm_fbdev_cma_restore_mode(priv->fbdev); +} + +static struct drm_driver pl111_drm_driver = { + .driver_features = + DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, + .lastclose = pl111_lastclose, + .ioctls = NULL, + .fops = &drm_fops, + .name = "pl111", + .desc = DRIVER_DESC, + .date = "20170317", + .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 = pl111_enable_vblank, + .disable_vblank = pl111_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, +}; + +#ifdef CONFIG_ARM_AMBA +static int pl111_amba_probe(struct amba_device *amba_dev, + const struct amba_id *id) +{ + struct device *dev = &amba_dev->dev; + struct pl111_drm_dev_private *priv; + struct drm_device *drm; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + drm = drm_dev_alloc(&pl111_drm_driver, dev); + if (IS_ERR(drm)) + return PTR_ERR(drm); + amba_set_drvdata(amba_dev, drm); + priv->drm = drm; + drm->dev_private = priv; + + priv->clk = devm_clk_get(dev, "clcdclk"); + if (IS_ERR(priv->clk)) { + dev_err(dev, "CLCD: unable to get clk.\n"); + ret = PTR_ERR(priv->clk); + goto dev_unref; + } + + priv->regs = devm_ioremap_resource(dev, &amba_dev->res); + if (!priv->regs) { + dev_err(dev, "%s failed mmio\n", __func__); + return -EINVAL; + } + + /* turn off interrupts before requesting the irq */ + writel(0, priv->regs + CLCD_PL111_IENB); + + ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0, + "pl111", priv); + if (ret != 0) { + dev_err(dev, "%s failed irq %d\n", __func__, ret); + return ret; + } + + ret = pl111_modeset_init(drm); + if (ret != 0) + goto dev_unref; + + ret = drm_dev_register(drm, 0); + if (ret < 0) + goto dev_unref; + + return 0; + +dev_unref: + drm_dev_unref(drm); + return ret; +} + +static int pl111_amba_remove(struct amba_device *amba_dev) +{ + struct drm_device *drm = amba_get_drvdata(amba_dev); + struct pl111_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); + drm_dev_unref(drm); + + return 0; +} + +static struct amba_id pl111_id_table[] = { + { + .id = 0x00041111, + .mask = 0x000fffff, + }, + {0, 0}, +}; + +static struct amba_driver pl111_amba_driver = { + .drv = { + .name = "drm-clcd-pl111", + }, + .probe = pl111_amba_probe, + .remove = pl111_amba_remove, + .id_table = pl111_id_table, +}; + +module_amba_driver(pl111_amba_driver); +#endif /* CONFIG_ARM_AMBA */ + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("ARM Ltd."); +MODULE_LICENSE("GPL"); -- 2.11.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Anholt Subject: [PATCH v6 2/2] drm/pl111: Initial drm/kms driver for pl111 Date: Wed, 12 Apr 2017 20:17:46 -0700 Message-ID: <20170413031746.12921-2-eric@anholt.net> References: <20170413031746.12921-1-eric@anholt.net> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from anholt.net (anholt.net [50.246.234.109]) by gabe.freedesktop.org (Postfix) with ESMTP id 5C2A06E7ED for ; Thu, 13 Apr 2017 03:17:53 +0000 (UTC) In-Reply-To: <20170413031746.12921-1-eric@anholt.net> 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, tom.cooksey@arm.com, Russell King , linus.walleij@linaro.org Cc: linux-kernel@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org RnJvbTogVG9tIENvb2tzZXkgPHRvbS5jb29rc2V5QGFybS5jb20+CgpUaGlzIGlzIGEgbW9kZXNl dHRpbmcgZHJpdmVyIGZvciB0aGUgcGwxMTEgQ0xDRCBkaXNwbGF5IGNvbnRyb2xsZXIKZm91bmQg b24gdmFyaW91cyBBUk0gcGxhdGZvcm1zIHN1Y2ggYXMgdGhlIFZlcnNhdGlsZSBFeHByZXNzLiBU aGUKZHJpdmVyIGhhcyBvbmx5IGJlZW4gdGVzdGVkIG9uIHRoZSBiY205MTEzNjBfZW50cGhuIHBs YXRmb3JtIHNvIGZhciwKd2l0aCBQUklNRS1iYXNlZCBidWZmZXIgc2hhcmluZyBiZXR3ZWVuIHZj NCBhbmQgY2xjZC4KCkl0IHJldXNlcyB0aGUgZXhpc3RpbmcgZGV2aWNldHJlZSBiaW5kaW5nLCB3 aGlsZSBub3QgdXNpbmcgcXVpdGUgYXMKbWFueSBvZiBpdHMgcHJvcGVydGllcyBhcyB0aGUgZmJk ZXYgZHJpdmVyIGRvZXMgKHRob3NlIGFyZSBsZWZ0IGZvcgpmdXR1cmUgd29yaykuCgp2MjogTmVh cmx5IGNvbXBsZXRlIHJld3JpdGUgYnkgYW5ob2x0LCBjdXR0aW5nIDIvMyBvZiB0aGUgY29kZSB0 aGFua3MKICAgIHRvIERSTSBjb3JlJ3MgZXhjZWxsZW50IG5ldyBoZWxwZXJzLgp2MzogRG9uJ3Qg bWF0Y2ggcGwxMTAgYW55IG1vcmUsIGRvbid0IGF0dGFjaCBpZiB3ZSBkb24ndCBoYXZlIGEgRFJN CiAgICBwYW5lbCwgdXNlIERSTV9HRU1fQ01BX0ZPUFMsIHVwZGF0ZSBNQUlOVEFJTkVSUywgdXNl IHRoZSBzaW1wbGUKICAgIGRpc3BsYXkgaGVscGVyLCB1c2UgZHJtX2dlbV9jbWFfZHVtYl9jcmVh dGUgKHNhbWUgYXMgb3VyIHdyYXBwZXIpLgp2NDogQ2hhbmdlIHRoZSBkcml2ZXIncyAubmFtZSB0 byBub3QgY2xhc2ggd2l0aCBmYmRldiBpbiBzeXNmcywgZHJvcAogICAgcGxhdGZvcm0gYWxpYXMs IGRyb3AgcmVkdW5kYW50ICJkcm0iIGluIERSTSBkcml2ZXIgbmFtZSwgaG9vayB1cAogICAgLnBy ZXBhcmVfZmIgdG8gdGhlIENNQSBoZWxwZXIgc28gdGhhdCBETUEgZmVuY2VzIHNob3VsZCB3b3Jr Lgp2NTogTW92ZSByZWdpc3RlciBkZWZpbml0aW9ucyBpbnNpZGUgdGhlIGRyaXZlciBkaXJlY3Rv cnksIGZpeCBidWlsZAogICAgaW4gQ09NUElMRV9URVNUIGFuZCAhQU1CQSBtb2RlLgp2NjogRHJv cCBUSU0yX0NMS1NFTCBmb3Igbm93IHRvIGJlIGNvbnNpc3RlbnQgd2l0aCBleGlzdGluZyBEVAog ICAgYmluZGluZ3MsIHN3aXRjaCBiYWNrIHRvIGV4dGVybmFsIHJlZ2lzdGVyIGRlZmluaXRpb25z LgoKU2lnbmVkLW9mZi1ieTogVG9tIENvb2tzZXkgPHRvbS5jb29rc2V5QGFybS5jb20+ClNpZ25l ZC1vZmYtYnk6IEVyaWMgQW5ob2x0IDxlcmljQGFuaG9sdC5uZXQ+ClJldmlld2VkLWJ5OiBMaW51 cyBXYWxsZWlqIDxsaW51cy53YWxsZWlqQGxpbmFyby5vcmc+ICh2NSkKLS0tCiBEb2N1bWVudGF0 aW9uL2dwdS9pbmRleC5yc3QgICAgICAgICAgICAgfCAgIDEgKwogRG9jdW1lbnRhdGlvbi9ncHUv cGwxMTEucnN0ICAgICAgICAgICAgIHwgICA2ICsKIE1BSU5UQUlORVJTICAgICAgICAgICAgICAg ICAgICAgICAgICAgICB8ICAgNiArCiBkcml2ZXJzL2dwdS9kcm0vS2NvbmZpZyAgICAgICAgICAg ICAgICAgfCAgIDIgKwogZHJpdmVycy9ncHUvZHJtL01ha2VmaWxlICAgICAgICAgICAgICAgIHwg ICAxICsKIGRyaXZlcnMvZ3B1L2RybS9wbDExMS9LY29uZmlnICAgICAgICAgICB8ICAxMiArKwog ZHJpdmVycy9ncHUvZHJtL3BsMTExL01ha2VmaWxlICAgICAgICAgIHwgICA1ICsKIGRyaXZlcnMv Z3B1L2RybS9wbDExMS9wbDExMV9jb25uZWN0b3IuYyB8IDEyNyArKysrKysrKysrKysKIGRyaXZl cnMvZ3B1L2RybS9wbDExMS9wbDExMV9kaXNwbGF5LmMgICB8IDM0NCArKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKwogZHJpdmVycy9ncHUvZHJtL3BsMTExL3BsMTExX2RybS5oICAgICAg IHwgIDU2ICsrKysrKwogZHJpdmVycy9ncHUvZHJtL3BsMTExL3BsMTExX2Rydi5jICAgICAgIHwg MjcyICsrKysrKysrKysrKysrKysrKysrKysrKysKIDExIGZpbGVzIGNoYW5nZWQsIDgzMiBpbnNl cnRpb25zKCspCiBjcmVhdGUgbW9kZSAxMDA2NDQgRG9jdW1lbnRhdGlvbi9ncHUvcGwxMTEucnN0 CiBjcmVhdGUgbW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3BsMTExL0tjb25maWcKIGNyZWF0 ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vcGwxMTEvTWFrZWZpbGUKIGNyZWF0ZSBtb2Rl IDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfY29ubmVjdG9yLmMKIGNyZWF0ZSBt b2RlIDEwMDY0NCBkcml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfZGlzcGxheS5jCiBjcmVhdGUg bW9kZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3BsMTExL3BsMTExX2RybS5oCiBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9ncHUvZHJtL3BsMTExL3BsMTExX2Rydi5jCgpkaWZmIC0tZ2l0IGEv RG9jdW1lbnRhdGlvbi9ncHUvaW5kZXgucnN0IGIvRG9jdW1lbnRhdGlvbi9ncHUvaW5kZXgucnN0 CmluZGV4IGM1NzJmMDkyNzM5ZS4uMDM3YTM5YWMxODA3IDEwMDY0NAotLS0gYS9Eb2N1bWVudGF0 aW9uL2dwdS9pbmRleC5yc3QKKysrIGIvRG9jdW1lbnRhdGlvbi9ncHUvaW5kZXgucnN0CkBAIC0x Miw2ICsxMiw3IEBAIExpbnV4IEdQVSBEcml2ZXIgRGV2ZWxvcGVyJ3MgR3VpZGUKICAgIGRybS11 YXBpCiAgICBpOTE1CiAgICBtZXNvbgorICAgcGwxMTEKICAgIHRpbnlkcm0KICAgIHZjNAogICAg dmdhLXN3aXRjaGVyb28KZGlmZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vZ3B1L3BsMTExLnJzdCBi L0RvY3VtZW50YXRpb24vZ3B1L3BsMTExLnJzdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAw MDAwMDAwMDAwMDAuLjliMDM3MzZkMzNkZAotLS0gL2Rldi9udWxsCisrKyBiL0RvY3VtZW50YXRp b24vZ3B1L3BsMTExLnJzdApAQCAtMCwwICsxLDYgQEAKKz09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PQorIGRybS9wbDExMSBBUk0gUHJpbWVDZWxsIFBMMTExIENMQ0Qg RHJpdmVyCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworLi4g a2VybmVsLWRvYzo6IGRyaXZlcnMvZ3B1L2RybS9wbDExMS9wbDExMV9kcnYuYworICAgOmRvYzog QVJNIFByaW1lQ2VsbCBQTDExMSBDTENEIERyaXZlcgpkaWZmIC0tZ2l0IGEvTUFJTlRBSU5FUlMg Yi9NQUlOVEFJTkVSUwppbmRleCBjMzZkZmFlZWYyNmIuLjc4MDYzMGUyMDU1YiAxMDA2NDQKLS0t IGEvTUFJTlRBSU5FUlMKKysrIGIvTUFJTlRBSU5FUlMKQEAgLTQxNjEsNiArNDE2MSwxMiBAQCBG OglpbmNsdWRlL2RybS9kcm0qCiBGOglpbmNsdWRlL3VhcGkvZHJtL2RybSoKIEY6CWluY2x1ZGUv bGludXgvdmdhKgogCitEUk0gRFJJVkVSIEZPUiBBUk0gUEwxMTEgQ0xDRAorTToJRXJpYyBBbmhv bHQgPGVyaWNAYW5ob2x0Lm5ldD4KK1Q6CWdpdCBnaXQ6Ly9hbm9uZ2l0LmZyZWVkZXNrdG9wLm9y Zy9kcm0vZHJtLW1pc2MKK1M6CVN1cHBvcnRlZAorRjoJZHJpdmVycy9ncHUvZHJtL3BsMTExLwor CiBEUk0gRFJJVkVSIEZPUiBBU1QgU0VSVkVSIEdSQVBISUNTIENISVBTCiBNOglEYXZlIEFpcmxp ZSA8YWlybGllZEByZWRoYXQuY29tPgogUzoJT2RkIEZpeGVzCmRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vS2NvbmZpZyBiL2RyaXZlcnMvZ3B1L2RybS9LY29uZmlnCmluZGV4IDc4ZDdmYzBl YmI1Ny4uZDFjNmMxMjE5OWI3IDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vS2NvbmZpZwor KysgYi9kcml2ZXJzL2dwdS9kcm0vS2NvbmZpZwpAQCAtMjc0LDYgKzI3NCw4IEBAIHNvdXJjZSAi ZHJpdmVycy9ncHUvZHJtL21lc29uL0tjb25maWciCiAKIHNvdXJjZSAiZHJpdmVycy9ncHUvZHJt L3Rpbnlkcm0vS2NvbmZpZyIKIAorc291cmNlICJkcml2ZXJzL2dwdS9kcm0vcGwxMTEvS2NvbmZp ZyIKKwogIyBLZWVwIGxlZ2FjeSBkcml2ZXJzIGxhc3QKIAogbWVudWNvbmZpZyBEUk1fTEVHQUNZ CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vTWFrZWZpbGUgYi9kcml2ZXJzL2dwdS9kcm0v TWFrZWZpbGUKaW5kZXggNTlmMGY5YjY5NmViLi4yOGRjZjkzZTFkOGYgMTAwNjQ0Ci0tLSBhL2Ry aXZlcnMvZ3B1L2RybS9NYWtlZmlsZQorKysgYi9kcml2ZXJzL2dwdS9kcm0vTWFrZWZpbGUKQEAg LTk2LDMgKzk2LDQgQEAgb2JqLXkJCQkrPSBoaXNpbGljb24vCiBvYmotJChDT05GSUdfRFJNX1pU RSkJKz0genRlLwogb2JqLSQoQ09ORklHX0RSTV9NWFNGQikJKz0gbXhzZmIvCiBvYmotJChDT05G SUdfRFJNX1RJTllEUk0pICs9IHRpbnlkcm0vCitvYmotJChDT05GSUdfRFJNX1BMMTExKSArPSBw bDExMS8KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9wbDExMS9LY29uZmlnIGIvZHJpdmVy cy9ncHUvZHJtL3BsMTExL0tjb25maWcKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAw MDAwMDAwLi5lZGU0OWVmZDUzMWYKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL2dwdS9kcm0v cGwxMTEvS2NvbmZpZwpAQCAtMCwwICsxLDEyIEBACitjb25maWcgRFJNX1BMMTExCisJdHJpc3Rh dGUgIkRSTSBTdXBwb3J0IGZvciBQTDExMSBDTENEIENvbnRyb2xsZXIiCisJZGVwZW5kcyBvbiBE Uk0KKwlkZXBlbmRzIG9uIEFSTSB8fCBBUk02NCB8fCBDT01QSUxFX1RFU1QKKwlzZWxlY3QgRFJN X0tNU19IRUxQRVIKKwlzZWxlY3QgRFJNX0tNU19DTUFfSEVMUEVSCisJc2VsZWN0IERSTV9HRU1f Q01BX0hFTFBFUgorCXNlbGVjdCBWVF9IV19DT05TT0xFX0JJTkRJTkcgaWYgRlJBTUVCVUZGRVJf Q09OU09MRQorCWhlbHAKKwkgIENob29zZSB0aGlzIG9wdGlvbiBmb3IgRFJNIHN1cHBvcnQgZm9y IHRoZSBQTDExMSBDTENEIGNvbnRyb2xsZXIuCisJICBJZiBNIGlzIHNlbGVjdGVkIHRoZSBtb2R1 bGUgd2lsbCBiZSBjYWxsZWQgcGwxMTFfZHJtLgorCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9k cm0vcGwxMTEvTWFrZWZpbGUgYi9kcml2ZXJzL2dwdS9kcm0vcGwxMTEvTWFrZWZpbGUKbmV3IGZp bGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4wMWNhZWU3MjdjMTMKLS0tIC9kZXYv bnVsbAorKysgYi9kcml2ZXJzL2dwdS9kcm0vcGwxMTEvTWFrZWZpbGUKQEAgLTAsMCArMSw1IEBA CitwbDExMV9kcm0teSArPQlwbDExMV9jb25uZWN0b3IubyBcCisJCXBsMTExX2Rpc3BsYXkubyBc CisJCXBsMTExX2Rydi5vCisKK29iai0kKENPTkZJR19EUk1fUEwxMTEpICs9IHBsMTExX2RybS5v CmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfY29ubmVjdG9yLmMgYi9k cml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfY29ubmVjdG9yLmMKbmV3IGZpbGUgbW9kZSAxMDA2 NDQKaW5kZXggMDAwMDAwMDAwMDAwLi4zZjIxM2Q3ZTc2OTIKLS0tIC9kZXYvbnVsbAorKysgYi9k cml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfY29ubmVjdG9yLmMKQEAgLTAsMCArMSwxMjcgQEAK Ky8qCisgKiAoQykgQ09QWVJJR0hUIDIwMTItMjAxMyBBUk0gTGltaXRlZC4gQWxsIHJpZ2h0cyBy ZXNlcnZlZC4KKyAqCisgKiBQYXJ0cyBvZiB0aGlzIGZpbGUgd2VyZSBiYXNlZCBvbiBzb3VyY2Vz IGFzIGZvbGxvd3M6CisgKgorICogQ29weXJpZ2h0IChjKSAyMDA2LTIwMDggSW50ZWwgQ29ycG9y YXRpb24KKyAqIENvcHlyaWdodCAoYykgMjAwNyBEYXZlIEFpcmxpZSA8YWlybGllZEBsaW51eC5p ZT4KKyAqIENvcHlyaWdodCAoQykgMjAxMSBUZXhhcyBJbnN0cnVtZW50cworICoKKyAqIFRoaXMg cHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlIGFuZCBpcyBwcm92aWRlZCB0byB5b3UgdW5kZXIgdGhl IHRlcm1zIG9mIHRoZQorICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFz IHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQorICogRm91bmRhdGlvbiwgYW5kIGFueSB1 c2UgYnkgeW91IG9mIHRoaXMgcHJvZ3JhbSBpcyBzdWJqZWN0IHRvIHRoZSB0ZXJtcyBvZgorICog c3VjaCBHTlUgbGljZW5jZS4KKyAqCisgKi8KKworLyoqCisgKiBwbDExMV9kcm1fY29ubmVjdG9y LmMKKyAqIEltcGxlbWVudGF0aW9uIG9mIHRoZSBjb25uZWN0b3IgZnVuY3Rpb25zIGZvciBQTDEx MSBEUk0KKyAqLworI2luY2x1ZGUgPGxpbnV4L2FtYmEvY2xjZC1yZWdzLmg+CisjaW5jbHVkZSA8 bGludXgvdmVyc2lvbi5oPgorI2luY2x1ZGUgPGxpbnV4L3NobWVtX2ZzLmg+CisjaW5jbHVkZSA8 bGludXgvZG1hLWJ1Zi5oPgorCisjaW5jbHVkZSA8ZHJtL2RybVAuaD4KKyNpbmNsdWRlIDxkcm0v ZHJtX2F0b21pY19oZWxwZXIuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX2NydGNfaGVscGVyLmg+Cisj aW5jbHVkZSA8ZHJtL2RybV9vZi5oPgorI2luY2x1ZGUgPGRybS9kcm1fcGFuZWwuaD4KKworI2lu Y2x1ZGUgInBsMTExX2RybS5oIgorCitzdGF0aWMgdm9pZCBwbDExMV9jb25uZWN0b3JfZGVzdHJv eShzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yKQoreworCXN0cnVjdCBwbDExMV9kcm1f Y29ubmVjdG9yICpwbDExMV9jb25uZWN0b3IgPQorCQl0b19wbDExMV9jb25uZWN0b3IoY29ubmVj dG9yKTsKKworCWlmIChwbDExMV9jb25uZWN0b3ItPnBhbmVsKQorCQlkcm1fcGFuZWxfZGV0YWNo KHBsMTExX2Nvbm5lY3Rvci0+cGFuZWwpOworCisJZHJtX2Nvbm5lY3Rvcl91bnJlZ2lzdGVyKGNv bm5lY3Rvcik7CisJZHJtX2Nvbm5lY3Rvcl9jbGVhbnVwKGNvbm5lY3Rvcik7Cit9CisKK3N0YXRp YyBlbnVtIGRybV9jb25uZWN0b3Jfc3RhdHVzIHBsMTExX2Nvbm5lY3Rvcl9kZXRlY3Qoc3RydWN0 IGRybV9jb25uZWN0b3IKKwkJCQkJCQkqY29ubmVjdG9yLCBib29sIGZvcmNlKQoreworCXN0cnVj dCBwbDExMV9kcm1fY29ubmVjdG9yICpwbDExMV9jb25uZWN0b3IgPQorCQl0b19wbDExMV9jb25u ZWN0b3IoY29ubmVjdG9yKTsKKworCXJldHVybiAocGwxMTFfY29ubmVjdG9yLT5wYW5lbCA/CisJ CWNvbm5lY3Rvcl9zdGF0dXNfY29ubmVjdGVkIDoKKwkJY29ubmVjdG9yX3N0YXR1c19kaXNjb25u ZWN0ZWQpOworfQorCitzdGF0aWMgaW50IHBsMTExX2Nvbm5lY3Rvcl9oZWxwZXJfZ2V0X21vZGVz KHN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0b3IpCit7CisJc3RydWN0IHBsMTExX2RybV9j b25uZWN0b3IgKnBsMTExX2Nvbm5lY3RvciA9CisJCXRvX3BsMTExX2Nvbm5lY3Rvcihjb25uZWN0 b3IpOworCisJaWYgKCFwbDExMV9jb25uZWN0b3ItPnBhbmVsKQorCQlyZXR1cm4gMDsKKworCXJl dHVybiBkcm1fcGFuZWxfZ2V0X21vZGVzKHBsMTExX2Nvbm5lY3Rvci0+cGFuZWwpOworfQorCitj b25zdCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9mdW5jcyBjb25uZWN0b3JfZnVuY3MgPSB7CisJLmZp bGxfbW9kZXMgPSBkcm1faGVscGVyX3Byb2JlX3NpbmdsZV9jb25uZWN0b3JfbW9kZXMsCisJLmRl c3Ryb3kgPSBwbDExMV9jb25uZWN0b3JfZGVzdHJveSwKKwkuZGV0ZWN0ID0gcGwxMTFfY29ubmVj dG9yX2RldGVjdCwKKwkuZHBtcyA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kcG1zLAor CS5yZXNldCA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9yZXNldCwKKwkuYXRvbWljX2R1 cGxpY2F0ZV9zdGF0ZSA9IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kdXBsaWNhdGVfc3Rh dGUsCisJLmF0b21pY19kZXN0cm95X3N0YXRlID0gZHJtX2F0b21pY19oZWxwZXJfY29ubmVjdG9y X2Rlc3Ryb3lfc3RhdGUsCit9OworCitjb25zdCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9oZWxwZXJf ZnVuY3MgY29ubmVjdG9yX2hlbHBlcl9mdW5jcyA9IHsKKwkuZ2V0X21vZGVzID0gcGwxMTFfY29u bmVjdG9yX2hlbHBlcl9nZXRfbW9kZXMsCit9OworCisvKiBXYWxrcyB0aGUgT0YgZ3JhcGggdG8g ZmluZCB0aGUgcGFuZWwgbm9kZSBhbmQgdGhlbiBhc2tzIERSTSB0byBsb29rCisgKiB1cCB0aGUg cGFuZWwuCisgKi8KK3N0YXRpYyBzdHJ1Y3QgZHJtX3BhbmVsICpwbDExMV9nZXRfcGFuZWwoc3Ry dWN0IGRldmljZSAqZGV2KQoreworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqZW5kcG9pbnQsICpwYW5l bF9ub2RlOworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBkZXYtPm9mX25vZGU7CisJc3RydWN0 IGRybV9wYW5lbCAqcGFuZWw7CisKKwllbmRwb2ludCA9IG9mX2dyYXBoX2dldF9uZXh0X2VuZHBv aW50KG5wLCBOVUxMKTsKKwlpZiAoIWVuZHBvaW50KSB7CisJCWRldl9lcnIoZGV2LCAibm8gZW5k cG9pbnQgdG8gZmV0Y2ggcGFuZWxcbiIpOworCQlyZXR1cm4gTlVMTDsKKwl9CisKKwkvKiBkb24n dCBwcm9jZWVkIGlmIHdlIGhhdmUgYW4gZW5kcG9pbnQgYnV0IG5vIHBhbmVsX25vZGUgdGllZCB0 byBpdCAqLworCXBhbmVsX25vZGUgPSBvZl9ncmFwaF9nZXRfcmVtb3RlX3BvcnRfcGFyZW50KGVu ZHBvaW50KTsKKwlvZl9ub2RlX3B1dChlbmRwb2ludCk7CisJaWYgKCFwYW5lbF9ub2RlKSB7CisJ CWRldl9lcnIoZGV2LCAibm8gdmFsaWQgcGFuZWwgbm9kZVxuIik7CisJCXJldHVybiBOVUxMOwor CX0KKworCXBhbmVsID0gb2ZfZHJtX2ZpbmRfcGFuZWwocGFuZWxfbm9kZSk7CisJb2Zfbm9kZV9w dXQocGFuZWxfbm9kZSk7CisKKwlyZXR1cm4gcGFuZWw7Cit9CisKK2ludCBwbDExMV9jb25uZWN0 b3JfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KQoreworCXN0cnVjdCBwbDExMV9kcm1fZGV2 X3ByaXZhdGUgKnByaXYgPSBkZXYtPmRldl9wcml2YXRlOworCXN0cnVjdCBwbDExMV9kcm1fY29u bmVjdG9yICpwbDExMV9jb25uZWN0b3IgPSAmcHJpdi0+Y29ubmVjdG9yOworCXN0cnVjdCBkcm1f Y29ubmVjdG9yICpjb25uZWN0b3IgPSAmcGwxMTFfY29ubmVjdG9yLT5jb25uZWN0b3I7CisKKwlk cm1fY29ubmVjdG9yX2luaXQoZGV2LCBjb25uZWN0b3IsICZjb25uZWN0b3JfZnVuY3MsCisJCQkg ICBEUk1fTU9ERV9DT05ORUNUT1JfRFBJKTsKKwlkcm1fY29ubmVjdG9yX2hlbHBlcl9hZGQoY29u bmVjdG9yLCAmY29ubmVjdG9yX2hlbHBlcl9mdW5jcyk7CisKKwlwbDExMV9jb25uZWN0b3ItPnBh bmVsID0gcGwxMTFfZ2V0X3BhbmVsKGRldi0+ZGV2KTsKKwlpZiAocGwxMTFfY29ubmVjdG9yLT5w YW5lbCkKKwkJZHJtX3BhbmVsX2F0dGFjaChwbDExMV9jb25uZWN0b3ItPnBhbmVsLCBjb25uZWN0 b3IpOworCisJcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9wbDEx MS9wbDExMV9kaXNwbGF5LmMgYi9kcml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfZGlzcGxheS5j Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAwMC4uY2IwMTcwNTMzMzQ2Ci0t LSAvZGV2L251bGwKKysrIGIvZHJpdmVycy9ncHUvZHJtL3BsMTExL3BsMTExX2Rpc3BsYXkuYwpA QCAtMCwwICsxLDM0NCBAQAorLyoKKyAqIChDKSBDT1BZUklHSFQgMjAxMi0yMDEzIEFSTSBMaW1p dGVkLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqIFBhcnRzIG9mIHRoaXMgZmlsZSB3ZXJl IGJhc2VkIG9uIHNvdXJjZXMgYXMgZm9sbG93czoKKyAqCisgKiBDb3B5cmlnaHQgKGMpIDIwMDYt MjAwOCBJbnRlbCBDb3Jwb3JhdGlvbgorICogQ29weXJpZ2h0IChjKSAyMDA3IERhdmUgQWlybGll IDxhaXJsaWVkQGxpbnV4LmllPgorICogQ29weXJpZ2h0IChDKSAyMDExIFRleGFzIEluc3RydW1l bnRzCisgKgorICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmUgYW5kIGlzIHByb3ZpZGVk IHRvIHlvdSB1bmRlciB0aGUgdGVybXMgb2YgdGhlCisgKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGlj ZW5zZSB2ZXJzaW9uIDIgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlCisgKiBGb3Vu ZGF0aW9uLCBhbmQgYW55IHVzZSBieSB5b3Ugb2YgdGhpcyBwcm9ncmFtIGlzIHN1YmplY3QgdG8g dGhlIHRlcm1zIG9mCisgKiBzdWNoIEdOVSBsaWNlbmNlLgorICoKKyAqLworCisjaW5jbHVkZSA8 bGludXgvYW1iYS9jbGNkLXJlZ3MuaD4KKyNpbmNsdWRlIDxsaW51eC9jbGsuaD4KKyNpbmNsdWRl IDxsaW51eC92ZXJzaW9uLmg+CisjaW5jbHVkZSA8bGludXgvZG1hLWJ1Zi5oPgorI2luY2x1ZGUg PGxpbnV4L29mX2dyYXBoLmg+CisKKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgorI2luY2x1ZGUgPGRy bS9kcm1fcGFuZWwuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX2dlbV9jbWFfaGVscGVyLmg+CisjaW5j bHVkZSA8ZHJtL2RybV9mYl9jbWFfaGVscGVyLmg+CisKKyNpbmNsdWRlICJwbDExMV9kcm0uaCIK KworaXJxcmV0dXJuX3QgcGwxMTFfaXJxKGludCBpcnEsIHZvaWQgKmRhdGEpCit7CisJc3RydWN0 IHBsMTExX2RybV9kZXZfcHJpdmF0ZSAqcHJpdiA9IGRhdGE7CisJdTMyIGlycV9zdGF0OworCWly cXJldHVybl90IHN0YXR1cyA9IElSUV9OT05FOworCisJaXJxX3N0YXQgPSByZWFkbChwcml2LT5y ZWdzICsgQ0xDRF9QTDExMV9NSVMpOworCisJaWYgKCFpcnFfc3RhdCkKKwkJcmV0dXJuIElSUV9O T05FOworCisJaWYgKGlycV9zdGF0ICYgQ0xDRF9JUlFfTkVYVEJBU0VfVVBEQVRFKSB7CisJCWRy bV9jcnRjX2hhbmRsZV92YmxhbmsoJnByaXYtPnBpcGUuY3J0Yyk7CisKKwkJc3RhdHVzID0gSVJR X0hBTkRMRUQ7CisJfQorCisJLyogQ2xlYXIgdGhlIGludGVycnVwdCBvbmNlIGRvbmUgKi8KKwl3 cml0ZWwoaXJxX3N0YXQsIHByaXYtPnJlZ3MgKyBDTENEX1BMMTExX0lDUik7CisKKwlyZXR1cm4g c3RhdHVzOworfQorCitzdGF0aWMgdTMyIHBsMTExX2dldF9mYl9vZmZzZXQoc3RydWN0IGRybV9w bGFuZV9zdGF0ZSAqcHN0YXRlKQoreworCXN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiID0gcHN0 YXRlLT5mYjsKKwlzdHJ1Y3QgZHJtX2dlbV9jbWFfb2JqZWN0ICpvYmogPSBkcm1fZmJfY21hX2dl dF9nZW1fb2JqKGZiLCAwKTsKKworCXJldHVybiAob2JqLT5wYWRkciArCisJCWZiLT5vZmZzZXRz WzBdICsKKwkJZmItPmZvcm1hdC0+Y3BwWzBdICogcHN0YXRlLT5zcmNfeCArCisJCWZiLT5waXRj aGVzWzBdICogcHN0YXRlLT5zcmNfeSk7Cit9CisKK3N0YXRpYyBpbnQgcGwxMTFfZGlzcGxheV9j aGVjayhzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUsCisJCQkgICAgICAgc3Ry dWN0IGRybV9wbGFuZV9zdGF0ZSAqcHN0YXRlLAorCQkJICAgICAgIHN0cnVjdCBkcm1fY3J0Y19z dGF0ZSAqY3N0YXRlKQoreworCWNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlICptb2RlID0g JmNzdGF0ZS0+bW9kZTsKKwlzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyICpvbGRfZmIgPSBwaXBlLT5w bGFuZS5zdGF0ZS0+ZmI7CisJc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIgPSBwc3RhdGUtPmZi OworCisJaWYgKG1vZGUtPmhkaXNwbGF5ICUgMTYpCisJCXJldHVybiAtRUlOVkFMOworCisJaWYg KGZiKSB7CisJCXUzMiBvZmZzZXQgPSBwbDExMV9nZXRfZmJfb2Zmc2V0KHBzdGF0ZSk7CisKKwkJ LyogRkIgYmFzZSBhZGRyZXNzIG11c3QgYmUgZHdvcmQgYWxpZ25lZC4gKi8KKwkJaWYgKG9mZnNl dCAmIDMpCisJCQlyZXR1cm4gLUVJTlZBTDsKKworCQkvKiBUaGVyZSdzIG5vIHBpdGNoIHJlZ2lz dGVyIC0tIHRoZSBtb2RlJ3MgaGRpc3BsYXkKKwkJICogY29udHJvbHMgaXQuCisJCSAqLworCQlp ZiAoZmItPnBpdGNoZXNbMF0gIT0gbW9kZS0+aGRpc3BsYXkgKiBmYi0+Zm9ybWF0LT5jcHBbMF0p CisJCQlyZXR1cm4gLUVJTlZBTDsKKworCQkvKiBXZSBjYW4ndCBjaGFuZ2UgdGhlIEZCIGZvcm1h dCBpbiBhIGZsaWNrZXItZnJlZQorCQkgKiBtYW5uZXIgKGFuZCBvbmx5IHVwZGF0ZSBpdCBkdXJp bmcgQ1JUQyBlbmFibGUpLgorCQkgKi8KKwkJaWYgKG9sZF9mYiAmJiBvbGRfZmItPmZvcm1hdCAh PSBmYi0+Zm9ybWF0KQorCQkJY3N0YXRlLT5tb2RlX2NoYW5nZWQgPSB0cnVlOworCX0KKworCXJl dHVybiAwOworfQorCitzdGF0aWMgdm9pZCBwbDExMV9kaXNwbGF5X2VuYWJsZShzdHJ1Y3QgZHJt X3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUsCisJCQkJIHN0cnVjdCBkcm1fY3J0Y19zdGF0ZSAq Y3N0YXRlKQoreworCXN0cnVjdCBkcm1fY3J0YyAqY3J0YyA9ICZwaXBlLT5jcnRjOworCXN0cnVj dCBkcm1fcGxhbmUgKnBsYW5lID0gJnBpcGUtPnBsYW5lOworCXN0cnVjdCBkcm1fZGV2aWNlICpk cm0gPSBjcnRjLT5kZXY7CisJc3RydWN0IHBsMTExX2RybV9kZXZfcHJpdmF0ZSAqcHJpdiA9IGRy bS0+ZGV2X3ByaXZhdGU7CisJY29uc3Qgc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1vZGUgPSAm Y3N0YXRlLT5tb2RlOworCXN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiID0gcGxhbmUtPnN0YXRl LT5mYjsKKwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yID0gJnByaXYtPmNvbm5lY3Rv ci5jb25uZWN0b3I7CisJdTMyIGNudGw7CisJdTMyIHBwbCwgaHN3LCBoZnAsIGhicDsKKwl1MzIg bHBwLCB2c3csIHZmcCwgdmJwOworCXUzMiBjcGw7CisJaW50IHJldDsKKworCXJldCA9IGNsa19z ZXRfcmF0ZShwcml2LT5jbGssIG1vZGUtPmNsb2NrICogMTAwMCk7CisJaWYgKHJldCkgeworCQlk ZXZfZXJyKGRybS0+ZGV2LAorCQkJIkZhaWxlZCB0byBzZXQgcGl4ZWwgY2xvY2sgcmF0ZSB0byAl ZDogJWRcbiIsCisJCQltb2RlLT5jbG9jayAqIDEwMDAsIHJldCk7CisJfQorCisJY2xrX3ByZXBh cmVfZW5hYmxlKHByaXYtPmNsayk7CisKKwlwcGwgPSAobW9kZS0+aGRpc3BsYXkgLyAxNikgLSAx OworCWhzdyA9IG1vZGUtPmhzeW5jX2VuZCAtIG1vZGUtPmhzeW5jX3N0YXJ0IC0gMTsKKwloZnAg PSBtb2RlLT5oc3luY19zdGFydCAtIG1vZGUtPmhkaXNwbGF5IC0gMTsKKwloYnAgPSBtb2RlLT5o dG90YWwgLSBtb2RlLT5oc3luY19lbmQgLSAxOworCisJbHBwID0gbW9kZS0+dmRpc3BsYXkgLSAx OworCXZzdyA9IG1vZGUtPnZzeW5jX2VuZCAtIG1vZGUtPnZzeW5jX3N0YXJ0IC0gMTsKKwl2ZnAg PSBtb2RlLT52c3luY19zdGFydCAtIG1vZGUtPnZkaXNwbGF5OworCXZicCA9IG1vZGUtPnZ0b3Rh bCAtIG1vZGUtPnZzeW5jX2VuZDsKKworCWNwbCA9IG1vZGUtPmhkaXNwbGF5IC0gMTsKKworCXdy aXRlbCgocHBsIDw8IDIpIHwKKwkgICAgICAgKGhzdyA8PCA4KSB8CisJICAgICAgIChoZnAgPDwg MTYpIHwKKwkgICAgICAgKGhicCA8PCAyNCksCisJICAgICAgIHByaXYtPnJlZ3MgKyBDTENEX1RJ TTApOworCXdyaXRlbChscHAgfAorCSAgICAgICAodnN3IDw8IDEwKSB8CisJICAgICAgICh2ZnAg PDwgMTYpIHwKKwkgICAgICAgKHZicCA8PCAyNCksCisJICAgICAgIHByaXYtPnJlZ3MgKyBDTENE X1RJTTEpOworCS8qIFhYWDogV2UgY3VycmVudGx5IGFsd2F5cyB1c2UgQ0xDRENMSyB3aXRoIG5v IGRpdmlzb3IuICBXZQorCSAqIGNvdWxkIHByb2JhYmx5IHJlZHVjZSBwb3dlciBjb25zdW1wdGlv biBieSB1c2luZyBIQ0xLCisJICogKGFwYl9wY2xrKSB3aXRoIGEgZGl2aXNvciB3aGVuIGl0IGdl dHMgdXMgbmVhciBvdXIgdGFyZ2V0CisJICogcGl4ZWwgY2xvY2suCisJICovCisJd3JpdGVsKCgo bW9kZS0+ZmxhZ3MgJiBEUk1fTU9ERV9GTEFHX05IU1lOQykgPyBUSU0yX0lIUyA6IDApIHwKKwkg ICAgICAgKChtb2RlLT5mbGFncyAmIERSTV9NT0RFX0ZMQUdfTlZTWU5DKSA/IFRJTTJfSVZTIDog MCkgfAorCSAgICAgICAoKGNvbm5lY3Rvci0+ZGlzcGxheV9pbmZvLmJ1c19mbGFncyAmCisJCSBE Uk1fQlVTX0ZMQUdfREVfTE9XKSA/IFRJTTJfSU9FIDogMCkgfAorCSAgICAgICAoKGNvbm5lY3Rv ci0+ZGlzcGxheV9pbmZvLmJ1c19mbGFncyAmCisJCSBEUk1fQlVTX0ZMQUdfUElYREFUQV9ORUdF REdFKSA/IFRJTTJfSVBDIDogMCkgfAorCSAgICAgICBUSU0yX0JDRCB8CisJICAgICAgIChjcGwg PDwgMTYpIHwKKwkgICAgICAgcHJpdi0+cmVncyArIENMQ0RfVElNMik7CisJd3JpdGVsKDAsIHBy aXYtPnJlZ3MgKyBDTENEX1RJTTMpOworCisJZHJtX3BhbmVsX3ByZXBhcmUocHJpdi0+Y29ubmVj dG9yLnBhbmVsKTsKKworCS8qIEVuYWJsZSBhbmQgUG93ZXIgVXAgKi8KKwljbnRsID0gQ05UTF9M Q0RFTiB8IENOVExfTENEVEZUIHwgQ05UTF9MQ0RQV1IgfCBDTlRMX0xDRFZDT01QKDEpOworCisJ LyogTm90ZSB0aGF0IHRoZSB0aGUgaGFyZHdhcmUncyBmb3JtYXQgcmVhZGVyIHRha2VzICdyJyBm cm9tCisJICogdGhlIGxvdyBiaXQsIHdoaWxlIERSTSBmb3JtYXRzIGxpc3QgY2hhbm5lbHMgZnJv bSBoaWdoIGJpdAorCSAqIHRvIGxvdyBiaXQgYXMgeW91IHJlYWQgbGVmdCB0byByaWdodC4KKwkg Ki8KKwlzd2l0Y2ggKGZiLT5mb3JtYXQtPmZvcm1hdCkgeworCWNhc2UgRFJNX0ZPUk1BVF9BQkdS ODg4ODoKKwljYXNlIERSTV9GT1JNQVRfWEJHUjg4ODg6CisJCWNudGwgfD0gQ05UTF9MQ0RCUFAy NDsKKwkJYnJlYWs7CisJY2FzZSBEUk1fRk9STUFUX0FSR0I4ODg4OgorCWNhc2UgRFJNX0ZPUk1B VF9YUkdCODg4ODoKKwkJY250bCB8PSBDTlRMX0xDREJQUDI0IHwgQ05UTF9CR1I7CisJCWJyZWFr OworCWNhc2UgRFJNX0ZPUk1BVF9CR1I1NjU6CisJCWNudGwgfD0gQ05UTF9MQ0RCUFAxNl81NjU7 CisJCWJyZWFrOworCWNhc2UgRFJNX0ZPUk1BVF9SR0I1NjU6CisJCWNudGwgfD0gQ05UTF9MQ0RC UFAxNl81NjUgfCBDTlRMX0JHUjsKKwkJYnJlYWs7CisJY2FzZSBEUk1fRk9STUFUX0FCR1IxNTU1 OgorCWNhc2UgRFJNX0ZPUk1BVF9YQkdSMTU1NToKKwkJY250bCB8PSBDTlRMX0xDREJQUDE2Owor CQlicmVhazsKKwljYXNlIERSTV9GT1JNQVRfQVJHQjE1NTU6CisJY2FzZSBEUk1fRk9STUFUX1hS R0IxNTU1OgorCQljbnRsIHw9IENOVExfTENEQlBQMTYgfCBDTlRMX0JHUjsKKwkJYnJlYWs7CisJ Y2FzZSBEUk1fRk9STUFUX0FCR1I0NDQ0OgorCWNhc2UgRFJNX0ZPUk1BVF9YQkdSNDQ0NDoKKwkJ Y250bCB8PSBDTlRMX0xDREJQUDE2XzQ0NDsKKwkJYnJlYWs7CisJY2FzZSBEUk1fRk9STUFUX0FS R0I0NDQ0OgorCWNhc2UgRFJNX0ZPUk1BVF9YUkdCNDQ0NDoKKwkJY250bCB8PSBDTlRMX0xDREJQ UDE2XzQ0NCB8IENOVExfQkdSOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlXQVJOX09OQ0UodHJ1 ZSwgIlVua25vd24gRkIgZm9ybWF0IDB4JTA4eFxuIiwKKwkJCSAgZmItPmZvcm1hdC0+Zm9ybWF0 KTsKKwkJYnJlYWs7CisJfQorCisJd3JpdGVsKGNudGwsIHByaXYtPnJlZ3MgKyBDTENEX1BMMTEx X0NOVEwpOworCisJZHJtX3BhbmVsX2VuYWJsZShwcml2LT5jb25uZWN0b3IucGFuZWwpOworCisJ ZHJtX2NydGNfdmJsYW5rX29uKGNydGMpOworfQorCit2b2lkIHBsMTExX2Rpc3BsYXlfZGlzYWJs ZShzdHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUpCit7CisJc3RydWN0IGRybV9j cnRjICpjcnRjID0gJnBpcGUtPmNydGM7CisJc3RydWN0IGRybV9kZXZpY2UgKmRybSA9IGNydGMt PmRldjsKKwlzdHJ1Y3QgcGwxMTFfZHJtX2Rldl9wcml2YXRlICpwcml2ID0gZHJtLT5kZXZfcHJp dmF0ZTsKKworCWRybV9jcnRjX3ZibGFua19vZmYoY3J0Yyk7CisKKwlkcm1fcGFuZWxfZGlzYWJs ZShwcml2LT5jb25uZWN0b3IucGFuZWwpOworCisJLyogRGlzYWJsZSBhbmQgUG93ZXIgRG93biAq LworCXdyaXRlbCgwLCBwcml2LT5yZWdzICsgQ0xDRF9QTDExMV9DTlRMKTsKKworCWRybV9wYW5l bF91bnByZXBhcmUocHJpdi0+Y29ubmVjdG9yLnBhbmVsKTsKKworCWNsa19kaXNhYmxlX3VucHJl cGFyZShwcml2LT5jbGspOworfQorCitzdGF0aWMgdm9pZCBwbDExMV9kaXNwbGF5X3VwZGF0ZShz dHJ1Y3QgZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGUgKnBpcGUsCisJCQkJIHN0cnVjdCBkcm1fcGxh bmVfc3RhdGUgKm9sZF9wc3RhdGUpCit7CisJc3RydWN0IGRybV9jcnRjICpjcnRjID0gJnBpcGUt PmNydGM7CisJc3RydWN0IGRybV9kZXZpY2UgKmRybSA9IGNydGMtPmRldjsKKwlzdHJ1Y3QgcGwx MTFfZHJtX2Rldl9wcml2YXRlICpwcml2ID0gZHJtLT5kZXZfcHJpdmF0ZTsKKwlzdHJ1Y3QgZHJt X3BlbmRpbmdfdmJsYW5rX2V2ZW50ICpldmVudCA9IGNydGMtPnN0YXRlLT5ldmVudDsKKwlzdHJ1 Y3QgZHJtX3BsYW5lICpwbGFuZSA9ICZwaXBlLT5wbGFuZTsKKwlzdHJ1Y3QgZHJtX3BsYW5lX3N0 YXRlICpwc3RhdGUgPSBwbGFuZS0+c3RhdGU7CisJc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIg PSBwc3RhdGUtPmZiOworCisJaWYgKGZiKSB7CisJCXUzMiBhZGRyID0gcGwxMTFfZ2V0X2ZiX29m ZnNldChwc3RhdGUpOworCisJCXdyaXRlbChhZGRyLCBwcml2LT5yZWdzICsgQ0xDRF9VQkFTKTsK Kwl9CisKKwlpZiAoZXZlbnQpIHsKKwkJY3J0Yy0+c3RhdGUtPmV2ZW50ID0gTlVMTDsKKworCQlz cGluX2xvY2tfaXJxKCZjcnRjLT5kZXYtPmV2ZW50X2xvY2spOworCQlpZiAoY3J0Yy0+c3RhdGUt PmFjdGl2ZSAmJiBkcm1fY3J0Y192YmxhbmtfZ2V0KGNydGMpID09IDApCisJCQlkcm1fY3J0Y19h cm1fdmJsYW5rX2V2ZW50KGNydGMsIGV2ZW50KTsKKwkJZWxzZQorCQkJZHJtX2NydGNfc2VuZF92 YmxhbmtfZXZlbnQoY3J0YywgZXZlbnQpOworCQlzcGluX3VubG9ja19pcnEoJmNydGMtPmRldi0+ ZXZlbnRfbG9jayk7CisJfQorfQorCitpbnQgcGwxMTFfZW5hYmxlX3ZibGFuayhzdHJ1Y3QgZHJt X2RldmljZSAqZHJtLCB1bnNpZ25lZCBpbnQgY3J0YykKK3sKKwlzdHJ1Y3QgcGwxMTFfZHJtX2Rl dl9wcml2YXRlICpwcml2ID0gZHJtLT5kZXZfcHJpdmF0ZTsKKworCXdyaXRlbChDTENEX0lSUV9O RVhUQkFTRV9VUERBVEUsIHByaXYtPnJlZ3MgKyBDTENEX1BMMTExX0lFTkIpOworCisJcmV0dXJu IDA7Cit9CisKK3ZvaWQgcGwxMTFfZGlzYWJsZV92Ymxhbmsoc3RydWN0IGRybV9kZXZpY2UgKmRy bSwgdW5zaWduZWQgaW50IGNydGMpCit7CisJc3RydWN0IHBsMTExX2RybV9kZXZfcHJpdmF0ZSAq cHJpdiA9IGRybS0+ZGV2X3ByaXZhdGU7CisKKwl3cml0ZWwoMCwgcHJpdi0+cmVncyArIENMQ0Rf UEwxMTFfSUVOQik7Cit9CisKK3N0YXRpYyBpbnQgcGwxMTFfZGlzcGxheV9wcmVwYXJlX2ZiKHN0 cnVjdCBkcm1fc2ltcGxlX2Rpc3BsYXlfcGlwZSAqcGlwZSwKKwkJCQkgICAgc3RydWN0IGRybV9w bGFuZV9zdGF0ZSAqcGxhbmVfc3RhdGUpCit7CisJcmV0dXJuIGRybV9mYl9jbWFfcHJlcGFyZV9m YigmcGlwZS0+cGxhbmUsIHBsYW5lX3N0YXRlKTsKK30KKworY29uc3Qgc3RydWN0IGRybV9zaW1w bGVfZGlzcGxheV9waXBlX2Z1bmNzIHBsMTExX2Rpc3BsYXlfZnVuY3MgPSB7CisJLmNoZWNrID0g cGwxMTFfZGlzcGxheV9jaGVjaywKKwkuZW5hYmxlID0gcGwxMTFfZGlzcGxheV9lbmFibGUsCisJ LmRpc2FibGUgPSBwbDExMV9kaXNwbGF5X2Rpc2FibGUsCisJLnVwZGF0ZSA9IHBsMTExX2Rpc3Bs YXlfdXBkYXRlLAorCS5wcmVwYXJlX2ZiID0gcGwxMTFfZGlzcGxheV9wcmVwYXJlX2ZiLAorfTsK KworaW50IHBsMTExX2Rpc3BsYXlfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAqZHJtKQoreworCXN0 cnVjdCBwbDExMV9kcm1fZGV2X3ByaXZhdGUgKnByaXYgPSBkcm0tPmRldl9wcml2YXRlOworCXN0 cnVjdCBkZXZpY2UgKmRldiA9IGRybS0+ZGV2OworCXN0cnVjdCBkZXZpY2Vfbm9kZSAqZW5kcG9p bnQ7CisJdTMyIHRmdF9yMGIwZzBbM107CisJaW50IHJldDsKKwlzdGF0aWMgY29uc3QgdTMyIGZv cm1hdHNbXSA9IHsKKwkJRFJNX0ZPUk1BVF9BQkdSODg4OCwKKwkJRFJNX0ZPUk1BVF9YQkdSODg4 OCwKKwkJRFJNX0ZPUk1BVF9BUkdCODg4OCwKKwkJRFJNX0ZPUk1BVF9YUkdCODg4OCwKKwkJRFJN X0ZPUk1BVF9CR1I1NjUsCisJCURSTV9GT1JNQVRfUkdCNTY1LAorCQlEUk1fRk9STUFUX0FCR1Ix NTU1LAorCQlEUk1fRk9STUFUX1hCR1IxNTU1LAorCQlEUk1fRk9STUFUX0FSR0IxNTU1LAorCQlE Uk1fRk9STUFUX1hSR0IxNTU1LAorCQlEUk1fRk9STUFUX0FCR1I0NDQ0LAorCQlEUk1fRk9STUFU X1hCR1I0NDQ0LAorCQlEUk1fRk9STUFUX0FSR0I0NDQ0LAorCQlEUk1fRk9STUFUX1hSR0I0NDQ0 LAorCX07CisKKwllbmRwb2ludCA9IG9mX2dyYXBoX2dldF9uZXh0X2VuZHBvaW50KGRldi0+b2Zf bm9kZSwgTlVMTCk7CisJaWYgKCFlbmRwb2ludCkKKwkJcmV0dXJuIC1FTk9ERVY7CisKKwlpZiAo b2ZfcHJvcGVydHlfcmVhZF91MzJfYXJyYXkoZW5kcG9pbnQsCisJCQkJICAgICAgICJhcm0scGwx MXgsdGZ0LXIwZzBiMC1wYWRzIiwKKwkJCQkgICAgICAgdGZ0X3IwYjBnMCwKKwkJCQkgICAgICAg QVJSQVlfU0laRSh0ZnRfcjBiMGcwKSkgIT0gMCkgeworCQlkZXZfZXJyKGRldiwgImFybSxwbDEx eCx0ZnQtcjBnMGIwLXBhZHMgc2hvdWxkIGJlIDMgaW50c1xuIik7CisJCW9mX25vZGVfcHV0KGVu ZHBvaW50KTsKKwkJcmV0dXJuIC1FTk9FTlQ7CisJfQorCW9mX25vZGVfcHV0KGVuZHBvaW50KTsK KworCWlmICh0ZnRfcjBiMGcwWzBdICE9IDAgfHwKKwkgICAgdGZ0X3IwYjBnMFsxXSAhPSA4IHx8 CisJICAgIHRmdF9yMGIwZzBbMl0gIT0gMTYpIHsKKwkJZGV2X2VycihkZXYsICJhcm0scGwxMXgs dGZ0LXIwZzBiMC1wYWRzICE9IFswLDgsMTZdIG5vdCB5ZXQgc3VwcG9ydGVkXG4iKTsKKwkJcmV0 dXJuIC1FSU5WQUw7CisJfQorCisJcmV0ID0gZHJtX3NpbXBsZV9kaXNwbGF5X3BpcGVfaW5pdChk cm0sICZwcml2LT5waXBlLAorCQkJCQkgICAmcGwxMTFfZGlzcGxheV9mdW5jcywKKwkJCQkJICAg Zm9ybWF0cywgQVJSQVlfU0laRShmb3JtYXRzKSwKKwkJCQkJICAgJnByaXYtPmNvbm5lY3Rvci5j b25uZWN0b3IpOworCWlmIChyZXQpCisJCXJldHVybiByZXQ7CisKKwlyZXR1cm4gMDsKK30KZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9wbDExMS9wbDExMV9kcm0uaCBiL2RyaXZlcnMvZ3B1 L2RybS9wbDExMS9wbDExMV9kcm0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAw MDAwMDAuLmYzODE1OTM5MjFiNwotLS0gL2Rldi9udWxsCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9w bDExMS9wbDExMV9kcm0uaApAQCAtMCwwICsxLDU2IEBACisvKgorICoKKyAqIChDKSBDT1BZUklH SFQgMjAxMi0yMDEzIEFSTSBMaW1pdGVkLiBBbGwgcmlnaHRzIHJlc2VydmVkLgorICoKKyAqCisg KiBQYXJ0cyBvZiB0aGlzIGZpbGUgd2VyZSBiYXNlZCBvbiBzb3VyY2VzIGFzIGZvbGxvd3M6Cisg KgorICogQ29weXJpZ2h0IChjKSAyMDA2LTIwMDggSW50ZWwgQ29ycG9yYXRpb24KKyAqIENvcHly aWdodCAoYykgMjAwNyBEYXZlIEFpcmxpZSA8YWlybGllZEBsaW51eC5pZT4KKyAqIENvcHlyaWdo dCAoQykgMjAxMSBUZXhhcyBJbnN0cnVtZW50cworICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVl IHNvZnR3YXJlIGFuZCBpcyBwcm92aWRlZCB0byB5b3UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZQor ICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAyIGFzIHB1Ymxpc2hlZCBieSB0 aGUgRnJlZSBTb2Z0d2FyZQorICogRm91bmRhdGlvbiwgYW5kIGFueSB1c2UgYnkgeW91IG9mIHRo aXMgcHJvZ3JhbSBpcyBzdWJqZWN0IHRvIHRoZSB0ZXJtcyBvZgorICogc3VjaCBHTlUgbGljZW5j ZS4KKyAqCisgKi8KKworI2lmbmRlZiBfUEwxMTFfRFJNX0hfCisjZGVmaW5lIF9QTDExMV9EUk1f SF8KKworI2luY2x1ZGUgPGRybS9kcm1fZ2VtLmg+CisjaW5jbHVkZSA8ZHJtL2RybV9zaW1wbGVf a21zX2hlbHBlci5oPgorCisjZGVmaW5lIENMQ0RfSVJRX05FWFRCQVNFX1VQREFURSBCSVQoMikK Kworc3RydWN0IHBsMTExX2RybV9jb25uZWN0b3IgeworCXN0cnVjdCBkcm1fY29ubmVjdG9yIGNv bm5lY3RvcjsKKwlzdHJ1Y3QgZHJtX3BhbmVsICpwYW5lbDsKK307CisKK3N0cnVjdCBwbDExMV9k cm1fZGV2X3ByaXZhdGUgeworCXN0cnVjdCBkcm1fZGV2aWNlICpkcm07CisKKwlzdHJ1Y3QgcGwx MTFfZHJtX2Nvbm5lY3RvciBjb25uZWN0b3I7CisJc3RydWN0IGRybV9zaW1wbGVfZGlzcGxheV9w aXBlIHBpcGU7CisJc3RydWN0IGRybV9mYmRldl9jbWEgKmZiZGV2OworCisJdm9pZCAqcmVnczsK KwlzdHJ1Y3QgY2xrICpjbGs7Cit9OworCisjZGVmaW5lIHRvX3BsMTExX2Nvbm5lY3Rvcih4KSBc CisJY29udGFpbmVyX29mKHgsIHN0cnVjdCBwbDExMV9kcm1fY29ubmVjdG9yLCBjb25uZWN0b3Ip CisKK2ludCBwbDExMV9kaXNwbGF5X2luaXQoc3RydWN0IGRybV9kZXZpY2UgKmRldik7CitpbnQg cGwxMTFfZW5hYmxlX3ZibGFuayhzdHJ1Y3QgZHJtX2RldmljZSAqZHJtLCB1bnNpZ25lZCBpbnQg Y3J0Yyk7Cit2b2lkIHBsMTExX2Rpc2FibGVfdmJsYW5rKHN0cnVjdCBkcm1fZGV2aWNlICpkcm0s IHVuc2lnbmVkIGludCBjcnRjKTsKK2lycXJldHVybl90IHBsMTExX2lycShpbnQgaXJxLCB2b2lk ICpkYXRhKTsKK2ludCBwbDExMV9jb25uZWN0b3JfaW5pdChzdHJ1Y3QgZHJtX2RldmljZSAqZGV2 KTsKK2ludCBwbDExMV9lbmNvZGVyX2luaXQoc3RydWN0IGRybV9kZXZpY2UgKmRldik7CitpbnQg cGwxMTFfZHVtYl9jcmVhdGUoc3RydWN0IGRybV9maWxlICpmaWxlX3ByaXYsCisJCSAgICAgIHN0 cnVjdCBkcm1fZGV2aWNlICpkZXYsCisJCSAgICAgIHN0cnVjdCBkcm1fbW9kZV9jcmVhdGVfZHVt YiAqYXJncyk7CisKKyNlbmRpZiAvKiBfUEwxMTFfRFJNX0hfICovCmRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfZHJ2LmMgYi9kcml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwx MTFfZHJ2LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMDAwMDAwLi45MzY0MDNm NjU1MDgKLS0tIC9kZXYvbnVsbAorKysgYi9kcml2ZXJzL2dwdS9kcm0vcGwxMTEvcGwxMTFfZHJ2 LmMKQEAgLTAsMCArMSwyNzIgQEAKKy8qCisgKiAoQykgQ09QWVJJR0hUIDIwMTItMjAxMyBBUk0g TGltaXRlZC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqCisgKiBQYXJ0cyBvZiB0aGlzIGZpbGUg d2VyZSBiYXNlZCBvbiBzb3VyY2VzIGFzIGZvbGxvd3M6CisgKgorICogQ29weXJpZ2h0IChjKSAy MDA2LTIwMDggSW50ZWwgQ29ycG9yYXRpb24KKyAqIENvcHlyaWdodCAoYykgMjAwNyBEYXZlIEFp cmxpZSA8YWlybGllZEBsaW51eC5pZT4KKyAqIENvcHlyaWdodCAoQykgMjAxMSBUZXhhcyBJbnN0 cnVtZW50cworICoKKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlIGFuZCBpcyBwcm92 aWRlZCB0byB5b3UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZQorICogR05VIEdlbmVyYWwgUHVibGlj IExpY2Vuc2UgdmVyc2lvbiAyIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZQorICog Rm91bmRhdGlvbiwgYW5kIGFueSB1c2UgYnkgeW91IG9mIHRoaXMgcHJvZ3JhbSBpcyBzdWJqZWN0 IHRvIHRoZSB0ZXJtcyBvZgorICogc3VjaCBHTlUgbGljZW5jZS4KKyAqCisgKi8KKworLyoqCisg KiBET0M6IEFSTSBQcmltZUNlbGwgUEwxMTEgQ0xDRCBEcml2ZXIKKyAqCisgKiBUaGUgUEwxMTEg aXMgYSBzaW1wbGUgTENEIGNvbnRyb2xsZXIgdGhhdCBjYW4gc3VwcG9ydCBURlQgYW5kIFNUTgor ICogZGlzcGxheXMuICBUaGlzIGRyaXZlciBleHBvc2VzIGEgc3RhbmRhcmQgS01TIGludGVyZmFj ZSBmb3IgdGhlbS4KKyAqCisgKiBUaGlzIGRyaXZlciB1c2VzIHRoZSBzYW1lIERldmljZSBUcmVl IGJpbmRpbmcgYXMgdGhlIGZiZGV2IENMQ0QKKyAqIGRyaXZlci4gIFdoaWxlIHRoZSBmYmRldiBk cml2ZXIgc3VwcG9ydHMgcGFuZWxzIHRoYXQgbWF5IGJlCisgKiBjb25uZWN0ZWQgdG8gdGhlIENM Q0QgaW50ZXJuYWxseSB0byB0aGUgQ0xDRCBkcml2ZXIsIGluIERSTSB0aGUKKyAqIHBhbmVscyBn ZXQgc3BsaXQgb3V0IHRvIGRyaXZlcnMvZ3B1L2RybS9wYW5lbHMvLiAgVGhpcyBtZWFucyB0aGF0 LAorICogaW4gY29udmVydGluZyBmcm9tIHVzaW5nIGZiZGV2IHRvIHVzaW5nIERSTSwgeW91IGFs c28gbmVlZCB0byB3cml0ZQorICogYSBwYW5lbCBkcml2ZXIgKHdoaWNoIG1heSBiZSBhcyBzaW1w bGUgYXMgYW4gZW50cnkgaW4KKyAqIHBhbmVsLXNpbXBsZS5jKS4KKyAqCisgKiBUaGUgZHJpdmVy IGN1cnJlbnRseSBkb2Vzbid0IGV4cG9zZSB0aGUgY3Vyc29yLiAgVGhlIERSTSBBUEkgZm9yCisg KiBjdXJzb3JzIHJlcXVpcmVzIHN1cHBvcnQgZm9yIDY0eDY0IEFSR0I4ODg4IGN1cnNvciBpbWFn ZXMsIHdoaWxlCisgKiB0aGUgaGFyZHdhcmUgY2FuIG9ubHkgc3VwcG9ydCA2NHg2NCBtb25vY2hy b21lIHdpdGggbWFza2luZworICogY3Vyc29ycy4gIFdoaWxlIG9uZSBjb3VsZCBpbWFnaW5lIHRy eWluZyB0byBoYWNrIHNvbWV0aGluZyB0b2dldGhlcgorICogdG8gbG9vayBhdCB0aGUgQVJHQjg4 ODggYW5kIHByb2dyYW0gcmVhc29uYWJsZSBpbiBtb25vY2hyb21lLCB3ZQorICoganVzdCBkb24n dCBleHBvc2UgdGhlIGN1cnNvciBhdCBhbGwgaW5zdGVhZCwgYW5kIGxlYXZlIGN1cnNvcgorICog c3VwcG9ydCB0byB0aGUgWDExIHNvZnR3YXJlIGN1cnNvciBsYXllci4KKyAqCisgKiBUT0RPOgor ICoKKyAqIC0gRml4IHJhY2UgYmV0d2VlbiBzZXR0aW5nIHBsYW5lIGJhc2UgYWRkcmVzcyBhbmQg Z2V0dGluZyBJUlEgZm9yCisgKiAgIHZzeW5jIGZpcmluZyB0aGUgcGFnZWZsaXAgY29tcGxldGlv bi4KKyAqCisgKiAtIEV4cG9zZSB0aGUgY29ycmVjdCBzZXQgb2YgZm9ybWF0cyB3ZSBjYW4gc3Vw cG9ydCBiYXNlZCBvbiB0aGUKKyAqICAgImFybSxwbDExeCx0ZnQtcjBnMGIwLXBhZHMiIERUIHBy b3BlcnR5LgorICoKKyAqIC0gVXNlIHRoZSAibWF4LW1lbW9yeS1iYW5kd2lkdGgiIERUIHByb3Bl cnR5IHRvIGZpbHRlciB0aGUKKyAqICAgc3VwcG9ydGVkIGZvcm1hdHMuCisgKgorICogLSBSZWFk IGJhY2sgaGFyZHdhcmUgc3RhdGUgYXQgYm9vdCB0byBza2lwIHJlcHJvZ3JhbW1pbmcgdGhlCisg KiAgIGhhcmR3YXJlIHdoZW4gZG9pbmcgYSBuby1vcCBtb2Rlc2V0LgorICoKKyAqIC0gVXNlIHRo ZSBpbnRlcm5hbCBjbG9jayBkaXZpc29yIHRvIHJlZHVjZSBwb3dlciBjb25zdW1wdGlvbiBieQor ICogICB1c2luZyBIQ0xLIChhcGJfcGNsaykgd2hlbiBhcHByb3ByaWF0ZS4KKyAqLworCisjaW5j bHVkZSA8bGludXgvYW1iYS9idXMuaD4KKyNpbmNsdWRlIDxsaW51eC9hbWJhL2NsY2QtcmVncy5o PgorI2luY2x1ZGUgPGxpbnV4L3ZlcnNpb24uaD4KKyNpbmNsdWRlIDxsaW51eC9zaG1lbV9mcy5o PgorI2luY2x1ZGUgPGxpbnV4L2RtYS1idWYuaD4KKyNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4K KyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CisKKyNpbmNsdWRlIDxkcm0vZHJtUC5oPgorI2luY2x1 ZGUgPGRybS9kcm1fYXRvbWljX2hlbHBlci5oPgorI2luY2x1ZGUgPGRybS9kcm1fY3J0Y19oZWxw ZXIuaD4KKyNpbmNsdWRlIDxkcm0vZHJtX2dlbV9jbWFfaGVscGVyLmg+CisjaW5jbHVkZSA8ZHJt L2RybV9mYl9jbWFfaGVscGVyLmg+CisKKyNpbmNsdWRlICJwbDExMV9kcm0uaCIKKworI2RlZmlu ZSBEUklWRVJfREVTQyAgICAgICJEUk0gbW9kdWxlIGZvciBQTDExMSIKKworc3RydWN0IGRybV9t b2RlX2NvbmZpZ19mdW5jcyBtb2RlX2NvbmZpZ19mdW5jcyA9IHsKKwkuZmJfY3JlYXRlID0gZHJt X2ZiX2NtYV9jcmVhdGUsCisJLmF0b21pY19jaGVjayA9IGRybV9hdG9taWNfaGVscGVyX2NoZWNr LAorCS5hdG9taWNfY29tbWl0ID0gZHJtX2F0b21pY19oZWxwZXJfY29tbWl0LAorfTsKKworc3Rh dGljIGludCBwbDExMV9tb2Rlc2V0X2luaXQoc3RydWN0IGRybV9kZXZpY2UgKmRldikKK3sKKwlz dHJ1Y3QgZHJtX21vZGVfY29uZmlnICptb2RlX2NvbmZpZzsKKwlzdHJ1Y3QgcGwxMTFfZHJtX2Rl dl9wcml2YXRlICpwcml2ID0gZGV2LT5kZXZfcHJpdmF0ZTsKKwlpbnQgcmV0ID0gMDsKKworCWRy bV9tb2RlX2NvbmZpZ19pbml0KGRldik7CisJbW9kZV9jb25maWcgPSAmZGV2LT5tb2RlX2NvbmZp ZzsKKwltb2RlX2NvbmZpZy0+ZnVuY3MgPSAmbW9kZV9jb25maWdfZnVuY3M7CisJbW9kZV9jb25m aWctPm1pbl93aWR0aCA9IDE7CisJbW9kZV9jb25maWctPm1heF93aWR0aCA9IDEwMjQ7CisJbW9k ZV9jb25maWctPm1pbl9oZWlnaHQgPSAxOworCW1vZGVfY29uZmlnLT5tYXhfaGVpZ2h0ID0gNzY4 OworCisJcmV0ID0gcGwxMTFfY29ubmVjdG9yX2luaXQoZGV2KTsKKwlpZiAocmV0KSB7CisJCWRl dl9lcnIoZGV2LT5kZXYsICJGYWlsZWQgdG8gY3JlYXRlIHBsMTExX2RybV9jb25uZWN0b3JcbiIp OworCQlnb3RvIG91dF9jb25maWc7CisJfQorCisJLyogRG9uJ3QgYWN0dWFsbHkgYXR0YWNoIGlm IHdlIGRpZG4ndCBmaW5kIGEgZHJtX3BhbmVsCisJICogYXR0YWNoZWQgdG8gdXMuICBUaGlzIHdp bGwgYWxsb3cgYSBrZXJuZWwgdG8gaW5jbHVkZSBib3RoCisJICogdGhlIGZiZGV2IHBsMTExIGRy aXZlciBhbmQgdGhpcyBvbmUsIGFuZCBjaG9vc2UgYmV0d2VlbgorCSAqIHRoZW0gYmFzZWQgb24g d2hpY2ggc3Vic3lzdGVtIGhhcyBzdXBwb3J0IGZvciB0aGUgcGFuZWwuCisJICovCisJaWYgKCFw cml2LT5jb25uZWN0b3IucGFuZWwpIHsKKwkJZGV2X2luZm8oZGV2LT5kZXYsCisJCQkgIkRpc2Fi bGluZyBkdWUgdG8gbGFjayBvZiBEUk0gcGFuZWwgZGV2aWNlLlxuIik7CisJCXJldCA9IC1FTk9E RVY7CisJCWdvdG8gb3V0X2NvbmZpZzsKKwl9CisKKwlyZXQgPSBwbDExMV9kaXNwbGF5X2luaXQo ZGV2KTsKKwlpZiAocmV0ICE9IDApIHsKKwkJZGV2X2VycihkZXYtPmRldiwgIkZhaWxlZCB0byBp bml0IGRpc3BsYXlcbiIpOworCQlnb3RvIG91dF9jb25maWc7CisJfQorCisJcmV0ID0gZHJtX3Zi bGFua19pbml0KGRldiwgMSk7CisJaWYgKHJldCAhPSAwKSB7CisJCWRldl9lcnIoZGV2LT5kZXYs ICJGYWlsZWQgdG8gaW5pdCB2YmxhbmtcbiIpOworCQlnb3RvIG91dF9jb25maWc7CisJfQorCisJ ZHJtX21vZGVfY29uZmlnX3Jlc2V0KGRldik7CisKKwlwcml2LT5mYmRldiA9IGRybV9mYmRldl9j bWFfaW5pdChkZXYsIDMyLAorCQkJCQkgZGV2LT5tb2RlX2NvbmZpZy5udW1fY29ubmVjdG9yKTsK KworCWRybV9rbXNfaGVscGVyX3BvbGxfaW5pdChkZXYpOworCisJZ290byBmaW5pc2g7CisKK291 dF9jb25maWc6CisJZHJtX21vZGVfY29uZmlnX2NsZWFudXAoZGV2KTsKK2ZpbmlzaDoKKwlyZXR1 cm4gcmV0OworfQorCitERUZJTkVfRFJNX0dFTV9DTUFfRk9QUyhkcm1fZm9wcyk7CisKK3N0YXRp YyB2b2lkIHBsMTExX2xhc3RjbG9zZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2KQoreworCXN0cnVj dCBwbDExMV9kcm1fZGV2X3ByaXZhdGUgKnByaXYgPSBkZXYtPmRldl9wcml2YXRlOworCisJZHJt X2ZiZGV2X2NtYV9yZXN0b3JlX21vZGUocHJpdi0+ZmJkZXYpOworfQorCitzdGF0aWMgc3RydWN0 IGRybV9kcml2ZXIgcGwxMTFfZHJtX2RyaXZlciA9IHsKKwkuZHJpdmVyX2ZlYXR1cmVzID0KKwkJ RFJJVkVSX01PREVTRVQgfCBEUklWRVJfR0VNIHwgRFJJVkVSX1BSSU1FIHwgRFJJVkVSX0FUT01J QywKKwkubGFzdGNsb3NlID0gcGwxMTFfbGFzdGNsb3NlLAorCS5pb2N0bHMgPSBOVUxMLAorCS5m b3BzID0gJmRybV9mb3BzLAorCS5uYW1lID0gInBsMTExIiwKKwkuZGVzYyA9IERSSVZFUl9ERVND LAorCS5kYXRlID0gIjIwMTcwMzE3IiwKKwkubWFqb3IgPSAxLAorCS5taW5vciA9IDAsCisJLnBh dGNobGV2ZWwgPSAwLAorCS5kdW1iX2NyZWF0ZSA9IGRybV9nZW1fY21hX2R1bWJfY3JlYXRlLAor CS5kdW1iX2Rlc3Ryb3kgPSBkcm1fZ2VtX2R1bWJfZGVzdHJveSwKKwkuZHVtYl9tYXBfb2Zmc2V0 ID0gZHJtX2dlbV9jbWFfZHVtYl9tYXBfb2Zmc2V0LAorCS5nZW1fZnJlZV9vYmplY3QgPSBkcm1f Z2VtX2NtYV9mcmVlX29iamVjdCwKKwkuZ2VtX3ZtX29wcyA9ICZkcm1fZ2VtX2NtYV92bV9vcHMs CisKKwkuZW5hYmxlX3ZibGFuayA9IHBsMTExX2VuYWJsZV92YmxhbmssCisJLmRpc2FibGVfdmJs YW5rID0gcGwxMTFfZGlzYWJsZV92YmxhbmssCisKKwkucHJpbWVfaGFuZGxlX3RvX2ZkID0gZHJt X2dlbV9wcmltZV9oYW5kbGVfdG9fZmQsCisJLnByaW1lX2ZkX3RvX2hhbmRsZSA9IGRybV9nZW1f cHJpbWVfZmRfdG9faGFuZGxlLAorCS5nZW1fcHJpbWVfaW1wb3J0ID0gZHJtX2dlbV9wcmltZV9p bXBvcnQsCisJLmdlbV9wcmltZV9pbXBvcnRfc2dfdGFibGUgPSBkcm1fZ2VtX2NtYV9wcmltZV9p bXBvcnRfc2dfdGFibGUsCisJLmdlbV9wcmltZV9leHBvcnQgPSBkcm1fZ2VtX3ByaW1lX2V4cG9y dCwKKwkuZ2VtX3ByaW1lX2dldF9zZ190YWJsZQk9IGRybV9nZW1fY21hX3ByaW1lX2dldF9zZ190 YWJsZSwKK307CisKKyNpZmRlZiBDT05GSUdfQVJNX0FNQkEKK3N0YXRpYyBpbnQgcGwxMTFfYW1i YV9wcm9iZShzdHJ1Y3QgYW1iYV9kZXZpY2UgKmFtYmFfZGV2LAorCQkJICAgIGNvbnN0IHN0cnVj dCBhbWJhX2lkICppZCkKK3sKKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSAmYW1iYV9kZXYtPmRldjsK KwlzdHJ1Y3QgcGwxMTFfZHJtX2Rldl9wcml2YXRlICpwcml2OworCXN0cnVjdCBkcm1fZGV2aWNl ICpkcm07CisJaW50IHJldDsKKworCXByaXYgPSBkZXZtX2t6YWxsb2MoZGV2LCBzaXplb2YoKnBy aXYpLCBHRlBfS0VSTkVMKTsKKwlpZiAoIXByaXYpCisJCXJldHVybiAtRU5PTUVNOworCisJZHJt ID0gZHJtX2Rldl9hbGxvYygmcGwxMTFfZHJtX2RyaXZlciwgZGV2KTsKKwlpZiAoSVNfRVJSKGRy bSkpCisJCXJldHVybiBQVFJfRVJSKGRybSk7CisJYW1iYV9zZXRfZHJ2ZGF0YShhbWJhX2Rldiwg ZHJtKTsKKwlwcml2LT5kcm0gPSBkcm07CisJZHJtLT5kZXZfcHJpdmF0ZSA9IHByaXY7CisKKwlw cml2LT5jbGsgPSBkZXZtX2Nsa19nZXQoZGV2LCAiY2xjZGNsayIpOworCWlmIChJU19FUlIocHJp di0+Y2xrKSkgeworCQlkZXZfZXJyKGRldiwgIkNMQ0Q6IHVuYWJsZSB0byBnZXQgY2xrLlxuIik7 CisJCXJldCA9IFBUUl9FUlIocHJpdi0+Y2xrKTsKKwkJZ290byBkZXZfdW5yZWY7CisJfQorCisJ cHJpdi0+cmVncyA9IGRldm1faW9yZW1hcF9yZXNvdXJjZShkZXYsICZhbWJhX2Rldi0+cmVzKTsK KwlpZiAoIXByaXYtPnJlZ3MpIHsKKwkJZGV2X2VycihkZXYsICIlcyBmYWlsZWQgbW1pb1xuIiwg X19mdW5jX18pOworCQlyZXR1cm4gLUVJTlZBTDsKKwl9CisKKwkvKiB0dXJuIG9mZiBpbnRlcnJ1 cHRzIGJlZm9yZSByZXF1ZXN0aW5nIHRoZSBpcnEgKi8KKwl3cml0ZWwoMCwgcHJpdi0+cmVncyAr IENMQ0RfUEwxMTFfSUVOQik7CisKKwlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKGRldiwgYW1iYV9k ZXYtPmlycVswXSwgcGwxMTFfaXJxLCAwLAorCQkJICAgICAgICJwbDExMSIsIHByaXYpOworCWlm IChyZXQgIT0gMCkgeworCQlkZXZfZXJyKGRldiwgIiVzIGZhaWxlZCBpcnEgJWRcbiIsIF9fZnVu Y19fLCByZXQpOworCQlyZXR1cm4gcmV0OworCX0KKworCXJldCA9IHBsMTExX21vZGVzZXRfaW5p dChkcm0pOworCWlmIChyZXQgIT0gMCkKKwkJZ290byBkZXZfdW5yZWY7CisKKwlyZXQgPSBkcm1f ZGV2X3JlZ2lzdGVyKGRybSwgMCk7CisJaWYgKHJldCA8IDApCisJCWdvdG8gZGV2X3VucmVmOwor CisJcmV0dXJuIDA7CisKK2Rldl91bnJlZjoKKwlkcm1fZGV2X3VucmVmKGRybSk7CisJcmV0dXJu IHJldDsKK30KKworc3RhdGljIGludCBwbDExMV9hbWJhX3JlbW92ZShzdHJ1Y3QgYW1iYV9kZXZp Y2UgKmFtYmFfZGV2KQoreworCXN0cnVjdCBkcm1fZGV2aWNlICpkcm0gPSBhbWJhX2dldF9kcnZk YXRhKGFtYmFfZGV2KTsKKwlzdHJ1Y3QgcGwxMTFfZHJtX2Rldl9wcml2YXRlICpwcml2ID0gZHJt LT5kZXZfcHJpdmF0ZTsKKworCWRybV9kZXZfdW5yZWdpc3Rlcihkcm0pOworCWlmIChwcml2LT5m YmRldikKKwkJZHJtX2ZiZGV2X2NtYV9maW5pKHByaXYtPmZiZGV2KTsKKwlkcm1fbW9kZV9jb25m aWdfY2xlYW51cChkcm0pOworCWRybV9kZXZfdW5yZWYoZHJtKTsKKworCXJldHVybiAwOworfQor CitzdGF0aWMgc3RydWN0IGFtYmFfaWQgcGwxMTFfaWRfdGFibGVbXSA9IHsKKwl7CisJCS5pZCA9 IDB4MDAwNDExMTEsCisJCS5tYXNrID0gMHgwMDBmZmZmZiwKKwl9LAorCXswLCAwfSwKK307CisK K3N0YXRpYyBzdHJ1Y3QgYW1iYV9kcml2ZXIgcGwxMTFfYW1iYV9kcml2ZXIgPSB7CisJLmRydiA9 IHsKKwkJLm5hbWUgPSAiZHJtLWNsY2QtcGwxMTEiLAorCX0sCisJLnByb2JlID0gcGwxMTFfYW1i YV9wcm9iZSwKKwkucmVtb3ZlID0gcGwxMTFfYW1iYV9yZW1vdmUsCisJLmlkX3RhYmxlID0gcGwx MTFfaWRfdGFibGUsCit9OworCittb2R1bGVfYW1iYV9kcml2ZXIocGwxMTFfYW1iYV9kcml2ZXIp OworI2VuZGlmIC8qIENPTkZJR19BUk1fQU1CQSAqLworCitNT0RVTEVfREVTQ1JJUFRJT04oRFJJ VkVSX0RFU0MpOworTU9EVUxFX0FVVEhPUigiQVJNIEx0ZC4iKTsKK01PRFVMRV9MSUNFTlNFKCJH UEwiKTsKLS0gCjIuMTEuMAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX18KZHJpLWRldmVsIG1haWxpbmcgbGlzdApkcmktZGV2ZWxAbGlzdHMuZnJlZWRlc2t0 b3Aub3JnCmh0dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vZHJp LWRldmVsCg==