From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96BBAC6FD19 for ; Thu, 16 Mar 2023 13:34:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229648AbjCPNeg (ORCPT ); Thu, 16 Mar 2023 09:34:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57978 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229506AbjCPNeg (ORCPT ); Thu, 16 Mar 2023 09:34:36 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 431FC22105; Thu, 16 Mar 2023 06:34:33 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 6351EB82175; Thu, 16 Mar 2023 13:34:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B5A99C433D2; Thu, 16 Mar 2023 13:34:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678973670; bh=qAdEOK4xXU5XBmMSBAwSRPhqlisfmLCDUAov97N9xA4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=AzP5xsEFCnyyDDWq4PkrPTE1OruLkwS3MaOeOW3sTsePcWw+j1BwlFV9rLcOCvu6Z ChB89CxENq6Z/iZl4W5WDQBD22MCitj/+d5Rs/c5c7NLNLBVohrPlLvOOHbntbPUsq QGsumB2Pj36JbzHFK6pA3cTp/6Q2fO9OXcg8q7h1EzrlVPTiA8Dqz7EwdNxmw8P5Qk OabjH8o/RKaAyWwNMpUqhD/1gWbOX5Pc9NOguj8WvIrWYe7O8sLy9YPKjL7m7QjAwu opEmEQTKLcstTx/6llTcOop/2c1wqj0l4zETudIhGzMZJg/xsi9kfi8gjIrMOs0dNJ jIfZ0lKgbMvOA== Date: Thu, 16 Mar 2023 13:34:22 +0000 From: Lee Jones To: Samuel Holland Cc: Pavel Machek , linux-leds@vger.kernel.org, Chen-Yu Tsai , Jernej Skrabec , Albert Ou , Conor Dooley , Guo Ren , Heiko Stuebner , Heiko Stuebner , Jisheng Zhang , Krzysztof Kozlowski , Palmer Dabbelt , Paul Walmsley , Philipp Zabel , Rob Herring , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: Re: [RESEND PATCH v7 2/5] leds: sun50i-a100: New driver for the A100 LED controller Message-ID: <20230316133422.GM9667@google.com> References: <20221231235541.13568-1-samuel@sholland.org> <20221231235541.13568-3-samuel@sholland.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20221231235541.13568-3-samuel@sholland.org> Precedence: bulk List-ID: X-Mailing-List: linux-leds@vger.kernel.org On Sat, 31 Dec 2022, Samuel Holland wrote: > Some Allwinner sunxi SoCs, starting with the A100, contain an LED > controller designed to drive RGB LED pixels. Add a driver for it using > the multicolor LED framework, and with LEDs defined in the device tree. > > Acked-by: Jernej Skrabec > Signed-off-by: Samuel Holland > --- > > Changes in v7: > - Use DEFINE_SIMPLE_DEV_PM_OPS > > Changes in v5: > - Rename the driver R329 -> A100, since that is the actual original > implementation > > Changes in v4: > - Depend on LEDS_CLASS_MULTICOLOR > > Changes in v3: > - Added vendor prefix to timing/format properties > - Renamed "format" property to "pixel-format" for clarity > - Dropped "vled-supply" as it is unrelated to the controller hardware > - Changed "writesl" to "iowrite32_rep" so the driver builds on hppa > > Changes in v2: > - Renamed from sunxi-ledc to sun50i-r329-ledc > - Added missing "static" to functions/globals as reported by 0day bot > > drivers/leds/Kconfig | 9 + > drivers/leds/Makefile | 1 + > drivers/leds/leds-sun50i-a100.c | 555 ++++++++++++++++++++++++++++++++ > 3 files changed, 565 insertions(+) > create mode 100644 drivers/leds/leds-sun50i-a100.c Nice driver. Just some nits below. > diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig > index 499d0f215a8b..4f4c515ed7d7 100644 > --- a/drivers/leds/Kconfig > +++ b/drivers/leds/Kconfig > @@ -281,6 +281,15 @@ config LEDS_COBALT_RAQ > help > This option enables support for the Cobalt Raq series LEDs. > > +config LEDS_SUN50I_A100 > + tristate "LED support for Allwinner A100 RGB LED controller" > + depends on LEDS_CLASS_MULTICOLOR && OF > + depends on ARCH_SUNXI || COMPILE_TEST > + help > + This option enables support for the RGB LED controller found > + in some Allwinner sunxi SoCs, includeing A100, R329, and D1. > + It uses a one-wire interface to control up to 1024 LEDs. Did you run spellcheck on this? > config LEDS_SUNFIRE > tristate "LED support for SunFire servers." > depends on LEDS_CLASS > diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile > index 4fd2f92cd198..a6ee3f5cf7be 100644 > --- a/drivers/leds/Makefile > +++ b/drivers/leds/Makefile > @@ -76,6 +76,7 @@ obj-$(CONFIG_LEDS_PWM) += leds-pwm.o > obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o > obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o > obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o > +obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o > obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o > obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o > obj-$(CONFIG_LEDS_TCA6507) += leds-tca6507.o > diff --git a/drivers/leds/leds-sun50i-a100.c b/drivers/leds/leds-sun50i-a100.c > new file mode 100644 > index 000000000000..30fa9be2cf2d > --- /dev/null > +++ b/drivers/leds/leds-sun50i-a100.c > @@ -0,0 +1,555 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// > +// Copyright (c) 2021-2022 Samuel Holland Please update. > +// Partly based on drivers/leds/leds-turris-omnia.c, which is: > +// Copyright (c) 2020 by Marek Behún > +// What is this line commenting? Could you please re-do this header to use C-style comments please. > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define LEDC_CTRL_REG 0x0000 > +#define LEDC_CTRL_REG_DATA_LENGTH (0x1fff << 16) > +#define LEDC_CTRL_REG_RGB_MODE (0x7 << 6) > +#define LEDC_CTRL_REG_LEDC_EN BIT(0) > +#define LEDC_T01_TIMING_CTRL_REG 0x0004 > +#define LEDC_T01_TIMING_CTRL_REG_T1H (0x3f << 21) > +#define LEDC_T01_TIMING_CTRL_REG_T1L (0x1f << 16) > +#define LEDC_T01_TIMING_CTRL_REG_T0H (0x1f << 6) > +#define LEDC_T01_TIMING_CTRL_REG_T0L (0x3f << 0) > +#define LEDC_RESET_TIMING_CTRL_REG 0x000c > +#define LEDC_RESET_TIMING_CTRL_REG_LED_NUM (0x3ff << 0) > +#define LEDC_DATA_REG 0x0014 > +#define LEDC_DMA_CTRL_REG 0x0018 > +#define LEDC_DMA_CTRL_REG_FIFO_TRIG_LEVEL (0x1f << 0) > +#define LEDC_INT_CTRL_REG 0x001c > +#define LEDC_INT_CTRL_REG_GLOBAL_INT_EN BIT(5) > +#define LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN BIT(1) > +#define LEDC_INT_CTRL_REG_TRANS_FINISH_INT_EN BIT(0) > +#define LEDC_INT_STS_REG 0x0020 > +#define LEDC_INT_STS_REG_FIFO_CPUREQ_INT BIT(1) > +#define LEDC_INT_STS_REG_TRANS_FINISH_INT BIT(0) > + > +#define LEDC_FIFO_DEPTH 32 > +#define LEDC_MAX_LEDS 1024 > + > +#define LEDS_TO_BYTES(n) ((n) * sizeof(u32)) > + > +struct sun50i_a100_ledc_led { Is this information likely to change on a per-LED basis? > + struct led_classdev_mc mc_cdev; > + struct mc_subled subled_info[3]; What is 3? > +}; > + > +#define to_ledc_led(mc) container_of(mc, struct sun50i_a100_ledc_led, mc_cdev) > + > +struct sun50i_a100_ledc_timing { > + u32 t0h_ns; > + u32 t0l_ns; > + u32 t1h_ns; > + u32 t1l_ns; > + u32 treset_ns; > +}; > + > +struct sun50i_a100_ledc { > + struct device *dev; > + void __iomem *base; > + struct clk *bus_clk; > + struct clk *mod_clk; > + struct reset_control *reset; > + > + u32 *buffer; > + struct dma_chan *dma_chan; > + dma_addr_t dma_handle; > + int pio_length; > + int pio_offset; > + > + spinlock_t lock; > + int next_length; > + bool xfer_active; > + > + u32 format; > + struct sun50i_a100_ledc_timing timing; > + > + int num_leds; > + struct sun50i_a100_ledc_led leds[]; > +}; > + > +static int sun50i_a100_ledc_dma_xfer(struct sun50i_a100_ledc *priv, int length) > +{ > + struct dma_async_tx_descriptor *desc; > + dma_cookie_t cookie; > + > + desc = dmaengine_prep_slave_single(priv->dma_chan, priv->dma_handle, > + LEDS_TO_BYTES(length), > + DMA_MEM_TO_DEV, 0); > + if (!desc) > + return -ENOMEM; > + > + cookie = dmaengine_submit(desc); > + if (dma_submit_error(cookie)) > + return -EIO; > + > + dma_async_issue_pending(priv->dma_chan); > + > + return 0; > +} > + > +static void sun50i_a100_ledc_pio_xfer(struct sun50i_a100_ledc *priv, int length) > +{ > + u32 burst, offset, val; > + > + if (length) { > + /* New transfer (FIFO is empty). */ > + offset = 0; > + burst = min(length, LEDC_FIFO_DEPTH); > + } else { > + /* Existing transfer (FIFO is half-full). */ > + length = priv->pio_length; > + offset = priv->pio_offset; > + burst = min(length, LEDC_FIFO_DEPTH / 2); Didn't we already establish that length was 0? > + } > + > + iowrite32_rep(priv->base + LEDC_DATA_REG, priv->buffer + offset, burst); > + > + if (burst < length) { > + priv->pio_length = length - burst; > + priv->pio_offset = offset + burst; > + > + if (!offset) { > + val = readl(priv->base + LEDC_INT_CTRL_REG); > + val |= LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN; > + writel(val, priv->base + LEDC_INT_CTRL_REG); > + } > + } else { > + /* Disable the request IRQ once all data is written. */ > + val = readl(priv->base + LEDC_INT_CTRL_REG); > + val &= ~LEDC_INT_CTRL_REG_FIFO_CPUREQ_INT_EN; > + writel(val, priv->base + LEDC_INT_CTRL_REG); > + } > +} > + > +static void sun50i_a100_ledc_start_xfer(struct sun50i_a100_ledc *priv, > + int length) > +{ > + u32 val; > + > + dev_dbg(priv->dev, "Updating %d LEDs\n", length); How useful is this, really? Could you consider removing it? > + val = readl(priv->base + LEDC_CTRL_REG); > + val &= ~LEDC_CTRL_REG_DATA_LENGTH; > + val |= length << 16 | LEDC_CTRL_REG_LEDC_EN; Why 16? Please consider defining all magic numbers. BLAH_BLAH_SHIFT ? > + writel(val, priv->base + LEDC_CTRL_REG); > + > + if (length > LEDC_FIFO_DEPTH) { > + int ret = sun50i_a100_ledc_dma_xfer(priv, length); Looks odd. It's way more common to separate the call from the declaration. > + if (!ret) > + return; > + > + dev_warn(priv->dev, "Failed to set up DMA: %d\n", ret); This looks like an error. Please tell the user we're falling back to PIO. > + } > + > + sun50i_a100_ledc_pio_xfer(priv, length); > +} > + > +static irqreturn_t sun50i_a100_ledc_irq(int irq, void *dev_id) > +{ > + struct sun50i_a100_ledc *priv = dev_id; This is clearly not a def_id. 'data' looks like a common alternative. > + u32 val; > + > + val = readl(priv->base + LEDC_INT_STS_REG); 'val' is a terrible variable name. 'status'? > + if (val & LEDC_INT_STS_REG_TRANS_FINISH_INT) { > + int next_length; > + > + /* Start the next transfer if needed. */ > + spin_lock(&priv->lock); > + next_length = priv->next_length; > + if (next_length) > + priv->next_length = 0; > + else > + priv->xfer_active = false; > + spin_unlock(&priv->lock); > + > + if (next_length) > + sun50i_a100_ledc_start_xfer(priv, next_length); > + } else if (val & LEDC_INT_STS_REG_FIFO_CPUREQ_INT) { > + /* Continue the current transfer. */ > + sun50i_a100_ledc_pio_xfer(priv, 0); > + } > + > + writel(val, priv->base + LEDC_INT_STS_REG); Did 'val' change? If this is intentional, perhaps a comment to clarify. > + return IRQ_HANDLED; > +} > + > +static void sun50i_a100_ledc_brightness_set(struct led_classdev *cdev, > + enum led_brightness brightness) > +{ > + struct sun50i_a100_ledc *priv = dev_get_drvdata(cdev->dev->parent); > + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(cdev); > + struct sun50i_a100_ledc_led *led = to_ledc_led(mc_cdev); > + int addr = led - priv->leds; Not really an address is it? 'offset' or something better? > + unsigned long flags; > + bool xfer_active; > + int next_length; > + > + led_mc_calc_color_components(mc_cdev, brightness); > + > + priv->buffer[addr] = led->subled_info[0].brightness << 16 | > + led->subled_info[1].brightness << 8 | > + led->subled_info[2].brightness; > + > + dev_dbg(priv->dev, "LED %d -> #%06x\n", addr, priv->buffer[addr]); As above. > + spin_lock_irqsave(&priv->lock, flags); > + next_length = max(priv->next_length, addr + 1); > + xfer_active = priv->xfer_active; > + if (xfer_active) > + priv->next_length = next_length; > + else > + priv->xfer_active = true; > + spin_unlock_irqrestore(&priv->lock, flags); Cramped code is not easy to read. Please consider some '\n's. > + if (!xfer_active) > + sun50i_a100_ledc_start_xfer(priv, next_length); > +} > + > +static const char *const sun50i_a100_ledc_formats[] = { > + "rgb", > + "rbg", > + "grb", > + "gbr", > + "brg", > + "bgr", > +}; > + > +static int sun50i_a100_ledc_parse_format(const struct device_node *np, > + struct sun50i_a100_ledc *priv) > +{ > + const char *format = "grb"; > + u32 i; > + > + of_property_read_string(np, "allwinner,pixel-format", &format); > + > + for (i = 0; i < ARRAY_SIZE(sun50i_a100_ledc_formats); ++i) { Does the pre-increment hold any significance? If not, please use the more common implementation of post-incrementing. > + if (!strcmp(format, sun50i_a100_ledc_formats[i])) { > + priv->format = i; > + return 0; > + } > + } > + > + dev_err(priv->dev, "Bad pixel format '%s'\n", format); > + > + return -EINVAL; > +} > + > +static void sun50i_a100_ledc_set_format(struct sun50i_a100_ledc *priv) > +{ > + u32 val; > + > + val = readl(priv->base + LEDC_CTRL_REG); > + val &= ~LEDC_CTRL_REG_RGB_MODE; > + val |= priv->format << 6; > + writel(val, priv->base + LEDC_CTRL_REG); > +} > + > +static const struct sun50i_a100_ledc_timing sun50i_a100_ledc_default_timing = { > + .t0h_ns = 336, > + .t0l_ns = 840, > + .t1h_ns = 882, > + .t1l_ns = 294, > + .treset_ns = 300000, > +}; > + > +static int sun50i_a100_ledc_parse_timing(const struct device_node *np, > + struct sun50i_a100_ledc *priv) > +{ > + struct sun50i_a100_ledc_timing *timing = &priv->timing; > + > + *timing = sun50i_a100_ledc_default_timing; > + > + of_property_read_u32(np, "allwinner,t0h-ns", &timing->t0h_ns); > + of_property_read_u32(np, "allwinner,t0l-ns", &timing->t0l_ns); > + of_property_read_u32(np, "allwinner,t1h-ns", &timing->t1h_ns); > + of_property_read_u32(np, "allwinner,t1l-ns", &timing->t1l_ns); > + of_property_read_u32(np, "allwinner,treset-ns", &timing->treset_ns); > + > + return 0; > +} > + > +static void sun50i_a100_ledc_set_timing(struct sun50i_a100_ledc *priv) > +{ > + const struct sun50i_a100_ledc_timing *timing = &priv->timing; > + unsigned long mod_freq = clk_get_rate(priv->mod_clk); > + u32 cycle_ns = NSEC_PER_SEC / mod_freq; > + u32 val; 'timing' > + val = (timing->t1h_ns / cycle_ns) << 21 | > + (timing->t1l_ns / cycle_ns) << 16 | > + (timing->t0h_ns / cycle_ns) << 6 | > + (timing->t0l_ns / cycle_ns); > + writel(val, priv->base + LEDC_T01_TIMING_CTRL_REG); > + > + val = (timing->treset_ns / cycle_ns) << 16 | > + (priv->num_leds - 1); > + writel(val, priv->base + LEDC_RESET_TIMING_CTRL_REG); > +} > + > +static int sun50i_a100_ledc_resume(struct device *dev) > +{ > + struct sun50i_a100_ledc *priv = dev_get_drvdata(dev); > + u32 val; > + int ret; 'control' > + ret = reset_control_deassert(priv->reset); > + if (ret) > + return ret; > + > + ret = clk_prepare_enable(priv->bus_clk); > + if (ret) > + goto err_assert_reset; > + > + ret = clk_prepare_enable(priv->mod_clk); > + if (ret) > + goto err_disable_bus_clk; > + > + sun50i_a100_ledc_set_format(priv); > + sun50i_a100_ledc_set_timing(priv); > + > + /* The trigger level must be at least the burst length. */ > + val = readl(priv->base + LEDC_DMA_CTRL_REG); > + val &= ~LEDC_DMA_CTRL_REG_FIFO_TRIG_LEVEL; > + val |= LEDC_FIFO_DEPTH / 2; > + writel(val, priv->base + LEDC_DMA_CTRL_REG); > + > + val = LEDC_INT_CTRL_REG_GLOBAL_INT_EN | > + LEDC_INT_CTRL_REG_TRANS_FINISH_INT_EN; > + writel(val, priv->base + LEDC_INT_CTRL_REG); > + > + return 0; > + > +err_disable_bus_clk: > + clk_disable_unprepare(priv->bus_clk); > +err_assert_reset: > + reset_control_assert(priv->reset); > + > + return ret; > +} > + > +static int sun50i_a100_ledc_suspend(struct device *dev) > +{ > + struct sun50i_a100_ledc *priv = dev_get_drvdata(dev); > + > + clk_disable_unprepare(priv->mod_clk); > + clk_disable_unprepare(priv->bus_clk); > + reset_control_assert(priv->reset); > + > + return 0; > +} > + > +static void sun50i_a100_ledc_dma_cleanup(void *data) > +{ > + struct sun50i_a100_ledc *priv = data; > + struct device *dma_dev = dmaengine_get_dma_device(priv->dma_chan); What happens if this is NULL or an error? > + if (priv->buffer) > + dma_free_wc(dma_dev, LEDS_TO_BYTES(priv->num_leds), > + priv->buffer, priv->dma_handle); '\n' > + dma_release_channel(priv->dma_chan); > +} > + > +static int sun50i_a100_ledc_probe(struct platform_device *pdev) > +{ > + const struct device_node *np = pdev->dev.of_node; > + struct dma_slave_config dma_cfg = {}; > + struct led_init_data init_data = {}; > + struct device *dev = &pdev->dev; > + struct device_node *child; > + struct sun50i_a100_ledc *priv; > + struct resource *mem; > + int count, irq, ret; > + > + count = of_get_available_child_count(np); > + if (!count) > + return -ENODEV; '\n' > + if (count > LEDC_MAX_LEDS) { > + dev_err(dev, "Too many LEDs! (max is %d)\n", LEDC_MAX_LEDS); > + return -EINVAL; > + } > + > + priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + priv->dev = dev; > + priv->num_leds = count; > + spin_lock_init(&priv->lock); > + dev_set_drvdata(dev, priv); > + > + ret = sun50i_a100_ledc_parse_format(np, priv); > + if (ret) > + return ret; > + > + ret = sun50i_a100_ledc_parse_timing(np, priv); > + if (ret) > + return ret; > + > + priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); > + if (IS_ERR(priv->base)) > + return PTR_ERR(priv->base); > + > + priv->bus_clk = devm_clk_get(dev, "bus"); > + if (IS_ERR(priv->bus_clk)) > + return PTR_ERR(priv->bus_clk); > + > + priv->mod_clk = devm_clk_get(dev, "mod"); > + if (IS_ERR(priv->mod_clk)) > + return PTR_ERR(priv->mod_clk); > + > + priv->reset = devm_reset_control_get_exclusive(dev, NULL); > + if (IS_ERR(priv->reset)) > + return PTR_ERR(priv->reset); > + > + priv->dma_chan = dma_request_chan(dev, "tx"); > + if (IS_ERR(priv->dma_chan)) > + return PTR_ERR(priv->dma_chan); > + > + ret = devm_add_action_or_reset(dev, sun50i_a100_ledc_dma_cleanup, priv); > + if (ret) > + return ret; > + > + dma_cfg.dst_addr = mem->start + LEDC_DATA_REG; > + dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; > + dma_cfg.dst_maxburst = LEDC_FIFO_DEPTH / 2; '\n' > + ret = dmaengine_slave_config(priv->dma_chan, &dma_cfg); > + if (ret) > + return ret; > + > + priv->buffer = dma_alloc_wc(dmaengine_get_dma_device(priv->dma_chan), > + LEDS_TO_BYTES(priv->num_leds), > + &priv->dma_handle, GFP_KERNEL); > + if (!priv->buffer) > + return -ENOMEM; > + > + irq = platform_get_irq(pdev, 0); > + if (irq < 0) > + return irq; > + > + ret = devm_request_irq(dev, irq, sun50i_a100_ledc_irq, > + 0, dev_name(dev), priv); > + if (ret) > + return ret; > + > + ret = sun50i_a100_ledc_resume(dev); > + if (ret) > + return ret; > + > + for_each_available_child_of_node(np, child) { > + struct sun50i_a100_ledc_led *led; > + struct led_classdev *cdev; > + u32 addr, color; > + > + ret = of_property_read_u32(child, "reg", &addr); > + if (ret || addr >= count) { > + dev_err(dev, "LED 'reg' values must be from 0 to %d\n", Doesn't sounds like an address. > + priv->num_leds - 1); 100-chars - no need to wrap. Please apply this everywhere. > + ret = -EINVAL; > + goto err_put_child; > + } > + > + ret = of_property_read_u32(child, "color", &color); > + if (ret || color != LED_COLOR_ID_RGB) { > + dev_err(dev, "LED 'color' must be LED_COLOR_ID_RGB\n"); Then why even provide the option? > + ret = -EINVAL; > + goto err_put_child; > + } > + > + led = &priv->leds[addr]; > + > + led->subled_info[0].color_index = LED_COLOR_ID_RED; > + led->subled_info[0].channel = 0; > + led->subled_info[1].color_index = LED_COLOR_ID_GREEN; > + led->subled_info[1].channel = 1; > + led->subled_info[2].color_index = LED_COLOR_ID_BLUE; > + led->subled_info[2].channel = 2; > + > + led->mc_cdev.num_colors = ARRAY_SIZE(led->subled_info); > + led->mc_cdev.subled_info = led->subled_info; > + > + cdev = &led->mc_cdev.led_cdev; > + cdev->max_brightness = U8_MAX; > + cdev->brightness_set = sun50i_a100_ledc_brightness_set; > + > + init_data.fwnode = of_fwnode_handle(child); > + > + ret = devm_led_classdev_multicolor_register_ext(dev, > + &led->mc_cdev, > + &init_data); > + if (ret) { > + dev_err(dev, "Failed to register LED %u: %d\n", "multicolor LED" > + addr, ret); > + goto err_put_child; > + } > + } > + > + dev_info(dev, "Registered %d LEDs\n", priv->num_leds); > + > + return 0; > + > +err_put_child: > + of_node_put(child); > + sun50i_a100_ledc_suspend(&pdev->dev); > + > + return ret; > +} > + > +static int sun50i_a100_ledc_remove(struct platform_device *pdev) > +{ > + sun50i_a100_ledc_suspend(&pdev->dev); > + > + return 0; return sun50i_a100_ledc_suspend(&pdev->dev); > +} > + > +static void sun50i_a100_ledc_shutdown(struct platform_device *pdev) > +{ > + sun50i_a100_ledc_suspend(&pdev->dev); > +} > + > +static const struct of_device_id sun50i_a100_ledc_of_match[] = { > + { .compatible = "allwinner,sun50i-a100-ledc" }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, sun50i_a100_ledc_of_match); > + > +static DEFINE_SIMPLE_DEV_PM_OPS(sun50i_a100_ledc_pm, > + sun50i_a100_ledc_suspend, > + sun50i_a100_ledc_resume); > + > +static struct platform_driver sun50i_a100_ledc_driver = { > + .probe = sun50i_a100_ledc_probe, > + .remove = sun50i_a100_ledc_remove, > + .shutdown = sun50i_a100_ledc_shutdown, > + .driver = { > + .name = "sun50i-a100-ledc", > + .of_match_table = sun50i_a100_ledc_of_match, > + .pm = pm_ptr(&sun50i_a100_ledc_pm), > + }, > +}; > +module_platform_driver(sun50i_a100_ledc_driver); > + > +MODULE_AUTHOR("Samuel Holland "); > +MODULE_DESCRIPTION("Allwinner A100 LED controller driver"); > +MODULE_LICENSE("GPL"); > -- > 2.37.4 > -- Lee Jones [李琼斯] From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2164EC6FD19 for ; Thu, 16 Mar 2023 13:34:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Az5QUrY7VtM/MnmOCWw1fylI+y4Pp1+nXtbs12ASQgQ=; b=CPvtNzFaTr79rL vtG8zLHa1xdM3hFjZEqdhRXPzYuo1+evUrGL1KAikuwKmBK60WvbDvQ3vlYQPSCxnFrS7YDp1TSo3 Z0ugrfQnoS60Au+RVnPBiepHXfS2CIidHZjlv3/EF0UX00ldA3VvymY9j5JvjMuMdI+yyfcDFxyXg iK9xaJIl8dW0jH9Pus6YtuuJ9X53zjIdlP8Qcs3gQMQTeCzB5CsohFMbGChfw4nicajX4XZ9X1c8P 2LdxZdBhgrMzn3Ao34DTYFIP4TDVGaNYLnSDZNCjWd3n9HMl8SsGzL+YqO7VpRpUrqIUp2sopAQSy n39LDQyB61ySVb2ET00g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pcnkd-00GXi5-2H; Thu, 16 Mar 2023 13:34:39 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pcnkY-00GXg8-0C; Thu, 16 Mar 2023 13:34:36 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 58C7EB82173; Thu, 16 Mar 2023 13:34:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B5A99C433D2; Thu, 16 Mar 2023 13:34:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678973670; bh=qAdEOK4xXU5XBmMSBAwSRPhqlisfmLCDUAov97N9xA4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=AzP5xsEFCnyyDDWq4PkrPTE1OruLkwS3MaOeOW3sTsePcWw+j1BwlFV9rLcOCvu6Z ChB89CxENq6Z/iZl4W5WDQBD22MCitj/+d5Rs/c5c7NLNLBVohrPlLvOOHbntbPUsq QGsumB2Pj36JbzHFK6pA3cTp/6Q2fO9OXcg8q7h1EzrlVPTiA8Dqz7EwdNxmw8P5Qk OabjH8o/RKaAyWwNMpUqhD/1gWbOX5Pc9NOguj8WvIrWYe7O8sLy9YPKjL7m7QjAwu opEmEQTKLcstTx/6llTcOop/2c1wqj0l4zETudIhGzMZJg/xsi9kfi8gjIrMOs0dNJ jIfZ0lKgbMvOA== Date: Thu, 16 Mar 2023 13:34:22 +0000 From: Lee Jones To: Samuel Holland Cc: Pavel Machek , linux-leds@vger.kernel.org, Chen-Yu Tsai , Jernej Skrabec , Albert Ou , Conor Dooley , Guo Ren , Heiko Stuebner , Heiko Stuebner , Jisheng Zhang , Krzysztof Kozlowski , Palmer Dabbelt , Paul Walmsley , Philipp Zabel , Rob Herring , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: Re: [RESEND PATCH v7 2/5] leds: sun50i-a100: New driver for the A100 LED controller Message-ID: <20230316133422.GM9667@google.com> References: <20221231235541.13568-1-samuel@sholland.org> <20221231235541.13568-3-samuel@sholland.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20221231235541.13568-3-samuel@sholland.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230316_063434_383411_62E2DEED X-CRM114-Status: GOOD ( 42.60 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org T24gU2F0LCAzMSBEZWMgMjAyMiwgU2FtdWVsIEhvbGxhbmQgd3JvdGU6Cgo+IFNvbWUgQWxsd2lu bmVyIHN1bnhpIFNvQ3MsIHN0YXJ0aW5nIHdpdGggdGhlIEExMDAsIGNvbnRhaW4gYW4gTEVECj4g Y29udHJvbGxlciBkZXNpZ25lZCB0byBkcml2ZSBSR0IgTEVEIHBpeGVscy4gQWRkIGEgZHJpdmVy IGZvciBpdCB1c2luZwo+IHRoZSBtdWx0aWNvbG9yIExFRCBmcmFtZXdvcmssIGFuZCB3aXRoIExF RHMgZGVmaW5lZCBpbiB0aGUgZGV2aWNlIHRyZWUuCj4KPiBBY2tlZC1ieTogSmVybmVqIFNrcmFi ZWMgPGplcm5lai5za3JhYmVjQGdtYWlsLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBTYW11ZWwgSG9s bGFuZCA8c2FtdWVsQHNob2xsYW5kLm9yZz4KPiAtLS0KPgo+IENoYW5nZXMgaW4gdjc6Cj4gIC0g VXNlIERFRklORV9TSU1QTEVfREVWX1BNX09QUwo+Cj4gQ2hhbmdlcyBpbiB2NToKPiAgLSBSZW5h bWUgdGhlIGRyaXZlciBSMzI5IC0+IEExMDAsIHNpbmNlIHRoYXQgaXMgdGhlIGFjdHVhbCBvcmln aW5hbAo+ICAgIGltcGxlbWVudGF0aW9uCj4KPiBDaGFuZ2VzIGluIHY0Ogo+ICAtIERlcGVuZCBv biBMRURTX0NMQVNTX01VTFRJQ09MT1IKPgo+IENoYW5nZXMgaW4gdjM6Cj4gIC0gQWRkZWQgdmVu ZG9yIHByZWZpeCB0byB0aW1pbmcvZm9ybWF0IHByb3BlcnRpZXMKPiAgLSBSZW5hbWVkICJmb3Jt YXQiIHByb3BlcnR5IHRvICJwaXhlbC1mb3JtYXQiIGZvciBjbGFyaXR5Cj4gIC0gRHJvcHBlZCAi dmxlZC1zdXBwbHkiIGFzIGl0IGlzIHVucmVsYXRlZCB0byB0aGUgY29udHJvbGxlciBoYXJkd2Fy ZQo+ICAtIENoYW5nZWQgIndyaXRlc2wiIHRvICJpb3dyaXRlMzJfcmVwIiBzbyB0aGUgZHJpdmVy IGJ1aWxkcyBvbiBocHBhCj4KPiBDaGFuZ2VzIGluIHYyOgo+ICAtIFJlbmFtZWQgZnJvbSBzdW54 aS1sZWRjIHRvIHN1bjUwaS1yMzI5LWxlZGMKPiAgLSBBZGRlZCBtaXNzaW5nICJzdGF0aWMiIHRv IGZ1bmN0aW9ucy9nbG9iYWxzIGFzIHJlcG9ydGVkIGJ5IDBkYXkgYm90Cj4KPiAgZHJpdmVycy9s ZWRzL0tjb25maWcgICAgICAgICAgICB8ICAgOSArCj4gIGRyaXZlcnMvbGVkcy9NYWtlZmlsZSAg ICAgICAgICAgfCAgIDEgKwo+ICBkcml2ZXJzL2xlZHMvbGVkcy1zdW41MGktYTEwMC5jIHwgNTU1 ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gIDMgZmlsZXMgY2hhbmdlZCwgNTY1 IGluc2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbGVkcy9sZWRzLXN1 bjUwaS1hMTAwLmMKCk5pY2UgZHJpdmVyLiAgSnVzdCBzb21lIG5pdHMgYmVsb3cuCgo+IGRpZmYg LS1naXQgYS9kcml2ZXJzL2xlZHMvS2NvbmZpZyBiL2RyaXZlcnMvbGVkcy9LY29uZmlnCj4gaW5k ZXggNDk5ZDBmMjE1YThiLi40ZjRjNTE1ZWQ3ZDcgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9sZWRz L0tjb25maWcKPiArKysgYi9kcml2ZXJzL2xlZHMvS2NvbmZpZwo+IEBAIC0yODEsNiArMjgxLDE1 IEBAIGNvbmZpZyBMRURTX0NPQkFMVF9SQVEKPiAgCWhlbHAKPiAgCSAgVGhpcyBvcHRpb24gZW5h YmxlcyBzdXBwb3J0IGZvciB0aGUgQ29iYWx0IFJhcSBzZXJpZXMgTEVEcy4KPgo+ICtjb25maWcg TEVEU19TVU41MElfQTEwMAo+ICsJdHJpc3RhdGUgIkxFRCBzdXBwb3J0IGZvciBBbGx3aW5uZXIg QTEwMCBSR0IgTEVEIGNvbnRyb2xsZXIiCj4gKwlkZXBlbmRzIG9uIExFRFNfQ0xBU1NfTVVMVElD T0xPUiAmJiBPRgo+ICsJZGVwZW5kcyBvbiBBUkNIX1NVTlhJIHx8IENPTVBJTEVfVEVTVAo+ICsJ aGVscAo+ICsJICBUaGlzIG9wdGlvbiBlbmFibGVzIHN1cHBvcnQgZm9yIHRoZSBSR0IgTEVEIGNv bnRyb2xsZXIgZm91bmQKPiArCSAgaW4gc29tZSBBbGx3aW5uZXIgc3VueGkgU29DcywgaW5jbHVk ZWluZyBBMTAwLCBSMzI5LCBhbmQgRDEuCj4gKwkgIEl0IHVzZXMgYSBvbmUtd2lyZSBpbnRlcmZh Y2UgdG8gY29udHJvbCB1cCB0byAxMDI0IExFRHMuCgpEaWQgeW91IHJ1biBzcGVsbGNoZWNrIG9u IHRoaXM/Cgo+ICBjb25maWcgTEVEU19TVU5GSVJFCj4gIAl0cmlzdGF0ZSAiTEVEIHN1cHBvcnQg Zm9yIFN1bkZpcmUgc2VydmVycy4iCj4gIAlkZXBlbmRzIG9uIExFRFNfQ0xBU1MKPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9sZWRzL01ha2VmaWxlIGIvZHJpdmVycy9sZWRzL01ha2VmaWxlCj4gaW5k ZXggNGZkMmY5MmNkMTk4Li5hNmVlM2Y1Y2Y3YmUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9sZWRz L01ha2VmaWxlCj4gKysrIGIvZHJpdmVycy9sZWRzL01ha2VmaWxlCj4gQEAgLTc2LDYgKzc2LDcg QEAgb2JqLSQoQ09ORklHX0xFRFNfUFdNKQkJCSs9IGxlZHMtcHdtLm8KPiAgb2JqLSQoQ09ORklH X0xFRFNfUkVHVUxBVE9SKQkJKz0gbGVkcy1yZWd1bGF0b3Iubwo+ICBvYmotJChDT05GSUdfTEVE U19TM0MyNFhYKQkJKz0gbGVkcy1zM2MyNHh4Lm8KPiAgb2JqLSQoQ09ORklHX0xFRFNfU0MyN1hY X0JMVEMpCQkrPSBsZWRzLXNjMjd4eC1ibHRjLm8KPiArb2JqLSQoQ09ORklHX0xFRFNfU1VONTBJ X0ExMDApCQkrPSBsZWRzLXN1bjUwaS1hMTAwLm8KPiAgb2JqLSQoQ09ORklHX0xFRFNfU1VORklS RSkJCSs9IGxlZHMtc3VuZmlyZS5vCj4gIG9iai0kKENPTkZJR19MRURTX1NZU0NPTikJCSs9IGxl ZHMtc3lzY29uLm8KPiAgb2JqLSQoQ09ORklHX0xFRFNfVENBNjUwNykJCSs9IGxlZHMtdGNhNjUw Ny5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbGVkcy9sZWRzLXN1bjUwaS1hMTAwLmMgYi9kcml2 ZXJzL2xlZHMvbGVkcy1zdW41MGktYTEwMC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRl eCAwMDAwMDAwMDAwMDAuLjMwZmE5YmUyY2YyZAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2 ZXJzL2xlZHMvbGVkcy1zdW41MGktYTEwMC5jCj4gQEAgLTAsMCArMSw1NTUgQEAKPiArLy8gU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPiArLy8KPiArLy8gQ29weXJpZ2h0IChjKSAy MDIxLTIwMjIgU2FtdWVsIEhvbGxhbmQgPHNhbXVlbEBzaG9sbGFuZC5vcmc+CgpQbGVhc2UgdXBk YXRlLgoKPiArLy8gUGFydGx5IGJhc2VkIG9uIGRyaXZlcnMvbGVkcy9sZWRzLXR1cnJpcy1vbW5p YS5jLCB3aGljaCBpczoKPiArLy8gICAgIENvcHlyaWdodCAoYykgMjAyMCBieSBNYXJlayBCZWjD um4gPGthYmVsQGtlcm5lbC5vcmc+Cj4gKy8vCgpXaGF0IGlzIHRoaXMgbGluZSBjb21tZW50aW5n PwoKQ291bGQgeW91IHBsZWFzZSByZS1kbyB0aGlzIGhlYWRlciB0byB1c2UgQy1zdHlsZSBjb21t ZW50cyBwbGVhc2UuCgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9kbWEtbWFwcGluZy5oPgo+ICsjaW5jbHVkZSA8bGludXgvZG1hZW5naW5lLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2lvLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9sZWQtY2xhc3MtbXVsdGljb2xvci5oPgo+ICsjaW5jbHVkZSA8bGludXgvbGVk cy5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZi5o Pgo+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9wbS5oPgo+ICsjaW5jbHVkZSA8bGludXgvcmVzZXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3Nw aW5sb2NrLmg+Cj4gKwo+ICsjZGVmaW5lIExFRENfQ1RSTF9SRUcJCQkweDAwMDAKPiArI2RlZmlu ZSBMRURDX0NUUkxfUkVHX0RBVEFfTEVOR1RICQkoMHgxZmZmIDw8IDE2KQo+ICsjZGVmaW5lIExF RENfQ1RSTF9SRUdfUkdCX01PREUJCQkoMHg3IDw8IDYpCj4gKyNkZWZpbmUgTEVEQ19DVFJMX1JF R19MRURDX0VOCQkJQklUKDApCj4gKyNkZWZpbmUgTEVEQ19UMDFfVElNSU5HX0NUUkxfUkVHCTB4 MDAwNAo+ICsjZGVmaW5lIExFRENfVDAxX1RJTUlOR19DVFJMX1JFR19UMUgJCSgweDNmIDw8IDIx KQo+ICsjZGVmaW5lIExFRENfVDAxX1RJTUlOR19DVFJMX1JFR19UMUwJCSgweDFmIDw8IDE2KQo+ ICsjZGVmaW5lIExFRENfVDAxX1RJTUlOR19DVFJMX1JFR19UMEgJCSgweDFmIDw8IDYpCj4gKyNk ZWZpbmUgTEVEQ19UMDFfVElNSU5HX0NUUkxfUkVHX1QwTAkJKDB4M2YgPDwgMCkKPiArI2RlZmlu ZSBMRURDX1JFU0VUX1RJTUlOR19DVFJMX1JFRwkweDAwMGMKPiArI2RlZmluZSBMRURDX1JFU0VU X1RJTUlOR19DVFJMX1JFR19MRURfTlVNCSgweDNmZiA8PCAwKQo+ICsjZGVmaW5lIExFRENfREFU QV9SRUcJCQkweDAwMTQKPiArI2RlZmluZSBMRURDX0RNQV9DVFJMX1JFRwkJMHgwMDE4Cj4gKyNk ZWZpbmUgTEVEQ19ETUFfQ1RSTF9SRUdfRklGT19UUklHX0xFVkVMCSgweDFmIDw8IDApCj4gKyNk ZWZpbmUgTEVEQ19JTlRfQ1RSTF9SRUcJCTB4MDAxYwo+ICsjZGVmaW5lIExFRENfSU5UX0NUUkxf UkVHX0dMT0JBTF9JTlRfRU4JCUJJVCg1KQo+ICsjZGVmaW5lIExFRENfSU5UX0NUUkxfUkVHX0ZJ Rk9fQ1BVUkVRX0lOVF9FTglCSVQoMSkKPiArI2RlZmluZSBMRURDX0lOVF9DVFJMX1JFR19UUkFO U19GSU5JU0hfSU5UX0VOCUJJVCgwKQo+ICsjZGVmaW5lIExFRENfSU5UX1NUU19SRUcJCTB4MDAy MAo+ICsjZGVmaW5lIExFRENfSU5UX1NUU19SRUdfRklGT19DUFVSRVFfSU5UCUJJVCgxKQo+ICsj ZGVmaW5lIExFRENfSU5UX1NUU19SRUdfVFJBTlNfRklOSVNIX0lOVAlCSVQoMCkKPiArCj4gKyNk ZWZpbmUgTEVEQ19GSUZPX0RFUFRICQkJMzIKPiArI2RlZmluZSBMRURDX01BWF9MRURTCQkJMTAy NAo+ICsKPiArI2RlZmluZSBMRURTX1RPX0JZVEVTKG4pCQkoKG4pICogc2l6ZW9mKHUzMikpCj4g Kwo+ICtzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkY19sZWQgewoKSXMgdGhpcyBpbmZvcm1hdGlvbiBs aWtlbHkgdG8gY2hhbmdlIG9uIGEgcGVyLUxFRCBiYXNpcz8KCj4gKwlzdHJ1Y3QgbGVkX2NsYXNz ZGV2X21jIG1jX2NkZXY7Cj4gKwlzdHJ1Y3QgbWNfc3VibGVkIHN1YmxlZF9pbmZvWzNdOwoKV2hh dCBpcyAzPwoKPiArfTsKPiArCj4gKyNkZWZpbmUgdG9fbGVkY19sZWQobWMpIGNvbnRhaW5lcl9v ZihtYywgc3RydWN0IHN1bjUwaV9hMTAwX2xlZGNfbGVkLCBtY19jZGV2KQo+ICsKPiArc3RydWN0 IHN1bjUwaV9hMTAwX2xlZGNfdGltaW5nIHsKPiArCXUzMiB0MGhfbnM7Cj4gKwl1MzIgdDBsX25z Owo+ICsJdTMyIHQxaF9uczsKPiArCXUzMiB0MWxfbnM7Cj4gKwl1MzIgdHJlc2V0X25zOwo+ICt9 Owo+ICsKPiArc3RydWN0IHN1bjUwaV9hMTAwX2xlZGMgewo+ICsJc3RydWN0IGRldmljZSAqZGV2 Owo+ICsJdm9pZCBfX2lvbWVtICpiYXNlOwo+ICsJc3RydWN0IGNsayAqYnVzX2NsazsKPiArCXN0 cnVjdCBjbGsgKm1vZF9jbGs7Cj4gKwlzdHJ1Y3QgcmVzZXRfY29udHJvbCAqcmVzZXQ7Cj4gKwo+ ICsJdTMyICpidWZmZXI7Cj4gKwlzdHJ1Y3QgZG1hX2NoYW4gKmRtYV9jaGFuOwo+ICsJZG1hX2Fk ZHJfdCBkbWFfaGFuZGxlOwo+ICsJaW50IHBpb19sZW5ndGg7Cj4gKwlpbnQgcGlvX29mZnNldDsK PiArCj4gKwlzcGlubG9ja190IGxvY2s7Cj4gKwlpbnQgbmV4dF9sZW5ndGg7Cj4gKwlib29sIHhm ZXJfYWN0aXZlOwo+ICsKPiArCXUzMiBmb3JtYXQ7Cj4gKwlzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVk Y190aW1pbmcgdGltaW5nOwo+ICsKPiArCWludCBudW1fbGVkczsKPiArCXN0cnVjdCBzdW41MGlf YTEwMF9sZWRjX2xlZCBsZWRzW107Cj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAw X2xlZGNfZG1hX3hmZXIoc3RydWN0IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYsIGludCBsZW5ndGgp Cj4gK3sKPiArCXN0cnVjdCBkbWFfYXN5bmNfdHhfZGVzY3JpcHRvciAqZGVzYzsKPiArCWRtYV9j b29raWVfdCBjb29raWU7Cj4gKwo+ICsJZGVzYyA9IGRtYWVuZ2luZV9wcmVwX3NsYXZlX3Npbmds ZShwcml2LT5kbWFfY2hhbiwgcHJpdi0+ZG1hX2hhbmRsZSwKPiArCQkJCQkgICBMRURTX1RPX0JZ VEVTKGxlbmd0aCksCj4gKwkJCQkJICAgRE1BX01FTV9UT19ERVYsIDApOwo+ICsJaWYgKCFkZXNj KQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCWNvb2tpZSA9IGRtYWVuZ2luZV9zdWJtaXQo ZGVzYyk7Cj4gKwlpZiAoZG1hX3N1Ym1pdF9lcnJvcihjb29raWUpKQo+ICsJCXJldHVybiAtRUlP Owo+ICsKPiArCWRtYV9hc3luY19pc3N1ZV9wZW5kaW5nKHByaXYtPmRtYV9jaGFuKTsKPiArCj4g KwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgc3VuNTBpX2ExMDBfbGVkY19waW9f eGZlcihzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkYyAqcHJpdiwgaW50IGxlbmd0aCkKPiArewo+ICsJ dTMyIGJ1cnN0LCBvZmZzZXQsIHZhbDsKPiArCj4gKwlpZiAobGVuZ3RoKSB7Cj4gKwkJLyogTmV3 IHRyYW5zZmVyIChGSUZPIGlzIGVtcHR5KS4gKi8KPiArCQlvZmZzZXQgPSAwOwo+ICsJCWJ1cnN0 ICA9IG1pbihsZW5ndGgsIExFRENfRklGT19ERVBUSCk7Cj4gKwl9IGVsc2Ugewo+ICsJCS8qIEV4 aXN0aW5nIHRyYW5zZmVyIChGSUZPIGlzIGhhbGYtZnVsbCkuICovCj4gKwkJbGVuZ3RoID0gcHJp di0+cGlvX2xlbmd0aDsKPiArCQlvZmZzZXQgPSBwcml2LT5waW9fb2Zmc2V0Owo+ICsJCWJ1cnN0 ICA9IG1pbihsZW5ndGgsIExFRENfRklGT19ERVBUSCAvIDIpOwoKRGlkbid0IHdlIGFscmVhZHkg ZXN0YWJsaXNoIHRoYXQgbGVuZ3RoIHdhcyAwPwoKPiArCX0KPiArCj4gKwlpb3dyaXRlMzJfcmVw KHByaXYtPmJhc2UgKyBMRURDX0RBVEFfUkVHLCBwcml2LT5idWZmZXIgKyBvZmZzZXQsIGJ1cnN0 KTsKPiArCj4gKwlpZiAoYnVyc3QgPCBsZW5ndGgpIHsKPiArCQlwcml2LT5waW9fbGVuZ3RoID0g bGVuZ3RoIC0gYnVyc3Q7Cj4gKwkJcHJpdi0+cGlvX29mZnNldCA9IG9mZnNldCArIGJ1cnN0Owo+ ICsKPiArCQlpZiAoIW9mZnNldCkgewo+ICsJCQl2YWwgPSByZWFkbChwcml2LT5iYXNlICsgTEVE Q19JTlRfQ1RSTF9SRUcpOwo+ICsJCQl2YWwgfD0gTEVEQ19JTlRfQ1RSTF9SRUdfRklGT19DUFVS RVFfSU5UX0VOOwo+ICsJCQl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19JTlRfQ1RSTF9S RUcpOwo+ICsJCX0KPiArCX0gZWxzZSB7Cj4gKwkJLyogRGlzYWJsZSB0aGUgcmVxdWVzdCBJUlEg b25jZSBhbGwgZGF0YSBpcyB3cml0dGVuLiAqLwo+ICsJCXZhbCA9IHJlYWRsKHByaXYtPmJhc2Ug KyBMRURDX0lOVF9DVFJMX1JFRyk7Cj4gKwkJdmFsICY9IH5MRURDX0lOVF9DVFJMX1JFR19GSUZP X0NQVVJFUV9JTlRfRU47Cj4gKwkJd3JpdGVsKHZhbCwgcHJpdi0+YmFzZSArIExFRENfSU5UX0NU UkxfUkVHKTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIHZvaWQgc3VuNTBpX2ExMDBfbGVkY19z dGFydF94ZmVyKHN0cnVjdCBzdW41MGlfYTEwMF9sZWRjICpwcml2LAo+ICsJCQkJCWludCBsZW5n dGgpCj4gK3sKPiArCXUzMiB2YWw7Cj4gKwo+ICsJZGV2X2RiZyhwcml2LT5kZXYsICJVcGRhdGlu ZyAlZCBMRURzXG4iLCBsZW5ndGgpOwoKSG93IHVzZWZ1bCBpcyB0aGlzLCByZWFsbHk/CgpDb3Vs ZCB5b3UgY29uc2lkZXIgcmVtb3ZpbmcgaXQ/Cgo+ICsJdmFsID0gcmVhZGwocHJpdi0+YmFzZSAr IExFRENfQ1RSTF9SRUcpOwo+ICsJdmFsICY9IH5MRURDX0NUUkxfUkVHX0RBVEFfTEVOR1RIOwo+ ICsJdmFsIHw9IGxlbmd0aCA8PCAxNiB8IExFRENfQ1RSTF9SRUdfTEVEQ19FTjsKCldoeSAxNj8g IFBsZWFzZSBjb25zaWRlciBkZWZpbmluZyBhbGwgbWFnaWMgbnVtYmVycy4KCiAgQkxBSF9CTEFI X1NISUZUID8KCj4gKwl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19DVFJMX1JFRyk7Cj4g Kwo+ICsJaWYgKGxlbmd0aCA+IExFRENfRklGT19ERVBUSCkgewo+ICsJCWludCByZXQgPSBzdW41 MGlfYTEwMF9sZWRjX2RtYV94ZmVyKHByaXYsIGxlbmd0aCk7CgpMb29rcyBvZGQuICBJdCdzIHdh eSBtb3JlIGNvbW1vbiB0byBzZXBhcmF0ZSB0aGUgY2FsbCBmcm9tIHRoZSBkZWNsYXJhdGlvbi4K Cj4gKwkJaWYgKCFyZXQpCj4gKwkJCXJldHVybjsKPiArCj4gKwkJZGV2X3dhcm4ocHJpdi0+ZGV2 LCAiRmFpbGVkIHRvIHNldCB1cCBETUE6ICVkXG4iLCByZXQpOwoKVGhpcyBsb29rcyBsaWtlIGFu IGVycm9yLgoKUGxlYXNlIHRlbGwgdGhlIHVzZXIgd2UncmUgZmFsbGluZyBiYWNrIHRvIFBJTy4K Cj4gKwl9Cj4gKwo+ICsJc3VuNTBpX2ExMDBfbGVkY19waW9feGZlcihwcml2LCBsZW5ndGgpOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgaXJxcmV0dXJuX3Qgc3VuNTBpX2ExMDBfbGVkY19pcnEoaW50IGly cSwgdm9pZCAqZGV2X2lkKQo+ICt7Cj4gKwlzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkYyAqcHJpdiA9 IGRldl9pZDsKClRoaXMgaXMgY2xlYXJseSBub3QgYSBkZWZfaWQuICAnZGF0YScgbG9va3MgbGlr ZSBhIGNvbW1vbiBhbHRlcm5hdGl2ZS4KCj4gKwl1MzIgdmFsOwo+ICsKPiArCXZhbCA9IHJlYWRs KHByaXYtPmJhc2UgKyBMRURDX0lOVF9TVFNfUkVHKTsKCid2YWwnIGlzIGEgdGVycmlibGUgdmFy aWFibGUgbmFtZS4gICdzdGF0dXMnPwoKPiArCWlmICh2YWwgJiBMRURDX0lOVF9TVFNfUkVHX1RS QU5TX0ZJTklTSF9JTlQpIHsKPiArCQlpbnQgbmV4dF9sZW5ndGg7Cj4gKwo+ICsJCS8qIFN0YXJ0 IHRoZSBuZXh0IHRyYW5zZmVyIGlmIG5lZWRlZC4gKi8KPiArCQlzcGluX2xvY2soJnByaXYtPmxv Y2spOwo+ICsJCW5leHRfbGVuZ3RoID0gcHJpdi0+bmV4dF9sZW5ndGg7Cj4gKwkJaWYgKG5leHRf bGVuZ3RoKQo+ICsJCQlwcml2LT5uZXh0X2xlbmd0aCA9IDA7Cj4gKwkJZWxzZQo+ICsJCQlwcml2 LT54ZmVyX2FjdGl2ZSA9IGZhbHNlOwo+ICsJCXNwaW5fdW5sb2NrKCZwcml2LT5sb2NrKTsKPiAr Cj4gKwkJaWYgKG5leHRfbGVuZ3RoKQo+ICsJCQlzdW41MGlfYTEwMF9sZWRjX3N0YXJ0X3hmZXIo cHJpdiwgbmV4dF9sZW5ndGgpOwo+ICsJfSBlbHNlIGlmICh2YWwgJiBMRURDX0lOVF9TVFNfUkVH X0ZJRk9fQ1BVUkVRX0lOVCkgewo+ICsJCS8qIENvbnRpbnVlIHRoZSBjdXJyZW50IHRyYW5zZmVy LiAqLwo+ICsJCXN1bjUwaV9hMTAwX2xlZGNfcGlvX3hmZXIocHJpdiwgMCk7Cj4gKwl9Cj4gKwo+ ICsJd3JpdGVsKHZhbCwgcHJpdi0+YmFzZSArIExFRENfSU5UX1NUU19SRUcpOwoKRGlkICd2YWwn IGNoYW5nZT8gIElmIHRoaXMgaXMgaW50ZW50aW9uYWwsIHBlcmhhcHMgYSBjb21tZW50IHRvIGNs YXJpZnkuCgo+ICsJcmV0dXJuIElSUV9IQU5ETEVEOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBz dW41MGlfYTEwMF9sZWRjX2JyaWdodG5lc3Nfc2V0KHN0cnVjdCBsZWRfY2xhc3NkZXYgKmNkZXYs Cj4gKwkJCQkJICAgIGVudW0gbGVkX2JyaWdodG5lc3MgYnJpZ2h0bmVzcykKPiArewo+ICsJc3Ry dWN0IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYgPSBkZXZfZ2V0X2RydmRhdGEoY2Rldi0+ZGV2LT5w YXJlbnQpOwo+ICsJc3RydWN0IGxlZF9jbGFzc2Rldl9tYyAqbWNfY2RldiA9IGxjZGV2X3RvX21j Y2RldihjZGV2KTsKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRjX2xlZCAqbGVkID0gdG9fbGVk Y19sZWQobWNfY2Rldik7Cj4gKwlpbnQgYWRkciA9IGxlZCAtIHByaXYtPmxlZHM7CgpOb3QgcmVh bGx5IGFuIGFkZHJlc3MgaXMgaXQ/ICAnb2Zmc2V0JyBvciBzb21ldGhpbmcgYmV0dGVyPwoKPiAr CXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwlib29sIHhmZXJfYWN0aXZlOwo+ICsJaW50IG5leHRf bGVuZ3RoOwo+ICsKPiArCWxlZF9tY19jYWxjX2NvbG9yX2NvbXBvbmVudHMobWNfY2RldiwgYnJp Z2h0bmVzcyk7Cj4gKwo+ICsJcHJpdi0+YnVmZmVyW2FkZHJdID0gbGVkLT5zdWJsZWRfaW5mb1sw XS5icmlnaHRuZXNzIDw8IDE2IHwKPiArCQkJICAgICBsZWQtPnN1YmxlZF9pbmZvWzFdLmJyaWdo dG5lc3MgPDwgIDggfAo+ICsJCQkgICAgIGxlZC0+c3VibGVkX2luZm9bMl0uYnJpZ2h0bmVzczsK PiArCj4gKwlkZXZfZGJnKHByaXYtPmRldiwgIkxFRCAlZCAtPiAjJTA2eFxuIiwgYWRkciwgcHJp di0+YnVmZmVyW2FkZHJdKTsKCkFzIGFib3ZlLgoKPiArCXNwaW5fbG9ja19pcnFzYXZlKCZwcml2 LT5sb2NrLCBmbGFncyk7Cj4gKwluZXh0X2xlbmd0aCA9IG1heChwcml2LT5uZXh0X2xlbmd0aCwg YWRkciArIDEpOwo+ICsJeGZlcl9hY3RpdmUgPSBwcml2LT54ZmVyX2FjdGl2ZTsKPiArCWlmICh4 ZmVyX2FjdGl2ZSkKPiArCQlwcml2LT5uZXh0X2xlbmd0aCA9IG5leHRfbGVuZ3RoOwo+ICsJZWxz ZQo+ICsJCXByaXYtPnhmZXJfYWN0aXZlID0gdHJ1ZTsKPiArCXNwaW5fdW5sb2NrX2lycXJlc3Rv cmUoJnByaXYtPmxvY2ssIGZsYWdzKTsKCkNyYW1wZWQgY29kZSBpcyBub3QgZWFzeSB0byByZWFk LiAgUGxlYXNlIGNvbnNpZGVyIHNvbWUgJ1xuJ3MuCgo+ICsJaWYgKCF4ZmVyX2FjdGl2ZSkKPiAr CQlzdW41MGlfYTEwMF9sZWRjX3N0YXJ0X3hmZXIocHJpdiwgbmV4dF9sZW5ndGgpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgY29uc3QgY2hhciAqY29uc3Qgc3VuNTBpX2ExMDBfbGVkY19mb3JtYXRzW10g PSB7Cj4gKwkicmdiIiwKPiArCSJyYmciLAo+ICsJImdyYiIsCj4gKwkiZ2JyIiwKPiArCSJicmci LAo+ICsJImJnciIsCj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAwX2xlZGNfcGFy c2VfZm9ybWF0KGNvbnN0IHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAsCj4gKwkJCQkJIHN0cnVjdCBz dW41MGlfYTEwMF9sZWRjICpwcml2KQo+ICt7Cj4gKwljb25zdCBjaGFyICpmb3JtYXQgPSAiZ3Ji IjsKPiArCXUzMiBpOwo+ICsKPiArCW9mX3Byb3BlcnR5X3JlYWRfc3RyaW5nKG5wLCAiYWxsd2lu bmVyLHBpeGVsLWZvcm1hdCIsICZmb3JtYXQpOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBBUlJB WV9TSVpFKHN1bjUwaV9hMTAwX2xlZGNfZm9ybWF0cyk7ICsraSkgewoKRG9lcyB0aGUgcHJlLWlu Y3JlbWVudCBob2xkIGFueSBzaWduaWZpY2FuY2U/CgpJZiBub3QsIHBsZWFzZSB1c2UgdGhlIG1v cmUgY29tbW9uIGltcGxlbWVudGF0aW9uIG9mIHBvc3QtaW5jcmVtZW50aW5nLgoKPiArCQlpZiAo IXN0cmNtcChmb3JtYXQsIHN1bjUwaV9hMTAwX2xlZGNfZm9ybWF0c1tpXSkpIHsKPiArCQkJcHJp di0+Zm9ybWF0ID0gaTsKPiArCQkJcmV0dXJuIDA7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCWRldl9l cnIocHJpdi0+ZGV2LCAiQmFkIHBpeGVsIGZvcm1hdCAnJXMnXG4iLCBmb3JtYXQpOwo+ICsKPiAr CXJldHVybiAtRUlOVkFMOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBzdW41MGlfYTEwMF9sZWRj X3NldF9mb3JtYXQoc3RydWN0IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYpCj4gK3sKPiArCXUzMiB2 YWw7Cj4gKwo+ICsJdmFsID0gcmVhZGwocHJpdi0+YmFzZSArIExFRENfQ1RSTF9SRUcpOwo+ICsJ dmFsICY9IH5MRURDX0NUUkxfUkVHX1JHQl9NT0RFOwo+ICsJdmFsIHw9IHByaXYtPmZvcm1hdCA8 PCA2Owo+ICsJd3JpdGVsKHZhbCwgcHJpdi0+YmFzZSArIExFRENfQ1RSTF9SRUcpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHN1bjUwaV9hMTAwX2xlZGNfdGltaW5nIHN1bjUwaV9h MTAwX2xlZGNfZGVmYXVsdF90aW1pbmcgPSB7Cj4gKwkudDBoX25zID0gMzM2LAo+ICsJLnQwbF9u cyA9IDg0MCwKPiArCS50MWhfbnMgPSA4ODIsCj4gKwkudDFsX25zID0gMjk0LAo+ICsJLnRyZXNl dF9ucyA9IDMwMDAwMCwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgc3VuNTBpX2ExMDBfbGVkY19w YXJzZV90aW1pbmcoY29uc3Qgc3RydWN0IGRldmljZV9ub2RlICpucCwKPiArCQkJCQkgc3RydWN0 IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYpCj4gK3sKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRj X3RpbWluZyAqdGltaW5nID0gJnByaXYtPnRpbWluZzsKPiArCj4gKwkqdGltaW5nID0gc3VuNTBp X2ExMDBfbGVkY19kZWZhdWx0X3RpbWluZzsKPiArCj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihu cCwgImFsbHdpbm5lcix0MGgtbnMiLCAmdGltaW5nLT50MGhfbnMpOwo+ICsJb2ZfcHJvcGVydHlf cmVhZF91MzIobnAsICJhbGx3aW5uZXIsdDBsLW5zIiwgJnRpbWluZy0+dDBsX25zKTsKPiArCW9m X3Byb3BlcnR5X3JlYWRfdTMyKG5wLCAiYWxsd2lubmVyLHQxaC1ucyIsICZ0aW1pbmctPnQxaF9u cyk7Cj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgImFsbHdpbm5lcix0MWwtbnMiLCAmdGlt aW5nLT50MWxfbnMpOwo+ICsJb2ZfcHJvcGVydHlfcmVhZF91MzIobnAsICJhbGx3aW5uZXIsdHJl c2V0LW5zIiwgJnRpbWluZy0+dHJlc2V0X25zKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiArc3RhdGljIHZvaWQgc3VuNTBpX2ExMDBfbGVkY19zZXRfdGltaW5nKHN0cnVjdCBzdW41MGlf YTEwMF9sZWRjICpwcml2KQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkY190 aW1pbmcgKnRpbWluZyA9ICZwcml2LT50aW1pbmc7Cj4gKwl1bnNpZ25lZCBsb25nIG1vZF9mcmVx ID0gY2xrX2dldF9yYXRlKHByaXYtPm1vZF9jbGspOwo+ICsJdTMyIGN5Y2xlX25zID0gTlNFQ19Q RVJfU0VDIC8gbW9kX2ZyZXE7Cj4gKwl1MzIgdmFsOwoKJ3RpbWluZycKCj4gKwl2YWwgPSAodGlt aW5nLT50MWhfbnMgLyBjeWNsZV9ucykgPDwgMjEgfAo+ICsJICAgICAgKHRpbWluZy0+dDFsX25z IC8gY3ljbGVfbnMpIDw8IDE2IHwKPiArCSAgICAgICh0aW1pbmctPnQwaF9ucyAvIGN5Y2xlX25z KSA8PCAgNiB8Cj4gKwkgICAgICAodGltaW5nLT50MGxfbnMgLyBjeWNsZV9ucyk7Cj4gKwl3cml0 ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19UMDFfVElNSU5HX0NUUkxfUkVHKTsKPiArCj4gKwl2 YWwgPSAodGltaW5nLT50cmVzZXRfbnMgLyBjeWNsZV9ucykgPDwgMTYgfAo+ICsJICAgICAgKHBy aXYtPm51bV9sZWRzIC0gMSk7Cj4gKwl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19SRVNF VF9USU1JTkdfQ1RSTF9SRUcpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAwX2xl ZGNfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsJc3RydWN0IHN1bjUwaV9hMTAw X2xlZGMgKnByaXYgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiArCXUzMiB2YWw7Cj4gKwlpbnQg cmV0OwoKJ2NvbnRyb2wnCgo+ICsJcmV0ID0gcmVzZXRfY29udHJvbF9kZWFzc2VydChwcml2LT5y ZXNldCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX3By ZXBhcmVfZW5hYmxlKHByaXYtPmJ1c19jbGspOwo+ICsJaWYgKHJldCkKPiArCQlnb3RvIGVycl9h c3NlcnRfcmVzZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKHByaXYtPm1vZF9j bGspOwo+ICsJaWYgKHJldCkKPiArCQlnb3RvIGVycl9kaXNhYmxlX2J1c19jbGs7Cj4gKwo+ICsJ c3VuNTBpX2ExMDBfbGVkY19zZXRfZm9ybWF0KHByaXYpOwo+ICsJc3VuNTBpX2ExMDBfbGVkY19z ZXRfdGltaW5nKHByaXYpOwo+ICsKPiArCS8qIFRoZSB0cmlnZ2VyIGxldmVsIG11c3QgYmUgYXQg bGVhc3QgdGhlIGJ1cnN0IGxlbmd0aC4gKi8KPiArCXZhbCA9IHJlYWRsKHByaXYtPmJhc2UgKyBM RURDX0RNQV9DVFJMX1JFRyk7Cj4gKwl2YWwgJj0gfkxFRENfRE1BX0NUUkxfUkVHX0ZJRk9fVFJJ R19MRVZFTDsKPiArCXZhbCB8PSBMRURDX0ZJRk9fREVQVEggLyAyOwo+ICsJd3JpdGVsKHZhbCwg cHJpdi0+YmFzZSArIExFRENfRE1BX0NUUkxfUkVHKTsKPiArCj4gKwl2YWwgPSBMRURDX0lOVF9D VFJMX1JFR19HTE9CQUxfSU5UX0VOIHwKPiArCSAgICAgIExFRENfSU5UX0NUUkxfUkVHX1RSQU5T X0ZJTklTSF9JTlRfRU47Cj4gKwl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19JTlRfQ1RS TF9SRUcpOwo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXJyX2Rpc2FibGVfYnVzX2NsazoKPiAr CWNsa19kaXNhYmxlX3VucHJlcGFyZShwcml2LT5idXNfY2xrKTsKPiArZXJyX2Fzc2VydF9yZXNl dDoKPiArCXJlc2V0X2NvbnRyb2xfYXNzZXJ0KHByaXYtPnJlc2V0KTsKPiArCj4gKwlyZXR1cm4g cmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAwX2xlZGNfc3VzcGVuZChzdHJ1 Y3QgZGV2aWNlICpkZXYpCj4gK3sKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRjICpwcml2ID0g ZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHByaXYt Pm1vZF9jbGspOwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHByaXYtPmJ1c19jbGspOwo+ICsJ cmVzZXRfY29udHJvbF9hc3NlcnQocHJpdi0+cmVzZXQpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgdm9pZCBzdW41MGlfYTEwMF9sZWRjX2RtYV9jbGVhbnVwKHZvaWQgKmRh dGEpCj4gK3sKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRjICpwcml2ID0gZGF0YTsKPiArCXN0 cnVjdCBkZXZpY2UgKmRtYV9kZXYgPSBkbWFlbmdpbmVfZ2V0X2RtYV9kZXZpY2UocHJpdi0+ZG1h X2NoYW4pOwoKV2hhdCBoYXBwZW5zIGlmIHRoaXMgaXMgTlVMTCBvciBhbiBlcnJvcj8KCj4gKwlp ZiAocHJpdi0+YnVmZmVyKQo+ICsJCWRtYV9mcmVlX3djKGRtYV9kZXYsIExFRFNfVE9fQllURVMo cHJpdi0+bnVtX2xlZHMpLAo+ICsJCQkgICAgcHJpdi0+YnVmZmVyLCBwcml2LT5kbWFfaGFuZGxl KTsKCidcbicKCj4gKwlkbWFfcmVsZWFzZV9jaGFubmVsKHByaXYtPmRtYV9jaGFuKTsKPiArfQo+ ICsKPiArc3RhdGljIGludCBzdW41MGlfYTEwMF9sZWRjX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBwZGV2 LT5kZXYub2Zfbm9kZTsKPiArCXN0cnVjdCBkbWFfc2xhdmVfY29uZmlnIGRtYV9jZmcgPSB7fTsK PiArCXN0cnVjdCBsZWRfaW5pdF9kYXRhIGluaXRfZGF0YSA9IHt9Owo+ICsJc3RydWN0IGRldmlj ZSAqZGV2ID0gJnBkZXYtPmRldjsKPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqY2hpbGQ7Cj4gKwlz dHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkYyAqcHJpdjsKPiArCXN0cnVjdCByZXNvdXJjZSAqbWVtOwo+ ICsJaW50IGNvdW50LCBpcnEsIHJldDsKPiArCj4gKwljb3VudCA9IG9mX2dldF9hdmFpbGFibGVf Y2hpbGRfY291bnQobnApOwo+ICsJaWYgKCFjb3VudCkKPiArCQlyZXR1cm4gLUVOT0RFVjsKCidc bicKCj4gKwlpZiAoY291bnQgPiBMRURDX01BWF9MRURTKSB7Cj4gKwkJZGV2X2VycihkZXYsICJU b28gbWFueSBMRURzISAobWF4IGlzICVkKVxuIiwgTEVEQ19NQVhfTEVEUyk7Cj4gKwkJcmV0dXJu IC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJcHJpdiA9IGRldm1fa3phbGxvYyhkZXYsIHN0cnVjdF9z aXplKHByaXYsIGxlZHMsIGNvdW50KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXByaXYpCj4gKwkJ cmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJcHJpdi0+ZGV2ID0gZGV2Owo+ICsJcHJpdi0+bnVtX2xl ZHMgPSBjb3VudDsKPiArCXNwaW5fbG9ja19pbml0KCZwcml2LT5sb2NrKTsKPiArCWRldl9zZXRf ZHJ2ZGF0YShkZXYsIHByaXYpOwo+ICsKPiArCXJldCA9IHN1bjUwaV9hMTAwX2xlZGNfcGFyc2Vf Zm9ybWF0KG5wLCBwcml2KTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwly ZXQgPSBzdW41MGlfYTEwMF9sZWRjX3BhcnNlX3RpbWluZyhucCwgcHJpdik7Cj4gKwlpZiAocmV0 KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcHJpdi0+YmFzZSA9IGRldm1fcGxhdGZvcm1fZ2V0 X2FuZF9pb3JlbWFwX3Jlc291cmNlKHBkZXYsIDAsICZtZW0pOwo+ICsJaWYgKElTX0VSUihwcml2 LT5iYXNlKSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5iYXNlKTsKPiArCj4gKwlwcml2LT5i dXNfY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgImJ1cyIpOwo+ICsJaWYgKElTX0VSUihwcml2LT5i dXNfY2xrKSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5idXNfY2xrKTsKPiArCj4gKwlwcml2 LT5tb2RfY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgIm1vZCIpOwo+ICsJaWYgKElTX0VSUihwcml2 LT5tb2RfY2xrKSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5tb2RfY2xrKTsKPiArCj4gKwlw cml2LT5yZXNldCA9IGRldm1fcmVzZXRfY29udHJvbF9nZXRfZXhjbHVzaXZlKGRldiwgTlVMTCk7 Cj4gKwlpZiAoSVNfRVJSKHByaXYtPnJlc2V0KSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5y ZXNldCk7Cj4gKwo+ICsJcHJpdi0+ZG1hX2NoYW4gPSBkbWFfcmVxdWVzdF9jaGFuKGRldiwgInR4 Iik7Cj4gKwlpZiAoSVNfRVJSKHByaXYtPmRtYV9jaGFuKSkKPiArCQlyZXR1cm4gUFRSX0VSUihw cml2LT5kbWFfY2hhbik7Cj4gKwo+ICsJcmV0ID0gZGV2bV9hZGRfYWN0aW9uX29yX3Jlc2V0KGRl diwgc3VuNTBpX2ExMDBfbGVkY19kbWFfY2xlYW51cCwgcHJpdik7Cj4gKwlpZiAocmV0KQo+ICsJ CXJldHVybiByZXQ7Cj4gKwo+ICsJZG1hX2NmZy5kc3RfYWRkcgk9IG1lbS0+c3RhcnQgKyBMRURD X0RBVEFfUkVHOwo+ICsJZG1hX2NmZy5kc3RfYWRkcl93aWR0aAk9IERNQV9TTEFWRV9CVVNXSURU SF80X0JZVEVTOwo+ICsJZG1hX2NmZy5kc3RfbWF4YnVyc3QJPSBMRURDX0ZJRk9fREVQVEggLyAy OwoKJ1xuJwoKPiArCXJldCA9IGRtYWVuZ2luZV9zbGF2ZV9jb25maWcocHJpdi0+ZG1hX2NoYW4s ICZkbWFfY2ZnKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlwcml2LT5i dWZmZXIgPSBkbWFfYWxsb2Nfd2MoZG1hZW5naW5lX2dldF9kbWFfZGV2aWNlKHByaXYtPmRtYV9j aGFuKSwKPiArCQkJCSAgICBMRURTX1RPX0JZVEVTKHByaXYtPm51bV9sZWRzKSwKPiArCQkJCSAg ICAmcHJpdi0+ZG1hX2hhbmRsZSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXByaXYtPmJ1ZmZlcikK PiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYs IDApOwo+ICsJaWYgKGlycSA8IDApCj4gKwkJcmV0dXJuIGlycTsKPiArCj4gKwlyZXQgPSBkZXZt X3JlcXVlc3RfaXJxKGRldiwgaXJxLCBzdW41MGlfYTEwMF9sZWRjX2lycSwKPiArCQkJICAgICAg IDAsIGRldl9uYW1lKGRldiksIHByaXYpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ ICsKPiArCXJldCA9IHN1bjUwaV9hMTAwX2xlZGNfcmVzdW1lKGRldik7Cj4gKwlpZiAocmV0KQo+ ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJZm9yX2VhY2hfYXZhaWxhYmxlX2NoaWxkX29mX25vZGUo bnAsIGNoaWxkKSB7Cj4gKwkJc3RydWN0IHN1bjUwaV9hMTAwX2xlZGNfbGVkICpsZWQ7Cj4gKwkJ c3RydWN0IGxlZF9jbGFzc2RldiAqY2RldjsKPiArCQl1MzIgYWRkciwgY29sb3I7Cj4gKwo+ICsJ CXJldCA9IG9mX3Byb3BlcnR5X3JlYWRfdTMyKGNoaWxkLCAicmVnIiwgJmFkZHIpOwo+ICsJCWlm IChyZXQgfHwgYWRkciA+PSBjb3VudCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkxFRCAncmVnJyB2 YWx1ZXMgbXVzdCBiZSBmcm9tIDAgdG8gJWRcbiIsCgpEb2Vzbid0IHNvdW5kcyBsaWtlIGFuIGFk ZHJlc3MuCgo+ICsJCQkJcHJpdi0+bnVtX2xlZHMgLSAxKTsKCjEwMC1jaGFycyAtIG5vIG5lZWQg dG8gd3JhcC4KClBsZWFzZSBhcHBseSB0aGlzIGV2ZXJ5d2hlcmUuCgo+ICsJCQlyZXQgPSAtRUlO VkFMOwo+ICsJCQlnb3RvIGVycl9wdXRfY2hpbGQ7Cj4gKwkJfQo+ICsKPiArCQlyZXQgPSBvZl9w cm9wZXJ0eV9yZWFkX3UzMihjaGlsZCwgImNvbG9yIiwgJmNvbG9yKTsKPiArCQlpZiAocmV0IHx8 IGNvbG9yICE9IExFRF9DT0xPUl9JRF9SR0IpIHsKPiArCQkJZGV2X2VycihkZXYsICJMRUQgJ2Nv bG9yJyBtdXN0IGJlIExFRF9DT0xPUl9JRF9SR0JcbiIpOwoKVGhlbiB3aHkgZXZlbiBwcm92aWRl IHRoZSBvcHRpb24/Cgo+ICsJCQlyZXQgPSAtRUlOVkFMOwo+ICsJCQlnb3RvIGVycl9wdXRfY2hp bGQ7Cj4gKwkJfQo+ICsKPiArCQlsZWQgPSAmcHJpdi0+bGVkc1thZGRyXTsKPiArCj4gKwkJbGVk LT5zdWJsZWRfaW5mb1swXS5jb2xvcl9pbmRleCA9IExFRF9DT0xPUl9JRF9SRUQ7Cj4gKwkJbGVk LT5zdWJsZWRfaW5mb1swXS5jaGFubmVsID0gMDsKPiArCQlsZWQtPnN1YmxlZF9pbmZvWzFdLmNv bG9yX2luZGV4ID0gTEVEX0NPTE9SX0lEX0dSRUVOOwo+ICsJCWxlZC0+c3VibGVkX2luZm9bMV0u Y2hhbm5lbCA9IDE7Cj4gKwkJbGVkLT5zdWJsZWRfaW5mb1syXS5jb2xvcl9pbmRleCA9IExFRF9D T0xPUl9JRF9CTFVFOwo+ICsJCWxlZC0+c3VibGVkX2luZm9bMl0uY2hhbm5lbCA9IDI7Cj4gKwo+ ICsJCWxlZC0+bWNfY2Rldi5udW1fY29sb3JzID0gQVJSQVlfU0laRShsZWQtPnN1YmxlZF9pbmZv KTsKPiArCQlsZWQtPm1jX2NkZXYuc3VibGVkX2luZm8gPSBsZWQtPnN1YmxlZF9pbmZvOwo+ICsK PiArCQljZGV2ID0gJmxlZC0+bWNfY2Rldi5sZWRfY2RldjsKPiArCQljZGV2LT5tYXhfYnJpZ2h0 bmVzcyA9IFU4X01BWDsKPiArCQljZGV2LT5icmlnaHRuZXNzX3NldCA9IHN1bjUwaV9hMTAwX2xl ZGNfYnJpZ2h0bmVzc19zZXQ7Cj4gKwo+ICsJCWluaXRfZGF0YS5md25vZGUgPSBvZl9md25vZGVf aGFuZGxlKGNoaWxkKTsKPiArCj4gKwkJcmV0ID0gZGV2bV9sZWRfY2xhc3NkZXZfbXVsdGljb2xv cl9yZWdpc3Rlcl9leHQoZGV2LAo+ICsJCQkJCQkJCSZsZWQtPm1jX2NkZXYsCj4gKwkJCQkJCQkJ JmluaXRfZGF0YSk7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0 byByZWdpc3RlciBMRUQgJXU6ICVkXG4iLAoKIm11bHRpY29sb3IgTEVEIgoKPiArCQkJCWFkZHIs IHJldCk7Cj4gKwkJCWdvdG8gZXJyX3B1dF9jaGlsZDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJZGV2 X2luZm8oZGV2LCAiUmVnaXN0ZXJlZCAlZCBMRURzXG4iLCBwcml2LT5udW1fbGVkcyk7Cj4gKwo+ ICsJcmV0dXJuIDA7Cj4gKwo+ICtlcnJfcHV0X2NoaWxkOgo+ICsJb2Zfbm9kZV9wdXQoY2hpbGQp Owo+ICsJc3VuNTBpX2ExMDBfbGVkY19zdXNwZW5kKCZwZGV2LT5kZXYpOwo+ICsKPiArCXJldHVy biByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgc3VuNTBpX2ExMDBfbGVkY19yZW1vdmUoc3Ry dWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3VuNTBpX2ExMDBfbGVkY19zdXNw ZW5kKCZwZGV2LT5kZXYpOwo+ICsKPiArCXJldHVybiAwOwoKcmV0dXJuIHN1bjUwaV9hMTAwX2xl ZGNfc3VzcGVuZCgmcGRldi0+ZGV2KTsKCj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHN1bjUwaV9h MTAwX2xlZGNfc2h1dGRvd24oc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJ c3VuNTBpX2ExMDBfbGVkY19zdXNwZW5kKCZwZGV2LT5kZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg Y29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBzdW41MGlfYTEwMF9sZWRjX29mX21hdGNoW10gPSB7 Cj4gKwl7IC5jb21wYXRpYmxlID0gImFsbHdpbm5lcixzdW41MGktYTEwMC1sZWRjIiB9LAo+ICsJ e30KPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgc3VuNTBpX2ExMDBfbGVkY19vZl9t YXRjaCk7Cj4gKwo+ICtzdGF0aWMgREVGSU5FX1NJTVBMRV9ERVZfUE1fT1BTKHN1bjUwaV9hMTAw X2xlZGNfcG0sCj4gKwkJCQlzdW41MGlfYTEwMF9sZWRjX3N1c3BlbmQsCj4gKwkJCQlzdW41MGlf YTEwMF9sZWRjX3Jlc3VtZSk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBz dW41MGlfYTEwMF9sZWRjX2RyaXZlciA9IHsKPiArCS5wcm9iZQkJPSBzdW41MGlfYTEwMF9sZWRj X3Byb2JlLAo+ICsJLnJlbW92ZQkJPSBzdW41MGlfYTEwMF9sZWRjX3JlbW92ZSwKPiArCS5zaHV0 ZG93bgk9IHN1bjUwaV9hMTAwX2xlZGNfc2h1dGRvd24sCj4gKwkuZHJpdmVyCQk9IHsKPiArCQku bmFtZQkJPSAic3VuNTBpLWExMDAtbGVkYyIsCj4gKwkJLm9mX21hdGNoX3RhYmxlCT0gc3VuNTBp X2ExMDBfbGVkY19vZl9tYXRjaCwKPiArCQkucG0JCT0gcG1fcHRyKCZzdW41MGlfYTEwMF9sZWRj X3BtKSwKPiArCX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIoc3VuNTBpX2ExMDBf bGVkY19kcml2ZXIpOwo+ICsKPiArTU9EVUxFX0FVVEhPUigiU2FtdWVsIEhvbGxhbmQgPHNhbXVl bEBzaG9sbGFuZC5vcmc+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiQWxsd2lubmVyIEExMDAg TEVEIGNvbnRyb2xsZXIgZHJpdmVyIik7Cj4gK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKPiAtLQo+ IDIuMzcuNAo+CgotLQpMZWUgSm9uZXMgW+adjueQvOaWr10KCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LXJpc2N2IG1haWxpbmcgbGlzdApsaW51 eC1yaXNjdkBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21h aWxtYW4vbGlzdGluZm8vbGludXgtcmlzY3YK From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C38CEC6FD19 for ; Thu, 16 Mar 2023 13:35:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=JlJkh9p8qiDAgJfl1zQo4U0ByoGEuPJIDRj9bncDjHA=; b=TsZzbZGLvPZS2v F6nHyTDuv1s1kEO39wAEDrX186kFsFoJ58hUbU69yECNPvhf+94QPZANqXwIfmAnyhLSl+aIuGleS ILIXlUnoyMPJP2LpriI0D7UuwEzjpbj6y//rp6bOeakqYOj+85VPciYT6WPih+616byRNK8taVpYB N/xwz9mlmZKFgCaHra7yT50sdVCSm5w9lt3E11d/TNmIWQYUMtgUBSntJlkElO2TdkGz4df7K0Ya0 4kq9Z1Kb5G6/Ittw+jqm40PIU10VVZpJRNZ68dKS+N5CwZqDiWqOW8YdFvX3Z6s9p+EVmDMfUSAyc UZkRiIgYEKRnBAiOC5kg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1pcnkc-00GXhX-2P; Thu, 16 Mar 2023 13:34:38 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1pcnkY-00GXg8-0C; Thu, 16 Mar 2023 13:34:36 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 58C7EB82173; Thu, 16 Mar 2023 13:34:31 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B5A99C433D2; Thu, 16 Mar 2023 13:34:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1678973670; bh=qAdEOK4xXU5XBmMSBAwSRPhqlisfmLCDUAov97N9xA4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=AzP5xsEFCnyyDDWq4PkrPTE1OruLkwS3MaOeOW3sTsePcWw+j1BwlFV9rLcOCvu6Z ChB89CxENq6Z/iZl4W5WDQBD22MCitj/+d5Rs/c5c7NLNLBVohrPlLvOOHbntbPUsq QGsumB2Pj36JbzHFK6pA3cTp/6Q2fO9OXcg8q7h1EzrlVPTiA8Dqz7EwdNxmw8P5Qk OabjH8o/RKaAyWwNMpUqhD/1gWbOX5Pc9NOguj8WvIrWYe7O8sLy9YPKjL7m7QjAwu opEmEQTKLcstTx/6llTcOop/2c1wqj0l4zETudIhGzMZJg/xsi9kfi8gjIrMOs0dNJ jIfZ0lKgbMvOA== Date: Thu, 16 Mar 2023 13:34:22 +0000 From: Lee Jones To: Samuel Holland Cc: Pavel Machek , linux-leds@vger.kernel.org, Chen-Yu Tsai , Jernej Skrabec , Albert Ou , Conor Dooley , Guo Ren , Heiko Stuebner , Heiko Stuebner , Jisheng Zhang , Krzysztof Kozlowski , Palmer Dabbelt , Paul Walmsley , Philipp Zabel , Rob Herring , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-sunxi@lists.linux.dev Subject: Re: [RESEND PATCH v7 2/5] leds: sun50i-a100: New driver for the A100 LED controller Message-ID: <20230316133422.GM9667@google.com> References: <20221231235541.13568-1-samuel@sholland.org> <20221231235541.13568-3-samuel@sholland.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20221231235541.13568-3-samuel@sholland.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230316_063434_383411_62E2DEED X-CRM114-Status: GOOD ( 42.60 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org T24gU2F0LCAzMSBEZWMgMjAyMiwgU2FtdWVsIEhvbGxhbmQgd3JvdGU6Cgo+IFNvbWUgQWxsd2lu bmVyIHN1bnhpIFNvQ3MsIHN0YXJ0aW5nIHdpdGggdGhlIEExMDAsIGNvbnRhaW4gYW4gTEVECj4g Y29udHJvbGxlciBkZXNpZ25lZCB0byBkcml2ZSBSR0IgTEVEIHBpeGVscy4gQWRkIGEgZHJpdmVy IGZvciBpdCB1c2luZwo+IHRoZSBtdWx0aWNvbG9yIExFRCBmcmFtZXdvcmssIGFuZCB3aXRoIExF RHMgZGVmaW5lZCBpbiB0aGUgZGV2aWNlIHRyZWUuCj4KPiBBY2tlZC1ieTogSmVybmVqIFNrcmFi ZWMgPGplcm5lai5za3JhYmVjQGdtYWlsLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBTYW11ZWwgSG9s bGFuZCA8c2FtdWVsQHNob2xsYW5kLm9yZz4KPiAtLS0KPgo+IENoYW5nZXMgaW4gdjc6Cj4gIC0g VXNlIERFRklORV9TSU1QTEVfREVWX1BNX09QUwo+Cj4gQ2hhbmdlcyBpbiB2NToKPiAgLSBSZW5h bWUgdGhlIGRyaXZlciBSMzI5IC0+IEExMDAsIHNpbmNlIHRoYXQgaXMgdGhlIGFjdHVhbCBvcmln aW5hbAo+ICAgIGltcGxlbWVudGF0aW9uCj4KPiBDaGFuZ2VzIGluIHY0Ogo+ICAtIERlcGVuZCBv biBMRURTX0NMQVNTX01VTFRJQ09MT1IKPgo+IENoYW5nZXMgaW4gdjM6Cj4gIC0gQWRkZWQgdmVu ZG9yIHByZWZpeCB0byB0aW1pbmcvZm9ybWF0IHByb3BlcnRpZXMKPiAgLSBSZW5hbWVkICJmb3Jt YXQiIHByb3BlcnR5IHRvICJwaXhlbC1mb3JtYXQiIGZvciBjbGFyaXR5Cj4gIC0gRHJvcHBlZCAi dmxlZC1zdXBwbHkiIGFzIGl0IGlzIHVucmVsYXRlZCB0byB0aGUgY29udHJvbGxlciBoYXJkd2Fy ZQo+ICAtIENoYW5nZWQgIndyaXRlc2wiIHRvICJpb3dyaXRlMzJfcmVwIiBzbyB0aGUgZHJpdmVy IGJ1aWxkcyBvbiBocHBhCj4KPiBDaGFuZ2VzIGluIHYyOgo+ICAtIFJlbmFtZWQgZnJvbSBzdW54 aS1sZWRjIHRvIHN1bjUwaS1yMzI5LWxlZGMKPiAgLSBBZGRlZCBtaXNzaW5nICJzdGF0aWMiIHRv IGZ1bmN0aW9ucy9nbG9iYWxzIGFzIHJlcG9ydGVkIGJ5IDBkYXkgYm90Cj4KPiAgZHJpdmVycy9s ZWRzL0tjb25maWcgICAgICAgICAgICB8ICAgOSArCj4gIGRyaXZlcnMvbGVkcy9NYWtlZmlsZSAg ICAgICAgICAgfCAgIDEgKwo+ICBkcml2ZXJzL2xlZHMvbGVkcy1zdW41MGktYTEwMC5jIHwgNTU1 ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCj4gIDMgZmlsZXMgY2hhbmdlZCwgNTY1 IGluc2VydGlvbnMoKykKPiAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvbGVkcy9sZWRzLXN1 bjUwaS1hMTAwLmMKCk5pY2UgZHJpdmVyLiAgSnVzdCBzb21lIG5pdHMgYmVsb3cuCgo+IGRpZmYg LS1naXQgYS9kcml2ZXJzL2xlZHMvS2NvbmZpZyBiL2RyaXZlcnMvbGVkcy9LY29uZmlnCj4gaW5k ZXggNDk5ZDBmMjE1YThiLi40ZjRjNTE1ZWQ3ZDcgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9sZWRz L0tjb25maWcKPiArKysgYi9kcml2ZXJzL2xlZHMvS2NvbmZpZwo+IEBAIC0yODEsNiArMjgxLDE1 IEBAIGNvbmZpZyBMRURTX0NPQkFMVF9SQVEKPiAgCWhlbHAKPiAgCSAgVGhpcyBvcHRpb24gZW5h YmxlcyBzdXBwb3J0IGZvciB0aGUgQ29iYWx0IFJhcSBzZXJpZXMgTEVEcy4KPgo+ICtjb25maWcg TEVEU19TVU41MElfQTEwMAo+ICsJdHJpc3RhdGUgIkxFRCBzdXBwb3J0IGZvciBBbGx3aW5uZXIg QTEwMCBSR0IgTEVEIGNvbnRyb2xsZXIiCj4gKwlkZXBlbmRzIG9uIExFRFNfQ0xBU1NfTVVMVElD T0xPUiAmJiBPRgo+ICsJZGVwZW5kcyBvbiBBUkNIX1NVTlhJIHx8IENPTVBJTEVfVEVTVAo+ICsJ aGVscAo+ICsJICBUaGlzIG9wdGlvbiBlbmFibGVzIHN1cHBvcnQgZm9yIHRoZSBSR0IgTEVEIGNv bnRyb2xsZXIgZm91bmQKPiArCSAgaW4gc29tZSBBbGx3aW5uZXIgc3VueGkgU29DcywgaW5jbHVk ZWluZyBBMTAwLCBSMzI5LCBhbmQgRDEuCj4gKwkgIEl0IHVzZXMgYSBvbmUtd2lyZSBpbnRlcmZh Y2UgdG8gY29udHJvbCB1cCB0byAxMDI0IExFRHMuCgpEaWQgeW91IHJ1biBzcGVsbGNoZWNrIG9u IHRoaXM/Cgo+ICBjb25maWcgTEVEU19TVU5GSVJFCj4gIAl0cmlzdGF0ZSAiTEVEIHN1cHBvcnQg Zm9yIFN1bkZpcmUgc2VydmVycy4iCj4gIAlkZXBlbmRzIG9uIExFRFNfQ0xBU1MKPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9sZWRzL01ha2VmaWxlIGIvZHJpdmVycy9sZWRzL01ha2VmaWxlCj4gaW5k ZXggNGZkMmY5MmNkMTk4Li5hNmVlM2Y1Y2Y3YmUgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9sZWRz L01ha2VmaWxlCj4gKysrIGIvZHJpdmVycy9sZWRzL01ha2VmaWxlCj4gQEAgLTc2LDYgKzc2LDcg QEAgb2JqLSQoQ09ORklHX0xFRFNfUFdNKQkJCSs9IGxlZHMtcHdtLm8KPiAgb2JqLSQoQ09ORklH X0xFRFNfUkVHVUxBVE9SKQkJKz0gbGVkcy1yZWd1bGF0b3Iubwo+ICBvYmotJChDT05GSUdfTEVE U19TM0MyNFhYKQkJKz0gbGVkcy1zM2MyNHh4Lm8KPiAgb2JqLSQoQ09ORklHX0xFRFNfU0MyN1hY X0JMVEMpCQkrPSBsZWRzLXNjMjd4eC1ibHRjLm8KPiArb2JqLSQoQ09ORklHX0xFRFNfU1VONTBJ X0ExMDApCQkrPSBsZWRzLXN1bjUwaS1hMTAwLm8KPiAgb2JqLSQoQ09ORklHX0xFRFNfU1VORklS RSkJCSs9IGxlZHMtc3VuZmlyZS5vCj4gIG9iai0kKENPTkZJR19MRURTX1NZU0NPTikJCSs9IGxl ZHMtc3lzY29uLm8KPiAgb2JqLSQoQ09ORklHX0xFRFNfVENBNjUwNykJCSs9IGxlZHMtdGNhNjUw Ny5vCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbGVkcy9sZWRzLXN1bjUwaS1hMTAwLmMgYi9kcml2 ZXJzL2xlZHMvbGVkcy1zdW41MGktYTEwMC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRl eCAwMDAwMDAwMDAwMDAuLjMwZmE5YmUyY2YyZAo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2 ZXJzL2xlZHMvbGVkcy1zdW41MGktYTEwMC5jCj4gQEAgLTAsMCArMSw1NTUgQEAKPiArLy8gU1BE WC1MaWNlbnNlLUlkZW50aWZpZXI6IEdQTC0yLjAKPiArLy8KPiArLy8gQ29weXJpZ2h0IChjKSAy MDIxLTIwMjIgU2FtdWVsIEhvbGxhbmQgPHNhbXVlbEBzaG9sbGFuZC5vcmc+CgpQbGVhc2UgdXBk YXRlLgoKPiArLy8gUGFydGx5IGJhc2VkIG9uIGRyaXZlcnMvbGVkcy9sZWRzLXR1cnJpcy1vbW5p YS5jLCB3aGljaCBpczoKPiArLy8gICAgIENvcHlyaWdodCAoYykgMjAyMCBieSBNYXJlayBCZWjD um4gPGthYmVsQGtlcm5lbC5vcmc+Cj4gKy8vCgpXaGF0IGlzIHRoaXMgbGluZSBjb21tZW50aW5n PwoKQ291bGQgeW91IHBsZWFzZSByZS1kbyB0aGlzIGhlYWRlciB0byB1c2UgQy1zdHlsZSBjb21t ZW50cyBwbGVhc2UuCgo+ICsjaW5jbHVkZSA8bGludXgvY2xrLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9kbWEtbWFwcGluZy5oPgo+ICsjaW5jbHVkZSA8bGludXgvZG1hZW5naW5lLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L2lvLmg+Cj4gKyNpbmNs dWRlIDxsaW51eC9sZWQtY2xhc3MtbXVsdGljb2xvci5oPgo+ICsjaW5jbHVkZSA8bGludXgvbGVk cy5oPgo+ICsjaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9vZi5o Pgo+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+Cj4gKyNpbmNsdWRlIDxsaW51 eC9wbS5oPgo+ICsjaW5jbHVkZSA8bGludXgvcmVzZXQuaD4KPiArI2luY2x1ZGUgPGxpbnV4L3Nw aW5sb2NrLmg+Cj4gKwo+ICsjZGVmaW5lIExFRENfQ1RSTF9SRUcJCQkweDAwMDAKPiArI2RlZmlu ZSBMRURDX0NUUkxfUkVHX0RBVEFfTEVOR1RICQkoMHgxZmZmIDw8IDE2KQo+ICsjZGVmaW5lIExF RENfQ1RSTF9SRUdfUkdCX01PREUJCQkoMHg3IDw8IDYpCj4gKyNkZWZpbmUgTEVEQ19DVFJMX1JF R19MRURDX0VOCQkJQklUKDApCj4gKyNkZWZpbmUgTEVEQ19UMDFfVElNSU5HX0NUUkxfUkVHCTB4 MDAwNAo+ICsjZGVmaW5lIExFRENfVDAxX1RJTUlOR19DVFJMX1JFR19UMUgJCSgweDNmIDw8IDIx KQo+ICsjZGVmaW5lIExFRENfVDAxX1RJTUlOR19DVFJMX1JFR19UMUwJCSgweDFmIDw8IDE2KQo+ ICsjZGVmaW5lIExFRENfVDAxX1RJTUlOR19DVFJMX1JFR19UMEgJCSgweDFmIDw8IDYpCj4gKyNk ZWZpbmUgTEVEQ19UMDFfVElNSU5HX0NUUkxfUkVHX1QwTAkJKDB4M2YgPDwgMCkKPiArI2RlZmlu ZSBMRURDX1JFU0VUX1RJTUlOR19DVFJMX1JFRwkweDAwMGMKPiArI2RlZmluZSBMRURDX1JFU0VU X1RJTUlOR19DVFJMX1JFR19MRURfTlVNCSgweDNmZiA8PCAwKQo+ICsjZGVmaW5lIExFRENfREFU QV9SRUcJCQkweDAwMTQKPiArI2RlZmluZSBMRURDX0RNQV9DVFJMX1JFRwkJMHgwMDE4Cj4gKyNk ZWZpbmUgTEVEQ19ETUFfQ1RSTF9SRUdfRklGT19UUklHX0xFVkVMCSgweDFmIDw8IDApCj4gKyNk ZWZpbmUgTEVEQ19JTlRfQ1RSTF9SRUcJCTB4MDAxYwo+ICsjZGVmaW5lIExFRENfSU5UX0NUUkxf UkVHX0dMT0JBTF9JTlRfRU4JCUJJVCg1KQo+ICsjZGVmaW5lIExFRENfSU5UX0NUUkxfUkVHX0ZJ Rk9fQ1BVUkVRX0lOVF9FTglCSVQoMSkKPiArI2RlZmluZSBMRURDX0lOVF9DVFJMX1JFR19UUkFO U19GSU5JU0hfSU5UX0VOCUJJVCgwKQo+ICsjZGVmaW5lIExFRENfSU5UX1NUU19SRUcJCTB4MDAy MAo+ICsjZGVmaW5lIExFRENfSU5UX1NUU19SRUdfRklGT19DUFVSRVFfSU5UCUJJVCgxKQo+ICsj ZGVmaW5lIExFRENfSU5UX1NUU19SRUdfVFJBTlNfRklOSVNIX0lOVAlCSVQoMCkKPiArCj4gKyNk ZWZpbmUgTEVEQ19GSUZPX0RFUFRICQkJMzIKPiArI2RlZmluZSBMRURDX01BWF9MRURTCQkJMTAy NAo+ICsKPiArI2RlZmluZSBMRURTX1RPX0JZVEVTKG4pCQkoKG4pICogc2l6ZW9mKHUzMikpCj4g Kwo+ICtzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkY19sZWQgewoKSXMgdGhpcyBpbmZvcm1hdGlvbiBs aWtlbHkgdG8gY2hhbmdlIG9uIGEgcGVyLUxFRCBiYXNpcz8KCj4gKwlzdHJ1Y3QgbGVkX2NsYXNz ZGV2X21jIG1jX2NkZXY7Cj4gKwlzdHJ1Y3QgbWNfc3VibGVkIHN1YmxlZF9pbmZvWzNdOwoKV2hh dCBpcyAzPwoKPiArfTsKPiArCj4gKyNkZWZpbmUgdG9fbGVkY19sZWQobWMpIGNvbnRhaW5lcl9v ZihtYywgc3RydWN0IHN1bjUwaV9hMTAwX2xlZGNfbGVkLCBtY19jZGV2KQo+ICsKPiArc3RydWN0 IHN1bjUwaV9hMTAwX2xlZGNfdGltaW5nIHsKPiArCXUzMiB0MGhfbnM7Cj4gKwl1MzIgdDBsX25z Owo+ICsJdTMyIHQxaF9uczsKPiArCXUzMiB0MWxfbnM7Cj4gKwl1MzIgdHJlc2V0X25zOwo+ICt9 Owo+ICsKPiArc3RydWN0IHN1bjUwaV9hMTAwX2xlZGMgewo+ICsJc3RydWN0IGRldmljZSAqZGV2 Owo+ICsJdm9pZCBfX2lvbWVtICpiYXNlOwo+ICsJc3RydWN0IGNsayAqYnVzX2NsazsKPiArCXN0 cnVjdCBjbGsgKm1vZF9jbGs7Cj4gKwlzdHJ1Y3QgcmVzZXRfY29udHJvbCAqcmVzZXQ7Cj4gKwo+ ICsJdTMyICpidWZmZXI7Cj4gKwlzdHJ1Y3QgZG1hX2NoYW4gKmRtYV9jaGFuOwo+ICsJZG1hX2Fk ZHJfdCBkbWFfaGFuZGxlOwo+ICsJaW50IHBpb19sZW5ndGg7Cj4gKwlpbnQgcGlvX29mZnNldDsK PiArCj4gKwlzcGlubG9ja190IGxvY2s7Cj4gKwlpbnQgbmV4dF9sZW5ndGg7Cj4gKwlib29sIHhm ZXJfYWN0aXZlOwo+ICsKPiArCXUzMiBmb3JtYXQ7Cj4gKwlzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVk Y190aW1pbmcgdGltaW5nOwo+ICsKPiArCWludCBudW1fbGVkczsKPiArCXN0cnVjdCBzdW41MGlf YTEwMF9sZWRjX2xlZCBsZWRzW107Cj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAw X2xlZGNfZG1hX3hmZXIoc3RydWN0IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYsIGludCBsZW5ndGgp Cj4gK3sKPiArCXN0cnVjdCBkbWFfYXN5bmNfdHhfZGVzY3JpcHRvciAqZGVzYzsKPiArCWRtYV9j b29raWVfdCBjb29raWU7Cj4gKwo+ICsJZGVzYyA9IGRtYWVuZ2luZV9wcmVwX3NsYXZlX3Npbmds ZShwcml2LT5kbWFfY2hhbiwgcHJpdi0+ZG1hX2hhbmRsZSwKPiArCQkJCQkgICBMRURTX1RPX0JZ VEVTKGxlbmd0aCksCj4gKwkJCQkJICAgRE1BX01FTV9UT19ERVYsIDApOwo+ICsJaWYgKCFkZXNj KQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCWNvb2tpZSA9IGRtYWVuZ2luZV9zdWJtaXQo ZGVzYyk7Cj4gKwlpZiAoZG1hX3N1Ym1pdF9lcnJvcihjb29raWUpKQo+ICsJCXJldHVybiAtRUlP Owo+ICsKPiArCWRtYV9hc3luY19pc3N1ZV9wZW5kaW5nKHByaXYtPmRtYV9jaGFuKTsKPiArCj4g KwlyZXR1cm4gMDsKPiArfQo+ICsKPiArc3RhdGljIHZvaWQgc3VuNTBpX2ExMDBfbGVkY19waW9f eGZlcihzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkYyAqcHJpdiwgaW50IGxlbmd0aCkKPiArewo+ICsJ dTMyIGJ1cnN0LCBvZmZzZXQsIHZhbDsKPiArCj4gKwlpZiAobGVuZ3RoKSB7Cj4gKwkJLyogTmV3 IHRyYW5zZmVyIChGSUZPIGlzIGVtcHR5KS4gKi8KPiArCQlvZmZzZXQgPSAwOwo+ICsJCWJ1cnN0 ICA9IG1pbihsZW5ndGgsIExFRENfRklGT19ERVBUSCk7Cj4gKwl9IGVsc2Ugewo+ICsJCS8qIEV4 aXN0aW5nIHRyYW5zZmVyIChGSUZPIGlzIGhhbGYtZnVsbCkuICovCj4gKwkJbGVuZ3RoID0gcHJp di0+cGlvX2xlbmd0aDsKPiArCQlvZmZzZXQgPSBwcml2LT5waW9fb2Zmc2V0Owo+ICsJCWJ1cnN0 ICA9IG1pbihsZW5ndGgsIExFRENfRklGT19ERVBUSCAvIDIpOwoKRGlkbid0IHdlIGFscmVhZHkg ZXN0YWJsaXNoIHRoYXQgbGVuZ3RoIHdhcyAwPwoKPiArCX0KPiArCj4gKwlpb3dyaXRlMzJfcmVw KHByaXYtPmJhc2UgKyBMRURDX0RBVEFfUkVHLCBwcml2LT5idWZmZXIgKyBvZmZzZXQsIGJ1cnN0 KTsKPiArCj4gKwlpZiAoYnVyc3QgPCBsZW5ndGgpIHsKPiArCQlwcml2LT5waW9fbGVuZ3RoID0g bGVuZ3RoIC0gYnVyc3Q7Cj4gKwkJcHJpdi0+cGlvX29mZnNldCA9IG9mZnNldCArIGJ1cnN0Owo+ ICsKPiArCQlpZiAoIW9mZnNldCkgewo+ICsJCQl2YWwgPSByZWFkbChwcml2LT5iYXNlICsgTEVE Q19JTlRfQ1RSTF9SRUcpOwo+ICsJCQl2YWwgfD0gTEVEQ19JTlRfQ1RSTF9SRUdfRklGT19DUFVS RVFfSU5UX0VOOwo+ICsJCQl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19JTlRfQ1RSTF9S RUcpOwo+ICsJCX0KPiArCX0gZWxzZSB7Cj4gKwkJLyogRGlzYWJsZSB0aGUgcmVxdWVzdCBJUlEg b25jZSBhbGwgZGF0YSBpcyB3cml0dGVuLiAqLwo+ICsJCXZhbCA9IHJlYWRsKHByaXYtPmJhc2Ug KyBMRURDX0lOVF9DVFJMX1JFRyk7Cj4gKwkJdmFsICY9IH5MRURDX0lOVF9DVFJMX1JFR19GSUZP X0NQVVJFUV9JTlRfRU47Cj4gKwkJd3JpdGVsKHZhbCwgcHJpdi0+YmFzZSArIExFRENfSU5UX0NU UkxfUkVHKTsKPiArCX0KPiArfQo+ICsKPiArc3RhdGljIHZvaWQgc3VuNTBpX2ExMDBfbGVkY19z dGFydF94ZmVyKHN0cnVjdCBzdW41MGlfYTEwMF9sZWRjICpwcml2LAo+ICsJCQkJCWludCBsZW5n dGgpCj4gK3sKPiArCXUzMiB2YWw7Cj4gKwo+ICsJZGV2X2RiZyhwcml2LT5kZXYsICJVcGRhdGlu ZyAlZCBMRURzXG4iLCBsZW5ndGgpOwoKSG93IHVzZWZ1bCBpcyB0aGlzLCByZWFsbHk/CgpDb3Vs ZCB5b3UgY29uc2lkZXIgcmVtb3ZpbmcgaXQ/Cgo+ICsJdmFsID0gcmVhZGwocHJpdi0+YmFzZSAr IExFRENfQ1RSTF9SRUcpOwo+ICsJdmFsICY9IH5MRURDX0NUUkxfUkVHX0RBVEFfTEVOR1RIOwo+ ICsJdmFsIHw9IGxlbmd0aCA8PCAxNiB8IExFRENfQ1RSTF9SRUdfTEVEQ19FTjsKCldoeSAxNj8g IFBsZWFzZSBjb25zaWRlciBkZWZpbmluZyBhbGwgbWFnaWMgbnVtYmVycy4KCiAgQkxBSF9CTEFI X1NISUZUID8KCj4gKwl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19DVFJMX1JFRyk7Cj4g Kwo+ICsJaWYgKGxlbmd0aCA+IExFRENfRklGT19ERVBUSCkgewo+ICsJCWludCByZXQgPSBzdW41 MGlfYTEwMF9sZWRjX2RtYV94ZmVyKHByaXYsIGxlbmd0aCk7CgpMb29rcyBvZGQuICBJdCdzIHdh eSBtb3JlIGNvbW1vbiB0byBzZXBhcmF0ZSB0aGUgY2FsbCBmcm9tIHRoZSBkZWNsYXJhdGlvbi4K Cj4gKwkJaWYgKCFyZXQpCj4gKwkJCXJldHVybjsKPiArCj4gKwkJZGV2X3dhcm4ocHJpdi0+ZGV2 LCAiRmFpbGVkIHRvIHNldCB1cCBETUE6ICVkXG4iLCByZXQpOwoKVGhpcyBsb29rcyBsaWtlIGFu IGVycm9yLgoKUGxlYXNlIHRlbGwgdGhlIHVzZXIgd2UncmUgZmFsbGluZyBiYWNrIHRvIFBJTy4K Cj4gKwl9Cj4gKwo+ICsJc3VuNTBpX2ExMDBfbGVkY19waW9feGZlcihwcml2LCBsZW5ndGgpOwo+ ICt9Cj4gKwo+ICtzdGF0aWMgaXJxcmV0dXJuX3Qgc3VuNTBpX2ExMDBfbGVkY19pcnEoaW50IGly cSwgdm9pZCAqZGV2X2lkKQo+ICt7Cj4gKwlzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkYyAqcHJpdiA9 IGRldl9pZDsKClRoaXMgaXMgY2xlYXJseSBub3QgYSBkZWZfaWQuICAnZGF0YScgbG9va3MgbGlr ZSBhIGNvbW1vbiBhbHRlcm5hdGl2ZS4KCj4gKwl1MzIgdmFsOwo+ICsKPiArCXZhbCA9IHJlYWRs KHByaXYtPmJhc2UgKyBMRURDX0lOVF9TVFNfUkVHKTsKCid2YWwnIGlzIGEgdGVycmlibGUgdmFy aWFibGUgbmFtZS4gICdzdGF0dXMnPwoKPiArCWlmICh2YWwgJiBMRURDX0lOVF9TVFNfUkVHX1RS QU5TX0ZJTklTSF9JTlQpIHsKPiArCQlpbnQgbmV4dF9sZW5ndGg7Cj4gKwo+ICsJCS8qIFN0YXJ0 IHRoZSBuZXh0IHRyYW5zZmVyIGlmIG5lZWRlZC4gKi8KPiArCQlzcGluX2xvY2soJnByaXYtPmxv Y2spOwo+ICsJCW5leHRfbGVuZ3RoID0gcHJpdi0+bmV4dF9sZW5ndGg7Cj4gKwkJaWYgKG5leHRf bGVuZ3RoKQo+ICsJCQlwcml2LT5uZXh0X2xlbmd0aCA9IDA7Cj4gKwkJZWxzZQo+ICsJCQlwcml2 LT54ZmVyX2FjdGl2ZSA9IGZhbHNlOwo+ICsJCXNwaW5fdW5sb2NrKCZwcml2LT5sb2NrKTsKPiAr Cj4gKwkJaWYgKG5leHRfbGVuZ3RoKQo+ICsJCQlzdW41MGlfYTEwMF9sZWRjX3N0YXJ0X3hmZXIo cHJpdiwgbmV4dF9sZW5ndGgpOwo+ICsJfSBlbHNlIGlmICh2YWwgJiBMRURDX0lOVF9TVFNfUkVH X0ZJRk9fQ1BVUkVRX0lOVCkgewo+ICsJCS8qIENvbnRpbnVlIHRoZSBjdXJyZW50IHRyYW5zZmVy LiAqLwo+ICsJCXN1bjUwaV9hMTAwX2xlZGNfcGlvX3hmZXIocHJpdiwgMCk7Cj4gKwl9Cj4gKwo+ ICsJd3JpdGVsKHZhbCwgcHJpdi0+YmFzZSArIExFRENfSU5UX1NUU19SRUcpOwoKRGlkICd2YWwn IGNoYW5nZT8gIElmIHRoaXMgaXMgaW50ZW50aW9uYWwsIHBlcmhhcHMgYSBjb21tZW50IHRvIGNs YXJpZnkuCgo+ICsJcmV0dXJuIElSUV9IQU5ETEVEOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBz dW41MGlfYTEwMF9sZWRjX2JyaWdodG5lc3Nfc2V0KHN0cnVjdCBsZWRfY2xhc3NkZXYgKmNkZXYs Cj4gKwkJCQkJICAgIGVudW0gbGVkX2JyaWdodG5lc3MgYnJpZ2h0bmVzcykKPiArewo+ICsJc3Ry dWN0IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYgPSBkZXZfZ2V0X2RydmRhdGEoY2Rldi0+ZGV2LT5w YXJlbnQpOwo+ICsJc3RydWN0IGxlZF9jbGFzc2Rldl9tYyAqbWNfY2RldiA9IGxjZGV2X3RvX21j Y2RldihjZGV2KTsKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRjX2xlZCAqbGVkID0gdG9fbGVk Y19sZWQobWNfY2Rldik7Cj4gKwlpbnQgYWRkciA9IGxlZCAtIHByaXYtPmxlZHM7CgpOb3QgcmVh bGx5IGFuIGFkZHJlc3MgaXMgaXQ/ICAnb2Zmc2V0JyBvciBzb21ldGhpbmcgYmV0dGVyPwoKPiAr CXVuc2lnbmVkIGxvbmcgZmxhZ3M7Cj4gKwlib29sIHhmZXJfYWN0aXZlOwo+ICsJaW50IG5leHRf bGVuZ3RoOwo+ICsKPiArCWxlZF9tY19jYWxjX2NvbG9yX2NvbXBvbmVudHMobWNfY2RldiwgYnJp Z2h0bmVzcyk7Cj4gKwo+ICsJcHJpdi0+YnVmZmVyW2FkZHJdID0gbGVkLT5zdWJsZWRfaW5mb1sw XS5icmlnaHRuZXNzIDw8IDE2IHwKPiArCQkJICAgICBsZWQtPnN1YmxlZF9pbmZvWzFdLmJyaWdo dG5lc3MgPDwgIDggfAo+ICsJCQkgICAgIGxlZC0+c3VibGVkX2luZm9bMl0uYnJpZ2h0bmVzczsK PiArCj4gKwlkZXZfZGJnKHByaXYtPmRldiwgIkxFRCAlZCAtPiAjJTA2eFxuIiwgYWRkciwgcHJp di0+YnVmZmVyW2FkZHJdKTsKCkFzIGFib3ZlLgoKPiArCXNwaW5fbG9ja19pcnFzYXZlKCZwcml2 LT5sb2NrLCBmbGFncyk7Cj4gKwluZXh0X2xlbmd0aCA9IG1heChwcml2LT5uZXh0X2xlbmd0aCwg YWRkciArIDEpOwo+ICsJeGZlcl9hY3RpdmUgPSBwcml2LT54ZmVyX2FjdGl2ZTsKPiArCWlmICh4 ZmVyX2FjdGl2ZSkKPiArCQlwcml2LT5uZXh0X2xlbmd0aCA9IG5leHRfbGVuZ3RoOwo+ICsJZWxz ZQo+ICsJCXByaXYtPnhmZXJfYWN0aXZlID0gdHJ1ZTsKPiArCXNwaW5fdW5sb2NrX2lycXJlc3Rv cmUoJnByaXYtPmxvY2ssIGZsYWdzKTsKCkNyYW1wZWQgY29kZSBpcyBub3QgZWFzeSB0byByZWFk LiAgUGxlYXNlIGNvbnNpZGVyIHNvbWUgJ1xuJ3MuCgo+ICsJaWYgKCF4ZmVyX2FjdGl2ZSkKPiAr CQlzdW41MGlfYTEwMF9sZWRjX3N0YXJ0X3hmZXIocHJpdiwgbmV4dF9sZW5ndGgpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgY29uc3QgY2hhciAqY29uc3Qgc3VuNTBpX2ExMDBfbGVkY19mb3JtYXRzW10g PSB7Cj4gKwkicmdiIiwKPiArCSJyYmciLAo+ICsJImdyYiIsCj4gKwkiZ2JyIiwKPiArCSJicmci LAo+ICsJImJnciIsCj4gK307Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAwX2xlZGNfcGFy c2VfZm9ybWF0KGNvbnN0IHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAsCj4gKwkJCQkJIHN0cnVjdCBz dW41MGlfYTEwMF9sZWRjICpwcml2KQo+ICt7Cj4gKwljb25zdCBjaGFyICpmb3JtYXQgPSAiZ3Ji IjsKPiArCXUzMiBpOwo+ICsKPiArCW9mX3Byb3BlcnR5X3JlYWRfc3RyaW5nKG5wLCAiYWxsd2lu bmVyLHBpeGVsLWZvcm1hdCIsICZmb3JtYXQpOwo+ICsKPiArCWZvciAoaSA9IDA7IGkgPCBBUlJB WV9TSVpFKHN1bjUwaV9hMTAwX2xlZGNfZm9ybWF0cyk7ICsraSkgewoKRG9lcyB0aGUgcHJlLWlu Y3JlbWVudCBob2xkIGFueSBzaWduaWZpY2FuY2U/CgpJZiBub3QsIHBsZWFzZSB1c2UgdGhlIG1v cmUgY29tbW9uIGltcGxlbWVudGF0aW9uIG9mIHBvc3QtaW5jcmVtZW50aW5nLgoKPiArCQlpZiAo IXN0cmNtcChmb3JtYXQsIHN1bjUwaV9hMTAwX2xlZGNfZm9ybWF0c1tpXSkpIHsKPiArCQkJcHJp di0+Zm9ybWF0ID0gaTsKPiArCQkJcmV0dXJuIDA7Cj4gKwkJfQo+ICsJfQo+ICsKPiArCWRldl9l cnIocHJpdi0+ZGV2LCAiQmFkIHBpeGVsIGZvcm1hdCAnJXMnXG4iLCBmb3JtYXQpOwo+ICsKPiAr CXJldHVybiAtRUlOVkFMOwo+ICt9Cj4gKwo+ICtzdGF0aWMgdm9pZCBzdW41MGlfYTEwMF9sZWRj X3NldF9mb3JtYXQoc3RydWN0IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYpCj4gK3sKPiArCXUzMiB2 YWw7Cj4gKwo+ICsJdmFsID0gcmVhZGwocHJpdi0+YmFzZSArIExFRENfQ1RSTF9SRUcpOwo+ICsJ dmFsICY9IH5MRURDX0NUUkxfUkVHX1JHQl9NT0RFOwo+ICsJdmFsIHw9IHByaXYtPmZvcm1hdCA8 PCA2Owo+ICsJd3JpdGVsKHZhbCwgcHJpdi0+YmFzZSArIExFRENfQ1RSTF9SRUcpOwo+ICt9Cj4g Kwo+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHN1bjUwaV9hMTAwX2xlZGNfdGltaW5nIHN1bjUwaV9h MTAwX2xlZGNfZGVmYXVsdF90aW1pbmcgPSB7Cj4gKwkudDBoX25zID0gMzM2LAo+ICsJLnQwbF9u cyA9IDg0MCwKPiArCS50MWhfbnMgPSA4ODIsCj4gKwkudDFsX25zID0gMjk0LAo+ICsJLnRyZXNl dF9ucyA9IDMwMDAwMCwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgc3VuNTBpX2ExMDBfbGVkY19w YXJzZV90aW1pbmcoY29uc3Qgc3RydWN0IGRldmljZV9ub2RlICpucCwKPiArCQkJCQkgc3RydWN0 IHN1bjUwaV9hMTAwX2xlZGMgKnByaXYpCj4gK3sKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRj X3RpbWluZyAqdGltaW5nID0gJnByaXYtPnRpbWluZzsKPiArCj4gKwkqdGltaW5nID0gc3VuNTBp X2ExMDBfbGVkY19kZWZhdWx0X3RpbWluZzsKPiArCj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihu cCwgImFsbHdpbm5lcix0MGgtbnMiLCAmdGltaW5nLT50MGhfbnMpOwo+ICsJb2ZfcHJvcGVydHlf cmVhZF91MzIobnAsICJhbGx3aW5uZXIsdDBsLW5zIiwgJnRpbWluZy0+dDBsX25zKTsKPiArCW9m X3Byb3BlcnR5X3JlYWRfdTMyKG5wLCAiYWxsd2lubmVyLHQxaC1ucyIsICZ0aW1pbmctPnQxaF9u cyk7Cj4gKwlvZl9wcm9wZXJ0eV9yZWFkX3UzMihucCwgImFsbHdpbm5lcix0MWwtbnMiLCAmdGlt aW5nLT50MWxfbnMpOwo+ICsJb2ZfcHJvcGVydHlfcmVhZF91MzIobnAsICJhbGx3aW5uZXIsdHJl c2V0LW5zIiwgJnRpbWluZy0+dHJlc2V0X25zKTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsK PiArc3RhdGljIHZvaWQgc3VuNTBpX2ExMDBfbGVkY19zZXRfdGltaW5nKHN0cnVjdCBzdW41MGlf YTEwMF9sZWRjICpwcml2KQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkY190 aW1pbmcgKnRpbWluZyA9ICZwcml2LT50aW1pbmc7Cj4gKwl1bnNpZ25lZCBsb25nIG1vZF9mcmVx ID0gY2xrX2dldF9yYXRlKHByaXYtPm1vZF9jbGspOwo+ICsJdTMyIGN5Y2xlX25zID0gTlNFQ19Q RVJfU0VDIC8gbW9kX2ZyZXE7Cj4gKwl1MzIgdmFsOwoKJ3RpbWluZycKCj4gKwl2YWwgPSAodGlt aW5nLT50MWhfbnMgLyBjeWNsZV9ucykgPDwgMjEgfAo+ICsJICAgICAgKHRpbWluZy0+dDFsX25z IC8gY3ljbGVfbnMpIDw8IDE2IHwKPiArCSAgICAgICh0aW1pbmctPnQwaF9ucyAvIGN5Y2xlX25z KSA8PCAgNiB8Cj4gKwkgICAgICAodGltaW5nLT50MGxfbnMgLyBjeWNsZV9ucyk7Cj4gKwl3cml0 ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19UMDFfVElNSU5HX0NUUkxfUkVHKTsKPiArCj4gKwl2 YWwgPSAodGltaW5nLT50cmVzZXRfbnMgLyBjeWNsZV9ucykgPDwgMTYgfAo+ICsJICAgICAgKHBy aXYtPm51bV9sZWRzIC0gMSk7Cj4gKwl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19SRVNF VF9USU1JTkdfQ1RSTF9SRUcpOwo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAwX2xl ZGNfcmVzdW1lKHN0cnVjdCBkZXZpY2UgKmRldikKPiArewo+ICsJc3RydWN0IHN1bjUwaV9hMTAw X2xlZGMgKnByaXYgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiArCXUzMiB2YWw7Cj4gKwlpbnQg cmV0OwoKJ2NvbnRyb2wnCgo+ICsJcmV0ID0gcmVzZXRfY29udHJvbF9kZWFzc2VydChwcml2LT5y ZXNldCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX3By ZXBhcmVfZW5hYmxlKHByaXYtPmJ1c19jbGspOwo+ICsJaWYgKHJldCkKPiArCQlnb3RvIGVycl9h c3NlcnRfcmVzZXQ7Cj4gKwo+ICsJcmV0ID0gY2xrX3ByZXBhcmVfZW5hYmxlKHByaXYtPm1vZF9j bGspOwo+ICsJaWYgKHJldCkKPiArCQlnb3RvIGVycl9kaXNhYmxlX2J1c19jbGs7Cj4gKwo+ICsJ c3VuNTBpX2ExMDBfbGVkY19zZXRfZm9ybWF0KHByaXYpOwo+ICsJc3VuNTBpX2ExMDBfbGVkY19z ZXRfdGltaW5nKHByaXYpOwo+ICsKPiArCS8qIFRoZSB0cmlnZ2VyIGxldmVsIG11c3QgYmUgYXQg bGVhc3QgdGhlIGJ1cnN0IGxlbmd0aC4gKi8KPiArCXZhbCA9IHJlYWRsKHByaXYtPmJhc2UgKyBM RURDX0RNQV9DVFJMX1JFRyk7Cj4gKwl2YWwgJj0gfkxFRENfRE1BX0NUUkxfUkVHX0ZJRk9fVFJJ R19MRVZFTDsKPiArCXZhbCB8PSBMRURDX0ZJRk9fREVQVEggLyAyOwo+ICsJd3JpdGVsKHZhbCwg cHJpdi0+YmFzZSArIExFRENfRE1BX0NUUkxfUkVHKTsKPiArCj4gKwl2YWwgPSBMRURDX0lOVF9D VFJMX1JFR19HTE9CQUxfSU5UX0VOIHwKPiArCSAgICAgIExFRENfSU5UX0NUUkxfUkVHX1RSQU5T X0ZJTklTSF9JTlRfRU47Cj4gKwl3cml0ZWwodmFsLCBwcml2LT5iYXNlICsgTEVEQ19JTlRfQ1RS TF9SRUcpOwo+ICsKPiArCXJldHVybiAwOwo+ICsKPiArZXJyX2Rpc2FibGVfYnVzX2NsazoKPiAr CWNsa19kaXNhYmxlX3VucHJlcGFyZShwcml2LT5idXNfY2xrKTsKPiArZXJyX2Fzc2VydF9yZXNl dDoKPiArCXJlc2V0X2NvbnRyb2xfYXNzZXJ0KHByaXYtPnJlc2V0KTsKPiArCj4gKwlyZXR1cm4g cmV0Owo+ICt9Cj4gKwo+ICtzdGF0aWMgaW50IHN1bjUwaV9hMTAwX2xlZGNfc3VzcGVuZChzdHJ1 Y3QgZGV2aWNlICpkZXYpCj4gK3sKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRjICpwcml2ID0g ZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHByaXYt Pm1vZF9jbGspOwo+ICsJY2xrX2Rpc2FibGVfdW5wcmVwYXJlKHByaXYtPmJ1c19jbGspOwo+ICsJ cmVzZXRfY29udHJvbF9hc3NlcnQocHJpdi0+cmVzZXQpOwo+ICsKPiArCXJldHVybiAwOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgdm9pZCBzdW41MGlfYTEwMF9sZWRjX2RtYV9jbGVhbnVwKHZvaWQgKmRh dGEpCj4gK3sKPiArCXN0cnVjdCBzdW41MGlfYTEwMF9sZWRjICpwcml2ID0gZGF0YTsKPiArCXN0 cnVjdCBkZXZpY2UgKmRtYV9kZXYgPSBkbWFlbmdpbmVfZ2V0X2RtYV9kZXZpY2UocHJpdi0+ZG1h X2NoYW4pOwoKV2hhdCBoYXBwZW5zIGlmIHRoaXMgaXMgTlVMTCBvciBhbiBlcnJvcj8KCj4gKwlp ZiAocHJpdi0+YnVmZmVyKQo+ICsJCWRtYV9mcmVlX3djKGRtYV9kZXYsIExFRFNfVE9fQllURVMo cHJpdi0+bnVtX2xlZHMpLAo+ICsJCQkgICAgcHJpdi0+YnVmZmVyLCBwcml2LT5kbWFfaGFuZGxl KTsKCidcbicKCj4gKwlkbWFfcmVsZWFzZV9jaGFubmVsKHByaXYtPmRtYV9jaGFuKTsKPiArfQo+ ICsKPiArc3RhdGljIGludCBzdW41MGlfYTEwMF9sZWRjX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpCj4gK3sKPiArCWNvbnN0IHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBwZGV2 LT5kZXYub2Zfbm9kZTsKPiArCXN0cnVjdCBkbWFfc2xhdmVfY29uZmlnIGRtYV9jZmcgPSB7fTsK PiArCXN0cnVjdCBsZWRfaW5pdF9kYXRhIGluaXRfZGF0YSA9IHt9Owo+ICsJc3RydWN0IGRldmlj ZSAqZGV2ID0gJnBkZXYtPmRldjsKPiArCXN0cnVjdCBkZXZpY2Vfbm9kZSAqY2hpbGQ7Cj4gKwlz dHJ1Y3Qgc3VuNTBpX2ExMDBfbGVkYyAqcHJpdjsKPiArCXN0cnVjdCByZXNvdXJjZSAqbWVtOwo+ ICsJaW50IGNvdW50LCBpcnEsIHJldDsKPiArCj4gKwljb3VudCA9IG9mX2dldF9hdmFpbGFibGVf Y2hpbGRfY291bnQobnApOwo+ICsJaWYgKCFjb3VudCkKPiArCQlyZXR1cm4gLUVOT0RFVjsKCidc bicKCj4gKwlpZiAoY291bnQgPiBMRURDX01BWF9MRURTKSB7Cj4gKwkJZGV2X2VycihkZXYsICJU b28gbWFueSBMRURzISAobWF4IGlzICVkKVxuIiwgTEVEQ19NQVhfTEVEUyk7Cj4gKwkJcmV0dXJu IC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJcHJpdiA9IGRldm1fa3phbGxvYyhkZXYsIHN0cnVjdF9z aXplKHByaXYsIGxlZHMsIGNvdW50KSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXByaXYpCj4gKwkJ cmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJcHJpdi0+ZGV2ID0gZGV2Owo+ICsJcHJpdi0+bnVtX2xl ZHMgPSBjb3VudDsKPiArCXNwaW5fbG9ja19pbml0KCZwcml2LT5sb2NrKTsKPiArCWRldl9zZXRf ZHJ2ZGF0YShkZXYsIHByaXYpOwo+ICsKPiArCXJldCA9IHN1bjUwaV9hMTAwX2xlZGNfcGFyc2Vf Zm9ybWF0KG5wLCBwcml2KTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwly ZXQgPSBzdW41MGlfYTEwMF9sZWRjX3BhcnNlX3RpbWluZyhucCwgcHJpdik7Cj4gKwlpZiAocmV0 KQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJcHJpdi0+YmFzZSA9IGRldm1fcGxhdGZvcm1fZ2V0 X2FuZF9pb3JlbWFwX3Jlc291cmNlKHBkZXYsIDAsICZtZW0pOwo+ICsJaWYgKElTX0VSUihwcml2 LT5iYXNlKSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5iYXNlKTsKPiArCj4gKwlwcml2LT5i dXNfY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgImJ1cyIpOwo+ICsJaWYgKElTX0VSUihwcml2LT5i dXNfY2xrKSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5idXNfY2xrKTsKPiArCj4gKwlwcml2 LT5tb2RfY2xrID0gZGV2bV9jbGtfZ2V0KGRldiwgIm1vZCIpOwo+ICsJaWYgKElTX0VSUihwcml2 LT5tb2RfY2xrKSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5tb2RfY2xrKTsKPiArCj4gKwlw cml2LT5yZXNldCA9IGRldm1fcmVzZXRfY29udHJvbF9nZXRfZXhjbHVzaXZlKGRldiwgTlVMTCk7 Cj4gKwlpZiAoSVNfRVJSKHByaXYtPnJlc2V0KSkKPiArCQlyZXR1cm4gUFRSX0VSUihwcml2LT5y ZXNldCk7Cj4gKwo+ICsJcHJpdi0+ZG1hX2NoYW4gPSBkbWFfcmVxdWVzdF9jaGFuKGRldiwgInR4 Iik7Cj4gKwlpZiAoSVNfRVJSKHByaXYtPmRtYV9jaGFuKSkKPiArCQlyZXR1cm4gUFRSX0VSUihw cml2LT5kbWFfY2hhbik7Cj4gKwo+ICsJcmV0ID0gZGV2bV9hZGRfYWN0aW9uX29yX3Jlc2V0KGRl diwgc3VuNTBpX2ExMDBfbGVkY19kbWFfY2xlYW51cCwgcHJpdik7Cj4gKwlpZiAocmV0KQo+ICsJ CXJldHVybiByZXQ7Cj4gKwo+ICsJZG1hX2NmZy5kc3RfYWRkcgk9IG1lbS0+c3RhcnQgKyBMRURD X0RBVEFfUkVHOwo+ICsJZG1hX2NmZy5kc3RfYWRkcl93aWR0aAk9IERNQV9TTEFWRV9CVVNXSURU SF80X0JZVEVTOwo+ICsJZG1hX2NmZy5kc3RfbWF4YnVyc3QJPSBMRURDX0ZJRk9fREVQVEggLyAy OwoKJ1xuJwoKPiArCXJldCA9IGRtYWVuZ2luZV9zbGF2ZV9jb25maWcocHJpdi0+ZG1hX2NoYW4s ICZkbWFfY2ZnKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4gKwlwcml2LT5i dWZmZXIgPSBkbWFfYWxsb2Nfd2MoZG1hZW5naW5lX2dldF9kbWFfZGV2aWNlKHByaXYtPmRtYV9j aGFuKSwKPiArCQkJCSAgICBMRURTX1RPX0JZVEVTKHByaXYtPm51bV9sZWRzKSwKPiArCQkJCSAg ICAmcHJpdi0+ZG1hX2hhbmRsZSwgR0ZQX0tFUk5FTCk7Cj4gKwlpZiAoIXByaXYtPmJ1ZmZlcikK PiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlpcnEgPSBwbGF0Zm9ybV9nZXRfaXJxKHBkZXYs IDApOwo+ICsJaWYgKGlycSA8IDApCj4gKwkJcmV0dXJuIGlycTsKPiArCj4gKwlyZXQgPSBkZXZt X3JlcXVlc3RfaXJxKGRldiwgaXJxLCBzdW41MGlfYTEwMF9sZWRjX2lycSwKPiArCQkJICAgICAg IDAsIGRldl9uYW1lKGRldiksIHByaXYpOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ ICsKPiArCXJldCA9IHN1bjUwaV9hMTAwX2xlZGNfcmVzdW1lKGRldik7Cj4gKwlpZiAocmV0KQo+ ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJZm9yX2VhY2hfYXZhaWxhYmxlX2NoaWxkX29mX25vZGUo bnAsIGNoaWxkKSB7Cj4gKwkJc3RydWN0IHN1bjUwaV9hMTAwX2xlZGNfbGVkICpsZWQ7Cj4gKwkJ c3RydWN0IGxlZF9jbGFzc2RldiAqY2RldjsKPiArCQl1MzIgYWRkciwgY29sb3I7Cj4gKwo+ICsJ CXJldCA9IG9mX3Byb3BlcnR5X3JlYWRfdTMyKGNoaWxkLCAicmVnIiwgJmFkZHIpOwo+ICsJCWlm IChyZXQgfHwgYWRkciA+PSBjb3VudCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkxFRCAncmVnJyB2 YWx1ZXMgbXVzdCBiZSBmcm9tIDAgdG8gJWRcbiIsCgpEb2Vzbid0IHNvdW5kcyBsaWtlIGFuIGFk ZHJlc3MuCgo+ICsJCQkJcHJpdi0+bnVtX2xlZHMgLSAxKTsKCjEwMC1jaGFycyAtIG5vIG5lZWQg dG8gd3JhcC4KClBsZWFzZSBhcHBseSB0aGlzIGV2ZXJ5d2hlcmUuCgo+ICsJCQlyZXQgPSAtRUlO VkFMOwo+ICsJCQlnb3RvIGVycl9wdXRfY2hpbGQ7Cj4gKwkJfQo+ICsKPiArCQlyZXQgPSBvZl9w cm9wZXJ0eV9yZWFkX3UzMihjaGlsZCwgImNvbG9yIiwgJmNvbG9yKTsKPiArCQlpZiAocmV0IHx8 IGNvbG9yICE9IExFRF9DT0xPUl9JRF9SR0IpIHsKPiArCQkJZGV2X2VycihkZXYsICJMRUQgJ2Nv bG9yJyBtdXN0IGJlIExFRF9DT0xPUl9JRF9SR0JcbiIpOwoKVGhlbiB3aHkgZXZlbiBwcm92aWRl IHRoZSBvcHRpb24/Cgo+ICsJCQlyZXQgPSAtRUlOVkFMOwo+ICsJCQlnb3RvIGVycl9wdXRfY2hp bGQ7Cj4gKwkJfQo+ICsKPiArCQlsZWQgPSAmcHJpdi0+bGVkc1thZGRyXTsKPiArCj4gKwkJbGVk LT5zdWJsZWRfaW5mb1swXS5jb2xvcl9pbmRleCA9IExFRF9DT0xPUl9JRF9SRUQ7Cj4gKwkJbGVk LT5zdWJsZWRfaW5mb1swXS5jaGFubmVsID0gMDsKPiArCQlsZWQtPnN1YmxlZF9pbmZvWzFdLmNv bG9yX2luZGV4ID0gTEVEX0NPTE9SX0lEX0dSRUVOOwo+ICsJCWxlZC0+c3VibGVkX2luZm9bMV0u Y2hhbm5lbCA9IDE7Cj4gKwkJbGVkLT5zdWJsZWRfaW5mb1syXS5jb2xvcl9pbmRleCA9IExFRF9D T0xPUl9JRF9CTFVFOwo+ICsJCWxlZC0+c3VibGVkX2luZm9bMl0uY2hhbm5lbCA9IDI7Cj4gKwo+ ICsJCWxlZC0+bWNfY2Rldi5udW1fY29sb3JzID0gQVJSQVlfU0laRShsZWQtPnN1YmxlZF9pbmZv KTsKPiArCQlsZWQtPm1jX2NkZXYuc3VibGVkX2luZm8gPSBsZWQtPnN1YmxlZF9pbmZvOwo+ICsK PiArCQljZGV2ID0gJmxlZC0+bWNfY2Rldi5sZWRfY2RldjsKPiArCQljZGV2LT5tYXhfYnJpZ2h0 bmVzcyA9IFU4X01BWDsKPiArCQljZGV2LT5icmlnaHRuZXNzX3NldCA9IHN1bjUwaV9hMTAwX2xl ZGNfYnJpZ2h0bmVzc19zZXQ7Cj4gKwo+ICsJCWluaXRfZGF0YS5md25vZGUgPSBvZl9md25vZGVf aGFuZGxlKGNoaWxkKTsKPiArCj4gKwkJcmV0ID0gZGV2bV9sZWRfY2xhc3NkZXZfbXVsdGljb2xv cl9yZWdpc3Rlcl9leHQoZGV2LAo+ICsJCQkJCQkJCSZsZWQtPm1jX2NkZXYsCj4gKwkJCQkJCQkJ JmluaXRfZGF0YSk7Cj4gKwkJaWYgKHJldCkgewo+ICsJCQlkZXZfZXJyKGRldiwgIkZhaWxlZCB0 byByZWdpc3RlciBMRUQgJXU6ICVkXG4iLAoKIm11bHRpY29sb3IgTEVEIgoKPiArCQkJCWFkZHIs IHJldCk7Cj4gKwkJCWdvdG8gZXJyX3B1dF9jaGlsZDsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJZGV2 X2luZm8oZGV2LCAiUmVnaXN0ZXJlZCAlZCBMRURzXG4iLCBwcml2LT5udW1fbGVkcyk7Cj4gKwo+ ICsJcmV0dXJuIDA7Cj4gKwo+ICtlcnJfcHV0X2NoaWxkOgo+ICsJb2Zfbm9kZV9wdXQoY2hpbGQp Owo+ICsJc3VuNTBpX2ExMDBfbGVkY19zdXNwZW5kKCZwZGV2LT5kZXYpOwo+ICsKPiArCXJldHVy biByZXQ7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgc3VuNTBpX2ExMDBfbGVkY19yZW1vdmUoc3Ry dWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJc3VuNTBpX2ExMDBfbGVkY19zdXNw ZW5kKCZwZGV2LT5kZXYpOwo+ICsKPiArCXJldHVybiAwOwoKcmV0dXJuIHN1bjUwaV9hMTAwX2xl ZGNfc3VzcGVuZCgmcGRldi0+ZGV2KTsKCj4gK30KPiArCj4gK3N0YXRpYyB2b2lkIHN1bjUwaV9h MTAwX2xlZGNfc2h1dGRvd24oc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKPiArewo+ICsJ c3VuNTBpX2ExMDBfbGVkY19zdXNwZW5kKCZwZGV2LT5kZXYpOwo+ICt9Cj4gKwo+ICtzdGF0aWMg Y29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBzdW41MGlfYTEwMF9sZWRjX29mX21hdGNoW10gPSB7 Cj4gKwl7IC5jb21wYXRpYmxlID0gImFsbHdpbm5lcixzdW41MGktYTEwMC1sZWRjIiB9LAo+ICsJ e30KPiArfTsKPiArTU9EVUxFX0RFVklDRV9UQUJMRShvZiwgc3VuNTBpX2ExMDBfbGVkY19vZl9t YXRjaCk7Cj4gKwo+ICtzdGF0aWMgREVGSU5FX1NJTVBMRV9ERVZfUE1fT1BTKHN1bjUwaV9hMTAw X2xlZGNfcG0sCj4gKwkJCQlzdW41MGlfYTEwMF9sZWRjX3N1c3BlbmQsCj4gKwkJCQlzdW41MGlf YTEwMF9sZWRjX3Jlc3VtZSk7Cj4gKwo+ICtzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBz dW41MGlfYTEwMF9sZWRjX2RyaXZlciA9IHsKPiArCS5wcm9iZQkJPSBzdW41MGlfYTEwMF9sZWRj X3Byb2JlLAo+ICsJLnJlbW92ZQkJPSBzdW41MGlfYTEwMF9sZWRjX3JlbW92ZSwKPiArCS5zaHV0 ZG93bgk9IHN1bjUwaV9hMTAwX2xlZGNfc2h1dGRvd24sCj4gKwkuZHJpdmVyCQk9IHsKPiArCQku bmFtZQkJPSAic3VuNTBpLWExMDAtbGVkYyIsCj4gKwkJLm9mX21hdGNoX3RhYmxlCT0gc3VuNTBp X2ExMDBfbGVkY19vZl9tYXRjaCwKPiArCQkucG0JCT0gcG1fcHRyKCZzdW41MGlfYTEwMF9sZWRj X3BtKSwKPiArCX0sCj4gK307Cj4gK21vZHVsZV9wbGF0Zm9ybV9kcml2ZXIoc3VuNTBpX2ExMDBf bGVkY19kcml2ZXIpOwo+ICsKPiArTU9EVUxFX0FVVEhPUigiU2FtdWVsIEhvbGxhbmQgPHNhbXVl bEBzaG9sbGFuZC5vcmc+Iik7Cj4gK01PRFVMRV9ERVNDUklQVElPTigiQWxsd2lubmVyIEExMDAg TEVEIGNvbnRyb2xsZXIgZHJpdmVyIik7Cj4gK01PRFVMRV9MSUNFTlNFKCJHUEwiKTsKPiAtLQo+ IDIuMzcuNAo+CgotLQpMZWUgSm9uZXMgW+adjueQvOaWr10KCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0 CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFk ZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK