* Re: [PATCH v2 0/4] Make PL031 interrupt optional
From: Alexandre Belloni @ 2017-10-12 15:07 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Alessandro Zummo, linux-rtc, Linus Walleij, linux-arm-kernel
In-Reply-To: <20170929102116.GX20805@n2100.armlinux.org.uk>
On 29/09/2017 at 11:21:16 +0100, Russell King - ARM Linux wrote:
> There are some boards out there which have a PL031 RTC, but its
> interrupt is not wired up. To support these, we need the PL031
> to support the primecell without interrupts.
>
> When no interrupt is present, there's little point exposing the
> RTC's alarm capabilities, so we omit the alarm-related function
> calls - the RTC merely becomes a source of time-of-day.
>
> This patch series cleans up the pl031 driver a little, and adds
> support for this configuration.
>
> drivers/rtc/rtc-pl031.c | 48 +++++++++++++++++++++++++++---------------------
> 1 file changed, 27 insertions(+), 21 deletions(-)
>
> v2: update patch 2 & 3 for review comment on v1.
>
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH] rtc: rv3029: Clean up error handling in rv3029_eeprom_write()
From: Alexandre Belloni @ 2017-10-12 14:40 UTC (permalink / raw)
To: Dan Carpenter; +Cc: Alessandro Zummo, linux-rtc, kernel-janitors
In-Reply-To: <20170920214530.jusyjbnvkopsumrr@mwanda>
On 21/09/2017 at 00:45:30 +0300, Dan Carpenter wrote:
> We don't need both "ret" and "err" when they do the same thing. All the
> functions called here return zero on success or negative error codes.
> It's more clear to return a literal zero at the end instead of
> "return ret;"
>
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: Guenter Roeck @ 2017-10-12 14:12 UTC (permalink / raw)
To: 刘稳
Cc: Alexandre Belloni, a.zummo, linux-rtc, linux-kernel,
linux-watchdog
In-Reply-To: <33912070.da58.15f10d0b307.Coremail.18502523564@163.com>
On 10/12/2017 06:40 AM, 刘稳 wrote:
>
>
>
>
>
>
>
>
>
>
> At 2017-10-10 23:05:14, "Guenter Roeck" <linux@roeck-us.net> wrote:
>> On Tue, Oct 10, 2017 at 03:51:34PM +0200, Alexandre Belloni wrote:
>>> On 10/10/2017 at 06:41:15 -0700, Guenter Roeck wrote:
>>>> On 10/10/2017 06:12 AM, winton.liu wrote:
>>>>> When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
>>>>> in suspend mode, watchdog is still working but no daemon
>>>>> patting the watchdog. The system will reboot if timeout.
>>>>>
>>>>> Add support suspend/resume for watchdog.
>>>>> suspend: disable the watchdog
>>>>> resume: disable existing watchdog, reload watchdog timer, enable watchdog
>>>>>
>>>>> Signed-off-by: winton.liu <18502523564@163.com>
>>>>> ---
>>>>> drivers/rtc/rtc-ds1374.c | 31 +++++++++++++++++++++++++++++++
>>>>> 1 file changed, 31 insertions(+)
>>>>>
>>>>> diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
>>>>> index 38a2e9e..642e31d 100644
>>>>> --- a/drivers/rtc/rtc-ds1374.c
>>>>> +++ b/drivers/rtc/rtc-ds1374.c
>>>>> @@ -437,6 +437,29 @@ static void ds1374_wdt_ping(void)
>>>>> pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
>>>>> }
>>>>> +static void ds1374_wdt_resume(void)
>>>>> +{
>>>>> + int ret = -ENOIOCTLCMD;
>>>>
>>>> Useless initialization (yes, I can see that this is widely done in the driver,
>>>> but that doesn't make it better).
>>>>
> Yes, I think this is useless. The original ds1374_wdt_disable has the same issue.
That doesn't make it better and is not an argument.
>>>>> + int cr;
>>>>> +
>>>>> + cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
>>>>> +
>>>>> + /* Disable any existing watchdog/alarm before setting the new one */
>>>>> + cr &= ~DS1374_REG_CR_WACE;
>>>>> +
>>>>> + i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
>>>>> +
>>>>> + /* Reload watchdog timer */
>>>>> + ds1374_wdt_ping();
>>>>> +
>>>>> + /* Enable watchdog timer */
>>>>> + cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM;
>>>>> + cr &= ~DS1374_REG_CR_AIE;
>>>>> +
>>>>> + ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
>>>>> +
>>>> Extra empty line. Also, returns void, so what is the point of assigning
>>>> the result to ret ?
>>>>
>>>>> +}
>>>>
>>>> Unless I am missing something, this unconditionally starts the watchdog
>>>> at resume time. So if it was not running before, it will be started anyway,
>>>> and the system will reboot since there will be no ping.
>>>>
> This driver starts watchdog by default. In probe watchdog starts:
> #ifdef CONFIG_RTC_DRV_DS1374_WDT
> save_client = client;
> ret = misc_register(&ds1374_miscdev);
> if (ret)
> return ret;
> ret = register_reboot_notifier(&ds1374_wdt_notifier);
> if (ret) {
> misc_deregister(&ds1374_miscdev);
> return ret;
> }
> ds1374_wdt_settimeout(131072); //Here starts watchdog
Meaning the system will reboot unless the watchdog device is opened ?
Weird, and conceptually wrong.
What if the watchdog device is stopped explicitly by the watchdog demon ?
> #endif
> And userspace watchdogd will ping.
>>>
>>> Also, I'm still not convinced this is the right thing to do. I have seen
>>> many systems were it was desirable to let the watchdog run while the
>>> system is suspended. It ensures it will either wake up or reboot. If you
>>> don't want that, why not disabling the watchdog from userspace before
>>> going to suspend?
>>>
>>
>> Usually watchdog drivers supporting suspend/resume do handle it this way.
>> Maybe that depends on the HW. Expecting user space to do it makes it
>> even more racy than it already is, since there is no watchdog protection
>> after it has been disabled, so I am not sure if that is really better.
>> Does anyone happen to know if/how systemd and watchdogd are handling
>> this situation ?
>>
>>>> I assume it is guaranteed that the chip doesn't forget the previously
>>>> configured timeout on resume.
>>>>
>>>> Overall the driver would really benefit from a conversion to the watchdog
>>>> subsystem.
>>>>
>>>
>>> That is the point of https://www.spinics.net/lists/linux-watchdog/msg12095.html
>>
>> Ah, yes, and I even provided feedback. Hope I didn't miss an updated
>> version of that patch. Either case, seems to me we should wait for that
>> patch to make it in before accepting any further changes to the driver.
>>
> Is this multi function patch has any update ? If not, could my patch be acceptable before moving to watchdog subsystem.(I could update a new patch for your suggestion)?
> Because current kernel using ds1374 for watchdog. If the device need suspend, there will be a reboot issue.
>
Only if CONFIG_RTC_DRV_DS1374_WDT is enabled, and then it appears the driver
has other problems such as unconditionally enabling the watchdog.
Given that, I am not in favor of temporary changes.
Guenter
^ permalink raw reply
* Re:Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: 刘稳 @ 2017-10-12 13:40 UTC (permalink / raw)
To: Guenter Roeck
Cc: Alexandre Belloni, a.zummo, linux-rtc, linux-kernel,
linux-watchdog
In-Reply-To: <20171010150514.GB1879@roeck-us.net>
CgoKCgoKCgoKCkF0IDIwMTctMTAtMTAgMjM6MDU6MTQsICJHdWVudGVyIFJvZWNrIiA8bGludXhA
cm9lY2stdXMubmV0PiB3cm90ZToKPk9uIFR1ZSwgT2N0IDEwLCAyMDE3IGF0IDAzOjUxOjM0UE0g
KzAyMDAsIEFsZXhhbmRyZSBCZWxsb25pIHdyb3RlOgo+PiBPbiAxMC8xMC8yMDE3IGF0IDA2OjQx
OjE1IC0wNzAwLCBHdWVudGVyIFJvZWNrIHdyb3RlOgo+PiA+IE9uIDEwLzEwLzIwMTcgMDY6MTIg
QU0sIHdpbnRvbi5saXUgd3JvdGU6Cj4+ID4gPiBXaGVuIGVuYWJsZSBDT05GSUdfUlRDX0RSVl9E
UzEzNzRfV0RUIHVzZSBhcyB3YXRjaGRvZywKPj4gPiA+IGluIHN1c3BlbmQgbW9kZSwgd2F0Y2hk
b2cgaXMgc3RpbGwgd29ya2luZyBidXQgbm8gZGFlbW9uCj4+ID4gPiBwYXR0aW5nIHRoZSB3YXRj
aGRvZy4gVGhlIHN5c3RlbSB3aWxsIHJlYm9vdCBpZiB0aW1lb3V0Lgo+PiA+ID4gCj4+ID4gPiBB
ZGQgc3VwcG9ydCBzdXNwZW5kL3Jlc3VtZSBmb3Igd2F0Y2hkb2cuCj4+ID4gPiBzdXNwZW5kOiBk
aXNhYmxlIHRoZSB3YXRjaGRvZwo+PiA+ID4gcmVzdW1lOiBkaXNhYmxlIGV4aXN0aW5nIHdhdGNo
ZG9nLCByZWxvYWQgd2F0Y2hkb2cgdGltZXIsIGVuYWJsZSB3YXRjaGRvZwo+PiA+ID4gCj4+ID4g
PiBTaWduZWQtb2ZmLWJ5OiB3aW50b24ubGl1IDwxODUwMjUyMzU2NEAxNjMuY29tPgo+PiA+ID4g
LS0tCj4+ID4gPiAgIGRyaXZlcnMvcnRjL3J0Yy1kczEzNzQuYyB8IDMxICsrKysrKysrKysrKysr
KysrKysrKysrKysrKysrKysKPj4gPiA+ICAgMSBmaWxlIGNoYW5nZWQsIDMxIGluc2VydGlvbnMo
KykKPj4gPiA+IAo+PiA+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcnRjL3J0Yy1kczEzNzQuYyBi
L2RyaXZlcnMvcnRjL3J0Yy1kczEzNzQuYwo+PiA+ID4gaW5kZXggMzhhMmU5ZS4uNjQyZTMxZCAx
MDA2NDQKPj4gPiA+IC0tLSBhL2RyaXZlcnMvcnRjL3J0Yy1kczEzNzQuYwo+PiA+ID4gKysrIGIv
ZHJpdmVycy9ydGMvcnRjLWRzMTM3NC5jCj4+ID4gPiBAQCAtNDM3LDYgKzQzNywyOSBAQCBzdGF0
aWMgdm9pZCBkczEzNzRfd2R0X3Bpbmcodm9pZCkKPj4gPiA+ICAgCQlwcl9pbmZvKCJXRCBUSUNL
IEZBSUwhISEhISEhISEhICVpXG4iLCByZXQpOwo+PiA+ID4gICB9Cj4+ID4gPiArc3RhdGljIHZv
aWQgZHMxMzc0X3dkdF9yZXN1bWUodm9pZCkKPj4gPiA+ICt7Cj4+ID4gPiArCWludCByZXQgPSAt
RU5PSU9DVExDTUQ7Cj4+ID4gCj4+ID4gVXNlbGVzcyBpbml0aWFsaXphdGlvbiAoeWVzLCBJIGNh
biBzZWUgdGhhdCB0aGlzIGlzIHdpZGVseSBkb25lIGluIHRoZSBkcml2ZXIsCj4+ID4gYnV0IHRo
YXQgZG9lc24ndCBtYWtlIGl0IGJldHRlcikuCj4+ID4gCiAgICAgICAgWWVzLCBJIHRoaW5rIHRo
aXMgaXMgdXNlbGVzcy4gVGhlIG9yaWdpbmFsIGRzMTM3NF93ZHRfZGlzYWJsZSBoYXMgdGhlIHNh
bWUgaXNzdWUuCj4+ID4gPiArCWludCBjcjsKPj4gPiA+ICsKPj4gPiA+ICsJY3IgPSBpMmNfc21i
dXNfcmVhZF9ieXRlX2RhdGEoc2F2ZV9jbGllbnQsIERTMTM3NF9SRUdfQ1IpOwo+PiA+ID4gKwo+
PiA+ID4gKwkvKiBEaXNhYmxlIGFueSBleGlzdGluZyB3YXRjaGRvZy9hbGFybSBiZWZvcmUgc2V0
dGluZyB0aGUgbmV3IG9uZSAqLwo+PiA+ID4gKwljciAmPSB+RFMxMzc0X1JFR19DUl9XQUNFOwo+
PiA+ID4gKwo+PiA+ID4gKwlpMmNfc21idXNfd3JpdGVfYnl0ZV9kYXRhKHNhdmVfY2xpZW50LCBE
UzEzNzRfUkVHX0NSLCBjcik7Cj4+ID4gPiArCj4+ID4gPiArCS8qIFJlbG9hZCB3YXRjaGRvZyB0
aW1lciAqLwo+PiA+ID4gKwlkczEzNzRfd2R0X3BpbmcoKTsKPj4gPiA+ICsKPj4gPiA+ICsJLyog
RW5hYmxlIHdhdGNoZG9nIHRpbWVyICovCj4+ID4gPiArCWNyIHw9IERTMTM3NF9SRUdfQ1JfV0FD
RSB8IERTMTM3NF9SRUdfQ1JfV0RBTE07Cj4+ID4gPiArCWNyICY9IH5EUzEzNzRfUkVHX0NSX0FJ
RTsKPj4gPiA+ICsKPj4gPiA+ICsJcmV0ID0gaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShzYXZl
X2NsaWVudCwgRFMxMzc0X1JFR19DUiwgY3IpOwo+PiA+ID4gKwo+PiA+IEV4dHJhIGVtcHR5IGxp
bmUuIEFsc28sIHJldHVybnMgdm9pZCwgc28gd2hhdCBpcyB0aGUgcG9pbnQgb2YgYXNzaWduaW5n
Cj4+ID4gdGhlIHJlc3VsdCB0byByZXQgPwo+PiA+IAo+PiA+ID4gK30KPj4gPiAKPj4gPiBVbmxl
c3MgSSBhbSBtaXNzaW5nIHNvbWV0aGluZywgdGhpcyB1bmNvbmRpdGlvbmFsbHkgc3RhcnRzIHRo
ZSB3YXRjaGRvZwo+PiA+IGF0IHJlc3VtZSB0aW1lLiBTbyBpZiBpdCB3YXMgbm90IHJ1bm5pbmcg
YmVmb3JlLCBpdCB3aWxsIGJlIHN0YXJ0ZWQgYW55d2F5LAo+PiA+IGFuZCB0aGUgc3lzdGVtIHdp
bGwgcmVib290IHNpbmNlIHRoZXJlIHdpbGwgYmUgbm8gcGluZy4KPj4gPiAKICAgIFRoaXMgZHJp
dmVyIHN0YXJ0cyB3YXRjaGRvZyBieSBkZWZhdWx0LiBJbiBwcm9iZSB3YXRjaGRvZyBzdGFydHM6
IAogICAjaWZkZWYgQ09ORklHX1JUQ19EUlZfRFMxMzc0X1dEVAogICAgc2F2ZV9jbGllbnQgPSBj
bGllbnQ7CiAgICByZXQgPSBtaXNjX3JlZ2lzdGVyKCZkczEzNzRfbWlzY2Rldik7CiAgICBpZiAo
cmV0KQogICAgICAgIHJldHVybiByZXQ7CiAgICByZXQgPSByZWdpc3Rlcl9yZWJvb3Rfbm90aWZp
ZXIoJmRzMTM3NF93ZHRfbm90aWZpZXIpOwogICAgaWYgKHJldCkgewogICAgICAgIG1pc2NfZGVy
ZWdpc3RlcigmZHMxMzc0X21pc2NkZXYpOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9CiAgICBk
czEzNzRfd2R0X3NldHRpbWVvdXQoMTMxMDcyKTsgICAvL0hlcmUgc3RhcnRzIHdhdGNoZG9nCiNl
bmRpZgogICBBbmQgdXNlcnNwYWNlIHdhdGNoZG9nZCB3aWxsIHBpbmcuCj4+IAo+PiBBbHNvLCBJ
J20gc3RpbGwgbm90IGNvbnZpbmNlZCB0aGlzIGlzIHRoZSByaWdodCB0aGluZyB0byBkby4gSSBo
YXZlIHNlZW4KPj4gbWFueSBzeXN0ZW1zIHdlcmUgaXQgd2FzIGRlc2lyYWJsZSB0byBsZXQgdGhl
IHdhdGNoZG9nIHJ1biB3aGlsZSB0aGUKPj4gc3lzdGVtIGlzIHN1c3BlbmRlZC4gSXQgZW5zdXJl
cyBpdCB3aWxsIGVpdGhlciB3YWtlIHVwIG9yIHJlYm9vdC4gSWYgeW91Cj4+IGRvbid0IHdhbnQg
dGhhdCwgd2h5IG5vdCBkaXNhYmxpbmcgdGhlIHdhdGNoZG9nIGZyb20gdXNlcnNwYWNlIGJlZm9y
ZQo+PiBnb2luZyB0byBzdXNwZW5kPwo+PiAKPgo+VXN1YWxseSB3YXRjaGRvZyBkcml2ZXJzIHN1
cHBvcnRpbmcgc3VzcGVuZC9yZXN1bWUgZG8gaGFuZGxlIGl0IHRoaXMgd2F5Lgo+TWF5YmUgdGhh
dCBkZXBlbmRzIG9uIHRoZSBIVy4gRXhwZWN0aW5nIHVzZXIgc3BhY2UgdG8gZG8gaXQgbWFrZXMg
aXQKPmV2ZW4gbW9yZSByYWN5IHRoYW4gaXQgYWxyZWFkeSBpcywgc2luY2UgdGhlcmUgaXMgbm8g
d2F0Y2hkb2cgcHJvdGVjdGlvbgo+YWZ0ZXIgaXQgaGFzIGJlZW4gZGlzYWJsZWQsIHNvIEkgYW0g
bm90IHN1cmUgaWYgdGhhdCBpcyByZWFsbHkgYmV0dGVyLgo+RG9lcyBhbnlvbmUgaGFwcGVuIHRv
IGtub3cgaWYvaG93IHN5c3RlbWQgYW5kIHdhdGNoZG9nZCBhcmUgaGFuZGxpbmcKPnRoaXMgc2l0
dWF0aW9uID8KPgo+PiA+IEkgYXNzdW1lIGl0IGlzIGd1YXJhbnRlZWQgdGhhdCB0aGUgY2hpcCBk
b2Vzbid0IGZvcmdldCB0aGUgcHJldmlvdXNseQo+PiA+IGNvbmZpZ3VyZWQgdGltZW91dCBvbiBy
ZXN1bWUuCj4+ID4gCj4+ID4gT3ZlcmFsbCB0aGUgZHJpdmVyIHdvdWxkIHJlYWxseSBiZW5lZml0
IGZyb20gYSBjb252ZXJzaW9uIHRvIHRoZSB3YXRjaGRvZwo+PiA+IHN1YnN5c3RlbS4KPj4gPiAK
Pj4gCj4+IFRoYXQgaXMgdGhlIHBvaW50IG9mIGh0dHBzOi8vd3d3LnNwaW5pY3MubmV0L2xpc3Rz
L2xpbnV4LXdhdGNoZG9nL21zZzEyMDk1Lmh0bWwKPgo+QWgsIHllcywgYW5kIEkgZXZlbiBwcm92
aWRlZCBmZWVkYmFjay4gSG9wZSBJIGRpZG4ndCBtaXNzIGFuIHVwZGF0ZWQKPnZlcnNpb24gb2Yg
dGhhdCBwYXRjaC4gRWl0aGVyIGNhc2UsIHNlZW1zIHRvIG1lIHdlIHNob3VsZCB3YWl0IGZvciB0
aGF0Cj5wYXRjaCB0byBtYWtlIGl0IGluIGJlZm9yZSBhY2NlcHRpbmcgYW55IGZ1cnRoZXIgY2hh
bmdlcyB0byB0aGUgZHJpdmVyLgo+CiAgIElzIHRoaXMgbXVsdGkgZnVuY3Rpb24gcGF0Y2ggaGFz
IGFueSB1cGRhdGUgPyBJZiBub3QsIGNvdWxkIG15IHBhdGNoIGJlIGFjY2VwdGFibGUgYmVmb3Jl
IG1vdmluZyB0byB3YXRjaGRvZyBzdWJzeXN0ZW0uKEkgY291bGQgdXBkYXRlIGEgbmV3IHBhdGNo
IGZvciB5b3VyIHN1Z2dlc3Rpb24pPwogICBCZWNhdXNlIGN1cnJlbnQga2VybmVsIHVzaW5nIGRz
MTM3NCBmb3Igd2F0Y2hkb2cuIElmIHRoZSBkZXZpY2UgbmVlZCBzdXNwZW5kLCB0aGVyZSB3aWxs
IGJlIGEgcmVib290IGlzc3VlLgoKPkd1ZW50ZXIK
^ permalink raw reply
* Re: [PATCH v1 24/25] kdb: Switch to use %pt
From: Arnd Bergmann @ 2017-10-12 13:31 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Rasmus Villemoes, Greg Kroah-Hartman, Andrew Morton,
Linux Kernel Mailing List, Alessandro Zummo, Alexandre Belloni,
linux-rtc, Jason Wessel, Ingo Molnar
In-Reply-To: <20170608134811.60786-25-andriy.shevchenko@linux.intel.com>
On Thu, Jun 8, 2017 at 3:48 PM, Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
> diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
> index c8146d53ca67..2a6f12be79d8 100644
> --- a/kernel/debug/kdb/kdb_main.c
> +++ b/kernel/debug/kdb/kdb_main.c
> @@ -2556,12 +2556,7 @@ static int kdb_summary(int argc, const char **argv)
>
> now = __current_kernel_time();
> kdb_gmtime(&now, &tm);
> - kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d "
> - "tz_minuteswest %d\n",
> - 1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
> - tm.tm_hour, tm.tm_min, tm.tm_sec,
> - sys_tz.tz_minuteswest);
> -
I just experimented with a similar change and noticed your version.
You forgot to remove the kdb_gmtime() function that is now completely
unneeded. My patch takes care of that now.
Arnd
^ permalink raw reply
* Re: [PATCH] rtc: jz4740: fix loading of rtc driver
From: Alexandre Belloni @ 2017-10-12 12:32 UTC (permalink / raw)
To: Mathieu Malaterre
Cc: Ralf Baechle, Alex Smith, Zubair Lutfullah Kakakhel,
Alessandro Zummo, linux-rtc, linux-kernel
In-Reply-To: <20170918191014.28106-1-malat@debian.org>
On 18/09/2017 at 21:10:13 +0200, Mathieu Malaterre wrote:
> The current timeout for waiting for WRDY is not always sufficient. Always
> increase it to 10000 even on JZ4740. This is technically only required on
> JZ4780, where the current symptoms seen after a hard reboot are:
>
> jz4740-rtc 10003000.rtc: rtc core: registered 10003000.rtc as rtc0
> jz4740-rtc 10003000.rtc: Could not write to RTC registers
> jz4740-rtc: probe of 10003000.rtc failed with error -5
>
> Suggested-by: Alex Smith <alex.smith@imgtec.com>
> Cc: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>
> Signed-off-by: Mathieu Malaterre <malat@debian.org>
> ---
> drivers/rtc/rtc-jz4740.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH] rtc: jz4740: remove duplicate 'write' in message
From: Alexandre Belloni @ 2017-10-12 12:25 UTC (permalink / raw)
To: Mathieu Malaterre; +Cc: Alessandro Zummo, linux-rtc, linux-kernel
In-Reply-To: <20170910193957.25037-1-malat@debian.org>
On 10/09/2017 at 21:39:57 +0200, Mathieu Malaterre wrote:
> Trivial fix in error message with duplicate 'write'
>
> Signed-off-by: Mathieu Malaterre <malat@debian.org>
> ---
> drivers/rtc/rtc-jz4740.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH RfC] rtc: ds1307: improve weekday handling
From: Alexandre Belloni @ 2017-10-12 12:20 UTC (permalink / raw)
To: Heiner Kallweit; +Cc: linux-rtc
In-Reply-To: <abf5f5ff-b406-eff0-a1ec-9486efbe8506@gmail.com>
On 29/08/2017 at 21:52:56 +0200, Heiner Kallweit wrote:
> The current code for checking and fixing the weekday in ds1307_probe
> faces some issues:
> - This check is applied to all chips even if its applicable (AFAIK)
> to mcp794xx only
> - The check uses MCP794XX constants for registers and bits even though
> it's executed also on other chips (ok, this could be fixed easily)
> - It relies on tm_wday being properly populated when core calls set_time
> and set_alarm. This is not guaranteed at all.
>
> First two issue we could solve by moving the check to the
> mcp794xx-specific initialization (where also VBATEN flag is set).
>
> The proposed alternative is in the set_alarm path for mcp794xx only and
> calculates the alarm weekday based on the current weekday in the RTC
> timekeeping regs and the difference between alarm date and current date.
> So we are fine with any weekday even if it doesn't match the date.
>
> Still there are cases where this could fail, e.g.:
> - rtc date/time + weekday have power-on-reset default values
> - alarm is set to actual date/time + x
> - set_time is called (may change diff between rtc weekday and actual
> weekday)
>
> But similar issues we have with the current code too:
> - rtc date/time + weekday have power-on-reset default values
> - alarm is set to rtc date/time + x
> - set_time is called before the alarm triggers
>
> Using random rtc date/time with relative alarms simply can interfere
> with set_time. I'm not totally convinced of either option yet.
>
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
> drivers/rtc/rtc-ds1307.c | 52 ++++++++++++++++++++++++------------------------
> 1 file changed, 26 insertions(+), 26 deletions(-)
>
It took me some time to test it (I've received an mcp79410) because at
first, it seemed the regmap conversion made the IO timeout. I can't
reproduce that anymore though.
Applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: DryIce , RTC not working on imx53.
From: Russell King - ARM Linux @ 2017-10-12 9:36 UTC (permalink / raw)
To: Patrick Brünn
Cc: Vellemans, Noel, linux-arm-kernel@lists.infradead.org,
linux-rtc@vger.kernel.org
In-Reply-To: <3BB206AB2B1BD448954845CE6FF69A8E01B8E754AA@NT-Mail07.beckhoff.com>
On Thu, Oct 12, 2017 at 07:50:41AM +0000, Patrick Brünn wrote:
> Novice question: Is hwclock still required these days? For me it looks
> like the kernel is synchronizing with rtc on it's own. Maybe some kernel
> config is incompatible with hwclock?
It depends on your application. If you want the kernel's idea of time
to be wrong up to a second or two, then you can rely on the kernel's
time setting.
Please realise that the kernel has always set the time from the RTC,
even on x86 where hwclock has been used. hwclock, however, has some
advanced features and advantages that are beneficial if you're after
accuracy.
1) hwclock will try to read the RTC as close to a second-change as
possible, so that the time read from the RTC is as close to the
second.
2) hwclock can measure and correct the RTC time for its own drift if
hwclock has been allowed to capture and process the offset.
What this means is that hwclock has the capability to precisely set
the kernel's time at boot, way more accurately than the kernel does.
The kernel's time setting is focused on speed, not accuracy.
So, if your userspace application is to monitor something using a
precise timestamp, and you are NTP synchronising (or other method) the
time on the system, then you need the kernel's idea of time to be set
much more precisely to avoid NTP making big corrections over the
following three to six hours.
This happens because NTP will slew the clock for a few seconds of
difference, which makes storing and reloading the PPM value useless,
and can also mean that in such a monitoring application, the results
are unreliable until NTP has re-stabilised.
Here's an example of an application where this may matter: average
speed camera system. You have two cameras over a section of road,
each with their own processing, which are NTP synchronised. Each
reads the numberplate of passing vehicles using ANPR technology,
and timestamps the passing of the vehicle using their local clock.
The distance is known, so it's an easy calculation to calculate the
vehicle speed. If the vehicle speed is over the limit, the driver
is fined.
Consider what the implications are if one of the systems rebooted
and then had incorrect time (up to two seconds wrong) for up to six
hours after - a two second error is about a 3% error in recorded
speed. Would you want to be sent a speeding fine from such a system?
(We have the first non-motorway road in Surrey, UK to have average
speed cameras installed down its entire length because of "piston
heads" who think the speed limit is 60mph rather than the sign-
posted 40mph.)
Another, probably more relevant application is a stratum-1 NTP server
synchronised via PPS to a GPS. I wonder how many people are aware
that if you reboot such a setup relying on the kernel's time setting
only, the time sent to clients will be wrong while NTP slews the local
clock. I've seen these effects locally, where rebooting exactly such
a system results in slaved systems which have no other source of time
also making big corrections.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* RE: DryIce , RTC not working on imx53.
From: Patrick Brünn @ 2017-10-12 7:50 UTC (permalink / raw)
To: Vellemans, Noel, linux-arm-kernel@lists.infradead.org
Cc: linux-rtc@vger.kernel.org
In-Reply-To: <D24E577EA1E37B4788A3BFBC418F14A70760C04A@wetsrvex01.loepfe.com>
PkZyb206IFZlbGxlbWFucywgTm9lbCBbbWFpbHRvOk5vZWwuVmVsbGVtYW5zQHZpc2lvbkJNUy5j
b21dDQo+U2VudDogRG9ubmVyc3RhZywgNS4gT2t0b2JlciAyMDE3IDE2OjE5DQo+SGVsbG8sDQo+
DQpIaSwNCm5vdCBzdXJlIGlmIEkgY2FuIGhlbHAgb24gdGhpcywgYnV0IGFzIEkgZGlkIHNvbWUg
dGVzdGluZyBteXNlbGYgSSB0aG91Z2h0IEkgc2hvdWxkIHRocm93IGluIG15IHJlc3VsdHMgYXMg
d2VsbC4NCg0KPkRyeUljZSAsIFNSVEMgbm90IHdvcmtpbmcgb24gaW14NTMuICgga2VybmVsIDQu
eCkgICggc2FtZSBoYXJkd2FyZSBydW5uaW5nDQo+b2xkZXIga2VybmVsIHZlcnNpb25zLi4gbWVh
bnMgLCBydGMgaXMgd29ya2luZykNCj4NCklzIGl0IG9ubHkgdGhlIGtlcm5lbCB5b3UgYXJlIGNo
YW5naW5nPyBJIGFtIGFza2luZyBiZWNhdXNlIEkgaGFkIHRoZSBpbXByZXNzaW9uIHRoYXQgaHdj
bG9jayBiZWhhdmVzIGRpZmZlcmVudCBvbiBEZWJpYW4gc3RyZXRjaCAodXRpbC1saW51eCAyLjI5
LjIpIGFuZCBqZXNzaWUgKHV0aWwtbGludXggMi4yNS4yKS4NCkkgYW0gc2F5aW5nIGltcHJlc3Np
b24gYmVjYXVzZSBpdCBzZWVtZWQgb24gamVzc2llIEkgd291bGQgYWx3YXlzIGdldCBhIHJlc3Bv
bnNlIG9mIGh3Y2xvY2ssIGJ1dCBvbiBzdHJldGNoIG5ldmVyLiBXaGVuIEkgZGlkIG1vcmUgc3lz
dGVtYXRpYyB0ZXN0aW5nIGl0IGxvb2tzIGxpa2UgcmlnaHQgYWZ0ZXIgYm9vdCBod2Nsb2NrIC1y
IHdpbGwgYWx3YXlzIGZhaWwuIEJ1dCBpZiBJIHdhaXQgc29tZSBtaW51dGVzLCBhbGwgY2FsbHMg
c3VjY2VlZC4NCj4uLi4NCj5RVUlDSyBhbmFseXNlcyAgKCBjb3VsZCBiZSB3cm9uZykgPw0KPkl0
IHNlZW1zIHRoYXQgaHdjbG9jayBpcyByZWFkaW5nIHRoZSBjdXJyZW50LXRpbWVzdGFtcCAzIHRp
bWVzIGFuZCBpZiBub3QNCj5jaGFuZ2VkIGluIHRob3NlIDMgcmVhZCBjeWNsZXPigKYgaXQgc2V0
cyB1cCBhbiByZWFkLWludGVycnVwdC1hYm9ydCBhYmxlIHRpbWUNCj5yZWFkZXIgdGhhdCBzaG91
bGQgcmV0dXJuIGFzIHNvb24gYXMgdGhlIGlycSBmaXJlc+KApiBidXQgdGhpcyBzZWVtcyB0byBi
ZQ0KPm1pc3NpbmcgIQ0KPg0KSSBhbSBzZWVpbmcgYSBsb3Qgb2YgaW50ZXJydXB0cyB3aXRoIGtl
cm5lbCA0LjE0LXJjNCAoamVzc2llIGFuZCBzdHJldGNoKSwgYnV0IHRoZXkgc2VlbSB0byBiZSB1
bmhhbmRsZWQ6DQpyb290QENYOTAyMDp+IyB1bmFtZSAtYQ0KTGludXggQ1g5MDIwIDQuMTQuMC1y
YzQrICMxNTEgUFJFRU1QVCBXZWQgT2N0IDExIDEwOjQwOjM0IENFU1QgMjAxNyBhcm12N2wgR05V
L0xpbnV4DQpyb290QENYOTAyMDp+IyBod2Nsb2NrIC1EIC1yDQpod2Nsb2NrIGZyb20gdXRpbC1s
aW51eCAyLjI5LjINClVzaW5nIHRoZSAvZGV2IGludGVyZmFjZSB0byB0aGUgY2xvY2suDQpMYXN0
IGRyaWZ0IGFkanVzdG1lbnQgZG9uZSBhdCAxNDkwODg1MDgyIHNlY29uZHMgYWZ0ZXIgMTk2OQ0K
TGFzdCBjYWxpYnJhdGlvbiBkb25lIGF0IDE0OTA4ODUwODIgc2Vjb25kcyBhZnRlciAxOTY5DQpI
YXJkd2FyZSBjbG9jayBpcyBvbiBVVEMgdGltZQ0KQXNzdW1pbmcgaGFyZHdhcmUgY2xvY2sgaXMg
a2VwdCBpbiBVVEMgdGltZS4NCldhaXRpbmcgZm9yIGNsb2NrIHRpY2suLi4NClsgICAyNi43OTU0
MzddIGlycSA0MDogbm9ib2R5IGNhcmVkICh0cnkgYm9vdGluZyB3aXRoIHRoZSAiaXJxcG9sbCIg
b3B0aW9uKQ0KWyAgIDI2LjgwMjY5Nl0gaGFuZGxlcnM6DQpbICAgMjYuODA1MDMxXSBbPGMwNjAy
OWU4Pl0gZHJ5aWNlX2lycQ0KWyAgIDI2LjgwODU4NF0gRGlzYWJsaW5nIElSUSAjNDANCnNlbGVj
dCgpIHRvIC9kZXYvcnRjIHRvIHdhaXQgZm9yIGNsb2NrIHRpY2sgdGltZWQgb3V0Li4uc3luY2hy
b25pemF0aW9uIGZhaWxlZA0Kcm9vdEBDWDkwMjA6fiMgY2F0IC9wcm9jL2ludGVycnVwdHMNCiAg
ICAgICAgICAgQ1BVMA0KIDE3OiAgICAgICA0Mjc2ICAgICAgdHppYyAgIDEgRWRnZSAgICAgIG1t
YzANCiAxODogICAgICAgICA1MiAgICAgIHR6aWMgICAyIEVkZ2UgICAgICBtbWMxDQogMjI6ICAg
ICAgICAgIDAgICAgICB0emljICAgNiBFZGdlICAgICAgc2RtYQ0KIDMwOiAgICAgICAgMTc2ICAg
ICAgdHppYyAgMTQgRWRnZSAgICAgIDUzZjgwMjAwLnVzYg0KIDQwOiAgICAgMTAwMDAwICAgICAg
dHppYyAgMjQgRWRnZSAgICAgIDUzZmE0MDAwLnNydGMNCiA0ODogICAgICAgIDI2OCAgICAgIHR6
aWMgIDMyIEVkZ2UgICAgICA1M2ZjMDAwMC5zZXJpYWwNCiA1NTogICAgICAgMjI4OCAgICAgIHR6
aWMgIDM5IEVkZ2UgICAgICBpLk1YIFRpbWVyIFRpY2sNCiA3NDogICAgICAgICAgMCAgICAgIHR6
aWMgIDU4IEVkZ2UgICAgICA1M2Y5ODAwMC53ZG9nDQogNzk6ICAgICAgICAyNzggICAgICB0emlj
ICA2MyBFZGdlICAgICAgNjNmYzQwMDAuaTJjDQogOTM6ICAgICAgICAgIDAgICAgICB0emljICA3
NyBFZGdlICAgICAgYXJtLXBtdQ0KMTAzOiAgICAgICAgNjYyICAgICAgdHppYyAgODcgRWRnZSAg
ICAgIDYzZmVjMDAwLmV0aGVybmV0DQoxNDU6ICAgICAgICAgIDAgIGdwaW8tbXhjICAgMSBFZGdl
ICAgICAgNTAwMDQwMDAuZXNkaGMgY2QNCjE0ODogICAgICAgICAgMCAgZ3Bpby1teGMgICA0IEVk
Z2UgICAgICA1MDAwODAwMC5lc2RoYyBjZA0KMzY4OiAgICAgICAgNjc0ICAgICAgIElQVSAgMjMg
RWRnZSAgICAgIGlteF9kcm0NCjM2OTogICAgICAgICAgMCAgICAgICBJUFUgIDI4IEVkZ2UgICAg
ICBpbXhfZHJtDQpFcnI6ICAgICAgICAgIDANCg0KSSBhZGRlZCBzb21lIHRyYWNpbmcgdG8gZHJ5
aWNlX2lycSgpIGFuZCBzYXcgdGhhdCBtb3N0IG9mIHRoZSB0aW1lIChpZiBub3QgYWxsIHRoZSB0
aW1lKSBkc3IgPT0gRFNSX01DTyAvKiBtb25vdG9uaWMgY2xvY2sgb3ZlcmZsb3cgKi8gd2l0aCBk
aWVyIHZhcnkgYmV0d2VlbiAweDExMCwgMHgxMCBhbmQgZXZlbiAweDAuDQpJIGRvbid0IGtub3cg
d2hhdCdzIHRoZSByaWdodCB0aGluZyB0byBkbywgdG8gcmVjb3ZlciBmcm9tIERTUl9NQ08uICIg
cmV0dXJuIElSUV9IQU5ETEVEIiB3aWxsIHN0b3AgdGhlIG5vYm9keSBjYXJlZCBtZXNzYWdlIGJ1
dCBod2Nsb2NrIHN0aWxsIHRpbWVzIG91dC4NCg0KQW5kIGZvciBjb21wbGV0ZW5lc3M6DQpyb290
QENYOTAyMDp+IyBkbWVzZyB8IGdyZXAgc3J0Yw0KWyAgICAwLjI5OTA0M10gaW14ZGlfcnRjIDUz
ZmE0MDAwLnNydGM6IFVubG9ja2VkIHVuaXQgZGV0ZWN0ZWQNClsgICAgMC4yOTk1MzldIGlteGRp
X3J0YyA1M2ZhNDAwMC5zcnRjOiBzZWN1cml0eSB2aW9sYXRpb24gaW50ZXJydXB0IG5vdCBhdmFp
bGFibGUuDQpbICAgIDAuMjk5NzU3XSBydGMgcnRjMDogNTNmYTQwMDAuc3J0YzogZGV2ICgyNTM6
MCkNClsgICAgMC4yOTk3NzhdIGlteGRpX3J0YyA1M2ZhNDAwMC5zcnRjOiBydGMgY29yZTogcmVn
aXN0ZXJlZCA1M2ZhNDAwMC5zcnRjIGFzIHJ0YzANClsgICAgMC40MzY3ODVdIGlteGRpX3J0YyA1
M2ZhNDAwMC5zcnRjOiBzZXR0aW5nIHN5c3RlbSBjbG9jayB0byAyMDE3LTEwLTEyIDA2OjM4OjA4
IFVUQyAoMTUwNzc5MDI4OCkNClsgIDQ0NS40ODY2MjRdIGlteGRpX3J0YyA1M2ZhNDAwMC5zcnRj
OiBXcml0ZS13YWl0IHRpbWVvdXQgdmFsID0gMHg1OWRmMGY4ZSByZWcgPSAweDAwMDAwMDA4DQpb
IDMwMjUuMDc2NjEyXSBpbXhkaV9ydGMgNTNmYTQwMDAuc3J0YzogV3JpdGUtd2FpdCB0aW1lb3V0
IHZhbCA9IDB4NTlkZjE5YTIgcmVnID0gMHgwMDAwMDAwOA0KWyAzMDgyLjMxNjYxMl0gaW14ZGlf
cnRjIDUzZmE0MDAwLnNydGM6IFdyaXRlLXdhaXQgdGltZW91dCB2YWwgPSAweDU5ZGYxOWRiIHJl
ZyA9IDB4MDAwMDAwMDgNCg0KTm92aWNlIHF1ZXN0aW9uOiBJcyBod2Nsb2NrIHN0aWxsIHJlcXVp
cmVkIHRoZXNlIGRheXM/IEZvciBtZSBpdCBsb29rcyBsaWtlIHRoZSBrZXJuZWwgaXMgc3luY2hy
b25pemluZyB3aXRoIHJ0YyBvbiBpdCdzIG93bi4gTWF5YmUgc29tZSBrZXJuZWwgY29uZmlnIGlz
IGluY29tcGF0aWJsZSB3aXRoIGh3Y2xvY2s/DQoNClJlZ2FyZHMsDQpQYXRyaWNrDQpCZWNraG9m
ZiBBdXRvbWF0aW9uIEdtYkggJiBDby4gS0cgfCBNYW5hZ2luZyBEaXJlY3RvcjogRGlwbC4gUGh5
cy4gSGFucyBCZWNraG9mZg0KUmVnaXN0ZXJlZCBvZmZpY2U6IFZlcmwsIEdlcm1hbnkgfCBSZWdp
c3RlciBjb3VydDogR3VldGVyc2xvaCBIUkEgNzA3NQ0KDQoNCg==
^ permalink raw reply
* Re: [PATCH] rtc: clarify the RTC offset correction
From: Russell King - ARM Linux @ 2017-10-11 21:47 UTC (permalink / raw)
To: Alexandre Belloni; +Cc: Alessandro Zummo, linux-rtc
In-Reply-To: <20171003133158.db4eibi6xqdtvbxg@piout.net>
On Tue, Oct 03, 2017 at 03:31:58PM +0200, Alexandre Belloni wrote:
> Hi,
>
> On 29/09/2017 at 11:23:25 +0100, Russell King wrote:
> > The RTC offset correction documentation is not very clear about the
> > exact relationship between "offset" and the effect it has on the RTC.
> > Supplement the documentation with an equation giving the relationship.
> >
> > Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> > ---
> > drivers/rtc/interface.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
> > index 8cec9a02c0b8..045e0a72d14b 100644
> > --- a/drivers/rtc/interface.c
> > +++ b/drivers/rtc/interface.c
> > @@ -1004,6 +1004,10 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset)
> > * to compensate for differences in the actual clock rate due to temperature,
> > * the crystal, capacitor, etc.
> > *
> > + * The adjustment applied is as follows:
> > + * t = t0 * (1 + offset * 1e-9)
> > + * where t0 is the measured length of 1 RTC second with offset = 0
> > + *
>
> More documentation is available in Documentation/rtc.txt. Maybe it is
> worth having the formula in both.
That sounds like a nightmare - stuff should be documented in detail in
one place and only one place, otherwise we risk the two sets of identical
documentation going out of sync. A better idea would be to reference the
detailed documentation - which I guess would be easier if rtc.txt were
converted to a .rst file?
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* Re: [PATCH V2] imx: mx7dsabresd: include BLK for MMC/eMMC support of driver model
From: Eric Nelson @ 2017-10-11 21:41 UTC (permalink / raw)
To: linux-rtc
Cc: a.zummo, alexandre.belloni, robh+dt, mark.rutland, devicetree,
otavio.salvador, peng.fan
In-Reply-To: <1507757654-22114-1-git-send-email-eric@nelint.com>
Please disregard.
I chose the wrong entry in my command-line history and
sent this to the wrong list.
On 10/11/2017 02:34 PM, Eric Nelson wrote:
> Commit 6fbbcfd introduced device-tree support for MMC devices on
> the mx7sabresd boards and didn't include BLK, which requires BLK.
>
> Commit 8ae5bb3 did the same for secure boot.
>
> Fix both by allowing blk-uclass (BLK) support.
>
> Tested-by: Fabio Estevam <festevam@gmail.com>
> Signed-off-by: Eric Nelson <eric@nelint.com>
> ---
> V2 includes the updated to mx7dsabresd_secure_defconfig
> configs/mx7dsabresd_defconfig | 1 -
> configs/mx7dsabresd_secure_defconfig | 1 -
> 2 files changed, 2 deletions(-)
>
> diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig
> index 795c4f2..144fb50 100644
> --- a/configs/mx7dsabresd_defconfig
> +++ b/configs/mx7dsabresd_defconfig
> @@ -38,7 +38,6 @@ CONFIG_CMD_EXT4=y
> CONFIG_CMD_EXT4_WRITE=y
> CONFIG_CMD_FAT=y
> CONFIG_OF_CONTROL=y
> -# CONFIG_BLK is not set
> CONFIG_DFU_MMC=y
> CONFIG_DFU_RAM=y
> CONFIG_DM_GPIO=y
> diff --git a/configs/mx7dsabresd_secure_defconfig b/configs/mx7dsabresd_secure_defconfig
> index bd68831..d1af138 100644
> --- a/configs/mx7dsabresd_secure_defconfig
> +++ b/configs/mx7dsabresd_secure_defconfig
> @@ -40,7 +40,6 @@ CONFIG_CMD_EXT4=y
> CONFIG_CMD_EXT4_WRITE=y
> CONFIG_CMD_FAT=y
> CONFIG_OF_CONTROL=y
> -# CONFIG_BLK is not set
> CONFIG_DFU_MMC=y
> CONFIG_DFU_RAM=y
> CONFIG_DM_GPIO=y
>
^ permalink raw reply
* [PATCH V2] imx: mx7dsabresd: include BLK for MMC/eMMC support of driver model
From: Eric Nelson @ 2017-10-11 21:34 UTC (permalink / raw)
To: linux-rtc
Cc: a.zummo, alexandre.belloni, robh+dt, mark.rutland, devicetree,
otavio.salvador, peng.fan, Eric Nelson
In-Reply-To: <1507753798-20666-1-git-send-email-eric@nelint.com>
Commit 6fbbcfd introduced device-tree support for MMC devices on
the mx7sabresd boards and didn't include BLK, which requires BLK.
Commit 8ae5bb3 did the same for secure boot.
Fix both by allowing blk-uclass (BLK) support.
Tested-by: Fabio Estevam <festevam@gmail.com>
Signed-off-by: Eric Nelson <eric@nelint.com>
---
V2 includes the updated to mx7dsabresd_secure_defconfig
configs/mx7dsabresd_defconfig | 1 -
configs/mx7dsabresd_secure_defconfig | 1 -
2 files changed, 2 deletions(-)
diff --git a/configs/mx7dsabresd_defconfig b/configs/mx7dsabresd_defconfig
index 795c4f2..144fb50 100644
--- a/configs/mx7dsabresd_defconfig
+++ b/configs/mx7dsabresd_defconfig
@@ -38,7 +38,6 @@ CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_OF_CONTROL=y
-# CONFIG_BLK is not set
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_DM_GPIO=y
diff --git a/configs/mx7dsabresd_secure_defconfig b/configs/mx7dsabresd_secure_defconfig
index bd68831..d1af138 100644
--- a/configs/mx7dsabresd_secure_defconfig
+++ b/configs/mx7dsabresd_secure_defconfig
@@ -40,7 +40,6 @@ CONFIG_CMD_EXT4=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FAT=y
CONFIG_OF_CONTROL=y
-# CONFIG_BLK is not set
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_DM_GPIO=y
--
2.7.4
^ permalink raw reply related
* [PATCH V2] rtc: add support for NXP PCF85363 real-time clock
From: Eric Nelson @ 2017-10-11 15:56 UTC (permalink / raw)
To: linux-rtc
Cc: a.zummo, alexandre.belloni, robh+dt, mark.rutland, devicetree,
otavio.salvador, festevam, Eric Nelson
In-Reply-To: <CAOMZO5C_boginn88C7zgXSBaikx==5FHJrgaE1ewYUyUgGfnFQ@mail.gmail.com>
Note that alarms are not currently implemented.
64 bytes of nvmem is supported and exposed in
sysfs (# is the instance number, starting with 0):
/sys/bus/nvmem/devices/pcf85363-#/nvmem
Signed-off-by: Eric Nelson <eric@nelint.com>
---
V2 addresses a couple of issues highlighted by Fabio Estevam
1. Kconfig updated to select REGMAP_I2C
2. Switch to of_device_id from i2c_device_id for driver matching
Documentation/devicetree/bindings/rtc/pcf85363.txt | 16 ++
drivers/rtc/Kconfig | 13 ++
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-pcf85363.c | 221 +++++++++++++++++++++
4 files changed, 251 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/pcf85363.txt
create mode 100644 drivers/rtc/rtc-pcf85363.c
diff --git a/Documentation/devicetree/bindings/rtc/pcf85363.txt b/Documentation/devicetree/bindings/rtc/pcf85363.txt
new file mode 100644
index 0000000..5fddb9f
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/pcf85363.txt
@@ -0,0 +1,16 @@
+NXP PCF85363 Real Time Clock
+============================
+
+Required properties:
+- compatible: Should contain "nxp,pcf85363".
+- reg: I2C address for chip.
+
+Example:
+
+pcf85363: pcf85363@51 {
+ compatible = "nxp,pcf85363";
+ reg = <0x51>;
+};
+
+Note that alarms are not yet supported, so a specifier for
+"interrupts" will be ignored.
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e0e58f3..15306ed 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -433,6 +433,19 @@ config RTC_DRV_PCF85063
This driver can also be built as a module. If so, the module
will be called rtc-pcf85063.
+config RTC_DRV_PCF85363
+ tristate "NXP PCF85363"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the PCF85363 RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-pcf85363.
+
+ The nvmem interface will be named pcf85363-#, where # is the
+ zero-based instance number.
+
config RTC_DRV_PCF8563
tristate "Philips PCF8563/Epson RTC8564"
help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 7230014..934a9dd 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
obj-$(CONFIG_RTC_DRV_PCF2127) += rtc-pcf2127.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
obj-$(CONFIG_RTC_DRV_PCF85063) += rtc-pcf85063.o
+obj-$(CONFIG_RTC_DRV_PCF85363) += rtc-pcf85363.o
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c
new file mode 100644
index 0000000..cf1e70c
--- /dev/null
+++ b/drivers/rtc/rtc-pcf85363.c
@@ -0,0 +1,221 @@
+/*
+ * drivers/rtc/rtc-pcf85363.c
+ *
+ * Driver for NXP PCF85363 real-time clock.
+ *
+ * Copyright (C) 2017 Eric Nelson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Based loosely on rtc-8583 by Russell King, Wolfram Sang and Juergen Beisert
+ */
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/bcd.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+
+/*
+ * Date/Time registers
+ */
+#define DT_100THS 0x00
+#define DT_SECS 0x01
+#define DT_MINUTES 0x02
+#define DT_HOURS 0x03
+#define DT_DAYS 0x04
+#define DT_WEEKDAYS 0x05
+#define DT_MONTHS 0x06
+#define DT_YEARS 0x07
+
+/*
+ * Alarm registers
+ */
+#define DT_SECOND_ALM1 0x08
+#define DT_MINUTE_ALM1 0x09
+#define DT_HOUR_ALM1 0x0a
+#define DT_DAY_ALM1 0x0b
+#define DT_MONTH_ALM1 0x0c
+#define DT_MINUTE_ALM2 0x0d
+#define DT_HOUR_ALM2 0x0e
+#define DT_WEEKDAY_ALM2 0x0f
+#define DT_ALARM_EN 0x10
+
+/*
+ * Time stamp registers
+ */
+#define DT_TIMESTAMP1 0x11
+#define DT_TIMESTAMP2 0x17
+#define DT_TIMESTAMP3 0x1d
+#define DT_TS_MODE 0x23
+
+/*
+ * control registers
+ */
+#define CTRL_OFFSET 0x24
+#define CTRL_OSCILLATOR 0x25
+#define CTRL_BATTERY 0x26
+#define CTRL_PIN_IO 0x27
+#define CTRL_FUNCTION 0x28
+#define CTRL_INTA_EN 0x29
+#define CTRL_INTB_EN 0x2a
+#define CTRL_FLAGS 0x2b
+#define CTRL_RAMBYTE 0x2c
+#define CTRL_WDOG 0x2d
+#define CTRL_STOP_EN 0x2e
+#define CTRL_RESETS 0x2f
+#define CTRL_RAM 0x40
+
+#define NVRAM_SIZE 0x40
+
+static struct i2c_driver pcf85363_driver;
+
+struct pcf85363 {
+ struct device *dev;
+ struct rtc_device *rtc;
+ struct nvmem_config nvmem_cfg;
+ struct regmap *regmap;
+};
+
+static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
+ unsigned char buf[DT_YEARS + 1];
+ int ret, len = sizeof(buf);
+
+ /* read the RTC date and time registers all at once */
+ ret = regmap_bulk_read(pcf85363->regmap, DT_100THS, buf, len);
+ if (ret) {
+ dev_err(dev, "%s: error %d\n", __func__, ret);
+ return ret;
+ }
+
+ tm->tm_year = bcd2bin(buf[DT_YEARS]);
+ /* adjust for 1900 base of rtc_time */
+ tm->tm_year += 100;
+
+ tm->tm_wday = buf[DT_WEEKDAYS] & 7;
+ buf[DT_SECS] &= 0x7F;
+ tm->tm_sec = bcd2bin(buf[DT_SECS]);
+ buf[DT_MINUTES] &= 0x7F;
+ tm->tm_min = bcd2bin(buf[DT_MINUTES]);
+ tm->tm_hour = bcd2bin(buf[DT_HOURS]);
+ tm->tm_mday = bcd2bin(buf[DT_DAYS]);
+ tm->tm_mon = bcd2bin(buf[DT_MONTHS]) - 1;
+
+ return 0;
+}
+
+static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pcf85363 *pcf85363 = dev_get_drvdata(dev);
+ unsigned char buf[DT_YEARS + 1];
+ int len = sizeof(buf);
+
+ buf[DT_100THS] = 0;
+ buf[DT_SECS] = bin2bcd(tm->tm_sec);
+ buf[DT_MINUTES] = bin2bcd(tm->tm_min);
+ buf[DT_HOURS] = bin2bcd(tm->tm_hour);
+ buf[DT_DAYS] = bin2bcd(tm->tm_mday);
+ buf[DT_WEEKDAYS] = tm->tm_wday;
+ buf[DT_MONTHS] = bin2bcd(tm->tm_mon + 1);
+ buf[DT_YEARS] = bin2bcd(tm->tm_year % 100);
+
+ return regmap_bulk_write(pcf85363->regmap, DT_100THS,
+ buf, len);
+}
+
+static const struct rtc_class_ops rtc_ops = {
+ .read_time = pcf85363_rtc_read_time,
+ .set_time = pcf85363_rtc_set_time,
+};
+
+static int pcf85363_nvram_read(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct pcf85363 *pcf85363 = priv;
+
+ return regmap_bulk_read(pcf85363->regmap, CTRL_RAM + offset,
+ val, bytes);
+}
+
+static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val,
+ size_t bytes)
+{
+ struct pcf85363 *pcf85363 = priv;
+
+ return regmap_bulk_write(pcf85363->regmap, CTRL_RAM + offset,
+ val, bytes);
+}
+
+static const struct regmap_config regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int pcf85363_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct pcf85363 *pcf85363;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
+
+ pcf85363 = devm_kzalloc(&client->dev, sizeof(struct pcf85363),
+ GFP_KERNEL);
+ if (!pcf85363)
+ return -ENOMEM;
+
+ pcf85363->regmap = devm_regmap_init_i2c(client, ®map_config);
+ if (IS_ERR(pcf85363->regmap)) {
+ dev_err(&client->dev, "regmap allocation failed\n");
+ return PTR_ERR(pcf85363->regmap);
+ }
+
+ pcf85363->dev = &client->dev;
+ i2c_set_clientdata(client, pcf85363);
+
+ pcf85363->rtc = devm_rtc_allocate_device(pcf85363->dev);
+ if (IS_ERR(pcf85363->rtc))
+ return PTR_ERR(pcf85363->rtc);
+
+ pcf85363->nvmem_cfg.name = "pcf85363-";
+ pcf85363->nvmem_cfg.word_size = 1;
+ pcf85363->nvmem_cfg.stride = 1;
+ pcf85363->nvmem_cfg.size = NVRAM_SIZE;
+ pcf85363->nvmem_cfg.reg_read = pcf85363_nvram_read;
+ pcf85363->nvmem_cfg.reg_write = pcf85363_nvram_write;
+ pcf85363->nvmem_cfg.priv = pcf85363;
+ pcf85363->rtc->nvmem_config = &pcf85363->nvmem_cfg;
+ pcf85363->rtc->nvram_old_abi = true;
+ pcf85363->rtc->ops = &rtc_ops;
+
+ return rtc_register_device(pcf85363->rtc);
+}
+
+static const struct of_device_id dev_ids[] = {
+ { .compatible = "nxp,pcf85363" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, dev_ids);
+
+static struct i2c_driver pcf85363_driver = {
+ .driver = {
+ .name = "pcf85363",
+ .of_match_table = of_match_ptr(dev_ids),
+ },
+ .probe = pcf85363_probe,
+};
+
+module_i2c_driver(pcf85363_driver);
+
+MODULE_AUTHOR("Eric Nelson");
+MODULE_DESCRIPTION("pcf85363 I2C RTC driver");
+MODULE_LICENSE("GPL");
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] rtc: add support for NXP PCF85363 real-time clock
From: Eric Nelson @ 2017-10-11 15:08 UTC (permalink / raw)
To: Fabio Estevam
Cc: linux-rtc, Alessandro Zummo, Alexandre Belloni,
robh+dt@kernel.org, Mark Rutland, devicetree@vger.kernel.org,
Otavio Salvador
In-Reply-To: <CAOMZO5C_boginn88C7zgXSBaikx==5FHJrgaE1ewYUyUgGfnFQ@mail.gmail.com>
Hi Fabio,
On 10/10/2017 06:31 AM, Fabio Estevam wrote:
> Hi Eric,
>
> On Mon, Oct 9, 2017 at 4:41 PM, Eric Nelson <eric@nelint.com> wrote:
>
>> +config RTC_DRV_PCF85363
>> + tristate "NXP PCF85363"
>> + depends on I2C
>
> It seems you missed a dependency on REGMAP_I2C.
>
Nice catch. Thanks.
>> +static const struct i2c_device_id pcf85363_id[] = {
>> + { "pcf85363", 0 },
>> + { }
>> +};
>> +MODULE_DEVICE_TABLE(i2c, pcf85363_id);
>
> Even though the driver can probe via the i2c device id, it is
> recommended to explicitly pass the compatible string:
>
> static const struct of_device_id pcf85363_dt_match[] = {
> { .compatible = "nxp,pcf85363" },
> { },
>
> See this previous discussion:
> https://www.spinics.net/lists/devicetree/msg195176.html
>
Thanks for that, too.
I'll fix this up in V2.
^ permalink raw reply
* RE: [RFC v5 4/8] platform: x86: Add generic Intel IPC driver
From: Chakravarty, Souvik K @ 2017-10-11 3:57 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy@linux.intel.com, a.zummo@towertech.it,
x86@kernel.org, wim@iguana.be, mingo@redhat.com,
alexandre.belloni@free-electrons.com, Zha, Qipeng, hpa@zytor.com,
dvhart@infradead.org, tglx@linutronix.de, lee.jones@linaro.org,
andy@infradead.org
Cc: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org,
linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org,
sathyaosid@gmail.com
In-Reply-To: <d6d98062-9abe-9bd3-8ab7-52b9d1ec8336@linux.intel.com>
T24gT2N0b2JlciAxMSwgMjAxNyAzOjM5IEFNLCBLdXBwdXN3YW15IFNhdGh5YW5hcmF5YW5hbiB3
cm90ZToNCj4gSGksDQo+IA0KPiANCj4gT24gMTAvMDgvMjAxNyAwOTo1MyBQTSwgQ2hha3JhdmFy
dHksIFNvdXZpayBLIHdyb3RlOg0KPiA+PiBGcm9tOiBzYXRoeWFuYXJheWFuYW4ua3VwcHVzd2Ft
eUBsaW51eC5pbnRlbC5jb20NCj4gPj4gW21haWx0bzpzYXRoeWFuYXJheWFuYW4ua3VwcHVzd2Ft
eUBsaW51eC5pbnRlbC5jb21dDQo+ID4+IFNlbnQ6IFN1bmRheSwgT2N0b2JlciA4LCAyMDE3IDM6
NTAgQU0NCj4gPj4gVG86IGEuenVtbW9AdG93ZXJ0ZWNoLml0OyB4ODZAa2VybmVsLm9yZzsgd2lt
QGlndWFuYS5iZTsNCj4gPj4gbWluZ29AcmVkaGF0LmNvbTsgYWxleGFuZHJlLmJlbGxvbmlAZnJl
ZS1lbGVjdHJvbnMuY29tOyBaaGEsIFFpcGVuZw0KPiA+PiA8cWlwZW5nLnpoYUBpbnRlbC5jb20+
OyBocGFAenl0b3IuY29tOyBkdmhhcnRAaW5mcmFkZWFkLm9yZzsNCj4gPj4gdGdseEBsaW51dHJv
bml4LmRlOyBsZWUuam9uZXNAbGluYXJvLm9yZzsgYW5keUBpbmZyYWRlYWQub3JnOw0KPiA+PiBD
aGFrcmF2YXJ0eSwgU291dmlrIEsgPHNvdXZpay5rLmNoYWtyYXZhcnR5QGludGVsLmNvbT4NCj4g
Pj4gQ2M6IGxpbnV4LXJ0Y0B2Z2VyLmtlcm5lbC5vcmc7IGxpbnV4LXdhdGNoZG9nQHZnZXIua2Vy
bmVsLm9yZzsgbGludXgtDQo+ID4+IGtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7IHBsYXRmb3JtLWRy
aXZlci14ODZAdmdlci5rZXJuZWwub3JnOw0KPiA+PiBzYXRoeWFvc2lkQGdtYWlsLmNvbTsgS3Vw
cHVzd2FteSBTYXRoeWFuYXJheWFuYW4NCj4gPj4gPHNhdGh5YW5hcmF5YW5hbi5rdXBwdXN3YW15
QGxpbnV4LmludGVsLmNvbT4NCj4gPj4gU3ViamVjdDogW1JGQyB2NSA0LzhdIHBsYXRmb3JtOiB4
ODY6IEFkZCBnZW5lcmljIEludGVsIElQQyBkcml2ZXINCj4gPj4NCj4gPj4gRnJvbTogS3VwcHVz
d2FteSBTYXRoeWFuYXJheWFuYW4NCj4gPj4gPHNhdGh5YW5hcmF5YW5hbi5rdXBwdXN3YW15QGxp
bnV4LmludGVsLmNvbT4NCj4gPj4NCj4gPj4gQ3VycmVudGx5IGludGVsX3NjdV9pcGMuYywgaW50
ZWxfcG1jX2lwYy5jIGFuZCBpbnRlbF9wdW5pdF9pcGMuYw0KPiA+PiByZWR1bmRhbnRseSBpbXBs
ZW1lbnRzIHRoZSBzYW1lIElQQyBmZWF0dXJlcyBhbmQgaGFzIGxvdCBvZiBjb2RlDQo+ID4+IGR1
cGxpY2F0aW9uIGJldHdlZW4gdGhlbS4gVGhpcyBkcml2ZXIgYWRkcmVzc2VzIHRoaXMgaXNzdWUg
YnkNCj4gPj4gZ3JvdXBpbmcgdGhlIGNvbW1vbiBJUEMgZnVuY3Rpb25hbGl0aWVzIHVuZGVyIHRo
ZSBzYW1lIGRyaXZlci4NCj4gPj4NCj4gPj4gU2lnbmVkLW9mZi1ieTogS3VwcHVzd2FteSBTYXRo
eWFuYXJheWFuYW4NCj4gPj4gPHNhdGh5YW5hcmF5YW5hbi5rdXBwdXN3YW15QGxpbnV4LmludGVs
LmNvbT4NCj4gPj4gLS0tDQo+ID4+ICAgZHJpdmVycy9wbGF0Zm9ybS94ODYvS2NvbmZpZyAgICAg
ICAgICAgICAgICAgICAgfCAgIDggKw0KPiA+PiAgIGRyaXZlcnMvcGxhdGZvcm0veDg2L01ha2Vm
aWxlICAgICAgICAgICAgICAgICAgIHwgICAxICsNCj4gPj4gICBkcml2ZXJzL3BsYXRmb3JtL3g4
Ni9pbnRlbF9pcGNfZGV2LmMgICAgICAgICAgICB8IDU3Ng0KPiA+PiArKysrKysrKysrKysrKysr
KysrKysrKysNCj4gPj4gICBpbmNsdWRlL2xpbnV4L3BsYXRmb3JtX2RhdGEveDg2L2ludGVsX2lw
Y19kZXYuaCB8IDIwNiArKysrKysrKysNCj4gPj4gICA0IGZpbGVzIGNoYW5nZWQsIDc5MSBpbnNl
cnRpb25zKCspDQo+ID4+ICAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvcGxhdGZvcm0veDg2
L2ludGVsX2lwY19kZXYuYw0KPiA+PiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBpbmNsdWRlL2xpbnV4
L3BsYXRmb3JtX2RhdGEveDg2L2ludGVsX2lwY19kZXYuaA0KPiA+Pg0KPiA+PiBDaGFuZ2VzIHNp
bmNlIHY0Og0KPiA+PiAgICogTm9uZQ0KPiA+Pg0KPiA+PiBDaGFuZ2VzIHNpbmNlIHYzOg0KPiA+
PiAgICogRml4ZWQgTlVMTCBwb2ludGVyIGV4Y2VwdGlvbiBpbiBpbnRlbF9pcGNfZGV2X2dldCgp
Lg0KPiA+PiAgICogRml4ZWQgZXJyb3IgaW4gY2hlY2sgZm9yIGR1cGxpY2F0ZSBpbnRlbF9pcGNf
ZGV2Lg0KPiA+PiAgICogQWRkZWQgY3VzdG9tIGludGVycnVwdCBoYW5kbGVyIHN1cHBvcnQuDQo+
ID4+ICAgKiBVc2VkIGNoYXIgYXJyYXkgZm9yIGVycm9yIHN0cmluZyBjb252ZXJzaW9uLg0KPiA+
PiAgICogQWRkZWQgcHV0IGRldiBzdXBwb3J0Lg0KPiA+PiAgICogQWRkZWQgZGV2bV8qIHZhcmlh
bnQgb2YgaW50ZWxfaXBjX2Rldl9nZXQoKS4NCj4gPj4NCj4gPj4gQ2hhbmdlcyBzaW5jZSB2MjoN
Cj4gPj4gICAqIEFkZGVkIGlwY19kZXZfY21kIEFQSSBzdXBwb3J0Lg0KPiA+Pg0KPiA+PiBkaWZm
IC0tZ2l0IGEvZHJpdmVycy9wbGF0Zm9ybS94ODYvS2NvbmZpZw0KPiA+PiBiL2RyaXZlcnMvcGxh
dGZvcm0veDg2L0tjb25maWcgaW5kZXggZGEyZDliYS4uNzI0ZWU2OTYgMTAwNjQ0DQo+ID4+IC0t
LSBhL2RyaXZlcnMvcGxhdGZvcm0veDg2L0tjb25maWcNCj4gPj4gKysrIGIvZHJpdmVycy9wbGF0
Zm9ybS94ODYvS2NvbmZpZw0KPiA+PiBAQCAtMTE1Myw2ICsxMTUzLDE0IEBAIGNvbmZpZyBTSUxF
QURfRE1JDQo+ID4+ICAgCSAgd2l0aCB0aGUgT1MtaW1hZ2UgZm9yIHRoZSBkZXZpY2UuIFRoaXMg
b3B0aW9uIHN1cHBsaWVzIHRoZSBtaXNzaW5nDQo+ID4+ICAgCSAgaW5mb3JtYXRpb24uIEVuYWJs
ZSB0aGlzIGZvciB4ODYgdGFibGV0cyB3aXRoIFNpbGVhZCB0b3VjaHNjcmVlbnMuDQo+ID4+DQo+
ID4+ICtjb25maWcgSU5URUxfSVBDX0RFVg0KPiA+PiArCWJvb2wgIkludGVsIElQQyBEZXZpY2Ug
RHJpdmVyIg0KPiA+PiArCWRlcGVuZHMgb24gWDg2XzY0DQo+ID4+ICsJLS0taGVscC0tLQ0KPiA+
PiArCSAgVGhpcyBkcml2ZXIgaW1wbGVtZW50cyBjb3JlIGZlYXR1cmVzIG9mIEludGVsIElQQyBk
ZXZpY2UuIERldmljZXMNCj4gPj4gKwkgIGxpa2UgUE1DLCBTQ1UsIFBVTklULCBldGMgY2FuIHVz
ZSBpbnRlcmZhY2VzIHByb3ZpZGVkIGJ5IHRoaXMNCj4gPj4gKwkgIGRyaXZlciB0byBpbXBsZW1l
bnQgSVBDIHByb3RvY29sIG9mIHRoZWlyIHJlc3BlY3RpdmUgZGV2aWNlLg0KPiA+PiArDQo+ID4+
ICAgZW5kaWYgIyBYODZfUExBVEZPUk1fREVWSUNFUw0KPiA+Pg0KPiA+PiAgIGNvbmZpZyBQTUNf
QVRPTQ0KPiA+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wbGF0Zm9ybS94ODYvTWFrZWZpbGUNCj4g
Pj4gYi9kcml2ZXJzL3BsYXRmb3JtL3g4Ni9NYWtlZmlsZSBpbmRleCAyYjMxNWQwLi45OWExYWYx
IDEwMDY0NA0KPiA+PiAtLS0gYS9kcml2ZXJzL3BsYXRmb3JtL3g4Ni9NYWtlZmlsZQ0KPiA+PiAr
KysgYi9kcml2ZXJzL3BsYXRmb3JtL3g4Ni9NYWtlZmlsZQ0KPiA+PiBAQCAtODQsMyArODQsNCBA
QCBvYmotJChDT05GSUdfUE1DX0FUT00pCQkrPQ0KPiA+PiBwbWNfYXRvbS5vDQo+ID4+ICAgb2Jq
LSQoQ09ORklHX01MWF9QTEFURk9STSkJKz0gbWx4LXBsYXRmb3JtLm8NCj4gPj4gICBvYmotJChD
T05GSUdfTUxYX0NQTERfUExBVEZPUk0pCSs9IG1seGNwbGQtaG90cGx1Zy5vDQo+ID4+ICAgb2Jq
LSQoQ09ORklHX0lOVEVMX1RVUkJPX01BWF8zKSArPSBpbnRlbF90dXJib19tYXhfMy5vDQo+ID4+
ICtvYmotJChDT05GSUdfSU5URUxfSVBDX0RFVikJKz0gaW50ZWxfaXBjX2Rldi5vDQo+ID4+IGRp
ZmYgLS1naXQgYS9kcml2ZXJzL3BsYXRmb3JtL3g4Ni9pbnRlbF9pcGNfZGV2LmMNCj4gPj4gYi9k
cml2ZXJzL3BsYXRmb3JtL3g4Ni9pbnRlbF9pcGNfZGV2LmMNCj4gPj4gbmV3IGZpbGUgbW9kZSAx
MDA2NDQNCj4gPj4gaW5kZXggMDAwMDAwMC4uZjU1ZGRlYw0KPiA+PiAtLS0gL2Rldi9udWxsDQo+
ID4+ICsrKyBiL2RyaXZlcnMvcGxhdGZvcm0veDg2L2ludGVsX2lwY19kZXYuYw0KPiA+PiBAQCAt
MCwwICsxLDU3NiBAQA0KPiA+PiArLyoNCj4gPj4gKyAqIGludGVsX2lwY19kZXYuYzogSW50ZWwg
SVBDIGRldmljZSBjbGFzcyBkcml2ZXINCj4gPj4gKyAqDQo+ID4+ICsgKiAoQykgQ29weXJpZ2h0
IDIwMTcgSW50ZWwgQ29ycG9yYXRpb24NCj4gPj4gKyAqDQo+ID4+ICsgKiBUaGlzIHByb2dyYW0g
aXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yDQo+ID4+ICsg
KiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGlj
ZW5zZQ0KPiA+PiArICogYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRp
b247IHZlcnNpb24gMg0KPiA+PiArICogb2YgdGhlIExpY2Vuc2UuDQo+ID4+ICsgKg0KPiA+PiAr
ICovDQo+ID4+ICsNCj4gPj4gKyNpbmNsdWRlIDxsaW51eC9kZXZpY2UuaD4NCj4gPj4gKyNpbmNs
dWRlIDxsaW51eC9tb2R1bGUuaD4NCj4gPj4gKyNpbmNsdWRlIDxsaW51eC9kZWxheS5oPg0KPiA+
PiArI2luY2x1ZGUgPGxpbnV4L2Vyci5oPg0KPiA+PiArI2luY2x1ZGUgPGxpbnV4L2V4cG9ydC5o
Pg0KPiA+PiArI2luY2x1ZGUgPGxpbnV4L2lkci5oPg0KPiA+PiArI2luY2x1ZGUgPGxpbnV4L2lu
aXQuaD4NCj4gPj4gKyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+DQo+ID4+ICsjaW5jbHVkZSA8bGlu
dXgvaW50ZXJydXB0Lmg+DQo+ID4+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGF0YS94ODYv
aW50ZWxfaXBjX2Rldi5oPg0KPiA+PiArI2luY2x1ZGUgPGxpbnV4L3JlZ21hcC5oPg0KPiA+PiAr
DQo+ID4+ICsvKiBtdXRleCB0byBzeW5jIGRpZmZlcmVudCBpcGMgZGV2aWNlcyBpbiBzYW1lIGNo
YW5uZWwgKi8gc3RhdGljDQo+ID4+ICtzdHJ1Y3QgbXV0ZXggY2hhbm5lbF9sb2NrW0lQQ19DSEFO
TkVMX01BWF07DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBjaGFyICppcGNfZXJyX3NvdXJjZXNbXSA9
IHsNCj4gPj4gKwlbSVBDX0RFVl9FUlJfTk9ORV0gPQ0KPiA+PiArCQkiTm8gZXJyb3IiLA0KPiA+
PiArCVtJUENfREVWX0VSUl9DTURfTk9UX1NVUFBPUlRFRF0gPQ0KPiA+PiArCQkiQ29tbWFuZCBu
b3Qtc3VwcG9ydGVkL0ludmFsaWQiLA0KPiA+PiArCVtJUENfREVWX0VSUl9DTURfTk9UX1NFUlZJ
Q0VEXSA9DQo+ID4+ICsJCSJDb21tYW5kIG5vdC1zZXJ2aWNlZC9JbnZhbGlkIHBhcmFtIiwNCj4g
Pj4gKwlbSVBDX0RFVl9FUlJfVU5BQkxFX1RPX1NFUlZJQ0VdID0NCj4gPj4gKwkJIlVuYWJsZS10
by1zZXJ2aWNlL0NtZC10aW1lb3V0IiwNCj4gPj4gKwlbSVBDX0RFVl9FUlJfQ01EX0lOVkFMSURd
ID0NCj4gPj4gKwkJIkNvbW1hbmQtaW52YWxpZC9DbWQtbG9ja2VkIiwNCj4gPj4gKwlbSVBDX0RF
Vl9FUlJfQ01EX0ZBSUxFRF0gPQ0KPiA+PiArCQkiQ29tbWFuZC1mYWlsZWQvSW52YWxpZC1WUi1p
ZCIsDQo+ID4+ICsJW0lQQ19ERVZfRVJSX0VNU0VDVVJJVFldID0NCj4gPj4gKwkJIkludmFsaWQg
QmF0dGVyeS9WUi1FcnJvciIsDQo+ID4+ICsJW0lQQ19ERVZfRVJSX1VOU0lHTkVES0VSTkVMXSA9
DQo+ID4+ICsJCSJVbnNpZ25lZCBrZXJuZWwiLA0KPiA+PiArfTsNCj4gPj4gKw0KPiA+PiArc3Rh
dGljIHZvaWQgaXBjX2NoYW5uZWxfbG9ja19pbml0KHZvaWQpIHsNCj4gPj4gKwlpbnQgaTsNCj4g
Pj4gKw0KPiA+PiArCWZvciAoaSA9IDA7IGkgPCBJUENfQ0hBTk5FTF9NQVg7IGkrKykNCj4gPj4g
KwkJbXV0ZXhfaW5pdCgmY2hhbm5lbF9sb2NrW2ldKTsNCj4gPj4gK30NCj4gPj4gKw0KPiA+PiAr
c3RhdGljIHN0cnVjdCBjbGFzcyBpbnRlbF9pcGNfY2xhc3MgPSB7DQo+ID4+ICsJLm5hbWUgPSAi
aW50ZWxfaXBjIiwNCj4gPj4gKwkub3duZXIgPSBUSElTX01PRFVMRSwNCj4gPj4gK307DQo+ID4+
ICsNCj4gPj4gK3N0YXRpYyBpbnQgaXBjX2Rldl9sb2NrKHN0cnVjdCBpbnRlbF9pcGNfZGV2ICpp
cGNfZGV2KSB7DQo+ID4+ICsJaW50IGNoYW5fdHlwZTsNCj4gPj4gKw0KPiA+PiArCWlmICghaXBj
X2RldiB8fCAhaXBjX2Rldi0+Y2ZnKQ0KPiA+PiArCQlyZXR1cm4gLUVOT0RFVjsNCj4gPj4gKw0K
PiA+PiArCWNoYW5fdHlwZSA9IGlwY19kZXYtPmNmZy0+Y2hhbl90eXBlOw0KPiA+PiArCWlmIChj
aGFuX3R5cGUgPiBJUENfQ0hBTk5FTF9NQVgpDQo+ID4+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+
PiArDQo+ID4+ICsJLyogYWNxdWlyZSBjaGFubmVsIGxvY2sgKi8NCj4gPj4gKwltdXRleF9sb2Nr
KCZjaGFubmVsX2xvY2tbY2hhbl90eXBlXSk7DQo+ID4+ICsNCj4gPj4gKwkvKiBhY3F1aXJlIElQ
QyBkZXZpY2UgbG9jayAqLw0KPiA+PiArCW11dGV4X2xvY2soJmlwY19kZXYtPmxvY2spOw0KPiA+
PiArDQo+ID4+ICsJcmV0dXJuIDA7DQo+ID4+ICt9DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBpbnQg
aXBjX2Rldl91bmxvY2soc3RydWN0IGludGVsX2lwY19kZXYgKmlwY19kZXYpIHsNCj4gPj4gKwlp
bnQgY2hhbl90eXBlOw0KPiA+PiArDQo+ID4+ICsJaWYgKCFpcGNfZGV2IHx8ICFpcGNfZGV2LT5j
ZmcpDQo+ID4+ICsJCXJldHVybiAtRU5PREVWOw0KPiA+PiArDQo+ID4+ICsJY2hhbl90eXBlID0g
aXBjX2Rldi0+Y2ZnLT5jaGFuX3R5cGU7DQo+ID4+ICsJaWYgKGNoYW5fdHlwZSA+IElQQ19DSEFO
TkVMX01BWCkNCj4gPj4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4+ICsNCj4gPj4gKwkvKiByZWxl
YXNlIElQQyBkZXZpY2UgbG9jayAqLw0KPiA+PiArCW11dGV4X3VubG9jaygmaXBjX2Rldi0+bG9j
ayk7DQo+ID4+ICsNCj4gPj4gKwkvKiByZWxlYXNlIGNoYW5uZWwgbG9jayAqLw0KPiA+PiArCW11
dGV4X3VubG9jaygmY2hhbm5lbF9sb2NrW2NoYW5fdHlwZV0pOw0KPiA+PiArDQo+ID4+ICsJcmV0
dXJuIDA7DQo+ID4+ICt9DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBjb25zdCBjaGFyICppcGNfZGV2
X2Vycl9zdHJpbmcoc3RydWN0IGludGVsX2lwY19kZXYgKmlwY19kZXYsDQo+ID4+ICsJaW50IGVy
cm9yKQ0KPiA+PiArew0KPiA+PiArCWlmIChlcnJvciA8IElQQ19ERVZfRVJSX01BWCkNCj4gPj4g
KwkJcmV0dXJuIGlwY19lcnJfc291cmNlc1tlcnJvcl07DQo+ID4+ICsNCj4gPj4gKwlyZXR1cm4g
IlVua25vd24gQ29tbWFuZCI7DQo+ID4+ICt9DQo+ID4+ICsNCj4gPj4gKy8qIEhlbHBlciBmdW5j
dGlvbiB0byBzZW5kIGdpdmVuIGNvbW1hbmQgdG8gSVBDIGRldmljZSAqLyBzdGF0aWMNCj4gPj4g
K2lubGluZSB2b2lkIGlwY19kZXZfc2VuZF9jbWQoc3RydWN0IGludGVsX2lwY19kZXYgKmlwY19k
ZXYsIHUzMiBjbWQpIHsNCj4gPj4gKwlpcGNfZGV2LT5jbWQgPSBjbWQ7DQo+ID4+ICsNCj4gPj4g
KwlpZiAoaXBjX2Rldi0+Y2ZnLT5tb2RlID09IElQQ19ERVZfTU9ERV9JUlEpDQo+ID4+ICsJCXJl
aW5pdF9jb21wbGV0aW9uKCZpcGNfZGV2LT5jbWRfY29tcGxldGUpOw0KPiA+PiArDQo+ID4+ICsJ
aWYgKGlwY19kZXYtPm9wcy0+ZW5hYmxlX21zaSkNCj4gPj4gKwkJY21kID0gaXBjX2Rldi0+b3Bz
LT5lbmFibGVfbXNpKGNtZCk7DQo+ID4+ICsNCj4gPj4gKwlyZWdtYXBfd3JpdGUoaXBjX2Rldi0+
Y2ZnLT5jbWRfcmVncywgaXBjX2Rldi0+Y2ZnLT5jbWRfcmVnLCBjbWQpOw0KPiA+PiB9DQo+ID4+
ICsNCj4gPj4gK3N0YXRpYyBpbmxpbmUgaW50IGlwY19kZXZfc3RhdHVzX2J1c3koc3RydWN0IGlu
dGVsX2lwY19kZXYgKmlwY19kZXYpIHsNCj4gPj4gKwlpbnQgc3RhdHVzOw0KPiA+PiArDQo+ID4+
ICsJcmVnbWFwX3JlYWQoaXBjX2Rldi0+Y2ZnLT5jbWRfcmVncywgaXBjX2Rldi0+Y2ZnLT5zdGF0
dXNfcmVnLA0KPiA+PiArJnN0YXR1cyk7DQo+ID4+ICsNCj4gPj4gKwlpZiAoaXBjX2Rldi0+b3Bz
LT5idXN5X2NoZWNrKQ0KPiA+PiArCQlyZXR1cm4gaXBjX2Rldi0+b3BzLT5idXN5X2NoZWNrKHN0
YXR1cyk7DQo+ID4+ICsNCj4gPj4gKwlyZXR1cm4gMDsNCj4gPj4gK30NCj4gPj4gKw0KPiA+PiAr
LyogQ2hlY2sgdGhlIHN0YXR1cyBvZiBJUEMgY29tbWFuZCBhbmQgcmV0dXJuIGVyciBjb2RlIGlm
IGZhaWxlZCAqLw0KPiA+PiArc3RhdGljIGludCBpcGNfZGV2X2NoZWNrX3N0YXR1cyhzdHJ1Y3Qg
aW50ZWxfaXBjX2RldiAqaXBjX2Rldikgew0KPiA+PiArCWludCBsb29wX2NvdW50ID0gSVBDX0RF
Vl9DTURfTE9PUF9DTlQ7DQo+ID4+ICsJaW50IHN0YXR1czsNCj4gPj4gKwlpbnQgcmV0ID0gMDsN
Cj4gPj4gKw0KPiA+PiArCWlmIChpcGNfZGV2LT5jZmctPm1vZGUgPT0gSVBDX0RFVl9NT0RFX0lS
USkgew0KPiA+PiArCQlpZiAoIXdhaXRfZm9yX2NvbXBsZXRpb25fdGltZW91dCgmaXBjX2Rldi0+
Y21kX2NvbXBsZXRlLA0KPiA+PiArCQkJCUlQQ19ERVZfQ01EX1RJTUVPVVQpKQ0KPiA+PiArCQkJ
cmV0ID0gLUVUSU1FRE9VVDsNCj4gPj4gKwl9IGVsc2Ugew0KPiA+PiArCQl3aGlsZSAoaXBjX2Rl
dl9zdGF0dXNfYnVzeShpcGNfZGV2KSAmJiAtLWxvb3BfY291bnQpDQo+ID4+ICsJCQl1ZGVsYXko
MSk7DQo+ID4+ICsJCWlmICghbG9vcF9jb3VudCkNCj4gPj4gKwkJCXJldCA9IC1FVElNRURPVVQ7
DQo+ID4+ICsJfQ0KPiA+PiArDQo+ID4+ICsJaWYgKHJldCA8IDApIHsNCj4gPj4gKwkJZGV2X2Vy
cigmaXBjX2Rldi0+ZGV2LA0KPiA+PiArCQkJCSJJUEMgdGltZWQgb3V0LCBDTUQ9MHgleFxuIiwg
aXBjX2Rldi0NCj4gPj4+IGNtZCk7DQo+ID4+ICsJCXJldHVybiByZXQ7DQo+ID4+ICsJfQ0KPiA+
PiArDQo+ID4+ICsJcmVnbWFwX3JlYWQoaXBjX2Rldi0+Y2ZnLT5jbWRfcmVncywgaXBjX2Rldi0+
Y2ZnLT5zdGF0dXNfcmVnLA0KPiA+PiArJnN0YXR1cyk7DQo+ID4+ICsNCj4gPj4gKwlpZiAoaXBj
X2Rldi0+b3BzLT50b19lcnJfY29kZSkNCj4gPj4gKwkJcmV0ID0gaXBjX2Rldi0+b3BzLT50b19l
cnJfY29kZShzdGF0dXMpOw0KPiA+PiArDQo+ID4+ICsJaWYgKHJldCkgew0KPiA+PiArCQlkZXZf
ZXJyKCZpcGNfZGV2LT5kZXYsDQo+ID4+ICsJCQkJIklQQyBmYWlsZWQ6ICVzLCBTVFM9MHgleCwg
Q01EPTB4JXhcbiIsDQo+ID4+ICsJCQkJaXBjX2Rldl9lcnJfc3RyaW5nKGlwY19kZXYsIHJldCks
DQo+ID4+ICsJCQkJc3RhdHVzLCBpcGNfZGV2LT5jbWQpOw0KPiA+PiArCQlyZXR1cm4gLUVJTzsN
Cj4gPj4gKwl9DQo+ID4+ICsNCj4gPj4gKwlyZXR1cm4gMDsNCj4gPj4gK30NCj4gPj4gKw0KPiA+
PiArLyoqDQo+ID4+ICsgKiBpcGNfZGV2X3NpbXBsZV9jbWQoKSAtIFNlbmQgc2ltcGxlIElQQyBj
b21tYW5kDQo+ID4+ICsgKiBAaXBjX2RldiAgICAgOiBSZWZlcmVuY2UgdG8gaXBjIGRldmljZS4N
Cj4gPj4gKyAqIEBjbWRfbGlzdCAgICA6IElQQyBjb21tYW5kIGxpc3QuDQo+ID4+ICsgKiBAY21k
bGVuICAgICAgOiBOdW1iZXIgb2YgY21kL3N1Yi1jbWRzLg0KPiA+PiArICoNCj4gPj4gKyAqIFNl
bmQgYSBzaW1wbGUgSVBDIGNvbW1hbmQgdG8gaXBjIGRldmljZS4NCj4gPj4gKyAqIFVzZSB0aGlz
IHdoZW4gZG9uJ3QgbmVlZCB0byBzcGVjaWZ5IGlucHV0L291dHB1dCBkYXRhDQo+ID4+ICsgKiBh
bmQgc291cmNlL2Rlc3QgcG9pbnRlcnMuDQo+ID4+ICsgKg0KPiA+PiArICogUmV0dXJuOglhbiBJ
UEMgZXJyb3IgY29kZSBvciAwIG9uIHN1Y2Nlc3MuDQo+ID4+ICsgKi8NCj4gPj4gKw0KPiA+PiAr
aW50IGlwY19kZXZfc2ltcGxlX2NtZChzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaXBjX2RldiwgdTMy
ICpjbWRfbGlzdCwNCj4gPj4gKwkJdTMyIGNtZGxlbikNCj4gPj4gK3sNCj4gPj4gKwlpbnQgcmV0
Ow0KPiA+PiArDQo+ID4+ICsJaWYgKCFjbWRfbGlzdCkNCj4gPj4gKwkJcmV0dXJuIC1FSU5WQUw7
DQo+ID4+ICsNCj4gPj4gKwlyZXQgPSBpcGNfZGV2X2xvY2soaXBjX2Rldik7DQo+ID4+ICsJaWYg
KHJldCkNCj4gPj4gKwkJcmV0dXJuIHJldDsNCj4gPj4gKw0KPiA+PiArCS8qIENhbGwgY3VzdG9t
IHByZS1wcm9jZXNzaW5nIGhhbmRsZXIgKi8NCj4gPj4gKwlpZiAoaXBjX2Rldi0+b3BzLT5wcmVf
c2ltcGxlX2NtZF9mbikgew0KPiA+PiArCQlyZXQgPSBpcGNfZGV2LT5vcHMtPnByZV9zaW1wbGVf
Y21kX2ZuKGNtZF9saXN0LCBjbWRsZW4pOw0KPiA+PiArCQlpZiAocmV0KQ0KPiA+PiArCQkJZ290
byB1bmxvY2tfZGV2aWNlOw0KPiA+PiArCX0NCj4gPj4gKw0KPiA+PiArCWlwY19kZXZfc2VuZF9j
bWQoaXBjX2RldiwgY21kX2xpc3RbMF0pOw0KPiA+PiArDQo+ID4+ICsJcmV0ID0gaXBjX2Rldl9j
aGVja19zdGF0dXMoaXBjX2Rldik7DQo+ID4+ICsNCj4gPj4gK3VubG9ja19kZXZpY2U6DQo+ID4+
ICsJaXBjX2Rldl91bmxvY2soaXBjX2Rldik7DQo+ID4+ICsNCj4gPj4gKwlyZXR1cm4gcmV0Ow0K
PiA+PiArfQ0KPiA+PiArRVhQT1JUX1NZTUJPTF9HUEwoaXBjX2Rldl9zaW1wbGVfY21kKTsNCj4g
Pj4gKw0KPiA+PiArLyoqDQo+ID4+ICsgKiBpcGNfZGV2X2NtZCgpIC0gU2VuZCBJUEMgY29tbWFu
ZCB3aXRoIGRhdGEuDQo+ID4+ICsgKiBAaXBjX2RldiAgICAgOiBSZWZlcmVuY2UgdG8gaXBjX2Rl
di4NCj4gPj4gKyAqIEBjbWRfbGlzdCAgICA6IEFycmF5IG9mIGNvbW1hbmRzL3N1Yi1jb21tYW5k
cy4NCj4gPj4gKyAqIEBjbWRsZW4gICAgICA6IE51bWJlciBvZiBjb21tYW5kcy4NCj4gPj4gKyAq
IEBpbiAgICAgICAgICA6IElucHV0IGRhdGEgb2YgdGhpcyBJUEMgY29tbWFuZC4NCj4gPj4gKyAq
IEBpbmxlbiAgICAgICA6IElucHV0IGRhdGEgbGVuZ3RoIGluIGR3b3Jkcy4NCj4gPj4gKyAqIEBv
dXQgICAgICAgICA6IE91dHB1dCBkYXRhIG9mIHRoaXMgSVBDIGNvbW1hbmQuDQo+ID4+ICsgKiBA
b3V0bGVuICAgICAgOiBMZW5ndGggb2Ygb3V0cHV0IGRhdGEgaW4gZHdvcmRzLg0KPiA+PiArICoN
Cj4gPj4gKyAqIFNlbmQgYW4gSVBDIGNvbW1hbmQgdG8gZGV2aWNlIHdpdGggaW5wdXQvb3V0cHV0
IGRhdGEuDQo+ID4+ICsgKg0KPiA+PiArICogUmV0dXJuOglhbiBJUEMgZXJyb3IgY29kZSBvciAw
IG9uIHN1Y2Nlc3MuDQo+ID4+ICsgKi8NCj4gPj4gK2ludCBpcGNfZGV2X2NtZChzdHJ1Y3QgaW50
ZWxfaXBjX2RldiAqaXBjX2RldiwgdTMyICpjbWRfbGlzdCwgdTMyDQo+IGNtZGxlbiwNCj4gPj4g
KwkJdTMyICppbiwgdTMyIGlubGVuLCB1MzIgKm91dCwgdTMyIG91dGxlbikgew0KPiA+PiArCWlu
dCByZXQ7DQo+ID4+ICsNCj4gPj4gKwlpZiAoIWNtZF9saXN0IHx8ICFpbikNCj4gPj4gKwkJcmV0
dXJuIC1FSU5WQUw7DQo+ID4+ICsNCj4gPj4gKwlyZXQgPSBpcGNfZGV2X2xvY2soaXBjX2Rldik7
DQo+ID4+ICsJaWYgKHJldCkNCj4gPj4gKwkJcmV0dXJuIHJldDsNCj4gPj4gKw0KPiA+PiArCS8q
IENhbGwgY3VzdG9tIHByZS1wcm9jZXNzaW5nIGhhbmRsZXIuICovDQo+ID4+ICsJaWYgKGlwY19k
ZXYtPm9wcy0+cHJlX2NtZF9mbikgew0KPiA+PiArCQlyZXQgPSBpcGNfZGV2LT5vcHMtPnByZV9j
bWRfZm4oY21kX2xpc3QsIGNtZGxlbiwgaW4sIGlubGVuLA0KPiA+PiArCQkJCW91dCwgb3V0bGVu
KTsNCj4gPj4gKwkJaWYgKHJldCkNCj4gPj4gKwkJCWdvdG8gdW5sb2NrX2RldmljZTsNCj4gPj4g
Kwl9DQo+ID4+ICsNCj4gPj4gKwkvKiBXcml0ZSBpbmxlbiBkd29yZHMgb2YgZGF0YSB0byB3cmJ1
Zl9yZWcuICovDQo+ID4+ICsJaWYgKGlubGVuID4gMCkNCj4gPj4gKwkJcmVnbWFwX2J1bGtfd3Jp
dGUoaXBjX2Rldi0+Y2ZnLT5kYXRhX3JlZ3MsDQo+ID4+ICsJCQkJaXBjX2Rldi0+Y2ZnLT53cmJ1
Zl9yZWcsIGluLCBpbmxlbik7DQo+ID4+ICsNCj4gPj4gKwlpcGNfZGV2X3NlbmRfY21kKGlwY19k
ZXYsIGNtZF9saXN0WzBdKTsNCj4gPj4gKw0KPiA+PiArCXJldCA9IGlwY19kZXZfY2hlY2tfc3Rh
dHVzKGlwY19kZXYpOw0KPiA+PiArDQo+ID4+ICsJLyogUmVhZCBvdXRsZW4gZHdvcmRzIG9mIGRh
dGEgZnJvbSByYnVnX3JlZy4gKi8NCj4gPj4gKwlpZiAoIXJldCAmJiBvdXRsZW4gPiAwKQ0KPiA+
PiArCQlyZWdtYXBfYnVsa19yZWFkKGlwY19kZXYtPmNmZy0+ZGF0YV9yZWdzLA0KPiA+PiArCQkJ
CWlwY19kZXYtPmNmZy0+cmJ1Zl9yZWcsIG91dCwgb3V0bGVuKTsNCj4gPj4gK3VubG9ja19kZXZp
Y2U6DQo+ID4+ICsJaXBjX2Rldl91bmxvY2soaXBjX2Rldik7DQo+ID4+ICsNCj4gPj4gKwlyZXR1
cm4gcmV0Ow0KPiA+PiArfQ0KPiA+PiArRVhQT1JUX1NZTUJPTF9HUEwoaXBjX2Rldl9jbWQpOw0K
PiA+PiArDQo+ID4+ICsvKioNCj4gPj4gKyAqIGlwY19kZXZfcmF3X2NtZCgpIC0gU2VuZCBJUEMg
Y29tbWFuZCB3aXRoIGRhdGEgYW5kIHBvaW50ZXJzLg0KPiA+PiArICogQGlwY19kZXYgICAgIDog
UmVmZXJlbmNlIHRvIGlwY19kZXYuDQo+ID4+ICsgKiBAY21kX2xpc3QgICAgOiBBcnJheSBvZiBj
b21tYW5kcy9zdWItY29tbWFuZHMuDQo+ID4+ICsgKiBAY21kbGVuICAgICAgOiBOdW1iZXIgb2Yg
Y29tbWFuZHMuDQo+ID4+ICsgKiBAaW4gICAgICAgICAgOiBJbnB1dCBkYXRhIG9mIHRoaXMgSVBD
IGNvbW1hbmQuDQo+ID4+ICsgKiBAaW5sZW4gICAgICAgOiBJbnB1dCBkYXRhIGxlbmd0aCBpbiBi
eXRlcy4NCj4gPj4gKyAqIEBvdXQgICAgICAgICA6IE91dHB1dCBkYXRhIG9mIHRoaXMgSVBDIGNv
bW1hbmQuDQo+ID4+ICsgKiBAb3V0bGVuICAgICAgOiBMZW5ndGggb2Ygb3V0cHV0IGRhdGEgaW4g
ZHdvcmRzLg0KPiA+PiArICogQGRwdHIgICAgICAgIDogSVBDIGRlc3RpbmF0aW9uIGRhdGEgYWRk
cmVzcy4NCj4gPj4gKyAqIEBzcHRyICAgICAgICA6IElQQyBzb3VyY2UgZGF0YSBhZGRyZXNzLg0K
PiA+PiArICoNCj4gPj4gKyAqIFNlbmQgYW4gSVBDIGNvbW1hbmQgdG8gZGV2aWNlIHdpdGggaW5w
dXQvb3V0cHV0IGRhdGEgYW5kDQo+ID4+ICsgKiBzb3VyY2UvZGVzdCBwb2ludGVycy4NCj4gPj4g
KyAqDQo+ID4+ICsgKiBSZXR1cm46CWFuIElQQyBlcnJvciBjb2RlIG9yIDAgb24gc3VjY2Vzcy4N
Cj4gPj4gKyAqLw0KPiA+IFNvcnJ5IGZvciBjb21pbmcgaW4gc28gbGF0ZSBidXQgc2luY2Ugd2Ug
YXJlIHJlZmFjdG9yaW5nIHRoZSBBUEkNCj4gPiBhbnl3YXlzLCBpc24ndCBpdCBiZXR0ZXIgdG8g
cmVkdWNlIHRoZSBzaWduYXR1cmU/IE5pbmUgcGFyYW1ldGVycyBpcw0KPiA+IGFuIGF3ZnVsIGxv
dCBhbmQgcHJvbmUgdG8gZXJyb3JzIGFuZCBkaWZmaWN1bHQgdG8gZGVidWcuIChXZSBmb3VuZCBp
dA0KPiA+IG91dCB0aGUgaGFyZCB3YXkgd2hlbiB3ZSBzdGFydGVkIHVzaW5nIHRoaXMgYSBmZXcg
eWVhcnMgYWdvLikNCj4gSSBhZ3JlZS4gSW5pdGlhbGx5IEkgdGhvdWdodCBvZiBhZGRpbmcgYSBj
b21tYW5kIHN0cnVjdHVyZSBqdXN0IGxpa2UgeW91DQo+IG1lbnRpb25lZC4gQnV0IGZpbmFsbHkg
ZGVjaWRlZCBub3QgdG8gZG8gaXQgYmVjYXVzZSwNCj4gDQo+IDEuIE5vdCBhbGwgZHJpdmVycyB1
c2VzIGFsbCBwYXJhbWV0ZXJzIG9mIHRoaXMgQVBJLiBNb3N0IG9mIHRoZW0gcGFzcw0KPiAwLDAg
Zm9yIERQVFIgYW5kIFNQVFIgcG9pbnRlcnMuIFNvIHRoZSBsYXN0IHR3byBhcmd1bWVudHMgYXJl
IGFsbW9zdCBub3QNCj4gdXNlZC4NCj4gMi4gQWRkaW5nIGEgbmV3IHN0cnVjdHVyZSByZXF1aXJl
cyBhbGwgdXNlcnMgb2YgdGhpcyBBUEkgdG8gYWRkIGJ1ZmZlciBjb2RlIC8NCj4gc29tZSBhZGRp
dGlvbmFsIGNhbGwgdG8gaW5pdGlhbGl6ZSB0aGUgY29tbWFuZCBzdHJ1Y3R1cmUgd2hpY2ggaW4g
dHVybiBtYWtlcw0KPiB0aGUgY29kZSBsb29rIGJpdCBjb21wbGV4Lg0KPiANCk9uZSBjYW4gY29t
YmluZSBTUFRSL0RQVFIgaW50byBhIHNlcGFyYXRlIHN0cnVjdCBjb3VsZCBkaXJlY3RseSBiZSBw
YXNzZWQgYXMgTlVMTCBmb3IgdXNlcnMgd2hvIGFyZSBub3QgaW50ZXJlc3RlZC4gVGhhdCB3b3Vs
ZCB0YWtlIGNhcmUgb2Ygc29tZSBjb21wbGV4aXR5Lg0KRm9yIHRoZSByZXN0IG9mIHRoZSBwYXJh
bWV0ZXJzLCByZXF1aXJpbmcgdGhlIHVzZXIgdG8gcG9wdWxhdGUgYSBzdHJ1Y3QgZm9yIGNtZF9w
YXJhbXMgY291bGQgYWN0dWFsbHkgYmUgdXNlZnVsLiBTaW5jZSB0aGUgdXNlciB3aWxsIGJlIHJl
cXVpcmVkIHRvIHNwZWNpZmljYWxseSBpbml0aWFsaXplIGVhY2ggcGFyYW1ldGVyIGJ5IG5hbWUs
IGl0IG1heSBwcmV2ZW50IGFjY2lkZW50YWwganVtYmxpbmcgb2YgcGFyYW1ldGVycyAobGlrZSBt
aXhpbmcgdXAgaW4vb3V0IGV0Yy4pIHZpcy1hLXZpcyBwYXNzaW5nIGFsbCBuaW5lIHBhcmFtZXRl
cnMgaW4gYSByb3cuDQpQbHVzIGl0IHdpbGwgYmUgYSBsb3QgYmV0dGVyIGZyb20gdGhlIHJlYWRh
YmlsaXR5IHBlcnNwZWN0aXZlLg0KU28gZnJvbSBteSBwb2ludCBvZiB2aWV3LCB0aGUgbGl0dGxl
IGNtZF9wYXJhbSBhc3NpZ25tZW50IG92ZXJoZWFkIGlzIHdvcnRoIHRoZSBiZW5lZml0cyBpbiBy
ZWFkYWJpbGl0eSArIHByZXZlbnRpbmcgYWNjaWRlbnRhbCBidWcgaW5zZXJ0aW9ucyArIGVhc2Ug
b2YgZGVidWcuDQpGV0lXIEkgaGF2ZSBub3Qgc2VlbiBzaXgrIHBhcmFtZXRlcnMgZm9yIGFueSBB
UEkgaW4gTGludXguDQoNCj4gU28gSSBhbSBub3QgcmVhbGx5IHN1cmUgd2hldGhlciBpdCBhZGQg
YW55IHZhbHVlLiBCdXQgaWYgaXRzIHRoZSByZWNvbW1lbmRlZA0KPiBhcHByb2FjaCB0aGVuIEkg
d2lsbCBtYWtlIHRoYXQgbW9kaWZpY2F0aW9uLg0KPiA+IFRoaXMgY2FuIGJlIGNvbnNvbGlkYXRl
ZCBpbnRvIGEgZmV3IG5lYXQgc3RydWN0cywgZS5nLiw6DQo+ID4gaW50IGlwY19kZXZfcmF3X2Nt
ZChzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaXBjX2Rldiwgc3RydWN0IGlwY19jbWQgKmNtZCwNCj4g
PiAJCXN0cnVjdCBpcGNfY21kX2RhdGEgKmNtZF9kYXRhLCBzdHJ1Y3QgaXBjX2RhdGFfYWRkciAq
YWRkcikNCj4gPg0KPiA+IFNhbWUgZm9yIHRoZSBpcGNfZGV2X2NtZCgpIEFQSXMgYWJvdmUgYXMg
d2VsbC4NCj4gPg0KPiA+PiArDQo+ID4+ICtpbnQgaXBjX2Rldl9yYXdfY21kKHN0cnVjdCBpbnRl
bF9pcGNfZGV2ICppcGNfZGV2LCB1MzIgKmNtZF9saXN0LA0KPiA+PiArdTMyDQo+ID4+IGNtZGxl
biwNCj4gPj4gKwkJdTggKmluLCB1MzIgaW5sZW4sIHUzMiAqb3V0LCB1MzIgb3V0bGVuLCB1MzIg
ZHB0ciwgdTMyIHNwdHIpIHsNCj4gPj4gKwlpbnQgcmV0Ow0KPiA+PiArCWludCBpbmJ1ZmxlbiA9
IERJVl9ST1VORF9VUChpbmxlbiwgNCk7DQo+ID4+ICsJdTMyICppbmJ1ZjsNCj4gPj4gKw0KPiA+
PiArCWlmICghY21kX2xpc3QgfHwgIWluKQ0KPiA+PiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPj4g
Kw0KPiA+PiArCWluYnVmID0ga3phbGxvYyhpbmJ1ZmxlbiwgR0ZQX0tFUk5FTCk7DQo+ID4+ICsJ
aWYgKCFpbmJ1ZikNCj4gPj4gKwkJcmV0dXJuIC1FTk9NRU07DQo+ID4+ICsNCj4gPj4gKwlyZXQg
PSBpcGNfZGV2X2xvY2soaXBjX2Rldik7DQo+ID4+ICsJaWYgKHJldCkNCj4gPj4gKwkJcmV0dXJu
IHJldDsNCj4gPj4gKw0KPiA+PiArCS8qIENhbGwgY3VzdG9tIHByZS1wcm9jZXNzaW5nIGhhbmRs
ZXIuICovDQo+ID4+ICsJaWYgKGlwY19kZXYtPm9wcy0+cHJlX3Jhd19jbWRfZm4pIHsNCj4gPj4g
KwkJcmV0ID0gaXBjX2Rldi0+b3BzLT5wcmVfcmF3X2NtZF9mbihjbWRfbGlzdCwgY21kbGVuLCBp
biwNCj4gPj4gaW5sZW4sDQo+ID4+ICsJCQkJb3V0LCBvdXRsZW4sIGRwdHIsIHNwdHIpOw0KPiA+
PiArCQlpZiAocmV0KQ0KPiA+PiArCQkJZ290byB1bmxvY2tfZGV2aWNlOw0KPiA+PiArCX0NCj4g
Pj4gKw0KPiA+PiArCS8qIElmIHN1cHBvcnRlZCwgd3JpdGUgRFBUUiByZWdpc3Rlci4qLw0KPiA+
PiArCWlmIChpcGNfZGV2LT5jZmctPnN1cHBvcnRfZHB0cikNCj4gPj4gKwkJcmVnbWFwX3dyaXRl
KGlwY19kZXYtPmNmZy0+Y21kX3JlZ3MsIGlwY19kZXYtPmNmZy0NCj4gPj4+IGRwdHJfcmVnLA0K
PiA+PiArCQkJCWRwdHIpOw0KPiA+PiArDQo+ID4+ICsJLyogSWYgc3VwcG9ydGVkLCB3cml0ZSBT
UFRSIHJlZ2lzdGVyLiAqLw0KPiA+PiArCWlmIChpcGNfZGV2LT5jZmctPnN1cHBvcnRfc3B0cikN
Cj4gPj4gKwkJcmVnbWFwX3dyaXRlKGlwY19kZXYtPmNmZy0+Y21kX3JlZ3MsIGlwY19kZXYtPmNm
Zy0NCj4gPj4+IHNwdHJfcmVnLA0KPiA+PiArCQkJCXNwdHIpOw0KPiA+PiArDQo+ID4+ICsJbWVt
Y3B5KGluYnVmLCBpbiwgaW5sZW4pOw0KPiA+PiArDQo+ID4+ICsJLyogV3JpdGUgaW5sZW4gZHdv
cmRzIG9mIGRhdGEgdG8gd3JidWZfcmVnLiAqLw0KPiA+PiArCWlmIChpbmxlbiA+IDApDQo+ID4+
ICsJCXJlZ21hcF9idWxrX3dyaXRlKGlwY19kZXYtPmNmZy0+ZGF0YV9yZWdzLA0KPiA+PiArCQkJ
CWlwY19kZXYtPmNmZy0+d3JidWZfcmVnLCBpbmJ1ZiwgaW5idWZsZW4pOw0KPiA+PiArDQo+ID4+
ICsJaXBjX2Rldl9zZW5kX2NtZChpcGNfZGV2LCBjbWRfbGlzdFswXSk7DQo+ID4+ICsNCj4gPj4g
KwlyZXQgPSBpcGNfZGV2X2NoZWNrX3N0YXR1cyhpcGNfZGV2KTsNCj4gPj4gKw0KPiA+PiArCS8q
IFJlYWQgb3V0bGVuIGR3b3JkcyBvZiBkYXRhIGZyb20gcmJ1Z19yZWcuICovDQo+ID4+ICsJaWYg
KCFyZXQgJiYgb3V0bGVuID4gMCkNCj4gPj4gKwkJcmVnbWFwX2J1bGtfcmVhZChpcGNfZGV2LT5j
ZmctPmRhdGFfcmVncywNCj4gPj4gKwkJCQlpcGNfZGV2LT5jZmctPnJidWZfcmVnLCBvdXQsIG91
dGxlbik7DQo+ID4+ICt1bmxvY2tfZGV2aWNlOg0KPiA+PiArCWlwY19kZXZfdW5sb2NrKGlwY19k
ZXYpOw0KPiA+PiArCWtmcmVlKGluYnVmKTsNCj4gPj4gKw0KPiA+PiArCXJldHVybiByZXQ7DQo+
ID4+ICt9DQo+ID4+ICtFWFBPUlRfU1lNQk9MX0dQTChpcGNfZGV2X3Jhd19jbWQpOw0KPiA+PiAr
DQo+ID4+ICsvKiBzeXNmcyBvcHRpb24gdG8gc2VuZCBzaW1wbGUgSVBDIGNvbW1hbmRzIGZyb20g
dXNlcnNwYWNlICovIHN0YXRpYw0KPiA+PiArc3NpemVfdCBpcGNfZGV2X2NtZF9yZWdfc3RvcmUo
c3RydWN0IGRldmljZSAqZGV2LA0KPiA+PiArCQkJCSAgICAgc3RydWN0IGRldmljZV9hdHRyaWJ1
dGUgKmF0dHIsDQo+ID4+ICsJCQkJICAgICBjb25zdCBjaGFyICpidWYsIHNpemVfdCBjb3VudCkg
ew0KPiA+PiArCXN0cnVjdCBpbnRlbF9pcGNfZGV2ICppcGNfZGV2ID0gZGV2X2dldF9kcnZkYXRh
KGRldik7DQo+ID4+ICsJdTMyIGNtZDsNCj4gPj4gKwlpbnQgcmV0Ow0KPiA+PiArDQo+ID4+ICsJ
cmV0ID0gc3NjYW5mKGJ1ZiwgIiVkIiwgJmNtZCk7DQo+ID4+ICsJaWYgKHJldCAhPSAxKSB7DQo+
ID4+ICsJCWRldl9lcnIoZGV2LCAiRXJyb3IgYXJnc1xuIik7DQo+ID4+ICsJCXJldHVybiAtRUlO
VkFMOw0KPiA+PiArCX0NCj4gPj4gKw0KPiA+PiArCXJldCA9IGlwY19kZXZfc2ltcGxlX2NtZChp
cGNfZGV2LCAmY21kLCAxKTsNCj4gPj4gKwlpZiAocmV0KSB7DQo+ID4+ICsJCWRldl9lcnIoZGV2
LCAiY29tbWFuZCAweCV4IGVycm9yIHdpdGggJWRcbiIsIGNtZCwgcmV0KTsNCj4gPj4gKwkJcmV0
dXJuIHJldDsNCj4gPj4gKwl9DQo+ID4+ICsJcmV0dXJuIChzc2l6ZV90KWNvdW50Ow0KPiA+PiAr
fQ0KPiA+PiArDQo+ID4+ICtzdGF0aWMgREVWSUNFX0FUVFIoc2VuZF9jbWQsIFNfSVdVU1IsIE5V
TEwsIGlwY19kZXZfY21kX3JlZ19zdG9yZSk7DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBzdHJ1Y3Qg
YXR0cmlidXRlICppcGNfZGV2X2F0dHJzW10gPSB7DQo+ID4+ICsJJmRldl9hdHRyX3NlbmRfY21k
LmF0dHIsDQo+ID4+ICsJTlVMTA0KPiA+PiArfTsNCj4gPj4gKw0KPiA+PiArc3RhdGljIGNvbnN0
IHN0cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgaXBjX2Rldl9ncm91cCA9IHsNCj4gPj4gKwkuYXR0cnMg
PSBpcGNfZGV2X2F0dHJzLA0KPiA+PiArfTsNCj4gPj4gKw0KPiA+PiArc3RhdGljIGNvbnN0IHN0
cnVjdCBhdHRyaWJ1dGVfZ3JvdXAgKmlwY19kZXZfZ3JvdXBzW10gPSB7DQo+ID4+ICsJJmlwY19k
ZXZfZ3JvdXAsDQo+ID4+ICsJTlVMTCwNCj4gPj4gK307DQo+ID4+ICsNCj4gPj4gKy8qIElQQyBk
ZXZpY2UgSVJRIGhhbmRsZXIgKi8NCj4gPj4gK3N0YXRpYyBpcnFyZXR1cm5fdCBpcGNfZGV2X2ly
cV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRldl9pZCkgew0KPiA+PiArCXN0cnVjdCBpbnRlbF9p
cGNfZGV2ICppcGNfZGV2ID0gKHN0cnVjdCBpbnRlbF9pcGNfZGV2ICopZGV2X2lkOw0KPiA+PiAr
DQo+ID4+ICsJaWYgKGlwY19kZXYtPm9wcy0+cHJlX2lycV9oYW5kbGVyX2ZuKQ0KPiA+PiArCQlp
cGNfZGV2LT5vcHMtPnByZV9pcnFfaGFuZGxlcl9mbihpcGNfZGV2LCBpcnEpOw0KPiA+PiArDQo+
ID4+ICsJY29tcGxldGUoJmlwY19kZXYtPmNtZF9jb21wbGV0ZSk7DQo+ID4+ICsNCj4gPj4gKwly
ZXR1cm4gSVJRX0hBTkRMRUQ7DQo+ID4+ICt9DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyB2b2lkIGRl
dm1faW50ZWxfaXBjX2Rldl9yZWxlYXNlKHN0cnVjdCBkZXZpY2UgKmRldiwgdm9pZCAqcmVzKSB7
DQo+ID4+ICsJc3RydWN0IGludGVsX2lwY19kZXYgKmlwY19kZXYgPSAqKHN0cnVjdCBpbnRlbF9p
cGNfZGV2ICoqKXJlczsNCj4gPj4gKw0KPiA+PiArCWlmICghaXBjX2RldikNCj4gPj4gKwkJcmV0
dXJuOw0KPiA+PiArDQo+ID4+ICsJZGV2aWNlX2RlbCgmaXBjX2Rldi0+ZGV2KTsNCj4gPj4gKw0K
PiA+PiArCWtmcmVlKGlwY19kZXYpOw0KPiA+PiArfQ0KPiA+PiArDQo+ID4+ICtzdGF0aWMgaW50
IG1hdGNoX25hbWUoc3RydWN0IGRldmljZSAqZGV2LCBjb25zdCB2b2lkICpkYXRhKSB7DQo+ID4+
ICsgICAgICAgIGlmICghZGV2X25hbWUoZGV2KSkNCj4gPj4gKyAgICAgICAgICAgICAgICByZXR1
cm4gMDsNCj4gPj4gKw0KPiA+PiArICAgICAgICByZXR1cm4gIXN0cmNtcChkZXZfbmFtZShkZXYp
LCAoY2hhciAqKWRhdGEpOyB9DQo+ID4+ICsNCj4gPj4gKy8qKg0KPiA+PiArICogaW50ZWxfaXBj
X2Rldl9nZXQoKSAtIEdldCBJbnRlbCBJUEMgZGV2aWNlIGZyb20gbmFtZS4NCj4gPj4gKyAqIEBk
ZXZfbmFtZSAgICA6IE5hbWUgb2YgdGhlIElQQyBkZXZpY2UuDQo+ID4+ICsgKg0KPiA+PiArICog
UmV0dXJuICAgICAgIDogRVJSX1BUUi9OVUxMIG9yIGludGVsX2lwY19kZXYgcG9pbnRlciBvbiBz
dWNjZXNzLg0KPiA+PiArICovDQo+ID4+ICtzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaW50ZWxfaXBj
X2Rldl9nZXQoY29uc3QgY2hhciAqZGV2X25hbWUpIHsNCj4gPj4gKyAgICAgICAgc3RydWN0IGRl
dmljZSAqZGV2Ow0KPiA+PiArDQo+ID4+ICsJaWYgKCFkZXZfbmFtZSkNCj4gPj4gKwkJcmV0dXJu
IEVSUl9QVFIoLUVJTlZBTCk7DQo+ID4+ICsNCj4gPj4gKwlkZXYgPSBjbGFzc19maW5kX2Rldmlj
ZSgmaW50ZWxfaXBjX2NsYXNzLCBOVUxMLCBkZXZfbmFtZSwNCj4gPj4gbWF0Y2hfbmFtZSk7DQo+
ID4+ICsNCj4gPj4gKwlyZXR1cm4gZGV2ID8gZGV2X2dldF9kcnZkYXRhKGRldikgOiBOVUxMOyB9
DQo+ID4+ICtFWFBPUlRfU1lNQk9MX0dQTChpbnRlbF9pcGNfZGV2X2dldCk7DQo+ID4+ICsNCj4g
Pj4gK3N0YXRpYyB2b2lkIGRldm1faW50ZWxfaXBjX2Rldl9wdXQoc3RydWN0IGRldmljZSAqZGV2
LCB2b2lkICpyZXMpIHsNCj4gPj4gKwlpbnRlbF9pcGNfZGV2X3B1dCgqKHN0cnVjdCBpbnRlbF9p
cGNfZGV2ICoqKXJlcyk7IH0NCj4gPj4gKw0KPiA+PiArLyoqDQo+ID4+ICsgKiBkZXZtX2ludGVs
X2lwY19kZXZfZ2V0KCkgLSBSZXNvdXJjZSBtYW5hZ2VkIHZlcnNpb24gb2YNCj4gPj4gaW50ZWxf
aXBjX2Rldl9nZXQoKS4NCj4gPj4gKyAqIEBkZXYgICAgICAgICA6IERldmljZSBwb2ludGVyLg0K
PiA+PiArICogQGRldl9uYW1lICAgIDogTmFtZSBvZiB0aGUgSVBDIGRldmljZS4NCj4gPj4gKyAq
DQo+ID4+ICsgKiBSZXR1cm4gICAgICAgOiBFUlJfUFRSL05VTEwgb3IgaW50ZWxfaXBjX2RldiBw
b2ludGVyIG9uIHN1Y2Nlc3MuDQo+ID4+ICsgKi8NCj4gPj4gK3N0cnVjdCBpbnRlbF9pcGNfZGV2
ICpkZXZtX2ludGVsX2lwY19kZXZfZ2V0KHN0cnVjdCBkZXZpY2UgKmRldiwNCj4gPj4gKwkJCQkJ
Y29uc3QgY2hhciAqZGV2X25hbWUpDQo+ID4+ICt7DQo+ID4+ICsJc3RydWN0IGludGVsX2lwY19k
ZXYgKipwdHIsICppcGNfZGV2Ow0KPiA+PiArDQo+ID4+ICsJcHRyID0gZGV2cmVzX2FsbG9jKGRl
dm1faW50ZWxfaXBjX2Rldl9wdXQsIHNpemVvZigqcHRyKSwNCj4gPj4gR0ZQX0tFUk5FTCk7DQo+
ID4+ICsJaWYgKCFwdHIpDQo+ID4+ICsJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOw0KPiA+PiAr
DQo+ID4+ICsJaXBjX2RldiA9IGludGVsX2lwY19kZXZfZ2V0KGRldl9uYW1lKTsNCj4gPj4gKwlp
ZiAoIUlTX0VSUl9PUl9OVUxMKGlwY19kZXYpKSB7DQo+ID4+ICsJCSpwdHIgPSBpcGNfZGV2Ow0K
PiA+PiArCQlkZXZyZXNfYWRkKGRldiwgcHRyKTsNCj4gPj4gKwl9IGVsc2Ugew0KPiA+PiArCQlk
ZXZyZXNfZnJlZShwdHIpOw0KPiA+PiArCX0NCj4gPj4gKw0KPiA+PiArCXJldHVybiBpcGNfZGV2
Ow0KPiA+PiArfQ0KPiA+PiArRVhQT1JUX1NZTUJPTF9HUEwoZGV2bV9pbnRlbF9pcGNfZGV2X2dl
dCk7DQo+ID4+ICsNCj4gPj4gKy8qKg0KPiA+PiArICogZGV2bV9pbnRlbF9pcGNfZGV2X2NyZWF0
ZSgpIC0gQ3JlYXRlIElQQyBkZXZpY2UNCj4gPj4gKyAqIEBkZXYJCTogSVBDIHBhcmVudCBkZXZp
Y2UuDQo+ID4+ICsgKiBAZGV2bmFtZQk6IE5hbWUgb2YgdGhlIElQQyBkZXZpY2UuDQo+ID4+ICsg
KiBAY2ZnCQk6IElQQyBkZXZpY2UgY29uZmlndXJhdGlvbi4NCj4gPj4gKyAqIEBvcHMJCTogSVBD
IGRldmljZSBvcHMuDQo+ID4+ICsgKg0KPiA+PiArICogUmVzb3VyY2UgbWFuYWdlZCBBUEkgdG8g
Y3JlYXRlIElQQyBkZXZpY2Ugd2l0aA0KPiA+PiArICogZ2l2ZW4gY29uZmlndXJhdGlvbi4NCj4g
Pj4gKyAqDQo+ID4+ICsgKiBSZXR1cm4JOiBJUEMgZGV2aWNlIHBvaW50ZXIgb3IgRVJSX1BUUihl
cnJvciBjb2RlKS4NCj4gPj4gKyAqLw0KPiA+PiArc3RydWN0IGludGVsX2lwY19kZXYgKmRldm1f
aW50ZWxfaXBjX2Rldl9jcmVhdGUoc3RydWN0IGRldmljZSAqZGV2LA0KPiA+PiArCQljb25zdCBj
aGFyICpkZXZuYW1lLA0KPiA+PiArCQlzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9jZmcgKmNmZywNCj4g
Pj4gKwkJc3RydWN0IGludGVsX2lwY19kZXZfb3BzICpvcHMpDQo+ID4+ICt7DQo+ID4+ICsJc3Ry
dWN0IGludGVsX2lwY19kZXYgKipwdHIsICppcGNfZGV2Ow0KPiA+PiArCWludCByZXQ7DQo+ID4+
ICsNCj4gPj4gKwlpZiAoIWRldiAmJiAhZGV2bmFtZSAmJiAhY2ZnKQ0KPiA+PiArCQlyZXR1cm4g
RVJSX1BUUigtRUlOVkFMKTsNCj4gPj4gKw0KPiA+PiArCWlmIChpbnRlbF9pcGNfZGV2X2dldChk
ZXZuYW1lKSkgew0KPiA+PiArCQlkZXZfZXJyKGRldiwgIklQQyBkZXZpY2UgJXMgYWxyZWFkeSBl
eGlzdFxuIiwgZGV2bmFtZSk7DQo+ID4+ICsJCXJldHVybiBFUlJfUFRSKC1FSU5WQUwpOw0KPiA+
PiArCX0NCj4gPj4gKw0KPiA+PiArCXB0ciA9IGRldnJlc19hbGxvYyhkZXZtX2ludGVsX2lwY19k
ZXZfcmVsZWFzZSwgc2l6ZW9mKCpwdHIpLA0KPiA+PiArCQkJR0ZQX0tFUk5FTCk7DQo+ID4+ICsJ
aWYgKCFwdHIpDQo+ID4+ICsJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOw0KPiA+PiArDQo+ID4+
ICsJaXBjX2RldiA9IGt6YWxsb2Moc2l6ZW9mKCppcGNfZGV2KSwgR0ZQX0tFUk5FTCk7DQo+ID4+
ICsJaWYgKCFpcGNfZGV2KSB7DQo+ID4+ICsJCXJldCA9IC1FTk9NRU07DQo+ID4+ICsJCWdvdG8g
ZXJyX2Rldl9jcmVhdGU7DQo+ID4+ICsJfQ0KPiA+PiArDQo+ID4+ICsJaXBjX2Rldi0+ZGV2LmNs
YXNzID0gJmludGVsX2lwY19jbGFzczsNCj4gPj4gKwlpcGNfZGV2LT5kZXYucGFyZW50ID0gZGV2
Ow0KPiA+PiArCWlwY19kZXYtPmRldi5ncm91cHMgPSBpcGNfZGV2X2dyb3VwczsNCj4gPj4gKwlp
cGNfZGV2LT5jZmcgPSBjZmc7DQo+ID4+ICsJaXBjX2Rldi0+b3BzID0gb3BzOw0KPiA+PiArDQo+
ID4+ICsJbXV0ZXhfaW5pdCgmaXBjX2Rldi0+bG9jayk7DQo+ID4+ICsJaW5pdF9jb21wbGV0aW9u
KCZpcGNfZGV2LT5jbWRfY29tcGxldGUpOw0KPiA+PiArCWRldl9zZXRfZHJ2ZGF0YSgmaXBjX2Rl
di0+ZGV2LCBpcGNfZGV2KTsNCj4gPj4gKwlkZXZfc2V0X25hbWUoJmlwY19kZXYtPmRldiwgZGV2
bmFtZSk7DQo+ID4+ICsJZGV2aWNlX2luaXRpYWxpemUoJmlwY19kZXYtPmRldik7DQo+ID4+ICsN
Cj4gPj4gKwlyZXQgPSBkZXZpY2VfYWRkKCZpcGNfZGV2LT5kZXYpOw0KPiA+PiArCWlmIChyZXQg
PCAwKSB7DQo+ID4+ICsJCWRldl9lcnIoJmlwY19kZXYtPmRldiwgIiVzIGRldmljZSBjcmVhdGUg
ZmFpbGVkXG4iLA0KPiA+PiArCQkJCV9fZnVuY19fKTsNCj4gPj4gKwkJcmV0ID0gLUVOT0RFVjsN
Cj4gPj4gKwkJZ290byBlcnJfZGV2X2FkZDsNCj4gPj4gKwl9DQo+ID4+ICsNCj4gPj4gKwlpZiAo
aXBjX2Rldi0+Y2ZnLT5tb2RlID09IElQQ19ERVZfTU9ERV9JUlEpIHsNCj4gPj4gKwkJaWYgKGRl
dm1fcmVxdWVzdF9pcnEoJmlwY19kZXYtPmRldiwNCj4gPj4gKwkJCQlpcGNfZGV2LT5jZmctPmly
cSwNCj4gPj4gKwkJCQlpcGNfZGV2X2lycV9oYW5kbGVyLA0KPiA+PiArCQkJCWlwY19kZXYtPmNm
Zy0+aXJxZmxhZ3MsDQo+ID4+ICsJCQkJZGV2X25hbWUoJmlwY19kZXYtPmRldiksDQo+ID4+ICsJ
CQkJaXBjX2RldikpIHsNCj4gPj4gKwkJCWRldl9lcnIoJmlwY19kZXYtPmRldiwNCj4gPj4gKwkJ
CQkJIkZhaWxlZCB0byByZXF1ZXN0IGlycVxuIik7DQo+ID4+ICsJCQlnb3RvIGVycl9pcnFfcmVx
dWVzdDsNCj4gPj4gKwkJfQ0KPiA+PiArCX0NCj4gPj4gKw0KPiA+PiArCSpwdHIgPSBpcGNfZGV2
Ow0KPiA+PiArDQo+ID4+ICsJZGV2cmVzX2FkZChkZXYsIHB0cik7DQo+ID4+ICsNCj4gPj4gKwly
ZXR1cm4gaXBjX2RldjsNCj4gPj4gKw0KPiA+PiArZXJyX2lycV9yZXF1ZXN0Og0KPiA+PiArCWRl
dmljZV9kZWwoJmlwY19kZXYtPmRldik7DQo+ID4+ICtlcnJfZGV2X2FkZDoNCj4gPj4gKwlrZnJl
ZShpcGNfZGV2KTsNCj4gPj4gK2Vycl9kZXZfY3JlYXRlOg0KPiA+PiArCWRldnJlc19mcmVlKHB0
cik7DQo+ID4+ICsJcmV0dXJuIEVSUl9QVFIocmV0KTsNCj4gPj4gK30NCj4gPj4gK0VYUE9SVF9T
WU1CT0xfR1BMKGRldm1faW50ZWxfaXBjX2Rldl9jcmVhdGUpOw0KPiA+PiArDQo+ID4+ICtzdGF0
aWMgaW50IF9faW5pdCBpbnRlbF9pcGNfaW5pdCh2b2lkKSB7DQo+ID4+ICsJaXBjX2NoYW5uZWxf
bG9ja19pbml0KCk7DQo+ID4+ICsJcmV0dXJuIGNsYXNzX3JlZ2lzdGVyKCZpbnRlbF9pcGNfY2xh
c3MpOyB9DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyB2b2lkIF9fZXhpdCBpbnRlbF9pcGNfZXhpdCh2
b2lkKSB7DQo+ID4+ICsJY2xhc3NfdW5yZWdpc3RlcigmaW50ZWxfaXBjX2NsYXNzKTsNCj4gPj4g
K30NCj4gPj4gK3N1YnN5c19pbml0Y2FsbChpbnRlbF9pcGNfaW5pdCk7DQo+ID4+ICttb2R1bGVf
ZXhpdChpbnRlbF9pcGNfZXhpdCk7DQo+ID4+ICsNCj4gPj4gK01PRFVMRV9MSUNFTlNFKCJHUEwg
djIiKTsNCj4gPj4gK01PRFVMRV9BVVRIT1IoIkt1cHB1c3dhbXkNCj4gPj4gK1NhdGh5YW5hcmF5
YW5hbjxzYXRoeWFuYXJheWFuYW4ua3VwcHVzd2FteUBsaW51eC5pbnRlbC5jb20+Iik7DQo+ID4+
ICtNT0RVTEVfREVTQ1JJUFRJT04oIkludGVsIElQQyBkZXZpY2UgY2xhc3MgZHJpdmVyIik7DQo+
ID4+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L3BsYXRmb3JtX2RhdGEveDg2L2ludGVsX2lw
Y19kZXYuaA0KPiA+PiBiL2luY2x1ZGUvbGludXgvcGxhdGZvcm1fZGF0YS94ODYvaW50ZWxfaXBj
X2Rldi5oDQo+ID4+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4+IGluZGV4IDAwMDAwMDAuLmVh
ZWVkYWYNCj4gPj4gLS0tIC9kZXYvbnVsbA0KPiA+PiArKysgYi9pbmNsdWRlL2xpbnV4L3BsYXRm
b3JtX2RhdGEveDg2L2ludGVsX2lwY19kZXYuaA0KPiA+PiBAQCAtMCwwICsxLDIwNiBAQA0KPiA+
PiArLyoNCj4gPj4gKyAqIEludGVsIElQQyBjbGFzcyBkZXZpY2UgaGVhZGVyIGZpbGUuDQo+ID4+
ICsgKg0KPiA+PiArICogKEMpIENvcHlyaWdodCAyMDE3IEludGVsIENvcnBvcmF0aW9uDQo+ID4+
ICsgKg0KPiA+PiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVk
aXN0cmlidXRlIGl0IGFuZC9vcg0KPiA+PiArICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBv
ZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UNCj4gPj4gKyAqIGFzIHB1Ymxpc2hlZCBi
eSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDINCj4gPj4gKyAqIG9mIHRo
ZSBMaWNlbnNlLg0KPiA+PiArICoNCj4gPj4gKyAqLw0KPiA+PiArDQo+ID4+ICsjaWZuZGVmIElO
VEVMX0lQQ19ERVZfSA0KPiA+PiArI2RlZmluZSBJTlRFTF9JUENfREVWX0gNCj4gPj4gKw0KPiA+
PiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KPiA+PiArI2luY2x1ZGUgPGxpbnV4L2Rldmlj
ZS5oPg0KPiA+PiArDQo+ID4+ICsvKiBJUEMgY2hhbm5lbCB0eXBlICovDQo+ID4+ICsjZGVmaW5l
IElQQ19DSEFOTkVMX0lBX1BNQyAgICAgICAgICAgICAgICAgICAgICAwDQo+ID4+ICsjZGVmaW5l
IElQQ19DSEFOTkVMX0lBX1BVTklUICAgICAgICAgICAgICAgICAgICAxDQo+ID4+ICsjZGVmaW5l
IElQQ19DSEFOTkVMX1BNQ19QVU5JVCAgICAgICAgICAgICAgICAgICAyDQo+ID4+ICsjZGVmaW5l
IElQQ19DSEFOTkVMX0lBX1NDVSAgICAgICAgICAgICAgICAgICAgICAzDQo+ID4+ICsjZGVmaW5l
IElQQ19DSEFOTkVMX01BWCAgICAgICAgICAgICAgICAgICAgICAgICA0DQo+ID4+ICsNCj4gPj4g
Ky8qIElQQyByZXR1cm4gY29kZSAqLw0KPiA+PiArI2RlZmluZSBJUENfREVWX0VSUl9OT05FCQkJ
MA0KPiA+PiArI2RlZmluZSBJUENfREVWX0VSUl9DTURfTk9UX1NVUFBPUlRFRAkJMQ0KPiA+PiAr
I2RlZmluZSBJUENfREVWX0VSUl9DTURfTk9UX1NFUlZJQ0VECQkyDQo+ID4+ICsjZGVmaW5lIElQ
Q19ERVZfRVJSX1VOQUJMRV9UT19TRVJWSUNFCQkzDQo+ID4+ICsjZGVmaW5lIElQQ19ERVZfRVJS
X0NNRF9JTlZBTElECQkJNA0KPiA+PiArI2RlZmluZSBJUENfREVWX0VSUl9DTURfRkFJTEVECQkJ
NQ0KPiA+PiArI2RlZmluZSBJUENfREVWX0VSUl9FTVNFQ1VSSVRZCQkJNg0KPiA+PiArI2RlZmlu
ZSBJUENfREVWX0VSUl9VTlNJR05FREtFUk5FTAkJNw0KPiA+PiArI2RlZmluZSBJUENfREVWX0VS
Ul9NQVgJCQkJOA0KPiA+PiArDQo+ID4+ICsvKiBJUEMgbW9kZSAqLw0KPiA+PiArI2RlZmluZSBJ
UENfREVWX01PREVfSVJRCQkJMA0KPiA+PiArI2RlZmluZSBJUENfREVWX01PREVfUE9MTElORwkJ
CTENCj4gPj4gKw0KPiA+PiArLyogSVBDIGRldiBjb25zdGFudHMgKi8NCj4gPj4gKyNkZWZpbmUg
SVBDX0RFVl9DTURfTE9PUF9DTlQJCQkzMDAwMDAwDQo+ID4+ICsjZGVmaW5lIElQQ19ERVZfQ01E
X1RJTUVPVVQJCQkzICogSFoNCj4gPj4gKyNkZWZpbmUgSVBDX0RFVl9EQVRBX0JVRkZFUl9TSVpF
CQkxNg0KPiA+PiArDQo+ID4+ICtzdHJ1Y3QgaW50ZWxfaXBjX2RldjsNCj4gPj4gK3N0cnVjdCBp
bnRlbF9pcGNfcmF3X2NtZDsNCj4gPj4gKw0KPiA+PiArLyoqDQo+ID4+ICsgKiBzdHJ1Y3QgaW50
ZWxfaXBjX2Rldl9jZmcgLSBJUEMgZGV2aWNlIGNvbmZpZyBzdHJ1Y3R1cmUuDQo+ID4+ICsgKg0K
PiA+PiArICogSVBDIGRldmljZSBkcml2ZXJzIHVzZXMgdGhlIGZvbGxvd2luZyBjb25maWcgb3B0
aW9ucyB0bw0KPiA+PiArICogcmVnaXN0ZXIgbmV3IElQQyBkZXZpY2UuDQo+ID4+ICsgKg0KPiA+
PiArICogQGNtZF9yZWdzICAgICAgICAgICAgOiBJUEMgZGV2aWNlIGNvbW1hbmQgYmFzZSByZWdt
YXAuDQo+ID4+ICsgKiBAZGF0YV9yZWdzICAgICAgICAgICA6IElQQyBkZXZpY2UgZGF0YSBiYXNl
IHJlZ21hcC4NCj4gPj4gKyAqIEB3cmJ1Zl9yZWcgICAgICAgICAgIDogSVBDIGRldmljZSBkYXRh
IHdyaXRlIHJlZ2lzdGVyIGFkZHJlc3MuDQo+ID4+ICsgKiBAcmJ1Zl9yZWcgICAgICAgICAgICA6
IElQQyBkZXZpY2UgZGF0YSByZWFkIHJlZ2lzdGVyIGFkZHJlc3MuDQo+ID4+ICsgKiBAc3B0cl9y
ZWcgICAgICAgICAgICA6IElQQyBkZXZpY2Ugc291cmNlIGRhdGEgcG9pbnRlciByZWdpc3RlciBh
ZGRyZXNzLg0KPiA+PiArICogQGRwdHJfcmVnICAgICAgICAgICAgOiBJUEMgZGV2aWNlIGRlc3Rp
bmF0aW9uIGRhdGEgcG9pbnRlciByZWdpc3Rlcg0KPiA+PiArICogICAgICAgICAgICAgICAgICAg
ICAgICBhZGRyZXNzLg0KPiA+PiArICogQHN0YXR1c19yZWcgICAgICAgICAgOiBJUEMgY29tbWFu
ZCBzdGF0dXMgcmVnaXN0ZXIgYWRkcmVzcy4NCj4gPj4gKyAqIEBjbWRfcmVnICAgICAgICAgICAg
IDogSVBDIGNvbW1hbmQgcmVnaXN0ZXIgYWRkcmVzcy4NCj4gPj4gKyAqIEBtb2RlICAgICAgICAg
ICAgICAgIDogSVJRL1BPTExJTkcgbW9kZS4NCj4gPj4gKyAqIEBpcnEgICAgICAgICAgICAgICAg
IDogSVBDIGRldmljZSBJUlEgbnVtYmVyLg0KPiA+PiArICogQGlycWZsYWdzICAgICAgICAgICAg
OiBJUEMgZGV2aWNlIElSUSBmbGFncy4NCj4gPj4gKyAqIEBjaGFuX3R5cGUgICAgICAgICAgIDog
SVBDIGRldmljZSBjaGFubmVsIHR5cGUoUE1DL1BVTklUKS4NCj4gPj4gKyAqIEBtc2kgICAgICAg
ICAgICAgICAgIDogRW5hYmxlL0Rpc2FibGUgTVNJIGZvciBJUEMgY29tbWFuZHMuDQo+ID4+ICsg
KiBAc3VwcG9ydF9kcHRyICAgICAgICA6IFN1cHBvcnQgRFBUUiB1cGRhdGUuDQo+ID4+ICsgKiBA
c3VwcG9ydF9zcHRyICAgICAgICA6IFN1cHBvcnQgU1BUUiB1cGRhdGUuDQo+ID4+ICsgKg0KPiA+
PiArICovDQo+ID4+ICtzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9jZmcgew0KPiA+PiArCXN0cnVjdCBy
ZWdtYXAgKmNtZF9yZWdzOw0KPiA+PiArCXN0cnVjdCByZWdtYXAgKmRhdGFfcmVnczsNCj4gPj4g
Kwl1bnNpZ25lZCBpbnQgd3JidWZfcmVnOw0KPiA+PiArCXVuc2lnbmVkIGludCByYnVmX3JlZzsN
Cj4gPj4gKwl1bnNpZ25lZCBpbnQgc3B0cl9yZWc7DQo+ID4+ICsJdW5zaWduZWQgaW50IGRwdHJf
cmVnOw0KPiA+PiArCXVuc2lnbmVkIGludCBzdGF0dXNfcmVnOw0KPiA+PiArCXVuc2lnbmVkIGlu
dCBjbWRfcmVnOw0KPiA+PiArCWludCBtb2RlOw0KPiA+PiArCWludCBpcnE7DQo+ID4+ICsJaW50
IGlycWZsYWdzOw0KPiA+PiArCWludCBjaGFuX3R5cGU7DQo+ID4+ICsJYm9vbCB1c2VfbXNpOw0K
PiA+PiArCWJvb2wgc3VwcG9ydF9kcHRyOw0KPiA+PiArCWJvb2wgc3VwcG9ydF9zcHRyOw0KPiA+
PiArfTsNCj4gPj4gKw0KPiA+PiArLyoqDQo+ID4+ICsgKiBzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9v
cHMgLSBJUEMgZGV2aWNlIG9wcyBzdHJ1Y3R1cmUuDQo+ID4+ICsgKg0KPiA+PiArICogQ2FsbCBi
YWNrcyBmb3IgSVBDIGRldmljZSBzcGVjaWZpYyBvcGVyYXRpb25zLg0KPiA+PiArICoNCj4gPj4g
KyAqIEB0b19lcnJfY29kZSAgICAgICAgIDogU3RhdHVzIHRvIGVycm9yIGNvZGUgY29udmVyc2lv
biBmdW5jdGlvbi4NCj4gPj4gKyAqIEBidXN5X2NoZWNrICAgICAgICAgIDogQ2hlY2sgZm9yIElQ
QyBidXN5IHN0YXR1cy4NCj4gPj4gKyAqIEBlbmFibGVfbXNpICAgICAgICAgIDogRW5hYmxlIE1T
SSBmb3IgSVBDIGNvbW1hbmRzLg0KPiA+PiArICogQHByZV9zaW1wbGVfY21kX2ZuICAgOiBDdXN0
b20gcHJlLXByb2Nlc3NpbmcgZnVuY3Rpb24gZm9yDQo+ID4+ICsgKiAgICAgICAgICAgICAgICAg
ICAgICAgIGlwY19kZXZfc2ltcGxlX2NtZCgpDQo+ID4+ICsgKiBAcHJlX2NtZF9mbiAgICAgICAg
ICA6IEN1c3RvbSBwcmUtcHJvY2Vzc2luZyBmdW5jdGlvbiBmb3INCj4gPj4gKyAqICAgICAgICAg
ICAgICAgICAgICAgICAgaXBjX2Rldl9jbWQoKQ0KPiA+PiArICogQHByZV9yYXdfY21kX2ZuICAg
ICAgOiBDdXN0b20gcHJlLXByb2Nlc3NpbmcgZnVuY3Rpb24gZm9yDQo+ID4+ICsgKiAgICAgICAg
ICAgICAgICAgICAgICAgIGlwY19kZXZfcmF3X2NtZCgpDQo+ID4+ICsgKg0KPiA+PiArICovDQo+
ID4+ICtzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9vcHMgew0KPiA+PiArCWludCAoKnRvX2Vycl9jb2Rl
KShpbnQgc3RhdHVzKTsNCj4gPj4gKwlpbnQgKCpidXN5X2NoZWNrKShpbnQgc3RhdHVzKTsNCj4g
Pj4gKwl1MzIgKCplbmFibGVfbXNpKSh1MzIgY21kKTsNCj4gPj4gKwlpbnQgKCpwcmVfc2ltcGxl
X2NtZF9mbikodTMyICpjbWRfbGlzdCwgdTMyIGNtZGxlbik7DQo+ID4+ICsJaW50ICgqcHJlX2Nt
ZF9mbikodTMyICpjbWRfbGlzdCwgdTMyIGNtZGxlbiwgdTMyICppbiwgdTMyIGlubGVuLA0KPiA+
PiArCQkJdTMyICpvdXQsIHUzMiBvdXRsZW4pOw0KPiA+PiArCWludCAoKnByZV9yYXdfY21kX2Zu
KSh1MzIgKmNtZF9saXN0LCB1MzIgY21kbGVuLCB1OCAqaW4sIHUzMiBpbmxlbiwNCj4gPj4gKwkJ
CXUzMiAqb3V0LCB1MzIgb3V0bGVuLCB1MzIgZHB0ciwgdTMyIHNwdHIpOw0KPiA+PiArCWludCAo
KnByZV9pcnFfaGFuZGxlcl9mbikoc3RydWN0IGludGVsX2lwY19kZXYgKmlwY19kZXYsIGludCBp
cnEpOw0KPiA+PiArfTsNCj4gPj4gKw0KPiA+PiArLyoqDQo+ID4+ICsgKiBzdHJ1Y3QgaW50ZWxf
aXBjX2RldiAtIEludGVsIElQQyBkZXZpY2Ugc3RydWN0dXJlLg0KPiA+PiArICoNCj4gPj4gKyAq
IFVzZWQgd2l0aCBkZXZtX2ludGVsX2lwY19kZXZfY3JlYXRlKCkgdG8gY3JlYXRlIG5ldyBJUEMg
ZGV2aWNlLg0KPiA+PiArICoNCj4gPj4gKyAqIEBkZXYgICAgICAgICAgICAgICAgIDogSVBDIGRl
dmljZSBvYmplY3QuDQo+ID4+ICsgKiBAY21kICAgICAgICAgICAgICAgICA6IEN1cnJlbnQgSVBD
IGRldmljZSBjb21tYW5kLg0KPiA+PiArICogQGNtZF9jb21wbGV0ZSAgICAgICAgOiBDb21tYW5k
IGNvbXBsZXRpb24gb2JqZWN0Lg0KPiA+PiArICogQGxvY2sgICAgICAgICAgICAgICAgOiBMb2Nr
IHRvIHByb3RlY3QgSVBDIGRldmljZSBzdHJ1Y3R1cmUuDQo+ID4+ICsgKiBAb3BzICAgICAgICAg
ICAgICAgICA6IElQQyBkZXZpY2Ugb3BzIHBvaW50ZXIuDQo+ID4+ICsgKiBAY2ZnICAgICAgICAg
ICAgICAgICA6IElQQyBkZXZpY2UgY2ZnIHBvaW50ZXIuDQo+ID4+ICsgKg0KPiA+PiArICovDQo+
ID4+ICtzdHJ1Y3QgaW50ZWxfaXBjX2RldiB7DQo+ID4+ICsJc3RydWN0IGRldmljZSBkZXY7DQo+
ID4+ICsJaW50IGNtZDsNCj4gPj4gKwlzdHJ1Y3QgY29tcGxldGlvbiBjbWRfY29tcGxldGU7DQo+
ID4+ICsJc3RydWN0IG11dGV4IGxvY2s7DQo+ID4+ICsJc3RydWN0IGludGVsX2lwY19kZXZfb3Bz
ICpvcHM7DQo+ID4+ICsJc3RydWN0IGludGVsX2lwY19kZXZfY2ZnICpjZmc7DQo+ID4+ICt9Ow0K
PiA+PiArDQo+ID4+ICsjaWYgSVNfRU5BQkxFRChDT05GSUdfSU5URUxfSVBDX0RFVikNCj4gPj4g
Kw0KPiA+PiArLyogQVBJIHRvIGNyZWF0ZSBuZXcgSVBDIGRldmljZSAqLw0KPiA+PiArc3RydWN0
IGludGVsX2lwY19kZXYgKmRldm1faW50ZWxfaXBjX2Rldl9jcmVhdGUoc3RydWN0IGRldmljZSAq
ZGV2LA0KPiA+PiArCQljb25zdCBjaGFyICpkZXZuYW1lLCBzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9j
ZmcgKmNmZywNCj4gPj4gKwkJc3RydWN0IGludGVsX2lwY19kZXZfb3BzICpvcHMpOw0KPiA+PiAr
DQo+ID4+ICtpbnQgaXBjX2Rldl9zaW1wbGVfY21kKHN0cnVjdCBpbnRlbF9pcGNfZGV2ICppcGNf
ZGV2LCB1MzIgKmNtZF9saXN0LA0KPiA+PiArCQl1MzIgY21kbGVuKTsNCj4gPj4gK2ludCBpcGNf
ZGV2X2NtZChzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaXBjX2RldiwgdTMyICpjbWRfbGlzdCwgdTMy
DQo+IGNtZGxlbiwNCj4gPj4gKwkJdTMyICppbiwgdTMyIGlubGVuLCB1MzIgKm91dCwgdTMyIG91
dGxlbik7IGludA0KPiA+PiBpcGNfZGV2X3Jhd19jbWQoc3RydWN0DQo+ID4+ICtpbnRlbF9pcGNf
ZGV2ICppcGNfZGV2LCB1MzIgKmNtZF9saXN0LCB1MzIgY21kbGVuLA0KPiA+PiArCQl1OCAqaW4s
IHUzMiBpbmxlbiwgdTMyICpvdXQsIHUzMiBvdXRsZW4sIHUzMiBkcHRyLCB1MzIgc3B0cik7DQo+
ID4+IHN0cnVjdA0KPiA+PiAraW50ZWxfaXBjX2RldiAqaW50ZWxfaXBjX2Rldl9nZXQoY29uc3Qg
Y2hhciAqZGV2X25hbWUpOyBzdHJ1Y3QNCj4gPj4gK2ludGVsX2lwY19kZXYgKmRldm1faW50ZWxf
aXBjX2Rldl9nZXQoc3RydWN0IGRldmljZSAqZGV2LA0KPiA+PiArCQkJCQljb25zdCBjaGFyICpk
ZXZfbmFtZSk7DQo+ID4+ICtzdGF0aWMgaW5saW5lIHZvaWQgaW50ZWxfaXBjX2Rldl9wdXQoc3Ry
dWN0IGludGVsX2lwY19kZXYgKmlwY19kZXYpIHsNCj4gPj4gKwlwdXRfZGV2aWNlKCZpcGNfZGV2
LT5kZXYpOw0KPiA+PiArfQ0KPiA+PiArI2Vsc2UNCj4gPj4gKw0KPiA+PiArc3RhdGljIGlubGlu
ZSBzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqZGV2bV9pbnRlbF9pcGNfZGV2X2NyZWF0ZSgNCj4gPj4g
KwkJc3RydWN0IGRldmljZSAqZGV2LA0KPiA+PiArCQljb25zdCBjaGFyICpkZXZuYW1lLCBzdHJ1
Y3QgaW50ZWxfaXBjX2Rldl9jZmcgKmNmZywNCj4gPj4gKwkJc3RydWN0IGludGVsX2lwY19kZXZf
b3BzICpvcHMpDQo+ID4+ICt7DQo+ID4+ICsJcmV0dXJuIC1FSU5WQUw7DQo+ID4+ICt9DQo+ID4+
ICsNCj4gPj4gK3N0YXRpYyBpbmxpbmUgaW50IGlwY19kZXZfc2ltcGxlX2NtZChzdHJ1Y3QgaW50
ZWxfaXBjX2RldiAqaXBjX2RldiwNCj4gPj4gKwkJdTMyICpjbWRfbGlzdCwgdTMyIGNtZGxlbikN
Cj4gPj4gK3sNCj4gPj4gKwlyZXR1cm4gLUVJTlZBTDsNCj4gPj4gK30NCj4gPj4gKw0KPiA+PiAr
c3RhdGljIGludCBpcGNfZGV2X2NtZChzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaXBjX2RldiwgdTMy
ICpjbWRfbGlzdCwNCj4gPj4gKwkJdTMyIGNtZGxlbiwgdTMyICppbiwgdTMyIGlubGVuLCB1MzIg
Km91dCwgdTMyIG91dGxlbikgew0KPiA+PiArCXJldHVybiAtRUlOVkFMOw0KPiA+PiArfQ0KPiA+
PiArDQo+ID4+ICtzdGF0aWMgaW5saW5lIGludCBpcGNfZGV2X3Jhd19jbWQoc3RydWN0IGludGVs
X2lwY19kZXYgKmlwY19kZXYsIHUzMg0KPiA+PiAqY21kX2xpc3QsDQo+ID4+ICsJCXUzMiBjbWRs
ZW4sIHU4ICppbiwgdTMyIGlubGVuLCB1MzIgKm91dCwgdTMyIG91dGxlbiwNCj4gPj4gKwkJdTMy
IGRwdHIsIHUzMiBzcHRyKTsNCj4gPj4gK3sNCj4gPj4gKwlyZXR1cm4gLUVJTlZBTDsNCj4gPj4g
K30NCj4gPj4gKw0KPiA+PiArc3RhdGljIGlubGluZSBzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaW50
ZWxfaXBjX2Rldl9nZXQoY29uc3QgY2hhcg0KPiA+PiArKmRldl9uYW1lKSB7DQo+ID4+ICsJcmV0
dXJuIE5VTEw7DQo+ID4+ICt9DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBpbmxpbmUgc3RydWN0IGlu
dGVsX2lwY19kZXYgKmRldm1faW50ZWxfaXBjX2Rldl9nZXQoc3RydWN0DQo+ID4+ICtkZXZpY2UN
Cj4gPj4gKmRldiwNCj4gPj4gKwkJCQkJY29uc3QgY2hhciAqZGV2X25hbWUpOw0KPiA+PiArew0K
PiA+PiArCXJldHVybiBOVUxMOw0KPiA+PiArfQ0KPiA+PiArDQo+ID4+ICtzdGF0aWMgaW5saW5l
IHZvaWQgaW50ZWxfaXBjX2Rldl9wdXQoc3RydWN0IGludGVsX2lwY19kZXYgKmlwY19kZXYpIHsN
Cj4gPj4gKwlyZXR1cm4gTlVMTDsNCj4gPj4gK30NCj4gPj4gKyNlbmRpZiAvKiBDT05GSUdfSU5U
RUxfSVBDX0RFViAqLw0KPiA+PiArI2VuZGlmIC8qIElOVEVMX0lQQ19ERVZfSCAqLw0KPiA+PiAt
LQ0KPiA+PiAyLjcuNA0KPiA+DQo+IA0KPiAtLQ0KPiBTYXRoeWFuYXJheWFuYW4gS3VwcHVzd2Ft
eQ0KPiBMaW51eCBrZXJuZWwgZGV2ZWxvcGVyDQoNCg==
^ permalink raw reply
* RE: [RFC v5 6/8] platform/x86: intel_punit_ipc: Use generic intel ipc device calls
From: Chakravarty, Souvik K @ 2017-10-11 3:32 UTC (permalink / raw)
To: sathyanarayanan.kuppuswamy@linux.intel.com, a.zummo@towertech.it,
x86@kernel.org, wim@iguana.be, mingo@redhat.com,
alexandre.belloni@free-electrons.com, Zha, Qipeng, hpa@zytor.com,
dvhart@infradead.org, tglx@linutronix.de, lee.jones@linaro.org,
andy@infradead.org
Cc: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org,
linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org,
sathyaosid@gmail.com
In-Reply-To: <075be722-d145-5ad4-30cb-743844ee6370@linux.intel.com>
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogcGxhdGZvcm0tZHJpdmVy
LXg4Ni1vd25lckB2Z2VyLmtlcm5lbC5vcmcgW21haWx0bzpwbGF0Zm9ybS1kcml2ZXItDQo+IHg4
Ni1vd25lckB2Z2VyLmtlcm5lbC5vcmddIE9uIEJlaGFsZiBPZiBzYXRoeWFuYXJheWFuYW4ga3Vw
cHVzd2FteQ0KPiBTZW50OiBXZWRuZXNkYXksIE9jdG9iZXIgMTEsIDIwMTcgMzo1OSBBTQ0KPiBU
bzogQ2hha3JhdmFydHksIFNvdXZpayBLIDxzb3V2aWsuay5jaGFrcmF2YXJ0eUBpbnRlbC5jb20+
Ow0KPiBhLnp1bW1vQHRvd2VydGVjaC5pdDsgeDg2QGtlcm5lbC5vcmc7IHdpbUBpZ3VhbmEuYmU7
DQo+IG1pbmdvQHJlZGhhdC5jb207IGFsZXhhbmRyZS5iZWxsb25pQGZyZWUtZWxlY3Ryb25zLmNv
bTsgWmhhLCBRaXBlbmcNCj4gPHFpcGVuZy56aGFAaW50ZWwuY29tPjsgaHBhQHp5dG9yLmNvbTsg
ZHZoYXJ0QGluZnJhZGVhZC5vcmc7DQo+IHRnbHhAbGludXRyb25peC5kZTsgbGVlLmpvbmVzQGxp
bmFyby5vcmc7IGFuZHlAaW5mcmFkZWFkLm9yZw0KPiBDYzogbGludXgtcnRjQHZnZXIua2VybmVs
Lm9yZzsgbGludXgtd2F0Y2hkb2dAdmdlci5rZXJuZWwub3JnOyBsaW51eC0NCj4ga2VybmVsQHZn
ZXIua2VybmVsLm9yZzsgcGxhdGZvcm0tZHJpdmVyLXg4NkB2Z2VyLmtlcm5lbC5vcmc7DQo+IHNh
dGh5YW9zaWRAZ21haWwuY29tDQo+IFN1YmplY3Q6IFJlOiBbUkZDIHY1IDYvOF0gcGxhdGZvcm0v
eDg2OiBpbnRlbF9wdW5pdF9pcGM6IFVzZSBnZW5lcmljIGludGVsIGlwYw0KPiBkZXZpY2UgY2Fs
bHMNCj4gDQo+IA0KPiANCj4gT24gMTAvMDgvMjAxNyAxMDowNyBQTSwgQ2hha3JhdmFydHksIFNv
dXZpayBLIHdyb3RlOg0KPiA+PiBGcm9tOiBzYXRoeWFuYXJheWFuYW4ua3VwcHVzd2FteUBsaW51
eC5pbnRlbC5jb20NCj4gPj4gW21haWx0bzpzYXRoeWFuYXJheWFuYW4ua3VwcHVzd2FteUBsaW51
eC5pbnRlbC5jb21dDQo+ID4+IFNlbnQ6IFN1bmRheSwgT2N0b2JlciA4LCAyMDE3IDM6NTAgQU0N
Cj4gPj4gVG86IGEuenVtbW9AdG93ZXJ0ZWNoLml0OyB4ODZAa2VybmVsLm9yZzsgd2ltQGlndWFu
YS5iZTsNCj4gPj4gbWluZ29AcmVkaGF0LmNvbTsgYWxleGFuZHJlLmJlbGxvbmlAZnJlZS1lbGVj
dHJvbnMuY29tOyBaaGEsIFFpcGVuZw0KPiA+PiA8cWlwZW5nLnpoYUBpbnRlbC5jb20+OyBocGFA
enl0b3IuY29tOyBkdmhhcnRAaW5mcmFkZWFkLm9yZzsNCj4gPj4gdGdseEBsaW51dHJvbml4LmRl
OyBsZWUuam9uZXNAbGluYXJvLm9yZzsgYW5keUBpbmZyYWRlYWQub3JnOw0KPiA+PiBDaGFrcmF2
YXJ0eSwgU291dmlrIEsgPHNvdXZpay5rLmNoYWtyYXZhcnR5QGludGVsLmNvbT4NCj4gPj4gQ2M6
IGxpbnV4LXJ0Y0B2Z2VyLmtlcm5lbC5vcmc7IGxpbnV4LXdhdGNoZG9nQHZnZXIua2VybmVsLm9y
ZzsgbGludXgtDQo+ID4+IGtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7IHBsYXRmb3JtLWRyaXZlci14
ODZAdmdlci5rZXJuZWwub3JnOw0KPiA+PiBzYXRoeWFvc2lkQGdtYWlsLmNvbTsgS3VwcHVzd2Ft
eSBTYXRoeWFuYXJheWFuYW4NCj4gPj4gPHNhdGh5YW5hcmF5YW5hbi5rdXBwdXN3YW15QGxpbnV4
LmludGVsLmNvbT4NCj4gPj4gU3ViamVjdDogW1JGQyB2NSA2LzhdIHBsYXRmb3JtL3g4NjogaW50
ZWxfcHVuaXRfaXBjOiBVc2UgZ2VuZXJpYw0KPiA+PiBpbnRlbCBpcGMgZGV2aWNlIGNhbGxzDQo+
ID4+DQo+ID4+IEZyb206IEt1cHB1c3dhbXkgU2F0aHlhbmFyYXlhbmFuDQo+ID4+IDxzYXRoeWFu
YXJheWFuYW4ua3VwcHVzd2FteUBsaW51eC5pbnRlbC5jb20+DQo+ID4+DQo+ID4+IFJlbW92ZWQg
cmVkdW5kYW50IElQQyBoZWxwZXIgZnVuY3Rpb25zIGFuZCByZWZhY3RvcmVkIHRoZSBkcml2ZXIg
dG8NCj4gPj4gdXNlIEFQSXMgcHJvdmlkZWQgYnkgZ2VuZXJpYyBJUEMgZHJpdmVyLiBUaGlzIHBh
dGNoIGFsc28gY2xlYW5zLXVwDQo+ID4+IFBVTklUIElQQyB1c2VyDQo+ID4+IGRyaXZlcnMoaW50
ZWxfdGVsZW1ldHJ5X3BsdGRydi5jKSB0byB1c2UgQVBJcyBwcm92aWRlZCBieSBnZW5lcmljIElQ
Qw0KPiBkcml2ZXIuDQo+ID4+DQo+ID4+IFNpZ25lZC1vZmYtYnk6IEt1cHB1c3dhbXkgU2F0aHlh
bmFyYXlhbmFuDQo+ID4+IDxzYXRoeWFuYXJheWFuYW4ua3VwcHVzd2FteUBsaW51eC5pbnRlbC5j
b20+DQo+ID4+IC0tLQ0KPiA+PiAgIGFyY2gveDg2L2luY2x1ZGUvYXNtL2ludGVsX3B1bml0X2lw
Yy5oICAgICAgICB8IDEyNSArKysrKy0tLS0tLQ0KPiA+PiAgIGRyaXZlcnMvcGxhdGZvcm0veDg2
L0tjb25maWcgICAgICAgICAgICAgICAgICB8ICAgMSArDQo+ID4+ICAgZHJpdmVycy9wbGF0Zm9y
bS94ODYvaW50ZWxfcHVuaXRfaXBjLmMgICAgICAgIHwgMzAzICsrKysrKysrKystLS0tLS0tLS0t
LS0tLS0tDQo+ID4+ICAgZHJpdmVycy9wbGF0Zm9ybS94ODYvaW50ZWxfdGVsZW1ldHJ5X3BsdGRy
di5jIHwgIDk3ICsrKysrLS0tLQ0KPiA+PiAgIDQgZmlsZXMgY2hhbmdlZCwgMjIzIGluc2VydGlv
bnMoKyksIDMwMyBkZWxldGlvbnMoLSkNCj4gPj4NCj4gPj4gQ2hhbmdlcyBzaW5jZSB2NDoNCj4g
Pj4gICAqIE5vbmUNCj4gPj4NCj4gPj4gQ2hhbmdlcyBzaW5jZSB2MjoNCj4gPj4gICAqIEFkZGVk
IHVuaXF1ZSBuYW1lIHRvIFBVTklUIEJJT1MsIEdURCwgJiBJU1AgcmVnbWFwcy4NCj4gPj4gICAq
IEFkZGVkIGludGVsX2lwY19kZXZfcHV0KCkgc3VwcG9ydC4NCj4gPj4NCj4gPj4gQ2hhbmdlcyBz
aW5jZSB2MToNCj4gPj4gICAqIFJlbW92ZWQgY3VzdG9tIEFQSXMuDQo+ID4+ICAgKiBDbGVhbmVk
IHVwIFBVTklUIElQQyB1c2VyIGRyaXZlcnMgdG8gdXNlIEFQSXMgcHJvdmlkZWQgYnkgZ2VuZXJp
Yw0KPiA+PiAgICAgSVBDIGRyaXZlci4NCj4gPj4NCj4gPj4gZGlmZiAtLWdpdCBhL2FyY2gveDg2
L2luY2x1ZGUvYXNtL2ludGVsX3B1bml0X2lwYy5oDQo+ID4+IGIvYXJjaC94ODYvaW5jbHVkZS9h
c20vaW50ZWxfcHVuaXRfaXBjLmgNCj4gPj4gaW5kZXggMjAxZWI5ZC4uY2YxNjMwYyAxMDA2NDQN
Cj4gPj4gLS0tIGEvYXJjaC94ODYvaW5jbHVkZS9hc20vaW50ZWxfcHVuaXRfaXBjLmgNCj4gPj4g
KysrIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vaW50ZWxfcHVuaXRfaXBjLmgNCj4gPj4gQEAgLTEs
MTAgKzEsOCBAQA0KPiA+PiAgICNpZm5kZWYgX0FTTV9YODZfSU5URUxfUFVOSVRfSVBDX0hfDQo+
ID4+ICAgI2RlZmluZSAgX0FTTV9YODZfSU5URUxfUFVOSVRfSVBDX0hfDQo+ID4+DQo+ID4+IC0v
Kg0KPiA+PiAtICogVGhyZWUgdHlwZXMgb2YgOGJpdCBQLVVuaXQgSVBDIGNvbW1hbmRzIGFyZSBz
dXBwb3J0ZWQsDQo+ID4+IC0gKiBiaXRbNzo2XTogWzAwXTogQklPUzsgWzAxXTogR1REOyBbMTBd
OiBJU1BELg0KPiA+PiAtICovDQo+ID4+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGF0YS94
ODYvaW50ZWxfaXBjX2Rldi5oPg0KPiA+PiArDQo+ID4+ICAgdHlwZWRlZiBlbnVtIHsNCj4gPj4g
ICAJQklPU19JUEMgPSAwLA0KPiA+PiAgIAlHVERSSVZFUl9JUEMsDQo+ID4+IEBAIC0xMiw2MSAr
MTAsNjAgQEAgdHlwZWRlZiBlbnVtIHsNCj4gPj4gICAJUkVTRVJWRURfSVBDLA0KPiA+PiAgIH0g
SVBDX1RZUEU7DQo+ID4+DQo+ID4+IC0jZGVmaW5lIElQQ19UWVBFX09GRlNFVAkJCTYNCj4gPj4g
LSNkZWZpbmUgSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UJCShCSU9TX0lQQyA8PA0KPiA+PiBJUENf
VFlQRV9PRkZTRVQpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9HVERfQ01EX0JBU0UJCShHVERE
UklWRVJfSVBDIDw8DQo+ID4+IElQQ19UWVBFX09GRlNFVCkNCj4gPj4gLSNkZWZpbmUgSVBDX1BV
TklUX0lTUERfQ01EX0JBU0UJCShJU1BEUklWRVJfSVBDIDw8DQo+ID4+IElQQ19UWVBFX09GRlNF
VCkNCj4gPj4gLSNkZWZpbmUgSVBDX1BVTklUX0NNRF9UWVBFX01BU0sJCShSRVNFUlZFRF9JUEMg
PDwNCj4gPj4gSVBDX1RZUEVfT0ZGU0VUKQ0KPiA+PiArI2RlZmluZSBQVU5JVF9CSU9TX0lQQ19E
RVYJCQkicHVuaXRfYmlvc19pcGMiDQo+ID4+ICsjZGVmaW5lIFBVTklUX0dURF9JUENfREVWCQkJ
InB1bml0X2d0ZF9pcGMiDQo+ID4+ICsjZGVmaW5lIFBVTklUX0lTUF9JUENfREVWCQkJInB1bml0
X2lzcF9pcGMiDQo+ID4+ICsjZGVmaW5lIFBVTklUX1BBUkFNX0xFTgkJCQkzDQo+ID4+DQo+ID4+
ICAgLyogQklPUyA9PiBQY29kZSBjb21tYW5kcyAqLw0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRf
QklPU19aRVJPDQo+IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UNCj4gPj4gfCAweDAwKQ0KPiA+
PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19WUl9JTlRFUkZBQ0UNCj4gPj4gCShJUENfUFVOSVRf
QklPU19DTURfQkFTRSB8IDB4MDEpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1JFQURf
UENTDQo+ID4+IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UgfCAweDAyKQ0KPiA+PiAtI2RlZmlu
ZSBJUENfUFVOSVRfQklPU19XUklURV9QQ1MNCj4gCShJUENfUFVOSVRfQklPU19DTURfQkFTRQ0K
PiA+PiB8IDB4MDMpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1JFQURfUENVX0NPTkZJ
Rw0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NNRF9CQVNFIHwgMHgwNCkNCj4gPj4gLSNkZWZpbmUg
SVBDX1BVTklUX0JJT1NfV1JJVEVfUENVX0NPTkZJRw0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NN
RF9CQVNFIHwgMHgwNSkNCj4gPj4gLSNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9QTDFfU0VU
VElORw0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NNRF9CQVNFIHwgMHgwNikNCj4gPj4gLSNkZWZp
bmUgSVBDX1BVTklUX0JJT1NfV1JJVEVfUEwxX1NFVFRJTkcNCj4gCShJUENfUFVOSVRfQklPU19D
TURfQkFTRQ0KPiA+PiB8IDB4MDcpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1RSSUdH
RVJfVkREX1JBTQ0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NNRF9CQVNFIHwgMHgwOCkNCj4gPj4g
LSNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX0lORk8NCj4gPj4gCShJUENfUFVOSVRf
QklPU19DTURfQkFTRSB8IDB4MDkpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1JFQURf
VEVMRV9UUkFDRV9DVFJMDQo+ID4+IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UgfCAweDBhKQ0K
PiA+PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklURV9URUxFX1RSQUNFX0NUUkwNCj4gPj4g
CShJUENfUFVOSVRfQklPU19DTURfQkFTRSB8IDB4MGIpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5J
VF9CSU9TX1JFQURfVEVMRV9FVkVOVF9DVFJMDQo+ID4+IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JB
U0UgfCAweDBjKQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklURV9URUxFX0VWRU5U
X0NUUkwNCj4gPj4gCShJUENfUFVOSVRfQklPU19DTURfQkFTRSB8IDB4MGQpDQo+ID4+IC0jZGVm
aW5lIElQQ19QVU5JVF9CSU9TX1JFQURfVEVMRV9UUkFDRQ0KPiA+PiAJKElQQ19QVU5JVF9CSU9T
X0NNRF9CQVNFIHwgMHgwZSkNCj4gPj4gLSNkZWZpbmUgSVBDX1BVTklUX0JJT1NfV1JJVEVfVEVM
RV9UUkFDRQ0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NNRF9CQVNFIHwgMHgwZikNCj4gPj4gLSNk
ZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX0VWRU5UDQo+ID4+IAkoSVBDX1BVTklUX0JJ
T1NfQ01EX0JBU0UgfCAweDEwKQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklURV9U
RUxFX0VWRU5UDQo+ID4+IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UgfCAweDExKQ0KPiA+PiAt
I2RlZmluZSBJUENfUFVOSVRfQklPU19SRUFEX01PRFVMRV9URU1QDQo+ID4+IAkoSVBDX1BVTklU
X0JJT1NfQ01EX0JBU0UgfCAweDEyKQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19SRVNF
UlZFRA0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NNRF9CQVNFIHwgMHgxMykNCj4gPj4gLSNkZWZp
bmUgSVBDX1BVTklUX0JJT1NfUkVBRF9WT0xUQUdFX09WRVINCj4gPj4gCShJUENfUFVOSVRfQklP
U19DTURfQkFTRSB8IDB4MTQpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1dSSVRFX1ZP
TFRBR0VfT1ZFUg0KPiA+PiAJKElQQ19QVU5JVF9CSU9TX0NNRF9CQVNFIHwgMHgxNSkNCj4gPj4g
LSNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9SQVRJT19PVkVSDQo+ID4+IAkoSVBDX1BVTklU
X0JJT1NfQ01EX0JBU0UgfCAweDE2KQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklU
RV9SQVRJT19PVkVSDQo+ID4+IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UgfCAweDE3KQ0KPiA+
PiAtI2RlZmluZSBJUENfUFVOSVRfQklPU19SRUFEX1ZGX0dMX0NUUkwNCj4gPj4gCShJUENfUFVO
SVRfQklPU19DTURfQkFTRSB8IDB4MTgpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1dS
SVRFX1ZGX0dMX0NUUkwNCj4gPj4gCShJUENfUFVOSVRfQklPU19DTURfQkFTRSB8IDB4MTkpDQo+
ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9CSU9TX1JFQURfRk1fU09DX1RFTVBfVEhSRVNIDQo+ID4+
IAkoSVBDX1BVTklUX0JJT1NfQ01EX0JBU0UgfCAweDFhKQ0KPiA+PiAtI2RlZmluZSBJUENfUFVO
SVRfQklPU19XUklURV9GTV9TT0NfVEVNUF9USFJFU0gNCj4gPj4gCShJUENfUFVOSVRfQklPU19D
TURfQkFTRSB8IDB4MWIpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5JVF9CSU9TX1pFUk8JCQkoMHgw
MCkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfVlJfSU5URVJGQUNFCQkoMHgwMSkNCj4g
Pj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9QQ1MJCQkoMHgwMikNCj4gPj4gKyNkZWZp
bmUgSVBDX1BVTklUX0JJT1NfV1JJVEVfUENTCQkoMHgwMykNCj4gPj4gKyNkZWZpbmUgSVBDX1BV
TklUX0JJT1NfUkVBRF9QQ1VfQ09ORklHCQkoMHgwNCkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklU
X0JJT1NfV1JJVEVfUENVX0NPTkZJRwkJKDB4MDUpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5JVF9C
SU9TX1JFQURfUEwxX1NFVFRJTkcJCSgweDA2KQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklP
U19XUklURV9QTDFfU0VUVElORwkoMHgwNykNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1Nf
VFJJR0dFUl9WRERfUkFNCQkoMHgwOCkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVB
RF9URUxFX0lORk8JCSgweDA5KQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19SRUFEX1RF
TEVfVFJBQ0VfQ1RSTAkoMHgwYSkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfV1JJVEVf
VEVMRV9UUkFDRV9DVFJMCSgweDBiKQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19SRUFE
X1RFTEVfRVZFTlRfQ1RSTAkoMHgwYykNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfV1JJ
VEVfVEVMRV9FVkVOVF9DVFJMCSgweDBkKQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19S
RUFEX1RFTEVfVFJBQ0UJCSgweDBlKQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklU
RV9URUxFX1RSQUNFCQkoMHgwZikNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9U
RUxFX0VWRU5UCQkoMHgxMCkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfV1JJVEVfVEVM
RV9FVkVOVAkJKDB4MTEpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5JVF9CSU9TX1JFQURfTU9EVUxF
X1RFTVAJCSgweDEyKQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19SRVNFUlZFRAkJCSgw
eDEzKQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19SRUFEX1ZPTFRBR0VfT1ZFUgkoMHgx
NCkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfV1JJVEVfVk9MVEFHRV9PVkVSCSgweDE1
KQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19SRUFEX1JBVElPX09WRVIJCSgweDE2KQ0K
PiA+PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklURV9SQVRJT19PVkVSCQkoMHgxNykNCj4g
Pj4gKyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfUkVBRF9WRl9HTF9DVFJMCQkoMHgxOCkNCj4gPj4g
KyNkZWZpbmUgSVBDX1BVTklUX0JJT1NfV1JJVEVfVkZfR0xfQ1RSTAkJKDB4MTkpDQo+ID4+ICsj
ZGVmaW5lIElQQ19QVU5JVF9CSU9TX1JFQURfRk1fU09DX1RFTVBfVEhSRVNICSgweDFhKQ0KPiA+
PiArI2RlZmluZSBJUENfUFVOSVRfQklPU19XUklURV9GTV9TT0NfVEVNUF9USFJFU0gJKDB4MWIp
DQo+ID4+DQo+ID4+ICAgLyogR1QgRHJpdmVyID0+IFBjb2RlIGNvbW1hbmRzICovDQo+ID4+IC0j
ZGVmaW5lIElQQ19QVU5JVF9HVERfWkVSTw0KPiAJKElQQ19QVU5JVF9HVERfQ01EX0JBU0UNCj4g
Pj4gfCAweDAwKQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfR1REX0NPTkZJRw0KPiA+PiAJKElQ
Q19QVU5JVF9HVERfQ01EX0JBU0UgfCAweDAxKQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfR1RE
X1JFQURfSUNDUF9MSUNfQ0RZTl9TQ0FMDQo+ID4+IAkoSVBDX1BVTklUX0dURF9DTURfQkFTRSB8
IDB4MDIpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9HVERfV1JJVEVfSUNDUF9MSUNfQ0RZTl9T
Q0FMDQo+ID4+IAkoSVBDX1BVTklUX0dURF9DTURfQkFTRSB8IDB4MDMpDQo+ID4+IC0jZGVmaW5l
IElQQ19QVU5JVF9HVERfR0VUX1dNX1ZBTA0KPiA+PiAJKElQQ19QVU5JVF9HVERfQ01EX0JBU0Ug
fCAweDA2KQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfR1REX1dSSVRFX0NPTkZJR19XSVNIUkVR
DQo+ID4+IAkoSVBDX1BVTklUX0dURF9DTURfQkFTRSB8IDB4MDcpDQo+ID4+IC0jZGVmaW5lIElQ
Q19QVU5JVF9HVERfUkVBRF9SRVFfRFVUWV9DWUNMRQ0KPiA+PiAJKElQQ19QVU5JVF9HVERfQ01E
X0JBU0UgfCAweDE2KQ0KPiA+PiAtI2RlZmluZSBJUENfUFVOSVRfR1REX0RJU19WT0xfRlJFUV9D
SEdfUkVRVUVTVA0KPiA+PiAJKElQQ19QVU5JVF9HVERfQ01EX0JBU0UgfCAweDE3KQ0KPiA+PiAt
I2RlZmluZSBJUENfUFVOSVRfR1REX0RZTkFfRFVUWV9DWUNMRV9DVFJMDQo+ID4+IAkoSVBDX1BV
TklUX0dURF9DTURfQkFTRSB8IDB4MWEpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9HVERfRFlO
QV9EVVRZX0NZQ0xFX1RVTklORw0KPiA+PiAJKElQQ19QVU5JVF9HVERfQ01EX0JBU0UgfCAweDFj
KQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfR1REX1pFUk8JCQkoMHgwMCkNCj4gPj4gKyNkZWZp
bmUgSVBDX1BVTklUX0dURF9DT05GSUcJCQkoMHgwMSkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklU
X0dURF9SRUFEX0lDQ1BfTElDX0NEWU5fU0NBTAkoMHgwMikNCj4gPj4gKyNkZWZpbmUgSVBDX1BV
TklUX0dURF9XUklURV9JQ0NQX0xJQ19DRFlOX1NDQUwJKDB4MDMpDQo+ID4+ICsjZGVmaW5lIElQ
Q19QVU5JVF9HVERfR0VUX1dNX1ZBTAkJKDB4MDYpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5JVF9H
VERfV1JJVEVfQ09ORklHX1dJU0hSRVEJKDB4MDcpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5JVF9H
VERfUkVBRF9SRVFfRFVUWV9DWUNMRQkoMHgxNikNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0dU
RF9ESVNfVk9MX0ZSRVFfQ0hHX1JFUVVFU1QJKDB4MTcpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5J
VF9HVERfRFlOQV9EVVRZX0NZQ0xFX0NUUkwJKDB4MWEpDQo+ID4+ICsjZGVmaW5lIElQQ19QVU5J
VF9HVERfRFlOQV9EVVRZX0NZQ0xFX1RVTklORwkoMHgxYykNCj4gPj4NCj4gPj4gICAvKiBJU1Ag
RHJpdmVyID0+IFBjb2RlIGNvbW1hbmRzICovDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9JU1BE
X1pFUk8NCj4gCShJUENfUFVOSVRfSVNQRF9DTURfQkFTRQ0KPiA+PiB8IDB4MDApDQo+ID4+IC0j
ZGVmaW5lIElQQ19QVU5JVF9JU1BEX0NPTkZJRw0KPiA+PiAJKElQQ19QVU5JVF9JU1BEX0NNRF9C
QVNFIHwgMHgwMSkNCj4gPj4gLSNkZWZpbmUgSVBDX1BVTklUX0lTUERfR0VUX0lTUF9MVFJfVkFM
DQo+ID4+IAkoSVBDX1BVTklUX0lTUERfQ01EX0JBU0UgfCAweDAyKQ0KPiA+PiAtI2RlZmluZSBJ
UENfUFVOSVRfSVNQRF9BQ0NFU1NfSVVfRlJFUV9CT1VORFMNCj4gPj4gCShJUENfUFVOSVRfSVNQ
RF9DTURfQkFTRSB8IDB4MDMpDQo+ID4+IC0jZGVmaW5lIElQQ19QVU5JVF9JU1BEX1JFQURfQ0RZ
Tl9MRVZFTA0KPiA+PiAJKElQQ19QVU5JVF9JU1BEX0NNRF9CQVNFIHwgMHgwNCkNCj4gPj4gLSNk
ZWZpbmUgSVBDX1BVTklUX0lTUERfV1JJVEVfQ0RZTl9MRVZFTA0KPiA+PiAJKElQQ19QVU5JVF9J
U1BEX0NNRF9CQVNFIHwgMHgwNSkNCj4gPj4gKyNkZWZpbmUgSVBDX1BVTklUX0lTUERfWkVSTwkJ
CSgweDAwKQ0KPiA+PiArI2RlZmluZSBJUENfUFVOSVRfSVNQRF9DT05GSUcJCQkoMHgwMSkNCj4g
Pj4gKyNkZWZpbmUgSVBDX1BVTklUX0lTUERfR0VUX0lTUF9MVFJfVkFMCQkoMHgwMikNCj4gPj4g
KyNkZWZpbmUgSVBDX1BVTklUX0lTUERfQUNDRVNTX0lVX0ZSRVFfQk9VTkRTCSgweDAzKQ0KPiA+
PiArI2RlZmluZSBJUENfUFVOSVRfSVNQRF9SRUFEX0NEWU5fTEVWRUwJCSgweDA0KQ0KPiA+PiAr
I2RlZmluZSBJUENfUFVOSVRfSVNQRF9XUklURV9DRFlOX0xFVkVMCQkoMHgwNSkNCj4gPj4NCj4g
Pj4gICAvKiBFcnJvciBjb2RlcyAqLw0KPiA+PiAgICNkZWZpbmUgSVBDX1BVTklUX0VSUl9TVUND
RVNTCQkJMA0KPiA+PiBAQCAtNzcsMjUgKzc0LDExIEBAIHR5cGVkZWYgZW51bSB7DQo+ID4+ICAg
I2RlZmluZSBJUENfUFVOSVRfRVJSX0lOVkFMSURfVlJfSUQJCTUNCj4gPj4gICAjZGVmaW5lIElQ
Q19QVU5JVF9FUlJfVlJfRVJSCQkJNg0KPiA+Pg0KPiA+PiAtI2lmIElTX0VOQUJMRUQoQ09ORklH
X0lOVEVMX1BVTklUX0lQQykNCj4gPj4gLQ0KPiA+PiAtaW50IGludGVsX3B1bml0X2lwY19zaW1w
bGVfY29tbWFuZChpbnQgY21kLCBpbnQgcGFyYTEsIGludCBwYXJhMik7DQo+ID4+IC1pbnQNCj4g
Pj4gaW50ZWxfcHVuaXRfaXBjX2NvbW1hbmQodTMyIGNtZCwgdTMyIHBhcmExLCB1MzIgcGFyYTIs
IHUzMiAqaW4sIHUzMg0KPiA+PiAqb3V0KTsNCj4gPj4gLQ0KPiA+PiAtI2Vsc2UNCj4gPj4gLQ0K
PiA+PiAtc3RhdGljIGlubGluZSBpbnQgaW50ZWxfcHVuaXRfaXBjX3NpbXBsZV9jb21tYW5kKGlu
dCBjbWQsDQo+ID4+IC0JCQkJCQkgIGludCBwYXJhMSwgaW50IHBhcmEyKQ0KPiA+PiArc3RhdGlj
IGlubGluZSB2b2lkIHB1bml0X2NtZF9pbml0KHUzMiAqY21kLCB1MzIgcGFyYW0xLCB1MzIgcGFy
YW0yLA0KPiA+PiArdTMyDQo+ID4+ICtwYXJhbTMpDQo+ID4+ICAgew0KPiA+PiAtCXJldHVybiAt
RU5PREVWOw0KPiA+PiArCWNtZFswXSA9IHBhcmFtMTsNCj4gPj4gKwljbWRbMV0gPSBwYXJhbTI7
DQo+ID4+ICsJY21kWzJdID0gcGFyYW0zOw0KPiA+PiAgIH0NCj4gPj4NCj4gPj4gLXN0YXRpYyBp
bmxpbmUgaW50IGludGVsX3B1bml0X2lwY19jb21tYW5kKHUzMiBjbWQsIHUzMiBwYXJhMSwgdTMy
DQo+IHBhcmEyLA0KPiA+PiAtCQkJCQkgIHUzMiAqaW4sIHUzMiAqb3V0KQ0KPiA+PiAtew0KPiA+
PiAtCXJldHVybiAtRU5PREVWOw0KPiA+PiAtfQ0KPiA+PiAtDQo+ID4+IC0jZW5kaWYgLyogQ09O
RklHX0lOVEVMX1BVTklUX0lQQyAqLw0KPiA+PiAtDQo+ID4+ICAgI2VuZGlmDQo+ID4+IGRpZmYg
LS1naXQgYS9kcml2ZXJzL3BsYXRmb3JtL3g4Ni9LY29uZmlnDQo+ID4+IGIvZHJpdmVycy9wbGF0
Zm9ybS94ODYvS2NvbmZpZyBpbmRleCA3MjRlZTY5Ni4uOTQ0MmMyMyAxMDA2NDQNCj4gPj4gLS0t
IGEvZHJpdmVycy9wbGF0Zm9ybS94ODYvS2NvbmZpZw0KPiA+PiArKysgYi9kcml2ZXJzL3BsYXRm
b3JtL3g4Ni9LY29uZmlnDQo+ID4+IEBAIC0xMDk2LDYgKzEwOTYsNyBAQCBjb25maWcgU1VSRkFD
RV8zX0JVVFRPTg0KPiA+Pg0KPiA+PiAgIGNvbmZpZyBJTlRFTF9QVU5JVF9JUEMNCj4gPj4gICAJ
dHJpc3RhdGUgIkludGVsIFAtVW5pdCBJUEMgRHJpdmVyIg0KPiA+PiArCXNlbGVjdCBSRUdNQVBf
TU1JTw0KPiA+PiAgIAktLS1oZWxwLS0tDQo+ID4+ICAgCSAgVGhpcyBkcml2ZXIgcHJvdmlkZXMg
c3VwcG9ydCBmb3IgSW50ZWwgUC1Vbml0IE1haWxib3ggSVBDDQo+ID4+IG1lY2hhbmlzbSwNCj4g
Pj4gICAJICB3aGljaCBpcyB1c2VkIHRvIGJyaWRnZSB0aGUgY29tbXVuaWNhdGlvbnMgYmV0d2Vl
biBrZXJuZWwgYW5kIFAtDQo+ID4+IFVuaXQuDQo+ID4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3Bs
YXRmb3JtL3g4Ni9pbnRlbF9wdW5pdF9pcGMuYw0KPiA+PiBiL2RyaXZlcnMvcGxhdGZvcm0veDg2
L2ludGVsX3B1bml0X2lwYy5jDQo+ID4+IGluZGV4IGI1Yjg5MDEuLmYzMTBhMDUgMTAwNjQ0DQo+
ID4+IC0tLSBhL2RyaXZlcnMvcGxhdGZvcm0veDg2L2ludGVsX3B1bml0X2lwYy5jDQo+ID4+ICsr
KyBiL2RyaXZlcnMvcGxhdGZvcm0veDg2L2ludGVsX3B1bml0X2lwYy5jDQo+ID4+IEBAIC0xOCwx
OCArMTgsMTggQEANCj4gPj4gICAjaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+DQo+ID4+ICAgI2lu
Y2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPg0KPiA+PiAgICNpbmNsdWRlIDxsaW51eC9wbGF0Zm9y
bV9kZXZpY2UuaD4NCj4gPj4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kYXRhL3g4Ni9pbnRl
bF9pcGNfZGV2Lmg+DQo+ID4+ICsjaW5jbHVkZSA8bGludXgvcmVnbWFwLmg+DQo+ID4+ICAgI2lu
Y2x1ZGUgPGFzbS9pbnRlbF9wdW5pdF9pcGMuaD4NCj4gPj4NCj4gPj4gLS8qIElQQyBNYWlsYm94
IHJlZ2lzdGVycyAqLw0KPiA+PiAtI2RlZmluZSBPRkZTRVRfREFUQV9MT1cJCTB4MA0KPiA+PiAt
I2RlZmluZSBPRkZTRVRfREFUQV9ISUdICTB4NA0KPiA+PiAgIC8qIGJpdCBmaWVsZCBvZiBpbnRl
cmZhY2UgcmVnaXN0ZXIgKi8NCj4gPj4gICAjZGVmaW5lCUNNRF9SVU4JCQlCSVQoMzEpDQo+ID4+
IC0jZGVmaW5lCUNNRF9FUlJDT0RFX01BU0sJR0VOTUFTSyg3LCAwKQ0KPiA+PiArI2RlZmluZSBD
TURfRVJSQ09ERV9NQVNLCUdFTk1BU0soNywgMCkNCj4gPj4gICAjZGVmaW5lCUNNRF9QQVJBMV9T
SElGVAkJOA0KPiA+PiAgICNkZWZpbmUJQ01EX1BBUkEyX1NISUZUCQkxNg0KPiA+Pg0KPiA+PiAt
I2RlZmluZSBDTURfVElNRU9VVF9TRUNPTkRTCTENCj4gPj4gKy8qIElQQyBQVU5JVCBjb21tYW5k
cyAqLw0KPiA+PiArI2RlZmluZQlJUENfREVWX1BVTklUX0NNRF9TVEFUVVNfRVJSX01BU0sJR0VO
TUFTSyg3LA0KPiA+PiAwKQ0KPiA+Pg0KPiA+PiAgIGVudW0gew0KPiA+PiAgIAlCQVNFX0RBVEEg
PSAwLA0KPiA+PiBAQCAtMzksMTg3ICszOSw0MiBAQCBlbnVtIHsNCj4gPj4NCj4gPj4gICB0eXBl
ZGVmIHN0cnVjdCB7DQo+ID4+ICAgCXN0cnVjdCBkZXZpY2UgKmRldjsNCj4gPj4gLQlzdHJ1Y3Qg
bXV0ZXggbG9jazsNCj4gPj4gLQlpbnQgaXJxOw0KPiA+PiAtCXN0cnVjdCBjb21wbGV0aW9uIGNt
ZF9jb21wbGV0ZTsNCj4gPj4gICAJLyogYmFzZSBvZiBpbnRlcmZhY2UgYW5kIGRhdGEgcmVnaXN0
ZXJzICovDQo+ID4+ICAgCXZvaWQgX19pb21lbSAqYmFzZVtSRVNFUlZFRF9JUENdW0JBU0VfTUFY
XTsNCj4gPj4gKwlzdHJ1Y3QgaW50ZWxfaXBjX2RldiAqaXBjX2RldltSRVNFUlZFRF9JUENdOw0K
PiA+PiAgIAlJUENfVFlQRSB0eXBlOw0KPiA+PiAgIH0gSVBDX0RFVjsNCj4gPj4NCj4gPj4gICBz
dGF0aWMgSVBDX0RFViAqcHVuaXRfaXBjZGV2Ow0KPiA+Pg0KPiA+PiAtc3RhdGljIGlubGluZSB1
MzIgaXBjX3JlYWRfc3RhdHVzKElQQ19ERVYgKmlwY2RldiwgSVBDX1RZUEUgdHlwZSkgLXsNCj4g
Pj4gLQlyZXR1cm4gcmVhZGwoaXBjZGV2LT5iYXNlW3R5cGVdW0JBU0VfSUZBQ0VdKTsNCj4gPj4g
LX0NCj4gPj4gLQ0KPiA+PiAtc3RhdGljIGlubGluZSB2b2lkIGlwY193cml0ZV9jbWQoSVBDX0RF
ViAqaXBjZGV2LCBJUENfVFlQRSB0eXBlLCB1MzINCj4gPj4gY21kKSAtIHsNCj4gPj4gLQl3cml0
ZWwoY21kLCBpcGNkZXYtPmJhc2VbdHlwZV1bQkFTRV9JRkFDRV0pOw0KPiA+PiAtfQ0KPiA+PiAt
DQo+ID4+IC1zdGF0aWMgaW5saW5lIHUzMiBpcGNfcmVhZF9kYXRhX2xvdyhJUENfREVWICppcGNk
ZXYsIElQQ19UWVBFIHR5cGUpIC17DQo+ID4+IC0JcmV0dXJuIHJlYWRsKGlwY2Rldi0+YmFzZVt0
eXBlXVtCQVNFX0RBVEFdICsgT0ZGU0VUX0RBVEFfTE9XKTsNCj4gPj4gLX0NCj4gPj4gLQ0KPiA+
PiAtc3RhdGljIGlubGluZSB1MzIgaXBjX3JlYWRfZGF0YV9oaWdoKElQQ19ERVYgKmlwY2Rldiwg
SVBDX1RZUEUgdHlwZSkgLXsNCj4gPj4gLQlyZXR1cm4gcmVhZGwoaXBjZGV2LT5iYXNlW3R5cGVd
W0JBU0VfREFUQV0gKyBPRkZTRVRfREFUQV9ISUdIKTsNCj4gPj4gLX0NCj4gPj4gLQ0KPiA+PiAt
c3RhdGljIGlubGluZSB2b2lkIGlwY193cml0ZV9kYXRhX2xvdyhJUENfREVWICppcGNkZXYsIElQ
Q19UWVBFDQo+ID4+IHR5cGUsIHUzMg0KPiA+PiBkYXRhKSAtew0KPiA+PiAtCXdyaXRlbChkYXRh
LCBpcGNkZXYtPmJhc2VbdHlwZV1bQkFTRV9EQVRBXSArIE9GRlNFVF9EQVRBX0xPVyk7DQo+ID4+
IC19DQo+ID4+IC0NCj4gPj4gLXN0YXRpYyBpbmxpbmUgdm9pZCBpcGNfd3JpdGVfZGF0YV9oaWdo
KElQQ19ERVYgKmlwY2RldiwgSVBDX1RZUEUNCj4gPj4gdHlwZSwgdTMyDQo+ID4+IGRhdGEpIC17
DQo+ID4+IC0Jd3JpdGVsKGRhdGEsIGlwY2Rldi0+YmFzZVt0eXBlXVtCQVNFX0RBVEFdICsgT0ZG
U0VUX0RBVEFfSElHSCk7DQo+ID4+IC19DQo+ID4+ICtjb25zdCBjaGFyICppcGNfZGV2X25hbWVb
UkVTRVJWRURfSVBDXSA9IHsNCj4gPj4gKwlQVU5JVF9CSU9TX0lQQ19ERVYsDQo+ID4+ICsJUFVO
SVRfR1REX0lQQ19ERVYsDQo+ID4+ICsJUFVOSVRfSVNQX0lQQ19ERVYNCj4gPj4gK307DQo+ID4+
DQo+ID4+IC1zdGF0aWMgY29uc3QgY2hhciAqaXBjX2Vycl9zdHJpbmcoaW50IGVycm9yKSAtew0K
PiA+PiAtCWlmIChlcnJvciA9PSBJUENfUFVOSVRfRVJSX1NVQ0NFU1MpDQo+ID4+IC0JCXJldHVy
biAibm8gZXJyb3IiOw0KPiA+PiAtCWVsc2UgaWYgKGVycm9yID09IElQQ19QVU5JVF9FUlJfSU5W
QUxJRF9DTUQpDQo+ID4+IC0JCXJldHVybiAiaW52YWxpZCBjb21tYW5kIjsNCj4gPj4gLQllbHNl
IGlmIChlcnJvciA9PSBJUENfUFVOSVRfRVJSX0lOVkFMSURfUEFSQU1FVEVSKQ0KPiA+PiAtCQly
ZXR1cm4gImludmFsaWQgcGFyYW1ldGVyIjsNCj4gPj4gLQllbHNlIGlmIChlcnJvciA9PSBJUENf
UFVOSVRfRVJSX0NNRF9USU1FT1VUKQ0KPiA+PiAtCQlyZXR1cm4gImNvbW1hbmQgdGltZW91dCI7
DQo+ID4+IC0JZWxzZSBpZiAoZXJyb3IgPT0gSVBDX1BVTklUX0VSUl9DTURfTE9DS0VEKQ0KPiA+
PiAtCQlyZXR1cm4gImNvbW1hbmQgbG9ja2VkIjsNCj4gPj4gLQllbHNlIGlmIChlcnJvciA9PSBJ
UENfUFVOSVRfRVJSX0lOVkFMSURfVlJfSUQpDQo+ID4+IC0JCXJldHVybiAiaW52YWxpZCB2ciBp
ZCI7DQo+ID4+IC0JZWxzZSBpZiAoZXJyb3IgPT0gSVBDX1BVTklUX0VSUl9WUl9FUlIpDQo+ID4+
IC0JCXJldHVybiAidnIgZXJyb3IiOw0KPiA+PiAtCWVsc2UNCj4gPj4gLQkJcmV0dXJuICJ1bmtu
b3duIGVycm9yIjsNCj4gPj4gLX0NCj4gPj4gK3N0YXRpYyBzdHJ1Y3QgcmVnbWFwX2NvbmZpZyBw
dW5pdF9yZWdtYXBfY29uZmlnID0gew0KPiA+PiArICAgICAgICAucmVnX2JpdHMgPSAzMiwNCj4g
Pj4gKyAgICAgICAgLnJlZ19zdHJpZGUgPSA0LA0KPiA+PiArICAgICAgICAudmFsX2JpdHMgPSAz
MiwNCj4gPj4gK307DQo+ID4+DQo+ID4+IC1zdGF0aWMgaW50IGludGVsX3B1bml0X2lwY19jaGVj
a19zdGF0dXMoSVBDX0RFViAqaXBjZGV2LCBJUENfVFlQRQ0KPiA+PiB0eXBlKQ0KPiA+PiAraW50
IHByZV9zaW1wbGVfY21kX2ZuKHUzMiAqY21kX2xpc3QsIHUzMiBjbWRsZW4pDQo+ID4+ICAgew0K
PiA+PiAtCWludCBsb29wcyA9IENNRF9USU1FT1VUX1NFQ09ORFMgKiBVU0VDX1BFUl9TRUM7DQo+
ID4+IC0JaW50IGVycmNvZGU7DQo+ID4+IC0JaW50IHN0YXR1czsNCj4gPj4gLQ0KPiA+PiAtCWlm
IChpcGNkZXYtPmlycSkgew0KPiA+PiAtCQlpZiAoIXdhaXRfZm9yX2NvbXBsZXRpb25fdGltZW91
dCgmaXBjZGV2LT5jbWRfY29tcGxldGUsDQo+ID4+IC0JCQkJCQkgQ01EX1RJTUVPVVRfU0VDT05E
UyAqDQo+ID4+IEhaKSkgew0KPiA+PiAtCQkJZGV2X2VycihpcGNkZXYtPmRldiwgIklQQyB0aW1l
ZCBvdXRcbiIpOw0KPiA+PiAtCQkJcmV0dXJuIC1FVElNRURPVVQ7DQo+ID4+IC0JCX0NCj4gPj4g
LQl9IGVsc2Ugew0KPiA+PiAtCQl3aGlsZSAoKGlwY19yZWFkX3N0YXR1cyhpcGNkZXYsIHR5cGUp
ICYgQ01EX1JVTikgJiYgLS0NCj4gPj4gbG9vcHMpDQo+ID4+IC0JCQl1ZGVsYXkoMSk7DQo+ID4+
IC0JCWlmICghbG9vcHMpIHsNCj4gPj4gLQkJCWRldl9lcnIoaXBjZGV2LT5kZXYsICJJUEMgdGlt
ZWQgb3V0XG4iKTsNCj4gPj4gLQkJCXJldHVybiAtRVRJTUVET1VUOw0KPiA+PiAtCQl9DQo+ID4+
IC0JfQ0KPiA+PiArCWlmICghY21kX2xpc3QgfHwgY21kbGVuICE9IFBVTklUX1BBUkFNX0xFTikN
Cj4gPj4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4+DQo+ID4+IC0Jc3RhdHVzID0gaXBjX3JlYWRf
c3RhdHVzKGlwY2RldiwgdHlwZSk7DQo+ID4+IC0JZXJyY29kZSA9IHN0YXR1cyAmIENNRF9FUlJD
T0RFX01BU0s7DQo+ID4+IC0JaWYgKGVycmNvZGUpIHsNCj4gPj4gLQkJZGV2X2VycihpcGNkZXYt
PmRldiwgIklQQyBmYWlsZWQ6ICVzLCBJUENfU1RTPTB4JXhcbiIsDQo+ID4+IC0JCQlpcGNfZXJy
X3N0cmluZyhlcnJjb2RlKSwgc3RhdHVzKTsNCj4gPj4gLQkJcmV0dXJuIC1FSU87DQo+ID4+IC0J
fQ0KPiA+PiArCWNtZF9saXN0WzBdIHw9IENNRF9SVU4gfCBjbWRfbGlzdFsxXSA8PCBDTURfUEFS
QTFfU0hJRlQgfA0KPiA+PiArCQljbWRfbGlzdFsyXSA8PCBDTURfUEFSQTFfU0hJRlQ7DQo+ID4+
DQo+ID4+ICAgCXJldHVybiAwOw0KPiA+PiAgIH0NCj4gPj4NCj4gPj4gLS8qKg0KPiA+PiAtICog
aW50ZWxfcHVuaXRfaXBjX3NpbXBsZV9jb21tYW5kKCkgLSBTaW1wbGUgSVBDIGNvbW1hbmQNCj4g
Pj4gLSAqIEBjbWQ6CUlQQyBjb21tYW5kIGNvZGUuDQo+ID4+IC0gKiBAcGFyYTE6CUZpcnN0IDhi
aXQgcGFyYW1ldGVyLCBzZXQgMCBpZiBub3QgdXNlZC4NCj4gPj4gLSAqIEBwYXJhMjoJU2Vjb25k
IDhiaXQgcGFyYW1ldGVyLCBzZXQgMCBpZiBub3QgdXNlZC4NCj4gPj4gLSAqDQo+ID4+IC0gKiBT
ZW5kIGEgSVBDIGNvbW1hbmQgdG8gUC1Vbml0IHdoZW4gdGhlcmUgaXMgbm8gZGF0YSB0cmFuc2Fj
dGlvbg0KPiA+PiAtICoNCj4gPj4gLSAqIFJldHVybjoJSVBDIGVycm9yIGNvZGUgb3IgMCBvbiBz
dWNjZXNzLg0KPiA+PiAtICovDQo+ID4+IC1pbnQgaW50ZWxfcHVuaXRfaXBjX3NpbXBsZV9jb21t
YW5kKGludCBjbWQsIGludCBwYXJhMSwgaW50IHBhcmEyKSAtew0KPiA+PiAtCUlQQ19ERVYgKmlw
Y2RldiA9IHB1bml0X2lwY2RldjsNCj4gPj4gLQlJUENfVFlQRSB0eXBlOw0KPiA+PiAtCXUzMiB2
YWw7DQo+ID4+IC0JaW50IHJldDsNCj4gPj4gLQ0KPiA+PiAtCW11dGV4X2xvY2soJmlwY2Rldi0+
bG9jayk7DQo+ID4+IC0NCj4gPj4gLQlyZWluaXRfY29tcGxldGlvbigmaXBjZGV2LT5jbWRfY29t
cGxldGUpOw0KPiA+PiAtCXR5cGUgPSAoY21kICYgSVBDX1BVTklUX0NNRF9UWVBFX01BU0spID4+
IElQQ19UWVBFX09GRlNFVDsNCj4gPj4gLQ0KPiA+PiAtCXZhbCA9IGNtZCAmIH5JUENfUFVOSVRf
Q01EX1RZUEVfTUFTSzsNCj4gPj4gLQl2YWwgfD0gQ01EX1JVTiB8IHBhcmEyIDw8IENNRF9QQVJB
Ml9TSElGVCB8IHBhcmExIDw8DQo+ID4+IENNRF9QQVJBMV9TSElGVDsNCj4gPj4gLQlpcGNfd3Jp
dGVfY21kKGlwY2RldiwgdHlwZSwgdmFsKTsNCj4gPj4gLQlyZXQgPSBpbnRlbF9wdW5pdF9pcGNf
Y2hlY2tfc3RhdHVzKGlwY2RldiwgdHlwZSk7DQo+ID4+IC0NCj4gPj4gLQltdXRleF91bmxvY2so
JmlwY2Rldi0+bG9jayk7DQo+ID4+IC0NCj4gPj4gLQlyZXR1cm4gcmV0Ow0KPiA+PiAtfQ0KPiA+
PiAtRVhQT1JUX1NZTUJPTChpbnRlbF9wdW5pdF9pcGNfc2ltcGxlX2NvbW1hbmQpOw0KPiA+PiAt
DQo+ID4+IC0vKioNCj4gPj4gLSAqIGludGVsX3B1bml0X2lwY19jb21tYW5kKCkgLSBJUEMgY29t
bWFuZCB3aXRoIGRhdGEgYW5kIHBvaW50ZXJzDQo+ID4+IC0gKiBAY21kOglJUEMgY29tbWFuZCBj
b2RlLg0KPiA+PiAtICogQHBhcmExOglGaXJzdCA4Yml0IHBhcmFtZXRlciwgc2V0IDAgaWYgbm90
IHVzZWQuDQo+ID4+IC0gKiBAcGFyYTI6CVNlY29uZCA4Yml0IHBhcmFtZXRlciwgc2V0IDAgaWYg
bm90IHVzZWQuDQo+ID4+IC0gKiBAaW46CQlJbnB1dCBkYXRhLCAzMmJpdCBmb3IgQklPUyBjbWQs
IHR3byAzMmJpdCBmb3IgR1REDQo+ID4+IGFuZCBJU1BELg0KPiA+PiAtICogQG91dDoJT3V0cHV0
IGRhdGEuDQo+ID4+IC0gKg0KPiA+PiAtICogU2VuZCBhIElQQyBjb21tYW5kIHRvIFAtVW5pdCB3
aXRoIGRhdGEgdHJhbnNhY3Rpb24NCj4gPj4gLSAqDQo+ID4+IC0gKiBSZXR1cm46CUlQQyBlcnJv
ciBjb2RlIG9yIDAgb24gc3VjY2Vzcy4NCj4gPj4gLSAqLw0KPiA+PiAtaW50IGludGVsX3B1bml0
X2lwY19jb21tYW5kKHUzMiBjbWQsIHUzMiBwYXJhMSwgdTMyIHBhcmEyLCB1MzIgKmluLA0KPiA+
PiB1MzINCj4gPj4gKm91dCkgLXsNCj4gPj4gLQlJUENfREVWICppcGNkZXYgPSBwdW5pdF9pcGNk
ZXY7DQo+ID4+IC0JSVBDX1RZUEUgdHlwZTsNCj4gPj4gLQl1MzIgdmFsOw0KPiA+PiAtCWludCBy
ZXQ7DQo+ID4+IC0NCj4gPj4gLQltdXRleF9sb2NrKCZpcGNkZXYtPmxvY2spOw0KPiA+PiAtDQo+
ID4+IC0JcmVpbml0X2NvbXBsZXRpb24oJmlwY2Rldi0+Y21kX2NvbXBsZXRlKTsNCj4gPj4gLQl0
eXBlID0gKGNtZCAmIElQQ19QVU5JVF9DTURfVFlQRV9NQVNLKSA+PiBJUENfVFlQRV9PRkZTRVQ7
DQo+ID4+IC0NCj4gPj4gLQlpZiAoaW4pIHsNCj4gPj4gLQkJaXBjX3dyaXRlX2RhdGFfbG93KGlw
Y2RldiwgdHlwZSwgKmluKTsNCj4gPj4gLQkJaWYgKHR5cGUgPT0gR1REUklWRVJfSVBDIHx8IHR5
cGUgPT0gSVNQRFJJVkVSX0lQQykNCj4gPj4gLQkJCWlwY193cml0ZV9kYXRhX2hpZ2goaXBjZGV2
LCB0eXBlLCAqKytpbik7DQo+ID4+IC0JfQ0KPiA+PiAtDQo+ID4+IC0JdmFsID0gY21kICYgfklQ
Q19QVU5JVF9DTURfVFlQRV9NQVNLOw0KPiA+PiAtCXZhbCB8PSBDTURfUlVOIHwgcGFyYTIgPDwg
Q01EX1BBUkEyX1NISUZUIHwgcGFyYTEgPDwNCj4gPj4gQ01EX1BBUkExX1NISUZUOw0KPiA+PiAt
CWlwY193cml0ZV9jbWQoaXBjZGV2LCB0eXBlLCB2YWwpOw0KPiA+PiAtDQo+ID4+IC0JcmV0ID0g
aW50ZWxfcHVuaXRfaXBjX2NoZWNrX3N0YXR1cyhpcGNkZXYsIHR5cGUpOw0KPiA+PiAtCWlmIChy
ZXQpDQo+ID4+IC0JCWdvdG8gb3V0Ow0KPiA+PiAtDQo+ID4+IC0JaWYgKG91dCkgew0KPiA+PiAt
CQkqb3V0ID0gaXBjX3JlYWRfZGF0YV9sb3coaXBjZGV2LCB0eXBlKTsNCj4gPj4gLQkJaWYgKHR5
cGUgPT0gR1REUklWRVJfSVBDIHx8IHR5cGUgPT0gSVNQRFJJVkVSX0lQQykNCj4gPj4gLQkJCSor
K291dCA9IGlwY19yZWFkX2RhdGFfaGlnaChpcGNkZXYsIHR5cGUpOw0KPiA+PiAtCX0NCj4gPj4g
LQ0KPiA+PiAtb3V0Og0KPiA+PiAtCW11dGV4X3VubG9jaygmaXBjZGV2LT5sb2NrKTsNCj4gPj4g
LQlyZXR1cm4gcmV0Ow0KPiA+PiAtfQ0KPiA+PiAtRVhQT1JUX1NZTUJPTF9HUEwoaW50ZWxfcHVu
aXRfaXBjX2NvbW1hbmQpOw0KPiA+PiAtDQo+ID4+IC1zdGF0aWMgaXJxcmV0dXJuX3QgaW50ZWxf
cHVuaXRfaW9jKGludCBpcnEsIHZvaWQgKmRldl9pZCkNCj4gPj4gKy8qIElucHV0IGRhdGEsIDMy
Yml0IGZvciBCSU9TIGNtZCwgdHdvIDMyYml0IGZvciBHVEQgYW5kIElTUEQuICovDQo+ID4+ICtp
bnQNCj4gPj4gK3ByZV9yYXdfY21kX2ZuKHUzMiAqY21kX2xpc3QsIHUzMiBjbWRsZW4sIHU4ICpp
biwgdTMyIGlubGVuLCB1MzIgKm91dCwNCj4gPj4gKwkJdTMyIG91dGxlbiwgdTMyIGRwdHIsIHUz
MiBzcHRyKQ0KPiA+PiAgIHsNCj4gPj4gLQlJUENfREVWICppcGNkZXYgPSBkZXZfaWQ7DQo+ID4+
IC0NCj4gPj4gLQljb21wbGV0ZSgmaXBjZGV2LT5jbWRfY29tcGxldGUpOw0KPiA+PiAtCXJldHVy
biBJUlFfSEFORExFRDsNCj4gPj4gKwlyZXR1cm4gcHJlX3NpbXBsZV9jbWRfZm4oY21kX2xpc3Qs
IGNtZGxlbik7DQo+ID4+ICAgfQ0KPiA+Pg0KPiA+PiAgIHN0YXRpYyBpbnQgaW50ZWxfcHVuaXRf
Z2V0X2JhcnMoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikgQEANCj4gPj4gLTI4Miw5DQo+
ID4+ICsxMzcsNzcgQEAgc3RhdGljIGludCBpbnRlbF9wdW5pdF9nZXRfYmFycyhzdHJ1Y3QgcGxh
dGZvcm1fZGV2aWNlDQo+ID4+ICsqcGRldikNCj4gPj4gICAJcmV0dXJuIDA7DQo+ID4+ICAgfQ0K
PiA+Pg0KPiA+PiArc3RhdGljIGludCBwdW5pdF9pcGNfZXJyX2NvZGUoaW50IHN0YXR1cykgew0K
PiA+PiArCXJldHVybiAoc3RhdHVzICYgQ01EX0VSUkNPREVfTUFTSyk7IH0NCj4gPj4gKw0KPiA+
PiArc3RhdGljIGludCBwdW5pdF9pcGNfYnVzeV9jaGVjayhpbnQgc3RhdHVzKSB7DQo+ID4+ICsJ
cmV0dXJuIHN0YXR1cyB8IENNRF9SVU47DQo+ID4+ICt9DQo+ID4+ICsNCj4gPj4gK3N0YXRpYyBz
dHJ1Y3QgaW50ZWxfaXBjX2RldiAqaW50ZWxfcHVuaXRfaXBjX2Rldl9jcmVhdGUoc3RydWN0IGRl
dmljZQ0KPiAqZGV2LA0KPiA+PiArCQljb25zdCBjaGFyICpkZXZuYW1lLA0KPiA+PiArCQlpbnQg
aXJxLA0KPiA+PiArCQl2b2lkIF9faW9tZW0gKmJhc2UsDQo+ID4+ICsJCXZvaWQgX19pb21lbSAq
ZGF0YSkNCj4gPj4gK3sNCj4gPj4gKwlzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9vcHMgKm9wczsNCj4g
Pj4gKwlzdHJ1Y3QgaW50ZWxfaXBjX2Rldl9jZmcgKmNmZzsNCj4gPj4gKwlzdHJ1Y3QgcmVnbWFw
ICpjbWRfcmVncywgKmRhdGFfcmVnczsNCj4gPj4gKw0KPiA+PiArICAgICAgICBjZmcgPSBkZXZt
X2t6YWxsb2MoZGV2LCBzaXplb2YoKmNmZyksIEdGUF9LRVJORUwpOw0KPiA+PiArICAgICAgICBp
ZiAoIWNmZykNCj4gPj4gKyAgICAgICAgICAgICAgICByZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsN
Cj4gPj4gKw0KPiA+PiArCW9wcyA9IGRldm1fa3phbGxvYyhkZXYsIHNpemVvZigqb3BzKSwgR0ZQ
X0tFUk5FTCk7DQo+ID4+ICsJaWYgKCFvcHMpDQo+ID4+ICsJCXJldHVybiBFUlJfUFRSKC1FTk9N
RU0pOw0KPiA+PiArDQo+ID4+ICsJcHVuaXRfcmVnbWFwX2NvbmZpZy5uYW1lID0gZGV2bV9rYXNw
cmludGYoZGV2LCBHRlBfS0VSTkVMLA0KPiA+PiAiJXNfJXMiLA0KPiA+PiArCQkJCQkJICBkZXZu
YW1lLCAiYmFzZSIpOw0KPiA+PiArDQo+ID4+ICsJY21kX3JlZ3MgPSBkZXZtX3JlZ21hcF9pbml0
X21taW9fY2xrKGRldiwgTlVMTCwgYmFzZSwNCj4gPj4gKwkJCSZwdW5pdF9yZWdtYXBfY29uZmln
KTsNCj4gPj4gKwlpZiAoSVNfRVJSKGNtZF9yZWdzKSkgew0KPiA+PiArICAgICAgICAgICAgICAg
IGRldl9lcnIoZGV2LCAiY21kX3JlZ3MgcmVnbWFwIGluaXQgZmFpbGVkXG4iKTsNCj4gPj4gKyAg
ICAgICAgICAgICAgICByZXR1cm4gRVJSX0NBU1QoY21kX3JlZ3MpOzsNCj4gPj4gKyAgICAgICAg
fQ0KPiA+PiArDQo+ID4+ICsJcHVuaXRfcmVnbWFwX2NvbmZpZy5uYW1lID0gZGV2bV9rYXNwcmlu
dGYoZGV2LCBHRlBfS0VSTkVMLA0KPiA+PiAiJXNfJXMiLA0KPiA+PiArCQkJCQkJICBkZXZuYW1l
LCAiZGF0YSIpOw0KPiA+PiArDQo+ID4+ICsgICAgICAgIGRhdGFfcmVncyA9IGRldm1fcmVnbWFw
X2luaXRfbW1pb19jbGsoZGV2LCBOVUxMLCBkYXRhLA0KPiA+PiArCQkJJnB1bml0X3JlZ21hcF9j
b25maWcpOw0KPiA+PiArICAgICAgICBpZiAoSVNfRVJSKGRhdGFfcmVncykpIHsNCj4gPj4gKyAg
ICAgICAgICAgICAgICBkZXZfZXJyKGRldiwgImRhdGFfcmVncyByZWdtYXAgaW5pdCBmYWlsZWRc
biIpOw0KPiA+PiArICAgICAgICAgICAgICAgIHJldHVybiBFUlJfQ0FTVChkYXRhX3JlZ3MpOzsN
Cj4gPj4gKyAgICAgICAgfQ0KPiA+PiArDQo+ID4+ICsJLyogc2V0IElQQyBkZXYgb3BzICovDQo+
ID4+ICsJb3BzLT50b19lcnJfY29kZSA9IHB1bml0X2lwY19lcnJfY29kZTsNCj4gPj4gKwlvcHMt
PmJ1c3lfY2hlY2sgPSBwdW5pdF9pcGNfYnVzeV9jaGVjazsNCj4gPj4gKwlvcHMtPnByZV9zaW1w
bGVfY21kX2ZuID0gcHJlX3NpbXBsZV9jbWRfZm47DQo+ID4+ICsJb3BzLT5wcmVfcmF3X2NtZF9m
biA9IHByZV9yYXdfY21kX2ZuOw0KPiA+PiArDQo+ID4+ICsJaWYgKGlycSA+IDApDQo+ID4+ICsJ
ICAgICAgICBjZmctPm1vZGUgPSBJUENfREVWX01PREVfSVJROw0KPiA+PiArCWVsc2UNCj4gPj4g
KwkgICAgICAgIGNmZy0+bW9kZSA9IElQQ19ERVZfTU9ERV9QT0xMSU5HOw0KPiA+PiArDQo+ID4+
ICsJY2ZnLT5jaGFuX3R5cGUgPSBJUENfQ0hBTk5FTF9JQV9QVU5JVDsNCj4gPj4gKwljZmctPmly
cSA9IGlycTsNCj4gPj4gKwljZmctPmlycWZsYWdzID0gSVJRRl9OT19TVVNQRU5EIHwgSVJRRl9T
SEFSRUQ7DQo+ID4+ICsJY2ZnLT5jbWRfcmVncyA9IGNtZF9yZWdzOw0KPiA+PiArCWNmZy0+ZGF0
YV9yZWdzID0gZGF0YV9yZWdzOw0KPiA+PiArDQo+ID4+ICsJcmV0dXJuIGRldm1faW50ZWxfaXBj
X2Rldl9jcmVhdGUoZGV2LCBkZXZuYW1lLCBjZmcsIG9wcyk7IH0NCj4gPj4gKw0KPiA+PiAgIHN0
YXRpYyBpbnQgaW50ZWxfcHVuaXRfaXBjX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBk
ZXYpICB7DQo+ID4+IC0JaW50IGlycSwgcmV0Ow0KPiA+PiArCWludCBpcnEsIHJldCwgaTsNCj4g
Pj4NCj4gPj4gICAJcHVuaXRfaXBjZGV2ID0gZGV2bV9remFsbG9jKCZwZGV2LT5kZXYsDQo+ID4+
ICAgCQkJCSAgICBzaXplb2YoKnB1bml0X2lwY2RldiksIEdGUF9LRVJORUwpOyBAQCAtDQo+ID4+
IDI5NCwzNSArMjE3LDMwIEBAIHN0YXRpYyBpbnQgaW50ZWxfcHVuaXRfaXBjX3Byb2JlKHN0cnVj
dA0KPiA+PiBwbGF0Zm9ybV9kZXZpY2UNCj4gPj4gKnBkZXYpDQo+ID4+ICAgCXBsYXRmb3JtX3Nl
dF9kcnZkYXRhKHBkZXYsIHB1bml0X2lwY2Rldik7DQo+ID4+DQo+ID4+ICAgCWlycSA9IHBsYXRm
b3JtX2dldF9pcnEocGRldiwgMCk7DQo+ID4+IC0JaWYgKGlycSA8IDApIHsNCj4gPj4gLQkJcHVu
aXRfaXBjZGV2LT5pcnEgPSAwOw0KPiA+PiAtCQlkZXZfd2FybigmcGRldi0+ZGV2LCAiSW52YWxp
ZCBJUlEsIHVzaW5nIHBvbGxpbmcgbW9kZVxuIik7DQo+ID4+IC0JfSBlbHNlIHsNCj4gPj4gLQkJ
cmV0ID0gZGV2bV9yZXF1ZXN0X2lycSgmcGRldi0+ZGV2LCBpcnEsIGludGVsX3B1bml0X2lvYywN
Cj4gPj4gLQkJCQkgICAgICAgSVJRRl9OT19TVVNQRU5ELCAiaW50ZWxfcHVuaXRfaXBjIiwNCj4g
Pj4gLQkJCQkgICAgICAgJnB1bml0X2lwY2Rldik7DQo+ID4+IC0JCWlmIChyZXQpIHsNCj4gPj4g
LQkJCWRldl9lcnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byByZXF1ZXN0IGlycTogJWRcbiIsDQo+
ID4+IGlycSk7DQo+ID4+IC0JCQlyZXR1cm4gcmV0Ow0KPiA+PiAtCQl9DQo+ID4+IC0JCXB1bml0
X2lwY2Rldi0+aXJxID0gaXJxOw0KPiA+PiAtCX0NCj4gPj4NCj4gPj4gICAJcmV0ID0gaW50ZWxf
cHVuaXRfZ2V0X2JhcnMocGRldik7DQo+ID4+ICAgCWlmIChyZXQpDQo+ID4+IC0JCWdvdG8gb3V0
Ow0KPiA+PiArCQlyZXR1cm4gcmV0Ow0KPiA+PiArDQo+ID4+ICsJZm9yIChpID0gMDsgaSA8IFJF
U0VSVkVEX0lQQzsgaSsrKSB7DQo+ID4+ICsJCXB1bml0X2lwY2Rldi0+aXBjX2RldltpXSA9IGlu
dGVsX3B1bml0X2lwY19kZXZfY3JlYXRlKA0KPiA+PiArCQkJCSZwZGV2LT5kZXYsDQo+ID4+ICsJ
CQkJaXBjX2Rldl9uYW1lW2ldLA0KPiA+PiArCQkJCWlycSwNCj4gPj4gKwkJCQlwdW5pdF9pcGNk
ZXYtPmJhc2VbaV1bQkFTRV9JRkFDRV0sDQo+ID4+ICsJCQkJcHVuaXRfaXBjZGV2LT5iYXNlW2ld
W0JBU0VfREFUQV0pOw0KPiA+PiArDQo+ID4+ICsJCWlmIChJU19FUlIocHVuaXRfaXBjZGV2LT5p
cGNfZGV2W2ldKSkgew0KPiA+PiArCQkJZGV2X2VycigmcGRldi0+ZGV2LCAiJXMgY3JlYXRlIGZh
aWxlZFxuIiwNCj4gPj4gKwkJCQkJaXBjX2Rldl9uYW1lW2ldKTsNCj4gPj4gKwkJCXJldHVybiBQ
VFJfRVJSKHB1bml0X2lwY2Rldi0+aXBjX2RldltpXSk7DQo+ID4+ICsJCX0NCj4gPj4gKwl9DQo+
ID4+DQo+ID4+ICAgCXB1bml0X2lwY2Rldi0+ZGV2ID0gJnBkZXYtPmRldjsNCj4gPj4gLQltdXRl
eF9pbml0KCZwdW5pdF9pcGNkZXYtPmxvY2spOw0KPiA+PiAtCWluaXRfY29tcGxldGlvbigmcHVu
aXRfaXBjZGV2LT5jbWRfY29tcGxldGUpOw0KPiA+Pg0KPiA+PiAtb3V0Og0KPiA+PiAgIAlyZXR1
cm4gcmV0Ow0KPiA+PiAtfQ0KPiA+Pg0KPiA+PiAtc3RhdGljIGludCBpbnRlbF9wdW5pdF9pcGNf
cmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpIC17DQo+ID4+IC0JcmV0dXJuIDA7
DQo+ID4+ICAgfQ0KPiA+Pg0KPiA+PiAgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgYWNwaV9kZXZpY2Vf
aWQgcHVuaXRfaXBjX2FjcGlfaWRzW10gPSB7IEBADQo+ID4+IC0zMzIsNyArMjUwLDYgQEAgc3Rh
dGljIGNvbnN0IHN0cnVjdCBhY3BpX2RldmljZV9pZA0KPiA+PiBwdW5pdF9pcGNfYWNwaV9pZHNb
XSA9IHsNCj4gPj4NCj4gPj4gICBzdGF0aWMgc3RydWN0IHBsYXRmb3JtX2RyaXZlciBpbnRlbF9w
dW5pdF9pcGNfZHJpdmVyID0gew0KPiA+PiAgIAkucHJvYmUgPSBpbnRlbF9wdW5pdF9pcGNfcHJv
YmUsDQo+ID4+IC0JLnJlbW92ZSA9IGludGVsX3B1bml0X2lwY19yZW1vdmUsDQo+ID4+ICAgCS5k
cml2ZXIgPSB7DQo+ID4+ICAgCQkubmFtZSA9ICJpbnRlbF9wdW5pdF9pcGMiLA0KPiA+PiAgIAkJ
LmFjcGlfbWF0Y2hfdGFibGUgPSBBQ1BJX1BUUihwdW5pdF9pcGNfYWNwaV9pZHMpLCBkaWZmIC0t
Z2l0DQo+ID4+IGEvZHJpdmVycy9wbGF0Zm9ybS94ODYvaW50ZWxfdGVsZW1ldHJ5X3BsdGRydi5j
DQo+ID4+IGIvZHJpdmVycy9wbGF0Zm9ybS94ODYvaW50ZWxfdGVsZW1ldHJ5X3BsdGRydi5jDQo+
ID4+IGluZGV4IGUwNDI0ZDUuLmJmODI4NGEgMTAwNjQ0DQo+ID4+IC0tLSBhL2RyaXZlcnMvcGxh
dGZvcm0veDg2L2ludGVsX3RlbGVtZXRyeV9wbHRkcnYuYw0KPiA+PiArKysgYi9kcml2ZXJzL3Bs
YXRmb3JtL3g4Ni9pbnRlbF90ZWxlbWV0cnlfcGx0ZHJ2LmMNCj4gPiBUaGlzIGlzIGEgbG9naWNh
bCBzZXBhcmF0aW9uIGFuZCBzbyBzaG91bGQgYmUgYSBkaWZmZXJlbnQgcGF0Y2guDQo+IEJ1dCBp
ZiB3ZSBzcGxpdCBpdCBpbnRvIHR3byBkaWZmZXJlbnQgcGF0Y2hlcyB0aGVuIGl0IHdpbGwgYnJl
YWsgdGhlIGJpc2VjdC0NCj4gYWJpbGl0eSBvZiB0aGVzZSBwYXRjaGVzLg0KPiA+DQo+ID4+IEBA
IC05OCw2ICs5OCw3IEBAIHN0cnVjdCB0ZWxlbV9zc3JhbV9yZWdpb24geyAgfTsNCj4gPj4NCj4g
Pj4gICBzdGF0aWMgc3RydWN0IHRlbGVtZXRyeV9wbHRfY29uZmlnICp0ZWxtX2NvbmY7DQo+ID4+
ICtzdGF0aWMgc3RydWN0IGludGVsX2lwY19kZXYgKnB1bml0X2Jpb3NfaXBjX2RldjsNCj4gPiBT
aW1wbHkgcHVuaXRfaXBjX2RldiBpcyBnb29kIGVub3VnaC4NCj4gVGhlcmUgYXJlIHRocmVlIFBV
TklUIElQQyBkZXZpY2VzLiBTbyB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gdGhlbSBJIGFkZGVk
DQo+IGV4dHJhIHN0cmluZyB0byBpdC4NCg0KT0sgdGhhdCBtYWtlcyBzZW5zZS4gDQpIb3dldmVy
IHB1bml0X2Jpb3NfaXBjIGlzIG5laXRoZXIgdGhlIGFjdHVhbCBkZXZpY2UgdHlwZS9uYW1lIG5v
ciBpbmRpY2F0ZXMgdGhlIHVzYWdlIG9mIGl0IHNpbmNlIEJJT1MgaGFzIGdvdCBub3RoaW5nIHRv
IGRvIHdpdGggaXQgKGV4Y2VwdCBmb3IgZXhwb3NpbmcgdGhlIFNTUkFNIGJhc2UgYWRkcikuDQpD
YW4gd2UgcmVuYW1lIHRoaXMgdG8gc29tZXRoaW5nIHRoYXQgYWN0dWFsbHkgZGVub3RlcyB3aGF0
IHRoaXMgaXMsIGUuZywgInB1bml0X3RlbGVtZXRyeV9pcGNfZGV2Ii4gU2FtZSBjaGFuZ2UgbmVl
ZHMgdG8gYmUgZG9uZSBpbiBpbnRlbF9wdW5pdF9pcGMuYyBhcyB3ZWxsLiANCg0KPiA+DQo+ID4+
ICAgLyoNCj4gPj4gICAgKiBUaGUgZm9sbG93aW5nIGNvdW50ZXJzIGFyZSBwcm9ncmFtbWVkIGJ5
IGRlZmF1bHQgZHVyaW5nIHNldHVwLg0KPiA+PiBAQCAtMTI3LDcgKzEyOCw2IEBAIHN0YXRpYyBz
dHJ1Y3QgdGVsZW1ldHJ5X2V2dG1hcA0KPiA+PiAgIAl7IlBNQ19TMElYX0JMT0NLX0lQU19DTE9D
S1MiLCAgICAgICAgICAgMHg2MDBCfSwNCj4gPj4gICB9Ow0KPiA+Pg0KPiA+PiAtDQo+ID4+ICAg
c3RhdGljIHN0cnVjdCB0ZWxlbWV0cnlfZXZ0bWFwDQo+ID4+DQo+ID4+IAl0ZWxlbWV0cnlfYXBs
X3Bzc19kZWZhdWx0X2V2ZW50c1tURUxFTV9NQVhfT1NfQUxMT0NBVEVEX0VWRQ0KPiA+PiBOVFNd
ID0gew0KPiA+PiAgIAl7IklBX0NPUkUwX0M2X1JFUyIsCQkJMHgwNDAwfSwNCj4gPj4gQEAgLTI4
MywxMyArMjgzLDEyIEBAIHN0YXRpYyBpbmxpbmUgaW50DQo+ID4+IHRlbGVtZXRyeV9wbHRfY29u
ZmlnX2lvc3NfZXZlbnQodTMyIGV2dF9pZCwgaW50IGluZGV4KSAgc3RhdGljIGlubGluZQ0KPiA+
PiBpbnQNCj4gPj4gdGVsZW1ldHJ5X3BsdF9jb25maWdfcHNzX2V2ZW50KHUzMiBldnRfaWQsIGlu
dCBpbmRleCkgIHsNCj4gPj4gICAJdTMyIHdyaXRlX2J1ZjsNCj4gPj4gLQlpbnQgcmV0Ow0KPiA+
PiArCXUzMiBjbWRbUFVOSVRfUEFSQU1fTEVOXSA9IHswfTsNCj4gPj4NCj4gPj4gICAJd3JpdGVf
YnVmID0gZXZ0X2lkIHwgVEVMRU1fRVZFTlRfRU5BQkxFOw0KPiA+PiAtCXJldCA9DQo+ID4+IGlu
dGVsX3B1bml0X2lwY19jb21tYW5kKElQQ19QVU5JVF9CSU9TX1dSSVRFX1RFTEVfRVZFTlQsDQo+
ID4+IC0JCQkJICAgICAgaW5kZXgsIDAsICZ3cml0ZV9idWYsIE5VTEwpOw0KPiA+PiAtDQo+ID4+
IC0JcmV0dXJuIHJldDsNCj4gPj4gKwlwdW5pdF9jbWRfaW5pdChjbWQsIElQQ19QVU5JVF9CSU9T
X1dSSVRFX1RFTEVfRVZFTlQsIGluZGV4LCAwKTsNCj4gPj4gKwlyZXR1cm4gaXBjX2Rldl9yYXdf
Y21kKHB1bml0X2Jpb3NfaXBjX2RldiwgY21kLA0KPiA+PiBQVU5JVF9QQVJBTV9MRU4sDQo+ID4+
ICsJCQkodTggKikmd3JpdGVfYnVmLCBzaXplb2Yod3JpdGVfYnVmKSwgTlVMTCwgMCwgMCwgMCk7
DQo+ID4+ICAgfQ0KPiA+IDEpIFdoeSB1c2UgcmF3X2NtZCBoZXJlPyBJdCBzaG91bGQgdXNlIGlw
Y19kZXZfY21kKCkgYWNjb3JkaW5nIHRvDQo+IG9yaWdpbmFsIGRlc2lnbi4gU2FtZSBldmVyeXdo
ZXJlIHRob3VnaCB0aGlzIGZpbGUuDQo+IEluIG15IGluaXRpYWwgdmVyc2lvbnMgb2YgdGhpcyBw
YXRjaCBzZXQsIEkgaGFkIG9ubHkgZXhwb3J0ZWQNCj4gaXBjX2Rldl9yYXdfY21kKCkgQVBJLiBT
aW5jZSB0aGlzIGRyaXZlciByZWZhY3RvcmluZyB3b3JrIHdhcyBkb25lIGR1cmluZw0KPiB0aGF0
IHRpbWUsIEkgaGF2ZSB1c2VkIGludGVsX2Rldl9yYXdfY21kKCkgQVBJIGluIGl0LiBJIGhhdmUg
YWRkZWQNCj4gaXBjX2Rldl9jbWQoKSBBUEkgb25seSByZWNlbnRsecKgIHRvIGhhbmRsZSBzb21l
IG5ldyByZXF1aXJlbWVudHMgaW4NCj4gaW50ZWxfc2N1X2lwYy5jIGRyaXZlci4NCj4gDQo+IEkg
d2lsbCBmaXggaXQgaW4gbmV4dCB2ZXJzaW9uLg0KPiANCj4gPiAyKSBwdW5pdF9jbWRfaW5pdCBh
bmQgaXBjX2Rldl9yYXdfY21kIGFyZSByZXBlYXRlZCBtdWx0aXBsZSB0aW1lDQo+ID4gdGhvdWdo
b3V0IHRoZSBmaWxlLiBUaGV5IGNhbiBiZSBtYWRlIGludG8gYSBzZXBhcmF0ZSBsb2NhbCBBUEkg
aW5zaWRlDQo+ID4gdGVsZW1ldHJ5LCBsaWtlIHRlbGVtZXRyeV9wdW5pdF9zZW5kX2NtZCgpLiBT
YW1lIHRob3VnaG91dA0KPiBJIHdpbGwgbWFrZSB0aGlzIGNoYW5nZSBpbiBuZXh0IHZlcnNpb24u
DQo+ID4NCj4gPj4gICBzdGF0aWMgaW50IHRlbGVtZXRyeV9zZXR1cF9pb3NzZXZ0Y29uZmlnKHN0
cnVjdCB0ZWxlbWV0cnlfZXZ0Y29uZmlnDQo+ID4+IGV2dGNvbmZpZywgQEAgLTQzNSw2ICs0MzQs
NyBAQCBzdGF0aWMgaW50DQo+ID4+IHRlbGVtZXRyeV9zZXR1cF9wc3NldnRjb25maWcoc3RydWN0
IHRlbGVtZXRyeV9ldnRjb25maWcgZXZ0Y29uZmlnLA0KPiA+PiAgIAlpbnQgcmV0LCBpbmRleCwg
aWR4Ow0KPiA+PiAgIAl1MzIgKnBzc19ldnRtYXA7DQo+ID4+ICAgCXUzMiB0ZWxlbV9jdHJsOw0K
PiA+PiArCXUzMiBjbWRbUFVOSVRfUEFSQU1fTEVOXSA9IHswfTsNCj4gPj4NCj4gPj4gICAJbnVt
X3Bzc19ldnRzID0gZXZ0Y29uZmlnLm51bV9ldnRzOw0KPiA+PiAgIAlwc3NfcGVyaW9kID0gZXZ0
Y29uZmlnLnBlcmlvZDsNCj4gPj4gQEAgLTQ0Miw4ICs0NDIsOSBAQCBzdGF0aWMgaW50IHRlbGVt
ZXRyeV9zZXR1cF9wc3NldnRjb25maWcoc3RydWN0DQo+ID4+IHRlbGVtZXRyeV9ldnRjb25maWcg
ZXZ0Y29uZmlnLA0KPiA+Pg0KPiA+PiAgIAkvKiBQU1MgQ29uZmlnICovDQo+ID4+ICAgCS8qIEdl
dCB0ZWxlbWV0cnkgRVZFTlQgQ1RMICovDQo+ID4+IC0JcmV0ID0NCj4gPj4gaW50ZWxfcHVuaXRf
aXBjX2NvbW1hbmQoSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX0VWRU5UX0NUUkwsDQo+ID4+IC0J
CQkJICAgICAgMCwgMCwgTlVMTCwgJnRlbGVtX2N0cmwpOw0KPiA+PiArCXB1bml0X2NtZF9pbml0
KGNtZCwgSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX0VWRU5UX0NUUkwsIDAsDQo+ID4+IDApOw0K
PiA+PiArCXJldCA9IGlwY19kZXZfcmF3X2NtZChwdW5pdF9iaW9zX2lwY19kZXYsIGNtZCwNCj4g
Pj4gUFVOSVRfUEFSQU1fTEVOLCBOVUxMLA0KPiA+PiArCQkJMCwgJnRlbGVtX2N0cmwsIDEsIDAs
IDApOw0KPiA+PiAgIAlpZiAocmV0KSB7DQo+ID4+ICAgCQlwcl9lcnIoIlBTUyBURUxFTV9DVFJM
IFJlYWQgRmFpbGVkXG4iKTsNCj4gPj4gICAJCXJldHVybiByZXQ7DQo+ID4+IEBAIC00NTEsOCAr
NDUyLDkgQEAgc3RhdGljIGludCB0ZWxlbWV0cnlfc2V0dXBfcHNzZXZ0Y29uZmlnKHN0cnVjdA0K
PiA+PiB0ZWxlbWV0cnlfZXZ0Y29uZmlnIGV2dGNvbmZpZywNCj4gPj4NCj4gPj4gICAJLyogRGlz
YWJsZSBUZWxlbWV0cnkgKi8NCj4gPj4gICAJVEVMRU1fRElTQUJMRSh0ZWxlbV9jdHJsKTsNCj4g
Pj4gLQlyZXQgPQ0KPiA+PiBpbnRlbF9wdW5pdF9pcGNfY29tbWFuZChJUENfUFVOSVRfQklPU19X
UklURV9URUxFX0VWRU5UX0NUUkwsDQo+ID4+IC0JCQkJICAgICAgMCwgMCwgJnRlbGVtX2N0cmws
IE5VTEwpOw0KPiA+PiArCXB1bml0X2NtZF9pbml0KGNtZCwgSVBDX1BVTklUX0JJT1NfV1JJVEVf
VEVMRV9FVkVOVF9DVFJMLCAwLA0KPiA+PiAwKTsNCj4gPj4gKwlyZXQgPSBpcGNfZGV2X3Jhd19j
bWQocHVuaXRfYmlvc19pcGNfZGV2LCBjbWQsDQo+ID4+IFBVTklUX1BBUkFNX0xFTiwNCj4gPj4g
KwkJCSh1OCAqKSZ0ZWxlbV9jdHJsLCBzaXplb2YodGVsZW1fY3RybCksIE5VTEwsIDAsIDAsIDAp
Ow0KPiA+PiAgIAlpZiAocmV0KSB7DQo+ID4+ICAgCQlwcl9lcnIoIlBTUyBURUxFTV9DVFJMIEV2
ZW50IERpc2FibGUgV3JpdGUgRmFpbGVkXG4iKTsNCj4gPj4gICAJCXJldHVybiByZXQ7DQo+ID4+
IEBAIC00NjMsOSArNDY1LDEwIEBAIHN0YXRpYyBpbnQgdGVsZW1ldHJ5X3NldHVwX3Bzc2V2dGNv
bmZpZyhzdHJ1Y3QNCj4gPj4gdGVsZW1ldHJ5X2V2dGNvbmZpZyBldnRjb25maWcsDQo+ID4+ICAg
CQkvKiBDbGVhciBBbGwgRXZlbnRzICovDQo+ID4+ICAgCQlURUxFTV9DTEVBUl9FVkVOVFModGVs
ZW1fY3RybCk7DQo+ID4+DQo+ID4+IC0JCXJldCA9IGludGVsX3B1bml0X2lwY19jb21tYW5kKA0K
PiA+PiAtCQkJCUlQQ19QVU5JVF9CSU9TX1dSSVRFX1RFTEVfRVZFTlRfQ1RSTCwNCj4gPj4gLQkJ
CQkwLCAwLCAmdGVsZW1fY3RybCwgTlVMTCk7DQo+ID4+ICsJCXB1bml0X2NtZF9pbml0KGNtZCwN
Cj4gPj4gSVBDX1BVTklUX0JJT1NfV1JJVEVfVEVMRV9FVkVOVF9DVFJMLCAwLCAwKTsNCj4gPj4g
KwkJcmV0ID0gaXBjX2Rldl9yYXdfY21kKHB1bml0X2Jpb3NfaXBjX2RldiwgY21kLA0KPiA+PiBQ
VU5JVF9QQVJBTV9MRU4sDQo+ID4+ICsJCQkJKHU4ICopJnRlbGVtX2N0cmwsIHNpemVvZih0ZWxl
bV9jdHJsKSwgTlVMTCwNCj4gPj4gKwkJCQkwLCAwLCAwKTsNCj4gPj4gICAJCWlmIChyZXQpIHsN
Cj4gPj4gICAJCQlwcl9lcnIoIlBTUyBURUxFTV9DVFJMIEV2ZW50IERpc2FibGUgV3JpdGUNCj4g
RmFpbGVkXG4iKTsNCj4gPj4gICAJCQlyZXR1cm4gcmV0Ow0KPiA+PiBAQCAtNDg5LDkgKzQ5Miwx
MCBAQCBzdGF0aWMgaW50IHRlbGVtZXRyeV9zZXR1cF9wc3NldnRjb25maWcoc3RydWN0DQo+ID4+
IHRlbGVtZXRyeV9ldnRjb25maWcgZXZ0Y29uZmlnLA0KPiA+PiAgIAkJLyogQ2xlYXIgQWxsIEV2
ZW50cyAqLw0KPiA+PiAgIAkJVEVMRU1fQ0xFQVJfRVZFTlRTKHRlbGVtX2N0cmwpOw0KPiA+Pg0K
PiA+PiAtCQlyZXQgPSBpbnRlbF9wdW5pdF9pcGNfY29tbWFuZCgNCj4gPj4gLQkJCQlJUENfUFVO
SVRfQklPU19XUklURV9URUxFX0VWRU5UX0NUUkwsDQo+ID4+IC0JCQkJMCwgMCwgJnRlbGVtX2N0
cmwsIE5VTEwpOw0KPiA+PiArCQlwdW5pdF9jbWRfaW5pdChjbWQsDQo+ID4+IElQQ19QVU5JVF9C
SU9TX1dSSVRFX1RFTEVfRVZFTlRfQ1RSTCwgMCwgMCk7DQo+ID4+ICsJCXJldCA9IGlwY19kZXZf
cmF3X2NtZChwdW5pdF9iaW9zX2lwY19kZXYsIGNtZCwNCj4gPj4gUFVOSVRfUEFSQU1fTEVOLA0K
PiA+PiArCQkJCSh1OCAqKSZ0ZWxlbV9jdHJsLCBzaXplb2YodGVsZW1fY3RybCksIE5VTEwsDQo+
ID4+ICsJCQkJMCwgMCwgMCk7DQo+ID4+ICAgCQlpZiAocmV0KSB7DQo+ID4+ICAgCQkJcHJfZXJy
KCJQU1MgVEVMRU1fQ1RSTCBFdmVudCBEaXNhYmxlIFdyaXRlDQo+IEZhaWxlZFxuIik7DQo+ID4+
ICAgCQkJcmV0dXJuIHJldDsNCj4gPj4gQEAgLTU0MCw4ICs1NDQsOSBAQCBzdGF0aWMgaW50IHRl
bGVtZXRyeV9zZXR1cF9wc3NldnRjb25maWcoc3RydWN0DQo+ID4+IHRlbGVtZXRyeV9ldnRjb25m
aWcgZXZ0Y29uZmlnLA0KPiA+PiAgIAlURUxFTV9FTkFCTEVfUEVSSU9ESUModGVsZW1fY3RybCk7
DQo+ID4+ICAgCXRlbGVtX2N0cmwgfD0gcHNzX3BlcmlvZDsNCj4gPj4NCj4gPj4gLQlyZXQgPQ0K
PiA+PiBpbnRlbF9wdW5pdF9pcGNfY29tbWFuZChJUENfUFVOSVRfQklPU19XUklURV9URUxFX0VW
RU5UX0NUUkwsDQo+ID4+IC0JCQkJICAgICAgMCwgMCwgJnRlbGVtX2N0cmwsIE5VTEwpOw0KPiA+
PiArCXB1bml0X2NtZF9pbml0KGNtZCwgSVBDX1BVTklUX0JJT1NfV1JJVEVfVEVMRV9FVkVOVF9D
VFJMLCAwLA0KPiA+PiAwKTsNCj4gPj4gKwlyZXQgPSBpcGNfZGV2X3Jhd19jbWQocHVuaXRfYmlv
c19pcGNfZGV2LCBjbWQsDQo+ID4+IFBVTklUX1BBUkFNX0xFTiwNCj4gPj4gKwkJCSh1OCAqKSZ0
ZWxlbV9jdHJsLCBzaXplb2YodGVsZW1fY3RybCksIE5VTEwsIDAsIDAsIDApOw0KPiA+PiAgIAlp
ZiAocmV0KSB7DQo+ID4+ICAgCQlwcl9lcnIoIlBTUyBURUxFTV9DVFJMIEV2ZW50IEVuYWJsZSBX
cml0ZSBGYWlsZWRcbiIpOw0KPiA+PiAgIAkJcmV0dXJuIHJldDsNCj4gPj4gQEAgLTYwMSw2ICs2
MDYsNyBAQCBzdGF0aWMgaW50IHRlbGVtZXRyeV9zZXR1cChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNl
DQo+ID4+ICpwZGV2KSAgew0KPiA+PiAgIAlzdHJ1Y3QgdGVsZW1ldHJ5X2V2dGNvbmZpZyBwc3Nf
ZXZ0Y29uZmlnLCBpb3NzX2V2dGNvbmZpZzsNCj4gPj4gICAJdTMyIHJlYWRfYnVmLCBldmVudHMs
IGV2ZW50X3JlZ3M7DQo+ID4+ICsJdTMyIGNtZFtQVU5JVF9QQVJBTV9MRU5dID0gezB9Ow0KPiA+
PiAgIAlpbnQgcmV0Ow0KPiA+Pg0KPiA+PiAgIAlyZXQgPSBpbnRlbF9wbWNfaXBjX2NvbW1hbmQo
UE1DX0lQQ19QTUNfVEVMRU1UUlksDQo+ID4+IElPU1NfVEVMRU1fSU5GT19SRUFELCBAQCAtNjI2
LDggKzYzMiw5IEBAIHN0YXRpYyBpbnQNCj4gPj4gdGVsZW1ldHJ5X3NldHVwKHN0cnVjdCBwbGF0
Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4+ICAgCXRlbG1fY29uZi0+aW9zc19jb25maWcubWF4X3Bl
cmlvZCA9DQo+IFRFTEVNX01BWF9QRVJJT0QocmVhZF9idWYpOw0KPiA+Pg0KPiA+PiAgIAkvKiBQ
VU5JVCBNYWlsYm94IFNldHVwICovDQo+ID4+IC0JcmV0ID0gaW50ZWxfcHVuaXRfaXBjX2NvbW1h
bmQoSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX0lORk8sDQo+ID4+IDAsIDAsDQo+ID4+IC0JCQkJ
ICAgICAgTlVMTCwgJnJlYWRfYnVmKTsNCj4gPj4gKwlwdW5pdF9jbWRfaW5pdChjbWQsIElQQ19Q
VU5JVF9CSU9TX1JFQURfVEVMRV9JTkZPLCAwLCAwKTsNCj4gPj4gKwlyZXQgPSBpcGNfZGV2X3Jh
d19jbWQocHVuaXRfYmlvc19pcGNfZGV2LCBjbWQsDQo+ID4+IFBVTklUX1BBUkFNX0xFTiwNCj4g
Pj4gKwkJCU5VTEwsIDAsICZyZWFkX2J1ZiwgMSwgMCwgMCk7DQo+ID4+ICAgCWlmIChyZXQpIHsN
Cj4gPj4gICAJCWRldl9lcnIoJnBkZXYtPmRldiwgIlBTUyBURUxFTV9JTkZPIFJlYWQgRmFpbGVk
XG4iKTsNCj4gPj4gICAJCXJldHVybiByZXQ7DQo+ID4+IEBAIC02OTUsNiArNzAyLDcgQEAgc3Rh
dGljIGludCB0ZWxlbWV0cnlfcGx0X3NldF9zYW1wbGluZ19wZXJpb2QodTgNCj4gPj4gcHNzX3Bl
cmlvZCwgdTggaW9zc19wZXJpb2QpICB7DQo+ID4+ICAgCXUzMiB0ZWxlbV9jdHJsID0gMDsNCj4g
Pj4gICAJaW50IHJldCA9IDA7DQo+ID4+ICsJdTMyIGNtZFtQVU5JVF9QQVJBTV9MRU5dID0gezB9
Ow0KPiA+Pg0KPiA+PiAgIAltdXRleF9sb2NrKCYodGVsbV9jb25mLT50ZWxlbV9sb2NrKSk7DQo+
ID4+ICAgCWlmIChpb3NzX3BlcmlvZCkgew0KPiA+PiBAQCAtNzUyLDkgKzc2MCw5IEBAIHN0YXRp
YyBpbnQgdGVsZW1ldHJ5X3BsdF9zZXRfc2FtcGxpbmdfcGVyaW9kKHU4DQo+ID4+IHBzc19wZXJp
b2QsIHU4IGlvc3NfcGVyaW9kKQ0KPiA+PiAgIAkJfQ0KPiA+Pg0KPiA+PiAgIAkJLyogR2V0IHRl
bGVtZXRyeSBFVkVOVCBDVEwgKi8NCj4gPj4gLQkJcmV0ID0gaW50ZWxfcHVuaXRfaXBjX2NvbW1h
bmQoDQo+ID4+IC0JCQkJSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX0VWRU5UX0NUUkwsDQo+ID4+
IC0JCQkJMCwgMCwgTlVMTCwgJnRlbGVtX2N0cmwpOw0KPiA+PiArCQlwdW5pdF9jbWRfaW5pdChj
bWQsDQo+ID4+IElQQ19QVU5JVF9CSU9TX1JFQURfVEVMRV9FVkVOVF9DVFJMLCAwLCAwKTsNCj4g
Pj4gKwkJcmV0ID0gaXBjX2Rldl9yYXdfY21kKHB1bml0X2Jpb3NfaXBjX2RldiwgY21kLA0KPiA+
PiBQVU5JVF9QQVJBTV9MRU4sDQo+ID4+ICsJCQkJTlVMTCwgMCwgJnRlbGVtX2N0cmwsIDEsIDAs
IDApOw0KPiA+PiAgIAkJaWYgKHJldCkgew0KPiA+PiAgIAkJCXByX2VycigiUFNTIFRFTEVNX0NU
UkwgUmVhZCBGYWlsZWRcbiIpOw0KPiA+PiAgIAkJCWdvdG8gb3V0Ow0KPiA+PiBAQCAtNzYyLDkg
Kzc3MCwxMSBAQCBzdGF0aWMgaW50IHRlbGVtZXRyeV9wbHRfc2V0X3NhbXBsaW5nX3BlcmlvZCh1
OA0KPiA+PiBwc3NfcGVyaW9kLCB1OCBpb3NzX3BlcmlvZCkNCj4gPj4NCj4gPj4gICAJCS8qIERp
c2FibGUgVGVsZW1ldHJ5ICovDQo+ID4+ICAgCQlURUxFTV9ESVNBQkxFKHRlbGVtX2N0cmwpOw0K
PiA+PiAtCQlyZXQgPSBpbnRlbF9wdW5pdF9pcGNfY29tbWFuZCgNCj4gPj4gLQkJCQlJUENfUFVO
SVRfQklPU19XUklURV9URUxFX0VWRU5UX0NUUkwsDQo+ID4+IC0JCQkJMCwgMCwgJnRlbGVtX2N0
cmwsIE5VTEwpOw0KPiA+PiArCQlwdW5pdF9jbWRfaW5pdChjbWQsDQo+ID4+IElQQ19QVU5JVF9C
SU9TX1dSSVRFX1RFTEVfRVZFTlRfQ1RSTCwgMCwNCj4gPj4gKwkJCQkwKTsNCj4gPj4gKwkJcmV0
ID0gaXBjX2Rldl9yYXdfY21kKHB1bml0X2Jpb3NfaXBjX2RldiwgY21kLA0KPiA+PiBQVU5JVF9Q
QVJBTV9MRU4sDQo+ID4+ICsJCQkJKHU4ICopJnRlbGVtX2N0cmwsIHNpemVvZih0ZWxlbV9jdHJs
KSwgTlVMTCwNCj4gPj4gKwkJCQkwLCAwLCAwKTsNCj4gPj4gICAJCWlmIChyZXQpIHsNCj4gPj4g
ICAJCQlwcl9lcnIoIlBTUyBURUxFTV9DVFJMIEV2ZW50IERpc2FibGUgV3JpdGUNCj4gRmFpbGVk
XG4iKTsNCj4gPj4gICAJCQlnb3RvIG91dDsNCj4gPj4gQEAgLTc3Niw5ICs3ODYsMTEgQEAgc3Rh
dGljIGludCB0ZWxlbWV0cnlfcGx0X3NldF9zYW1wbGluZ19wZXJpb2QodTgNCj4gPj4gcHNzX3Bl
cmlvZCwgdTggaW9zc19wZXJpb2QpDQo+ID4+ICAgCQlURUxFTV9FTkFCTEVfUEVSSU9ESUModGVs
ZW1fY3RybCk7DQo+ID4+ICAgCQl0ZWxlbV9jdHJsIHw9IHBzc19wZXJpb2Q7DQo+ID4+DQo+ID4+
IC0JCXJldCA9IGludGVsX3B1bml0X2lwY19jb21tYW5kKA0KPiA+PiAtCQkJCUlQQ19QVU5JVF9C
SU9TX1dSSVRFX1RFTEVfRVZFTlRfQ1RSTCwNCj4gPj4gLQkJCQkwLCAwLCAmdGVsZW1fY3RybCwg
TlVMTCk7DQo+ID4+ICsJCXB1bml0X2NtZF9pbml0KGNtZCwNCj4gPj4gSVBDX1BVTklUX0JJT1Nf
V1JJVEVfVEVMRV9FVkVOVF9DVFJMLCAwLA0KPiA+PiArCQkJCTApOw0KPiA+PiArCQlyZXQgPSBp
cGNfZGV2X3Jhd19jbWQocHVuaXRfYmlvc19pcGNfZGV2LCBjbWQsDQo+ID4+IFBVTklUX1BBUkFN
X0xFTiwNCj4gPj4gKwkJCQkodTggKikmdGVsZW1fY3RybCwgc2l6ZW9mKHRlbGVtX2N0cmwpLCBO
VUxMLA0KPiA+PiArCQkJCTAsIDAsIDApOw0KPiA+PiAgIAkJaWYgKHJldCkgew0KPiA+PiAgIAkJ
CXByX2VycigiUFNTIFRFTEVNX0NUUkwgRXZlbnQgRW5hYmxlIFdyaXRlDQo+IEZhaWxlZFxuIik7
DQo+ID4+ICAgCQkJZ290byBvdXQ7DQo+ID4+IEBAIC0xMDEzLDYgKzEwMjUsNyBAQCBzdGF0aWMg
aW50DQo+ID4+IHRlbGVtZXRyeV9wbHRfZ2V0X3RyYWNlX3ZlcmJvc2l0eShlbnVtDQo+ID4+IHRl
bGVtZXRyeV91bml0IHRlbGVtX3VuaXQsICB7DQo+ID4+ICAgCXUzMiB0ZW1wID0gMDsNCj4gPj4g
ICAJaW50IHJldDsNCj4gPj4gKwl1MzIgY21kW1BVTklUX1BBUkFNX0xFTl0gPSB7MH07DQo+ID4+
DQo+ID4+ICAgCWlmICh2ZXJib3NpdHkgPT0gTlVMTCkNCj4gPj4gICAJCXJldHVybiAtRUlOVkFM
Ow0KPiA+PiBAQCAtMTAyMCw5ICsxMDMzLDkgQEAgc3RhdGljIGludA0KPiA+PiB0ZWxlbWV0cnlf
cGx0X2dldF90cmFjZV92ZXJib3NpdHkoZW51bQ0KPiA+PiB0ZWxlbWV0cnlfdW5pdCB0ZWxlbV91
bml0LA0KPiA+PiAgIAltdXRleF9sb2NrKCYodGVsbV9jb25mLT50ZWxlbV90cmFjZV9sb2NrKSk7
DQo+ID4+ICAgCXN3aXRjaCAodGVsZW1fdW5pdCkgew0KPiA+PiAgIAljYXNlIFRFTEVNX1BTUzoN
Cj4gPj4gLQkJcmV0ID0gaW50ZWxfcHVuaXRfaXBjX2NvbW1hbmQoDQo+ID4+IC0JCQkJSVBDX1BV
TklUX0JJT1NfUkVBRF9URUxFX1RSQUNFX0NUUkwsDQo+ID4+IC0JCQkJMCwgMCwgTlVMTCwgJnRl
bXApOw0KPiA+PiArCQlwdW5pdF9jbWRfaW5pdChjbWQsDQo+ID4+IElQQ19QVU5JVF9CSU9TX1JF
QURfVEVMRV9UUkFDRV9DVFJMLCAwLCAwKTsNCj4gPj4gKwkJcmV0ID0gaXBjX2Rldl9yYXdfY21k
KHB1bml0X2Jpb3NfaXBjX2RldiwgY21kLA0KPiA+PiBQVU5JVF9QQVJBTV9MRU4sDQo+ID4+ICsJ
CQkJTlVMTCwgMCwgJnRlbXAsIDEsIDAsIDApOw0KPiA+PiAgIAkJaWYgKHJldCkgew0KPiA+PiAg
IAkJCXByX2VycigiUFNTIFRSQUNFX0NUUkwgUmVhZCBGYWlsZWRcbiIpOw0KPiA+PiAgIAkJCWdv
dG8gb3V0Ow0KPiA+PiBAQCAtMTA1OCwxNSArMTA3MSwxNiBAQCBzdGF0aWMgaW50DQo+ID4+IHRl
bGVtZXRyeV9wbHRfc2V0X3RyYWNlX3ZlcmJvc2l0eShlbnVtIHRlbGVtZXRyeV91bml0IHRlbGVt
X3VuaXQsICB7DQo+ID4+ICAgCXUzMiB0ZW1wID0gMDsNCj4gPj4gICAJaW50IHJldDsNCj4gPj4g
Kwl1MzIgY21kW1BVTklUX1BBUkFNX0xFTl0gPSB7MH07DQo+ID4+DQo+ID4+ICAgCXZlcmJvc2l0
eSAmPSBURUxFTV9UUkNfVkVSQk9TSVRZX01BU0s7DQo+ID4+DQo+ID4+ICAgCW11dGV4X2xvY2so
Jih0ZWxtX2NvbmYtPnRlbGVtX3RyYWNlX2xvY2spKTsNCj4gPj4gICAJc3dpdGNoICh0ZWxlbV91
bml0KSB7DQo+ID4+ICAgCWNhc2UgVEVMRU1fUFNTOg0KPiA+PiAtCQlyZXQgPSBpbnRlbF9wdW5p
dF9pcGNfY29tbWFuZCgNCj4gPj4gLQkJCQlJUENfUFVOSVRfQklPU19SRUFEX1RFTEVfVFJBQ0Vf
Q1RSTCwNCj4gPj4gLQkJCQkwLCAwLCBOVUxMLCAmdGVtcCk7DQo+ID4+ICsJCXB1bml0X2NtZF9p
bml0KGNtZCwNCj4gPj4gSVBDX1BVTklUX0JJT1NfUkVBRF9URUxFX1RSQUNFX0NUUkwsIDAsIDAp
Ow0KPiA+PiArCQlyZXQgPSBpcGNfZGV2X3Jhd19jbWQocHVuaXRfYmlvc19pcGNfZGV2LCBjbWQs
DQo+ID4+IFBVTklUX1BBUkFNX0xFTiwNCj4gPj4gKwkJCQlOVUxMLCAwLCAmdGVtcCwgMSwgMCwg
MCk7DQo+ID4+ICAgCQlpZiAocmV0KSB7DQo+ID4+ICAgCQkJcHJfZXJyKCJQU1MgVFJBQ0VfQ1RS
TCBSZWFkIEZhaWxlZFxuIik7DQo+ID4+ICAgCQkJZ290byBvdXQ7DQo+ID4+IEBAIC0xMDc0LDEw
ICsxMDg4LDEwIEBAIHN0YXRpYyBpbnQNCj4gPj4gdGVsZW1ldHJ5X3BsdF9zZXRfdHJhY2VfdmVy
Ym9zaXR5KGVudW0gdGVsZW1ldHJ5X3VuaXQgdGVsZW1fdW5pdCwNCj4gPj4NCj4gPj4gICAJCVRF
TEVNX0NMRUFSX1ZFUkJPU0lUWV9CSVRTKHRlbXApOw0KPiA+PiAgIAkJVEVMRU1fU0VUX1ZFUkJP
U0lUWV9CSVRTKHRlbXAsIHZlcmJvc2l0eSk7DQo+ID4+IC0NCj4gPj4gLQkJcmV0ID0gaW50ZWxf
cHVuaXRfaXBjX2NvbW1hbmQoDQo+ID4+IC0JCQkJSVBDX1BVTklUX0JJT1NfV1JJVEVfVEVMRV9U
UkFDRV9DVFJMLA0KPiA+PiAtCQkJCTAsIDAsICZ0ZW1wLCBOVUxMKTsNCj4gPj4gKwkJcHVuaXRf
Y21kX2luaXQoY21kLA0KPiA+PiBJUENfUFVOSVRfQklPU19XUklURV9URUxFX0VWRU5UX0NUUkws
DQo+ID4+ICsJCQkJMCwgMCk7DQo+ID4+ICsJCXJldCA9IGlwY19kZXZfcmF3X2NtZChwdW5pdF9i
aW9zX2lwY19kZXYsIGNtZCwNCj4gPj4gUFVOSVRfUEFSQU1fTEVOLA0KPiA+PiArCQkJCSh1OCAq
KSZ0ZW1wLCBzaXplb2YodGVtcCksIE5VTEwsIDAsIDAsIDApOw0KPiA+PiAgIAkJaWYgKHJldCkg
ew0KPiA+PiAgIAkJCXByX2VycigiUFNTIFRSQUNFX0NUUkwgVmVyYm9zaXR5IFNldCBGYWlsZWRc
biIpOw0KPiA+PiAgIAkJCWdvdG8gb3V0Ow0KPiA+PiBAQCAtMTEzOSw2ICsxMTUzLDEwIEBAIHN0
YXRpYyBpbnQgdGVsZW1ldHJ5X3BsdGRydl9wcm9iZShzdHJ1Y3QNCj4gPj4gcGxhdGZvcm1fZGV2
aWNlICpwZGV2KQ0KPiA+PiAgIAlpZiAoIWlkKQ0KPiA+PiAgIAkJcmV0dXJuIC1FTk9ERVY7DQo+
ID4+DQo+ID4+ICsJcHVuaXRfYmlvc19pcGNfZGV2ID0gaW50ZWxfaXBjX2Rldl9nZXQoUFVOSVRf
QklPU19JUENfREVWKTsNCj4gPj4gKwlpZiAoSVNfRVJSX09SX05VTEwocHVuaXRfYmlvc19pcGNf
ZGV2KSkNCj4gPj4gKwkJcmV0dXJuIFBUUl9FUlIocHVuaXRfYmlvc19pcGNfZGV2KTsNCj4gPj4g
Kw0KPiA+PiAgIAl0ZWxtX2NvbmYgPSAoc3RydWN0IHRlbGVtZXRyeV9wbHRfY29uZmlnICopaWQt
PmRyaXZlcl9kYXRhOw0KPiA+Pg0KPiA+PiAgIAlyZXMwID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNl
KHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsgQEAgLQ0KPiA+PiAxMjE4LDYgKzEyMzYsNyBAQCBz
dGF0aWMgaW50IHRlbGVtZXRyeV9wbHRkcnZfcHJvYmUoc3RydWN0DQo+ID4+IHBsYXRmb3JtX2Rl
dmljZQ0KPiA+PiAqcGRldikgIHN0YXRpYyBpbnQgdGVsZW1ldHJ5X3BsdGRydl9yZW1vdmUoc3Ry
dWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4gew0KPiA+PiAgIAl0ZWxlbWV0cnlfY2xlYXJf
cGx0ZGF0YSgpOw0KPiA+PiArCWludGVsX2lwY19kZXZfcHV0KHB1bml0X2Jpb3NfaXBjX2Rldik7
DQo+ID4+ICAgCWlvdW5tYXAodGVsbV9jb25mLT5wc3NfY29uZmlnLnJlZ21hcCk7DQo+ID4+ICAg
CWlvdW5tYXAodGVsbV9jb25mLT5pb3NzX2NvbmZpZy5yZWdtYXApOw0KPiA+Pg0KPiA+PiAtLQ0K
PiA+PiAyLjcuNA0KPiA+DQo+IA0KPiAtLQ0KPiBTYXRoeWFuYXJheWFuYW4gS3VwcHVzd2FteQ0K
PiBMaW51eCBrZXJuZWwgZGV2ZWxvcGVyDQoNCg==
^ permalink raw reply
* Re: [RFC v5 6/8] platform/x86: intel_punit_ipc: Use generic intel ipc device calls
From: sathyanarayanan kuppuswamy @ 2017-10-10 22:28 UTC (permalink / raw)
To: Chakravarty, Souvik K, a.zummo@towertech.it, x86@kernel.org,
wim@iguana.be, mingo@redhat.com,
alexandre.belloni@free-electrons.com, Zha, Qipeng, hpa@zytor.com,
dvhart@infradead.org, tglx@linutronix.de, lee.jones@linaro.org,
andy@infradead.org
Cc: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org,
linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org,
sathyaosid@gmail.com
In-Reply-To: <5F7315E704FA0841B5DFCE90329B2BB4661E2103@BGSMSX102.gar.corp.intel.com>
On 10/08/2017 10:07 PM, Chakravarty, Souvik K wrote:
>> From: sathyanarayanan.kuppuswamy@linux.intel.com
>> [mailto:sathyanarayanan.kuppuswamy@linux.intel.com]
>> Sent: Sunday, October 8, 2017 3:50 AM
>> To: a.zummo@towertech.it; x86@kernel.org; wim@iguana.be;
>> mingo@redhat.com; alexandre.belloni@free-electrons.com; Zha, Qipeng
>> <qipeng.zha@intel.com>; hpa@zytor.com; dvhart@infradead.org;
>> tglx@linutronix.de; lee.jones@linaro.org; andy@infradead.org; Chakravarty,
>> Souvik K <souvik.k.chakravarty@intel.com>
>> Cc: linux-rtc@vger.kernel.org; linux-watchdog@vger.kernel.org; linux-
>> kernel@vger.kernel.org; platform-driver-x86@vger.kernel.org;
>> sathyaosid@gmail.com; Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com>
>> Subject: [RFC v5 6/8] platform/x86: intel_punit_ipc: Use generic intel ipc
>> device calls
>>
>> From: Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com>
>>
>> Removed redundant IPC helper functions and refactored the driver to use
>> APIs provided by generic IPC driver. This patch also cleans-up PUNIT IPC user
>> drivers(intel_telemetry_pltdrv.c) to use APIs provided by generic IPC driver.
>>
>> Signed-off-by: Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com>
>> ---
>> arch/x86/include/asm/intel_punit_ipc.h | 125 +++++------
>> drivers/platform/x86/Kconfig | 1 +
>> drivers/platform/x86/intel_punit_ipc.c | 303 ++++++++++----------------
>> drivers/platform/x86/intel_telemetry_pltdrv.c | 97 +++++----
>> 4 files changed, 223 insertions(+), 303 deletions(-)
>>
>> Changes since v4:
>> * None
>>
>> Changes since v2:
>> * Added unique name to PUNIT BIOS, GTD, & ISP regmaps.
>> * Added intel_ipc_dev_put() support.
>>
>> Changes since v1:
>> * Removed custom APIs.
>> * Cleaned up PUNIT IPC user drivers to use APIs provided by generic
>> IPC driver.
>>
>> diff --git a/arch/x86/include/asm/intel_punit_ipc.h
>> b/arch/x86/include/asm/intel_punit_ipc.h
>> index 201eb9d..cf1630c 100644
>> --- a/arch/x86/include/asm/intel_punit_ipc.h
>> +++ b/arch/x86/include/asm/intel_punit_ipc.h
>> @@ -1,10 +1,8 @@
>> #ifndef _ASM_X86_INTEL_PUNIT_IPC_H_
>> #define _ASM_X86_INTEL_PUNIT_IPC_H_
>>
>> -/*
>> - * Three types of 8bit P-Unit IPC commands are supported,
>> - * bit[7:6]: [00]: BIOS; [01]: GTD; [10]: ISPD.
>> - */
>> +#include <linux/platform_data/x86/intel_ipc_dev.h>
>> +
>> typedef enum {
>> BIOS_IPC = 0,
>> GTDRIVER_IPC,
>> @@ -12,61 +10,60 @@ typedef enum {
>> RESERVED_IPC,
>> } IPC_TYPE;
>>
>> -#define IPC_TYPE_OFFSET 6
>> -#define IPC_PUNIT_BIOS_CMD_BASE (BIOS_IPC <<
>> IPC_TYPE_OFFSET)
>> -#define IPC_PUNIT_GTD_CMD_BASE (GTDDRIVER_IPC <<
>> IPC_TYPE_OFFSET)
>> -#define IPC_PUNIT_ISPD_CMD_BASE (ISPDRIVER_IPC <<
>> IPC_TYPE_OFFSET)
>> -#define IPC_PUNIT_CMD_TYPE_MASK (RESERVED_IPC <<
>> IPC_TYPE_OFFSET)
>> +#define PUNIT_BIOS_IPC_DEV "punit_bios_ipc"
>> +#define PUNIT_GTD_IPC_DEV "punit_gtd_ipc"
>> +#define PUNIT_ISP_IPC_DEV "punit_isp_ipc"
>> +#define PUNIT_PARAM_LEN 3
>>
>> /* BIOS => Pcode commands */
>> -#define IPC_PUNIT_BIOS_ZERO (IPC_PUNIT_BIOS_CMD_BASE
>> | 0x00)
>> -#define IPC_PUNIT_BIOS_VR_INTERFACE
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x01)
>> -#define IPC_PUNIT_BIOS_READ_PCS
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x02)
>> -#define IPC_PUNIT_BIOS_WRITE_PCS (IPC_PUNIT_BIOS_CMD_BASE
>> | 0x03)
>> -#define IPC_PUNIT_BIOS_READ_PCU_CONFIG
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x04)
>> -#define IPC_PUNIT_BIOS_WRITE_PCU_CONFIG
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x05)
>> -#define IPC_PUNIT_BIOS_READ_PL1_SETTING
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x06)
>> -#define IPC_PUNIT_BIOS_WRITE_PL1_SETTING (IPC_PUNIT_BIOS_CMD_BASE
>> | 0x07)
>> -#define IPC_PUNIT_BIOS_TRIGGER_VDD_RAM
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x08)
>> -#define IPC_PUNIT_BIOS_READ_TELE_INFO
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x09)
>> -#define IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x0a)
>> -#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x0b)
>> -#define IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x0c)
>> -#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x0d)
>> -#define IPC_PUNIT_BIOS_READ_TELE_TRACE
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x0e)
>> -#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x0f)
>> -#define IPC_PUNIT_BIOS_READ_TELE_EVENT
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x10)
>> -#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x11)
>> -#define IPC_PUNIT_BIOS_READ_MODULE_TEMP
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x12)
>> -#define IPC_PUNIT_BIOS_RESERVED
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x13)
>> -#define IPC_PUNIT_BIOS_READ_VOLTAGE_OVER
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x14)
>> -#define IPC_PUNIT_BIOS_WRITE_VOLTAGE_OVER
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x15)
>> -#define IPC_PUNIT_BIOS_READ_RATIO_OVER
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x16)
>> -#define IPC_PUNIT_BIOS_WRITE_RATIO_OVER
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x17)
>> -#define IPC_PUNIT_BIOS_READ_VF_GL_CTRL
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x18)
>> -#define IPC_PUNIT_BIOS_WRITE_VF_GL_CTRL
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x19)
>> -#define IPC_PUNIT_BIOS_READ_FM_SOC_TEMP_THRESH
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x1a)
>> -#define IPC_PUNIT_BIOS_WRITE_FM_SOC_TEMP_THRESH
>> (IPC_PUNIT_BIOS_CMD_BASE | 0x1b)
>> +#define IPC_PUNIT_BIOS_ZERO (0x00)
>> +#define IPC_PUNIT_BIOS_VR_INTERFACE (0x01)
>> +#define IPC_PUNIT_BIOS_READ_PCS (0x02)
>> +#define IPC_PUNIT_BIOS_WRITE_PCS (0x03)
>> +#define IPC_PUNIT_BIOS_READ_PCU_CONFIG (0x04)
>> +#define IPC_PUNIT_BIOS_WRITE_PCU_CONFIG (0x05)
>> +#define IPC_PUNIT_BIOS_READ_PL1_SETTING (0x06)
>> +#define IPC_PUNIT_BIOS_WRITE_PL1_SETTING (0x07)
>> +#define IPC_PUNIT_BIOS_TRIGGER_VDD_RAM (0x08)
>> +#define IPC_PUNIT_BIOS_READ_TELE_INFO (0x09)
>> +#define IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL (0x0a)
>> +#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL (0x0b)
>> +#define IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL (0x0c)
>> +#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL (0x0d)
>> +#define IPC_PUNIT_BIOS_READ_TELE_TRACE (0x0e)
>> +#define IPC_PUNIT_BIOS_WRITE_TELE_TRACE (0x0f)
>> +#define IPC_PUNIT_BIOS_READ_TELE_EVENT (0x10)
>> +#define IPC_PUNIT_BIOS_WRITE_TELE_EVENT (0x11)
>> +#define IPC_PUNIT_BIOS_READ_MODULE_TEMP (0x12)
>> +#define IPC_PUNIT_BIOS_RESERVED (0x13)
>> +#define IPC_PUNIT_BIOS_READ_VOLTAGE_OVER (0x14)
>> +#define IPC_PUNIT_BIOS_WRITE_VOLTAGE_OVER (0x15)
>> +#define IPC_PUNIT_BIOS_READ_RATIO_OVER (0x16)
>> +#define IPC_PUNIT_BIOS_WRITE_RATIO_OVER (0x17)
>> +#define IPC_PUNIT_BIOS_READ_VF_GL_CTRL (0x18)
>> +#define IPC_PUNIT_BIOS_WRITE_VF_GL_CTRL (0x19)
>> +#define IPC_PUNIT_BIOS_READ_FM_SOC_TEMP_THRESH (0x1a)
>> +#define IPC_PUNIT_BIOS_WRITE_FM_SOC_TEMP_THRESH (0x1b)
>>
>> /* GT Driver => Pcode commands */
>> -#define IPC_PUNIT_GTD_ZERO (IPC_PUNIT_GTD_CMD_BASE
>> | 0x00)
>> -#define IPC_PUNIT_GTD_CONFIG
>> (IPC_PUNIT_GTD_CMD_BASE | 0x01)
>> -#define IPC_PUNIT_GTD_READ_ICCP_LIC_CDYN_SCAL
>> (IPC_PUNIT_GTD_CMD_BASE | 0x02)
>> -#define IPC_PUNIT_GTD_WRITE_ICCP_LIC_CDYN_SCAL
>> (IPC_PUNIT_GTD_CMD_BASE | 0x03)
>> -#define IPC_PUNIT_GTD_GET_WM_VAL
>> (IPC_PUNIT_GTD_CMD_BASE | 0x06)
>> -#define IPC_PUNIT_GTD_WRITE_CONFIG_WISHREQ
>> (IPC_PUNIT_GTD_CMD_BASE | 0x07)
>> -#define IPC_PUNIT_GTD_READ_REQ_DUTY_CYCLE
>> (IPC_PUNIT_GTD_CMD_BASE | 0x16)
>> -#define IPC_PUNIT_GTD_DIS_VOL_FREQ_CHG_REQUEST
>> (IPC_PUNIT_GTD_CMD_BASE | 0x17)
>> -#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_CTRL
>> (IPC_PUNIT_GTD_CMD_BASE | 0x1a)
>> -#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_TUNING
>> (IPC_PUNIT_GTD_CMD_BASE | 0x1c)
>> +#define IPC_PUNIT_GTD_ZERO (0x00)
>> +#define IPC_PUNIT_GTD_CONFIG (0x01)
>> +#define IPC_PUNIT_GTD_READ_ICCP_LIC_CDYN_SCAL (0x02)
>> +#define IPC_PUNIT_GTD_WRITE_ICCP_LIC_CDYN_SCAL (0x03)
>> +#define IPC_PUNIT_GTD_GET_WM_VAL (0x06)
>> +#define IPC_PUNIT_GTD_WRITE_CONFIG_WISHREQ (0x07)
>> +#define IPC_PUNIT_GTD_READ_REQ_DUTY_CYCLE (0x16)
>> +#define IPC_PUNIT_GTD_DIS_VOL_FREQ_CHG_REQUEST (0x17)
>> +#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_CTRL (0x1a)
>> +#define IPC_PUNIT_GTD_DYNA_DUTY_CYCLE_TUNING (0x1c)
>>
>> /* ISP Driver => Pcode commands */
>> -#define IPC_PUNIT_ISPD_ZERO (IPC_PUNIT_ISPD_CMD_BASE
>> | 0x00)
>> -#define IPC_PUNIT_ISPD_CONFIG
>> (IPC_PUNIT_ISPD_CMD_BASE | 0x01)
>> -#define IPC_PUNIT_ISPD_GET_ISP_LTR_VAL
>> (IPC_PUNIT_ISPD_CMD_BASE | 0x02)
>> -#define IPC_PUNIT_ISPD_ACCESS_IU_FREQ_BOUNDS
>> (IPC_PUNIT_ISPD_CMD_BASE | 0x03)
>> -#define IPC_PUNIT_ISPD_READ_CDYN_LEVEL
>> (IPC_PUNIT_ISPD_CMD_BASE | 0x04)
>> -#define IPC_PUNIT_ISPD_WRITE_CDYN_LEVEL
>> (IPC_PUNIT_ISPD_CMD_BASE | 0x05)
>> +#define IPC_PUNIT_ISPD_ZERO (0x00)
>> +#define IPC_PUNIT_ISPD_CONFIG (0x01)
>> +#define IPC_PUNIT_ISPD_GET_ISP_LTR_VAL (0x02)
>> +#define IPC_PUNIT_ISPD_ACCESS_IU_FREQ_BOUNDS (0x03)
>> +#define IPC_PUNIT_ISPD_READ_CDYN_LEVEL (0x04)
>> +#define IPC_PUNIT_ISPD_WRITE_CDYN_LEVEL (0x05)
>>
>> /* Error codes */
>> #define IPC_PUNIT_ERR_SUCCESS 0
>> @@ -77,25 +74,11 @@ typedef enum {
>> #define IPC_PUNIT_ERR_INVALID_VR_ID 5
>> #define IPC_PUNIT_ERR_VR_ERR 6
>>
>> -#if IS_ENABLED(CONFIG_INTEL_PUNIT_IPC)
>> -
>> -int intel_punit_ipc_simple_command(int cmd, int para1, int para2); -int
>> intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32
>> *out);
>> -
>> -#else
>> -
>> -static inline int intel_punit_ipc_simple_command(int cmd,
>> - int para1, int para2)
>> +static inline void punit_cmd_init(u32 *cmd, u32 param1, u32 param2, u32
>> +param3)
>> {
>> - return -ENODEV;
>> + cmd[0] = param1;
>> + cmd[1] = param2;
>> + cmd[2] = param3;
>> }
>>
>> -static inline int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2,
>> - u32 *in, u32 *out)
>> -{
>> - return -ENODEV;
>> -}
>> -
>> -#endif /* CONFIG_INTEL_PUNIT_IPC */
>> -
>> #endif
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index 724ee696..9442c23 100644
>> --- a/drivers/platform/x86/Kconfig
>> +++ b/drivers/platform/x86/Kconfig
>> @@ -1096,6 +1096,7 @@ config SURFACE_3_BUTTON
>>
>> config INTEL_PUNIT_IPC
>> tristate "Intel P-Unit IPC Driver"
>> + select REGMAP_MMIO
>> ---help---
>> This driver provides support for Intel P-Unit Mailbox IPC
>> mechanism,
>> which is used to bridge the communications between kernel and P-
>> Unit.
>> diff --git a/drivers/platform/x86/intel_punit_ipc.c
>> b/drivers/platform/x86/intel_punit_ipc.c
>> index b5b8901..f310a05 100644
>> --- a/drivers/platform/x86/intel_punit_ipc.c
>> +++ b/drivers/platform/x86/intel_punit_ipc.c
>> @@ -18,18 +18,18 @@
>> #include <linux/device.h>
>> #include <linux/interrupt.h>
>> #include <linux/platform_device.h>
>> +#include <linux/platform_data/x86/intel_ipc_dev.h>
>> +#include <linux/regmap.h>
>> #include <asm/intel_punit_ipc.h>
>>
>> -/* IPC Mailbox registers */
>> -#define OFFSET_DATA_LOW 0x0
>> -#define OFFSET_DATA_HIGH 0x4
>> /* bit field of interface register */
>> #define CMD_RUN BIT(31)
>> -#define CMD_ERRCODE_MASK GENMASK(7, 0)
>> +#define CMD_ERRCODE_MASK GENMASK(7, 0)
>> #define CMD_PARA1_SHIFT 8
>> #define CMD_PARA2_SHIFT 16
>>
>> -#define CMD_TIMEOUT_SECONDS 1
>> +/* IPC PUNIT commands */
>> +#define IPC_DEV_PUNIT_CMD_STATUS_ERR_MASK GENMASK(7,
>> 0)
>>
>> enum {
>> BASE_DATA = 0,
>> @@ -39,187 +39,42 @@ enum {
>>
>> typedef struct {
>> struct device *dev;
>> - struct mutex lock;
>> - int irq;
>> - struct completion cmd_complete;
>> /* base of interface and data registers */
>> void __iomem *base[RESERVED_IPC][BASE_MAX];
>> + struct intel_ipc_dev *ipc_dev[RESERVED_IPC];
>> IPC_TYPE type;
>> } IPC_DEV;
>>
>> static IPC_DEV *punit_ipcdev;
>>
>> -static inline u32 ipc_read_status(IPC_DEV *ipcdev, IPC_TYPE type) -{
>> - return readl(ipcdev->base[type][BASE_IFACE]);
>> -}
>> -
>> -static inline void ipc_write_cmd(IPC_DEV *ipcdev, IPC_TYPE type, u32 cmd) -
>> {
>> - writel(cmd, ipcdev->base[type][BASE_IFACE]);
>> -}
>> -
>> -static inline u32 ipc_read_data_low(IPC_DEV *ipcdev, IPC_TYPE type) -{
>> - return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW);
>> -}
>> -
>> -static inline u32 ipc_read_data_high(IPC_DEV *ipcdev, IPC_TYPE type) -{
>> - return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH);
>> -}
>> -
>> -static inline void ipc_write_data_low(IPC_DEV *ipcdev, IPC_TYPE type, u32
>> data) -{
>> - writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW);
>> -}
>> -
>> -static inline void ipc_write_data_high(IPC_DEV *ipcdev, IPC_TYPE type, u32
>> data) -{
>> - writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH);
>> -}
>> +const char *ipc_dev_name[RESERVED_IPC] = {
>> + PUNIT_BIOS_IPC_DEV,
>> + PUNIT_GTD_IPC_DEV,
>> + PUNIT_ISP_IPC_DEV
>> +};
>>
>> -static const char *ipc_err_string(int error) -{
>> - if (error == IPC_PUNIT_ERR_SUCCESS)
>> - return "no error";
>> - else if (error == IPC_PUNIT_ERR_INVALID_CMD)
>> - return "invalid command";
>> - else if (error == IPC_PUNIT_ERR_INVALID_PARAMETER)
>> - return "invalid parameter";
>> - else if (error == IPC_PUNIT_ERR_CMD_TIMEOUT)
>> - return "command timeout";
>> - else if (error == IPC_PUNIT_ERR_CMD_LOCKED)
>> - return "command locked";
>> - else if (error == IPC_PUNIT_ERR_INVALID_VR_ID)
>> - return "invalid vr id";
>> - else if (error == IPC_PUNIT_ERR_VR_ERR)
>> - return "vr error";
>> - else
>> - return "unknown error";
>> -}
>> +static struct regmap_config punit_regmap_config = {
>> + .reg_bits = 32,
>> + .reg_stride = 4,
>> + .val_bits = 32,
>> +};
>>
>> -static int intel_punit_ipc_check_status(IPC_DEV *ipcdev, IPC_TYPE type)
>> +int pre_simple_cmd_fn(u32 *cmd_list, u32 cmdlen)
>> {
>> - int loops = CMD_TIMEOUT_SECONDS * USEC_PER_SEC;
>> - int errcode;
>> - int status;
>> -
>> - if (ipcdev->irq) {
>> - if (!wait_for_completion_timeout(&ipcdev->cmd_complete,
>> - CMD_TIMEOUT_SECONDS *
>> HZ)) {
>> - dev_err(ipcdev->dev, "IPC timed out\n");
>> - return -ETIMEDOUT;
>> - }
>> - } else {
>> - while ((ipc_read_status(ipcdev, type) & CMD_RUN) && --
>> loops)
>> - udelay(1);
>> - if (!loops) {
>> - dev_err(ipcdev->dev, "IPC timed out\n");
>> - return -ETIMEDOUT;
>> - }
>> - }
>> + if (!cmd_list || cmdlen != PUNIT_PARAM_LEN)
>> + return -EINVAL;
>>
>> - status = ipc_read_status(ipcdev, type);
>> - errcode = status & CMD_ERRCODE_MASK;
>> - if (errcode) {
>> - dev_err(ipcdev->dev, "IPC failed: %s, IPC_STS=0x%x\n",
>> - ipc_err_string(errcode), status);
>> - return -EIO;
>> - }
>> + cmd_list[0] |= CMD_RUN | cmd_list[1] << CMD_PARA1_SHIFT |
>> + cmd_list[2] << CMD_PARA1_SHIFT;
>>
>> return 0;
>> }
>>
>> -/**
>> - * intel_punit_ipc_simple_command() - Simple IPC command
>> - * @cmd: IPC command code.
>> - * @para1: First 8bit parameter, set 0 if not used.
>> - * @para2: Second 8bit parameter, set 0 if not used.
>> - *
>> - * Send a IPC command to P-Unit when there is no data transaction
>> - *
>> - * Return: IPC error code or 0 on success.
>> - */
>> -int intel_punit_ipc_simple_command(int cmd, int para1, int para2) -{
>> - IPC_DEV *ipcdev = punit_ipcdev;
>> - IPC_TYPE type;
>> - u32 val;
>> - int ret;
>> -
>> - mutex_lock(&ipcdev->lock);
>> -
>> - reinit_completion(&ipcdev->cmd_complete);
>> - type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET;
>> -
>> - val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK;
>> - val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 <<
>> CMD_PARA1_SHIFT;
>> - ipc_write_cmd(ipcdev, type, val);
>> - ret = intel_punit_ipc_check_status(ipcdev, type);
>> -
>> - mutex_unlock(&ipcdev->lock);
>> -
>> - return ret;
>> -}
>> -EXPORT_SYMBOL(intel_punit_ipc_simple_command);
>> -
>> -/**
>> - * intel_punit_ipc_command() - IPC command with data and pointers
>> - * @cmd: IPC command code.
>> - * @para1: First 8bit parameter, set 0 if not used.
>> - * @para2: Second 8bit parameter, set 0 if not used.
>> - * @in: Input data, 32bit for BIOS cmd, two 32bit for GTD
>> and ISPD.
>> - * @out: Output data.
>> - *
>> - * Send a IPC command to P-Unit with data transaction
>> - *
>> - * Return: IPC error code or 0 on success.
>> - */
>> -int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32
>> *out) -{
>> - IPC_DEV *ipcdev = punit_ipcdev;
>> - IPC_TYPE type;
>> - u32 val;
>> - int ret;
>> -
>> - mutex_lock(&ipcdev->lock);
>> -
>> - reinit_completion(&ipcdev->cmd_complete);
>> - type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET;
>> -
>> - if (in) {
>> - ipc_write_data_low(ipcdev, type, *in);
>> - if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC)
>> - ipc_write_data_high(ipcdev, type, *++in);
>> - }
>> -
>> - val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK;
>> - val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 <<
>> CMD_PARA1_SHIFT;
>> - ipc_write_cmd(ipcdev, type, val);
>> -
>> - ret = intel_punit_ipc_check_status(ipcdev, type);
>> - if (ret)
>> - goto out;
>> -
>> - if (out) {
>> - *out = ipc_read_data_low(ipcdev, type);
>> - if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC)
>> - *++out = ipc_read_data_high(ipcdev, type);
>> - }
>> -
>> -out:
>> - mutex_unlock(&ipcdev->lock);
>> - return ret;
>> -}
>> -EXPORT_SYMBOL_GPL(intel_punit_ipc_command);
>> -
>> -static irqreturn_t intel_punit_ioc(int irq, void *dev_id)
>> +/* Input data, 32bit for BIOS cmd, two 32bit for GTD and ISPD. */ int
>> +pre_raw_cmd_fn(u32 *cmd_list, u32 cmdlen, u8 *in, u32 inlen, u32 *out,
>> + u32 outlen, u32 dptr, u32 sptr)
>> {
>> - IPC_DEV *ipcdev = dev_id;
>> -
>> - complete(&ipcdev->cmd_complete);
>> - return IRQ_HANDLED;
>> + return pre_simple_cmd_fn(cmd_list, cmdlen);
>> }
>>
>> static int intel_punit_get_bars(struct platform_device *pdev) @@ -282,9
>> +137,77 @@ static int intel_punit_get_bars(struct platform_device *pdev)
>> return 0;
>> }
>>
>> +static int punit_ipc_err_code(int status) {
>> + return (status & CMD_ERRCODE_MASK);
>> +}
>> +
>> +static int punit_ipc_busy_check(int status) {
>> + return status | CMD_RUN;
>> +}
>> +
>> +static struct intel_ipc_dev *intel_punit_ipc_dev_create(struct device *dev,
>> + const char *devname,
>> + int irq,
>> + void __iomem *base,
>> + void __iomem *data)
>> +{
>> + struct intel_ipc_dev_ops *ops;
>> + struct intel_ipc_dev_cfg *cfg;
>> + struct regmap *cmd_regs, *data_regs;
>> +
>> + cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
>> + if (!cfg)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ops = devm_kzalloc(dev, sizeof(*ops), GFP_KERNEL);
>> + if (!ops)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + punit_regmap_config.name = devm_kasprintf(dev, GFP_KERNEL,
>> "%s_%s",
>> + devname, "base");
>> +
>> + cmd_regs = devm_regmap_init_mmio_clk(dev, NULL, base,
>> + &punit_regmap_config);
>> + if (IS_ERR(cmd_regs)) {
>> + dev_err(dev, "cmd_regs regmap init failed\n");
>> + return ERR_CAST(cmd_regs);;
>> + }
>> +
>> + punit_regmap_config.name = devm_kasprintf(dev, GFP_KERNEL,
>> "%s_%s",
>> + devname, "data");
>> +
>> + data_regs = devm_regmap_init_mmio_clk(dev, NULL, data,
>> + &punit_regmap_config);
>> + if (IS_ERR(data_regs)) {
>> + dev_err(dev, "data_regs regmap init failed\n");
>> + return ERR_CAST(data_regs);;
>> + }
>> +
>> + /* set IPC dev ops */
>> + ops->to_err_code = punit_ipc_err_code;
>> + ops->busy_check = punit_ipc_busy_check;
>> + ops->pre_simple_cmd_fn = pre_simple_cmd_fn;
>> + ops->pre_raw_cmd_fn = pre_raw_cmd_fn;
>> +
>> + if (irq > 0)
>> + cfg->mode = IPC_DEV_MODE_IRQ;
>> + else
>> + cfg->mode = IPC_DEV_MODE_POLLING;
>> +
>> + cfg->chan_type = IPC_CHANNEL_IA_PUNIT;
>> + cfg->irq = irq;
>> + cfg->irqflags = IRQF_NO_SUSPEND | IRQF_SHARED;
>> + cfg->cmd_regs = cmd_regs;
>> + cfg->data_regs = data_regs;
>> +
>> + return devm_intel_ipc_dev_create(dev, devname, cfg, ops); }
>> +
>> static int intel_punit_ipc_probe(struct platform_device *pdev) {
>> - int irq, ret;
>> + int irq, ret, i;
>>
>> punit_ipcdev = devm_kzalloc(&pdev->dev,
>> sizeof(*punit_ipcdev), GFP_KERNEL); @@ -
>> 294,35 +217,30 @@ static int intel_punit_ipc_probe(struct platform_device
>> *pdev)
>> platform_set_drvdata(pdev, punit_ipcdev);
>>
>> irq = platform_get_irq(pdev, 0);
>> - if (irq < 0) {
>> - punit_ipcdev->irq = 0;
>> - dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n");
>> - } else {
>> - ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc,
>> - IRQF_NO_SUSPEND, "intel_punit_ipc",
>> - &punit_ipcdev);
>> - if (ret) {
>> - dev_err(&pdev->dev, "Failed to request irq: %d\n",
>> irq);
>> - return ret;
>> - }
>> - punit_ipcdev->irq = irq;
>> - }
>>
>> ret = intel_punit_get_bars(pdev);
>> if (ret)
>> - goto out;
>> + return ret;
>> +
>> + for (i = 0; i < RESERVED_IPC; i++) {
>> + punit_ipcdev->ipc_dev[i] = intel_punit_ipc_dev_create(
>> + &pdev->dev,
>> + ipc_dev_name[i],
>> + irq,
>> + punit_ipcdev->base[i][BASE_IFACE],
>> + punit_ipcdev->base[i][BASE_DATA]);
>> +
>> + if (IS_ERR(punit_ipcdev->ipc_dev[i])) {
>> + dev_err(&pdev->dev, "%s create failed\n",
>> + ipc_dev_name[i]);
>> + return PTR_ERR(punit_ipcdev->ipc_dev[i]);
>> + }
>> + }
>>
>> punit_ipcdev->dev = &pdev->dev;
>> - mutex_init(&punit_ipcdev->lock);
>> - init_completion(&punit_ipcdev->cmd_complete);
>>
>> -out:
>> return ret;
>> -}
>>
>> -static int intel_punit_ipc_remove(struct platform_device *pdev) -{
>> - return 0;
>> }
>>
>> static const struct acpi_device_id punit_ipc_acpi_ids[] = { @@ -332,7 +250,6
>> @@ static const struct acpi_device_id punit_ipc_acpi_ids[] = {
>>
>> static struct platform_driver intel_punit_ipc_driver = {
>> .probe = intel_punit_ipc_probe,
>> - .remove = intel_punit_ipc_remove,
>> .driver = {
>> .name = "intel_punit_ipc",
>> .acpi_match_table = ACPI_PTR(punit_ipc_acpi_ids), diff --git
>> a/drivers/platform/x86/intel_telemetry_pltdrv.c
>> b/drivers/platform/x86/intel_telemetry_pltdrv.c
>> index e0424d5..bf8284a 100644
>> --- a/drivers/platform/x86/intel_telemetry_pltdrv.c
>> +++ b/drivers/platform/x86/intel_telemetry_pltdrv.c
> This is a logical separation and so should be a different patch.
But if we split it into two different patches then it will break the
bisect-ability of these patches.
>
>> @@ -98,6 +98,7 @@ struct telem_ssram_region { };
>>
>> static struct telemetry_plt_config *telm_conf;
>> +static struct intel_ipc_dev *punit_bios_ipc_dev;
> Simply punit_ipc_dev is good enough.
There are three PUNIT IPC devices. So to differentiate between them I
added extra string to it.
>
>> /*
>> * The following counters are programmed by default during setup.
>> @@ -127,7 +128,6 @@ static struct telemetry_evtmap
>> {"PMC_S0IX_BLOCK_IPS_CLOCKS", 0x600B},
>> };
>>
>> -
>> static struct telemetry_evtmap
>>
>> telemetry_apl_pss_default_events[TELEM_MAX_OS_ALLOCATED_EVE
>> NTS] = {
>> {"IA_CORE0_C6_RES", 0x0400},
>> @@ -283,13 +283,12 @@ static inline int
>> telemetry_plt_config_ioss_event(u32 evt_id, int index) static inline int
>> telemetry_plt_config_pss_event(u32 evt_id, int index) {
>> u32 write_buf;
>> - int ret;
>> + u32 cmd[PUNIT_PARAM_LEN] = {0};
>>
>> write_buf = evt_id | TELEM_EVENT_ENABLE;
>> - ret =
>> intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT,
>> - index, 0, &write_buf, NULL);
>> -
>> - return ret;
>> + punit_cmd_init(cmd, IPC_PUNIT_BIOS_WRITE_TELE_EVENT, index, 0);
>> + return ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&write_buf, sizeof(write_buf), NULL, 0, 0, 0);
>> }
> 1) Why use raw_cmd here? It should use ipc_dev_cmd() according to original design. Same everywhere though this file.
In my initial versions of this patch set, I had only exported
ipc_dev_raw_cmd() API. Since this driver refactoring work was done
during that time, I have used intel_dev_raw_cmd() API in it. I have
added ipc_dev_cmd() API only recently to handle some new requirements
in intel_scu_ipc.c driver.
I will fix it in next version.
> 2) punit_cmd_init and ipc_dev_raw_cmd are repeated multiple time thoughout the file. They can be made into a separate local API inside telemetry, like
> telemetry_punit_send_cmd(). Same thoughout
I will make this change in next version.
>
>> static int telemetry_setup_iossevtconfig(struct telemetry_evtconfig
>> evtconfig, @@ -435,6 +434,7 @@ static int
>> telemetry_setup_pssevtconfig(struct telemetry_evtconfig evtconfig,
>> int ret, index, idx;
>> u32 *pss_evtmap;
>> u32 telem_ctrl;
>> + u32 cmd[PUNIT_PARAM_LEN] = {0};
>>
>> num_pss_evts = evtconfig.num_evts;
>> pss_period = evtconfig.period;
>> @@ -442,8 +442,9 @@ static int telemetry_setup_pssevtconfig(struct
>> telemetry_evtconfig evtconfig,
>>
>> /* PSS Config */
>> /* Get telemetry EVENT CTL */
>> - ret =
>> intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
>> - 0, 0, NULL, &telem_ctrl);
>> + punit_cmd_init(cmd, IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL, 0,
>> 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN, NULL,
>> + 0, &telem_ctrl, 1, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Read Failed\n");
>> return ret;
>> @@ -451,8 +452,9 @@ static int telemetry_setup_pssevtconfig(struct
>> telemetry_evtconfig evtconfig,
>>
>> /* Disable Telemetry */
>> TELEM_DISABLE(telem_ctrl);
>> - ret =
>> intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> - 0, 0, &telem_ctrl, NULL);
>> + punit_cmd_init(cmd, IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 0,
>> 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&telem_ctrl, sizeof(telem_ctrl), NULL, 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Event Disable Write Failed\n");
>> return ret;
>> @@ -463,9 +465,10 @@ static int telemetry_setup_pssevtconfig(struct
>> telemetry_evtconfig evtconfig,
>> /* Clear All Events */
>> TELEM_CLEAR_EVENTS(telem_ctrl);
>>
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> - 0, 0, &telem_ctrl, NULL);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&telem_ctrl, sizeof(telem_ctrl), NULL,
>> + 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Event Disable Write
>> Failed\n");
>> return ret;
>> @@ -489,9 +492,10 @@ static int telemetry_setup_pssevtconfig(struct
>> telemetry_evtconfig evtconfig,
>> /* Clear All Events */
>> TELEM_CLEAR_EVENTS(telem_ctrl);
>>
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> - 0, 0, &telem_ctrl, NULL);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&telem_ctrl, sizeof(telem_ctrl), NULL,
>> + 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Event Disable Write
>> Failed\n");
>> return ret;
>> @@ -540,8 +544,9 @@ static int telemetry_setup_pssevtconfig(struct
>> telemetry_evtconfig evtconfig,
>> TELEM_ENABLE_PERIODIC(telem_ctrl);
>> telem_ctrl |= pss_period;
>>
>> - ret =
>> intel_punit_ipc_command(IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> - 0, 0, &telem_ctrl, NULL);
>> + punit_cmd_init(cmd, IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 0,
>> 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&telem_ctrl, sizeof(telem_ctrl), NULL, 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Event Enable Write Failed\n");
>> return ret;
>> @@ -601,6 +606,7 @@ static int telemetry_setup(struct platform_device
>> *pdev) {
>> struct telemetry_evtconfig pss_evtconfig, ioss_evtconfig;
>> u32 read_buf, events, event_regs;
>> + u32 cmd[PUNIT_PARAM_LEN] = {0};
>> int ret;
>>
>> ret = intel_pmc_ipc_command(PMC_IPC_PMC_TELEMTRY,
>> IOSS_TELEM_INFO_READ, @@ -626,8 +632,9 @@ static int
>> telemetry_setup(struct platform_device *pdev)
>> telm_conf->ioss_config.max_period =
>> TELEM_MAX_PERIOD(read_buf);
>>
>> /* PUNIT Mailbox Setup */
>> - ret = intel_punit_ipc_command(IPC_PUNIT_BIOS_READ_TELE_INFO,
>> 0, 0,
>> - NULL, &read_buf);
>> + punit_cmd_init(cmd, IPC_PUNIT_BIOS_READ_TELE_INFO, 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + NULL, 0, &read_buf, 1, 0, 0);
>> if (ret) {
>> dev_err(&pdev->dev, "PSS TELEM_INFO Read Failed\n");
>> return ret;
>> @@ -695,6 +702,7 @@ static int telemetry_plt_set_sampling_period(u8
>> pss_period, u8 ioss_period) {
>> u32 telem_ctrl = 0;
>> int ret = 0;
>> + u32 cmd[PUNIT_PARAM_LEN] = {0};
>>
>> mutex_lock(&(telm_conf->telem_lock));
>> if (ioss_period) {
>> @@ -752,9 +760,9 @@ static int telemetry_plt_set_sampling_period(u8
>> pss_period, u8 ioss_period)
>> }
>>
>> /* Get telemetry EVENT CTL */
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL,
>> - 0, 0, NULL, &telem_ctrl);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_READ_TELE_EVENT_CTRL, 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + NULL, 0, &telem_ctrl, 1, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Read Failed\n");
>> goto out;
>> @@ -762,9 +770,11 @@ static int telemetry_plt_set_sampling_period(u8
>> pss_period, u8 ioss_period)
>>
>> /* Disable Telemetry */
>> TELEM_DISABLE(telem_ctrl);
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> - 0, 0, &telem_ctrl, NULL);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 0,
>> + 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&telem_ctrl, sizeof(telem_ctrl), NULL,
>> + 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Event Disable Write
>> Failed\n");
>> goto out;
>> @@ -776,9 +786,11 @@ static int telemetry_plt_set_sampling_period(u8
>> pss_period, u8 ioss_period)
>> TELEM_ENABLE_PERIODIC(telem_ctrl);
>> telem_ctrl |= pss_period;
>>
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> - 0, 0, &telem_ctrl, NULL);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL, 0,
>> + 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&telem_ctrl, sizeof(telem_ctrl), NULL,
>> + 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TELEM_CTRL Event Enable Write
>> Failed\n");
>> goto out;
>> @@ -1013,6 +1025,7 @@ static int telemetry_plt_get_trace_verbosity(enum
>> telemetry_unit telem_unit, {
>> u32 temp = 0;
>> int ret;
>> + u32 cmd[PUNIT_PARAM_LEN] = {0};
>>
>> if (verbosity == NULL)
>> return -EINVAL;
>> @@ -1020,9 +1033,9 @@ static int telemetry_plt_get_trace_verbosity(enum
>> telemetry_unit telem_unit,
>> mutex_lock(&(telm_conf->telem_trace_lock));
>> switch (telem_unit) {
>> case TELEM_PSS:
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
>> - 0, 0, NULL, &temp);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL, 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + NULL, 0, &temp, 1, 0, 0);
>> if (ret) {
>> pr_err("PSS TRACE_CTRL Read Failed\n");
>> goto out;
>> @@ -1058,15 +1071,16 @@ static int
>> telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit, {
>> u32 temp = 0;
>> int ret;
>> + u32 cmd[PUNIT_PARAM_LEN] = {0};
>>
>> verbosity &= TELEM_TRC_VERBOSITY_MASK;
>>
>> mutex_lock(&(telm_conf->telem_trace_lock));
>> switch (telem_unit) {
>> case TELEM_PSS:
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL,
>> - 0, 0, NULL, &temp);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_READ_TELE_TRACE_CTRL, 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + NULL, 0, &temp, 1, 0, 0);
>> if (ret) {
>> pr_err("PSS TRACE_CTRL Read Failed\n");
>> goto out;
>> @@ -1074,10 +1088,10 @@ static int
>> telemetry_plt_set_trace_verbosity(enum telemetry_unit telem_unit,
>>
>> TELEM_CLEAR_VERBOSITY_BITS(temp);
>> TELEM_SET_VERBOSITY_BITS(temp, verbosity);
>> -
>> - ret = intel_punit_ipc_command(
>> - IPC_PUNIT_BIOS_WRITE_TELE_TRACE_CTRL,
>> - 0, 0, &temp, NULL);
>> + punit_cmd_init(cmd,
>> IPC_PUNIT_BIOS_WRITE_TELE_EVENT_CTRL,
>> + 0, 0);
>> + ret = ipc_dev_raw_cmd(punit_bios_ipc_dev, cmd,
>> PUNIT_PARAM_LEN,
>> + (u8 *)&temp, sizeof(temp), NULL, 0, 0, 0);
>> if (ret) {
>> pr_err("PSS TRACE_CTRL Verbosity Set Failed\n");
>> goto out;
>> @@ -1139,6 +1153,10 @@ static int telemetry_pltdrv_probe(struct
>> platform_device *pdev)
>> if (!id)
>> return -ENODEV;
>>
>> + punit_bios_ipc_dev = intel_ipc_dev_get(PUNIT_BIOS_IPC_DEV);
>> + if (IS_ERR_OR_NULL(punit_bios_ipc_dev))
>> + return PTR_ERR(punit_bios_ipc_dev);
>> +
>> telm_conf = (struct telemetry_plt_config *)id->driver_data;
>>
>> res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -
>> 1218,6 +1236,7 @@ static int telemetry_pltdrv_probe(struct platform_device
>> *pdev) static int telemetry_pltdrv_remove(struct platform_device *pdev) {
>> telemetry_clear_pltdata();
>> + intel_ipc_dev_put(punit_bios_ipc_dev);
>> iounmap(telm_conf->pss_config.regmap);
>> iounmap(telm_conf->ioss_config.regmap);
>>
>> --
>> 2.7.4
>
--
Sathyanarayanan Kuppuswamy
Linux kernel developer
^ permalink raw reply
* Re: [RFC v5 4/8] platform: x86: Add generic Intel IPC driver
From: sathyanarayanan kuppuswamy @ 2017-10-10 22:09 UTC (permalink / raw)
To: Chakravarty, Souvik K, a.zummo@towertech.it, x86@kernel.org,
wim@iguana.be, mingo@redhat.com,
alexandre.belloni@free-electrons.com, Zha, Qipeng, hpa@zytor.com,
dvhart@infradead.org, tglx@linutronix.de, lee.jones@linaro.org,
andy@infradead.org
Cc: linux-rtc@vger.kernel.org, linux-watchdog@vger.kernel.org,
linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org,
sathyaosid@gmail.com
In-Reply-To: <5F7315E704FA0841B5DFCE90329B2BB4661E20EC@BGSMSX102.gar.corp.intel.com>
Hi,
On 10/08/2017 09:53 PM, Chakravarty, Souvik K wrote:
>> From: sathyanarayanan.kuppuswamy@linux.intel.com
>> [mailto:sathyanarayanan.kuppuswamy@linux.intel.com]
>> Sent: Sunday, October 8, 2017 3:50 AM
>> To: a.zummo@towertech.it; x86@kernel.org; wim@iguana.be;
>> mingo@redhat.com; alexandre.belloni@free-electrons.com; Zha, Qipeng
>> <qipeng.zha@intel.com>; hpa@zytor.com; dvhart@infradead.org;
>> tglx@linutronix.de; lee.jones@linaro.org; andy@infradead.org; Chakravarty,
>> Souvik K <souvik.k.chakravarty@intel.com>
>> Cc: linux-rtc@vger.kernel.org; linux-watchdog@vger.kernel.org; linux-
>> kernel@vger.kernel.org; platform-driver-x86@vger.kernel.org;
>> sathyaosid@gmail.com; Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com>
>> Subject: [RFC v5 4/8] platform: x86: Add generic Intel IPC driver
>>
>> From: Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com>
>>
>> Currently intel_scu_ipc.c, intel_pmc_ipc.c and intel_punit_ipc.c redundantly
>> implements the same IPC features and has lot of code duplication between
>> them. This driver addresses this issue by grouping the common IPC
>> functionalities under the same driver.
>>
>> Signed-off-by: Kuppuswamy Sathyanarayanan
>> <sathyanarayanan.kuppuswamy@linux.intel.com>
>> ---
>> drivers/platform/x86/Kconfig | 8 +
>> drivers/platform/x86/Makefile | 1 +
>> drivers/platform/x86/intel_ipc_dev.c | 576
>> ++++++++++++++++++++++++
>> include/linux/platform_data/x86/intel_ipc_dev.h | 206 +++++++++
>> 4 files changed, 791 insertions(+)
>> create mode 100644 drivers/platform/x86/intel_ipc_dev.c
>> create mode 100644 include/linux/platform_data/x86/intel_ipc_dev.h
>>
>> Changes since v4:
>> * None
>>
>> Changes since v3:
>> * Fixed NULL pointer exception in intel_ipc_dev_get().
>> * Fixed error in check for duplicate intel_ipc_dev.
>> * Added custom interrupt handler support.
>> * Used char array for error string conversion.
>> * Added put dev support.
>> * Added devm_* variant of intel_ipc_dev_get().
>>
>> Changes since v2:
>> * Added ipc_dev_cmd API support.
>>
>> diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
>> index da2d9ba..724ee696 100644
>> --- a/drivers/platform/x86/Kconfig
>> +++ b/drivers/platform/x86/Kconfig
>> @@ -1153,6 +1153,14 @@ config SILEAD_DMI
>> with the OS-image for the device. This option supplies the missing
>> information. Enable this for x86 tablets with Silead touchscreens.
>>
>> +config INTEL_IPC_DEV
>> + bool "Intel IPC Device Driver"
>> + depends on X86_64
>> + ---help---
>> + This driver implements core features of Intel IPC device. Devices
>> + like PMC, SCU, PUNIT, etc can use interfaces provided by this
>> + driver to implement IPC protocol of their respective device.
>> +
>> endif # X86_PLATFORM_DEVICES
>>
>> config PMC_ATOM
>> diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
>> index 2b315d0..99a1af1 100644
>> --- a/drivers/platform/x86/Makefile
>> +++ b/drivers/platform/x86/Makefile
>> @@ -84,3 +84,4 @@ obj-$(CONFIG_PMC_ATOM) +=
>> pmc_atom.o
>> obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
>> obj-$(CONFIG_MLX_CPLD_PLATFORM) += mlxcpld-hotplug.o
>> obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
>> +obj-$(CONFIG_INTEL_IPC_DEV) += intel_ipc_dev.o
>> diff --git a/drivers/platform/x86/intel_ipc_dev.c
>> b/drivers/platform/x86/intel_ipc_dev.c
>> new file mode 100644
>> index 0000000..f55ddec
>> --- /dev/null
>> +++ b/drivers/platform/x86/intel_ipc_dev.c
>> @@ -0,0 +1,576 @@
>> +/*
>> + * intel_ipc_dev.c: Intel IPC device class driver
>> + *
>> + * (C) Copyright 2017 Intel Corporation
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; version 2
>> + * of the License.
>> + *
>> + */
>> +
>> +#include <linux/device.h>
>> +#include <linux/module.h>
>> +#include <linux/delay.h>
>> +#include <linux/err.h>
>> +#include <linux/export.h>
>> +#include <linux/idr.h>
>> +#include <linux/init.h>
>> +#include <linux/slab.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/platform_data/x86/intel_ipc_dev.h>
>> +#include <linux/regmap.h>
>> +
>> +/* mutex to sync different ipc devices in same channel */ static struct
>> +mutex channel_lock[IPC_CHANNEL_MAX];
>> +
>> +static char *ipc_err_sources[] = {
>> + [IPC_DEV_ERR_NONE] =
>> + "No error",
>> + [IPC_DEV_ERR_CMD_NOT_SUPPORTED] =
>> + "Command not-supported/Invalid",
>> + [IPC_DEV_ERR_CMD_NOT_SERVICED] =
>> + "Command not-serviced/Invalid param",
>> + [IPC_DEV_ERR_UNABLE_TO_SERVICE] =
>> + "Unable-to-service/Cmd-timeout",
>> + [IPC_DEV_ERR_CMD_INVALID] =
>> + "Command-invalid/Cmd-locked",
>> + [IPC_DEV_ERR_CMD_FAILED] =
>> + "Command-failed/Invalid-VR-id",
>> + [IPC_DEV_ERR_EMSECURITY] =
>> + "Invalid Battery/VR-Error",
>> + [IPC_DEV_ERR_UNSIGNEDKERNEL] =
>> + "Unsigned kernel",
>> +};
>> +
>> +static void ipc_channel_lock_init(void) {
>> + int i;
>> +
>> + for (i = 0; i < IPC_CHANNEL_MAX; i++)
>> + mutex_init(&channel_lock[i]);
>> +}
>> +
>> +static struct class intel_ipc_class = {
>> + .name = "intel_ipc",
>> + .owner = THIS_MODULE,
>> +};
>> +
>> +static int ipc_dev_lock(struct intel_ipc_dev *ipc_dev) {
>> + int chan_type;
>> +
>> + if (!ipc_dev || !ipc_dev->cfg)
>> + return -ENODEV;
>> +
>> + chan_type = ipc_dev->cfg->chan_type;
>> + if (chan_type > IPC_CHANNEL_MAX)
>> + return -EINVAL;
>> +
>> + /* acquire channel lock */
>> + mutex_lock(&channel_lock[chan_type]);
>> +
>> + /* acquire IPC device lock */
>> + mutex_lock(&ipc_dev->lock);
>> +
>> + return 0;
>> +}
>> +
>> +static int ipc_dev_unlock(struct intel_ipc_dev *ipc_dev) {
>> + int chan_type;
>> +
>> + if (!ipc_dev || !ipc_dev->cfg)
>> + return -ENODEV;
>> +
>> + chan_type = ipc_dev->cfg->chan_type;
>> + if (chan_type > IPC_CHANNEL_MAX)
>> + return -EINVAL;
>> +
>> + /* release IPC device lock */
>> + mutex_unlock(&ipc_dev->lock);
>> +
>> + /* release channel lock */
>> + mutex_unlock(&channel_lock[chan_type]);
>> +
>> + return 0;
>> +}
>> +
>> +static const char *ipc_dev_err_string(struct intel_ipc_dev *ipc_dev,
>> + int error)
>> +{
>> + if (error < IPC_DEV_ERR_MAX)
>> + return ipc_err_sources[error];
>> +
>> + return "Unknown Command";
>> +}
>> +
>> +/* Helper function to send given command to IPC device */ static inline
>> +void ipc_dev_send_cmd(struct intel_ipc_dev *ipc_dev, u32 cmd) {
>> + ipc_dev->cmd = cmd;
>> +
>> + if (ipc_dev->cfg->mode == IPC_DEV_MODE_IRQ)
>> + reinit_completion(&ipc_dev->cmd_complete);
>> +
>> + if (ipc_dev->ops->enable_msi)
>> + cmd = ipc_dev->ops->enable_msi(cmd);
>> +
>> + regmap_write(ipc_dev->cfg->cmd_regs, ipc_dev->cfg->cmd_reg, cmd);
>> }
>> +
>> +static inline int ipc_dev_status_busy(struct intel_ipc_dev *ipc_dev) {
>> + int status;
>> +
>> + regmap_read(ipc_dev->cfg->cmd_regs, ipc_dev->cfg->status_reg,
>> +&status);
>> +
>> + if (ipc_dev->ops->busy_check)
>> + return ipc_dev->ops->busy_check(status);
>> +
>> + return 0;
>> +}
>> +
>> +/* Check the status of IPC command and return err code if failed */
>> +static int ipc_dev_check_status(struct intel_ipc_dev *ipc_dev) {
>> + int loop_count = IPC_DEV_CMD_LOOP_CNT;
>> + int status;
>> + int ret = 0;
>> +
>> + if (ipc_dev->cfg->mode == IPC_DEV_MODE_IRQ) {
>> + if (!wait_for_completion_timeout(&ipc_dev->cmd_complete,
>> + IPC_DEV_CMD_TIMEOUT))
>> + ret = -ETIMEDOUT;
>> + } else {
>> + while (ipc_dev_status_busy(ipc_dev) && --loop_count)
>> + udelay(1);
>> + if (!loop_count)
>> + ret = -ETIMEDOUT;
>> + }
>> +
>> + if (ret < 0) {
>> + dev_err(&ipc_dev->dev,
>> + "IPC timed out, CMD=0x%x\n", ipc_dev-
>>> cmd);
>> + return ret;
>> + }
>> +
>> + regmap_read(ipc_dev->cfg->cmd_regs, ipc_dev->cfg->status_reg,
>> +&status);
>> +
>> + if (ipc_dev->ops->to_err_code)
>> + ret = ipc_dev->ops->to_err_code(status);
>> +
>> + if (ret) {
>> + dev_err(&ipc_dev->dev,
>> + "IPC failed: %s, STS=0x%x, CMD=0x%x\n",
>> + ipc_dev_err_string(ipc_dev, ret),
>> + status, ipc_dev->cmd);
>> + return -EIO;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +/**
>> + * ipc_dev_simple_cmd() - Send simple IPC command
>> + * @ipc_dev : Reference to ipc device.
>> + * @cmd_list : IPC command list.
>> + * @cmdlen : Number of cmd/sub-cmds.
>> + *
>> + * Send a simple IPC command to ipc device.
>> + * Use this when don't need to specify input/output data
>> + * and source/dest pointers.
>> + *
>> + * Return: an IPC error code or 0 on success.
>> + */
>> +
>> +int ipc_dev_simple_cmd(struct intel_ipc_dev *ipc_dev, u32 *cmd_list,
>> + u32 cmdlen)
>> +{
>> + int ret;
>> +
>> + if (!cmd_list)
>> + return -EINVAL;
>> +
>> + ret = ipc_dev_lock(ipc_dev);
>> + if (ret)
>> + return ret;
>> +
>> + /* Call custom pre-processing handler */
>> + if (ipc_dev->ops->pre_simple_cmd_fn) {
>> + ret = ipc_dev->ops->pre_simple_cmd_fn(cmd_list, cmdlen);
>> + if (ret)
>> + goto unlock_device;
>> + }
>> +
>> + ipc_dev_send_cmd(ipc_dev, cmd_list[0]);
>> +
>> + ret = ipc_dev_check_status(ipc_dev);
>> +
>> +unlock_device:
>> + ipc_dev_unlock(ipc_dev);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(ipc_dev_simple_cmd);
>> +
>> +/**
>> + * ipc_dev_cmd() - Send IPC command with data.
>> + * @ipc_dev : Reference to ipc_dev.
>> + * @cmd_list : Array of commands/sub-commands.
>> + * @cmdlen : Number of commands.
>> + * @in : Input data of this IPC command.
>> + * @inlen : Input data length in dwords.
>> + * @out : Output data of this IPC command.
>> + * @outlen : Length of output data in dwords.
>> + *
>> + * Send an IPC command to device with input/output data.
>> + *
>> + * Return: an IPC error code or 0 on success.
>> + */
>> +int ipc_dev_cmd(struct intel_ipc_dev *ipc_dev, u32 *cmd_list, u32 cmdlen,
>> + u32 *in, u32 inlen, u32 *out, u32 outlen) {
>> + int ret;
>> +
>> + if (!cmd_list || !in)
>> + return -EINVAL;
>> +
>> + ret = ipc_dev_lock(ipc_dev);
>> + if (ret)
>> + return ret;
>> +
>> + /* Call custom pre-processing handler. */
>> + if (ipc_dev->ops->pre_cmd_fn) {
>> + ret = ipc_dev->ops->pre_cmd_fn(cmd_list, cmdlen, in, inlen,
>> + out, outlen);
>> + if (ret)
>> + goto unlock_device;
>> + }
>> +
>> + /* Write inlen dwords of data to wrbuf_reg. */
>> + if (inlen > 0)
>> + regmap_bulk_write(ipc_dev->cfg->data_regs,
>> + ipc_dev->cfg->wrbuf_reg, in, inlen);
>> +
>> + ipc_dev_send_cmd(ipc_dev, cmd_list[0]);
>> +
>> + ret = ipc_dev_check_status(ipc_dev);
>> +
>> + /* Read outlen dwords of data from rbug_reg. */
>> + if (!ret && outlen > 0)
>> + regmap_bulk_read(ipc_dev->cfg->data_regs,
>> + ipc_dev->cfg->rbuf_reg, out, outlen);
>> +unlock_device:
>> + ipc_dev_unlock(ipc_dev);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(ipc_dev_cmd);
>> +
>> +/**
>> + * ipc_dev_raw_cmd() - Send IPC command with data and pointers.
>> + * @ipc_dev : Reference to ipc_dev.
>> + * @cmd_list : Array of commands/sub-commands.
>> + * @cmdlen : Number of commands.
>> + * @in : Input data of this IPC command.
>> + * @inlen : Input data length in bytes.
>> + * @out : Output data of this IPC command.
>> + * @outlen : Length of output data in dwords.
>> + * @dptr : IPC destination data address.
>> + * @sptr : IPC source data address.
>> + *
>> + * Send an IPC command to device with input/output data and
>> + * source/dest pointers.
>> + *
>> + * Return: an IPC error code or 0 on success.
>> + */
> Sorry for coming in so late but since we are refactoring the API anyways, isn't it better to reduce the signature? Nine parameters is an awful lot and prone to errors and difficult to debug. (We found it out the hard way when we started using this a few years ago.)
I agree. Initially I thought of adding a command structure just like you
mentioned. But finally decided not to do it because,
1. Not all drivers uses all parameters of this API. Most of them pass
0,0 for DPTR and SPTR pointers. So the last two arguments are almost not
used.
2. Adding a new structure requires all users of this API to add buffer
code / some additional call to initialize the command structure which in
turn makes the code look bit complex.
So I am not really sure whether it add any value. But if its the
recommended approach then I will make that modification.
> This can be consolidated into a few neat structs, e.g.,:
> int ipc_dev_raw_cmd(struct intel_ipc_dev *ipc_dev, struct ipc_cmd *cmd,
> struct ipc_cmd_data *cmd_data, struct ipc_data_addr *addr)
>
> Same for the ipc_dev_cmd() APIs above as well.
>
>> +
>> +int ipc_dev_raw_cmd(struct intel_ipc_dev *ipc_dev, u32 *cmd_list, u32
>> cmdlen,
>> + u8 *in, u32 inlen, u32 *out, u32 outlen, u32 dptr, u32 sptr) {
>> + int ret;
>> + int inbuflen = DIV_ROUND_UP(inlen, 4);
>> + u32 *inbuf;
>> +
>> + if (!cmd_list || !in)
>> + return -EINVAL;
>> +
>> + inbuf = kzalloc(inbuflen, GFP_KERNEL);
>> + if (!inbuf)
>> + return -ENOMEM;
>> +
>> + ret = ipc_dev_lock(ipc_dev);
>> + if (ret)
>> + return ret;
>> +
>> + /* Call custom pre-processing handler. */
>> + if (ipc_dev->ops->pre_raw_cmd_fn) {
>> + ret = ipc_dev->ops->pre_raw_cmd_fn(cmd_list, cmdlen, in,
>> inlen,
>> + out, outlen, dptr, sptr);
>> + if (ret)
>> + goto unlock_device;
>> + }
>> +
>> + /* If supported, write DPTR register.*/
>> + if (ipc_dev->cfg->support_dptr)
>> + regmap_write(ipc_dev->cfg->cmd_regs, ipc_dev->cfg-
>>> dptr_reg,
>> + dptr);
>> +
>> + /* If supported, write SPTR register. */
>> + if (ipc_dev->cfg->support_sptr)
>> + regmap_write(ipc_dev->cfg->cmd_regs, ipc_dev->cfg-
>>> sptr_reg,
>> + sptr);
>> +
>> + memcpy(inbuf, in, inlen);
>> +
>> + /* Write inlen dwords of data to wrbuf_reg. */
>> + if (inlen > 0)
>> + regmap_bulk_write(ipc_dev->cfg->data_regs,
>> + ipc_dev->cfg->wrbuf_reg, inbuf, inbuflen);
>> +
>> + ipc_dev_send_cmd(ipc_dev, cmd_list[0]);
>> +
>> + ret = ipc_dev_check_status(ipc_dev);
>> +
>> + /* Read outlen dwords of data from rbug_reg. */
>> + if (!ret && outlen > 0)
>> + regmap_bulk_read(ipc_dev->cfg->data_regs,
>> + ipc_dev->cfg->rbuf_reg, out, outlen);
>> +unlock_device:
>> + ipc_dev_unlock(ipc_dev);
>> + kfree(inbuf);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(ipc_dev_raw_cmd);
>> +
>> +/* sysfs option to send simple IPC commands from userspace */ static
>> +ssize_t ipc_dev_cmd_reg_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf, size_t count) {
>> + struct intel_ipc_dev *ipc_dev = dev_get_drvdata(dev);
>> + u32 cmd;
>> + int ret;
>> +
>> + ret = sscanf(buf, "%d", &cmd);
>> + if (ret != 1) {
>> + dev_err(dev, "Error args\n");
>> + return -EINVAL;
>> + }
>> +
>> + ret = ipc_dev_simple_cmd(ipc_dev, &cmd, 1);
>> + if (ret) {
>> + dev_err(dev, "command 0x%x error with %d\n", cmd, ret);
>> + return ret;
>> + }
>> + return (ssize_t)count;
>> +}
>> +
>> +static DEVICE_ATTR(send_cmd, S_IWUSR, NULL, ipc_dev_cmd_reg_store);
>> +
>> +static struct attribute *ipc_dev_attrs[] = {
>> + &dev_attr_send_cmd.attr,
>> + NULL
>> +};
>> +
>> +static const struct attribute_group ipc_dev_group = {
>> + .attrs = ipc_dev_attrs,
>> +};
>> +
>> +static const struct attribute_group *ipc_dev_groups[] = {
>> + &ipc_dev_group,
>> + NULL,
>> +};
>> +
>> +/* IPC device IRQ handler */
>> +static irqreturn_t ipc_dev_irq_handler(int irq, void *dev_id) {
>> + struct intel_ipc_dev *ipc_dev = (struct intel_ipc_dev *)dev_id;
>> +
>> + if (ipc_dev->ops->pre_irq_handler_fn)
>> + ipc_dev->ops->pre_irq_handler_fn(ipc_dev, irq);
>> +
>> + complete(&ipc_dev->cmd_complete);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static void devm_intel_ipc_dev_release(struct device *dev, void *res) {
>> + struct intel_ipc_dev *ipc_dev = *(struct intel_ipc_dev **)res;
>> +
>> + if (!ipc_dev)
>> + return;
>> +
>> + device_del(&ipc_dev->dev);
>> +
>> + kfree(ipc_dev);
>> +}
>> +
>> +static int match_name(struct device *dev, const void *data) {
>> + if (!dev_name(dev))
>> + return 0;
>> +
>> + return !strcmp(dev_name(dev), (char *)data); }
>> +
>> +/**
>> + * intel_ipc_dev_get() - Get Intel IPC device from name.
>> + * @dev_name : Name of the IPC device.
>> + *
>> + * Return : ERR_PTR/NULL or intel_ipc_dev pointer on success.
>> + */
>> +struct intel_ipc_dev *intel_ipc_dev_get(const char *dev_name) {
>> + struct device *dev;
>> +
>> + if (!dev_name)
>> + return ERR_PTR(-EINVAL);
>> +
>> + dev = class_find_device(&intel_ipc_class, NULL, dev_name,
>> match_name);
>> +
>> + return dev ? dev_get_drvdata(dev) : NULL; }
>> +EXPORT_SYMBOL_GPL(intel_ipc_dev_get);
>> +
>> +static void devm_intel_ipc_dev_put(struct device *dev, void *res) {
>> + intel_ipc_dev_put(*(struct intel_ipc_dev **)res); }
>> +
>> +/**
>> + * devm_intel_ipc_dev_get() - Resource managed version of
>> intel_ipc_dev_get().
>> + * @dev : Device pointer.
>> + * @dev_name : Name of the IPC device.
>> + *
>> + * Return : ERR_PTR/NULL or intel_ipc_dev pointer on success.
>> + */
>> +struct intel_ipc_dev *devm_intel_ipc_dev_get(struct device *dev,
>> + const char *dev_name)
>> +{
>> + struct intel_ipc_dev **ptr, *ipc_dev;
>> +
>> + ptr = devres_alloc(devm_intel_ipc_dev_put, sizeof(*ptr),
>> GFP_KERNEL);
>> + if (!ptr)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ipc_dev = intel_ipc_dev_get(dev_name);
>> + if (!IS_ERR_OR_NULL(ipc_dev)) {
>> + *ptr = ipc_dev;
>> + devres_add(dev, ptr);
>> + } else {
>> + devres_free(ptr);
>> + }
>> +
>> + return ipc_dev;
>> +}
>> +EXPORT_SYMBOL_GPL(devm_intel_ipc_dev_get);
>> +
>> +/**
>> + * devm_intel_ipc_dev_create() - Create IPC device
>> + * @dev : IPC parent device.
>> + * @devname : Name of the IPC device.
>> + * @cfg : IPC device configuration.
>> + * @ops : IPC device ops.
>> + *
>> + * Resource managed API to create IPC device with
>> + * given configuration.
>> + *
>> + * Return : IPC device pointer or ERR_PTR(error code).
>> + */
>> +struct intel_ipc_dev *devm_intel_ipc_dev_create(struct device *dev,
>> + const char *devname,
>> + struct intel_ipc_dev_cfg *cfg,
>> + struct intel_ipc_dev_ops *ops)
>> +{
>> + struct intel_ipc_dev **ptr, *ipc_dev;
>> + int ret;
>> +
>> + if (!dev && !devname && !cfg)
>> + return ERR_PTR(-EINVAL);
>> +
>> + if (intel_ipc_dev_get(devname)) {
>> + dev_err(dev, "IPC device %s already exist\n", devname);
>> + return ERR_PTR(-EINVAL);
>> + }
>> +
>> + ptr = devres_alloc(devm_intel_ipc_dev_release, sizeof(*ptr),
>> + GFP_KERNEL);
>> + if (!ptr)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ipc_dev = kzalloc(sizeof(*ipc_dev), GFP_KERNEL);
>> + if (!ipc_dev) {
>> + ret = -ENOMEM;
>> + goto err_dev_create;
>> + }
>> +
>> + ipc_dev->dev.class = &intel_ipc_class;
>> + ipc_dev->dev.parent = dev;
>> + ipc_dev->dev.groups = ipc_dev_groups;
>> + ipc_dev->cfg = cfg;
>> + ipc_dev->ops = ops;
>> +
>> + mutex_init(&ipc_dev->lock);
>> + init_completion(&ipc_dev->cmd_complete);
>> + dev_set_drvdata(&ipc_dev->dev, ipc_dev);
>> + dev_set_name(&ipc_dev->dev, devname);
>> + device_initialize(&ipc_dev->dev);
>> +
>> + ret = device_add(&ipc_dev->dev);
>> + if (ret < 0) {
>> + dev_err(&ipc_dev->dev, "%s device create failed\n",
>> + __func__);
>> + ret = -ENODEV;
>> + goto err_dev_add;
>> + }
>> +
>> + if (ipc_dev->cfg->mode == IPC_DEV_MODE_IRQ) {
>> + if (devm_request_irq(&ipc_dev->dev,
>> + ipc_dev->cfg->irq,
>> + ipc_dev_irq_handler,
>> + ipc_dev->cfg->irqflags,
>> + dev_name(&ipc_dev->dev),
>> + ipc_dev)) {
>> + dev_err(&ipc_dev->dev,
>> + "Failed to request irq\n");
>> + goto err_irq_request;
>> + }
>> + }
>> +
>> + *ptr = ipc_dev;
>> +
>> + devres_add(dev, ptr);
>> +
>> + return ipc_dev;
>> +
>> +err_irq_request:
>> + device_del(&ipc_dev->dev);
>> +err_dev_add:
>> + kfree(ipc_dev);
>> +err_dev_create:
>> + devres_free(ptr);
>> + return ERR_PTR(ret);
>> +}
>> +EXPORT_SYMBOL_GPL(devm_intel_ipc_dev_create);
>> +
>> +static int __init intel_ipc_init(void)
>> +{
>> + ipc_channel_lock_init();
>> + return class_register(&intel_ipc_class); }
>> +
>> +static void __exit intel_ipc_exit(void) {
>> + class_unregister(&intel_ipc_class);
>> +}
>> +subsys_initcall(intel_ipc_init);
>> +module_exit(intel_ipc_exit);
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR("Kuppuswamy
>> +Sathyanarayanan<sathyanarayanan.kuppuswamy@linux.intel.com>");
>> +MODULE_DESCRIPTION("Intel IPC device class driver");
>> diff --git a/include/linux/platform_data/x86/intel_ipc_dev.h
>> b/include/linux/platform_data/x86/intel_ipc_dev.h
>> new file mode 100644
>> index 0000000..eaeedaf
>> --- /dev/null
>> +++ b/include/linux/platform_data/x86/intel_ipc_dev.h
>> @@ -0,0 +1,206 @@
>> +/*
>> + * Intel IPC class device header file.
>> + *
>> + * (C) Copyright 2017 Intel Corporation
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; version 2
>> + * of the License.
>> + *
>> + */
>> +
>> +#ifndef INTEL_IPC_DEV_H
>> +#define INTEL_IPC_DEV_H
>> +
>> +#include <linux/module.h>
>> +#include <linux/device.h>
>> +
>> +/* IPC channel type */
>> +#define IPC_CHANNEL_IA_PMC 0
>> +#define IPC_CHANNEL_IA_PUNIT 1
>> +#define IPC_CHANNEL_PMC_PUNIT 2
>> +#define IPC_CHANNEL_IA_SCU 3
>> +#define IPC_CHANNEL_MAX 4
>> +
>> +/* IPC return code */
>> +#define IPC_DEV_ERR_NONE 0
>> +#define IPC_DEV_ERR_CMD_NOT_SUPPORTED 1
>> +#define IPC_DEV_ERR_CMD_NOT_SERVICED 2
>> +#define IPC_DEV_ERR_UNABLE_TO_SERVICE 3
>> +#define IPC_DEV_ERR_CMD_INVALID 4
>> +#define IPC_DEV_ERR_CMD_FAILED 5
>> +#define IPC_DEV_ERR_EMSECURITY 6
>> +#define IPC_DEV_ERR_UNSIGNEDKERNEL 7
>> +#define IPC_DEV_ERR_MAX 8
>> +
>> +/* IPC mode */
>> +#define IPC_DEV_MODE_IRQ 0
>> +#define IPC_DEV_MODE_POLLING 1
>> +
>> +/* IPC dev constants */
>> +#define IPC_DEV_CMD_LOOP_CNT 3000000
>> +#define IPC_DEV_CMD_TIMEOUT 3 * HZ
>> +#define IPC_DEV_DATA_BUFFER_SIZE 16
>> +
>> +struct intel_ipc_dev;
>> +struct intel_ipc_raw_cmd;
>> +
>> +/**
>> + * struct intel_ipc_dev_cfg - IPC device config structure.
>> + *
>> + * IPC device drivers uses the following config options to
>> + * register new IPC device.
>> + *
>> + * @cmd_regs : IPC device command base regmap.
>> + * @data_regs : IPC device data base regmap.
>> + * @wrbuf_reg : IPC device data write register address.
>> + * @rbuf_reg : IPC device data read register address.
>> + * @sptr_reg : IPC device source data pointer register address.
>> + * @dptr_reg : IPC device destination data pointer register
>> + * address.
>> + * @status_reg : IPC command status register address.
>> + * @cmd_reg : IPC command register address.
>> + * @mode : IRQ/POLLING mode.
>> + * @irq : IPC device IRQ number.
>> + * @irqflags : IPC device IRQ flags.
>> + * @chan_type : IPC device channel type(PMC/PUNIT).
>> + * @msi : Enable/Disable MSI for IPC commands.
>> + * @support_dptr : Support DPTR update.
>> + * @support_sptr : Support SPTR update.
>> + *
>> + */
>> +struct intel_ipc_dev_cfg {
>> + struct regmap *cmd_regs;
>> + struct regmap *data_regs;
>> + unsigned int wrbuf_reg;
>> + unsigned int rbuf_reg;
>> + unsigned int sptr_reg;
>> + unsigned int dptr_reg;
>> + unsigned int status_reg;
>> + unsigned int cmd_reg;
>> + int mode;
>> + int irq;
>> + int irqflags;
>> + int chan_type;
>> + bool use_msi;
>> + bool support_dptr;
>> + bool support_sptr;
>> +};
>> +
>> +/**
>> + * struct intel_ipc_dev_ops - IPC device ops structure.
>> + *
>> + * Call backs for IPC device specific operations.
>> + *
>> + * @to_err_code : Status to error code conversion function.
>> + * @busy_check : Check for IPC busy status.
>> + * @enable_msi : Enable MSI for IPC commands.
>> + * @pre_simple_cmd_fn : Custom pre-processing function for
>> + * ipc_dev_simple_cmd()
>> + * @pre_cmd_fn : Custom pre-processing function for
>> + * ipc_dev_cmd()
>> + * @pre_raw_cmd_fn : Custom pre-processing function for
>> + * ipc_dev_raw_cmd()
>> + *
>> + */
>> +struct intel_ipc_dev_ops {
>> + int (*to_err_code)(int status);
>> + int (*busy_check)(int status);
>> + u32 (*enable_msi)(u32 cmd);
>> + int (*pre_simple_cmd_fn)(u32 *cmd_list, u32 cmdlen);
>> + int (*pre_cmd_fn)(u32 *cmd_list, u32 cmdlen, u32 *in, u32 inlen,
>> + u32 *out, u32 outlen);
>> + int (*pre_raw_cmd_fn)(u32 *cmd_list, u32 cmdlen, u8 *in, u32 inlen,
>> + u32 *out, u32 outlen, u32 dptr, u32 sptr);
>> + int (*pre_irq_handler_fn)(struct intel_ipc_dev *ipc_dev, int irq); };
>> +
>> +/**
>> + * struct intel_ipc_dev - Intel IPC device structure.
>> + *
>> + * Used with devm_intel_ipc_dev_create() to create new IPC device.
>> + *
>> + * @dev : IPC device object.
>> + * @cmd : Current IPC device command.
>> + * @cmd_complete : Command completion object.
>> + * @lock : Lock to protect IPC device structure.
>> + * @ops : IPC device ops pointer.
>> + * @cfg : IPC device cfg pointer.
>> + *
>> + */
>> +struct intel_ipc_dev {
>> + struct device dev;
>> + int cmd;
>> + struct completion cmd_complete;
>> + struct mutex lock;
>> + struct intel_ipc_dev_ops *ops;
>> + struct intel_ipc_dev_cfg *cfg;
>> +};
>> +
>> +#if IS_ENABLED(CONFIG_INTEL_IPC_DEV)
>> +
>> +/* API to create new IPC device */
>> +struct intel_ipc_dev *devm_intel_ipc_dev_create(struct device *dev,
>> + const char *devname, struct intel_ipc_dev_cfg *cfg,
>> + struct intel_ipc_dev_ops *ops);
>> +
>> +int ipc_dev_simple_cmd(struct intel_ipc_dev *ipc_dev, u32 *cmd_list,
>> + u32 cmdlen);
>> +int ipc_dev_cmd(struct intel_ipc_dev *ipc_dev, u32 *cmd_list, u32 cmdlen,
>> + u32 *in, u32 inlen, u32 *out, u32 outlen); int
>> ipc_dev_raw_cmd(struct
>> +intel_ipc_dev *ipc_dev, u32 *cmd_list, u32 cmdlen,
>> + u8 *in, u32 inlen, u32 *out, u32 outlen, u32 dptr, u32 sptr);
>> struct
>> +intel_ipc_dev *intel_ipc_dev_get(const char *dev_name); struct
>> +intel_ipc_dev *devm_intel_ipc_dev_get(struct device *dev,
>> + const char *dev_name);
>> +static inline void intel_ipc_dev_put(struct intel_ipc_dev *ipc_dev) {
>> + put_device(&ipc_dev->dev);
>> +}
>> +#else
>> +
>> +static inline struct intel_ipc_dev *devm_intel_ipc_dev_create(
>> + struct device *dev,
>> + const char *devname, struct intel_ipc_dev_cfg *cfg,
>> + struct intel_ipc_dev_ops *ops)
>> +{
>> + return -EINVAL;
>> +}
>> +
>> +static inline int ipc_dev_simple_cmd(struct intel_ipc_dev *ipc_dev,
>> + u32 *cmd_list, u32 cmdlen)
>> +{
>> + return -EINVAL;
>> +}
>> +
>> +static int ipc_dev_cmd(struct intel_ipc_dev *ipc_dev, u32 *cmd_list,
>> + u32 cmdlen, u32 *in, u32 inlen, u32 *out, u32 outlen) {
>> + return -EINVAL;
>> +}
>> +
>> +static inline int ipc_dev_raw_cmd(struct intel_ipc_dev *ipc_dev, u32
>> *cmd_list,
>> + u32 cmdlen, u8 *in, u32 inlen, u32 *out, u32 outlen,
>> + u32 dptr, u32 sptr);
>> +{
>> + return -EINVAL;
>> +}
>> +
>> +static inline struct intel_ipc_dev *intel_ipc_dev_get(const char
>> +*dev_name) {
>> + return NULL;
>> +}
>> +
>> +static inline struct intel_ipc_dev *devm_intel_ipc_dev_get(struct device
>> *dev,
>> + const char *dev_name);
>> +{
>> + return NULL;
>> +}
>> +
>> +static inline void intel_ipc_dev_put(struct intel_ipc_dev *ipc_dev) {
>> + return NULL;
>> +}
>> +#endif /* CONFIG_INTEL_IPC_DEV */
>> +#endif /* INTEL_IPC_DEV_H */
>> --
>> 2.7.4
>
--
Sathyanarayanan Kuppuswamy
Linux kernel developer
^ permalink raw reply
* Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: Guenter Roeck @ 2017-10-10 15:05 UTC (permalink / raw)
To: Alexandre Belloni
Cc: winton.liu, a.zummo, linux-rtc, linux-kernel, linux-watchdog
In-Reply-To: <20171010135134.2zepquujhfwbhxoq@piout.net>
On Tue, Oct 10, 2017 at 03:51:34PM +0200, Alexandre Belloni wrote:
> On 10/10/2017 at 06:41:15 -0700, Guenter Roeck wrote:
> > On 10/10/2017 06:12 AM, winton.liu wrote:
> > > When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
> > > in suspend mode, watchdog is still working but no daemon
> > > patting the watchdog. The system will reboot if timeout.
> > >
> > > Add support suspend/resume for watchdog.
> > > suspend: disable the watchdog
> > > resume: disable existing watchdog, reload watchdog timer, enable watchdog
> > >
> > > Signed-off-by: winton.liu <18502523564@163.com>
> > > ---
> > > drivers/rtc/rtc-ds1374.c | 31 +++++++++++++++++++++++++++++++
> > > 1 file changed, 31 insertions(+)
> > >
> > > diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
> > > index 38a2e9e..642e31d 100644
> > > --- a/drivers/rtc/rtc-ds1374.c
> > > +++ b/drivers/rtc/rtc-ds1374.c
> > > @@ -437,6 +437,29 @@ static void ds1374_wdt_ping(void)
> > > pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
> > > }
> > > +static void ds1374_wdt_resume(void)
> > > +{
> > > + int ret = -ENOIOCTLCMD;
> >
> > Useless initialization (yes, I can see that this is widely done in the driver,
> > but that doesn't make it better).
> >
> > > + int cr;
> > > +
> > > + cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
> > > +
> > > + /* Disable any existing watchdog/alarm before setting the new one */
> > > + cr &= ~DS1374_REG_CR_WACE;
> > > +
> > > + i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
> > > +
> > > + /* Reload watchdog timer */
> > > + ds1374_wdt_ping();
> > > +
> > > + /* Enable watchdog timer */
> > > + cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM;
> > > + cr &= ~DS1374_REG_CR_AIE;
> > > +
> > > + ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
> > > +
> > Extra empty line. Also, returns void, so what is the point of assigning
> > the result to ret ?
> >
> > > +}
> >
> > Unless I am missing something, this unconditionally starts the watchdog
> > at resume time. So if it was not running before, it will be started anyway,
> > and the system will reboot since there will be no ping.
> >
>
> Also, I'm still not convinced this is the right thing to do. I have seen
> many systems were it was desirable to let the watchdog run while the
> system is suspended. It ensures it will either wake up or reboot. If you
> don't want that, why not disabling the watchdog from userspace before
> going to suspend?
>
Usually watchdog drivers supporting suspend/resume do handle it this way.
Maybe that depends on the HW. Expecting user space to do it makes it
even more racy than it already is, since there is no watchdog protection
after it has been disabled, so I am not sure if that is really better.
Does anyone happen to know if/how systemd and watchdogd are handling
this situation ?
> > I assume it is guaranteed that the chip doesn't forget the previously
> > configured timeout on resume.
> >
> > Overall the driver would really benefit from a conversion to the watchdog
> > subsystem.
> >
>
> That is the point of https://www.spinics.net/lists/linux-watchdog/msg12095.html
Ah, yes, and I even provided feedback. Hope I didn't miss an updated
version of that patch. Either case, seems to me we should wait for that
patch to make it in before accepting any further changes to the driver.
Guenter
^ permalink raw reply
* Re:Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: 刘稳 @ 2017-10-10 13:36 UTC (permalink / raw)
To: Guenter Roeck
Cc: Alexandre Belloni, a.zummo, linux-rtc, linux-kernel,
Wim Van Sebroeck, linux-watchdog
In-Reply-To: <2b8f974f-6151-ea72-55e1-58df07279a06@roeck-us.net>
[-- Attachment #1: Type: text/plain, Size: 3420 bytes --]
Hi Guenter & Alexander,
Sorry for late update. I have modified the resume function.
resume: disable existing watchdog, reload watchdog timer, enable watchdog
Could you help to review attached patch ?
Thanks a lot.
Winton.Liu
At 2017-09-26 21:52:24, "Guenter Roeck" <linux@roeck-us.net> wrote:
>On 09/26/2017 03:22 AM, Alexandre Belloni wrote:
>> (+Cc wdt maintainers)
>>
>> On 26/09/2017 at 09:56:32 +0800, 18502523564 wrote:
>>> Hi Alexandre,
>>>
>>> Thanks for your reply.
>>> Do you think is this a issue when using as a watchdog in suspend?
>>> I takes the drivers/watchdog/ subsystem for reference, some drivers in suspend
>>> also call disable_watchdog.Or do you have any better suggestion?
>>
>> I guess this is a question for the watchdog subsystem maintainers.
>> However, I think that everything can be handled properly from userspace
>> as I know some atmel based devices have their watchdog enabled while
>> the platform is suspended.
>>
>
>Depends on the driver, really. There is one thing wrong below, though:
>It appears that on resume, the watchdog is unconditionally enabled.
>
>Guenter
>
>>> Thank you.
>>>
>>>
>>>
>>>
>>> ------------------ Original ------------------
>>> From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
>>> Date: 周一,9月 25,2017 20:07
>>> To: winton.liu <18502523564@163.com>
>>> Cc: a.zummo <a.zummo@towertech.it>, linux-rtc <linux-rtc@vger.kernel.org>,
>>> linux-kernel <linux-kernel@vger.kernel.org>
>>> Subject: Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
>>>
>>>
>>> Hi,
>>>
>>> On 25/09/2017 at 19:58:44 +0800, winton.liu wrote:
>>>> When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
>>>> in suspend mode, watchdog is still working but no daemon
>>>> patting the watchdog. The system will reboot if timeout.
>>>> So disable watchdog in suspend and recover it in resume.
>>>>
>>>
>>> That is definitively not what we want. Many people will want to still
>>> have the watchdog running when the platform is suspended. Your options
>>> are to either disable the watchdog before going to suspend or wake up
>>> the platform just in time to ping the watchdog.
>>>
>>>> Signed-off-by: winton.liu <18502523564@163.com>
>>>> ---
>>>> drivers/rtc/rtc-ds1374.c | 8 ++++++++
>>>> 1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
>>>> index 38a2e9e..e990773 100644
>>>> --- a/drivers/rtc/rtc-ds1374.c
>>>> +++ b/drivers/rtc/rtc-ds1374.c
>>>> @@ -690,6 +690,10 @@ static int ds1374_suspend(struct device *dev)
>>>> {
>>>> struct i2c_client *client = to_i2c_client(dev);
>>>>
>>>> +#ifdef CONFIG_RTC_DRV_DS1374_WDT
>>>> + ds1374_wdt_disable();
>>>> +#endif
>>>> +
>>>> if (client->irq > 0 && device_may_wakeup(&client->dev))
>>>> enable_irq_wake(client->irq);
>>>> return 0;
>>>> @@ -699,6 +703,10 @@ static int ds1374_resume(struct device *dev)
>>>> {
>>>> struct i2c_client *client = to_i2c_client(dev);
>>>>
>>>> +#ifdef CONFIG_RTC_DRV_DS1374_WDT
>>>> + ds1374_wdt_settimeout(131072);
>>>> +#endif
>>>> +
>>>> if (client->irq > 0 && device_may_wakeup(&client->dev))
>>>> disable_irq_wake(client->irq);
>>>> return 0;
>>>> --
>>>> 1.9.1
>>>>
>>>>
>>>
>>> --
>>> Alexandre Belloni, Free Electrons
>>> Embedded Linux and Kernel engineering
>>> http://free-electrons.com
>>>
>>
>
[-- Attachment #2: 0001-rtc-ds1374-wdt-support-suspend-resume-for-watchdog.patch --]
[-- Type: application/octet-stream, Size: 2158 bytes --]
From 0fcee72fbe953f2cd287e18821b8745e1260fbad Mon Sep 17 00:00:00 2001
From: "winton.liu" <18502523564@163.com>
Date: Mon, 25 Sep 2017 19:45:42 +0800
Subject: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
in suspend mode, watchdog is still working but no daemon
patting the watchdog. The system will reboot if timeout.
Add support suspend/resume for watchdog.
suspend: disable the watchdog
resume: disable existing watchdog, reload watchdog timer, enable watchdog
Signed-off-by: winton.liu <18502523564@163.com>
---
drivers/rtc/rtc-ds1374.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 38a2e9e..642e31d 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -437,6 +437,29 @@ static void ds1374_wdt_ping(void)
pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
}
+static void ds1374_wdt_resume(void)
+{
+ int ret = -ENOIOCTLCMD;
+ int cr;
+
+ cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
+
+ /* Disable any existing watchdog/alarm before setting the new one */
+ cr &= ~DS1374_REG_CR_WACE;
+
+ i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
+
+ /* Reload watchdog timer */
+ ds1374_wdt_ping();
+
+ /* Enable watchdog timer */
+ cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM;
+ cr &= ~DS1374_REG_CR_AIE;
+
+ ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
+
+}
+
static void ds1374_wdt_disable(void)
{
int ret = -ENOIOCTLCMD;
@@ -690,6 +713,10 @@ static int ds1374_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+#ifdef CONFIG_RTC_DRV_DS1374_WDT
+ ds1374_wdt_disable();
+#endif
+
if (client->irq > 0 && device_may_wakeup(&client->dev))
enable_irq_wake(client->irq);
return 0;
@@ -699,6 +726,10 @@ static int ds1374_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+#ifdef CONFIG_RTC_DRV_DS1374_WDT
+ ds1374_wdt_resume();
+#endif
+
if (client->irq > 0 && device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
return 0;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: Alexandre Belloni @ 2017-10-10 13:51 UTC (permalink / raw)
To: Guenter Roeck
Cc: winton.liu, a.zummo, linux-rtc, linux-kernel, linux-watchdog
In-Reply-To: <8b80788f-5906-38a5-4b40-0a78f0ab55d9@roeck-us.net>
On 10/10/2017 at 06:41:15 -0700, Guenter Roeck wrote:
> On 10/10/2017 06:12 AM, winton.liu wrote:
> > When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
> > in suspend mode, watchdog is still working but no daemon
> > patting the watchdog. The system will reboot if timeout.
> >
> > Add support suspend/resume for watchdog.
> > suspend: disable the watchdog
> > resume: disable existing watchdog, reload watchdog timer, enable watchdog
> >
> > Signed-off-by: winton.liu <18502523564@163.com>
> > ---
> > drivers/rtc/rtc-ds1374.c | 31 +++++++++++++++++++++++++++++++
> > 1 file changed, 31 insertions(+)
> >
> > diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
> > index 38a2e9e..642e31d 100644
> > --- a/drivers/rtc/rtc-ds1374.c
> > +++ b/drivers/rtc/rtc-ds1374.c
> > @@ -437,6 +437,29 @@ static void ds1374_wdt_ping(void)
> > pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
> > }
> > +static void ds1374_wdt_resume(void)
> > +{
> > + int ret = -ENOIOCTLCMD;
>
> Useless initialization (yes, I can see that this is widely done in the driver,
> but that doesn't make it better).
>
> > + int cr;
> > +
> > + cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
> > +
> > + /* Disable any existing watchdog/alarm before setting the new one */
> > + cr &= ~DS1374_REG_CR_WACE;
> > +
> > + i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
> > +
> > + /* Reload watchdog timer */
> > + ds1374_wdt_ping();
> > +
> > + /* Enable watchdog timer */
> > + cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM;
> > + cr &= ~DS1374_REG_CR_AIE;
> > +
> > + ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
> > +
> Extra empty line. Also, returns void, so what is the point of assigning
> the result to ret ?
>
> > +}
>
> Unless I am missing something, this unconditionally starts the watchdog
> at resume time. So if it was not running before, it will be started anyway,
> and the system will reboot since there will be no ping.
>
Also, I'm still not convinced this is the right thing to do. I have seen
many systems were it was desirable to let the watchdog run while the
system is suspended. It ensures it will either wake up or reboot. If you
don't want that, why not disabling the watchdog from userspace before
going to suspend?
> I assume it is guaranteed that the chip doesn't forget the previously
> configured timeout on resume.
>
> Overall the driver would really benefit from a conversion to the watchdog
> subsystem.
>
That is the point of https://www.spinics.net/lists/linux-watchdog/msg12095.html
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* Re: [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: Guenter Roeck @ 2017-10-10 13:41 UTC (permalink / raw)
To: winton.liu, a.zummo, alexandre.belloni
Cc: linux-rtc, linux-kernel, linux-watchdog
In-Reply-To: <1507641172-6099-1-git-send-email-18502523564@163.com>
On 10/10/2017 06:12 AM, winton.liu wrote:
> When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
> in suspend mode, watchdog is still working but no daemon
> patting the watchdog. The system will reboot if timeout.
>
> Add support suspend/resume for watchdog.
> suspend: disable the watchdog
> resume: disable existing watchdog, reload watchdog timer, enable watchdog
>
> Signed-off-by: winton.liu <18502523564@163.com>
> ---
> drivers/rtc/rtc-ds1374.c | 31 +++++++++++++++++++++++++++++++
> 1 file changed, 31 insertions(+)
>
> diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
> index 38a2e9e..642e31d 100644
> --- a/drivers/rtc/rtc-ds1374.c
> +++ b/drivers/rtc/rtc-ds1374.c
> @@ -437,6 +437,29 @@ static void ds1374_wdt_ping(void)
> pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
> }
>
> +static void ds1374_wdt_resume(void)
> +{
> + int ret = -ENOIOCTLCMD;
Useless initialization (yes, I can see that this is widely done in the driver,
but that doesn't make it better).
> + int cr;
> +
> + cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
> +
> + /* Disable any existing watchdog/alarm before setting the new one */
> + cr &= ~DS1374_REG_CR_WACE;
> +
> + i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
> +
> + /* Reload watchdog timer */
> + ds1374_wdt_ping();
> +
> + /* Enable watchdog timer */
> + cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM;
> + cr &= ~DS1374_REG_CR_AIE;
> +
> + ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
> +
Extra empty line. Also, returns void, so what is the point of assigning
the result to ret ?
> +}
Unless I am missing something, this unconditionally starts the watchdog
at resume time. So if it was not running before, it will be started anyway,
and the system will reboot since there will be no ping.
I assume it is guaranteed that the chip doesn't forget the previously
configured timeout on resume.
Overall the driver would really benefit from a conversion to the watchdog
subsystem.
> +
> static void ds1374_wdt_disable(void)
> {
> int ret = -ENOIOCTLCMD;
> @@ -690,6 +713,10 @@ static int ds1374_suspend(struct device *dev)
> {
> struct i2c_client *client = to_i2c_client(dev);
>
> +#ifdef CONFIG_RTC_DRV_DS1374_WDT
> + ds1374_wdt_disable();
> +#endif
> +
> if (client->irq > 0 && device_may_wakeup(&client->dev))
> enable_irq_wake(client->irq);
> return 0;
> @@ -699,6 +726,10 @@ static int ds1374_resume(struct device *dev)
> {
> struct i2c_client *client = to_i2c_client(dev);
>
> +#ifdef CONFIG_RTC_DRV_DS1374_WDT
> + ds1374_wdt_resume();
> +#endif
> +
> if (client->irq > 0 && device_may_wakeup(&client->dev))
> disable_irq_wake(client->irq);
> return 0;
>
^ permalink raw reply
* Re: [PATCH] rtc: add support for NXP PCF85363 real-time clock
From: Fabio Estevam @ 2017-10-10 13:31 UTC (permalink / raw)
To: Eric Nelson
Cc: linux-rtc, Alessandro Zummo, Alexandre Belloni,
robh+dt@kernel.org, Mark Rutland, devicetree@vger.kernel.org,
Otavio Salvador
In-Reply-To: <1507578100-2148-1-git-send-email-eric@nelint.com>
Hi Eric,
On Mon, Oct 9, 2017 at 4:41 PM, Eric Nelson <eric@nelint.com> wrote:
> +config RTC_DRV_PCF85363
> + tristate "NXP PCF85363"
> + depends on I2C
It seems you missed a dependency on REGMAP_I2C.
> +static const struct i2c_device_id pcf85363_id[] = {
> + { "pcf85363", 0 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(i2c, pcf85363_id);
Even though the driver can probe via the i2c device id, it is
recommended to explicitly pass the compatible string:
static const struct of_device_id pcf85363_dt_match[] = {
{ .compatible = "nxp,pcf85363" },
{ },
See this previous discussion:
https://www.spinics.net/lists/devicetree/msg195176.html
^ permalink raw reply
* [PATCH] rtc: ds1374: wdt:support suspend/resume for watchdog
From: winton.liu @ 2017-10-10 13:12 UTC (permalink / raw)
To: a.zummo, alexandre.belloni, linux
Cc: linux-rtc, linux-kernel, linux-watchdog, winton.liu
When enable CONFIG_RTC_DRV_DS1374_WDT use as watchdog,
in suspend mode, watchdog is still working but no daemon
patting the watchdog. The system will reboot if timeout.
Add support suspend/resume for watchdog.
suspend: disable the watchdog
resume: disable existing watchdog, reload watchdog timer, enable watchdog
Signed-off-by: winton.liu <18502523564@163.com>
---
drivers/rtc/rtc-ds1374.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index 38a2e9e..642e31d 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -437,6 +437,29 @@ static void ds1374_wdt_ping(void)
pr_info("WD TICK FAIL!!!!!!!!!! %i\n", ret);
}
+static void ds1374_wdt_resume(void)
+{
+ int ret = -ENOIOCTLCMD;
+ int cr;
+
+ cr = i2c_smbus_read_byte_data(save_client, DS1374_REG_CR);
+
+ /* Disable any existing watchdog/alarm before setting the new one */
+ cr &= ~DS1374_REG_CR_WACE;
+
+ i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
+
+ /* Reload watchdog timer */
+ ds1374_wdt_ping();
+
+ /* Enable watchdog timer */
+ cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_WDALM;
+ cr &= ~DS1374_REG_CR_AIE;
+
+ ret = i2c_smbus_write_byte_data(save_client, DS1374_REG_CR, cr);
+
+}
+
static void ds1374_wdt_disable(void)
{
int ret = -ENOIOCTLCMD;
@@ -690,6 +713,10 @@ static int ds1374_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+#ifdef CONFIG_RTC_DRV_DS1374_WDT
+ ds1374_wdt_disable();
+#endif
+
if (client->irq > 0 && device_may_wakeup(&client->dev))
enable_irq_wake(client->irq);
return 0;
@@ -699,6 +726,10 @@ static int ds1374_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
+#ifdef CONFIG_RTC_DRV_DS1374_WDT
+ ds1374_wdt_resume();
+#endif
+
if (client->irq > 0 && device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
return 0;
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox