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=-8.2 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=unavailable 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 1B41AC2D0C0 for ; Mon, 16 Dec 2019 13:02:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D3DA020717 for ; Mon, 16 Dec 2019 13:02:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727862AbfLPNCI (ORCPT ); Mon, 16 Dec 2019 08:02:08 -0500 Received: from foss.arm.com ([217.140.110.172]:54586 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727576AbfLPNCH (ORCPT ); Mon, 16 Dec 2019 08:02:07 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2123D1FB; Mon, 16 Dec 2019 05:02:06 -0800 (PST) Received: from [10.37.12.145] (unknown [10.37.12.145]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A80CC3F718; Mon, 16 Dec 2019 05:02:01 -0800 (PST) Subject: Re: Re: [PATCH 7/7] devfreq: move statistics to separate struct To: Bartlomiej Zolnierkiewicz Cc: Chanwoo Choi , Javi Merino , linux-samsung-soc@vger.kernel.org, linux-pm@vger.kernel.org, Kamil Konieczny , linux-kernel@vger.kernel.org, Krzysztof Kozlowski , Eduardo Valentin , Kyungmin Park , Kukjin Kim , MyungJoo Ham , Zhang Rui , =?UTF-8?Q?=c3=98rjan_Eide?= , linux-arm-kernel@lists.infradead.org, Marek Szyprowski , Dietmar Eggemann , a.hajda@samsung.com, robin.murphy@arm.com References: <20191113091336.5218-1-k.konieczny@samsung.com> <20191113091336.5218-8-k.konieczny@samsung.com> <4942d2ad-fef7-89be-91c1-c02c319546ff@samsung.com> <38350d81-e916-b386-6727-f4c85689c172@samsung.com> <85a29ce4-0f89-2b50-b046-dba747208933@samsung.com> <4ed6b8bf-b415-c42d-33d6-d2ed0504eaf4@samsung.com> From: Lukasz Luba Message-ID: Date: Mon, 16 Dec 2019 13:01:59 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Bartek, [added Dietmar, Robin, Andrzej (for upcoming DRM drm-misc-next)] On 11/15/19 12:40 PM, Bartlomiej Zolnierkiewicz wrote: > > [ added Zhang, Eduardo, Ørjan and Javi to Cc: ] > > On 11/15/19 7:21 AM, Chanwoo Choi wrote: >> Hi Bartlomiej, >> >> On 11/15/19 12:25 PM, Chanwoo Choi wrote: >>> Hi Bartlomiej, >>> >>> On 11/15/19 3:01 AM, Bartlomiej Zolnierkiewicz wrote: >>>> >>>> Hi Chanwoo, >>>> >>>> On 11/14/19 2:52 AM, Chanwoo Choi wrote: >>>>> Hi Kamil, >>>>> >>>>> The 'freq_table' and 'max_state' in the devfreq_dev_profile >>>>> were used in the ARM Mali device driver[1][2][3]. Although ARM Mali >>>>> device driver was posted to mainline kernel, they used >>>>> them for a long time. It means that this patch break >>>>> the compatibility. The ARM Mali drivers are very >>>>> important devfreq device driver. >>>> >>>> This argument is not a a technical one and the official upstream >>>> kernel policy is to not depend on out-of-tree drivers. >>>> >>>> Besides the ARM Mali drivers are full of code like: >>>> >>>> #if LINUX_VERSION_CODE >= KERNEL_VERSION(x, y, z) >>>> ... >>>> #else >>>> ... >>>> #endif >>>> >>>> so few more instances of similar code won't do any harm.. ;-) >>>> >>>>> [1] https://protect2.fireeye.com/url?k=909caa5c-cd52abe8-909d2113-000babdfecba-812f16576c3614a3&u=https://developer.arm.com/tools-and-software/graphics-and-gaming/mali-drivers/bifrost-kernel# >>>>> [2] https://protect2.fireeye.com/url?k=33265f96-6ee85e22-3327d4d9-000babdfecba-44c2daec328712e6&u=https://developer.arm.com/tools-and-software/graphics-and-gaming/mali-drivers/midgard-kernel >>>>> [3] https://protect2.fireeye.com/url?k=69bdcab0-3473cb04-69bc41ff-000babdfecba-4b576facf85e0208&u=https://developer.arm.com/tools-and-software/graphics-and-gaming/mali-drivers/utgard-kernel >>>> >>>> I took a look at ARM Mali drivers source code anyway and I fail to >>>> see a rationale behind their behavior of doing 'freq_table' and >>>> 'max_state' initialization in the driver itself (instead of leaving >>>> it up to the devfreq core code, like all in-kernel drivers are doing >>>> already). >>>> >>>> Could you please explain rationale behind ARM Mali drivers' special >>>> needs? >>>> >>>> [ Both ARM Mali and devfreq core code are using generic PM OPP code >>>> these days to do 'freq_table' and 'max_state' initialization, the >>>> only difference seems to be that ARM Mali creates the frequency >>>> table in the descending order (but there also seems to be no real >>>> need for it). ] >>>> >>>> Maybe this is an opportunity to simplify also the ARM Mali driver? >>> >>> OK. I agree to simplify them on this time. >>> For touching the 'freq_table' and 'max_state', need to fix >>> the descending order of freq_table. >>> >>> The partition_enable_ops() in the drivers/thermal/devfreq_cooling.c >>> requires the descending order of freq_table. Have to change it by using >>> the ascending time or support both ascending and descending order for freq_table. >>> >>> 1. Move freq_table, max_state of devfreq_dev_profile to struct devfreq >>> 2. Edit partition_enable_ops() in the drivers/thermal/devfreq_cooling.c >>> by using ascending order instead of descending order. >>> >> >> After changed about 'freq_table' and 'max_state', the build error >> will happen on ARM mail driver because the initialization code of >> 'freq_table' in ARM mali driver, didn't check the kernel version. >> >> The first devfreq patch provided the 'freq_table' as optional variable >> in the 'struct devfreq_dev_profile'. Even if ARM mali driver is out of mainline tree, >> this change seems that break the usage rule of 'freq_table' in 'struct devfreq_dev_profile'. >> >> So, if there are no any beneficial reason, I just keep the current status of 'freq_table' >> in order to keep the previous usage rule of 'freq_table' in 'struct devfreq_dev_profile'. >> >> Frankly, I'm note sure that it is necessary. I don't want to make >> the side-effect without any useful reason. >> >> But, >> Separately, have to fix the ordering issue of partition_enable_ops() >> in the drivers/thermal/devfreq_cooling.c. > > Hmmm.. fixing partition_enable_opps() should be trivial but I wonder > why we are carrying devfreq_cooling.c code in upstream kernel at all? Well, the devfreq_cooling.c is going to have a client in mainline: the GPU driver - Panfrost. It is already in DRM branch 'drm-misc-next': https://patchwork.freedesktop.org/patch/342848/ Regarding the devfreq_cooling.c code structure. I am currently working on cleaning up the devfreq cooling code and adding Energy Model instead for private freq, power tables. It will be in similar fashion as it is done in cpufreq_cooling. The model will be also simplified so hopefully more clients would come. It is under internal review and will be posted shortly. > > It has been merged in the following commit: > > commit a76caf55e5b356ba20a5a43ac4d9f7a04b20941d > Author: Ørjan Eide > Date: Thu Sep 10 18:09:30 2015 +0100 > > thermal: Add devfreq cooling > > Add a generic thermal cooling device for devfreq, that is similar to > cpu_cooling. > > The device must use devfreq. In order to use the power extension of the > cooling device, it must have registered its OPPs using the OPP library. > > Cc: Zhang Rui > Cc: Eduardo Valentin > Signed-off-by: Javi Merino > Signed-off-by: Ørjan Eide > Signed-off-by: Eduardo Valentin > ... > > but 4 years later there is still no single in-kernel user for this code? There will be, via DRM tree. Regards, Lukasz > > Best regards, > -- > Bartlomiej Zolnierkiewicz > Samsung R&D Institute Poland > Samsung Electronics > >>>> >>>>> Also, the devfreq device driver specifies their own >>>>> information and data into devfreq_dev_profile structure >>>>> before registering the devfreq device with devfreq_add_device(). >>>>> This patch breaks the basic usage rule of devfreq_dev_profile structure. >>>> >>>> Well, 'struct devfreq_stats *stats' can be trivially moved out of >>>> 'struct devfreq_profile' to 'struct devfreq' if you prefer it that >>>> way.. >>>> >>>> Best regards, >>>> -- >>>> Bartlomiej Zolnierkiewicz >>>> Samsung R&D Institute Poland >>>> Samsung Electronics >>>> >>>>> So, I can't agree this patch. Not ack. >>>>> >>>>> Regards, >>>>> Chanwoo Choi >>>>> >>>>> On 11/13/19 6:13 PM, Kamil Konieczny wrote: >>>>>> Count time and transitions between devfreq frequencies in separate struct >>>>>> for improved code readability and maintenance. >>>>>> >>>>>> Signed-off-by: Kamil Konieczny >>>>>> --- >>>>>> drivers/devfreq/devfreq.c | 156 ++++++++++++++++------------- >>>>>> drivers/devfreq/exynos-bus.c | 6 +- >>>>>> drivers/devfreq/governor_passive.c | 26 +++-- >>>>>> include/linux/devfreq.h | 43 ++++---- >>>>>> 4 files changed, 129 insertions(+), 102 deletions(-) >>>>>> >>>>>> diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c >>>>>> index d79412b0de59..d85867a91230 100644 >>>>>> --- a/drivers/devfreq/devfreq.c >>>>>> +++ b/drivers/devfreq/devfreq.c >>>>>> @@ -105,10 +105,11 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq) >>>>>> */ >>>>>> static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) >>>>>> { >>>>>> + struct devfreq_stats *stats = devfreq->profile->stats; >>>>>> int lev; >>>>>> >>>>>> - for (lev = 0; lev < devfreq->profile->max_state; lev++) >>>>>> - if (freq == devfreq->profile->freq_table[lev]) >>>>>> + for (lev = 0; lev < stats->max_state; lev++) >>>>>> + if (freq == stats->freq_table[lev]) >>>>>> return lev; >>>>>> >>>>>> return -EINVAL; >>>>>> @@ -117,56 +118,64 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) >>>>>> static int set_freq_table(struct devfreq *devfreq) >>>>>> { >>>>>> struct devfreq_dev_profile *profile = devfreq->profile; >>>>>> + struct devfreq_stats *stats; >>>>>> struct dev_pm_opp *opp; >>>>>> unsigned long freq; >>>>>> - int i, count; >>>>>> + int i, count, err = -ENOMEM; >>>>>> >>>>>> /* Initialize the freq_table from OPP table */ >>>>>> count = dev_pm_opp_get_opp_count(devfreq->dev.parent); >>>>>> if (count <= 0) >>>>>> return -EINVAL; >>>>>> >>>>>> - profile->max_state = count; >>>>>> - profile->freq_table = devm_kcalloc(devfreq->dev.parent, >>>>>> - count, >>>>>> - sizeof(*profile->freq_table), >>>>>> - GFP_KERNEL); >>>>>> - if (!profile->freq_table) { >>>>>> - profile->max_state = 0; >>>>>> + stats = devm_kzalloc(devfreq->dev.parent, >>>>>> + sizeof(struct devfreq_stats), GFP_KERNEL); >>>>>> + if (!stats) >>>>>> return -ENOMEM; >>>>>> - } >>>>>> >>>>>> - for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { >>>>>> + profile->stats = stats; >>>>>> + stats->max_state = count; >>>>>> + stats->freq_table = devm_kcalloc(devfreq->dev.parent, >>>>>> + count, >>>>>> + sizeof(*stats->freq_table), >>>>>> + GFP_KERNEL); >>>>>> + if (!stats->freq_table) >>>>>> + goto err_no_mem; >>>>>> + >>>>>> + for (i = 0, freq = 0; i < count; i++, freq++) { >>>>>> opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); >>>>>> if (IS_ERR(opp)) { >>>>>> - devm_kfree(devfreq->dev.parent, profile->freq_table); >>>>>> - profile->max_state = 0; >>>>>> - return PTR_ERR(opp); >>>>>> + devm_kfree(devfreq->dev.parent, stats->freq_table); >>>>>> + stats->max_state = 0; >>>>>> + err = PTR_ERR(opp); >>>>>> + goto err_no_mem; >>>>>> } >>>>>> dev_pm_opp_put(opp); >>>>>> - profile->freq_table[i] = freq; >>>>>> + stats->freq_table[i] = freq; >>>>>> } >>>>>> >>>>>> - profile->trans_table = devm_kzalloc(devfreq->dev.parent, >>>>>> - array3_size(sizeof(unsigned int), >>>>>> - count, count), >>>>>> - GFP_KERNEL); >>>>>> - if (!profile->trans_table) >>>>>> + stats->trans_table = devm_kzalloc(devfreq->dev.parent, >>>>>> + array3_size(sizeof(unsigned int), >>>>>> + count, count), >>>>>> + GFP_KERNEL); >>>>>> + if (!stats->trans_table) >>>>>> goto err_no_mem; >>>>>> >>>>>> - profile->time_in_state = devm_kcalloc(devfreq->dev.parent, count, >>>>>> - sizeof(*profile->time_in_state), >>>>>> - GFP_KERNEL); >>>>>> - if (!profile->time_in_state) >>>>>> + stats->time_in_state = devm_kcalloc(devfreq->dev.parent, count, >>>>>> + sizeof(*stats->time_in_state), >>>>>> + GFP_KERNEL); >>>>>> + if (!stats->time_in_state) >>>>>> goto err_no_mem; >>>>>> >>>>>> - profile->last_time = get_jiffies_64(); >>>>>> - spin_lock_init(&profile->stats_lock); >>>>>> + stats->last_time = get_jiffies_64(); >>>>>> + spin_lock_init(&stats->stats_lock); >>>>>> >>>>>> return 0; >>>>>> err_no_mem: >>>>>> - profile->max_state = 0; >>>>>> - return -ENOMEM; >>>>>> + stats->max_state = 0; >>>>>> + devm_kfree(devfreq->dev.parent, profile->stats); >>>>>> + profile->stats = NULL; >>>>>> + return err; >>>>>> } >>>>>> >>>>>> /** >>>>>> @@ -176,7 +185,7 @@ static int set_freq_table(struct devfreq *devfreq) >>>>>> */ >>>>>> int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) >>>>>> { >>>>>> - struct devfreq_dev_profile *profile = devfreq->profile; >>>>>> + struct devfreq_stats *stats = devfreq->profile->stats; >>>>>> unsigned long long cur_time; >>>>>> int lev, prev_lev, ret = 0; >>>>>> >>>>>> @@ -184,22 +193,21 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) >>>>>> >>>>>> /* Immediately exit if previous_freq is not initialized yet. */ >>>>>> if (!devfreq->previous_freq) { >>>>>> - spin_lock(&profile->stats_lock); >>>>>> - profile->last_time = cur_time; >>>>>> - spin_unlock(&profile->stats_lock); >>>>>> + spin_lock(&stats->stats_lock); >>>>>> + stats->last_time = cur_time; >>>>>> + spin_unlock(&stats->stats_lock); >>>>>> return 0; >>>>>> } >>>>>> >>>>>> prev_lev = devfreq_get_freq_level(devfreq, devfreq->previous_freq); >>>>>> >>>>>> - spin_lock(&profile->stats_lock); >>>>>> + spin_lock(&stats->stats_lock); >>>>>> if (prev_lev < 0) { >>>>>> ret = prev_lev; >>>>>> goto out; >>>>>> } >>>>>> >>>>>> - profile->time_in_state[prev_lev] += >>>>>> - cur_time - profile->last_time; >>>>>> + stats->time_in_state[prev_lev] += cur_time - stats->last_time; >>>>>> lev = devfreq_get_freq_level(devfreq, freq); >>>>>> if (lev < 0) { >>>>>> ret = lev; >>>>>> @@ -207,14 +215,14 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) >>>>>> } >>>>>> >>>>>> if (lev != prev_lev) { >>>>>> - profile->trans_table[(prev_lev * >>>>>> - profile->max_state) + lev]++; >>>>>> - profile->total_trans++; >>>>>> + stats->trans_table[(prev_lev * >>>>>> + stats->max_state) + lev]++; >>>>>> + stats->total_trans++; >>>>>> } >>>>>> >>>>>> out: >>>>>> - profile->last_time = cur_time; >>>>>> - spin_unlock(&profile->stats_lock); >>>>>> + stats->last_time = cur_time; >>>>>> + spin_unlock(&stats->stats_lock); >>>>>> return ret; >>>>>> } >>>>>> EXPORT_SYMBOL(devfreq_update_status); >>>>>> @@ -504,9 +512,9 @@ void devfreq_monitor_resume(struct devfreq *devfreq) >>>>>> queue_delayed_work(devfreq_wq, &devfreq->work, >>>>>> msecs_to_jiffies(profile->polling_ms)); >>>>>> >>>>>> - spin_lock(&profile->stats_lock); >>>>>> - profile->last_time = get_jiffies_64(); >>>>>> - spin_unlock(&profile->stats_lock); >>>>>> + spin_lock(&profile->stats->stats_lock); >>>>>> + profile->stats->last_time = get_jiffies_64(); >>>>>> + spin_unlock(&profile->stats->stats_lock); >>>>>> devfreq->stop_polling = false; >>>>>> >>>>>> if (profile->get_cur_freq && >>>>>> @@ -677,7 +685,7 @@ struct devfreq *devfreq_add_device(struct device *dev, >>>>>> devfreq->data = data; >>>>>> devfreq->nb.notifier_call = devfreq_notifier_call; >>>>>> >>>>>> - if (!profile->max_state && !profile->freq_table) { >>>>>> + if (!profile->stats) { >>>>>> mutex_unlock(&devfreq->lock); >>>>>> err = set_freq_table(devfreq); >>>>>> if (err < 0) >>>>>> @@ -1282,6 +1290,7 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr, >>>>>> const char *buf, size_t count) >>>>>> { >>>>>> struct devfreq *df = to_devfreq(dev); >>>>>> + struct devfreq_stats *stats = df->profile->stats; >>>>>> unsigned long value; >>>>>> int ret; >>>>>> >>>>>> @@ -1297,13 +1306,13 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr, >>>>>> goto unlock; >>>>>> } >>>>>> } else { >>>>>> - unsigned long *freq_table = df->profile->freq_table; >>>>>> + unsigned long *freq_table = stats->freq_table; >>>>>> >>>>>> /* Get minimum frequency according to sorting order */ >>>>>> - if (freq_table[0] < freq_table[df->profile->max_state - 1]) >>>>>> + if (freq_table[0] < freq_table[stats->max_state - 1]) >>>>>> value = freq_table[0]; >>>>>> else >>>>>> - value = freq_table[df->profile->max_state - 1]; >>>>>> + value = freq_table[stats->max_state - 1]; >>>>>> } >>>>>> >>>>>> df->min_freq = value; >>>>>> @@ -1326,6 +1335,7 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, >>>>>> const char *buf, size_t count) >>>>>> { >>>>>> struct devfreq *df = to_devfreq(dev); >>>>>> + struct devfreq_stats *stats = df->profile->stats; >>>>>> unsigned long value; >>>>>> int ret; >>>>>> >>>>>> @@ -1341,11 +1351,11 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, >>>>>> goto unlock; >>>>>> } >>>>>> } else { >>>>>> - unsigned long *freq_table = df->profile->freq_table; >>>>>> + unsigned long *freq_table = stats->freq_table; >>>>>> >>>>>> /* Get maximum frequency according to sorting order */ >>>>>> - if (freq_table[0] < freq_table[df->profile->max_state - 1]) >>>>>> - value = freq_table[df->profile->max_state - 1]; >>>>>> + if (freq_table[0] < freq_table[stats->max_state - 1]) >>>>>> + value = freq_table[stats->max_state - 1]; >>>>>> else >>>>>> value = freq_table[0]; >>>>>> } >>>>>> @@ -1373,14 +1383,15 @@ static ssize_t available_frequencies_show(struct device *d, >>>>>> char *buf) >>>>>> { >>>>>> struct devfreq *df = to_devfreq(d); >>>>>> + struct devfreq_stats *stats = df->profile->stats; >>>>>> ssize_t count = 0; >>>>>> int i; >>>>>> >>>>>> mutex_lock(&df->lock); >>>>>> >>>>>> - for (i = 0; i < df->profile->max_state; i++) >>>>>> + for (i = 0; i < stats->max_state; i++) >>>>>> count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), >>>>>> - "%lu ", df->profile->freq_table[i]); >>>>>> + "%lu ", stats->freq_table[i]); >>>>>> >>>>>> mutex_unlock(&df->lock); >>>>>> /* Truncate the trailing space */ >>>>>> @@ -1398,9 +1409,10 @@ static ssize_t trans_stat_show(struct device *dev, >>>>>> { >>>>>> struct devfreq *devfreq = to_devfreq(dev); >>>>>> struct devfreq_dev_profile *profile = devfreq->profile; >>>>>> + struct devfreq_stats *stats = profile->stats; >>>>>> + unsigned int max_state = stats->max_state; >>>>>> ssize_t len; >>>>>> int i, j; >>>>>> - unsigned int max_state = profile->max_state; >>>>>> >>>>>> if (!devfreq->stop_polling && >>>>>> devfreq_update_status(devfreq, devfreq->previous_freq)) >>>>>> @@ -1411,45 +1423,45 @@ static ssize_t trans_stat_show(struct device *dev, >>>>>> len = sprintf(buf, " From : To\n"); >>>>>> len += sprintf(buf + len, " :"); >>>>>> >>>>>> - spin_lock(&profile->stats_lock); >>>>>> + spin_lock(&stats->stats_lock); >>>>>> for (i = 0; i < max_state; i++) >>>>>> len += sprintf(buf + len, "%10lu", >>>>>> - profile->freq_table[i]); >>>>>> + stats->freq_table[i]); >>>>>> >>>>>> len += sprintf(buf + len, " time(ms)\n"); >>>>>> >>>>>> for (i = 0; i < max_state; i++) { >>>>>> - if (profile->freq_table[i] == devfreq->previous_freq) >>>>>> + if (stats->freq_table[i] == devfreq->previous_freq) >>>>>> len += sprintf(buf + len, "*"); >>>>>> else >>>>>> len += sprintf(buf + len, " "); >>>>>> >>>>>> len += sprintf(buf + len, "%10lu:", >>>>>> - profile->freq_table[i]); >>>>>> + stats->freq_table[i]); >>>>>> for (j = 0; j < max_state; j++) >>>>>> len += sprintf(buf + len, "%10u", >>>>>> - profile->trans_table[(i * max_state) + j]); >>>>>> + stats->trans_table[(i * max_state) + j]); >>>>>> len += sprintf(buf + len, "%10llu\n", (u64) >>>>>> - jiffies64_to_msecs(profile->time_in_state[i])); >>>>>> + jiffies64_to_msecs(stats->time_in_state[i])); >>>>>> } >>>>>> >>>>>> len += sprintf(buf + len, "Total transition : %u\n", >>>>>> - profile->total_trans); >>>>>> - spin_unlock(&profile->stats_lock); >>>>>> + stats->total_trans); >>>>>> + spin_unlock(&stats->stats_lock); >>>>>> return len; >>>>>> } >>>>>> static DEVICE_ATTR_RO(trans_stat); >>>>>> >>>>>> -static void defvreq_stats_clear_table(struct devfreq_dev_profile *profile) >>>>>> +static void defvreq_stats_clear_table(struct devfreq_stats *stats) >>>>>> { >>>>>> - unsigned int count = profile->max_state; >>>>>> - >>>>>> - spin_lock(&profile->stats_lock); >>>>>> - memset(profile->time_in_state, 0, count * sizeof(u64)); >>>>>> - memset(profile->trans_table, 0, count * count * sizeof(int)); >>>>>> - profile->last_time = get_jiffies_64(); >>>>>> - profile->total_trans = 0; >>>>>> - spin_unlock(&profile->stats_lock); >>>>>> + unsigned int count = stats->max_state; >>>>>> + >>>>>> + spin_lock(&stats->stats_lock); >>>>>> + memset(stats->time_in_state, 0, count * sizeof(u64)); >>>>>> + memset(stats->trans_table, 0, count * count * sizeof(int)); >>>>>> + stats->last_time = get_jiffies_64(); >>>>>> + stats->total_trans = 0; >>>>>> + spin_unlock(&stats->stats_lock); >>>>>> } >>>>>> >>>>>> static ssize_t trans_reset_store(struct device *dev, >>>>>> @@ -1459,7 +1471,7 @@ static ssize_t trans_reset_store(struct device *dev, >>>>>> { >>>>>> struct devfreq *devfreq = to_devfreq(dev); >>>>>> >>>>>> - defvreq_stats_clear_table(devfreq->profile); >>>>>> + defvreq_stats_clear_table(devfreq->profile->stats); >>>>>> >>>>>> return count; >>>>>> } >>>>>> diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c >>>>>> index d9f377912c10..b212aae2bb3e 100644 >>>>>> --- a/drivers/devfreq/exynos-bus.c >>>>>> +++ b/drivers/devfreq/exynos-bus.c >>>>>> @@ -496,9 +496,9 @@ static int exynos_bus_probe(struct platform_device *pdev) >>>>>> } >>>>>> >>>>>> out: >>>>>> - max_state = bus->devfreq->profile->max_state; >>>>>> - min_freq = (bus->devfreq->profile->freq_table[0] / 1000); >>>>>> - max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000); >>>>>> + max_state = profile->stats->max_state; >>>>>> + min_freq = (profile->stats->freq_table[0] / 1000); >>>>>> + max_freq = (profile->stats->freq_table[max_state - 1] / 1000); >>>>>> pr_info("exynos-bus: new bus device registered: %s (%6ld KHz ~ %6ld KHz)\n", >>>>>> dev_name(dev), min_freq, max_freq); >>>>>> >>>>>> diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c >>>>>> index 58308948b863..b2d87a88335c 100644 >>>>>> --- a/drivers/devfreq/governor_passive.c >>>>>> +++ b/drivers/devfreq/governor_passive.c >>>>>> @@ -18,6 +18,8 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, >>>>>> struct devfreq_passive_data *p_data >>>>>> = (struct devfreq_passive_data *)devfreq->data; >>>>>> struct devfreq *parent_devfreq = (struct devfreq *)p_data->parent; >>>>>> + struct devfreq_stats *parent_stats = parent_devfreq->profile->stats; >>>>>> + struct devfreq_stats *stats; >>>>>> unsigned long child_freq = ULONG_MAX; >>>>>> struct dev_pm_opp *opp; >>>>>> int i, count, ret = 0; >>>>>> @@ -47,10 +49,14 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, >>>>>> * device. And then the index is used for getting the suitable >>>>>> * new frequency for passive devfreq device. >>>>>> */ >>>>>> - if (!devfreq->profile || !devfreq->profile->freq_table >>>>>> - || devfreq->profile->max_state <= 0) >>>>>> + if (!devfreq->profile || !devfreq->profile->stats || >>>>>> + devfreq->profile->stats->max_state <= 0 || >>>>>> + !parent_devfreq->profile || !parent_devfreq->profile->stats || >>>>>> + parent_devfreq->profile->stats->max_state <= 0) >>>>>> return -EINVAL; >>>>>> >>>>>> + stats = devfreq->profile->stats; >>>>>> + parent_stats = parent_devfreq->profile->stats; >>>>>> /* >>>>>> * The passive governor have to get the correct frequency from OPP >>>>>> * list of parent device. Because in this case, *freq is temporary >>>>>> @@ -68,21 +74,21 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, >>>>>> * Get the OPP table's index of decided freqeuncy by governor >>>>>> * of parent device. >>>>>> */ >>>>>> - for (i = 0; i < parent_devfreq->profile->max_state; i++) >>>>>> - if (parent_devfreq->profile->freq_table[i] == *freq) >>>>>> + for (i = 0; i < parent_stats->max_state; i++) >>>>>> + if (parent_stats->freq_table[i] == *freq) >>>>>> break; >>>>>> >>>>>> - if (i == parent_devfreq->profile->max_state) { >>>>>> + if (i == parent_stats->max_state) { >>>>>> ret = -EINVAL; >>>>>> goto out; >>>>>> } >>>>>> >>>>>> /* Get the suitable frequency by using index of parent device. */ >>>>>> - if (i < devfreq->profile->max_state) { >>>>>> - child_freq = devfreq->profile->freq_table[i]; >>>>>> + if (i < stats->max_state) { >>>>>> + child_freq = stats->freq_table[i]; >>>>>> } else { >>>>>> - count = devfreq->profile->max_state; >>>>>> - child_freq = devfreq->profile->freq_table[count - 1]; >>>>>> + count = stats->max_state; >>>>>> + child_freq = stats->freq_table[count - 1]; >>>>>> } >>>>>> >>>>>> /* Return the suitable frequency for passive device. */ >>>>>> @@ -109,7 +115,7 @@ static int update_devfreq_passive(struct devfreq *devfreq, unsigned long freq) >>>>>> if (ret < 0) >>>>>> goto out; >>>>>> >>>>>> - if (devfreq->profile->freq_table >>>>>> + if (devfreq->profile->stats >>>>>> && (devfreq_update_status(devfreq, freq))) >>>>>> dev_err(&devfreq->dev, >>>>>> "Couldn't update frequency transition information.\n"); >>>>>> diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h >>>>>> index 4ceb2a517a9c..8459af1a1583 100644 >>>>>> --- a/include/linux/devfreq.h >>>>>> +++ b/include/linux/devfreq.h >>>>>> @@ -64,6 +64,30 @@ struct devfreq_dev_status { >>>>>> */ >>>>>> #define DEVFREQ_FLAG_LEAST_UPPER_BOUND 0x1 >>>>>> >>>>>> +/** >>>>>> + * struct devfreq_stats - Devfreq's transitions stats counters >>>>>> + * @freq_table: Optional list of frequencies to support statistics >>>>>> + * and freq_table must be generated in ascending order. >>>>>> + * @max_state: The size of freq_table. >>>>>> + * @total_trans: Number of devfreq transitions >>>>>> + * @trans_table: Statistics of devfreq transitions >>>>>> + * @time_in_state: Statistics of devfreq states >>>>>> + * @last_time: The last time stats were updated >>>>>> + * @stats_lock: Lock protecting trans_table, time_in_state, >>>>>> + * last_time and total_trans used for statistics >>>>>> + */ >>>>>> +struct devfreq_stats { >>>>>> + unsigned long *freq_table; >>>>>> + unsigned int max_state; >>>>>> + >>>>>> + /* information for device frequency transition */ >>>>>> + unsigned int total_trans; >>>>>> + unsigned int *trans_table; >>>>>> + u64 *time_in_state; >>>>>> + unsigned long long last_time; >>>>>> + spinlock_t stats_lock; >>>>>> +}; >>>>>> + >>>>>> /** >>>>>> * struct devfreq_dev_profile - Devfreq's user device profile >>>>>> * @initial_freq: The operating frequency when devfreq_add_device() is >>>>>> @@ -88,15 +112,7 @@ struct devfreq_dev_status { >>>>>> * from devfreq_remove_device() call. If the user >>>>>> * has registered devfreq->nb at a notifier-head, >>>>>> * this is the time to unregister it. >>>>>> - * @freq_table: Optional list of frequencies to support statistics >>>>>> - * and freq_table must be generated in ascending order. >>>>>> - * @max_state: The size of freq_table. >>>>>> - * @total_trans: Number of devfreq transitions >>>>>> - * @trans_table: Statistics of devfreq transitions >>>>>> - * @time_in_state: Statistics of devfreq states >>>>>> - * @last_time: The last time stats were updated >>>>>> - * @stats_lock: Lock protecting trans_table, time_in_state, >>>>>> - * last_time and total_trans used for statistics >>>>>> + * @stats: Statistics of devfreq states and state transitions >>>>>> */ >>>>>> struct devfreq_dev_profile { >>>>>> unsigned long initial_freq; >>>>>> @@ -108,14 +124,7 @@ struct devfreq_dev_profile { >>>>>> int (*get_cur_freq)(struct device *dev, unsigned long *freq); >>>>>> void (*exit)(struct device *dev); >>>>>> >>>>>> - unsigned long *freq_table; >>>>>> - unsigned int max_state; >>>>>> - /* information for device frequency transition */ >>>>>> - unsigned int total_trans; >>>>>> - unsigned int *trans_table; >>>>>> - u64 *time_in_state; >>>>>> - unsigned long long last_time; >>>>>> - spinlock_t stats_lock; >>>>>> + struct devfreq_stats *stats; >>>>>> }; >>>>>> >>>>>> /** >>>>>> > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > 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=-8.3 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 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 50CF6C43603 for ; Mon, 16 Dec 2019 13:02:18 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1924820726 for ; Mon, 16 Dec 2019 13:02:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="mdlfTLkV" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1924820726 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Content-Type: Content-Transfer-Encoding:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=af6q4eX94+gSafiQ7DXbxkQalpDuh/qkP4SlrWRXqRI=; b=mdlfTLkVrnzseJtd57aUPySX4 xki4suLpvyPBENwt1VZ+imde5JdnBdIT3rgdVqJJuevITW6//i2MO86vHVSNXszE4d7S4w3B1vfIe NhKWzFHp2xEDXlLUiakuTCar1vC8zvI1yJ1QlKpC9oPcPG1dOO4zlNb3y0nkrhp1vpu9cCsX1JnMk Xokx6PhXZ98V8CpCh3tQTfKupSQfR0UG1yZHUaI8N2c3BMoWl26i6SNoFJQj0qYzr/cNaVTUWVpeo lBxI29sDr3Eyvv6ynCnzdgm5kwNfkrjUQD3hcFiYfKHiJ41cPC5Z3mvTKYs89xHCxNPHIECpKbXUz HMRJu6nqA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1igq0r-0007lF-NG; Mon, 16 Dec 2019 13:02:13 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1igq0m-0007kQ-Mx for linux-arm-kernel@lists.infradead.org; Mon, 16 Dec 2019 13:02:11 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2123D1FB; Mon, 16 Dec 2019 05:02:06 -0800 (PST) Received: from [10.37.12.145] (unknown [10.37.12.145]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A80CC3F718; Mon, 16 Dec 2019 05:02:01 -0800 (PST) Subject: Re: Re: [PATCH 7/7] devfreq: move statistics to separate struct To: Bartlomiej Zolnierkiewicz References: <20191113091336.5218-1-k.konieczny@samsung.com> <20191113091336.5218-8-k.konieczny@samsung.com> <4942d2ad-fef7-89be-91c1-c02c319546ff@samsung.com> <38350d81-e916-b386-6727-f4c85689c172@samsung.com> <85a29ce4-0f89-2b50-b046-dba747208933@samsung.com> <4ed6b8bf-b415-c42d-33d6-d2ed0504eaf4@samsung.com> From: Lukasz Luba Message-ID: Date: Mon, 16 Dec 2019 13:01:59 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191216_050208_846413_6D82A44A X-CRM114-Status: GOOD ( 37.49 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: a.hajda@samsung.com, Javi Merino , linux-samsung-soc@vger.kernel.org, linux-pm@vger.kernel.org, Kamil Konieczny , linux-kernel@vger.kernel.org, Krzysztof Kozlowski , Dietmar Eggemann , Eduardo Valentin , Chanwoo Choi , Kyungmin Park , Kukjin Kim , MyungJoo Ham , Zhang Rui , robin.murphy@arm.com, =?UTF-8?Q?=c3=98rjan_Eide?= , linux-arm-kernel@lists.infradead.org, Marek Szyprowski Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgQmFydGVrLAoKW2FkZGVkIERpZXRtYXIsIFJvYmluLCBBbmRyemVqIChmb3IgdXBjb21pbmcg RFJNIGRybS1taXNjLW5leHQpXQoKT24gMTEvMTUvMTkgMTI6NDAgUE0sIEJhcnRsb21pZWogWm9s bmllcmtpZXdpY3ogd3JvdGU6Cj4gCj4gWyBhZGRlZCBaaGFuZywgRWR1YXJkbywgw5hyamFuIGFu ZCBKYXZpIHRvIENjOiBdCj4gCj4gT24gMTEvMTUvMTkgNzoyMSBBTSwgQ2hhbndvbyBDaG9pIHdy b3RlOgo+PiBIaSBCYXJ0bG9taWVqLAo+Pgo+PiBPbiAxMS8xNS8xOSAxMjoyNSBQTSwgQ2hhbndv byBDaG9pIHdyb3RlOgo+Pj4gSGkgQmFydGxvbWllaiwKPj4+Cj4+PiBPbiAxMS8xNS8xOSAzOjAx IEFNLCBCYXJ0bG9taWVqIFpvbG5pZXJraWV3aWN6IHdyb3RlOgo+Pj4+Cj4+Pj4gSGkgQ2hhbndv bywKPj4+Pgo+Pj4+IE9uIDExLzE0LzE5IDI6NTIgQU0sIENoYW53b28gQ2hvaSB3cm90ZToKPj4+ Pj4gSGkgS2FtaWwsCj4+Pj4+Cj4+Pj4+IFRoZSAnZnJlcV90YWJsZScgYW5kICdtYXhfc3RhdGUn IGluIHRoZSBkZXZmcmVxX2Rldl9wcm9maWxlCj4+Pj4+IHdlcmUgdXNlZCBpbiB0aGUgQVJNIE1h bGkgZGV2aWNlIGRyaXZlclsxXVsyXVszXS4gQWx0aG91Z2ggQVJNIE1hbGkKPj4+Pj4gZGV2aWNl IGRyaXZlciB3YXMgcG9zdGVkIHRvIG1haW5saW5lIGtlcm5lbCwgdGhleSB1c2VkCj4+Pj4+IHRo ZW0gZm9yIGEgbG9uZyB0aW1lLiBJdCBtZWFucyB0aGF0IHRoaXMgcGF0Y2ggYnJlYWsKPj4+Pj4g dGhlIGNvbXBhdGliaWxpdHkuIFRoZSBBUk0gTWFsaSBkcml2ZXJzIGFyZSB2ZXJ5Cj4+Pj4+IGlt cG9ydGFudCBkZXZmcmVxIGRldmljZSBkcml2ZXIuCj4+Pj4KPj4+PiBUaGlzIGFyZ3VtZW50IGlz IG5vdCBhIGEgdGVjaG5pY2FsIG9uZSBhbmQgdGhlIG9mZmljaWFsIHVwc3RyZWFtCj4+Pj4ga2Vy bmVsIHBvbGljeSBpcyB0byBub3QgZGVwZW5kIG9uIG91dC1vZi10cmVlIGRyaXZlcnMuCj4+Pj4K Pj4+PiBCZXNpZGVzIHRoZSBBUk0gTWFsaSBkcml2ZXJzIGFyZSBmdWxsIG9mIGNvZGUgbGlrZToK Pj4+Pgo+Pj4+ICNpZiBMSU5VWF9WRVJTSU9OX0NPREUgPj0gS0VSTkVMX1ZFUlNJT04oeCwgeSwg eikKPj4+PiAuLi4KPj4+PiAjZWxzZQo+Pj4+IC4uLgo+Pj4+ICNlbmRpZgo+Pj4+Cj4+Pj4gc28g ZmV3IG1vcmUgaW5zdGFuY2VzIG9mIHNpbWlsYXIgY29kZSB3b24ndCBkbyBhbnkgaGFybS4uIDst KQo+Pj4+Cj4+Pj4+IFsxXSBodHRwczovL3Byb3RlY3QyLmZpcmVleWUuY29tL3VybD9rPTkwOWNh YTVjLWNkNTJhYmU4LTkwOWQyMTEzLTAwMGJhYmRmZWNiYS04MTJmMTY1NzZjMzYxNGEzJnU9aHR0 cHM6Ly9kZXZlbG9wZXIuYXJtLmNvbS90b29scy1hbmQtc29mdHdhcmUvZ3JhcGhpY3MtYW5kLWdh bWluZy9tYWxpLWRyaXZlcnMvYmlmcm9zdC1rZXJuZWwjCj4+Pj4+IFsyXSBodHRwczovL3Byb3Rl Y3QyLmZpcmVleWUuY29tL3VybD9rPTMzMjY1Zjk2LTZlZTg1ZTIyLTMzMjdkNGQ5LTAwMGJhYmRm ZWNiYS00NGMyZGFlYzMyODcxMmU2JnU9aHR0cHM6Ly9kZXZlbG9wZXIuYXJtLmNvbS90b29scy1h bmQtc29mdHdhcmUvZ3JhcGhpY3MtYW5kLWdhbWluZy9tYWxpLWRyaXZlcnMvbWlkZ2FyZC1rZXJu ZWwKPj4+Pj4gWzNdIGh0dHBzOi8vcHJvdGVjdDIuZmlyZWV5ZS5jb20vdXJsP2s9NjliZGNhYjAt MzQ3M2NiMDQtNjliYzQxZmYtMDAwYmFiZGZlY2JhLTRiNTc2ZmFjZjg1ZTAyMDgmdT1odHRwczov L2RldmVsb3Blci5hcm0uY29tL3Rvb2xzLWFuZC1zb2Z0d2FyZS9ncmFwaGljcy1hbmQtZ2FtaW5n L21hbGktZHJpdmVycy91dGdhcmQta2VybmVsCj4+Pj4KPj4+PiBJIHRvb2sgYSBsb29rIGF0IEFS TSBNYWxpIGRyaXZlcnMgc291cmNlIGNvZGUgYW55d2F5IGFuZCBJIGZhaWwgdG8KPj4+PiBzZWUg YSByYXRpb25hbGUgYmVoaW5kIHRoZWlyIGJlaGF2aW9yIG9mIGRvaW5nICdmcmVxX3RhYmxlJyBh bmQKPj4+PiAnbWF4X3N0YXRlJyBpbml0aWFsaXphdGlvbiBpbiB0aGUgZHJpdmVyIGl0c2VsZiAo aW5zdGVhZCBvZiBsZWF2aW5nCj4+Pj4gaXQgdXAgdG8gdGhlIGRldmZyZXEgY29yZSBjb2RlLCBs aWtlIGFsbCBpbi1rZXJuZWwgZHJpdmVycyBhcmUgZG9pbmcKPj4+PiBhbHJlYWR5KS4KPj4+Pgo+ Pj4+IENvdWxkIHlvdSBwbGVhc2UgZXhwbGFpbiByYXRpb25hbGUgYmVoaW5kIEFSTSBNYWxpIGRy aXZlcnMnIHNwZWNpYWwKPj4+PiBuZWVkcz8KPj4+Pgo+Pj4+IFsgQm90aCBBUk0gTWFsaSBhbmQg ZGV2ZnJlcSBjb3JlIGNvZGUgYXJlIHVzaW5nIGdlbmVyaWMgUE0gT1BQIGNvZGUKPj4+PiAgICB0 aGVzZSBkYXlzIHRvIGRvICdmcmVxX3RhYmxlJyBhbmQgJ21heF9zdGF0ZScgaW5pdGlhbGl6YXRp b24sIHRoZQo+Pj4+ICAgIG9ubHkgZGlmZmVyZW5jZSBzZWVtcyB0byBiZSB0aGF0IEFSTSBNYWxp IGNyZWF0ZXMgdGhlIGZyZXF1ZW5jeQo+Pj4+ICAgIHRhYmxlIGluIHRoZSBkZXNjZW5kaW5nIG9y ZGVyIChidXQgdGhlcmUgYWxzbyBzZWVtcyB0byBiZSBubyByZWFsCj4+Pj4gICAgbmVlZCBmb3Ig aXQpLiBdCj4+Pj4KPj4+PiBNYXliZSB0aGlzIGlzIGFuIG9wcG9ydHVuaXR5IHRvIHNpbXBsaWZ5 IGFsc28gdGhlIEFSTSBNYWxpIGRyaXZlcj8KPj4+Cj4+PiBPSy4gSSBhZ3JlZSB0byBzaW1wbGlm eSB0aGVtIG9uIHRoaXMgdGltZS4KPj4+IEZvciB0b3VjaGluZyB0aGUgJ2ZyZXFfdGFibGUnIGFu ZCAnbWF4X3N0YXRlJywgbmVlZCB0byBmaXgKPj4+IHRoZSBkZXNjZW5kaW5nIG9yZGVyIG9mIGZy ZXFfdGFibGUuCj4+Pgo+Pj4gVGhlIHBhcnRpdGlvbl9lbmFibGVfb3BzKCkgaW4gdGhlIGRyaXZl cnMvdGhlcm1hbC9kZXZmcmVxX2Nvb2xpbmcuYwo+Pj4gcmVxdWlyZXMgdGhlIGRlc2NlbmRpbmcg b3JkZXIgb2YgZnJlcV90YWJsZS4gSGF2ZSB0byBjaGFuZ2UgaXQgYnkgdXNpbmcKPj4+IHRoZSBh c2NlbmRpbmcgdGltZSBvciBzdXBwb3J0IGJvdGggYXNjZW5kaW5nIGFuZCBkZXNjZW5kaW5nIG9y ZGVyIGZvciBmcmVxX3RhYmxlLgo+Pj4KPj4+IDEuIE1vdmUgZnJlcV90YWJsZSwgbWF4X3N0YXRl IG9mIGRldmZyZXFfZGV2X3Byb2ZpbGUgdG8gc3RydWN0IGRldmZyZXEKPj4+IDIuIEVkaXQgcGFy dGl0aW9uX2VuYWJsZV9vcHMoKSBpbiB0aGUgZHJpdmVycy90aGVybWFsL2RldmZyZXFfY29vbGlu Zy5jCj4+PiAgICAgYnkgdXNpbmcgYXNjZW5kaW5nIG9yZGVyIGluc3RlYWQgb2YgZGVzY2VuZGlu ZyBvcmRlci4KPj4+Cj4+Cj4+IEFmdGVyIGNoYW5nZWQgYWJvdXQgJ2ZyZXFfdGFibGUnIGFuZCAn bWF4X3N0YXRlJywgdGhlIGJ1aWxkIGVycm9yCj4+IHdpbGwgaGFwcGVuIG9uIEFSTSBtYWlsIGRy aXZlciBiZWNhdXNlIHRoZSBpbml0aWFsaXphdGlvbiBjb2RlIG9mCj4+ICdmcmVxX3RhYmxlJyBp biBBUk0gbWFsaSBkcml2ZXIsIGRpZG4ndCBjaGVjayB0aGUga2VybmVsIHZlcnNpb24uCj4+Cj4+ IFRoZSBmaXJzdCBkZXZmcmVxIHBhdGNoIHByb3ZpZGVkIHRoZSAnZnJlcV90YWJsZScgYXMgb3B0 aW9uYWwgdmFyaWFibGUKPj4gaW4gdGhlICdzdHJ1Y3QgZGV2ZnJlcV9kZXZfcHJvZmlsZScuIEV2 ZW4gaWYgQVJNIG1hbGkgZHJpdmVyIGlzIG91dCBvZiBtYWlubGluZSB0cmVlLAo+PiB0aGlzIGNo YW5nZSBzZWVtcyB0aGF0IGJyZWFrIHRoZSB1c2FnZSBydWxlIG9mICdmcmVxX3RhYmxlJyBpbiAn c3RydWN0IGRldmZyZXFfZGV2X3Byb2ZpbGUnLgo+Pgo+PiBTbywgaWYgdGhlcmUgYXJlIG5vIGFu eSBiZW5lZmljaWFsIHJlYXNvbiwgSSBqdXN0IGtlZXAgdGhlIGN1cnJlbnQgc3RhdHVzIG9mICdm cmVxX3RhYmxlJwo+PiBpbiBvcmRlciB0byBrZWVwIHRoZSBwcmV2aW91cyB1c2FnZSBydWxlIG9m ICdmcmVxX3RhYmxlJyBpbiAnc3RydWN0IGRldmZyZXFfZGV2X3Byb2ZpbGUnLgo+Pgo+PiBGcmFu a2x5LCBJJ20gbm90ZSBzdXJlIHRoYXQgaXQgaXMgbmVjZXNzYXJ5LiBJIGRvbid0IHdhbnQgdG8g bWFrZQo+PiB0aGUgc2lkZS1lZmZlY3Qgd2l0aG91dCBhbnkgdXNlZnVsIHJlYXNvbi4KPj4KPj4g QnV0LAo+PiBTZXBhcmF0ZWx5LCBoYXZlIHRvIGZpeCB0aGUgb3JkZXJpbmcgaXNzdWUgb2YgcGFy dGl0aW9uX2VuYWJsZV9vcHMoKQo+PiBpbiB0aGUgZHJpdmVycy90aGVybWFsL2RldmZyZXFfY29v bGluZy5jLgo+IAo+IEhtbW0uLiBmaXhpbmcgcGFydGl0aW9uX2VuYWJsZV9vcHBzKCkgc2hvdWxk IGJlIHRyaXZpYWwgYnV0IEkgd29uZGVyCj4gd2h5IHdlIGFyZSBjYXJyeWluZyBkZXZmcmVxX2Nv b2xpbmcuYyBjb2RlIGluIHVwc3RyZWFtIGtlcm5lbCBhdCBhbGw/CgpXZWxsLCB0aGUgZGV2ZnJl cV9jb29saW5nLmMgaXMgZ29pbmcgdG8gaGF2ZSBhIGNsaWVudCBpbiBtYWlubGluZToKdGhlIEdQ VSBkcml2ZXIgLSBQYW5mcm9zdC4KCkl0IGlzIGFscmVhZHkgaW4gRFJNIGJyYW5jaCAnZHJtLW1p c2MtbmV4dCc6Cmh0dHBzOi8vcGF0Y2h3b3JrLmZyZWVkZXNrdG9wLm9yZy9wYXRjaC8zNDI4NDgv CgpSZWdhcmRpbmcgdGhlIGRldmZyZXFfY29vbGluZy5jIGNvZGUgc3RydWN0dXJlLgpJIGFtIGN1 cnJlbnRseSB3b3JraW5nIG9uIGNsZWFuaW5nIHVwIHRoZSBkZXZmcmVxIGNvb2xpbmcgY29kZSBh bmQKYWRkaW5nIEVuZXJneSBNb2RlbCBpbnN0ZWFkIGZvciBwcml2YXRlIGZyZXEsIHBvd2VyIHRh Ymxlcy4gSXQgd2lsbCBiZQppbiBzaW1pbGFyIGZhc2hpb24gYXMgaXQgaXMgZG9uZSBpbiBjcHVm cmVxX2Nvb2xpbmcuIFRoZSBtb2RlbCB3aWxsCmJlIGFsc28gc2ltcGxpZmllZCBzbyBob3BlZnVs bHkgbW9yZSBjbGllbnRzIHdvdWxkIGNvbWUuCkl0IGlzIHVuZGVyIGludGVybmFsIHJldmlldyBh bmQgd2lsbCBiZSBwb3N0ZWQgc2hvcnRseS4KCj4gCj4gSXQgaGFzIGJlZW4gbWVyZ2VkIGluIHRo ZSBmb2xsb3dpbmcgY29tbWl0Ogo+IAo+IGNvbW1pdCBhNzZjYWY1NWU1YjM1NmJhMjBhNWE0M2Fj NGQ5ZjdhMDRiMjA5NDFkCj4gQXV0aG9yOiDDmHJqYW4gRWlkZSA8b3JqYW4uZWlkZUBhcm0uY29t Pgo+IERhdGU6ICAgVGh1IFNlcCAxMCAxODowOTozMCAyMDE1ICswMTAwCj4gCj4gICAgICB0aGVy bWFsOiBBZGQgZGV2ZnJlcSBjb29saW5nCj4gICAgICAKPiAgICAgIEFkZCBhIGdlbmVyaWMgdGhl cm1hbCBjb29saW5nIGRldmljZSBmb3IgZGV2ZnJlcSwgdGhhdCBpcyBzaW1pbGFyIHRvCj4gICAg ICBjcHVfY29vbGluZy4KPiAgICAgIAo+ICAgICAgVGhlIGRldmljZSBtdXN0IHVzZSBkZXZmcmVx LiAgSW4gb3JkZXIgdG8gdXNlIHRoZSBwb3dlciBleHRlbnNpb24gb2YgdGhlCj4gICAgICBjb29s aW5nIGRldmljZSwgaXQgbXVzdCBoYXZlIHJlZ2lzdGVyZWQgaXRzIE9QUHMgdXNpbmcgdGhlIE9Q UCBsaWJyYXJ5Lgo+ICAgICAgCj4gICAgICBDYzogWmhhbmcgUnVpIDxydWkuemhhbmdAaW50ZWwu Y29tPgo+ICAgICAgQ2M6IEVkdWFyZG8gVmFsZW50aW4gPGVkdWJlenZhbEBnbWFpbC5jb20+Cj4g ICAgICBTaWduZWQtb2ZmLWJ5OiBKYXZpIE1lcmlubyA8amF2aS5tZXJpbm9AYXJtLmNvbT4KPiAg ICAgIFNpZ25lZC1vZmYtYnk6IMOYcmphbiBFaWRlIDxvcmphbi5laWRlQGFybS5jb20+Cj4gICAg ICBTaWduZWQtb2ZmLWJ5OiBFZHVhcmRvIFZhbGVudGluIDxlZHViZXp2YWxAZ21haWwuY29tPgo+ IC4uLgo+IAo+IGJ1dCA0IHllYXJzIGxhdGVyIHRoZXJlIGlzIHN0aWxsIG5vIHNpbmdsZSBpbi1r ZXJuZWwgdXNlciBmb3IgdGhpcyBjb2RlPwoKVGhlcmUgd2lsbCBiZSwgdmlhIERSTSB0cmVlLgoK UmVnYXJkcywKTHVrYXN6Cgo+IAo+IEJlc3QgcmVnYXJkcywKPiAtLQo+IEJhcnRsb21pZWogWm9s bmllcmtpZXdpY3oKPiBTYW1zdW5nIFImRCBJbnN0aXR1dGUgUG9sYW5kCj4gU2Ftc3VuZyBFbGVj dHJvbmljcwo+IAo+Pj4+Cj4+Pj4+IEFsc28sIHRoZSBkZXZmcmVxIGRldmljZSBkcml2ZXIgc3Bl Y2lmaWVzIHRoZWlyIG93bgo+Pj4+PiBpbmZvcm1hdGlvbiBhbmQgZGF0YSBpbnRvIGRldmZyZXFf ZGV2X3Byb2ZpbGUgc3RydWN0dXJlCj4+Pj4+IGJlZm9yZSByZWdpc3RlcmluZyB0aGUgZGV2ZnJl cSBkZXZpY2Ugd2l0aCBkZXZmcmVxX2FkZF9kZXZpY2UoKS4KPj4+Pj4gVGhpcyBwYXRjaCBicmVh a3MgdGhlIGJhc2ljIHVzYWdlIHJ1bGUgb2YgZGV2ZnJlcV9kZXZfcHJvZmlsZSBzdHJ1Y3R1cmUu Cj4+Pj4KPj4+PiBXZWxsLCAnc3RydWN0IGRldmZyZXFfc3RhdHMgKnN0YXRzJyBjYW4gYmUgdHJp dmlhbGx5IG1vdmVkIG91dCBvZgo+Pj4+ICdzdHJ1Y3QgZGV2ZnJlcV9wcm9maWxlJyB0byAnc3Ry dWN0IGRldmZyZXEnIGlmIHlvdSBwcmVmZXIgaXQgdGhhdAo+Pj4+IHdheS4uCj4+Pj4KPj4+PiBC ZXN0IHJlZ2FyZHMsCj4+Pj4gLS0KPj4+PiBCYXJ0bG9taWVqIFpvbG5pZXJraWV3aWN6Cj4+Pj4g U2Ftc3VuZyBSJkQgSW5zdGl0dXRlIFBvbGFuZAo+Pj4+IFNhbXN1bmcgRWxlY3Ryb25pY3MKPj4+ Pgo+Pj4+PiBTbywgSSBjYW4ndCBhZ3JlZSB0aGlzIHBhdGNoLiBOb3QgYWNrLgo+Pj4+Pgo+Pj4+ PiBSZWdhcmRzLAo+Pj4+PiBDaGFud29vIENob2kKPj4+Pj4KPj4+Pj4gT24gMTEvMTMvMTkgNjox MyBQTSwgS2FtaWwgS29uaWVjem55IHdyb3RlOgo+Pj4+Pj4gQ291bnQgdGltZSBhbmQgdHJhbnNp dGlvbnMgYmV0d2VlbiBkZXZmcmVxIGZyZXF1ZW5jaWVzIGluIHNlcGFyYXRlIHN0cnVjdAo+Pj4+ Pj4gZm9yIGltcHJvdmVkIGNvZGUgcmVhZGFiaWxpdHkgYW5kIG1haW50ZW5hbmNlLgo+Pj4+Pj4K Pj4+Pj4+IFNpZ25lZC1vZmYtYnk6IEthbWlsIEtvbmllY3pueSA8ay5rb25pZWN6bnlAc2Ftc3Vu Zy5jb20+Cj4+Pj4+PiAtLS0KPj4+Pj4+ICAgZHJpdmVycy9kZXZmcmVxL2RldmZyZXEuYyAgICAg ICAgICB8IDE1NiArKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tLQo+Pj4+Pj4gICBkcml2ZXJz L2RldmZyZXEvZXh5bm9zLWJ1cy5jICAgICAgIHwgICA2ICstCj4+Pj4+PiAgIGRyaXZlcnMvZGV2 ZnJlcS9nb3Zlcm5vcl9wYXNzaXZlLmMgfCAgMjYgKysrLS0KPj4+Pj4+ICAgaW5jbHVkZS9saW51 eC9kZXZmcmVxLmggICAgICAgICAgICB8ICA0MyArKysrLS0tLQo+Pj4+Pj4gICA0IGZpbGVzIGNo YW5nZWQsIDEyOSBpbnNlcnRpb25zKCspLCAxMDIgZGVsZXRpb25zKC0pCj4+Pj4+Pgo+Pj4+Pj4g ZGlmZiAtLWdpdCBhL2RyaXZlcnMvZGV2ZnJlcS9kZXZmcmVxLmMgYi9kcml2ZXJzL2RldmZyZXEv ZGV2ZnJlcS5jCj4+Pj4+PiBpbmRleCBkNzk0MTJiMGRlNTkuLmQ4NTg2N2E5MTIzMCAxMDA2NDQK Pj4+Pj4+IC0tLSBhL2RyaXZlcnMvZGV2ZnJlcS9kZXZmcmVxLmMKPj4+Pj4+ICsrKyBiL2RyaXZl cnMvZGV2ZnJlcS9kZXZmcmVxLmMKPj4+Pj4+IEBAIC0xMDUsMTAgKzEwNSwxMSBAQCBzdGF0aWMg dW5zaWduZWQgbG9uZyBmaW5kX2F2YWlsYWJsZV9tYXhfZnJlcShzdHJ1Y3QgZGV2ZnJlcSAqZGV2 ZnJlcSkKPj4+Pj4+ICAgICovCj4+Pj4+PiAgIHN0YXRpYyBpbnQgZGV2ZnJlcV9nZXRfZnJlcV9s ZXZlbChzdHJ1Y3QgZGV2ZnJlcSAqZGV2ZnJlcSwgdW5zaWduZWQgbG9uZyBmcmVxKQo+Pj4+Pj4g ICB7Cj4+Pj4+PiArCXN0cnVjdCBkZXZmcmVxX3N0YXRzICpzdGF0cyA9IGRldmZyZXEtPnByb2Zp bGUtPnN0YXRzOwo+Pj4+Pj4gICAJaW50IGxldjsKPj4+Pj4+ICAgCj4+Pj4+PiAtCWZvciAobGV2 ID0gMDsgbGV2IDwgZGV2ZnJlcS0+cHJvZmlsZS0+bWF4X3N0YXRlOyBsZXYrKykKPj4+Pj4+IC0J CWlmIChmcmVxID09IGRldmZyZXEtPnByb2ZpbGUtPmZyZXFfdGFibGVbbGV2XSkKPj4+Pj4+ICsJ Zm9yIChsZXYgPSAwOyBsZXYgPCBzdGF0cy0+bWF4X3N0YXRlOyBsZXYrKykKPj4+Pj4+ICsJCWlm IChmcmVxID09IHN0YXRzLT5mcmVxX3RhYmxlW2xldl0pCj4+Pj4+PiAgIAkJCXJldHVybiBsZXY7 Cj4+Pj4+PiAgIAo+Pj4+Pj4gICAJcmV0dXJuIC1FSU5WQUw7Cj4+Pj4+PiBAQCAtMTE3LDU2ICsx MTgsNjQgQEAgc3RhdGljIGludCBkZXZmcmVxX2dldF9mcmVxX2xldmVsKHN0cnVjdCBkZXZmcmVx ICpkZXZmcmVxLCB1bnNpZ25lZCBsb25nIGZyZXEpCj4+Pj4+PiAgIHN0YXRpYyBpbnQgc2V0X2Zy ZXFfdGFibGUoc3RydWN0IGRldmZyZXEgKmRldmZyZXEpCj4+Pj4+PiAgIHsKPj4+Pj4+ICAgCXN0 cnVjdCBkZXZmcmVxX2Rldl9wcm9maWxlICpwcm9maWxlID0gZGV2ZnJlcS0+cHJvZmlsZTsKPj4+ Pj4+ICsJc3RydWN0IGRldmZyZXFfc3RhdHMgKnN0YXRzOwo+Pj4+Pj4gICAJc3RydWN0IGRldl9w bV9vcHAgKm9wcDsKPj4+Pj4+ICAgCXVuc2lnbmVkIGxvbmcgZnJlcTsKPj4+Pj4+IC0JaW50IGks IGNvdW50Owo+Pj4+Pj4gKwlpbnQgaSwgY291bnQsIGVyciA9IC1FTk9NRU07Cj4+Pj4+PiAgIAo+ Pj4+Pj4gICAJLyogSW5pdGlhbGl6ZSB0aGUgZnJlcV90YWJsZSBmcm9tIE9QUCB0YWJsZSAqLwo+ Pj4+Pj4gICAJY291bnQgPSBkZXZfcG1fb3BwX2dldF9vcHBfY291bnQoZGV2ZnJlcS0+ZGV2LnBh cmVudCk7Cj4+Pj4+PiAgIAlpZiAoY291bnQgPD0gMCkKPj4+Pj4+ICAgCQlyZXR1cm4gLUVJTlZB TDsKPj4+Pj4+ICAgCj4+Pj4+PiAtCXByb2ZpbGUtPm1heF9zdGF0ZSA9IGNvdW50Owo+Pj4+Pj4g LQlwcm9maWxlLT5mcmVxX3RhYmxlID0gZGV2bV9rY2FsbG9jKGRldmZyZXEtPmRldi5wYXJlbnQs Cj4+Pj4+PiAtCQkJCQljb3VudCwKPj4+Pj4+IC0JCQkJCXNpemVvZigqcHJvZmlsZS0+ZnJlcV90 YWJsZSksCj4+Pj4+PiAtCQkJCQlHRlBfS0VSTkVMKTsKPj4+Pj4+IC0JaWYgKCFwcm9maWxlLT5m cmVxX3RhYmxlKSB7Cj4+Pj4+PiAtCQlwcm9maWxlLT5tYXhfc3RhdGUgPSAwOwo+Pj4+Pj4gKwlz dGF0cyA9IGRldm1fa3phbGxvYyhkZXZmcmVxLT5kZXYucGFyZW50LAo+Pj4+Pj4gKwkJCSAgICAg c2l6ZW9mKHN0cnVjdCBkZXZmcmVxX3N0YXRzKSwgR0ZQX0tFUk5FTCk7Cj4+Pj4+PiArCWlmICgh c3RhdHMpCj4+Pj4+PiAgIAkJcmV0dXJuIC1FTk9NRU07Cj4+Pj4+PiAtCX0KPj4+Pj4+ICAgCj4+ Pj4+PiAtCWZvciAoaSA9IDAsIGZyZXEgPSAwOyBpIDwgcHJvZmlsZS0+bWF4X3N0YXRlOyBpKyss IGZyZXErKykgewo+Pj4+Pj4gKwlwcm9maWxlLT5zdGF0cyA9IHN0YXRzOwo+Pj4+Pj4gKwlzdGF0 cy0+bWF4X3N0YXRlID0gY291bnQ7Cj4+Pj4+PiArCXN0YXRzLT5mcmVxX3RhYmxlID0gZGV2bV9r Y2FsbG9jKGRldmZyZXEtPmRldi5wYXJlbnQsCj4+Pj4+PiArCQkJCQkgY291bnQsCj4+Pj4+PiAr CQkJCQkgc2l6ZW9mKCpzdGF0cy0+ZnJlcV90YWJsZSksCj4+Pj4+PiArCQkJCQkgR0ZQX0tFUk5F TCk7Cj4+Pj4+PiArCWlmICghc3RhdHMtPmZyZXFfdGFibGUpCj4+Pj4+PiArCQlnb3RvIGVycl9u b19tZW07Cj4+Pj4+PiArCj4+Pj4+PiArCWZvciAoaSA9IDAsIGZyZXEgPSAwOyBpIDwgY291bnQ7 IGkrKywgZnJlcSsrKSB7Cj4+Pj4+PiAgIAkJb3BwID0gZGV2X3BtX29wcF9maW5kX2ZyZXFfY2Vp bChkZXZmcmVxLT5kZXYucGFyZW50LCAmZnJlcSk7Cj4+Pj4+PiAgIAkJaWYgKElTX0VSUihvcHAp KSB7Cj4+Pj4+PiAtCQkJZGV2bV9rZnJlZShkZXZmcmVxLT5kZXYucGFyZW50LCBwcm9maWxlLT5m cmVxX3RhYmxlKTsKPj4+Pj4+IC0JCQlwcm9maWxlLT5tYXhfc3RhdGUgPSAwOwo+Pj4+Pj4gLQkJ CXJldHVybiBQVFJfRVJSKG9wcCk7Cj4+Pj4+PiArCQkJZGV2bV9rZnJlZShkZXZmcmVxLT5kZXYu cGFyZW50LCBzdGF0cy0+ZnJlcV90YWJsZSk7Cj4+Pj4+PiArCQkJc3RhdHMtPm1heF9zdGF0ZSA9 IDA7Cj4+Pj4+PiArCQkJZXJyID0gUFRSX0VSUihvcHApOwo+Pj4+Pj4gKwkJCWdvdG8gZXJyX25v X21lbTsKPj4+Pj4+ICAgCQl9Cj4+Pj4+PiAgIAkJZGV2X3BtX29wcF9wdXQob3BwKTsKPj4+Pj4+ IC0JCXByb2ZpbGUtPmZyZXFfdGFibGVbaV0gPSBmcmVxOwo+Pj4+Pj4gKwkJc3RhdHMtPmZyZXFf dGFibGVbaV0gPSBmcmVxOwo+Pj4+Pj4gICAJfQo+Pj4+Pj4gICAKPj4+Pj4+IC0JcHJvZmlsZS0+ dHJhbnNfdGFibGUgPSBkZXZtX2t6YWxsb2MoZGV2ZnJlcS0+ZGV2LnBhcmVudCwKPj4+Pj4+IC0J CQkJCSAgICBhcnJheTNfc2l6ZShzaXplb2YodW5zaWduZWQgaW50KSwKPj4+Pj4+IC0JCQkJCQkJ Y291bnQsIGNvdW50KSwKPj4+Pj4+IC0JCQkJCSAgICBHRlBfS0VSTkVMKTsKPj4+Pj4+IC0JaWYg KCFwcm9maWxlLT50cmFuc190YWJsZSkKPj4+Pj4+ICsJc3RhdHMtPnRyYW5zX3RhYmxlID0gZGV2 bV9remFsbG9jKGRldmZyZXEtPmRldi5wYXJlbnQsCj4+Pj4+PiArCQkJCQkgIGFycmF5M19zaXpl KHNpemVvZih1bnNpZ25lZCBpbnQpLAo+Pj4+Pj4gKwkJCQkJCSAgICAgIGNvdW50LCBjb3VudCks Cj4+Pj4+PiArCQkJCQkgIEdGUF9LRVJORUwpOwo+Pj4+Pj4gKwlpZiAoIXN0YXRzLT50cmFuc190 YWJsZSkKPj4+Pj4+ICAgCQlnb3RvIGVycl9ub19tZW07Cj4+Pj4+PiAgIAo+Pj4+Pj4gLQlwcm9m aWxlLT50aW1lX2luX3N0YXRlID0gZGV2bV9rY2FsbG9jKGRldmZyZXEtPmRldi5wYXJlbnQsIGNv dW50LAo+Pj4+Pj4gLQkJCQkJICAgICAgc2l6ZW9mKCpwcm9maWxlLT50aW1lX2luX3N0YXRlKSwK Pj4+Pj4+IC0JCQkJCSAgICAgIEdGUF9LRVJORUwpOwo+Pj4+Pj4gLQlpZiAoIXByb2ZpbGUtPnRp bWVfaW5fc3RhdGUpCj4+Pj4+PiArCXN0YXRzLT50aW1lX2luX3N0YXRlID0gZGV2bV9rY2FsbG9j KGRldmZyZXEtPmRldi5wYXJlbnQsIGNvdW50LAo+Pj4+Pj4gKwkJCQkJICAgIHNpemVvZigqc3Rh dHMtPnRpbWVfaW5fc3RhdGUpLAo+Pj4+Pj4gKwkJCQkJICAgIEdGUF9LRVJORUwpOwo+Pj4+Pj4g KwlpZiAoIXN0YXRzLT50aW1lX2luX3N0YXRlKQo+Pj4+Pj4gICAJCWdvdG8gZXJyX25vX21lbTsK Pj4+Pj4+ICAgCj4+Pj4+PiAtCXByb2ZpbGUtPmxhc3RfdGltZSA9IGdldF9qaWZmaWVzXzY0KCk7 Cj4+Pj4+PiAtCXNwaW5fbG9ja19pbml0KCZwcm9maWxlLT5zdGF0c19sb2NrKTsKPj4+Pj4+ICsJ c3RhdHMtPmxhc3RfdGltZSA9IGdldF9qaWZmaWVzXzY0KCk7Cj4+Pj4+PiArCXNwaW5fbG9ja19p bml0KCZzdGF0cy0+c3RhdHNfbG9jayk7Cj4+Pj4+PiAgIAo+Pj4+Pj4gICAJcmV0dXJuIDA7Cj4+ Pj4+PiAgIGVycl9ub19tZW06Cj4+Pj4+PiAtCXByb2ZpbGUtPm1heF9zdGF0ZSA9IDA7Cj4+Pj4+ PiAtCXJldHVybiAtRU5PTUVNOwo+Pj4+Pj4gKwlzdGF0cy0+bWF4X3N0YXRlID0gMDsKPj4+Pj4+ ICsJZGV2bV9rZnJlZShkZXZmcmVxLT5kZXYucGFyZW50LCBwcm9maWxlLT5zdGF0cyk7Cj4+Pj4+ PiArCXByb2ZpbGUtPnN0YXRzID0gTlVMTDsKPj4+Pj4+ICsJcmV0dXJuIGVycjsKPj4+Pj4+ICAg fQo+Pj4+Pj4gICAKPj4+Pj4+ICAgLyoqCj4+Pj4+PiBAQCAtMTc2LDcgKzE4NSw3IEBAIHN0YXRp YyBpbnQgc2V0X2ZyZXFfdGFibGUoc3RydWN0IGRldmZyZXEgKmRldmZyZXEpCj4+Pj4+PiAgICAq Lwo+Pj4+Pj4gICBpbnQgZGV2ZnJlcV91cGRhdGVfc3RhdHVzKHN0cnVjdCBkZXZmcmVxICpkZXZm cmVxLCB1bnNpZ25lZCBsb25nIGZyZXEpCj4+Pj4+PiAgIHsKPj4+Pj4+IC0Jc3RydWN0IGRldmZy ZXFfZGV2X3Byb2ZpbGUgKnByb2ZpbGUgPSBkZXZmcmVxLT5wcm9maWxlOwo+Pj4+Pj4gKwlzdHJ1 Y3QgZGV2ZnJlcV9zdGF0cyAqc3RhdHMgPSBkZXZmcmVxLT5wcm9maWxlLT5zdGF0czsKPj4+Pj4+ ICAgCXVuc2lnbmVkIGxvbmcgbG9uZyBjdXJfdGltZTsKPj4+Pj4+ICAgCWludCBsZXYsIHByZXZf bGV2LCByZXQgPSAwOwo+Pj4+Pj4gICAKPj4+Pj4+IEBAIC0xODQsMjIgKzE5MywyMSBAQCBpbnQg ZGV2ZnJlcV91cGRhdGVfc3RhdHVzKHN0cnVjdCBkZXZmcmVxICpkZXZmcmVxLCB1bnNpZ25lZCBs b25nIGZyZXEpCj4+Pj4+PiAgIAo+Pj4+Pj4gICAJLyogSW1tZWRpYXRlbHkgZXhpdCBpZiBwcmV2 aW91c19mcmVxIGlzIG5vdCBpbml0aWFsaXplZCB5ZXQuICovCj4+Pj4+PiAgIAlpZiAoIWRldmZy ZXEtPnByZXZpb3VzX2ZyZXEpIHsKPj4+Pj4+IC0JCXNwaW5fbG9jaygmcHJvZmlsZS0+c3RhdHNf bG9jayk7Cj4+Pj4+PiAtCQlwcm9maWxlLT5sYXN0X3RpbWUgPSBjdXJfdGltZTsKPj4+Pj4+IC0J CXNwaW5fdW5sb2NrKCZwcm9maWxlLT5zdGF0c19sb2NrKTsKPj4+Pj4+ICsJCXNwaW5fbG9jaygm c3RhdHMtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwkJc3RhdHMtPmxhc3RfdGltZSA9IGN1cl90aW1l Owo+Pj4+Pj4gKwkJc3Bpbl91bmxvY2soJnN0YXRzLT5zdGF0c19sb2NrKTsKPj4+Pj4+ICAgCQly ZXR1cm4gMDsKPj4+Pj4+ICAgCX0KPj4+Pj4+ICAgCj4+Pj4+PiAgIAlwcmV2X2xldiA9IGRldmZy ZXFfZ2V0X2ZyZXFfbGV2ZWwoZGV2ZnJlcSwgZGV2ZnJlcS0+cHJldmlvdXNfZnJlcSk7Cj4+Pj4+ PiAgIAo+Pj4+Pj4gLQlzcGluX2xvY2soJnByb2ZpbGUtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwlz cGluX2xvY2soJnN0YXRzLT5zdGF0c19sb2NrKTsKPj4+Pj4+ICAgCWlmIChwcmV2X2xldiA8IDAp IHsKPj4+Pj4+ICAgCQlyZXQgPSBwcmV2X2xldjsKPj4+Pj4+ICAgCQlnb3RvIG91dDsKPj4+Pj4+ ICAgCX0KPj4+Pj4+ICAgCj4+Pj4+PiAtCXByb2ZpbGUtPnRpbWVfaW5fc3RhdGVbcHJldl9sZXZd ICs9Cj4+Pj4+PiAtCQkJIGN1cl90aW1lIC0gcHJvZmlsZS0+bGFzdF90aW1lOwo+Pj4+Pj4gKwlz dGF0cy0+dGltZV9pbl9zdGF0ZVtwcmV2X2xldl0gKz0gY3VyX3RpbWUgLSBzdGF0cy0+bGFzdF90 aW1lOwo+Pj4+Pj4gICAJbGV2ID0gZGV2ZnJlcV9nZXRfZnJlcV9sZXZlbChkZXZmcmVxLCBmcmVx KTsKPj4+Pj4+ICAgCWlmIChsZXYgPCAwKSB7Cj4+Pj4+PiAgIAkJcmV0ID0gbGV2Owo+Pj4+Pj4g QEAgLTIwNywxNCArMjE1LDE0IEBAIGludCBkZXZmcmVxX3VwZGF0ZV9zdGF0dXMoc3RydWN0IGRl dmZyZXEgKmRldmZyZXEsIHVuc2lnbmVkIGxvbmcgZnJlcSkKPj4+Pj4+ICAgCX0KPj4+Pj4+ICAg Cj4+Pj4+PiAgIAlpZiAobGV2ICE9IHByZXZfbGV2KSB7Cj4+Pj4+PiAtCQlwcm9maWxlLT50cmFu c190YWJsZVsocHJldl9sZXYgKgo+Pj4+Pj4gLQkJCQlwcm9maWxlLT5tYXhfc3RhdGUpICsgbGV2 XSsrOwo+Pj4+Pj4gLQkJcHJvZmlsZS0+dG90YWxfdHJhbnMrKzsKPj4+Pj4+ICsJCXN0YXRzLT50 cmFuc190YWJsZVsocHJldl9sZXYgKgo+Pj4+Pj4gKwkJCQlzdGF0cy0+bWF4X3N0YXRlKSArIGxl dl0rKzsKPj4+Pj4+ICsJCXN0YXRzLT50b3RhbF90cmFucysrOwo+Pj4+Pj4gICAJfQo+Pj4+Pj4g ICAKPj4+Pj4+ICAgb3V0Ogo+Pj4+Pj4gLQlwcm9maWxlLT5sYXN0X3RpbWUgPSBjdXJfdGltZTsK Pj4+Pj4+IC0Jc3Bpbl91bmxvY2soJnByb2ZpbGUtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwlzdGF0 cy0+bGFzdF90aW1lID0gY3VyX3RpbWU7Cj4+Pj4+PiArCXNwaW5fdW5sb2NrKCZzdGF0cy0+c3Rh dHNfbG9jayk7Cj4+Pj4+PiAgIAlyZXR1cm4gcmV0Owo+Pj4+Pj4gICB9Cj4+Pj4+PiAgIEVYUE9S VF9TWU1CT0woZGV2ZnJlcV91cGRhdGVfc3RhdHVzKTsKPj4+Pj4+IEBAIC01MDQsOSArNTEyLDkg QEAgdm9pZCBkZXZmcmVxX21vbml0b3JfcmVzdW1lKHN0cnVjdCBkZXZmcmVxICpkZXZmcmVxKQo+ Pj4+Pj4gICAJCXF1ZXVlX2RlbGF5ZWRfd29yayhkZXZmcmVxX3dxLCAmZGV2ZnJlcS0+d29yaywK Pj4+Pj4+ICAgCQkJbXNlY3NfdG9famlmZmllcyhwcm9maWxlLT5wb2xsaW5nX21zKSk7Cj4+Pj4+ PiAgIAo+Pj4+Pj4gLQlzcGluX2xvY2soJnByb2ZpbGUtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gLQlw cm9maWxlLT5sYXN0X3RpbWUgPSBnZXRfamlmZmllc182NCgpOwo+Pj4+Pj4gLQlzcGluX3VubG9j aygmcHJvZmlsZS0+c3RhdHNfbG9jayk7Cj4+Pj4+PiArCXNwaW5fbG9jaygmcHJvZmlsZS0+c3Rh dHMtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwlwcm9maWxlLT5zdGF0cy0+bGFzdF90aW1lID0gZ2V0 X2ppZmZpZXNfNjQoKTsKPj4+Pj4+ICsJc3Bpbl91bmxvY2soJnByb2ZpbGUtPnN0YXRzLT5zdGF0 c19sb2NrKTsKPj4+Pj4+ICAgCWRldmZyZXEtPnN0b3BfcG9sbGluZyA9IGZhbHNlOwo+Pj4+Pj4g ICAKPj4+Pj4+ICAgCWlmIChwcm9maWxlLT5nZXRfY3VyX2ZyZXEgJiYKPj4+Pj4+IEBAIC02Nzcs NyArNjg1LDcgQEAgc3RydWN0IGRldmZyZXEgKmRldmZyZXFfYWRkX2RldmljZShzdHJ1Y3QgZGV2 aWNlICpkZXYsCj4+Pj4+PiAgIAlkZXZmcmVxLT5kYXRhID0gZGF0YTsKPj4+Pj4+ICAgCWRldmZy ZXEtPm5iLm5vdGlmaWVyX2NhbGwgPSBkZXZmcmVxX25vdGlmaWVyX2NhbGw7Cj4+Pj4+PiAgIAo+ Pj4+Pj4gLQlpZiAoIXByb2ZpbGUtPm1heF9zdGF0ZSAmJiAhcHJvZmlsZS0+ZnJlcV90YWJsZSkg ewo+Pj4+Pj4gKwlpZiAoIXByb2ZpbGUtPnN0YXRzKSB7Cj4+Pj4+PiAgIAkJbXV0ZXhfdW5sb2Nr KCZkZXZmcmVxLT5sb2NrKTsKPj4+Pj4+ICAgCQllcnIgPSBzZXRfZnJlcV90YWJsZShkZXZmcmVx KTsKPj4+Pj4+ICAgCQlpZiAoZXJyIDwgMCkKPj4+Pj4+IEBAIC0xMjgyLDYgKzEyOTAsNyBAQCBz dGF0aWMgc3NpemVfdCBtaW5fZnJlcV9zdG9yZShzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBk ZXZpY2VfYXR0cmlidXRlICphdHRyLAo+Pj4+Pj4gICAJCQkgICAgICBjb25zdCBjaGFyICpidWYs IHNpemVfdCBjb3VudCkKPj4+Pj4+ICAgewo+Pj4+Pj4gICAJc3RydWN0IGRldmZyZXEgKmRmID0g dG9fZGV2ZnJlcShkZXYpOwo+Pj4+Pj4gKwlzdHJ1Y3QgZGV2ZnJlcV9zdGF0cyAqc3RhdHMgPSBk Zi0+cHJvZmlsZS0+c3RhdHM7Cj4+Pj4+PiAgIAl1bnNpZ25lZCBsb25nIHZhbHVlOwo+Pj4+Pj4g ICAJaW50IHJldDsKPj4+Pj4+ICAgCj4+Pj4+PiBAQCAtMTI5NywxMyArMTMwNiwxMyBAQCBzdGF0 aWMgc3NpemVfdCBtaW5fZnJlcV9zdG9yZShzdHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZp Y2VfYXR0cmlidXRlICphdHRyLAo+Pj4+Pj4gICAJCQlnb3RvIHVubG9jazsKPj4+Pj4+ICAgCQl9 Cj4+Pj4+PiAgIAl9IGVsc2Ugewo+Pj4+Pj4gLQkJdW5zaWduZWQgbG9uZyAqZnJlcV90YWJsZSA9 IGRmLT5wcm9maWxlLT5mcmVxX3RhYmxlOwo+Pj4+Pj4gKwkJdW5zaWduZWQgbG9uZyAqZnJlcV90 YWJsZSA9IHN0YXRzLT5mcmVxX3RhYmxlOwo+Pj4+Pj4gICAKPj4+Pj4+ICAgCQkvKiBHZXQgbWlu aW11bSBmcmVxdWVuY3kgYWNjb3JkaW5nIHRvIHNvcnRpbmcgb3JkZXIgKi8KPj4+Pj4+IC0JCWlm IChmcmVxX3RhYmxlWzBdIDwgZnJlcV90YWJsZVtkZi0+cHJvZmlsZS0+bWF4X3N0YXRlIC0gMV0p Cj4+Pj4+PiArCQlpZiAoZnJlcV90YWJsZVswXSA8IGZyZXFfdGFibGVbc3RhdHMtPm1heF9zdGF0 ZSAtIDFdKQo+Pj4+Pj4gICAJCQl2YWx1ZSA9IGZyZXFfdGFibGVbMF07Cj4+Pj4+PiAgIAkJZWxz ZQo+Pj4+Pj4gLQkJCXZhbHVlID0gZnJlcV90YWJsZVtkZi0+cHJvZmlsZS0+bWF4X3N0YXRlIC0g MV07Cj4+Pj4+PiArCQkJdmFsdWUgPSBmcmVxX3RhYmxlW3N0YXRzLT5tYXhfc3RhdGUgLSAxXTsK Pj4+Pj4+ICAgCX0KPj4+Pj4+ICAgCj4+Pj4+PiAgIAlkZi0+bWluX2ZyZXEgPSB2YWx1ZTsKPj4+ Pj4+IEBAIC0xMzI2LDYgKzEzMzUsNyBAQCBzdGF0aWMgc3NpemVfdCBtYXhfZnJlcV9zdG9yZShz dHJ1Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+Pj4+Pj4g ICAJCQkgICAgICBjb25zdCBjaGFyICpidWYsIHNpemVfdCBjb3VudCkKPj4+Pj4+ICAgewo+Pj4+ Pj4gICAJc3RydWN0IGRldmZyZXEgKmRmID0gdG9fZGV2ZnJlcShkZXYpOwo+Pj4+Pj4gKwlzdHJ1 Y3QgZGV2ZnJlcV9zdGF0cyAqc3RhdHMgPSBkZi0+cHJvZmlsZS0+c3RhdHM7Cj4+Pj4+PiAgIAl1 bnNpZ25lZCBsb25nIHZhbHVlOwo+Pj4+Pj4gICAJaW50IHJldDsKPj4+Pj4+ICAgCj4+Pj4+PiBA QCAtMTM0MSwxMSArMTM1MSwxMSBAQCBzdGF0aWMgc3NpemVfdCBtYXhfZnJlcV9zdG9yZShzdHJ1 Y3QgZGV2aWNlICpkZXYsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLAo+Pj4+Pj4gICAJ CQlnb3RvIHVubG9jazsKPj4+Pj4+ICAgCQl9Cj4+Pj4+PiAgIAl9IGVsc2Ugewo+Pj4+Pj4gLQkJ dW5zaWduZWQgbG9uZyAqZnJlcV90YWJsZSA9IGRmLT5wcm9maWxlLT5mcmVxX3RhYmxlOwo+Pj4+ Pj4gKwkJdW5zaWduZWQgbG9uZyAqZnJlcV90YWJsZSA9IHN0YXRzLT5mcmVxX3RhYmxlOwo+Pj4+ Pj4gICAKPj4+Pj4+ICAgCQkvKiBHZXQgbWF4aW11bSBmcmVxdWVuY3kgYWNjb3JkaW5nIHRvIHNv cnRpbmcgb3JkZXIgKi8KPj4+Pj4+IC0JCWlmIChmcmVxX3RhYmxlWzBdIDwgZnJlcV90YWJsZVtk Zi0+cHJvZmlsZS0+bWF4X3N0YXRlIC0gMV0pCj4+Pj4+PiAtCQkJdmFsdWUgPSBmcmVxX3RhYmxl W2RmLT5wcm9maWxlLT5tYXhfc3RhdGUgLSAxXTsKPj4+Pj4+ICsJCWlmIChmcmVxX3RhYmxlWzBd IDwgZnJlcV90YWJsZVtzdGF0cy0+bWF4X3N0YXRlIC0gMV0pCj4+Pj4+PiArCQkJdmFsdWUgPSBm cmVxX3RhYmxlW3N0YXRzLT5tYXhfc3RhdGUgLSAxXTsKPj4+Pj4+ICAgCQllbHNlCj4+Pj4+PiAg IAkJCXZhbHVlID0gZnJlcV90YWJsZVswXTsKPj4+Pj4+ICAgCX0KPj4+Pj4+IEBAIC0xMzczLDE0 ICsxMzgzLDE1IEBAIHN0YXRpYyBzc2l6ZV90IGF2YWlsYWJsZV9mcmVxdWVuY2llc19zaG93KHN0 cnVjdCBkZXZpY2UgKmQsCj4+Pj4+PiAgIAkJCQkJICBjaGFyICpidWYpCj4+Pj4+PiAgIHsKPj4+ Pj4+ICAgCXN0cnVjdCBkZXZmcmVxICpkZiA9IHRvX2RldmZyZXEoZCk7Cj4+Pj4+PiArCXN0cnVj dCBkZXZmcmVxX3N0YXRzICpzdGF0cyA9IGRmLT5wcm9maWxlLT5zdGF0czsKPj4+Pj4+ICAgCXNz aXplX3QgY291bnQgPSAwOwo+Pj4+Pj4gICAJaW50IGk7Cj4+Pj4+PiAgIAo+Pj4+Pj4gICAJbXV0 ZXhfbG9jaygmZGYtPmxvY2spOwo+Pj4+Pj4gICAKPj4+Pj4+IC0JZm9yIChpID0gMDsgaSA8IGRm LT5wcm9maWxlLT5tYXhfc3RhdGU7IGkrKykKPj4+Pj4+ICsJZm9yIChpID0gMDsgaSA8IHN0YXRz LT5tYXhfc3RhdGU7IGkrKykKPj4+Pj4+ICAgCQljb3VudCArPSBzY25wcmludGYoJmJ1Zltjb3Vu dF0sIChQQUdFX1NJWkUgLSBjb3VudCAtIDIpLAo+Pj4+Pj4gLQkJCQkiJWx1ICIsIGRmLT5wcm9m aWxlLT5mcmVxX3RhYmxlW2ldKTsKPj4+Pj4+ICsJCQkJIiVsdSAiLCBzdGF0cy0+ZnJlcV90YWJs ZVtpXSk7Cj4+Pj4+PiAgIAo+Pj4+Pj4gICAJbXV0ZXhfdW5sb2NrKCZkZi0+bG9jayk7Cj4+Pj4+ PiAgIAkvKiBUcnVuY2F0ZSB0aGUgdHJhaWxpbmcgc3BhY2UgKi8KPj4+Pj4+IEBAIC0xMzk4LDkg KzE0MDksMTAgQEAgc3RhdGljIHNzaXplX3QgdHJhbnNfc3RhdF9zaG93KHN0cnVjdCBkZXZpY2Ug KmRldiwKPj4+Pj4+ICAgewo+Pj4+Pj4gICAJc3RydWN0IGRldmZyZXEgKmRldmZyZXEgPSB0b19k ZXZmcmVxKGRldik7Cj4+Pj4+PiAgIAlzdHJ1Y3QgZGV2ZnJlcV9kZXZfcHJvZmlsZSAqcHJvZmls ZSA9IGRldmZyZXEtPnByb2ZpbGU7Cj4+Pj4+PiArCXN0cnVjdCBkZXZmcmVxX3N0YXRzICpzdGF0 cyA9IHByb2ZpbGUtPnN0YXRzOwo+Pj4+Pj4gKwl1bnNpZ25lZCBpbnQgbWF4X3N0YXRlID0gc3Rh dHMtPm1heF9zdGF0ZTsKPj4+Pj4+ICAgCXNzaXplX3QgbGVuOwo+Pj4+Pj4gICAJaW50IGksIGo7 Cj4+Pj4+PiAtCXVuc2lnbmVkIGludCBtYXhfc3RhdGUgPSBwcm9maWxlLT5tYXhfc3RhdGU7Cj4+ Pj4+PiAgIAo+Pj4+Pj4gICAJaWYgKCFkZXZmcmVxLT5zdG9wX3BvbGxpbmcgJiYKPj4+Pj4+ICAg CQkJZGV2ZnJlcV91cGRhdGVfc3RhdHVzKGRldmZyZXEsIGRldmZyZXEtPnByZXZpb3VzX2ZyZXEp KQo+Pj4+Pj4gQEAgLTE0MTEsNDUgKzE0MjMsNDUgQEAgc3RhdGljIHNzaXplX3QgdHJhbnNfc3Rh dF9zaG93KHN0cnVjdCBkZXZpY2UgKmRldiwKPj4+Pj4+ICAgCWxlbiA9IHNwcmludGYoYnVmLCAi ICAgICBGcm9tICA6ICAgVG9cbiIpOwo+Pj4+Pj4gICAJbGVuICs9IHNwcmludGYoYnVmICsgbGVu LCAiICAgICAgICAgICA6Iik7Cj4+Pj4+PiAgIAo+Pj4+Pj4gLQlzcGluX2xvY2soJnByb2ZpbGUt PnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwlzcGluX2xvY2soJnN0YXRzLT5zdGF0c19sb2NrKTsKPj4+ Pj4+ICAgCWZvciAoaSA9IDA7IGkgPCBtYXhfc3RhdGU7IGkrKykKPj4+Pj4+ICAgCQlsZW4gKz0g c3ByaW50ZihidWYgKyBsZW4sICIlMTBsdSIsCj4+Pj4+PiAtCQkJCXByb2ZpbGUtPmZyZXFfdGFi bGVbaV0pOwo+Pj4+Pj4gKwkJCQlzdGF0cy0+ZnJlcV90YWJsZVtpXSk7Cj4+Pj4+PiAgIAo+Pj4+ Pj4gICAJbGVuICs9IHNwcmludGYoYnVmICsgbGVuLCAiICAgdGltZShtcylcbiIpOwo+Pj4+Pj4g ICAKPj4+Pj4+ICAgCWZvciAoaSA9IDA7IGkgPCBtYXhfc3RhdGU7IGkrKykgewo+Pj4+Pj4gLQkJ aWYgKHByb2ZpbGUtPmZyZXFfdGFibGVbaV0gPT0gZGV2ZnJlcS0+cHJldmlvdXNfZnJlcSkKPj4+ Pj4+ICsJCWlmIChzdGF0cy0+ZnJlcV90YWJsZVtpXSA9PSBkZXZmcmVxLT5wcmV2aW91c19mcmVx KQo+Pj4+Pj4gICAJCQlsZW4gKz0gc3ByaW50ZihidWYgKyBsZW4sICIqIik7Cj4+Pj4+PiAgIAkJ ZWxzZQo+Pj4+Pj4gICAJCQlsZW4gKz0gc3ByaW50ZihidWYgKyBsZW4sICIgIik7Cj4+Pj4+PiAg IAo+Pj4+Pj4gICAJCWxlbiArPSBzcHJpbnRmKGJ1ZiArIGxlbiwgIiUxMGx1OiIsCj4+Pj4+PiAt CQkJCXByb2ZpbGUtPmZyZXFfdGFibGVbaV0pOwo+Pj4+Pj4gKwkJCQlzdGF0cy0+ZnJlcV90YWJs ZVtpXSk7Cj4+Pj4+PiAgIAkJZm9yIChqID0gMDsgaiA8IG1heF9zdGF0ZTsgaisrKQo+Pj4+Pj4g ICAJCQlsZW4gKz0gc3ByaW50ZihidWYgKyBsZW4sICIlMTB1IiwKPj4+Pj4+IC0JCQkJcHJvZmls ZS0+dHJhbnNfdGFibGVbKGkgKiBtYXhfc3RhdGUpICsgal0pOwo+Pj4+Pj4gKwkJCQlzdGF0cy0+ dHJhbnNfdGFibGVbKGkgKiBtYXhfc3RhdGUpICsgal0pOwo+Pj4+Pj4gICAJCWxlbiArPSBzcHJp bnRmKGJ1ZiArIGxlbiwgIiUxMGxsdVxuIiwgKHU2NCkKPj4+Pj4+IC0JCQlqaWZmaWVzNjRfdG9f bXNlY3MocHJvZmlsZS0+dGltZV9pbl9zdGF0ZVtpXSkpOwo+Pj4+Pj4gKwkJCWppZmZpZXM2NF90 b19tc2VjcyhzdGF0cy0+dGltZV9pbl9zdGF0ZVtpXSkpOwo+Pj4+Pj4gICAJfQo+Pj4+Pj4gICAK Pj4+Pj4+ICAgCWxlbiArPSBzcHJpbnRmKGJ1ZiArIGxlbiwgIlRvdGFsIHRyYW5zaXRpb24gOiAl dVxuIiwKPj4+Pj4+IC0JCQkJCXByb2ZpbGUtPnRvdGFsX3RyYW5zKTsKPj4+Pj4+IC0Jc3Bpbl91 bmxvY2soJnByb2ZpbGUtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwkJCQkJc3RhdHMtPnRvdGFsX3Ry YW5zKTsKPj4+Pj4+ICsJc3Bpbl91bmxvY2soJnN0YXRzLT5zdGF0c19sb2NrKTsKPj4+Pj4+ICAg CXJldHVybiBsZW47Cj4+Pj4+PiAgIH0KPj4+Pj4+ICAgc3RhdGljIERFVklDRV9BVFRSX1JPKHRy YW5zX3N0YXQpOwo+Pj4+Pj4gICAKPj4+Pj4+IC1zdGF0aWMgdm9pZCBkZWZ2cmVxX3N0YXRzX2Ns ZWFyX3RhYmxlKHN0cnVjdCBkZXZmcmVxX2Rldl9wcm9maWxlICpwcm9maWxlKQo+Pj4+Pj4gK3N0 YXRpYyB2b2lkIGRlZnZyZXFfc3RhdHNfY2xlYXJfdGFibGUoc3RydWN0IGRldmZyZXFfc3RhdHMg KnN0YXRzKQo+Pj4+Pj4gICB7Cj4+Pj4+PiAtCXVuc2lnbmVkIGludCBjb3VudCA9IHByb2ZpbGUt Pm1heF9zdGF0ZTsKPj4+Pj4+IC0KPj4+Pj4+IC0Jc3Bpbl9sb2NrKCZwcm9maWxlLT5zdGF0c19s b2NrKTsKPj4+Pj4+IC0JbWVtc2V0KHByb2ZpbGUtPnRpbWVfaW5fc3RhdGUsIDAsIGNvdW50ICog c2l6ZW9mKHU2NCkpOwo+Pj4+Pj4gLQltZW1zZXQocHJvZmlsZS0+dHJhbnNfdGFibGUsIDAsIGNv dW50ICogY291bnQgKiBzaXplb2YoaW50KSk7Cj4+Pj4+PiAtCXByb2ZpbGUtPmxhc3RfdGltZSA9 IGdldF9qaWZmaWVzXzY0KCk7Cj4+Pj4+PiAtCXByb2ZpbGUtPnRvdGFsX3RyYW5zID0gMDsKPj4+ Pj4+IC0Jc3Bpbl91bmxvY2soJnByb2ZpbGUtPnN0YXRzX2xvY2spOwo+Pj4+Pj4gKwl1bnNpZ25l ZCBpbnQgY291bnQgPSBzdGF0cy0+bWF4X3N0YXRlOwo+Pj4+Pj4gKwo+Pj4+Pj4gKwlzcGluX2xv Y2soJnN0YXRzLT5zdGF0c19sb2NrKTsKPj4+Pj4+ICsJbWVtc2V0KHN0YXRzLT50aW1lX2luX3N0 YXRlLCAwLCBjb3VudCAqIHNpemVvZih1NjQpKTsKPj4+Pj4+ICsJbWVtc2V0KHN0YXRzLT50cmFu c190YWJsZSwgMCwgY291bnQgKiBjb3VudCAqIHNpemVvZihpbnQpKTsKPj4+Pj4+ICsJc3RhdHMt Pmxhc3RfdGltZSA9IGdldF9qaWZmaWVzXzY0KCk7Cj4+Pj4+PiArCXN0YXRzLT50b3RhbF90cmFu cyA9IDA7Cj4+Pj4+PiArCXNwaW5fdW5sb2NrKCZzdGF0cy0+c3RhdHNfbG9jayk7Cj4+Pj4+PiAg IH0KPj4+Pj4+ICAgCj4+Pj4+PiAgIHN0YXRpYyBzc2l6ZV90IHRyYW5zX3Jlc2V0X3N0b3JlKHN0 cnVjdCBkZXZpY2UgKmRldiwKPj4+Pj4+IEBAIC0xNDU5LDcgKzE0NzEsNyBAQCBzdGF0aWMgc3Np emVfdCB0cmFuc19yZXNldF9zdG9yZShzdHJ1Y3QgZGV2aWNlICpkZXYsCj4+Pj4+PiAgIHsKPj4+ Pj4+ICAgCXN0cnVjdCBkZXZmcmVxICpkZXZmcmVxID0gdG9fZGV2ZnJlcShkZXYpOwo+Pj4+Pj4g ICAKPj4+Pj4+IC0JZGVmdnJlcV9zdGF0c19jbGVhcl90YWJsZShkZXZmcmVxLT5wcm9maWxlKTsK Pj4+Pj4+ICsJZGVmdnJlcV9zdGF0c19jbGVhcl90YWJsZShkZXZmcmVxLT5wcm9maWxlLT5zdGF0 cyk7Cj4+Pj4+PiAgIAo+Pj4+Pj4gICAJcmV0dXJuIGNvdW50Owo+Pj4+Pj4gICB9Cj4+Pj4+PiBk aWZmIC0tZ2l0IGEvZHJpdmVycy9kZXZmcmVxL2V4eW5vcy1idXMuYyBiL2RyaXZlcnMvZGV2ZnJl cS9leHlub3MtYnVzLmMKPj4+Pj4+IGluZGV4IGQ5ZjM3NzkxMmMxMC4uYjIxMmFhZTJiYjNlIDEw MDY0NAo+Pj4+Pj4gLS0tIGEvZHJpdmVycy9kZXZmcmVxL2V4eW5vcy1idXMuYwo+Pj4+Pj4gKysr IGIvZHJpdmVycy9kZXZmcmVxL2V4eW5vcy1idXMuYwo+Pj4+Pj4gQEAgLTQ5Niw5ICs0OTYsOSBA QCBzdGF0aWMgaW50IGV4eW5vc19idXNfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRl dikKPj4+Pj4+ICAgCX0KPj4+Pj4+ICAgCj4+Pj4+PiAgIG91dDoKPj4+Pj4+IC0JbWF4X3N0YXRl ID0gYnVzLT5kZXZmcmVxLT5wcm9maWxlLT5tYXhfc3RhdGU7Cj4+Pj4+PiAtCW1pbl9mcmVxID0g KGJ1cy0+ZGV2ZnJlcS0+cHJvZmlsZS0+ZnJlcV90YWJsZVswXSAvIDEwMDApOwo+Pj4+Pj4gLQlt YXhfZnJlcSA9IChidXMtPmRldmZyZXEtPnByb2ZpbGUtPmZyZXFfdGFibGVbbWF4X3N0YXRlIC0g MV0gLyAxMDAwKTsKPj4+Pj4+ICsJbWF4X3N0YXRlID0gcHJvZmlsZS0+c3RhdHMtPm1heF9zdGF0 ZTsKPj4+Pj4+ICsJbWluX2ZyZXEgPSAocHJvZmlsZS0+c3RhdHMtPmZyZXFfdGFibGVbMF0gLyAx MDAwKTsKPj4+Pj4+ICsJbWF4X2ZyZXEgPSAocHJvZmlsZS0+c3RhdHMtPmZyZXFfdGFibGVbbWF4 X3N0YXRlIC0gMV0gLyAxMDAwKTsKPj4+Pj4+ICAgCXByX2luZm8oImV4eW5vcy1idXM6IG5ldyBi dXMgZGV2aWNlIHJlZ2lzdGVyZWQ6ICVzICglNmxkIEtIeiB+ICU2bGQgS0h6KVxuIiwKPj4+Pj4+ ICAgCQkJZGV2X25hbWUoZGV2KSwgbWluX2ZyZXEsIG1heF9mcmVxKTsKPj4+Pj4+ICAgCj4+Pj4+ PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9kZXZmcmVxL2dvdmVybm9yX3Bhc3NpdmUuYyBiL2RyaXZl cnMvZGV2ZnJlcS9nb3Zlcm5vcl9wYXNzaXZlLmMKPj4+Pj4+IGluZGV4IDU4MzA4OTQ4Yjg2My4u YjJkODdhODgzMzVjIDEwMDY0NAo+Pj4+Pj4gLS0tIGEvZHJpdmVycy9kZXZmcmVxL2dvdmVybm9y X3Bhc3NpdmUuYwo+Pj4+Pj4gKysrIGIvZHJpdmVycy9kZXZmcmVxL2dvdmVybm9yX3Bhc3NpdmUu Ywo+Pj4+Pj4gQEAgLTE4LDYgKzE4LDggQEAgc3RhdGljIGludCBkZXZmcmVxX3Bhc3NpdmVfZ2V0 X3RhcmdldF9mcmVxKHN0cnVjdCBkZXZmcmVxICpkZXZmcmVxLAo+Pj4+Pj4gICAJc3RydWN0IGRl dmZyZXFfcGFzc2l2ZV9kYXRhICpwX2RhdGEKPj4+Pj4+ICAgCQkJPSAoc3RydWN0IGRldmZyZXFf cGFzc2l2ZV9kYXRhICopZGV2ZnJlcS0+ZGF0YTsKPj4+Pj4+ICAgCXN0cnVjdCBkZXZmcmVxICpw YXJlbnRfZGV2ZnJlcSA9IChzdHJ1Y3QgZGV2ZnJlcSAqKXBfZGF0YS0+cGFyZW50Owo+Pj4+Pj4g KwlzdHJ1Y3QgZGV2ZnJlcV9zdGF0cyAqcGFyZW50X3N0YXRzID0gcGFyZW50X2RldmZyZXEtPnBy b2ZpbGUtPnN0YXRzOwo+Pj4+Pj4gKwlzdHJ1Y3QgZGV2ZnJlcV9zdGF0cyAqc3RhdHM7Cj4+Pj4+ PiAgIAl1bnNpZ25lZCBsb25nIGNoaWxkX2ZyZXEgPSBVTE9OR19NQVg7Cj4+Pj4+PiAgIAlzdHJ1 Y3QgZGV2X3BtX29wcCAqb3BwOwo+Pj4+Pj4gICAJaW50IGksIGNvdW50LCByZXQgPSAwOwo+Pj4+ Pj4gQEAgLTQ3LDEwICs0OSwxNCBAQCBzdGF0aWMgaW50IGRldmZyZXFfcGFzc2l2ZV9nZXRfdGFy Z2V0X2ZyZXEoc3RydWN0IGRldmZyZXEgKmRldmZyZXEsCj4+Pj4+PiAgIAkgKiBkZXZpY2UuIEFu ZCB0aGVuIHRoZSBpbmRleCBpcyB1c2VkIGZvciBnZXR0aW5nIHRoZSBzdWl0YWJsZQo+Pj4+Pj4g ICAJICogbmV3IGZyZXF1ZW5jeSBmb3IgcGFzc2l2ZSBkZXZmcmVxIGRldmljZS4KPj4+Pj4+ICAg CSAqLwo+Pj4+Pj4gLQlpZiAoIWRldmZyZXEtPnByb2ZpbGUgfHwgIWRldmZyZXEtPnByb2ZpbGUt PmZyZXFfdGFibGUKPj4+Pj4+IC0JCXx8IGRldmZyZXEtPnByb2ZpbGUtPm1heF9zdGF0ZSA8PSAw KQo+Pj4+Pj4gKwlpZiAoIWRldmZyZXEtPnByb2ZpbGUgfHwgIWRldmZyZXEtPnByb2ZpbGUtPnN0 YXRzIHx8Cj4+Pj4+PiArCSAgICBkZXZmcmVxLT5wcm9maWxlLT5zdGF0cy0+bWF4X3N0YXRlIDw9 IDAgfHwKPj4+Pj4+ICsJICAgICFwYXJlbnRfZGV2ZnJlcS0+cHJvZmlsZSB8fAkhcGFyZW50X2Rl dmZyZXEtPnByb2ZpbGUtPnN0YXRzIHx8Cj4+Pj4+PiArCSAgICBwYXJlbnRfZGV2ZnJlcS0+cHJv ZmlsZS0+c3RhdHMtPm1heF9zdGF0ZSA8PSAwKQo+Pj4+Pj4gICAJCXJldHVybiAtRUlOVkFMOwo+ Pj4+Pj4gICAKPj4+Pj4+ICsJc3RhdHMgPSBkZXZmcmVxLT5wcm9maWxlLT5zdGF0czsKPj4+Pj4+ ICsJcGFyZW50X3N0YXRzID0gcGFyZW50X2RldmZyZXEtPnByb2ZpbGUtPnN0YXRzOwo+Pj4+Pj4g ICAJLyoKPj4+Pj4+ICAgCSAqIFRoZSBwYXNzaXZlIGdvdmVybm9yIGhhdmUgdG8gZ2V0IHRoZSBj b3JyZWN0IGZyZXF1ZW5jeSBmcm9tIE9QUAo+Pj4+Pj4gICAJICogbGlzdCBvZiBwYXJlbnQgZGV2 aWNlLiBCZWNhdXNlIGluIHRoaXMgY2FzZSwgKmZyZXEgaXMgdGVtcG9yYXJ5Cj4+Pj4+PiBAQCAt NjgsMjEgKzc0LDIxIEBAIHN0YXRpYyBpbnQgZGV2ZnJlcV9wYXNzaXZlX2dldF90YXJnZXRfZnJl cShzdHJ1Y3QgZGV2ZnJlcSAqZGV2ZnJlcSwKPj4+Pj4+ICAgCSAqIEdldCB0aGUgT1BQIHRhYmxl J3MgaW5kZXggb2YgZGVjaWRlZCBmcmVxZXVuY3kgYnkgZ292ZXJub3IKPj4+Pj4+ICAgCSAqIG9m IHBhcmVudCBkZXZpY2UuCj4+Pj4+PiAgIAkgKi8KPj4+Pj4+IC0JZm9yIChpID0gMDsgaSA8IHBh cmVudF9kZXZmcmVxLT5wcm9maWxlLT5tYXhfc3RhdGU7IGkrKykKPj4+Pj4+IC0JCWlmIChwYXJl bnRfZGV2ZnJlcS0+cHJvZmlsZS0+ZnJlcV90YWJsZVtpXSA9PSAqZnJlcSkKPj4+Pj4+ICsJZm9y IChpID0gMDsgaSA8IHBhcmVudF9zdGF0cy0+bWF4X3N0YXRlOyBpKyspCj4+Pj4+PiArCQlpZiAo cGFyZW50X3N0YXRzLT5mcmVxX3RhYmxlW2ldID09ICpmcmVxKQo+Pj4+Pj4gICAJCQlicmVhazsK Pj4+Pj4+ICAgCj4+Pj4+PiAtCWlmIChpID09IHBhcmVudF9kZXZmcmVxLT5wcm9maWxlLT5tYXhf c3RhdGUpIHsKPj4+Pj4+ICsJaWYgKGkgPT0gcGFyZW50X3N0YXRzLT5tYXhfc3RhdGUpIHsKPj4+ Pj4+ICAgCQlyZXQgPSAtRUlOVkFMOwo+Pj4+Pj4gICAJCWdvdG8gb3V0Owo+Pj4+Pj4gICAJfQo+ Pj4+Pj4gICAKPj4+Pj4+ICAgCS8qIEdldCB0aGUgc3VpdGFibGUgZnJlcXVlbmN5IGJ5IHVzaW5n IGluZGV4IG9mIHBhcmVudCBkZXZpY2UuICovCj4+Pj4+PiAtCWlmIChpIDwgZGV2ZnJlcS0+cHJv ZmlsZS0+bWF4X3N0YXRlKSB7Cj4+Pj4+PiAtCQljaGlsZF9mcmVxID0gZGV2ZnJlcS0+cHJvZmls ZS0+ZnJlcV90YWJsZVtpXTsKPj4+Pj4+ICsJaWYgKGkgPCBzdGF0cy0+bWF4X3N0YXRlKSB7Cj4+ Pj4+PiArCQljaGlsZF9mcmVxID0gc3RhdHMtPmZyZXFfdGFibGVbaV07Cj4+Pj4+PiAgIAl9IGVs c2Ugewo+Pj4+Pj4gLQkJY291bnQgPSBkZXZmcmVxLT5wcm9maWxlLT5tYXhfc3RhdGU7Cj4+Pj4+ PiAtCQljaGlsZF9mcmVxID0gZGV2ZnJlcS0+cHJvZmlsZS0+ZnJlcV90YWJsZVtjb3VudCAtIDFd Owo+Pj4+Pj4gKwkJY291bnQgPSBzdGF0cy0+bWF4X3N0YXRlOwo+Pj4+Pj4gKwkJY2hpbGRfZnJl cSA9IHN0YXRzLT5mcmVxX3RhYmxlW2NvdW50IC0gMV07Cj4+Pj4+PiAgIAl9Cj4+Pj4+PiAgIAo+ Pj4+Pj4gICAJLyogUmV0dXJuIHRoZSBzdWl0YWJsZSBmcmVxdWVuY3kgZm9yIHBhc3NpdmUgZGV2 aWNlLiAqLwo+Pj4+Pj4gQEAgLTEwOSw3ICsxMTUsNyBAQCBzdGF0aWMgaW50IHVwZGF0ZV9kZXZm cmVxX3Bhc3NpdmUoc3RydWN0IGRldmZyZXEgKmRldmZyZXEsIHVuc2lnbmVkIGxvbmcgZnJlcSkK Pj4+Pj4+ICAgCWlmIChyZXQgPCAwKQo+Pj4+Pj4gICAJCWdvdG8gb3V0Owo+Pj4+Pj4gICAKPj4+ Pj4+IC0JaWYgKGRldmZyZXEtPnByb2ZpbGUtPmZyZXFfdGFibGUKPj4+Pj4+ICsJaWYgKGRldmZy ZXEtPnByb2ZpbGUtPnN0YXRzCj4+Pj4+PiAgIAkJJiYgKGRldmZyZXFfdXBkYXRlX3N0YXR1cyhk ZXZmcmVxLCBmcmVxKSkpCj4+Pj4+PiAgIAkJZGV2X2VycigmZGV2ZnJlcS0+ZGV2LAo+Pj4+Pj4g ICAJCQkiQ291bGRuJ3QgdXBkYXRlIGZyZXF1ZW5jeSB0cmFuc2l0aW9uIGluZm9ybWF0aW9uLlxu Iik7Cj4+Pj4+PiBkaWZmIC0tZ2l0IGEvaW5jbHVkZS9saW51eC9kZXZmcmVxLmggYi9pbmNsdWRl L2xpbnV4L2RldmZyZXEuaAo+Pj4+Pj4gaW5kZXggNGNlYjJhNTE3YTljLi44NDU5YWYxYTE1ODMg MTAwNjQ0Cj4+Pj4+PiAtLS0gYS9pbmNsdWRlL2xpbnV4L2RldmZyZXEuaAo+Pj4+Pj4gKysrIGIv aW5jbHVkZS9saW51eC9kZXZmcmVxLmgKPj4+Pj4+IEBAIC02NCw2ICs2NCwzMCBAQCBzdHJ1Y3Qg ZGV2ZnJlcV9kZXZfc3RhdHVzIHsKPj4+Pj4+ICAgICovCj4+Pj4+PiAgICNkZWZpbmUgREVWRlJF UV9GTEFHX0xFQVNUX1VQUEVSX0JPVU5ECQkweDEKPj4+Pj4+ICAgCj4+Pj4+PiArLyoqCj4+Pj4+ PiArICogc3RydWN0IGRldmZyZXFfc3RhdHMgLSBEZXZmcmVxJ3MgdHJhbnNpdGlvbnMgc3RhdHMg Y291bnRlcnMKPj4+Pj4+ICsgKiBAZnJlcV90YWJsZToJCU9wdGlvbmFsIGxpc3Qgb2YgZnJlcXVl bmNpZXMgdG8gc3VwcG9ydCBzdGF0aXN0aWNzCj4+Pj4+PiArICoJCQlhbmQgZnJlcV90YWJsZSBt dXN0IGJlIGdlbmVyYXRlZCBpbiBhc2NlbmRpbmcgb3JkZXIuCj4+Pj4+PiArICogQG1heF9zdGF0 ZToJCVRoZSBzaXplIG9mIGZyZXFfdGFibGUuCj4+Pj4+PiArICogQHRvdGFsX3RyYW5zOglOdW1i ZXIgb2YgZGV2ZnJlcSB0cmFuc2l0aW9ucwo+Pj4+Pj4gKyAqIEB0cmFuc190YWJsZToJU3RhdGlz dGljcyBvZiBkZXZmcmVxIHRyYW5zaXRpb25zCj4+Pj4+PiArICogQHRpbWVfaW5fc3RhdGU6CVN0 YXRpc3RpY3Mgb2YgZGV2ZnJlcSBzdGF0ZXMKPj4+Pj4+ICsgKiBAbGFzdF90aW1lOgkJVGhlIGxh c3QgdGltZSBzdGF0cyB3ZXJlIHVwZGF0ZWQKPj4+Pj4+ICsgKiBAc3RhdHNfbG9jazoJCUxvY2sg cHJvdGVjdGluZyB0cmFuc190YWJsZSwgdGltZV9pbl9zdGF0ZSwKPj4+Pj4+ICsgKgkJCWxhc3Rf dGltZSBhbmQgdG90YWxfdHJhbnMgdXNlZCBmb3Igc3RhdGlzdGljcwo+Pj4+Pj4gKyAqLwo+Pj4+ Pj4gK3N0cnVjdCBkZXZmcmVxX3N0YXRzIHsKPj4+Pj4+ICsJdW5zaWduZWQgbG9uZyAqZnJlcV90 YWJsZTsKPj4+Pj4+ICsJdW5zaWduZWQgaW50IG1heF9zdGF0ZTsKPj4+Pj4+ICsKPj4+Pj4+ICsJ LyogaW5mb3JtYXRpb24gZm9yIGRldmljZSBmcmVxdWVuY3kgdHJhbnNpdGlvbiAqLwo+Pj4+Pj4g Kwl1bnNpZ25lZCBpbnQgdG90YWxfdHJhbnM7Cj4+Pj4+PiArCXVuc2lnbmVkIGludCAqdHJhbnNf dGFibGU7Cj4+Pj4+PiArCXU2NCAqdGltZV9pbl9zdGF0ZTsKPj4+Pj4+ICsJdW5zaWduZWQgbG9u ZyBsb25nIGxhc3RfdGltZTsKPj4+Pj4+ICsJc3BpbmxvY2tfdCBzdGF0c19sb2NrOwo+Pj4+Pj4g K307Cj4+Pj4+PiArCj4+Pj4+PiAgIC8qKgo+Pj4+Pj4gICAgKiBzdHJ1Y3QgZGV2ZnJlcV9kZXZf cHJvZmlsZSAtIERldmZyZXEncyB1c2VyIGRldmljZSBwcm9maWxlCj4+Pj4+PiAgICAqIEBpbml0 aWFsX2ZyZXE6CVRoZSBvcGVyYXRpbmcgZnJlcXVlbmN5IHdoZW4gZGV2ZnJlcV9hZGRfZGV2aWNl KCkgaXMKPj4+Pj4+IEBAIC04OCwxNSArMTEyLDcgQEAgc3RydWN0IGRldmZyZXFfZGV2X3N0YXR1 cyB7Cj4+Pj4+PiAgICAqCQkJZnJvbSBkZXZmcmVxX3JlbW92ZV9kZXZpY2UoKSBjYWxsLiBJZiB0 aGUgdXNlcgo+Pj4+Pj4gICAgKgkJCWhhcyByZWdpc3RlcmVkIGRldmZyZXEtPm5iIGF0IGEgbm90 aWZpZXItaGVhZCwKPj4+Pj4+ICAgICoJCQl0aGlzIGlzIHRoZSB0aW1lIHRvIHVucmVnaXN0ZXIg aXQuCj4+Pj4+PiAtICogQGZyZXFfdGFibGU6CQlPcHRpb25hbCBsaXN0IG9mIGZyZXF1ZW5jaWVz IHRvIHN1cHBvcnQgc3RhdGlzdGljcwo+Pj4+Pj4gLSAqCQkJYW5kIGZyZXFfdGFibGUgbXVzdCBi ZSBnZW5lcmF0ZWQgaW4gYXNjZW5kaW5nIG9yZGVyLgo+Pj4+Pj4gLSAqIEBtYXhfc3RhdGU6CQlU aGUgc2l6ZSBvZiBmcmVxX3RhYmxlLgo+Pj4+Pj4gLSAqIEB0b3RhbF90cmFuczoJTnVtYmVyIG9m IGRldmZyZXEgdHJhbnNpdGlvbnMKPj4+Pj4+IC0gKiBAdHJhbnNfdGFibGU6CVN0YXRpc3RpY3Mg b2YgZGV2ZnJlcSB0cmFuc2l0aW9ucwo+Pj4+Pj4gLSAqIEB0aW1lX2luX3N0YXRlOglTdGF0aXN0 aWNzIG9mIGRldmZyZXEgc3RhdGVzCj4+Pj4+PiAtICogQGxhc3RfdGltZToJCVRoZSBsYXN0IHRp bWUgc3RhdHMgd2VyZSB1cGRhdGVkCj4+Pj4+PiAtICogQHN0YXRzX2xvY2s6CQlMb2NrIHByb3Rl Y3RpbmcgdHJhbnNfdGFibGUsIHRpbWVfaW5fc3RhdGUsCj4+Pj4+PiAtICoJCQlsYXN0X3RpbWUg YW5kIHRvdGFsX3RyYW5zIHVzZWQgZm9yIHN0YXRpc3RpY3MKPj4+Pj4+ICsgKiBAc3RhdHM6CQlT dGF0aXN0aWNzIG9mIGRldmZyZXEgc3RhdGVzIGFuZCBzdGF0ZSB0cmFuc2l0aW9ucwo+Pj4+Pj4g ICAgKi8KPj4+Pj4+ICAgc3RydWN0IGRldmZyZXFfZGV2X3Byb2ZpbGUgewo+Pj4+Pj4gICAJdW5z aWduZWQgbG9uZyBpbml0aWFsX2ZyZXE7Cj4+Pj4+PiBAQCAtMTA4LDE0ICsxMjQsNyBAQCBzdHJ1 Y3QgZGV2ZnJlcV9kZXZfcHJvZmlsZSB7Cj4+Pj4+PiAgIAlpbnQgKCpnZXRfY3VyX2ZyZXEpKHN0 cnVjdCBkZXZpY2UgKmRldiwgdW5zaWduZWQgbG9uZyAqZnJlcSk7Cj4+Pj4+PiAgIAl2b2lkICgq ZXhpdCkoc3RydWN0IGRldmljZSAqZGV2KTsKPj4+Pj4+ICAgCj4+Pj4+PiAtCXVuc2lnbmVkIGxv bmcgKmZyZXFfdGFibGU7Cj4+Pj4+PiAtCXVuc2lnbmVkIGludCBtYXhfc3RhdGU7Cj4+Pj4+PiAt CS8qIGluZm9ybWF0aW9uIGZvciBkZXZpY2UgZnJlcXVlbmN5IHRyYW5zaXRpb24gKi8KPj4+Pj4+ IC0JdW5zaWduZWQgaW50IHRvdGFsX3RyYW5zOwo+Pj4+Pj4gLQl1bnNpZ25lZCBpbnQgKnRyYW5z X3RhYmxlOwo+Pj4+Pj4gLQl1NjQgKnRpbWVfaW5fc3RhdGU7Cj4+Pj4+PiAtCXVuc2lnbmVkIGxv bmcgbG9uZyBsYXN0X3RpbWU7Cj4+Pj4+PiAtCXNwaW5sb2NrX3Qgc3RhdHNfbG9jazsKPj4+Pj4+ ICsJc3RydWN0IGRldmZyZXFfc3RhdHMgKnN0YXRzOwo+Pj4+Pj4gICB9Owo+Pj4+Pj4gICAKPj4+ Pj4+ICAgLyoqCj4+Pj4+Pgo+IAo+IF9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fCj4gbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKPiBsaW51eC1hcm0t a2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmcKPiBodHRwOi8vbGlzdHMuaW5mcmFkZWFkLm9yZy9t YWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwKPiAKCl9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCmxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0 CmxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZwpodHRwOi8vbGlzdHMuaW5mcmFk ZWFkLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2xpbnV4LWFybS1rZXJuZWwK