From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DD44C433DF for ; Mon, 3 Aug 2020 08:04:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 67CBD2072A for ; Mon, 3 Aug 2020 08:04:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596441884; bh=86jByJPP79HZFb7NJt9RymPkDBrD8xB0L58L0m5gXMo=; h=Date:From:To:Cc:Subject:In-Reply-To:References:List-ID:From; b=WWquF50Naphls6MG0SMyOpx1QcUBLzkEtKUm52DQYmzQR75ZyTPiES4euJybeiykJ i9H9tfHMOwhLMZAAP3KJIrxyuPG44jMNBjkE4PFbyzVh0xYQOiSPQcBeTxumSlBqjY MoXqNAJ0WdeW2CXtiQF3ocnGf/8E7mbrC9yshAQs= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726202AbgHCIEo (ORCPT ); Mon, 3 Aug 2020 04:04:44 -0400 Received: from mail.kernel.org ([198.145.29.99]:56758 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725806AbgHCIEo (ORCPT ); Mon, 3 Aug 2020 04:04:44 -0400 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E30F22177B; Mon, 3 Aug 2020 08:04:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1596441881; bh=86jByJPP79HZFb7NJt9RymPkDBrD8xB0L58L0m5gXMo=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=0TPAb+4m1u6BTKJKJTZkSF57dcsZYmS5f9UJn/olzqz4DSfA0wQ9v4S32SKSTf5OK iobLmB3a4vU9pS66FU3Z5aMln2Z6Rh4CYPTtyBgIm1yjWhgiOzc+rpI7CDxrDepn2K bZt+U9LelufiWlbNJJg+kLveIB1Nr2T4oJ7amJRA= Received: from disco-boy.misterjones.org ([51.254.78.96] helo=www.loen.fr) by disco-boy.misterjones.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1k2VSZ-00H2M2-Ph; Mon, 03 Aug 2020 09:04:39 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Date: Mon, 03 Aug 2020 09:04:39 +0100 From: Marc Zyngier To: Mark-PK Tsai Cc: yj.chiang@mediatek.com, alix.wu@mediatek.com, tglx@linutronix.de, jason@lakedaemon.net, robh+dt@kernel.org, matthias.bgg@gmail.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: Re: [PATCH 1/2] irqchip: irq-mt58xx: Add mt58xx interrupt controller support In-Reply-To: <20200803062214.24076-2-mark-pk.tsai@mediatek.com> References: <20200803062214.24076-1-mark-pk.tsai@mediatek.com> <20200803062214.24076-2-mark-pk.tsai@mediatek.com> User-Agent: Roundcube Webmail/1.4.5 Message-ID: <43f5cba1199f89cde68c8a577103f28b@kernel.org> X-Sender: maz@kernel.org X-SA-Exim-Connect-IP: 51.254.78.96 X-SA-Exim-Rcpt-To: mark-pk.tsai@mediatek.com, yj.chiang@mediatek.com, alix.wu@mediatek.com, tglx@linutronix.de, jason@lakedaemon.net, robh+dt@kernel.org, matthias.bgg@gmail.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org On 2020-08-03 07:22, Mark-PK Tsai wrote: > Add mt58xx interrupt controller support using hierarchy irq > domain. > > Signed-off-by: Mark-PK Tsai > --- > drivers/irqchip/Kconfig | 7 ++ > drivers/irqchip/Makefile | 1 + > drivers/irqchip/irq-mt58xx.c | 196 +++++++++++++++++++++++++++++++++++ > 3 files changed, 204 insertions(+) > create mode 100644 drivers/irqchip/irq-mt58xx.c > > diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig > index 216b3b8392b5..00453af78be0 100644 > --- a/drivers/irqchip/Kconfig > +++ b/drivers/irqchip/Kconfig > @@ -572,4 +572,11 @@ config LOONGSON_PCH_MSI > help > Support for the Loongson PCH MSI Controller. > > +config MT58XX_IRQ > + bool "MT58XX IRQ" > + select IRQ_DOMAIN > + select IRQ_DOMAIN_HIERARCHY > + help > + Support Mediatek MT58XX Interrupt Controller. > + > endmenu > diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile > index 133f9c45744a..5062e9bfa92d 100644 > --- a/drivers/irqchip/Makefile > +++ b/drivers/irqchip/Makefile > @@ -111,3 +111,4 @@ obj-$(CONFIG_LOONGSON_HTPIC) += > irq-loongson-htpic.o > obj-$(CONFIG_LOONGSON_HTVEC) += irq-loongson-htvec.o > obj-$(CONFIG_LOONGSON_PCH_PIC) += irq-loongson-pch-pic.o > obj-$(CONFIG_LOONGSON_PCH_MSI) += irq-loongson-pch-msi.o > +obj-$(CONFIG_MT58XX_IRQ) += irq-mt58xx.o > diff --git a/drivers/irqchip/irq-mt58xx.c > b/drivers/irqchip/irq-mt58xx.c > new file mode 100644 > index 000000000000..e45ad023afa6 > --- /dev/null > +++ b/drivers/irqchip/irq-mt58xx.c > @@ -0,0 +1,196 @@ > +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) > +/* > + * Copyright (c) 2020 MediaTek Inc. > + * Author Mark-PK Tsai > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define INTC_MASK 0x0 > +#define INTC_EOI 0x20 > + > +struct mtk_intc_chip_data { > + char *name; > + struct irq_chip chip; There is no need to embed a full struct irqchip per controller, see below. > + unsigned int irq_start, nr_irqs; > + void __iomem *base; > +}; > + > +static void mtk_poke_irq(struct irq_data *d, u32 offset) > +{ > + struct mtk_intc_chip_data *cd = irq_data_get_irq_chip_data(d); > + void __iomem *base = cd->base; > + u8 index = (u8)irqd_to_hwirq(d); Why the restrictive type? Why isn't unsigned int good enough? > + u16 val, mask; > + > + mask = 1 << (index % 16); > + val = readw_relaxed(base + offset + (index / 16) * 4) | mask; > + writew_relaxed(val, base + offset + (index / 16) * 4); RMW without locking, you will end-up with corruption. Please store the address calculation in a temporaty variable to make it more readable > +} > + > +static void mtk_clear_irq(struct irq_data *d, u32 offset) > +{ > + struct mtk_intc_chip_data *cd = irq_data_get_irq_chip_data(d); > + void __iomem *base = cd->base; > + u8 index = (u8)irqd_to_hwirq(d); > + u16 val, mask; > + > + mask = 1 << (index % 16); > + val = readw_relaxed(base + offset + (index / 16) * 4) & ~mask; > + writew_relaxed(val, base + offset + (index / 16) * 4); Same comments. > +} > + > +static void mtk_intc_mask_irq(struct irq_data *d) > +{ > + mtk_poke_irq(d, INTC_MASK); > + irq_chip_mask_parent(d); > +} > + > +static void mtk_intc_unmask_irq(struct irq_data *d) > +{ > + mtk_clear_irq(d, INTC_MASK); > + irq_chip_unmask_parent(d); > +} > + > +static void mtk_intc_eoi_irq(struct irq_data *d) > +{ > + mtk_poke_irq(d, INTC_EOI); > + irq_chip_eoi_parent(d); > +} > + > +static struct irq_chip mtk_intc_chip = { > + .irq_mask = mtk_intc_mask_irq, > + .irq_unmask = mtk_intc_unmask_irq, > + .irq_eoi = mtk_intc_eoi_irq, > + .irq_get_irqchip_state = irq_chip_get_parent_state, > + .irq_set_irqchip_state = irq_chip_set_parent_state, > + .irq_set_affinity = irq_chip_set_affinity_parent, > + .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent, How about retrigger? > + .irq_set_type = irq_chip_set_type_parent, > + .flags = IRQCHIP_SET_TYPE_MASKED | > + IRQCHIP_SKIP_SET_WAKE | > + IRQCHIP_MASK_ON_SUSPEND, > +}; > + > +static int mt58xx_intc_domain_translate(struct irq_domain *d, > + struct irq_fwspec *fwspec, > + unsigned long *hwirq, > + unsigned int *type) > +{ > + if (is_of_node(fwspec->fwnode)) { > + if (fwspec->param_count != 3) > + return -EINVAL; > + > + /* No PPI should point to this domain */ > + if (fwspec->param[0] != 0) > + return -EINVAL; > + > + *hwirq = fwspec->param[1]; > + *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; > + return 0; > + } > + > + return -EINVAL; > +} > + > +static int mt58xx_intc_domain_alloc(struct irq_domain *domain, > unsigned int virq, > + unsigned int nr_irqs, void *data) > +{ > + int i; > + irq_hw_number_t hwirq; > + struct irq_fwspec parent_fwspec, *fwspec = data; > + struct mtk_intc_chip_data *cd = (struct mtk_intc_chip_data > *)domain->host_data; > + > + /* Not GIC compliant */ > + if (fwspec->param_count != 3) > + return -EINVAL; > + > + /* No PPI should point to this domain */ > + if (fwspec->param[0]) > + return -EINVAL; > + > + if (fwspec->param[1] >= cd->nr_irqs) > + return -EINVAL; > + > + hwirq = fwspec->param[1]; > + for (i = 0; i < nr_irqs; i++) > + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, > + &cd->chip, > + domain->host_data); > + > + parent_fwspec = *fwspec; > + parent_fwspec.fwnode = domain->parent->fwnode; > + parent_fwspec.param[1] = cd->irq_start + hwirq; > + return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, > &parent_fwspec); > +} > + > +static const struct irq_domain_ops mt58xx_intc_domain_ops = { > + .translate = mt58xx_intc_domain_translate, > + .alloc = mt58xx_intc_domain_alloc, > + .free = irq_domain_free_irqs_common, > +}; > + > +int __init > +mt58xx_intc_of_init(struct device_node *dn, struct device_node > *parent) > +{ > + static int nr_intc; > + struct irq_domain *domain, *domain_parent; > + struct mtk_intc_chip_data *cd; > + unsigned int irq_start, irq_end; > + > + domain_parent = irq_find_host(parent); > + if (!domain_parent) { > + pr_err("mt58xx-intc: interrupt-parent not found\n"); > + return -EINVAL; > + } > + > + cd = kzalloc(sizeof(*cd), GFP_KERNEL); > + if (!cd) > + return -ENOMEM; > + > + cd->chip = mtk_intc_chip; > + if (of_property_read_u32_index(dn, "mediatek,irqs-map-range", 0, > &irq_start) || > + of_property_read_u32_index(dn, "mediatek,irqs-map-range", 1, > &irq_end)) { > + kfree(cd); > + return -EINVAL; > + } > + > + if (of_property_read_bool(dn, "mediatek,intc-no-eoi")) > + cd->chip.irq_eoi = irq_chip_eoi_parent; No. Just add a flag to your chip data structure, and check for this flag in your irq_eoi callback. Or provide two distinct irq_chip structures that will only differ by the irq_eoi method. > + > + cd->irq_start = irq_start; > + cd->nr_irqs = irq_end - irq_start + 1; > + cd->chip.name = kasprintf(GFP_KERNEL, "mt58xx-intc-%d", nr_intc++); Neither. That's not useful, and is a waste of memory. Stick to constant names in the irq_chip structure. > + if (!cd->chip.name) { > + kfree(cd); > + return -ENOMEM; > + } > + > + cd->base = of_iomap(dn, 0); > + if (!cd->base) { > + kfree(cd->chip.name); > + kfree(cd); > + return -ENOMEM; > + } > + > + domain = irq_domain_add_hierarchy(domain_parent, 0, cd->nr_irqs, > + dn, &mt58xx_intc_domain_ops, cd); > + if (!domain) { > + kfree(cd->chip.name); > + iounmap(cd->base); > + kfree(cd); > + return -ENOMEM; > + } > + > + return 0; > +} > + > +IRQCHIP_DECLARE(mt58xx_intc, "mediatek,mt58xx-intc", > mt58xx_intc_of_init); On a side note, the merge window has just opened. Please refrain from reposting this until -rc1. Thanks, M. -- Jazz is not dead. It just smells funny... From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.4 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,MIME_BASE64_TEXT,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, UNPARSEABLE_RELAY,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13A79C433E0 for ; Mon, 3 Aug 2020 15:04:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D767120775 for ; Mon, 3 Aug 2020 15:04:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="EGH2t2yq" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726356AbgHCPEY (ORCPT ); Mon, 3 Aug 2020 11:04:24 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:9837 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726276AbgHCPEY (ORCPT ); Mon, 3 Aug 2020 11:04:24 -0400 X-UUID: 44fc7870d10c4dc6a677fb0714efd6d4-20200803 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=lveE/B5Sc1PNwm2il2hYBThpT4HQ6BzCOeCbte77MAM=; b=EGH2t2yqz9uyT/cYjKROtRNY+yY8pYku8M/ORjIMaMB8WQPalFxHQNx9eWCAq91zzb3mMHnjuZfP3muJt5eu3eStiykVU3i7b8aeGbE0CIoZQLkOotnZeHfxo7HXnbL7jfT9J7kW3fULseBhPnIavhyu1fIxTMhg2sL6aANAjuo=; X-UUID: 44fc7870d10c4dc6a677fb0714efd6d4-20200803 Received: from mtkcas10.mediatek.inc [(172.21.101.39)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 1024477934; Mon, 03 Aug 2020 23:04:15 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Mon, 3 Aug 2020 23:04:10 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Mon, 3 Aug 2020 23:04:11 +0800 From: Mark-PK Tsai To: , Mark-PK Tsai CC: , , , , , , , , , Subject: Re: [PATCH 1/2] irqchip: irq-mt58xx: Add mt58xx interrupt controller support Date: Mon, 3 Aug 2020 23:03:37 +0800 Message-ID: <43f5cba1199f89cde68c8a577103f28b@kernel.org> (raw) X-Mailer: git-send-email 2.18.0 In-Reply-To: <20200803062214.24076-2-mark-pk.tsai@mediatek.com> References: <43f5cba1199f89cde68c8a577103f28b@kernel.org> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Content-Transfer-Encoding: base64 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Message-ID: <20200803150337.LfNGVJsb6p_3Qo8dTAwAYPxi5GUxl9MEQXSYxEfvo8Q@z> RnJvbTogTWFyYyBaeW5naWVyIDxtYXpAa2VybmVsLm9yZz4NCg0KPiBPbiAyMDIwLTA4LTAzIDA3 OjIyLCBNYXJrLVBLIFRzYWkgd3JvdGU6DQo+ID4gQWRkIG10NTh4eCBpbnRlcnJ1cHQgY29udHJv bGxlciBzdXBwb3J0IHVzaW5nIGhpZXJhcmNoeSBpcnENCj4gPiBkb21haW4uDQo+ID4gDQo+ID4g U2lnbmVkLW9mZi1ieTogTWFyay1QSyBUc2FpIDxtYXJrLXBrLnRzYWlAbWVkaWF0ZWsuY29tPg0K PiA+IC0tLQ0KPiA+ICBkcml2ZXJzL2lycWNoaXAvS2NvbmZpZyAgICAgIHwgICA3ICsrDQo+ID4g IGRyaXZlcnMvaXJxY2hpcC9NYWtlZmlsZSAgICAgfCAgIDEgKw0KPiA+ICBkcml2ZXJzL2lycWNo aXAvaXJxLW10NTh4eC5jIHwgMTk2ICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr DQo+ID4gIDMgZmlsZXMgY2hhbmdlZCwgMjA0IGluc2VydGlvbnMoKykNCj4gPiAgY3JlYXRlIG1v ZGUgMTAwNjQ0IGRyaXZlcnMvaXJxY2hpcC9pcnEtbXQ1OHh4LmMNCj4gPiANCj4gPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9pcnFjaGlwL0tjb25maWcgYi9kcml2ZXJzL2lycWNoaXAvS2NvbmZpZw0K PiA+IGluZGV4IDIxNmIzYjgzOTJiNS4uMDA0NTNhZjc4YmUwIDEwMDY0NA0KPiA+IC0tLSBhL2Ry aXZlcnMvaXJxY2hpcC9LY29uZmlnDQo+ID4gKysrIGIvZHJpdmVycy9pcnFjaGlwL0tjb25maWcN Cj4gPiBAQCAtNTcyLDQgKzU3MiwxMSBAQCBjb25maWcgTE9PTkdTT05fUENIX01TSQ0KPiA+ICAJ aGVscA0KPiA+ICAJICBTdXBwb3J0IGZvciB0aGUgTG9vbmdzb24gUENIIE1TSSBDb250cm9sbGVy Lg0KPiA+IA0KPiA+ICtjb25maWcgTVQ1OFhYX0lSUQ0KPiA+ICsJYm9vbCAiTVQ1OFhYIElSUSIN Cj4gPiArCXNlbGVjdCBJUlFfRE9NQUlODQo+ID4gKwlzZWxlY3QgSVJRX0RPTUFJTl9ISUVSQVJD SFkNCj4gPiArCWhlbHANCj4gPiArCSAgU3VwcG9ydCBNZWRpYXRlayBNVDU4WFggSW50ZXJydXB0 IENvbnRyb2xsZXIuDQo+ID4gKw0KPiA+ICBlbmRtZW51DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZl cnMvaXJxY2hpcC9NYWtlZmlsZSBiL2RyaXZlcnMvaXJxY2hpcC9NYWtlZmlsZQ0KPiA+IGluZGV4 IDEzM2Y5YzQ1NzQ0YS4uNTA2MmU5YmZhOTJkIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvaXJx Y2hpcC9NYWtlZmlsZQ0KPiA+ICsrKyBiL2RyaXZlcnMvaXJxY2hpcC9NYWtlZmlsZQ0KPiA+IEBA IC0xMTEsMyArMTExLDQgQEAgb2JqLSQoQ09ORklHX0xPT05HU09OX0hUUElDKQkJKz0gDQo+ID4g aXJxLWxvb25nc29uLWh0cGljLm8NCj4gPiAgb2JqLSQoQ09ORklHX0xPT05HU09OX0hUVkVDKQkJ Kz0gaXJxLWxvb25nc29uLWh0dmVjLm8NCj4gPiAgb2JqLSQoQ09ORklHX0xPT05HU09OX1BDSF9Q SUMpCQkrPSBpcnEtbG9vbmdzb24tcGNoLXBpYy5vDQo+ID4gIG9iai0kKENPTkZJR19MT09OR1NP Tl9QQ0hfTVNJKQkJKz0gaXJxLWxvb25nc29uLXBjaC1tc2kubw0KPiA+ICtvYmotJChDT05GSUdf TVQ1OFhYX0lSUSkJCSs9IGlycS1tdDU4eHgubw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2ly cWNoaXAvaXJxLW10NTh4eC5jIA0KPiA+IGIvZHJpdmVycy9pcnFjaGlwL2lycS1tdDU4eHguYw0K PiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMDAwMDAwLi5lNDVhZDAy M2FmYTYNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9pcnFjaGlwL2lycS1t dDU4eHguYw0KPiA+IEBAIC0wLDAgKzEsMTk2IEBADQo+ID4gKy8vIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiAoR1BMLTIuMCBPUiBCU0QtMy1DbGF1c2UpDQo+ID4gKy8qDQo+ID4gKyAqIENvcHly aWdodCAoYykgMjAyMCBNZWRpYVRlayBJbmMuDQo+ID4gKyAqIEF1dGhvciBNYXJrLVBLIFRzYWkg PG1hcmstcGsudHNhaUBtZWRpYXRlay5jb20+DQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2luY2x1 ZGUgPGxpbnV4L2ludGVycnVwdC5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaW8uaD4NCj4gPiAr I2luY2x1ZGUgPGxpbnV4L2lycS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaXJxY2hpcC5oPg0K PiA+ICsjaW5jbHVkZSA8bGludXgvaXJxZG9tYWluLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9v Zi5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvb2ZfYWRkcmVzcy5oPg0KPiA+ICsjaW5jbHVkZSA8 bGludXgvb2ZfaXJxLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+DQo+ID4gKw0KPiA+ ICsjZGVmaW5lIElOVENfTUFTSwkweDANCj4gPiArI2RlZmluZSBJTlRDX0VPSQkweDIwDQo+ID4g Kw0KPiA+ICtzdHJ1Y3QgbXRrX2ludGNfY2hpcF9kYXRhIHsNCj4gPiArCWNoYXIgKm5hbWU7DQo+ ID4gKwlzdHJ1Y3QgaXJxX2NoaXAgY2hpcDsNCj4gDQo+IFRoZXJlIGlzIG5vIG5lZWQgdG8gZW1i ZWQgYSBmdWxsIHN0cnVjdCBpcnFjaGlwIHBlciBjb250cm9sbGVyLCBzZWUgDQo+IGJlbG93Lg0K DQpXZSB3YW50IHRvIGRpc3Rpbmd1aXNoIHdoaWNoIGNvbnRyb2xsZXIgdGhlIGRldmljZSBpbnRl cnJ1cHRzIGFyZSBiZWxvbmcgdG8NCmJ5ICJjYXQgL3Byb2MvaW50ZXJydXB0cyIuDQpBbmQgaWYg YWxsIHRoZSBjb250cm9sbGVyIHNoYXJlIHRoZSBzYW1lIHN0cnVjdCwgdGhlIG5hbWUgZmllbGQg d2lsbCBiZSB0aGUNCnNhbWUuDQpEbyB5b3UgaGF2ZSBzdWdnZXN0aW9uIGZvciB0aGlzPw0KDQo+ IA0KPiA+ICsJdW5zaWduZWQgaW50IGlycV9zdGFydCwgbnJfaXJxczsNCj4gPiArCXZvaWQgX19p b21lbSAqYmFzZTsNCj4gPiArDQo+IH07DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBtdGtfcG9r ZV9pcnEoc3RydWN0IGlycV9kYXRhICpkLCB1MzIgb2Zmc2V0KQ0KPiAJPiArew0KPiA+ICsJc3Ry dWN0IG10a19pbnRjX2NoaXBfZGF0YSAqY2QgPSBpcnFfZGF0YV9nZXRfaXJxX2NoaXBfZGF0YShk KTsNCj4gPiArCXZvaWQgX19pb21lbSAqYmFzZSA9IGNkLT5iYXNlOw0KPiA+ICsJdTggaW5kZXgg PSAodTgpaXJxZF90b19od2lycShkKTsNCj4gDQo+IFdoeSB0aGUgcmVzdHJpY3RpdmUgdHlwZT8g V2h5IGlzbid0IHVuc2lnbmVkIGludCBnb29kIGVub3VnaD8NCg0KWW91J3JlIHJpZ2h0LCB1bnNp Z25lZCBpbnQgaXMgb2suDQpJJ2xsIGZpeCBpdCBpbiBwYXRjaCB2Mi4NCg0KPiANCj4gPiArCXUx NiB2YWwsIG1hc2s7DQo+ID4gKw0KPiA+ICsJbWFzayA9IDEgPDwgKGluZGV4ICUgMTYpOw0KPiA+ ICsJdmFsID0gcmVhZHdfcmVsYXhlZChiYXNlICsgb2Zmc2V0ICsgKGluZGV4IC8gMTYpICogNCkg fCBtYXNrOw0KPiA+ICsJd3JpdGV3X3JlbGF4ZWQodmFsLCBiYXNlICsgb2Zmc2V0ICsgKGluZGV4 IC8gMTYpICogNCk7DQo+IA0KPiBSTVcgd2l0aG91dCBsb2NraW5nLCB5b3Ugd2lsbCBlbmQtdXAg d2l0aCBjb3JydXB0aW9uLg0KPiBQbGVhc2Ugc3RvcmUgdGhlIGFkZHJlc3MgY2FsY3VsYXRpb24g aW4gYSB0ZW1wb3JhdHkgdmFyaWFibGUgdG8gbWFrZSBpdA0KPiBtb3JlIHJlYWRhYmxlDQo+IA0K DQpUaGFua3MgZm9yIHRoZSBjb21tZW50LCBJIHdpbGwgZml4IGl0IGluIHBhY3RoIHYyLg0KDQo+ ID4gKw0KPiAJfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2NsZWFyX2lycShzdHJ1Y3Qg aXJxX2RhdGEgKmQsIHUzMiBvZmZzZXQpDQo+IAk+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2ludGNf Y2hpcF9kYXRhICpjZCA9IGlycV9kYXRhX2dldF9pcnFfY2hpcF9kYXRhKGQpOw0KPiA+ICsJdm9p ZCBfX2lvbWVtICpiYXNlID0gY2QtPmJhc2U7DQo+ID4gKwl1OCBpbmRleCA9ICh1OClpcnFkX3Rv X2h3aXJxKGQpOw0KPiA+ICsJdTE2IHZhbCwgbWFzazsNCj4gPiArDQo+ID4gKwltYXNrID0gMSA8 PCAoaW5kZXggJSAxNik7DQo+ID4gKwl2YWwgPSByZWFkd19yZWxheGVkKGJhc2UgKyBvZmZzZXQg KyAoaW5kZXggLyAxNikgKiA0KSAmIH5tYXNrOw0KPiA+ICsJd3JpdGV3X3JlbGF4ZWQodmFsLCBi YXNlICsgb2Zmc2V0ICsgKGluZGV4IC8gMTYpICogNCk7DQo+IA0KPiBTYW1lIGNvbW1lbnRzLg0K PiANCg0KWW91J3JlIHJpZ2h0LCB1bnNpZ25lZCBpbnQgaXMgb2suDQpJJ2xsIGZpeCBpdCBpbiBw YXRjaCB2Mi4NCg0KPiA+ICsNCj4gCX0NCj4gPiArDQo+ID4gK3N0YXRpYyB2b2lkIG10a19pbnRj X21hc2tfaXJxKHN0cnVjdCBpcnFfZGF0YSAqZCkNCj4gCT4gK3sNCj4gPiArCW10a19wb2tlX2ly cShkLCBJTlRDX01BU0spOw0KPiA+ICsJaXJxX2NoaXBfbWFza19wYXJlbnQoZCk7DQo+ID4gKw0K PiAJfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2ludGNfdW5tYXNrX2lycShzdHJ1Y3Qg aXJxX2RhdGEgKmQpDQo+IAk+ICt7DQo+ID4gKwltdGtfY2xlYXJfaXJxKGQsIElOVENfTUFTSyk7 DQo+ID4gKwlpcnFfY2hpcF91bm1hc2tfcGFyZW50KGQpOw0KPiA+ICsNCj4gCX0NCj4gPiArDQo+ ID4gK3N0YXRpYyB2b2lkIG10a19pbnRjX2VvaV9pcnEoc3RydWN0IGlycV9kYXRhICpkKQ0KPiAJ PiArew0KPiA+ICsJbXRrX3Bva2VfaXJxKGQsIElOVENfRU9JKTsNCj4gPiArCWlycV9jaGlwX2Vv aV9wYXJlbnQoZCk7DQo+ID4gKw0KPiAJfQ0KPiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBpcnFf Y2hpcCBtdGtfaW50Y19jaGlwID0gew0KPiA+ICsJLmlycV9tYXNrCQk9IG10a19pbnRjX21hc2tf aXJxLA0KPiA+ICsJLmlycV91bm1hc2sJCT0gbXRrX2ludGNfdW5tYXNrX2lycSwNCj4gPiArCS5p cnFfZW9pCQk9IG10a19pbnRjX2VvaV9pcnEsDQo+ID4gKwkuaXJxX2dldF9pcnFjaGlwX3N0YXRl CT0gaXJxX2NoaXBfZ2V0X3BhcmVudF9zdGF0ZSwNCj4gPiArCS5pcnFfc2V0X2lycWNoaXBfc3Rh dGUJPSBpcnFfY2hpcF9zZXRfcGFyZW50X3N0YXRlLA0KPiA+ICsJLmlycV9zZXRfYWZmaW5pdHkJ PSBpcnFfY2hpcF9zZXRfYWZmaW5pdHlfcGFyZW50LA0KPiA+ICsJLmlycV9zZXRfdmNwdV9hZmZp bml0eQk9IGlycV9jaGlwX3NldF92Y3B1X2FmZmluaXR5X3BhcmVudCwNCj4gDQo+IEhvdyBhYm91 dCByZXRyaWdnZXI/DQo+IA0KDQpXaGF0IGlzIHJldHJpZ2dlciBtZWFucz8NClRvIGJlIGhvbmVz dCwgSSBqdXN0IHRyeSB0byBkaXJlY3QgYWxsIHRoZSBpcnFjaGlwIG9wcyBpbXBsZW1lbnRlZCBp biANCi9kcml2ZXJzL2lycWNoaXAvaXJxLWdpYy5jIHRvIGdpYyBkcml2ZXIuDQpCdXQgImlycV9z ZXRfdmNwdV9hZmZpbml0eSIgaXMgbm90IHVzZWQgaW4gb3VyIHByb2plY3RzIG5vdy4NClNob3Vs ZCBJIHJlbW92ZSAiLmlycV9zZXRfdmNwdV9hZmZpbml0eSIgaGVyZT8NCg0KPiA+ICsJLmlycV9z ZXRfdHlwZQkJPSBpcnFfY2hpcF9zZXRfdHlwZV9wYXJlbnQsDQo+ID4gKwkuZmxhZ3MJCQk9IElS UUNISVBfU0VUX1RZUEVfTUFTS0VEIHwNCj4gPiArCQkJCSAgSVJRQ0hJUF9TS0lQX1NFVF9XQUtF IHwNCj4gPiArCQkJCSAgSVJRQ0hJUF9NQVNLX09OX1NVU1BFTkQsDQo+ID4gKw0KPiB9Ow0KPiA+ ICsNCj4gPiArc3RhdGljIGludCBtdDU4eHhfaW50Y19kb21haW5fdHJhbnNsYXRlKHN0cnVjdCBp cnFfZG9tYWluICpkLA0KPiA+ICsJCQkJCXN0cnVjdCBpcnFfZndzcGVjICpmd3NwZWMsDQo+ID4g KwkJCQkJdW5zaWduZWQgbG9uZyAqaHdpcnEsDQo+ID4gKwkJCQkJdW5zaWduZWQgaW50ICp0eXBl KQ0KPiAJPiArew0KPiAJCT4gKwlpZiAoaXNfb2Zfbm9kZShmd3NwZWMtPmZ3bm9kZSkpIHsNCj4g PiArCQlpZiAoZndzcGVjLT5wYXJhbV9jb3VudCAhPSAzKQ0KPiA+ICsJCQlyZXR1cm4gLUVJTlZB TDsNCj4gPiArDQo+ID4gKwkJLyogTm8gUFBJIHNob3VsZCBwb2ludCB0byB0aGlzIGRvbWFpbiAq Lw0KPiA+ICsJCWlmIChmd3NwZWMtPnBhcmFtWzBdICE9IDApDQo+ID4gKwkJCXJldHVybiAtRUlO VkFMOw0KPiA+ICsNCj4gPiArCQkqaHdpcnEgPSBmd3NwZWMtPnBhcmFtWzFdOw0KPiA+ICsJCSp0 eXBlID0gZndzcGVjLT5wYXJhbVsyXSAmIElSUV9UWVBFX1NFTlNFX01BU0s7DQo+ID4gKwkJcmV0 dXJuIDA7DQo+ID4gKwkNCj4gCQl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIC1FSU5WQUw7DQo+ID4g Kw0KPiAJfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBtdDU4eHhfaW50Y19kb21haW5fYWxsb2Mo c3RydWN0IGlycV9kb21haW4gKmRvbWFpbiwNCj4gPiB1bnNpZ25lZCBpbnQgdmlycSwNCj4gPiAr CQkJCSAgICB1bnNpZ25lZCBpbnQgbnJfaXJxcywgdm9pZCAqZGF0YSkNCj4gCT4gK3sNCj4gPiAr CWludCBpOw0KPiA+ICsJaXJxX2h3X251bWJlcl90IGh3aXJxOw0KPiA+ICsJc3RydWN0IGlycV9m d3NwZWMgcGFyZW50X2Z3c3BlYywgKmZ3c3BlYyA9IGRhdGE7DQo+ID4gKwlzdHJ1Y3QgbXRrX2lu dGNfY2hpcF9kYXRhICpjZCA9IChzdHJ1Y3QgbXRrX2ludGNfY2hpcF9kYXRhDQo+ID4gKilkb21h aW4tPmhvc3RfZGF0YTsNCj4gPiArDQo+ID4gKwkvKiBOb3QgR0lDIGNvbXBsaWFudCAqLw0KPiA+ ICsJaWYgKGZ3c3BlYy0+cGFyYW1fY291bnQgIT0gMykNCj4gPiArCQlyZXR1cm4gLUVJTlZBTDsN Cj4gPiArDQo+ID4gKwkvKiBObyBQUEkgc2hvdWxkIHBvaW50IHRvIHRoaXMgZG9tYWluICovDQo+ ID4gKwlpZiAoZndzcGVjLT5wYXJhbVswXSkNCj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiAr DQo+ID4gKwlpZiAoZndzcGVjLT5wYXJhbVsxXSA+PSBjZC0+bnJfaXJxcykNCj4gPiArCQlyZXR1 cm4gLUVJTlZBTDsNCj4gPiArDQo+ID4gKwlod2lycSA9IGZ3c3BlYy0+cGFyYW1bMV07DQo+ID4g Kwlmb3IgKGkgPSAwOyBpIDwgbnJfaXJxczsgaSsrKQ0KPiA+ICsJCWlycV9kb21haW5fc2V0X2h3 aXJxX2FuZF9jaGlwKGRvbWFpbiwgdmlycSArIGksIGh3aXJxICsgaSwNCj4gPiArCQkJCQkgICAg ICAmY2QtPmNoaXAsDQo+ID4gKwkJCQkJICAgICAgZG9tYWluLT5ob3N0X2RhdGEpOw0KPiA+ICsN Cj4gPiArCXBhcmVudF9md3NwZWMgPSAqZndzcGVjOw0KPiA+ICsJcGFyZW50X2Z3c3BlYy5md25v ZGUgPSBkb21haW4tPnBhcmVudC0+Zndub2RlOw0KPiA+ICsJcGFyZW50X2Z3c3BlYy5wYXJhbVsx XSA9IGNkLT5pcnFfc3RhcnQgKyBod2lycTsNCj4gPiArCXJldHVybiBpcnFfZG9tYWluX2FsbG9j X2lycXNfcGFyZW50KGRvbWFpbiwgdmlycSwgbnJfaXJxcywgDQo+ID4gJnBhcmVudF9md3NwZWMp Ow0KPiA+ICsNCj4gCX0NCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaXJxX2RvbWFp bl9vcHMgbXQ1OHh4X2ludGNfZG9tYWluX29wcyA9IHsNCj4gPiArCS50cmFuc2xhdGUJPSBtdDU4 eHhfaW50Y19kb21haW5fdHJhbnNsYXRlLA0KPiA+ICsJLmFsbG9jCQk9IG10NTh4eF9pbnRjX2Rv bWFpbl9hbGxvYywNCj4gPiArCS5mcmVlCQk9IGlycV9kb21haW5fZnJlZV9pcnFzX2NvbW1vbiwN Cj4gPiArDQo+IH07DQo+ID4gKw0KPiA+ICtpbnQgX19pbml0DQo+ID4gK210NTh4eF9pbnRjX29m X2luaXQoc3RydWN0IGRldmljZV9ub2RlICpkbiwgc3RydWN0IGRldmljZV9ub2RlIA0KPiA+ICpw YXJlbnQpDQo+ID4gK3sNCj4gPiArCXN0YXRpYyBpbnQgbnJfaW50YzsNCj4gPiArCXN0cnVjdCBp cnFfZG9tYWluICpkb21haW4sICpkb21haW5fcGFyZW50Ow0KPiA+ICsJc3RydWN0IG10a19pbnRj X2NoaXBfZGF0YSAqY2Q7DQo+ID4gKwl1bnNpZ25lZCBpbnQgaXJxX3N0YXJ0LCBpcnFfZW5kOw0K PiA+ICsNCj4gPiArCWRvbWFpbl9wYXJlbnQgPSBpcnFfZmluZF9ob3N0KHBhcmVudCk7DQo+ID4g KwlpZiAoIWRvbWFpbl9wYXJlbnQpIHsNCj4gPiArCQlwcl9lcnIoIm10NTh4eC1pbnRjOiBpbnRl cnJ1cHQtcGFyZW50IG5vdCBmb3VuZFxuIik7DQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4g KwkNCj4gfQ0KPiA+ICsNCj4gPiArCWNkID0ga3phbGxvYyhzaXplb2YoKmNkKSwgR0ZQX0tFUk5F TCk7DQo+ID4gKwlpZiAoIWNkKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiAr CWNkLT5jaGlwID0gbXRrX2ludGNfY2hpcDsNCj4gPiArCWlmIChvZl9wcm9wZXJ0eV9yZWFkX3Uz Ml9pbmRleChkbiwgIm1lZGlhdGVrLGlycXMtbWFwLXJhbmdlIiwgMCwNCj4gPiAmaXJxX3N0YXJ0 KSB8fA0KPiA+ICsJICAgIG9mX3Byb3BlcnR5X3JlYWRfdTMyX2luZGV4KGRuLCAibWVkaWF0ZWss aXJxcy1tYXAtcmFuZ2UiLCAxLCANCj4gCT4gJmlycV9lbmQpKSB7DQo+ID4gKwkJa2ZyZWUoY2Qp Ow0KPiA+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+ICsJDQo+IH0NCj4gPiArDQo+ID4gKwlpZiAo b2ZfcHJvcGVydHlfcmVhZF9ib29sKGRuLCAibWVkaWF0ZWssaW50Yy1uby1lb2kiKSkNCj4gPiAr CQljZC0+Y2hpcC5pcnFfZW9pID0gaXJxX2NoaXBfZW9pX3BhcmVudDsNCj4gDQo+IE5vLiBKdXN0 IGFkZCBhIGZsYWcgdG8geW91ciBjaGlwIGRhdGEgc3RydWN0dXJlLCBhbmQgY2hlY2sgZm9yIHRo aXMNCj4gZmxhZyBpbiB5b3VyIGlycV9lb2kgY2FsbGJhY2suIE9yIHByb3ZpZGUgdHdvIGRpc3Rp bmN0IGlycV9jaGlwDQo+IHN0cnVjdHVyZXMgdGhhdCB3aWxsIG9ubHkgZGlmZmVyIGJ5IHRoZSBp cnFfZW9pIG1ldGhvZC4NCg0KVGhhbmtzIGZvciB0aGUgY29tbWVudCwgSSB3aWxsIG1vZGlmeSBp dCBpbiBwYXRjaCB2Mi4NCg0KPiANCj4gPiArDQo+ID4gKwljZC0+aXJxX3N0YXJ0ID0gaXJxX3N0 YXJ0Ow0KPiA+ICsJY2QtPm5yX2lycXMgPSBpcnFfZW5kIC0gaXJxX3N0YXJ0ICsgMTsNCj4gPiAr CWNkLT5jaGlwLm5hbWUgPSBrYXNwcmludGYoR0ZQX0tFUk5FTCwgIm10NTh4eC1pbnRjLSVkIiwg bnJfaW50YysrKTsNCj4gDQo+IE5laXRoZXIuIFRoYXQncyBub3QgdXNlZnVsLCBhbmQgaXMgYSB3 YXN0ZSBvZiBtZW1vcnkuIFN0aWNrIHRvIGNvbnN0YW50DQo+IG5hbWVzIGluIHRoZSBpcnFfY2hp cCBzdHJ1Y3R1cmUuDQo+IA0KDQpBY3R1YWxseSB3ZSBoYXZlIG11bHRpcGxlIGlycSBjb250cm9s bGVyIGluIG91ciBTb0NzLg0KQW5kIGlmIHdlIHVzZSB0aGUgY29uc3RhbnQgbmFtZXMgaW4gaXJx X2NoaXAgc3RydWN0dXJlLCB0aGUgaW5mb3JtYXRpb24gaW4NCiIvcHJvYy9pbnRlcnJ1cHRzIiB3 aWxsIGJlIGhhcmQgdG8gdW5kZXJzdGFuZCBiZWNhdXNlIGFsbCB0aGUgaXJxY2hpcCBuYW1lDQpp cyB0aGUgc2FtZS4NCkRvIHlvdSBoYXZlIGFueSBzdWdnZXN0aW9uIGZvciB0aGlzPw0KDQo+ID4g KwlpZiAoIWNkLT5jaGlwLm5hbWUpIHsNCj4gPiArCQlrZnJlZShjZCk7DQo+ID4gKwkJcmV0dXJu IC1FTk9NRU07DQo+ID4gKwkNCj4gfQ0KPiA+ICsNCj4gPiArCWNkLT5iYXNlID0gb2ZfaW9tYXAo ZG4sIDApOw0KPiA+ICsJaWYgKCFjZC0+YmFzZSkgew0KPiA+ICsJCWtmcmVlKGNkLT5jaGlwLm5h bWUpOw0KPiA+ICsJCWtmcmVlKGNkKTsNCj4gPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gPiArCQ0K PiB9DQo+ID4gKw0KPiA+ICsJZG9tYWluID0gaXJxX2RvbWFpbl9hZGRfaGllcmFyY2h5KGRvbWFp bl9wYXJlbnQsIDAsIGNkLT5ucl9pcnFzLA0KPiA+ICsJCQkJCSAgZG4sICZtdDU4eHhfaW50Y19k b21haW5fb3BzLCBjZCk7DQo+ID4gKwlpZiAoIWRvbWFpbikgew0KPiA+ICsJCWtmcmVlKGNkLT5j aGlwLm5hbWUpOw0KPiA+ICsJCWlvdW5tYXAoY2QtPmJhc2UpOw0KPiA+ICsJCWtmcmVlKGNkKTsN Cj4gPiArCQlyZXR1cm4gLUVOT01FTTsNCj4gPiArCQ0KPiB9DQo+ID4gKw0KPiA+ICsJcmV0dXJu IDA7DQo+ID4gKw0KPiB9DQo+ID4gKw0KPiA+ICtJUlFDSElQX0RFQ0xBUkUobXQ1OHh4X2ludGMs ICJtZWRpYXRlayxtdDU4eHgtaW50YyIsIA0KPiA+IG10NTh4eF9pbnRjX29mX2luaXQpOw0KPiAN Cj4gT24gYSBzaWRlIG5vdGUsIHRoZSBtZXJnZSB3aW5kb3cgaGFzIGp1c3Qgb3BlbmVkLiBQbGVh c2UgcmVmcmFpbiBmcm9tDQo+IHJlcG9zdGluZyB0aGlzIHVudGlsIC1yYzEuDQoNCkdvdCBpdCwg YW5kIHRoYW5rcyBmb3IgeW91ciBjb21tZW50cy4NCkknbGwgdXBkYXRlIHRoZSBwYXRjaCBhbmQg cG9zdCBpdCBhZnRlciAtcmMxLg0K